{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Basic numerics and plot"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"pylab notebook just like namespace"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Populating the interactive namespace from numpy and matplotlib\n"
]
}
],
"source": [
"#%matplotlib inline\n",
"# For interactive plot, please use \n",
"%pylab inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Commands beginning with % our IPython 'magic' commands. This one sets up a bunch of matplotlib back end and imports numpy into the global namespace. We will do this in all of our notebooks for simplicity. It's actually considered bad form because it puts a lot of numpy functions into the global namespace, but for exploratory work it's very convenient.\n",
"\n",
"To avoid importing everything into the global namespace, one would use instead"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"#%matplotlib notebook\n",
"import numpy as np\n",
"import matplotlib as mpl\n",
"#mpl.rcParams['figure.dpi']= 150\n",
"%config InlineBackend.figure_format = 'svg'\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"which will make all of the numpy functions, such as array() and sin(), available as np.array(), np.sin(), and the plotting functions such as plot() and xlabel() as plt.plot() and plt.xlabel()."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Numpy Arrays\n",
"\n",
"Numpy arrays store **multidimensional arrays** of objects of a fixed type. The type of an array is a **dtype**, which is a more refined typing system than Python provides. They are efficient maps **from indices (i,j) to values**. They have **minimal memory overhead**.\n",
"\n",
"Arrays are **mutable**: their contents can be changed after they are created. However, their size and dtype, once created cannot be efficiently changed (requires a copy).\n",
"\n",
"Arrays are good for:\n",
"1. Representing matrices and vectors (**linear algebra**)\n",
"2. Storing grids of numbers (**plotting, numerical analysis**)\n",
"3. Storing data series (**data analysis**)\n",
"4. Getting/changing slices (regular subarrays)\n",
"\n",
"Arrays are not good for:\n",
"1. Applications that require growing/shrinking the size.\n",
"2. Heterogenous objects.\n",
"3. Non-rectangular data.\n",
"\n",
"Arrays are 0-indexed."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.70710678, 0. , 0.70710678])"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# A vector is an array with 1 index\n",
"a = array([1/sqrt(2), 0, 1/sqrt(2)])\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3,)"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.shape"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('float64')"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.dtype"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.size"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.7071067811865475"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# We access the elements using [ ]\n",
"a[0]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"a[0] = a[0]*2"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1.41421356, 0. , 0.70710678])"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We create a 2D array (that is a matrix) by passing the array() function a list of lists of numbers in the right shape."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 0, 0],\n",
" [0, 0, 1],\n",
" [0, 1, 0]])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# A matrix is an array with 2 indices\n",
"B = array( [[ 1, 0, 0],\n",
" [ 0, 0, 1],\n",
" [ 0, 1, 0]] )\n",
"B"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3, 3)"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"B.shape"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('int64')"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"B.dtype"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"B.size"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"B[0,0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Warning!** There is also a type called 'matrix' instead of 'array' in numpy. This is specially for 2-index arrays but is being removed from Numpy over the next two years because it leads to bugs. **Never use matrix(), only array()**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Basic Linear Algebra\n",
"\n",
"There are two basic kinds of multiplication of arrays in Python:\n",
"\n",
"1. **Element-wise multiplication:** a*b multiplies arrays of the same shape element by element.\n",
"2. **Dot product:** a@b forms a dot product of two vectors or a matrix product of two rectangular matrices. \n",
"\n",
"Mathematically, for vectors,\n",
"\n",
"$$ a@b = \\sum_i a[i] b[i] $$\n",
"\n",
"while for 2D arrays (matrices),\n",
"\n",
"$$ A@B[i,j] = \\sum_k A[i,k] B[k,j] $$"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"a = array([1, 1]) / sqrt(2)\n",
"b = array([1, -1]) / sqrt(2)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.70710678, 0.70710678])"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 0.70710678, -0.70710678])"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.5, 0.5])"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a*a"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9999999999999998"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a@a"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9999999999999999"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Compute the length of a\n",
"norm(a)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.9999999999999999"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sqrt(a@a)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 0.5, -0.5])"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a*b"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.0"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a@b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There are many, many more functions for doing linear algebra operations numerically provided by numpy and scipy. We will use some of them as we go."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Basic Plotting\n",
"\n",
"The second primary use of numpy array's is to hold grids of numbers for analyzing and plotting. In this case, we consider a long 1D array with length N as representing the values of the x and y axis of a plot, for example. \n",
"\n",
"Let's plot a sine wave:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"# create an equally spaced array of 100 numbers \n",
"# from -2pi to 2pi \n",
"x = np.linspace(-2*np.pi, 2*np.pi, 100)\n",
"\n",
"# evaluate a function at each point in x and create a \n",
"# corresponding array\n",
"y = 0.5*np.sin(x)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"figure()\n",
"plot(x,y)\n",
"grid()\n",
"xlabel(r'$x$')\n",
"ylabel(r'$0.5 \\sin(x)$')\n",
"show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A few comments:\n",
"1. The call to sin(x) is a 'ufunc', which automatically acts element-by-element on whatever shape array it is passed.\n",
"2. Matplotlib supports $\\LaTeX$ style mathematical expressions in any text that it renders -- just enclose in \\$ -signs. We use a raw (r\"..\") string so that the backslashes are passed onto the $\\LaTeX$ interpreter intact rather than being interpreted as special characters.\n",
"3. The 'notebook' backend (which we turned on at the beginning of the notebook) provides basic interactive plotting inside the notebook. Try it out. There are other backends which provide somewhat better interaction if you setup jupyter on your local computer."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Speed ###"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"279 µs ± 4.72 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
]
}
],
"source": [
"L = range(1000)\n",
"%timeit [i**2 for i in L]# % is a comment communicate to jupyter, not to python."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"806 ns ± 35.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
]
}
],
"source": [
"a = arange(1000)\n",
"%timeit a**2"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"mpl.rcParams['text.usetex']=True # This assigned the font style to be the MathJax style in the plot.\n",
"mpl.rcParams['font.family']='Times New Roman'"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"figure()\n",
"plot(a, a**2, '--')\n",
"title(r'This is a test.')\n",
"xlabel(r'$a$')\n",
"ylabel(r'$a^2$',rotation=0)# Do not rotate the y axis label.\n",
"show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Some Common Arrays"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([2, 4, 6, 8])"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"arange(2,10,2)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([2, 4, 6, 8])"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# compact notation for the previous\n",
"# r_ creates a *row* vector with the contents of the slice \n",
"# notice the [ ] rather than ( )\n",
"r_[2:10:2]"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 2., 4., 6., 8., 10.])"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"linspace(2,10,5)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 2., 4., 6., 8., 10.])"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# compact notation for the previous\n",
"r_[2:10:5j]"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1., 1.],\n",
" [1., 1.]])"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ones((2,2))"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.],\n",
" [0.],\n",
" [0.]])"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"zeros((3,1))"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1., 0., 0.],\n",
" [0., 1., 0.],\n",
" [0., 0., 1.]])"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eye(3)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 0, 0],\n",
" [0, 2, 0],\n",
" [0, 0, 3]])"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"diag([1,2,3])"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.80947482, 0.89261187],\n",
" [0.021396 , 0.07445528]])"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.rand(2,2)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 1.72812182, 11.29459947, 4.62183267],\n",
" [ 2.47499787, 2.67545379, 3.34511434],\n",
" [ 0.75359228, 3.57557972, 0.46732403]])"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.exponential(scale=3,size=(3,3))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Array DTypes\n",
"\n",
"Numpy has its own set of data types for the elements of arrays. These **dtypes** are more specific than 'int' or 'str' so that you can control the number of bytes used. \n",
"\n",
"1. Integers: int16 ('i2'), int32 ('i4'), int64 ('i8'), ...\n",
"2. Unsigned: uint32 ('u4'), uint64 ('u8'), ...\n",
"3. Float: float16 ('f2'), float32 ('f4'), float64 ('f8'), ...\n",
"4. Boolean: bool\n",
"5. Fixed Length Strings: 'S1', 'S2', ...\n"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('int64')"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array([1,0]).dtype"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('float64')"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array([1.,0]).dtype"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"numpy.float32"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"float32"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('int32')"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dtype('i4')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Basic Operations and Visualization"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"x = linspace(-pi, pi, 100)\n",
"y1 = sin(x)\n",
"y2 = exp(x/pi)"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"figure()\n",
"plot(x,y1, label=r'$\\sin(x)$')\n",
"plot(x,y2, label=r'$e^{x/\\pi}$')\n",
"legend(loc='upper left')\n",
"show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"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.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}