#!/usr/bin/env python # coding: utf-8 # In[6]: import numpy as np import matplotlib.pyplot as plt from numpy import array, cos, sin # In[1]: get_ipython().run_line_magic('matplotlib', 'inline') # #### For loop and break # In[47]: for i in range(20): print(i) if i > 30: break else: print("maximum number of iteration reached") # ## Multiple assignments, comparisons # assigment: `a=b=c=0`, `a,b = b,a`, `a=0` does not return anything # In[48]: a = b = 3 # In[49]: print(a,b) # In[50]: a = b = [] # In[51]: a is b # In[52]: a,b = 3,4 # In[53]: print(a,b) # In[54]: a,b = b,a # In[55]: print(a,b) # In[58]: a,b,c,d = 1,2,3,"asf" # In[57]: ((a,b),c) = ((2,3),4) # In[60]: (a = 2) == 3 # illegal! # In[61]: 1/0 # In[62]: $# # In[63]: 1/0 $# # In[66]: array(1)/array(0) # In[65]: 1./0. # In[ ]: # In[ ]: # multiple comparison: ` 0 < x < 1` # In[68]: x = .5 print(0 < x < 1) print( (0 100: break else: print("Algorithm did not converge in %s steps" % max_iter) # ## Plotting # `plot` labels and legends # In[71]: xs = linspace(0,1,200) plot(xs, cos(xs), label='cos') plot(xs, sin(xs), label='sin') legend() savefig('sincos.pdf') # ## Function # Docstrings! (triple quotes) # In[72]: def my_function(): """ my_function is a super function more information here that's enough """ print("Hi! How are you?") # In[73]: get_ipython().run_line_magic('pinfo', 'my_function') # Return multiple values # Functions always return `None` # Function arguments: named, default, star operations (varargs) # In[113]: def power_function(a,b): return a**b # In[114]: power_function(2,3) # In[115]: param_list = [2,3] # In[116]: power_function(*param_list) # In[119]: power_function(array([2,3]), array([3,4])) # In[120]: power_function(*[3,4]) # In[123]: param_dict = { 'b': 3, 'c': 2} # In[124]: power_function(**param_dict) # In[125]: get_ipython().run_line_magic('pinfo2', 'power_function') # In[126]: power_function(b=3, a=2) # In[127]: b, a = 2, 3 # In[ ]: power_function(a=b, b=a) # In[128]: def nice_function(a, b=3): return a**b # In[129]: nice_function(2) # In[130]: nice_function(2, b=5) # In[131]: nice_function(2,5) # In[141]: def super_function(a,b,*args, **kwargs): print(args) print(kwargs) # In[139]: super_function(2,3,"hello",c=4,d=10) # In[134]: super_function(2,a=4,4,b=10) # In[144]: def append_function(a, b=[]): b.append(a) return b # In[145]: append_function(3,[4,5,6]) # In[146]: append_function(3) # In[147]: append_function(4) # closure example # In[91]: def sin_freq(freq, x): return sin(2*pi*freq*x) # In[92]: def get_sin_with_freq(freq): def sin_freq(x): return sin(2*pi*freq*x) return sin_freq # In[93]: sin10 = get_sin_with_freq(10) # In[94]: xs = linspace(0,1,200) plot(xs, sin10(xs)) # ## Generators # Generators: `enumerate`, `range`, `reversed` # ## Exceptions # In[148]: def divide(a,b): if b == 0: raise Exception("Oops, b is zero") return a/b # In[149]: divide(3,4) # In[150]: divide(3,0) # In[ ]: # ## Namespaces, imports # Namespaces, `import`, `%run`, etc. # In[95]: import example # In[96]: example.J # In[97]: example.imported_function(2.) # In[98]: get_ipython().run_line_magic('run', 'example.py') # In[99]: imported_function(2.) # In[156]: from example import bisect as example_bisect # In[182]: class Example: pass example = Example() # In[159]: example.bisect = example_bisect # In[ ]: # In[101]: from example import * # In[102]: import example1 import example2 example1.imported_function example2.imported_function # In[103]: a = 0 a = 1 # In[104]: example = 10 # In[105]: import example as ex # In[106]: ex.imported_function # ## Arrays # array length is fixed: `v[:2] = array([1])`, or `v.append` # flags? # Boolean arrays: mask, example with `rand(10,10)` and capping at `.5` # In[160]: M = np.random.randn(5,5) # In[161]: print(M) # In[163]: mask = M > 0 print(mask) # In[165]: M[mask] = 100 # In[166]: M # In[167]: M[M<0] = -100 print(M) # array comparison # In[168]: M # In[169]: M == M # In[171]: if (M == M).all(): print("M is equal to itself!") # `vectorize` example with `sign`? # In[173]: def sign(x): if x < 0: return -1 else: return 1 # In[174]: data = np.arange(5)-2 # In[175]: data # In[177]: vsign = np.vectorize(sign) # In[178]: vsign(data) # In[176]: sign(data) # reshape with -1 # `solve`!! # In[110]: M = array([[1.,2.], [3.,4.]]) V = array([2.,3.]) # In[111]: print(M, V) # In[116]: x = solve(M, V) # solves dot(M,x) == V # In[117]: allclose(dot(M,x), V) # No direct array comparision, use `all`, `A < .75 & A > .25` # Views? # Broadcasting! # In[123]: print(M, V) # In[124]: M * V # ## Exceptions # ## Object oriented programming # Objects: example with `Complex`, `__init__`, `__add__`. # In[217]: class Complex: def __init__(self, x, y): print("init!") self.r = x self.i = y def abs(self): return np.sqrt(self.r**2 + self.i**2) def __add__(self, zz): return Complex(self.r + zz.r, self.i + zz.i) def __str__(self): return "%s + %s J" % (self.r, self.i) def __repr__(self): return "Complex({},{})".format(self.r, self.i) # In[218]: z = Complex(1.,2.) # In[219]: z2 = Complex(10., 20.) z.__add__(z2) # In[216]: z + z2 # In[202]: z * z2 # In[193]: z.abs() # In[192]: z.r,z.i # In[186]: z.__dict__ # ## Performance # In[223]: def big_loop(): s = 0 for i in range(10000): s = s + np.sqrt(i) # In[221]: get_ipython().run_line_magic('prun', 'big_loop()') # In[224]: get_ipython().run_line_magic('timeit', 'big_loop()') # In[44]: get_ipython().run_line_magic('pinfo', '%prun') # In[227]: import datetime # In[250]: tic = datetime.datetime.now() big_loop() toc = datetime.datetime.now() print(toc - tic) # ## Numba # In[251]: def get_grid(nh,nv): x = np.linspace(-2,.8,nh) y = np.linspace(-1.4,1.4,nv) return np.meshgrid(x,y,indexing='ij') # In[253]: def mandel_py(w,h,maxit=20): # prepare initial points x, y = get_grid(w,h) c = x+y*1j # where to store output output = np.zeros(c.shape, dtype=int) + maxit for i in range(h): # loop 1 for j in range(w): # loop 2 z = 0. c0 = c[i,j] for k in range(maxit): # loop 3!! z = z**2 + c0 if z*z.conjugate() > 4.0: output[i, j] = k break return output.T # In[264]: nb.jit(nopython=True)(mandel_py)(200,200) # In[265]: def mandel_np(w,h,maxit=20): # prepare initial points x, y = get_grid(w,h) c = x+y*1j # where to store output output = np.zeros_like(c, dtype=int) + maxit z = np.zeros_like(c) for k in range(maxit): z = z**2 + c mask = z*z.conjugate() <= 4.0 output[mask] = k return output.T # In[266]: plt.imshow(mandel_py(200,200)) # In[262]: get_ipython().run_line_magic('timeit', 'mandel_np(200,200)') # In[147]: get_ipython().run_line_magic('pinfo', 'zeros_like') # In[150]: get_ipython().run_line_magic('timeit', 'mandel_py(200,200)') # In[256]: import numba as nb # In[257]: def mandel_raw(grid, output,maxit): for i in range(grid.shape[0]): # loop 1 for j in range(grid.shape[1]): # loop 2 z = 0.+0j c0 = grid[i,j] for k in range(maxit): # loop 3!! z = z**2 + c0 if z.real*z.real + z.imag*z.imag > 4.0: output[i, j] = k break mandel_nb = nb.jit('void(c16[:,:],i8[:,:],i8)', nopython=True)(mandel_raw) def mandel_opt(w,h,maxit=20): x, y = get_grid(w,h) grid = x+y*1j output = np.zeros_like(grid, dtype=int) + maxit mandel_nb(grid,output,maxit) return output.T # In[260]: get_ipython().run_line_magic('timeit', 'mandel_opt(200,200)') # In[259]: plt.imshow(mandel_opt(200,200)) # In[ ]: # In[155]: imshow(mandel_py(200,200)) # In[156]: get_ipython().run_line_magic('prun', 'mandel_py(200,200)') # ## Testing? # In[ ]: