{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Python Arrays "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "### Import Libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Array basics were covered earlier\n",
    "- Review those if needed\n",
    "- [See this page](https://www.w3schools.com/python/python_lists.asp) for more information on built-in Python Lists.\n",
    "\n",
    "## Numpy arrays\n",
    "\n",
    "- Python lists are nice, but for numerical work, numpy arrays are much better.\n",
    "- 90% of the work we will do in science, math, and engineering, is best done using numpy arrays.\n",
    "- All of the above regarding Python lists is the same, **except**\n",
    "    - Each element type needs to be the same.\n",
    "    - The way we create arrays is different.\n",
    "\n",
    "### Some good links:\n",
    "- [Numpy for Matlab users](https://docs.scipy.org/doc/numpy-1.15.0/user/numpy-for-matlab-users.html)\n",
    "    - [This too](http://mathesaurus.sourceforge.net/matlab-numpy.html)\n",
    "- [Tentative numpy tutorial](https://scipy.github.io/old-wiki/pages/Tentative_NumPy_Tutorial)\n",
    "- [Numpy quickstart tutorial](https://numpy.org/doc/stable/user/quickstart.html)\n",
    "- [Linear algebra](http://docs.scipy.org/doc/numpy/reference/routines.linalg.html)\n",
    "- [Cookbook with good recipes](https://scipy-cookbook.readthedocs.io)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Length of a list\n",
    "`len` function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "a = np.array([1.1, 2.2, 3.3, 4.4])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Creating arrays\n",
    "\n",
    "- `array` (we've already seen this)\n",
    "- `linspace`, `arange`\n",
    "- `empty`, `zeros`, `ones`, `full`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# linspace"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# arange\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# empty"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# zeros"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# ones"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# full"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Access elements\n",
    "- use square brackets with index number\n",
    "- array indexing **starts at zero**\n",
    "- for 2D arrays (matrix) `x[i,j]` is row `i`, column `j`\n",
    "- **can access backwards**0\n",
    "    - `x[-1]` is the last element\n",
    "    - `x[-2]` is the second to the last element, etc.\n",
    "    - See the figure below. If we wrap the array into a circle. Then element 0 is at the top. We index by +1 in moving clockwise, and index by -1 in moving counter-clockwise.\n",
    "    \n",
    "<img src=http://ignite.byu.edu/cbe263/lectures/arrays_f2.png width=800>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "x = np.arange(3,21,3)               # x is         [3 6 9 12 15 18]\n",
    "print(x)\n",
    "\n",
    "# Access elements with index values\n",
    "\n",
    "# or use an \"index array\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Array slices\n",
    "- Can access multiple elements using syntax: `a[s:e]`\n",
    "    - `s` is the start (optional)\n",
    "    - `e` is the end (optional)\n",
    "    - (stops short of the end)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "x = np.arange(0,11,1.5)       \n",
    "\n",
    "                                   # get all elements\n",
    "                                   # get indices 2 to the end\n",
    "                                   # get elements start to one before 2nd to last (stops short)\n",
    "                                   # get indices 2 to 4 (stops short of 5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Example\n",
    "\n",
    "We have an array of times $t$, and we want the array of differences $dt$ between times.\n",
    "- How big is $t$?\n",
    "- How big will $dt$ be?\n",
    "- Create $dt$ using a loop.\n",
    "- Create $dt$ using slice-indexing.\n",
    "    - Note, for arrays `a` and `b`, `a-b` is done element-wise.\n",
    "\n",
    "<img src=http://ignite.byu.edu/cbe263/lectures/arrays_f1.png width=300>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = np.array([ \n",
    "    0.01136646,  0.01655847,  0.02548247,  0.07698612,  0.17964401,\n",
    "    0.19813924,  0.22419994,  0.28622096,  0.28884997,  0.3627257 ,\n",
    "    0.42555072,  0.44965767,  0.47257237,  0.59335946,  0.73842352,\n",
    "    0.85900369,  0.88851226,  0.89153229,  0.89355469,  0.97705246,\n",
    "    ])\n",
    "\n",
    "# loop\n",
    "\n",
    "# slice\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Array properties\n",
    "\n",
    "- `size` and `shape`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "x = np.array([[1,2,3,4],[7,8,9,10]])\n",
    "print(x)\n",
    "\n",
    "np.shape(x)            # rows x columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "np.size(x)             # total number of elements"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "len(x)                 # length of first dimension (rows)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "x = np.array([1,2,3,4])\n",
    "len(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Arithmetic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "a = np.arange(9)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "#------- THIS\n",
    "\n",
    "b = 0.1 * a                 # multiplies each element of a by 0.1 and assigns whole resulting array to b\n",
    "\n",
    "#------- NOT THIS\n",
    "\n",
    "b = np.empty(len(a))\n",
    "for i in range(len(b)):\n",
    "    b[i] = 0.1*a[i]\n",
    "    \n",
    "#-------\n",
    "\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "a+b                 # adds element-wise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "a**2                # squares element-wise"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### BE CAREFUL about assignment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "x = np.array([1,2,3,4]) \n",
    "y = x                    # note, y is now just a reference to x.\n",
    "y[3] = 44                # if we change an element of y, it will change in x too!\n",
    "print(x)                 # this is not usually what we want\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "x = np.array([1,2,3,4])\n",
    "y = x.copy()                 # now x and y are two different objects\n",
    "y[3] = 44                    #   could also do y = np.array(x)\n",
    "print(x)\n",
    "print(y)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Basic Plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "x = np.linspace(0,20,1000)\n",
    "y = np.exp(-x/5)*np.sin(x)\n",
    "\n",
    "plt.plot(x,y);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Problem 1\n",
    "\n",
    "* Make an array of $x$ from 0 to 5 with 1000 points.\n",
    "* create the following arrays\n",
    "    * $2x$\n",
    "    * $x^2 -3x + 4$\n",
    "    * $\\sin(5x)$\n",
    "* Plot each array versus $x$ on a single plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Problem 2\n",
    "\n",
    "* Ideal gas law\n",
    "$$\\rho = \\frac{MP}{RT}$$\n",
    "* M=29 kg/kmol\n",
    "* R=8314 J/kmol*K\n",
    "* P=101325 Pa\n",
    "* **Find $\\rho$ for $T=300,400,\\ldots1000$ K**\n",
    "    * Store $\\rho$ and $T$ as arrays\n",
    "    * Plot $\\rho$ versus $T$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Problem 3\n",
    "\n",
    "* Redo Problem 2 by writing a function for $\\rho(T)$ as you would have in a previous lecture.\n",
    "    * Call the function with an array of $T$ and store the result as an array of $\\rho$.\n",
    "    * Plot $\\rho$ versus $T$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Problem 4\n",
    "\n",
    "- You have an array of $x$ points $x=0.0, 0.1, \\ldots, 50$.\n",
    "- Create $x$\n",
    "- Create $y=\\sin(x)$\n",
    "- At interior points, use a central difference approximation to find the derivative \n",
    "$$\\left(\\frac{dy}{dx}\\right)_i \\approx \\frac{y_{i+1}-y_{i-1}}{2\\Delta x},$$\n",
    "where $\\Delta x = x_1-x_0$.\n",
    "- At edge point use a one-sided difference approximation,\n",
    "$$\\left(\\frac{dy}{dx}\\right)_0 \\approx \\frac{y_{1}-y_{0}}{\\Delta x},$$\n",
    "$$\\left(\\frac{dy}{dx}\\right)_{n-1} \\approx \\frac{y_{n-1}-y_{n-2}}{\\Delta x}.$$\n",
    "- Plot $dy/dx$ versus $x$ , and $\\cos(x)$ versus $x$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# y: * (*  *  *  *  *  *) *        # boundary, (interior), boundary\n",
    "#    0  1  2  3  4  5  6  7\n",
    "#                     n-2 n-1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Problem 5\n",
    "- Solve the rate equation below to $t=5$ s using the Explicit Euler method $y_{i+1} = y_i + \\Delta tf(y_i,t_i).$\n",
    "\n",
    "$$\\frac{dy}{dt} = -ky,$$\n",
    "$$y_0=1,$$\n",
    "$$k=2.$$\n",
    "\n",
    "- Use $\\Delta t = 0.5$.\n",
    "- Store $t$ and $y$ in arrays.\n",
    "- Plot $y$ versus $t$, and $y_0e^{-kt}$ versus $t$ on the same plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Problem 6\n",
    "- The Haaland equation relates the friction factor $f$ in turbulent pipe flow to the Reynolds number $Re$.\n",
    "$$\\frac{1}{\\sqrt{f}} = -1.8\\log_{10}\\left[\\left(\\frac{\\epsilon/D}{3.7}\\right)^{1.11}+ \\frac{6.9}{Re}\\right].$$\n",
    "\n",
    "- Write a function to compute $f(Re, \\epsilon/D)$.\n",
    "- Create an array of 100 points that is uniformly spaced on a log scale, for $1000\\le Re\\le 1\\times 10^8$\n",
    "- Plot $f$ versus $\\log_{10}(Re)$. \n",
    "- Use $\\epsilon/D=0.001$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "base",
   "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.14.6"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
