{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Transpose Upper Triangular Matrix Vector Multiply Routines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook walks you through how to implement $ x := U^T x $ where $ U $ is upper triangular. Vector $ y $ is not to be touched (and, indeed, not even passed into the routines). This is a little trickier than you might think. You may want to do a few small problems by hand if you don't get the right answer. Also, PictureFLAME may help you see what is going on." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Getting started" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will use some functions that are part of our laff library (of which this function will become a part) as well as some routines from the FLAME API (Application Programming Interface) that allows us to write code that closely resembles how we typeset algorithms using the FLAME notation. These functions are imported with the \"import laff as laff\" and \"import flame\" statements." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Algorithm that takes dot products" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "The routine
Trmv_ut_unb_var1( U, x ) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This routine, given upper triangular $ U \\in \\mathbb{R}^{n \\times n} $ and $ x \\in \\mathbb{R}^n $ computes $ x := U^T x $. The \"_ut_\" in the name of the routine indicates this is the \"upper, transpose\" matrix-vector multiplication.\n", "\n", "The specific laff functions we will use are \n", "\n", "\n", "Use the Spark webpage to generate a code skeleton. (Make sure you adjust the name of the routine.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

NOTE: The algorithms for this operation march from bottom-right to top-left!!!

" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import flame\n", "import laff as laff\n", "\n", "def Trmv_ut_unb_var1(U, x):\n", "\n", " UTL, UTR, \\\n", " UBL, UBR = flame.part_2x2(U, \\\n", " 0, 0, 'BR')\n", "\n", " xT, \\\n", " xB = flame.part_2x1(x, \\\n", " 0, 'BOTTOM')\n", "\n", " while UBR.shape[0] < U.shape[0]:\n", "\n", " U00, u01, U02, \\\n", " u10t, upsilon11, u12t, \\\n", " U20, u21, U22 = flame.repart_2x2_to_3x3(UTL, UTR, \\\n", " UBL, UBR, \\\n", " 1, 1, 'TL')\n", "\n", " x0, \\\n", " chi1, \\\n", " x2 = flame.repart_2x1_to_3x1(xT, \\\n", " xB, \\\n", " 1, 'TOP')\n", "\n", " #------------------------------------------------------------#\n", "\n", " laff.scal( upsilon11, chi1 )\n", " laff.dots( u01, x0, chi1 )\n", " \n", " #------------------------------------------------------------#\n", "\n", " UTL, UTR, \\\n", " UBL, UBR = flame.cont_with_3x3_to_2x2(U00, u01, U02, \\\n", " u10t, upsilon11, u12t, \\\n", " U20, u21, U22, \\\n", " 'BR')\n", "\n", " xT, \\\n", " xB = flame.cont_with_3x1_to_2x1(x0, \\\n", " chi1, \\\n", " x2, \\\n", " 'BOTTOM')\n", "\n", " flame.merge_2x1(xT, \\\n", " xB, x)\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Testing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's quickly test the routine by creating a 4 x 4 matrix and related vectors, performing the computation." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from numpy import random\n", "from numpy import matrix\n", "\n", "U = matrix( random.rand( 4,4 ) )\n", "x = matrix( random.rand( 4,1 ) )\n", "xold = matrix( random.rand( 4,1 ) )\n", "\n", "# Notice that U is not upper triangular. We will only use the upper triangular part.\n", "\n", "print( 'U before =' )\n", "print( U )\n", "\n", "print( 'x before =' )\n", "print( x )" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "import numpy as np\n", "laff.copy( x, xold ) # save the original vector x\n", "\n", "Trmv_ut_unb_var1( U, x )\n", "\n", "print( 'x after =' )\n", "print( x )\n", "\n", "#np.triu makes the matrix upper triangular\n", "print( 'x - ( np.transpose( np.triu( U ) ) * xold ) = ' )\n", "print( x - ( np.transpose( np.triu( U ) ) * xold ) )" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bingo, it seems to work! (Notice that we are doing floating point computations, which means that due to rounding you may not get an exact \"0\".)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Watch your code in action!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Copy and paste the code into PictureFLAME , a webpage where you can watch your routine in action. Just cut and paste into the box. \n", "\n", "Disclaimer: we implemented a VERY simple interpreter. If you do something wrong, we cannot guarantee the results. But if you do it right, you are in for a treat.\n", "\n", "If you want to reset the problem, just click in the box into which you pasted the code and hit \"next\" again." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Algorithm that uses axpys" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "The routine
Trmv_ut_unb_var2( U, x ) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This routine, given upper triangular $ U \\in \\mathbb{R}^{n \\times n} $ and $ x \\in \\mathbb{R}^n $ computes $ x := U^T x $. The \"_ut_\" in the name of the routine indicates this is the \"upper triangular, transpose\" matrix-vector multiplication. \n", "\n", "The specific laff functions we will use are \n", "\n", "\n", "Use the Spark webpage to generate a code skeleton. (Make sure you adjust the name of the routine.)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import flame\n", "import laff as laff\n", "\n", "def Trmv_ut_unb_var2(U, x):\n", "\n", " UTL, UTR, \\\n", " UBL, UBR = flame.part_2x2(U, \\\n", " 0, 0, 'BR')\n", "\n", " xT, \\\n", " xB = flame.part_2x1(x, \\\n", " 0, 'BOTTOM')\n", "\n", " while UBR.shape[0] < U.shape[0]:\n", "\n", " U00, u01, U02, \\\n", " u10t, upsilon11, u12t, \\\n", " U20, u21, U22 = flame.repart_2x2_to_3x3(UTL, UTR, \\\n", " UBL, UBR, \\\n", " 1, 1, 'TL')\n", "\n", " x0, \\\n", " chi1, \\\n", " x2 = flame.repart_2x1_to_3x1(xT, \\\n", " xB, \\\n", " 1, 'TOP')\n", "\n", " #------------------------------------------------------------#\n", "\n", " laff.axpy( chi1, u12t, x2 )\n", " laff.scal( upsilon11, chi1 )\n", " \n", " #------------------------------------------------------------#\n", "\n", " UTL, UTR, \\\n", " UBL, UBR = flame.cont_with_3x3_to_2x2(U00, u01, U02, \\\n", " u10t, upsilon11, u12t, \\\n", " U20, u21, U22, \\\n", " 'BR')\n", "\n", " xT, \\\n", " xB = flame.cont_with_3x1_to_2x1(x0, \\\n", " chi1, \\\n", " x2, \\\n", " 'BOTTOM')\n", "\n", " flame.merge_2x1(xT, \\\n", " xB, x)\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Testing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's quickly test the routine by creating a 4 x 4 matrix and related vectors, performing the computation." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from numpy import random\n", "from numpy import matrix\n", "\n", "U = matrix( random.rand( 4,4 ) )\n", "x = matrix( random.rand( 4,1 ) )\n", "xold = matrix( random.rand( 4,1 ) )\n", "\n", "# U is not upper triangular. We will only use the upper triangular part.\n", "\n", "print( 'U before =' )\n", "print( U )\n", "\n", "print( 'x before =' )\n", "print( x )\n" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "laff.copy( x, xold ) # save the original vector y\n", "\n", "Trmv_ut_unb_var2( U, x )\n", "\n", "print( 'x after =' )\n", "print( x )\n", "\n", "#np.triu makes the matrix upper triangular\n", "print( 'x - ( np.transpose( np.triu( U ) ) * xold ) = ' )\n", "print( x - ( np.transpose( np.triu( U ) ) * xold ) )" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bingo, it seems to work! (Notice that we are doing floating point computations, which means that due to rounding you may not get an exact \"0\".)" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Watch your code in action!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Copy and paste the code into PictureFLAME , a webpage where you can watch your routine in action. Just cut and paste into the box. \n", "\n", "Disclaimer: we implemented a VERY simple interpreter. If you do something wrong, we cannot guarantee the results. But if you do it right, you are in for a treat.\n", "\n", "If you want to reset the problem, just click in the box into which you pasted the code and hit \"next\" again." ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }