diff --git a/00_Python_LinA/tutorial00.ipynb b/00_Python_LinA/tutorial00.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..8c361f230ee3ed9060a4f79555b97c50b0df2ae8 --- /dev/null +++ b/00_Python_LinA/tutorial00.ipynb @@ -0,0 +1,936 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Python Introduction" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Hello World\")\n", + "print(\"Hello\",\"World\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### Assigments and Objects" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "a = 1\n", + "b = \"42\"\n", + "b = \"Einen text mit einem 'zitat'\"\n", + "\n", + "print(a, type(a))\n", + "print(b, type(b))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "c = [1, \"2\", 3.4]\n", + "d = {\"x\": 1, \"y\": \"abc\", \"z\": 3}\n", + "\n", + "print(c, type(c))\n", + "print(d, type(d))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### Simple Functions and Mutability" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "def func(value):\n", + " value += 'Borealis'\n", + "\n", + "x = 'Anaconda'\n", + "print(x)\n", + "func(x)\n", + "print(x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "def func(value):\n", + " value += [4, 5, 6]\n", + " value.append(7)\n", + " \n", + "x = [1, 2, 3]\n", + "print(x)\n", + "func(x)\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "* Alles ist ein Objekt\n", + "* Objects können veränderlich sein (lists, dicts, numpy arrays, ...)\n", + "* Objects können unveränderlich sein (str, int, float, tuple, ...)\n", + "* Nur veränderliche Objekte können durch Funktion abgewandelt werden" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### Advance Functions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# Parameters can be set to default values\n", + "def f1(a, b=42, c=1): \n", + " return a + b + c\n", + "\n", + "# Functions can be invoked with anonymous and keyword parameters\n", + "print(f1(1, 2))\n", + "print(f1(1))\n", + "print(f1(c=2, a=1, b=2)) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# Parameters can be \"typed\", typechecking has to be done in a preprocessor\n", + "def fun(a: int, b: int): \n", + " return a + b\n", + "\n", + "print(fun(1, 2))\n", + "print(fun(\"Hallo\", \" Welt\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# Functions can return tuples\n", + "def foo(a, b):\n", + " return a + b, a * b\n", + "\n", + "c, d = foo(1, 2)\n", + "e = foo(1, 2)\n", + "print(c)\n", + "print(d)\n", + "print(e)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$\\Rightarrow$ Python Datei vom Anfang" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "from tutorium import function\n", + "\n", + "function(\"Imported!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### Conditional Branching" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "x = \"Hallo\"\n", + "\n", + "if x == 0:\n", + " print(\"x = 0\")\n", + "else:\n", + " if 'a' in x:\n", + " print(f\"a is in {x}\")\n", + " else:\n", + " print(\"So AmAzInG\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "if x == 0:\n", + " print(\"x = 0\")\n", + "elif 'a' in x:\n", + " print(f\"a is in {x}\")\n", + "else:\n", + " print(\"So AmAzInG\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### Range Function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "start, end, step = 2, 11, 3\n", + "idx = range(start, end, step)\n", + "\n", + "print(idx)\n", + "print(list(idx))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "#### For Loop" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# Looping over iterable objects\n", + "for i in idx:\n", + " print(i)\n", + " \n", + "for i in ['a', 'b']:\n", + " print(i)\n", + " \n", + "for i in 'ab':\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "idx = list(idx)\n", + "print(idx)\n", + "\n", + "# Looping over list indices\n", + "for i in range(len(idx)):\n", + " print(\"Index {0}, Value {1}\".format(i, idx[i]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# Looping over indices and elements\n", + "for i, e in enumerate(idx):\n", + " print(\"Index {0}, Value {1}\".format(i, e))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "d = {\"x\": 1, \"y\": \"abc\", \"z\": 3}\n", + "\n", + "# Looping over dictionary entries, CAREFUL: ITERATION IS NOT ORDERED\n", + "for k, v in d.items():\n", + " print(k, v)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "outputs": [], + "source": [ + "# While looping\n", + "i = 0\n", + "while i < 3:\n", + " print(i)\n", + " i += 1" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### Lambda Operator" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "f = lambda x, y: x + y\n", + "z = f(2, 3)\n", + "print(z)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### Functional Programming" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "l = [1, 2, 3]\n", + "\n", + "l1 = map(lambda x: x * 2, l)\n", + "print(list(l1))\n", + "\n", + "l2 = filter(lambda x: x > 2, l)\n", + "print(list(l2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "# second order function\n", + "def apply(f, a, b):\n", + " return f(a, b)\n", + "\n", + "fun = lambda x, y: x + y\n", + "c = apply(fun, 3, 4)\n", + "print(c)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Hinweise\n", + "\n", + "* Neue Sprache lernt man vor allem durch Anwendung\n", + "<br>\n", + "\n", + "* Exercise Notebook für tieferen Einblick in Python\n", + " * z.B. Objektorientierung" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Vectors in numpy" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Import numpy\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Initialization and types" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Intialize vector with values\n", + "a = np.array([1, 2, 3]) \n", + "# Initialize zero vector with shape from other\n", + "b1 = np.zeros_like(a)\n", + "b2 = np.random.randn(3)\n", + "print(a, b1, b2, \"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Initialize ones vector with given shape, \n", + "# IMPORTANT: Set shape to (x,) or x for vectors! \n", + "# This has implications for operations.\n", + "c1 = np.ones((4,))\n", + "c2 = np.ones(4)\n", + "# WRONG, this is a matrix (4 rows, 1 column) initialization. \n", + "d = np.ones((4,1))\n", + "print(c1.shape, c2.shape, d.shape, \"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Vectors (or in general numpy arrays) are typed\n", + "# Upcasting of types\n", + "e = np.array([1, 2, 3.0])\n", + "f = np.array([1, 2, 3])\n", + "g = np.array([1, 2, 3], dtype=complex)\n", + "print(e.dtype, f.dtype, g.dtype)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Operations on vectors" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Elementwise operations\n", + "print(a + a, a * a, a / a, a - a, a * 2, -a, \"\\n\") " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Other operations\n", + "print(a.argmax(), a.max(), a.sum(), abs(-a), \"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Slicing and indexing operations\n", + "print(a[0], a[0:1], a[-3:-1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dot product and Norm" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Naive implementation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def dot_p(a, b):\n", + " c = 0.0\n", + " if a.shape != b.shape: # Better to use error handling or assertions\n", + " return\n", + " for i in range(a.size):\n", + " c += a[i] * b[i]\n", + " return c\n", + "\n", + "print(dot_p(a, b2), dot_p(a, c1))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Numpy implementation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(a.dot(b2))\n", + "try:\n", + " a.dot(c1)\n", + "except ValueError as e:\n", + " print(e, \"\\n\")\n", + "\n", + "# Special cases\n", + "u = np.array([1., 0.])\n", + "v1 = np.array([0., 1.])\n", + "v2 = np.array([2., 0.])\n", + "v3 = np.array([.5, .5])\n", + "\n", + "# Normalize vector v3\n", + "v3 /= np.linalg.norm(v3)\n", + "\n", + "print(u.dot(v1), u.dot(v2), u.dot(v3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Matrices and linear maps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Explicit definition of a matrix\n", + "a = np.array([ [1, 2, 3], [4, 5, 6] ])\n", + "print(a, a.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Unity matrix generation\n", + "e = np.eye(3)\n", + "print(e)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Constant matrix generation\n", + "c = np.pi * np.ones((3, 3))\n", + "print(c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Random matrix, accessing elements\n", + "r = np.random.rand(3,3)\n", + "print(r, \"\\n\", r[:, 1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# NOTE: To run this example, you first have to run the plotting function cell below!\n", + "# Matrix vector product, linear mapping of a vector\n", + "v = np.array([0.5, 1])\n", + "m = np.array([[0, 1], [-1, 0]])\n", + "r = m.dot(v)\n", + "print(m, r)\n", + "plot([r, v], 'upper left')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plotting" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Plotting function\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import matplotlib\n", + "% matplotlib inline\n", + "\n", + "# Support animations\n", + "from matplotlib import animation, rc\n", + "from IPython.display import HTML\n", + "rc('animation', html='html5')\n", + "\n", + "# Find the first name in global names of the passed object\n", + "def get_label(o):\n", + " for k, v in list(globals().items()):\n", + " if v is o:\n", + " return k\n", + " return \"NoLabel\"\n", + "\n", + "# Plot a list of numpy arrays.\n", + "def plot(vectors, legend='lower right', cm='viridis'):\n", + " plt.figure(figsize=(5,5))\n", + " ax = plt.gca()\n", + " \n", + " mm = [0, 0]\n", + " c_idx = np.linspace(0.0, 1.0, len(vectors))\n", + " cm = matplotlib.cm.get_cmap(cm)\n", + " for i, v in enumerate(vectors):\n", + " if mm[1] < v.max():\n", + " mm[1] = v.max()\n", + " if mm[0] > v.min():\n", + " mm[0] = v.min()\n", + " label = get_label(v)\n", + " color = cm(c_idx[i])[:3]\n", + " ax.quiver(0, 0, v[0], v[1], angles='xy', scale_units='xy', scale=1, color=color, label=label)\n", + " \n", + " if legend != 'off':\n", + " plt.legend(loc=legend)\n", + " ax.set_xlim(mm)\n", + " ax.set_ylim(mm)\n", + "\n", + " plt.draw()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Change of basis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "B0 = np.eye(2) # Standardbasis\n", + "B1 = np.array([[-1, -1], [1, -1]]) # Rotated basis\n", + "B1 = B1 / np.sqrt(2)\n", + "\n", + "v = np.array([1, 0.5]) # Vector in stdbasis\n", + "v /= np.linalg.norm(v)\n", + "\n", + "B1_inv = np.linalg.inv(B1) # Inverse \n", + "v1 = B1.dot(v) # Rotated vector in new base\n", + "v2 = B1_inv.dot(v) # Original vector in new base\n", + "v3 = B1.dot(v2) # New base vector transformed back for plotting\n", + "\n", + "plot([B0, B1, v1, v2, v3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Linear map chaining" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "org = np.array([1, 0])\n", + "\n", + "alpha = 45 / 180 * np.pi\n", + "R1 = np.array([[np.cos(alpha), -np.sin(alpha)], [np.sin(alpha), np.cos(alpha)]])\n", + "S = np.array([[2, 0], [0, 1]])\n", + "\n", + "x = R1.dot(S.dot(org))\n", + "y = S.dot(R1.dot(org))\n", + "\n", + "plot([x, y, R1, S], 'upper left')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Eigenvectors and eigenvalues" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A = np.array([[1, 2], [2, -1]]) # Create linear transformation\n", + "val, EV = np.linalg.eig(A) # Calculate e-vectors and values\n", + "\n", + "ev0 = EV[:, 0] # First eigenvector\n", + "ev1 = EV[:, 1] # Second eigenvector\n", + "\n", + "# Transform eigenvectors by linear map A\n", + "v0 = A.dot(ev0) \n", + "v1 = A.dot(ev1)\n", + "\n", + "plot([A, v0, v1, EV], 'lower left') \n", + "\n", + "# Compare transformed vectors with scaled eigenvectors \n", + "print(val[0] * ev0, v0)\n", + "print(val[1] * ev1, v1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Explore unit sphere sampling vectors\n", + "t = np.linspace(0, 2 * np.pi, 101)\n", + "c = np.vstack(np.array([np.sin(ti), np.cos(ti)]) for ti in t[:-1])\n", + "c = c.T\n", + "cn = A.dot(c) # Linearly transform all sample vectors\n", + "\n", + "# Init figure\n", + "fig = plt.figure(figsize=(5,5))\n", + "ax = plt.axes(xlim=(-3, 3), ylim=(-3, 3))\n", + "\n", + "# Plot eigenvectors\n", + "ax.quiver(0, 0, ev0[0], ev0[1], angles='xy', scale_units='xy', scale=1, label='Eigenvectors')\n", + "ax.quiver(0, 0, ev1[0], ev1[1], angles='xy', scale_units='xy', scale=1)\n", + "\n", + "# Plot vectors sampled from unit sphere\n", + "q1 = ax.quiver(0, 0, 0, 0, angles='xy', scale_units='xy', scale=1, color='r', label='Original')\n", + "q2 = ax.quiver(0, 0, 0, 0, angles='xy', scale_units='xy', scale=1, color='g', label='Transformed')\n", + "plt.legend(loc='best')\n", + "\n", + "def animate(num, q1, q2, x, y):\n", + " q1.set_UVC(c[0][num], c[1][num])\n", + " q2.set_UVC(cn[0][num], cn[1][num])\n", + " return q1, q2\n", + "\n", + "anim = animation.FuncAnimation(fig, animate, fargs=(q1, q2, x, y), frames=100, interval=50, blit=False)\n", + "HTML(anim.to_html5_video())" + ] + }, + { + "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.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/0_Python_LinA/tutorial_0_python_exercise.ipynb b/00_Python_LinA/tutorial00_python_ex1.ipynb similarity index 100% rename from 0_Python_LinA/tutorial_0_python_exercise.ipynb rename to 00_Python_LinA/tutorial00_python_ex1.ipynb diff --git a/0_Python_LinA/tutorial_0_python_exercise2.ipynb b/00_Python_LinA/tutorial00_python_ex2.ipynb similarity index 100% rename from 0_Python_LinA/tutorial_0_python_exercise2.ipynb rename to 00_Python_LinA/tutorial00_python_ex2.ipynb diff --git a/0_Python_LinA/tutorial_0_python_exercise3.ipynb b/00_Python_LinA/tutorial00_python_ex3.ipynb similarity index 100% rename from 0_Python_LinA/tutorial_0_python_exercise3.ipynb rename to 00_Python_LinA/tutorial00_python_ex3.ipynb