====== 11. Numerické výpočty ====== Pro numerické výpočty, simulace a vizualizaci je možné využít v Pythonu knihovnu NumPy (součást balíku pro vědecké výpočty SciPy). Instalace pomocí instalátoru pip (i pokud nemáte administrátorská práva na počítači): pip install --user numpy scipy matplotlib scikit-image Po instalaci můžete začít knihovnu používat pomocí import numpy as np ==== Vytvoření pole konverzí z typů vestavěných v Pythonu ==== >>> x = np.array([2,3,1,0]) >>> x = np.array([2, 3, 1, 0]) >>> x = np.array([[1,2.0],[0,0],(1+1j,3.)]) # mix různých typů >>> x = np.array([[ 1.+0.j, 2.+0.j], [ 0.+0.j, 0.+0.j], [ 1.+1.j, 3.+0.j]]) ==== Vytvoření specializovaných polí ==== ''zeros(shape)'' - pole vyplněné nulami, datový typ ''float64'' >>> np.zeros((2, 3)) array([[ 0., 0., 0.], [ 0., 0., 0.]]) Obdobně lze pomocí funkce ''ones(shape)'' vytvářet i pole naplněná jedničkami. ''full(shape, value)'' - naplní pole prvky dané hodnoty >>> np.full((2, 2), 12.34) array([[12.34, 12.34], [12.34, 12.34]]) ''eye(size)'' - jednotková matice >>> np.eye(4) array([[1., 0., 0., 0.], [0., 1., 0., 0.], [0., 0., 1., 0.], [0., 0., 0., 1.]]) ''diag(vector)'' - diagonální matice >>> np.diag([1, 2, 3, 4]) array([[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]]) U funkcí lze stanovit datový typ pomocí argumentu ''dtype'' >>> np.zeros((4, 4), dtype='int8') array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=int8) ''arange()'' - pole s prvky rozmístěnými v pravidelných intervalech, specifikujeme krok >>> np.arange(10) array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> np.arange(2, 10, dtype=float) array([ 2., 3., 4., 5., 6., 7., 8., 9.]) >>> np.arange(2, 3, 0.1) array([ 2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9]) ''linspace()'' - pole s prvky rozmístěnými v pravidelných intervalech, specifikujeme počet prvků, délka intervalu je určena automaticky >>> np.linspace(1., 4., 6) array([ 1. , 1.6, 2.2, 2.8, 3.4, 4. ]) ==== Práce s polem v NumPy ==== * Informace o matici >>> import numpy as np >>> a = np.arange(15).reshape(3, 5) >>> a array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) >>> a.shape (3, 5) >>> a.ndim 2 >>> a.dtype.name 'int64' >>> a.itemsize 8 >>> a.size 15 >>> type(a) >>> b = np.array([6, 7, 8]) >>> b array([6, 7, 8]) >>> type(b) * Základní operace (po prvcích) >>> a - 1 >>> a / 2 >>> -(a % 4) >>> a > 5 # pravdivostni tabulka * Indexace >>> a[0] >>> a[0:-1] >>> a[0][1] >>> a[0, 1] >>> a[0:-1, 1:] >>> a[:, 2] # cely druhy sloupec >>> a[a>5] # indexace pravdivostni tabulkou -> vysledek je jednorozmerny ===== Příklady ===== ==== Lineární inerpolace metodou nejmenších čtverců ==== Mějme dvě pole, reprezentujícími čas (x) a hodnotu (y). Jaká je hodnota mezi mezi naměřenými body? import numpy as np x=np.array([10,20,30,40,50]) y=np.array([17.1,21.9,24.5,29.5,35.8]) Vykreslení pomocí knihovny matplotlib import matplotlib.pyplot as plt plt.plot(x,y,’ro’) # zdroj dat, vykresleno cervenymi body plt.xlabel(’x’) # popiska vodorovne osy plt.ylabel(’y’) # popiska svisle osy plt.title(’Measured data’) # titulek grafu plt.axis((0,60,10,40)) # nastaveni os plt.savefig(’data.pdf’) # ulozeni do souboru, podpora cele rady formatu, rozeznani pole pripony plt.show() # vykresleni grafu Interpolace metodou [[https://cs.wikipedia.org/wiki/Metoda_nejmen%C5%A1%C3%ADch_%C4%8Dtverc%C5%AF|nejmenších čtverců]] n=len(x) sx=np.sum(x) sy=np.sum(y) sxy=np.dot(x,y) sxx=np.dot(x,x) A=np.array([[sxx,sx],[sx,n]]) r=np.array([sxy,sy]) theta=np.linalg.solve(A,r) # obsahuje a,b print("theta=", theta) Interpolace a vykreslení t=np.arange(0,60,0.1) z=t*theta[0]+theta[1] plt.plot(t,z,’b-’) plt.legend([’naměřená data’,’aproximace’],loc=’upper left’) plt.savefig(’aproximace.pdf’) plt.show() ==== Vykreslení harmonického signálu ==== import matplotlib import matplotlib.pyplot as plt import numpy as np # data, ktera budeme kreslit x = np.arange(0.0, 2.0, 0.01) y1 = 1 + np.sin(2 * np.pi * t) # vykreslime průběh funkce plt.plot(x, y1) # popis os plt.xlabel("cas (s)") plt.ylabel("napeti (x)") # zobrazení grafu plt.show() === Úkoly === * vykreslete do grafu druhý průběh ''y2'', např. posunutý harmonický signál se stejnou časovou osou plt.plot(x, y1, x, y2) * definujte další průběh ''y3'' a vykreslete jednotlivé křivky s různým stylováním, graf doplňte legendou vykreslení jednotlivých průběhů plt.plot(x, y1, "b-", label="prvni funkce") plt.plot(x, y2, "r.", label="druha funkce") plt.plot(x, y3, "g--", label="treti funkce") # přidání legendy do levého dolního rohu plt.legend(loc="lower left") * vyzkoušejte vyplnění plochy pod křivkou plt.fill(x, y1, "red", x, y2, "yellow", alpha=0.3) * zapněte zobrazení mřížky plt.grid(True) ==== Vykreslení histogramu ==== import numpy as np import matplotlib.pyplot as plt # náhodné hodnoty y = np.random.normal(0, 0.1, 10000) plt.hist(y, bins=30, range=None, normed=True) # zkuste změnit počet binů # zobrazení grafu plt.show() ==== Práce s obrazovými daty ==== Pro práci s obrazovými daty můžeme využít třeba knihovnu ''scikit-image'', která obsahuje celou řadu [[https://scikit-image.org/docs/stable/auto_examples/|testovacích dat]]: import matplotlib.pyplot as plt from skimage import data camera = data.camera() plt.figure(figsize=(4, 4)) plt.imshow(camera, cmap='gray') plt.axis('off') plt.show()