Python is (like many script languages) very intuitive.
The open-source Python programming language [...] now surpasses that of its open-source and proprietary peers, according to a study published by development testing vendor Coverity.
Doing mathematical programming in a general-purpose language is easier than doing general-purpose programming in a mathematical language.
print('Hello world!') a = 42 # integer b = 42 / 21 + 10 # = 12 my_list = [1, 3, 'Hello World!'] # list: all types permitted! print(my_list[0]) # 0-based indexing for i in range(4): # i in 0,...,3 print(i) for elem in my_list: print(elem) d = { 'Hallo': 'hello', # dictionary ("map") 'Welt': 'world', 42: 'fourty-two'} print(d['Hallo']) # -> hello tuple = (4,3,1) if tuple == (4,): # easy to compare! print('yeah')
# mymodule.py def square(a): # functions can be defined anywhere return a*a # with arbitrary names (like variables) def arnoldi(A, v, maxiter=10, ortho='mgs'): # default arguments # compute V, H return V, H # multiple return arguments
import mymodule # import is possible anywhere in the code print( mymodule.square(3) )
from mymodule import square, arnoldi print( square(3) ) V, H = arnoldi(A, v, ortho='house') # maxiter is set to default (10)
Do everything yourself!
I want control!
You cannot trust 3rd party software!
Never share your code with anyone!
That's how we've always done it!
Jimmy on his way to Mars
We should no longer encourage or even allow our graduate students to write their programs from scratch; rather, they should build on what's already there.
NumPy is the basis package for numerics (based on BLAS, LAPACK, etc.).
from numpy import array, ones, dot # N-dim Arrays v = array([1,2,3]) # 1-dim arr, shape==(3,) v = ones(5) # 1-dim arr, shape==(5,) v = ones((5,1)) # 2-dim arr, shape==(5,1) A = array([[1,2,3],[4,5,6]]) # 2x3-matrix: 2-dim arr, shape==(2,3) A = ones((5,5)) # 5x5-matrix: 2-dim arr, shape==(5,5) b = dot(A, v) # A*v
The default data type in NumPy are NumPy arrays; there are also NumPy matrices. The main difference is that one can use the *-operator for matrix-matrix multiplication (as in MATLAB). Many (especially the NumPy community) recommend NumPy arrays.
Well-known commands in NumPy:
MATLAB's \-operator: solve(A, b).
For more info, see NumPy documentation.
Interesting for us:
For more info, see SciPy documentation.
from matplotlib import pyplot as pp data = [x**2 for x in range(100)] # list comprehension! pp.plot(data) pp.show()
LaTeX-integration via matplotlib2tikz.
import sympy as smp x, y = smp.symbols('x, y') f = x**2 + sin(x) * y diff(f, x) diff(f, x, 2)full-featured computer algebra system
J = [ X(NODES(2),1)-X(NODES(1),1) , X(NODES(3),1)-X(NODES(1),1) ; X(NODES(2),2)-X(NODES(1),2) , X(NODES(3),2)-X(NODES(1),2) ]; AbsDetJ = abs( J(1,1)*J(2,2) - J(1,2)*J(2,1) ) ; L = (eps/(2*AbsDetJ)) * [ J(1,2)^2 + J(2,2)^2 , - J(1,1)*J(1,2) - J(2,1)*J(2,2) ; 0 , J(1,1)^2 + J(2,1)^2 ]; A = z3A(1,1) = L(1,1) + 2*L(1,2) + L(2,2) + AbsDetJ/12 ; A(1,2) = - L(1,1) - L(1,2) + AbsDetJ/24 ; A(1,3) = - L(1,2) - L(2,2) + AbsDetJ/24 ; A(2,1) = - L(1,1) - L(1,2) + AbsDetJ/24 ; A(2,2) = L(1,1) + AbsDetJ/12 ; A(2,3) = L(1,2) + AbsDetJ/24 ; A(3,1) = - L(1,2) - L(2,2) + AbsDetJ/24 ; A(3,2) = L(1,2) + AbsDetJ/12 ; A(3,3) = L(2,2) + AbsDetJ/12 ;
for r=1:size(ECT,1) localStiffnessMatrix = local_assemble(ECT(r,:),X,eps); for alpha=1:3 i = ECT(r,alpha); for beta= 1:3 j = ECT(r,beta); K(i,j) = K(i,j) + localStiffnessMatrix(alpha,beta); end end endStill missing:
Always stay as high-level as possible.
from dolfin import * # Create mesh and define function space mesh = UnitSquareMesh(20, 20) V = FunctionSpace(mesh, 'Lagrange', 1) # Define boundary conditions u0 = Expression('1 + x[0]*x[0] + 2*x[1]*x[1]') def u0_boundary(x, on_boundary): return on_boundary bc = DirichletBC(V, u0, u0_boundary)
[...] # Define variational problem u = TrialFunction(V) v = TestFunction(V) f = Constant(-6.0) a = inner(nabla_grad(u), nabla_grad(v))*dx L = f*v*dx # Compute solution u = Function(V) solve(a == L, u, bc) # Plot solution and mesh plot(u) plot(mesh) # Dump solution to file in VTK format file = File('poisson.pvd') file << u # Hold plot interactive()
prm = parameters['krylov_solver'] # short form prm['absolute_tolerance'] = 0.0 prm['relative_tolerance'] = 1E-13 prm['maximum_iterations'] = 10000 prm['monitor_convergence'] = True solve(a == L, u, [bc0, bc1], solver_parameters={'linear_solver': 'cg', 'preconditioner': 'ilu'} )
from dolfin import * parameters['linear_algebra_backend'] = 'uBLAS' [...] a = inner(nabla_grad(u), nabla_grad(v))*dx L = f*v*dx + g*v*ds A = assemble(a, bcs=[bc0,bc1]) b = assemble(L, bcs=[bc0,bc1])Output:
$ python ex5.py (array([ 0, 3, 8, ..., 11433, 11438, 11441]), array([ 0, 1, 2, ..., 1678, 1679, 1680]), array([ 1. , -0.5, -0.5, ..., 0. , 0. , 1. ])) [ 0.00114583 0.0065625 0. ..., 0. 1. 1. ]
UnitSquare(4, 4) UnitCube(4, 4, 4) Rectangle(a, 0, b, 1, nr, nt, 'crossed') [...]
$ dolfin-convert mymesh.msh mymesh.xml dolfin-convert mymesh.msh mymesh.xml Converting from Gmsh format (.msh, .gmsh) to DOLFIN XML format Expecting 2001 vertices Found all vertices Expecting 10469 cells Found all cells Conversion done $ ls mymesh*.xml mymesh_physical_region.xml mymesh.xmlThen: Run Dolfin with those XML meshes.
a = u*v*dx + dt*inner(grad(u), grad(v))*dx L = y_1*v*dx + dt*f*v*dx while t < T: solve(a == L, y) t += dt y_1.assign(y)
Questions?