{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Numpy\n", "\n", "### by Long Nguyen\n", "\n", "#### This Python tutorial is minimal, covering only the absolute basics of the powerful Numpy library necessary for the Introduction to Neural Networks course. For an excellent and more comprehensive introduction to Numpy see Ryan Soklaski's [Python Like You Mean It](https://www.pythonlikeyoumeanit.com/).\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this tutorial, we will cover:\n", "\n", "* Numpy: Working with Arrays, Matrix operations, Broadcasting. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numpy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy is the core library for scientific computing in Python. It provides a high-performance multidimensional array object, and tools for working with these arrays. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To use Numpy, we first need to import the `numpy` package:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Arrays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A numpy array is a grid of values, all of the same type, and is indexed by a tuple of nonnegative integers. The number of dimensions is the rank of the array; the shape of an array is a tuple of integers giving the size of the array along each dimension." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can initialize numpy arrays from nested Python lists. We can create a 1D(rank 1) array as follows. " ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(4,)\n", "[1 2 3 4]\n" ] } ], "source": [ "a = np.array([1,2,3,4]) # rank 1 array (1D array)\n", "print(a.shape) \n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll work exclusively with 2D(rank 2) arrays in this course. " ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 2 3]\n", " [4 5 6]]\n" ] }, { "data": { "text/plain": [ "array([[1, 2, 3],\n", " [4, 5, 6]])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = np.array([[1,2,3],[4,5,6]]) # Create a rank 2 array\n", " # b has shape (2,3), two rows, three cols\n", "print(b) # notice the difference between printing b vs outputting b\n", "b " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy provides a way to generate a random array of any shape whose values are drawn from the standard normal distribution(Bell curve with mean(average) $0$ and standard deviation $1$.)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[-0.34529725 0.8569278 0.49064438]\n", " [-0.08365688 0.64257269 -1.53733287]]\n" ] } ], "source": [ "d = np.random.randn(2,3) # standard normal distribution\n", "print(d)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(16,)\n" ] }, { "data": { "text/plain": [ "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "e = np.arange(16) # rank 1 array with values from 0 to 15.\n", "print(e.shape)\n", "e" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The reshape function allows an array to be given a new shape without changing its data. The new shape, however, needs to be compatible with the original shape." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2, 3],\n", " [ 4, 5, 6, 7],\n", " [ 8, 9, 10, 11],\n", " [12, 13, 14, 15]])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "e = e.reshape(4,4)\n", "e # note the number of brackets, where they are and the commas." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multi-dimensional arrays " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start with a rank 3 array (3D array)." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] }, { "data": { "text/plain": [ "array([[[ 0, 1],\n", " [ 2, 3]],\n", "\n", " [[ 4, 5],\n", " [ 6, 7]],\n", "\n", " [[ 8, 9],\n", " [10, 11]]])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.arange(12)\n", "a = a.reshape(3,2,2) # three sheets, two rows and two columns\n", "print(a.ndim) # number of dimensions\n", "a # try writing out a before running this cell." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The 3D array `h` consists of three \"sheets\", each with two rows and two columns. " ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 1],\n", " [2, 3]])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[0] # sheet 0 (2D array of 2 rows and 2 columns)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([2, 3])" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[0,1] # sheet 0, row 1 (1D array)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[0,1,1] # sheet 0, row 1, column 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Array math" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll deal exclusively with greyscale images(2D arrays, or matrices) in this course. We begin by reviewing some basic matrices and their operations. \n", "\n", "An $m\\times n$ matrix $A$ is a rectangular array of real numbers arranged in $m$ rows and $n$ columns and has the form:\n", " \n", "$$\\left[ \\begin{array}{cccc}\n", "a_{11} & a_{12} & \\ldots & a_{1n} \\\\\n", "a_{21} & a_{22} & \\ldots & a_{2n} \\\\\n", "\\vdots & \\vdots & \\ddots & \\vdots \\\\\n", "a_{m1} & a_{m2} & \\ldots & a_{mn}\n", "\\end{array} \\right] $$\n", "\n", "We will denote an $m\\times n$ matrix $A$ as $[a_{ij}]$. \n", "\n", "In Numpy, such a 2D array has shape $(m,n)$.\n", "\n", "Given two matrices $A=[a_{ij}]$ and $B=[b_{ij}]$, of dimension $m\\times n$. The sum $A+B$ and difference $A-B$ are calculated elementwise.\n", "\n", "For example,\n", "$$\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]+\\left[\\begin{array}{rr}\n", "5 & 6 \\\\\n", "7 & 8\n", "\\end{array}\\right]=\\left[\\begin{array}{rr}\n", "6 & 8 \\\\\n", "10 & 12\n", "\\end{array}\\right]$$ \n", "\n" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 6 8]\n", " [10 12]]\n" ] } ], "source": [ "x = np.array([[1,2],[3,4]])\n", "y = np.array([[5,6],[7,8]])\n", "print(x + y) # elementwise sum" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[-4 -4]\n", " [-4 -4]]\n" ] } ], "source": [ "# Elementwise difference\n", "print(x - y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The scalar product $cA$ of a real number(scalar) $c$ and a matrix $A$ is computed by multiplying every entry of $\\textbf{A}$ by $c$. Thus $cA=[ca_{ij}].$" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 3 6]\n", " [ 9 12]]\n" ] } ], "source": [ "# scalar product \n", "print(3*x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The elementwise product of two matrices $A=[a_{ij}]$ and $B=[b_{ij}]$, of dimension $m\\times n$, also known as the **Hadamard** product is $A*B=[a_{ij}*b_{ij}]$. \n", "\n", "For example,\n", "$$\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]*\\left[\\begin{array}{rr}\n", "5 & 6 \\\\\n", "7 & 8\n", "\\end{array}\\right]=\\left[\\begin{array}{rr}\n", "5 & 12 \\\\\n", "21 & 32\n", "\\end{array}\\right]$$ " ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 5 12]\n", " [21 32]]\n" ] } ], "source": [ "# Elementwise product\n", "print(x * y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that `*` is elementwise multiplication, not matrix multiplication. We instead use the dot function to multiply matrices. Matrix multiplication is VERY important in machine learning. You need to be very comfortable with it. Please review it, if necessary.\n", "\n", "We'll review matrix multiplication through some examples." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]\\left[\\begin{array}{r}\n", "1 \\\\\n", "2\n", "\\end{array}\\right]=\\left[\\begin{array}{r}\n", "5 \\\\\n", "11\n", "\\end{array}\\right]$$ \n" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 5]\n", " [11]]\n" ] } ], "source": [ "x = np.array([[1,2],[3,4]]) # shape (2,2)\n", "v = np.array([[1],[2]]) # shape (2,1)\n", "\n", "print(np.dot(x, v)) #(2,2) matrix times (2,1) matrix yields a (2,1) matrix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\\left[\\begin{array}{rr}\n", "1 & 0 & 3 \\\\\n", "4 & -1 & 2\n", "\\end{array}\\right]\\left[\\begin{array}{rr}\n", "0 & 1 \\\\\n", "2 & -1 \\\\\n", "3 & 0 \n", "\\end{array}\\right]=\\left[\\begin{array}{r}\n", "9 & 1 \\\\\n", "4 & 5\n", "\\end{array}\\right]$$ \n", "\n", "Note that a `(2,3)` array times `(3,2)` array yields a `(2,2)` array." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[9 1]\n", " [4 5]]\n" ] } ], "source": [ "x = np.array([[1,0,3],[4,-1,2]]) \n", "y = np.array([[0,1],[2,-1],[3,0]])\n", "\n", "print(np.dot(x, y))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following matrix multiplication is undefined since the dimensions are not aligned correctly.\n", "\n", "$$\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]\\left[\\begin{array}{rr}\n", "0 & 1\n", "\\end{array}\\right]$$ \n", "\n" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "shapes (2,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: shapes (2,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)" ] } ], "source": [ "x = np.array([[1,2],[3,4]]) \n", "y = np.array([[0,1]])\n", "\n", "print(np.dot(x, y))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Given a matrix $A$ of dimension $m\\times n$, define the **transpose**\n", "of $A$ denoted by $A^T$ as the matrix whose rows are the columns of $A$. Thus the dimension of $A^T$ is $n\\times m$. \n", "\n", "In Numpy, to transpose a matrix, simply use the T attribute of an array object:" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 2]\n", " [3 4]]\n", "[[1 3]\n", " [2 4]]\n" ] } ], "source": [ "print(x)\n", "print(x.T)" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[1 2 3]]\n", "[[1]\n", " [2]\n", " [3]]\n" ] } ], "source": [ "v = np.array([[1,2,3]])\n", "print(v) # shape (1,3)\n", "print(v.T) # shape (3,1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy provides many useful functions for performing computations on arrays; one of the most useful is `sum`:" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n", "[4 6]\n", "[3 7]\n" ] } ], "source": [ "# .sum(axis=n) dimension n is collapsed \n", "# and all values in the new matrix equal to the sum of the corresponding collapsed values\n", "x = np.array([[1,2],[3,4]])\n", "\n", "print(np.sum(x)) # Compute sum of all elements; \n", "print(np.sum(x, axis=0)) # all the rows(axis=0) are collapsed, summing the columns\n", "print(np.sum(x, axis=1)) # all the columns(axis=1) are collapsed, summing the rows\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another useful numpy function that we will use is argmax which returns the index of the largest value. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([1,2,5,8,4,5])\n", "np.argmax(x) # returns 3 since 8 is the largest and it is at index 3. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can find the full list of mathematical functions provided by numpy in the [documentation](http://docs.scipy.org/doc/numpy/reference/routines.math.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Broadcasting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Broadcasting allows operations on arrays whose shapes are not compatible. This notebook's treatment of broadcasting is VERY minimal. We only cover what is necessary for the rest of the course. \n", "\n", "You can find more information about broadcasting in the [documentation](https://docs.scipy.org/doc/numpy-1.14.0/user/basics.broadcasting.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Consider the following matrices \n", "$A = \\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]$ and $B=\\left[\\begin{array}{rr}\n", "0 & 1\n", "\\end{array}\\right]$. Note that $A+B$ is undefined because the shapes `(2,2)` and `(2,1)` are not compatible.\n", "\n", "Numpy, however, will broadcast the shape of the second matrix to shape `(2,2)` to be compatible with the first so that the addition can be done. It does this without making copies of the data and wasting memory.\n", "\n", "$$\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]+\\left[\\begin{array}{rr}\n", "0 & 1\\end{array}\\right]\\rightarrow\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]+\\left[\\begin{array}{rr}\n", "0 & 1 \\\\\n", "0 & 1\n", "\\end{array}\\right]=\\left[\\begin{array}{rr}\n", "1 & 3 \\\\\n", "3 & 5\n", "\\end{array}\\right]$$\n", "\n", "Similarly, \n", "\n", "$$\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]+\\left[\\begin{array}{rr}\n", "0 \\\\\n", "1 \\end{array}\\right]\\rightarrow\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "3 & 4\n", "\\end{array}\\right]+\\left[\\begin{array}{rr}\n", "0 & 0 \\\\\n", "1 & 1\n", "\\end{array}\\right]=\\left[\\begin{array}{rr}\n", "1 & 2 \\\\\n", "4 & 5\n", "\\end{array}\\right]$$\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "array([[1, 3],\n", " [3, 5]])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = np.array([[1,2],[3,4]])\n", "B = np.array([[0,1]])\n", "A+B" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "array([[1, 2],\n", " [4, 5]])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A = np.array([[1,2],[3,4]])\n", "B = np.array([[0],[1]])\n", "A+B" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Homework\n", "## Do the following problems." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Manually create a numpy array of rank 1 with numbers from 1 to 4." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create a numpy array of rank 2 with numbers from 1 to 4." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create an 1D array with the arange function from 0 to 29. Then reshape it into 1) an array of rank 2 of the appropriate size. and 2) an array of rank 3 of the appropriate size." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create a numpy array of rank 2 with shape `(4,5)` with of random values from the normal distribution. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Compute the following using numpy arrays. Use rank 2 arrays for both the matrix and the column vector.\n", "\n", "$$\\left[\\begin{array}{rr}\n", "-2 & 1 & 1 \\\\\n", "3 & 2 & 3\n", "\\end{array}\\right]\\left[\\begin{array}{rr}\n", "0 \\\\\n", "2 \\\\\n", "3 \n", "\\end{array}\\right]$$ \n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let $X=\\left[\\begin{array}{rr}-2 & 1 & 1 \\\\3 & 2 & 3\\end{array}\\right]$. Compute $X^T$ the transpose of $X$.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let $A=\\left[\\begin{array}{rr} 3 & -1 \\\\ -2 & 1 \\end{array}\\right]$ and $B=\\left[\\begin{array}{rr} 1 & 2 \\\\ -4 & 3 \\end{array}\\right]$. Compute $3A-2B$." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let $A$ and $B$ be as in the previous problem. Compute the matrix product $AB$ and the elementwise Hadamard product $A*B$." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let $A=\\left[\\begin{array}{rr} 3 & -1 &2 \\\\ -2 & 1 & 4 \\\\ 0 & 5 & 1 \\end{array}\\right]$. Find the sum of all of the rows. Your answer should be the 1D array $$\\left[\\begin{array}{rr} 1 & 5 &7\\end{array}\\right].$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let $A$ be the array as in the previous problem. Find the sum by collapsing all of the columns. Your answer should be the 1D array $$\\left[\\begin{array}{rr} 4 & 3 &6\\end{array}\\right].$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let `A` be the array as in the previous problem. Consider the function below which accepts a number and returns its square. " ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def sq(x):\n", " return x*x" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "9" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sq(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Compute `sq(A)`. What do you notice? In general, if `A` is an $m\\times n$ matrix $[a_{ij}]$ and $f:\\mathbb{R}\\rightarrow\\mathbb{R}$ is a function. Then $f(A)$ is the $m\\times n$ matrix given by $[f(a_{ij})]$. In other words, $f$ is applied elementwise to each entry of `A`. This is an important operation in machine learning. \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let $A=\\left[\\begin{array}{rr} 4 & 5 & 0 \\\\ -1 & 3 & 2 \\\\ -3 & 6 & 3\\end{array}\\right]$ and $B=\\left[\\begin{array}{rr} 1 & -2 & 1 \\end{array}\\right]$. Use broadcasting to compute $A+B$. Do it by hand before verifying with code." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let $A=\\left[\\begin{array}{rr} 4 & 5 \\\\ -1 & 3 \\end{array}\\right]$ and $B=\\left[\\begin{array}{rr} 1 \\end{array}\\right]$. Use broadcasting to compute $A+B$. Do it by hand before verifying with code." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Let $A=\\left[\\begin{array}{rr} 4 & 5 \\\\ -1 & 3 \\end{array}\\right]$ and $X=\\left[\\begin{array}{rr} 1 & 1 \\\\ 2 & -1 \\end{array}\\right]$ and $b=\\left[\\begin{array}{rr} 1 \\\\ 2 \\end{array}\\right]$. Use broadcasting to compute $AX+b$. Do it by hand before verifying with code." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" } }, "nbformat": 4, "nbformat_minor": 1 }