#!/usr/bin/env python # coding: utf-8 # Matematički softver # =================== # # ## Sadržaj kolegija # # - Python # - Numpy / Scipy # - Pandas # - Sympy # - Sage # - Markdown # - $\LaTeX$ # # Kolegij će se bazirati na korištenju web platforme [Sagemath cloud](http://cloud.sagemath.com). # Materijali za kolegij se nalaze na web stranici [kolegija](http://web.math.pmf.unizg.hr/nastava/matsoft), na Sagemath oblaku te u [Git repozitoriju kolegija](https://github.com/inakic/matsoft). # ## Plan kolegija # # 1. Uvod u Python; upoznavanje s web platformom # 2. Markdown, $\LaTeX$ notacija za matematičke formule # 3. Python kao alat za znanstvenike (Matplotlib, Pandas, ...) # 4. Sage # 5. $\LaTeX$ # ## Polaganje kolegija # Ocjena se formira na osnovu dva kolokvija te domaćih zadaća. # # **Kolokviji** open-book tipa. # # Kolokviji nose najviše 80 bodova. # # **Domaće zadaće** u obliku eseja, sa zadanim elementima. # # Predaja ispravno napravljenih svih domaćih zadaća nužan je uvjet za polaganje kolegija. Domaća zadaća je uspješno predana samo ako ima **sve** tražene elemente. # # Domaće zadaće nose do 20 bodova, ali na sljedeći način: studenti čije domaće zadaće odskaču kvalitetom dobit će do 20 dodatnih bodova. # # **Popravni ispit** nije predviđen. # ## Literatura # # **GIYF** # # Kolegij se dosta oslanja na [Lectures on scientific computing with Python](https://github.com/jrjohansson/scientific-python-lectures). # ## Python # # ### Prvi primjeri, korištenje Jupyter (IPython) notebook-a # # Jupyter notebook ima puno mogućnosti, koje ćemo upoznavati tijekom kolegija. Jedna od njih je i jednostavan pristup datotečnom sustavu. # In[4]: ls # In[5]: pwd # In[6]: get_ipython().run_line_magic('matplotlib', 'inline') # In[ ]: get_ipython().run_line_magic('load', 'integral_demo.py') # In[8]: integral_plot(func) # In[9]: from IPython.display import Image Image(url='http://python.org/images/python-logo.gif') # In[10]: from IPython.display import HTML HTML('') # In[11]: from IPython.display import YouTubeVideo from IPython.display import display display(YouTubeVideo("GMKZD1Ohlzk",width="560",height="315", start=3)) # Jedan [primjer korištenja Jupytera](https://losc.ligo.org/s/events/GW150914/GW150914_tutorial.html). [Verzija](https://cloud.sagemath.com/projects/4a5f0542-5873-4eed-a85c-a18c706e8bcd/files/support/2016-02-12-LIGO/GW150914_tutorial.html) sa svim pomoćnim datotekama na Sagemath oblaku. # ### Primjer korištenja Pythona # # Krenimo s nečim korisnim. Učitajmo sliku, prikažimo je, prikažimo dio slike te smanjimo šum na tom dijelu slike. # In[12]: #Scikit-image je paket za manipulaciju slika from skimage import data import matplotlib.pyplot as plt coins = data.coins() plt.imshow(coins,cmap='gray'); # Što se dešava u gornjem kodu? # # Prvi redak koda služi da se iz biblioteke [scikit-image](http://scikit-image.org/) učita pod-bibiloteka *data*. # # U drugom retku iz biblioteke [matplotlib](http://matplotlib.org/) učitavamo pod-biblioteku *pyplot*. Kako ćemo *pyplot* često koristiti dajemo joj kraće ime *plt*. # # U trećem retku iz biblioteke *data* učitavamo objekt *coins*. To je u ovom slučaju slika novčića. # # Na koncu prikazujemo sliku. # In[13]: print(coins.shape) # Varijabla *coins.shape* sadrži par brojeva. # In[14]: a,b=coins.shape print(a) print(b) # In[15]: from skimage import restoration coins_zoom = coins[10:80, 300:370] tv_coins = restoration.denoise_tv_chambolle(coins_zoom, weight=0.1) plt.figure() plt.subplot(1,2,1) plt.imshow(coins_zoom,cmap='gray'); plt.subplot(1,2,2) plt.imshow(tv_coins, cmap='gray'); # Što točno radi funkcija *denoise_tv_chambolle*? To možemo saznati na sljedeći način. # In[16]: help(restoration.denoise_tv_chambolle) # Analogno smo mogli koristiti i *restoration.denoise_tv_chambolle?* # Još jedan primjer korištenja biblioteka. # In[17]: import math print ('pi je (otprilike): {}'.format(math.pi)) print ('pi je (otprilike): {:f}'.format(math.pi)) print ('pi je (otprilike): {:1.8f}'.format(math.pi)) # In[18]: import math as m print ('drugi korijen iz 7 je: {}'.format(m.sqrt(7))) # umjesto math.sqrt # In[19]: from math import sqrt print ('drugi korijen iz 9 je: {}'.format(sqrt(9))) # bez korištenja točke # Ukoliko želimo učitati sve iz biblioteke koristimo *. # In[20]: from math import * x = cos(2 * pi) print(x) # Varijable se definiraju sa znakom za jednakost *=*. # In[21]: masa = 90.5 godine = 50 ime = 'Osoba #1' # može i ime = "Osoba #1" # ## Brojevi # In[22]: 2/3 # U pythonu 2 rezultat bi bio 0 # In[23]: 2//3 # In[24]: float(2)/3 # In[25]: 8%4 # In[26]: 5**2 # In[27]: # kompleksni brojevi x = 1.0 - 1.0j print(x.real, x.imag) # ### Razlomci # In[28]: from fractions import Fraction print(Fraction(6,7)) print(Fraction(2)) print(Fraction('-3/7')) print(Fraction(2.25)) # ## Stringovi, liste, rječnici # In[29]: s = "Hello world" print(len(s)) s2 = s.replace("world", "test") print(s2) print(s[:5]) print(s[6:]) print(s[::2]) s3 = "Hello" + "world" # In[30]: l = [1,2,3,4] print(l[1:3]) l2 = [1, 'a', 1.0, 1-1j] l3 = [1, [2, [3, [4, [5]]]]] s2=list(s2) s2 # In[31]: l = [] l.append("A") l.append("d") l.append("d") l # In[32]: l[1]='A' l # In[33]: l.remove("A") l # In[34]: # nizovi (tuples) su isto što i liste, ali ne mogu se mijenjati point = (10, 20) point[0] = 20 # In[36]: # rječnici params = {"parametar1" : 1.0, "parametar2" : 2.0, "parametar3" : 3.0,} print("parametar2 = " + str(params["parametar2"])) # ## Skupovi # In[37]: korpa = ['jabuka', 'malina', 'jabuka', 'kupina', 'dunja', 'banana'] voce = set(korpa) voce # In[38]: 'dunja' in voce, 'ananas' in voce # In[39]: skup = {'a','b','c'} skup # In[40]: {x for x in 'abracadabra' if x not in 'abc'} # In[41]: a = set('abracadabra') b = set('alacazam') print(a - b) # razlika print(a | b) # unija print(a & b) # presjek print(a ^ b) # simetrična razlika # ## Funkcije # In[42]: def zero(): return 0 zero() # In[43]: def powers(x): """ Potencije od x. """ return x ** 2, x ** 3, x ** 4 x2, x3, x4 = powers(3) print(x3) # Blokovi se u Pythonu označavaju uvlačenjem koda. **Praznine imaju sintaktičku ulogu.** # # Kompliciraniji primjer. # In[44]: from skimage import io, transform def thumbnail(slika, sirina=100, ime='thumb.png'): """Ova funkcija kao ulazne parametre prima sliku, širinu (s defaultnom vrijednošću 100) te ime za thumbnail (s defaultnom vrijednošću thumb.png)""" visina = int(slika.shape[1] * float(sirina) / slika.shape[0]) io.imsave(ime, transform.resize(slika,(sirina, visina))) # In[45]: astro = data.astronaut() astro.view() # In[46]: plt.imshow(astro); # In[47]: io.imsave('astro.png', astro) # In[48]: astro_s_diska = io.imread('astro.png') thumbnail(astro_s_diska) # In[49]: Image('thumb.png') # In[50]: thumbnail(astro_s_diska, sirina=200, ime='thumb2.png') Image('thumb2.png') # In[51]: # Anonimne funkcije f1 = lambda x: x**2 # Gdje anonimne funkcije mogu biti korisne? map(lambda x: x**2, range(-3,4)) list(map(lambda x: x**2, range(-3,4))) # Funkcije su objekti kao i svi drugi. # In[52]: def linearna (a,b): def rezultat (x): return a*x+b return rezultat f=linearna(0.5,2) f(1e3) # In[53]: def kompozicija(f,g): return lambda x: f(g(x)) def g(x): return x**2 fg = kompozicija(f,g) fg(1) # In[54]: from operator import pow pow(5,2) # In[55]: def parcijalno(metoda, parametar): return lambda x: metoda(x,parametar) h = parcijalno(pow,2) h(20) # In[56]: #kompozija proizvoljnog broja funkcija from functools import reduce def compose(*funcs): return lambda x: reduce(lambda v, f: f(v), reversed(funcs), x) ffgh = compose(f,f,g,h) ffgh(1) # ## Kontrola toka # In[57]: izjava1 = False izjava2 = False if izjava1: print("izjava1 je True") elif izjava2: print("izjava2 je True") else: print("izjava1 i izjava2 su False") # In[58]: izjava1 = izjava2 = True if izjava1: if izjava2: print("i izjava1 i izjava2 su True") # In[59]: for x in range(4): #range počinje od 0 print(x) # In[60]: for word in ["Znanstvenici", "vole", "koristiti", "python"]: print(word) # In[61]: for key, value in params.items(): # print(key + " = " + str(value)) isto ispisuje ali je teže čitati kod print("{} = {}".format(key,str(value))) # In[62]: # kreiranje liste na elegantniji način pomoću for petlje l1 = [x**2 for x in range(0,5)] print(l1) # In[63]: i = 0 while i < 5: print(i) i = i + 1 print("gotovo") # ## Klase # # Smisao klasa (tj. objektnog programiranja) je da omogući grupiranje varijabli i pripadnih funkcija koje rade s njima. # In[64]: class Point: """ Jednostavna klasa koja služi za rad s točkama u Euklidskoj ravnini. """ def __init__(self, x, y): """ Kreiranje točke s koordinatama x i y. """ self.x = x self.y = y def translate(self, dx, dy): """ Translacija točke za dx u smjeru x-osi i dy u smjeru y-osi. """ self.x += dx self.y += dy def __str__(self): """ Prikaz točke. """ return("Point at [{:f}, {:f}]".format(self.x, self.y)) # Funkcija oblika `__imeFunkcija__` obično implementira neku standardnu metodu za odgovarajući tip podataka. # # + `__init__`služi za kreiranje objekta dane klase # + `__str__`služi za ispisivanje objekta # + s matematičkog aspekta je važno da se mogu definirati i matematičke operacije nad objektima, kao npr. zbrajanje, množenje,... # In[65]: # ako smo zaboravili definirati metodu pri kreiranju klase def add(self, other): return Point(self.x + other.x,self.y + other.y) Point.__add__ = add # In[66]: p1 = Point(1,1) p1.translate(2,3.5) p2 = Point (2,3.5) # In[67]: print(p1) print(p2) print(p1 + p2) # ## Moduli # # Moduli (ono što učitavamo s *import*) strukturom su ili datoteke (s nastavkom *.py*) koje na početku imaju *doc string* (komentar) koji opisuje modul. # # Primjer modula uz korištenje Jupyter magije. # In[68]: get_ipython().run_cell_magic('file', 'mojmodul.py', '\n# -*- coding: utf-8 -*-\n"""\nPrimjer modula. Sadrži varijablu my_variable,\nfunkciju my_function te klasu MyClass.\n"""\nmy_variable = 0\ndef my_function():\n """\n Primjer funkcije\n """\n return my_variable\nclass MyClass:\n """\n Primjer klase\n """\n def __init__(self):\n self.variable = my_variable \n def set_variable(self, new_value):\n """\n Daje novu vrijednost varijabli self.variable\n """\n self.variable = new_value \n def get_variable(self):\n return self.variable\n') # In[69]: import mojmodul help(mojmodul) # ## Paketi # # To su kompleksniji moduli, koji su strukturirani kao dorektoriji, s datotekom *`__init__.py`*. # ## Lovljenje grešaka # In[70]: raise Exception("opis greške") # In[71]: try: # varijabla varijabla nije definirana print(varijabla) except: print("Opa!") # ## Jupyter interactive # Jupyter notebook podržava i interaktivan rad. Dokumentaciju možete [ovdje](https://github.com/ipython/ipywidgets) pogledati. Za sada ćemo samo napraviti jedan primjer. # In[80]: from ipywidgets import interact import matplotlib.pyplot as plt import networkx as nx # In[81]: def random_lobster(n, m, k, p): return nx.random_lobster(n, p, p / m) def powerlaw_cluster(n, m, k, p): return nx.powerlaw_cluster_graph(n, m, p) def erdos_renyi(n, m, k, p): return nx.erdos_renyi_graph(n, p) def newman_watts_strogatz(n, m, k, p): return nx.newman_watts_strogatz_graph(n, k, p) def plot_random_graph(n, m, k, p, generator): g = generator(n,m, k, p) nx.draw(g) plt.show() # In[79]: interact(plot_random_graph, n=(2,30), m=(1,10), k=(1,10), p=(0.0, 1.0, 0.001), generator={'lobster': random_lobster, 'power law': powerlaw_cluster, 'Newman-Watts-Strogatz': newman_watts_strogatz, u'Erdős-Rényi': erdos_renyi, }); # In[75]: from verzije import * from IPython.display import HTML HTML(print_sysinfo()+info_packages('matplotlib,IPython,scikit-image,networkx')) # ## Zadaci za vježbu # 1. Napišite funkciju koja prima n, a vraća listu neparnih brojeva od 1 do n. # 2. Napišite funkciju koja rješava kvadratnu jednadžbu. # 3. Napišite funkciju koja numerički računa integral funkcije koristeći trapeznu formulu # $$ \int_a^b f(x)\approx \frac{h}{2}\sum_{i=1}^n (f(x_{i-1})+f(x_i)). $$ # Funkcija treba ovako izgledati: # ```trapezint(f,n,a,b)``` # 4. Napišite funkciju za numeričko deriviranje oblika # ```diff(f,x,h=1e-6)```