Einleitung Sprachelemente Nützliches Einführung in numerische Simulation mit Python Alexander Schlemmer, Jan Schumann-Bischoff, Tariq Baig Max-Planck-Institut für Dynamik und Selbstorganisation, Biomedizinische Physik Nichtlineare Dynamik Praktikum Num. Sim. mit Python Einleitung Sprachelemente Nützliches Inhaltsverzeichnis 1 Einleitung 2 Sprachelemente Numerik mit Numpy Plots mit matplotlib Scipy 3 Nützliches Num. Sim. mit Python Einleitung Sprachelemente Nützliches Python Universelle Skriptsprache, meistens interpretiert Fokus auf gute Lesbarkeit von Sourcecode Open Source (Python Software Foundation License) Existiert seit 1991 Wird gepflegt und weiter entwickelt von der Python Software Foundation Aktuell zwei (z.T. inkompatible) Hauptversionen: Python 2.7 und Python 3.4 Num. Sim. mit Python Einleitung Sprachelemente Nützliches Python: Merkmale Große Anzahl an (frei) verfügbaren Bibliotheken Im wissenschaftlichen Bereich: numpy, scipy, matplotlib Dynamische Typisierung Objektorientierung Reduzierte, übersichtliche Syntax, wenige Schlüsselwörter ⇒ Leicht zu lernen Als interpretierte Sprache eher langsam → Höhere Geschwindigkeit durch Vektorisierung von numerischen Operationen Schlechte Unterstützung von Threads (Multithreading) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Python ausführen Python-Interpreter ausführen: p y t h o n # Python 2 ( a u f den m e i s t e n R e c h n e r n ) python3 Skript / Programm ausführen: p y t h o n s k r i p t . py Äußerst praktische interaktive Shell: ipython Interaktives (Web-)Notebook: ipython notebook Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Einfache Beispiele Erstes Beispiel >>> print("Hello World!") Hello World! >>> # Das ist ein Kommentar >>> a = 42 # Variablendeklaration >>> print(a * 527 + abs(-0.1)) 22134.1 Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Variablendeklaration >>> v = 1 >>> type(v) <type ’int’> >>> y = 17 + 4j >>> type(y) <type ’complex’> >>> st = "str" >>> type(st) <type ’str’> >>> tr = True >>> type(tr) <type ’bool’> >>> x = 0.025 >>> type(x) <type ’float’> Mehr zu Typen unter: https://docs.python.org/2/library/types.html Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Mathematische Operationen (1) >>> # Einfache Ausdrücke: >>> 42 * 5 + 8 - 2 / (17 + 4) + a 260 >>> # Division: >>> 43.0 / 3 14.333333333333334 >>> 43 / 3 # Unterschied zw. Python 2 und 3! 14 >>> 43 // 3 # Ganzzahl-Division 14 >>> 43 % 3 # Modulo 1 Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Weitere Operatoren >>> # Potenzieren: >>> # Komplexe Zahlen: >>> 8**3 >>> c = 2 + 3j 512 >>> c.real >>> 9**(-2) 2.0 0.012345679012345678 >>> c.imag >>> # Vergleichen: 3.0 >>> 4 < 3 >>> c.conjugate() False (2-3j) >>> "str" == "str" >>> abs(c) True 3.605551275463989 >>> 68 >= 17*4 True >>> (not True == True) or (4 > 3 and 8 != 99) True Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Mathematische Standardfunktionen >>> from math import sqrt, exp >>> from math import pi,sin,acos >>> sqrt(2) 1.4142135623730951 >>> exp(a*-7) 2.0769322043867094e-128 >>> sin(0.5*pi) 1.0 >>> acos(1) 0.0 >>> import cmath >>> cmath.exp(-1/2*pi*1j) (-1-1.2246467991473532e-16j) >>> cmath.log(32, 2) (5+0j) >>> cmath.log(-2).imag 3.141592653589793 https://docs.python.org/3/library/math.html https://docs.python.org/3/library/cmath.html Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Listen >>> >>> >>> >>> >>> [3, >>> >>> [1, >>> >>> >>> [1, liste = [1, 3, 4, 5] liste.append(7) liste.extend([2, 3]) liste.reverse() liste 2, 7, 5, 4, 3, 1] liste.sort() liste 2, 3, 3, 4, 5, 7] liste.append("str") liste.append([1, 3]) liste 2, 3, 3, 4, 5, 7, ’str’, [1, >>> 1 >>> [7, >>> 5 >>> [7, >>> 216 liste[0] liste[6:8] ’str’] liste[-4] liste[-3:] ’str’, [1, 3]] liste[-1][1] * 72 3]] Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Bedingungen if-elif-else-Block >>> if a < 7: ... b = 17 ... print(a*7) ... elif a > 7: ... print(a/7) ... else: ... print(a) ... 6 Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Schleifen (1) for-Loop über Liste >>> for l in liste[0:2]: ... print(l) ... 1 2 for-Loop über Range >>> for l in range(-2,2): ... if l % 2 == 0: ... print(l) ... -2 0 Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Schleifen (2) while-Loop >>> i = 0 >>> while(i < 7): ... i += 2 # i = i + 2 ... >>> print(i) 8 Mehr zu Control-Flow: https://docs.python.org/3/tutorial/controlflow.html Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Funktionen Funktionen definieren >>> def f(x, y): ... print("Funktionsaufruf") ... b = a * x + y ... return(b) ... Funktionen aufrufen >>> f(23, -2) * 4 Funktionsaufruf 3856 Mehr zu Funktionen: https://docs.python.org/3/tutorial/ controlflow.html#defining-functions Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Numerik mit Numpy Numpy ist elementares Python Paket für numerische Berechnungen in Python Numpy bietet: → N-dimensionales Array Objekt → Indizierung ganzer Array Bereiche → Sehr schnelle Berechnung elementweiser Operationen (Vektorisierung) → Viele Lineare Algebra Routinen wie Matrix Multiplikation, SVD, Eigewertberechnungen, Invertierung, Zufallszahlengeneratoren, Foiurier-Transformation, ... Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Indizierung von Python Arrays Indizierung in Python ist Null-basiert (wie C)! Numpy Arrays sind keine Listen oder Listen von Listen Listen können zu Numpy Arrays konvertiert werden. Eindimensionales Array (1) >>> import numpy as np >>> a = np.array([1., 4.5, 6.3, 4.1, 0.3, 9.4, 7.1]) >>> a array([ 1. , 4.5, 6.3, 4.1, 0.3, 9.4, 7.1]) >>> a[2] 6.2999999999999998 >>> a.shape (7,) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Index ’von : bis : Schrittweite’ gibt Bereich im Array an Eindimensionales Array (2) >>> a = np.array([1., 4.5, 6.3, 4.1, 0.3, 9.4, 7.1]) >>> a[:3] # Das dritte Element ist NICHT enthalten! array([ 1. , 4.5, 6.3]) >>> a[3:] # Das dritte Element IST enthalten! array([ 4.1, 0.3, 9.4, 7.1]) >>> a[1:-2] # Indizierung bis vorvorletztem Element array([ 4.5, 6.3, 4.1, 0.3]) >>> a[::2] # Indizierung mit Schrittweite 2 array([ 1. , 6.3, 0.3, 7.1]) >>> a[1:5:2] array([ 4.5, 4.1]) >>> a[::-1] # Reihenfolge umdrehen array([ 7.1, 9.4, 0.3, 4.1, 6.3, 4.5, 1. ]) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Zweidimensionale Arrays >>> a = np.array([[4.2, 8.1, 7.9], [2.3, -7.6, 0.3]]) >>> a array([[ 4.2, 8.1, 7.9], [ 2.3, -7.6, 0.3]]) >>> a.shape (2, 3) >>> a[:,2] array([ 7.9, 0.3]) >>> a[1,1:] array([-7.6, 0.3]) >>> a.T # transponieren array([[ 4.2, 2.3], [ 8.1, -7.6], [ 7.9, 0.3]]) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Verändern von Elementen in Arrays >>> a = np.array([[4.2, 8.1, 7.9], [2.3, -7.6, 0.3]]) >>> a[0,2] = 1 >>> a array([[ 4.2, 8.1, 1. ], [ 2.3, -7.6, 0.3]]) >>> a[:,1] = [8, 9] >>> a array([[ 4.2, 8. , 1. ], [ 2.3, 9. , 0.3]]) >>> a[-1,:] = 3 >>> a array([[ 4.2, 8. , 1. ], [ 3. , 3. , 3. ]]) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Rechnen mit Arrays Elementweises Rechnen in Numpy deutlich schneller als mit eigenen Schleifen (wie in C, Fortran, ... üblich). Quellcode sollte also vektorisiert sein. >>> a = np.array([[4, 8, 7], [2., -7, 0]]) >>> a + 3 array([[ 7., 11., 10.], [ 5., -4., 3.]]) >>> np.sin(a) array([[-0.7568025 , 0.98935825, 0.6569866 ], [ 0.90929743, -0.6569866 , 0. ]]) >>> b = np.array([[1, 4, 3], [5, 2, 4.1]]) >>> a * b # Achtung: elementweise Multiplikation! array([[ 4., 32., 21.], [ 10., -14., 0.]]) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Spezielle Funktionen zum erzeugen von Arrays >>> a = np.zeros((4,3)) # Array mit Nullen >>> a = np.ones((4,3)) # Array mit Nullen >>> np.arange(3, 9, 2) # Werte mit gleichem Abstand array([3, 5, 7]) >>> np.diag([1, 2, 3]) # Diagonalmatrix array([[1, 0, 0], [0, 2, 0], [0, 0, 3]]) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Lineare Algebra mit numpy Lineare Algebra Routinen befinden sich in np.linalg >>> a = np.array([[2, 1], [3, 4]]) >>> b = np.array([[4, 8, 7], [2., -7, 0]]) >>> np.dot(a,b) # Matrixmultiplikation array([[ 10., 9., 14.], [ 20., -4., 21.]]) U, S, V = np.linalg.svd(a) w, v = np.linalg.eig(a) # Singulärwertzerlegung # Eigenwertberechnung http://docs.scipy.org/doc/numpy/reference/routines. linalg.html Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Kopieren und Referenzieren von Arrays >>> a = np.array([4.2, 8.1, 7.9, 2.3, -7.6, 0.3]) >>> b = a # Referenz auf gleichen Speicherbereich von a >>> a[1:4] = 4 >>> a array([ 4.2, 4. , 4. , 4. , -7.6, 0.3]) >>> b array([ 4.2, 4. , 4. , 4. , -7.6, 0.3]) >>> b = np.copy(a) # Kopie von a >>> a[-2:] = 3 >>> a array([ 4.2, 4. , 4. , 4. , 3. , 3. ]) >>> b array([ 4.2, 4. , 4. , 4. , -7.6, 0.3]) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Plots mit matplotlib Matplotlib ist quasi Standard zum graphischen darstellen von Daten Beherrscht 2D und 3D Plots, Histogramme und vieles mehr Gallery: http://www.matplotlib.org/gallery.html Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy 1.0 2D Matplotlib - einzelner Plot (1) import matplotlib.pyplot as plt import numpy as np x = np.arange(0,10,0.01) y = np.sin(x) plt.plot(x,y) 0.0 plt.show() 1.00 0.5 0.5 2 Num. Sim. mit Python 4 6 8 10 2D Matplotlib - einzelner Plot (2) import matplotlib.pyplot as plt import numpy as np x = np.arange(0,10,0.01) y = np.sin(x) fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.plot(x,y) ax.set_xlabel(’$x$’) ax.set_ylabel(’y’) plt.savefig(’sinusx2.pdf’) Numerik mit Numpy Plots mit matplotlib Scipy 1.0 0.5 y Einleitung Sprachelemente Nützliches 0.0 0.5 1.00 2 Num. Sim. mit Python 4 x 6 8 10 Einleitung Sprachelemente Nützliches 2D Matplotlib - Histogramm import matplotlib.pyplot as plt import numpy as np x = np.random.randn(10000) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.hist(x, 20) ax.set_xlabel(’$x$’) plt.savefig(’histogramm.pdf’) Numerik mit Numpy Plots mit matplotlib Scipy 1600 1400 1200 1000 800 600 400 200 04 3 Num. Sim. mit Python 2 1 0 x 1 2 3 4 y 2D Matplotlib - subplots import matplotlib.pyplot as plt import numpy as np x = np.arange(0,10,0.01) y = np.sin(x) z = np.cos(x) fig = plt.figure() ax = fig.add_subplot(2,1,1) ax.plot(x,y) ax.set_ylabel(’y’) ax = fig.add_subplot(2,1,2) ax.plot(x,z,’--r’) ax.set_ylabel(’z’) ax.set_xlabel(’x’) plt.savefig(’sincosx.pdf’) Numerik mit Numpy Plots mit matplotlib Scipy z Einleitung Sprachelemente Nützliches 1.0 0.5 0.0 0.5 1.00 1.0 0.5 0.0 0.5 1.00 2 4 2 4 Num. Sim. mit Python x 6 8 10 6 8 10 Einleitung Sprachelemente Nützliches 3D Matplotlib from mpl_toolkits.mplot3d \ import Axes3D import matplotlib.pyplot as plt import numpy as np x = np.arange(0,50,0.1) y = np.sin(x) z = np.cos(x) fig = plt.figure() ax = fig.add_subplot(1,1,1, projection=’3d’) ax.plot(x,y,z,’.’) ax.set_xlabel(’x’) ax.set_ylabel(’y’) ax.set_zlabel(’z’) plt.savefig(’sincosx3d.pdf’) Numerik mit Numpy Plots mit matplotlib Scipy 1.0 0.5 0 10 0.0y 20 30 0.5 x 40 50 1.0 Num. Sim. mit Python 0.5 0.0 z 0.5 1.0 1.0 Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Scipy Enthält weitere numerische Funktionen Basiert auf Numpy Beispiele: → Integrationsmethoden scipy.integrate → Minimierung von Funktionen scipy.optimize → Nächste Nachbarn Suche: scipy.spatial Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy DGL Integration Numerische Integratoren für gewöhnliche Differenzialgleichungen (DGLen) befinden sich im Paket scipy Gutes und genaues Integrationsverfahren ist Runge-Kutta45 (’dopri5’ in scipy) Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Beispiel: Lorenz63 model Definition der Modell Gleichungen def lorenz63(t,x): x1 = x[0] x2 = x[1] x3 = x[2] sigma = 10 rho = 28 beta = 8./3 F = np.zeros(3) F[0] = sigma*(x2-x1) F[1] = x1*(rho-x3)-x2 F[2] = x1*x2-beta*x3 return F Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Beispiel: Lorenz63 model Integration der Modell Gleichungen from scipy.integrate import ode N = 2000 dt = 0.01 x = np.zeros((N,3)) t = np.arange(0,2000*dt,dt) x[0,:] = [-4.70, 0.10, 29.10] r = ode(lorenz63).set_integrator(’dopri5’) r.set_initial_value(x[0,:], 0) i = 0 while r.successful() and r.t < (N-1)*dt: r.integrate(r.t+dt) i = i + 1 x[i,:] = r.y Num. Sim. mit Python Einleitung Sprachelemente Nützliches Numerik mit Numpy Plots mit matplotlib Scipy Attraktor des Lorenz63 Modells 20 15 10 45 40 35 30x3 25 20 15 10 5 30 20 10 0 10 x2 50 5 x1 10 15 3020 20 Num. Sim. mit Python Einleitung Sprachelemente Nützliches Dictionaries Dictionary: Datenstruktur, um Key-Value-Paare zu speichern Erzeugung >>> d1 = {} # Erzeugt ein leeres Dictionary >>> # Dictionary mit einigen Key-Value-Paaren: >>> d2 = {"key1": "value1", "key2": 728, ... "key3": [2, 3, 8]} Zugriff >>> d2["key1"] ’value1’ >>> d2["key2"] = 17 Mehr zu Dictionaries: https://docs.python.org/2/tutorial/ datastructures.html#dictionaries Num. Sim. mit Python Einleitung Sprachelemente Nützliches Serialisierung: Das Pickle-Modul ... stellt Funktionen bereit, um (fast) beliebige komplexe Datenstrukturen auf der Festplatte zu speichern und von dort wiederherzustellen. Erzeugung >>> import pickle >>> pickle.dump(d2, open("pickled_d2.dat", "wb")) >>> new_d = pickle.load(open("pickled_d2.dat", "rb")) >>> print(new_d) {’key3’: [2, 3, 8], ’key2’: 17, ’key1’: ’value1’} Num. Sim. mit Python Einleitung Sprachelemente Nützliches Weiteres Dokumentationsmaterial Offizielles Python-Tutorial: https://docs.python.org/3/tutorial/index.html Stackoverflow: http://stackoverflow.com/questions/tagged/python Offizielles Numpy-Tutorial: http://wiki.scipy.org/Tentative_NumPy_Tutorial Scipy-Cookbook: http://wiki.scipy.org/Cookbook Offizielles SciPy-Tutorial: http://docs.scipy.org/doc/scipy/reference/ tutorial/index.html Num. Sim. mit Python