{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Implementing a dot routine" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Preliminaries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Again, copy this notebook so that you don't corrupt the original! Then you can \"play\" with the copy of the notebook all you want!

\n", "\n", "

\n", "\n", "NOTE: A common problem that students have with IPython notebooks is not understanding that when the code in the gray boxes (cells) is executed, it assigns variables that persist the whole time that the notebook is open. Further, some cells rely on variables assigned by earlier cells. If you execute these cells out of order, or if you execute the same cell twice, then you may end up changing the value of the variables. To correct this, click on \"Cell\" at the top and execute \"run all above\" or \"run all\". You can also reset all cells by clicking \"Cell -> All Output -> Clear\"\n", "\n", "

\n", "\n", "

In this notebook, you are asked to write a loop that implements a routine that computes a dot (inner) product.

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by importing numpy and creating vectors $ x = \\left( \\begin{array}{r} 1 \\\\ 2 \\\\ 3 \\end{array} \\right) $ and $ y = \\left( \\begin{array}{r} -1 \\\\ 0 \\\\ -2 \\end{array} \\right) $.\n", "\n", "Execute the code in the box by clicking in the box and then on \"Cell -> Run\". Alternative, click on the box and push \"Shift\" and \"Return\" (or \"Enter\") together." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import numpy as np # This imports a package called \"numpy\" that will make working with matrices \n", " # simpler\n", "\n", "# create two two-dimensional matrices of only one column each. \n", "x = np.matrix( '1.;2.;3.' )\n", "print( 'x = ' )\n", "print( x )\n", "\n", "y = np.matrix( '-1.;0.;-2.' )\n", "print( 'y = ' )\n", "print( y )" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With Python, you can simply execute alpha = np.transpose( x ) * y to compute $ \\alpha : = x^T y $:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "alpha = np.transpose( x ) * y\n", "\n", "print( 'alpha:' )\n", "print( alpha )" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interestingly, this results is stored in a 1 x 1 matrix (a matrix with only one element). This is because \n", " x and y are matrices and what is being performed here is a matrix-matrix multiply (with matrices np.transpose( x ) and y ). That is a topic we will cover in a few weeks...\n", "\n", "

To treat this 1x1 matrix as a scalar, you have to extract the (0,0) element of this 1 x 1 matrix:

" ] }, { "cell_type": "code", "collapsed": false, "input": [ "alpha[0,0]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "More on this in the future." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Computing a dot product with a loop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we want you to write a loop that computes $ \\alpha := x^T y $. \n", "\n", "Recall that the loop for copying three entries of a vector $ x $ into a vector $ y $ was given by \n", "\n", "\n", " for i in range( 3 ):\n", " y[ i, 0 ] = x[ i, 0 ] \n", "\n", "\n", "Don't forget the indentation before y[ i, 0 ] since that indicates what statements are part of the \"loop body\" (in other words, what statements are executed as part of the \"for loop\").\n", "\n", "Remember that $ x^T y = \\sum_{i=0}^{m-1} \\chi_i \\psi_i $, where $ m $ is the size of the vectors." ] }, { "cell_type": "code", "collapsed": false, "input": [ "alpha = 0.\n", "\n", "for i in range( 3 ):\n", " alpha = x[ i, 0 ] * y[ i, 0 ] + alpha\n", "\n", "print( 'alpha' )\n", "print( alpha )\n", "\n", "print( 'compare alpha to np.transpose(x) * y:' )\n", "alpha_reference = np.transpose(x) * y\n", "\n", "print( alpha - alpha_reference[0,0] )" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result should be:\n", "\n", "\n", "alpha\n", "-7.0\n", "compare alpha to np.transpose(x) * y:\n", "0.0\n", "" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Dot as a simple routine" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", "Writing the \"for loop\" every time you want to compute $ alpha := x^Ty $ is tedious and unnecessary. Obviously, you can do \" alpha = np.transpose(x) * y \", but the point of this exercise is for you to write your own routine. For this reason, you are going to write a routine, dot( x, y ).\n", "

\n", "\n", "

\n", "Complete the following routine to implement this:\n", "

" ] }, { "cell_type": "code", "collapsed": false, "input": [ "def dot( x, y ):\n", " \n", " m, n = np.shape( x )\n", " \n", " alpha = 0.0\n", " \n", " for i in range( m ):\n", " alpha = x[ i, 0 ] * y[ i, 0 ] + alpha\n", " \n", " return alpha" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Be sure the run the above box, or this notebook won't know about the routine!!!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, if you execute" ] }, { "cell_type": "code", "collapsed": false, "input": [ "alpha = 0.\n", "\n", "alpha = dot( x, y )\n", "\n", "print( 'alpha' )\n", "print( alpha )\n", "\n", "print( 'compare alpha to np.transpose(x) * y:' )\n", "alpha_reference = np.transpose(x) * y\n", "\n", "print( alpha - alpha_reference[0,0] )" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result should be:\n", "\n", "\n", "alpha\n", "-7.0\n", "compare alpha to np.transpose(x) * y:\n", "0.0\n", "" ] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "A complete dot function as part of the LAFF library" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we proceed with progressively more advanced operations and routines, we are going to need a general dot routine where $ x $ and $ y $ can be row and/or column vectors. \n", "\n", "This routine is part of the 'laff' library. If you do\n", "\n", "\n", "import laff\n", "\n", "\n", "then laff.dot( x, y ) will perform the desired dot operation, when x and y are column and/or a row vectors. If you really want to see what this routine looks like, then ask for it on the discussion forum and we'll point you to where it can be found." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import laff\n", "\n", "alpha = 0.\n", "\n", "alpha = laff.dot( x, y )\n", "\n", "print( 'alpha' )\n", "print( alpha )\n", "\n", "print( 'compare alpha to np.transpose(x) * y:' )\n", "alpha_reference = np.transpose(x) * y\n", "\n", "print( alpha - alpha_reference[0,0] )" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Need a challenge?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In \"1.5.2 Implementing a copy routine\", we gave a complete routine that implements a copy from a row/column vector to a row/column vector, checked whether the parameters were legal, and had comments in it. If you feel up to the challenge, below write a similar routine dot that works for row and column vectors, checks the parameters, and has comments. Be sure to test your implementation. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "def dot( x, y ):\n", " ### You fill in the rest!" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }