29Approximation3.1 Sources of approximation error 3 … · 2017. 2. 13. · 42Approximation3.2...
Transcript of 29Approximation3.1 Sources of approximation error 3 … · 2017. 2. 13. · 42Approximation3.2...
29 Approximation 3.1 Sources of approximation error
3 Approximation in Scientific Computing
3.1 Sources of approximation error
3.1.1 Error sources that are under our control
MODELLING ERRORS – some physical entities in the model are simplified or evennot taken into account at all (for example: air resistance, viscosity, friction etc)
(Usually it is OK but sometimes not... )(You may want to look: http://en.wikipedia.org/wiki/Spherical_cow :-)
30 Approximation 3.1 Sources of approximation error
MEASUREMENT ERRORS – laboratory equipment has its precision
Errors come also out of
• random measurement deviation
• backward noise
As an example, Newton and Planck constants are used with 8-9 decimal places whilelaboratory measurements are performed with much less precision!
THE EFFECT OF PREVIOUS CALCULATIONS – the input for calculations isoften already output of some previous calculation with some computational errors
31 Approximation 3.1 Sources of approximation error
3.1.2 Errors created during the calculations
Discretisation
As an example:
• replacing derivatives with finite differences
• finite sums used instead of infinite series
• etc
Round-off errors – error created during the calculations due to limited available pre-cision, which the calcualtions are performed with
32 Approximation 3.1 Sources of approximation error
Example 4.1
Suppose, a computer program can find function f value f (x) for arbitrary x.Task: find an algorithm for calculating approximation to the derivative f ′(x)Algorithm: Choose small h > 0 and approximate:
f ′(x)≈ [ f (x+h)− f (x)]/h
Discretisation error is:
T := | f ′(x)− [ f (x+h)− f (x)]/h|.
Using Taylor series, we get an estimation:
T ≤ h2
∥∥ f ′′∥∥
∞. (1)
33 Approximation 3.1 Sources of approximation error
Computational error is created using finite precision arithmetics approximatingthe real f (x) with an approximation f (x). Computational error C is:
C =
∣∣∣∣ f (x+h)− f (x)h
− f (x+h)− f (x)h
∣∣∣∣=
∣∣∣∣ [ f (x+h)− f (x+h)]− [ f (x)− f (x)]h
∣∣∣∣ ,which gives an estimate:
C ≤ 2h‖ f − f‖∞. (2)
The resulting error is ∣∣∣∣ f ′(x)− f (x+h)− f (x)h
∣∣∣∣ ,which can be estimated using (1) and (2):
T +C ≤ h2‖ f ′′‖∞ +
2h‖ f − f‖∞. (3)
34 Approximation 3.1 Sources of approximation error
=⇒ if h is large – the discretisation error is dominating, if h is small, computationalerror starts dominating.
3.1.3 Forward error (arvutuslik viga e. tulemuse viga) and backward error(algandmete viga)
Consider computing y = f (x). Usually we can only compute an approximation ofy, we denote the approximately calculated value by y. We can observe two measuresof the error associated with this computation.
Forward error
The forward error is a measure of the difference between the approximation y andthe true value y:
absolute forward error: |y− y|relative forward error: |y−y|
|y|
35 Approximation 3.1 Sources of approximation error
The forward error would be a natural quantity to measure, but usually (since wedon’t know the actual value of y) we can only get an upper bound on it. Moreover,tight upper bounds on it can be very difficult.
Backward error
The question we might want to ask: For what input data we actually performed thecalculations? We would like to find the smallest ∆x for which
y = f (x+∆x)
– Here we have y as the exact value of f (x+∆x). The value |∆x| (or |∆x||x| ) is called
backward error. This means, backward error is the one which we have in the input.(Like the forward error is the error we observe in the output of the calculations or analgorithms.)
36 Approximation 3.1 Sources of approximation error
Condition number – upper limit of their ratio:
forward error≤ condition number×backward error
From (2) it follows that in Example 4.1 the value of condition number is: 2/h.In given calculations all the values are absolute: actual values of the approximated
entities are not considered. Relative forward error and relative backward error are inthis case:
C|( f (x+h)− f (x))/h|
and‖ f − f‖∞
‖ f‖∞
.
Assuming that minx | f ′(x)|> 0, it follows easily from (2), that:
C|( f (x+h)− f (x))/h|
≤{
2h‖ f‖∞
minx | f ′(x)|
}‖ f − f‖∞
‖ f‖∞
.
37 Approximation 3.1 Sources of approximation error
The value in the brackets {·} is called relative condition number of the problem.In general:
• If (absolute or relative) condition number is small,
– then (absolute or relative) error in the input data can produce only a smallerror in the result.
• If condition number is large
– then large error in the result can be caused even by a small error in theinput data
– such problems are said to be ill-conditioned
38 Approximation 3.1 Sources of approximation error
• Sometimes, in the case of finite precision arithmetics:
– backward error is much more simple to estimate than forward error
– Backward error combined with condition number makes it possibe to esti-mate the forward error (absolute or relative)
39 Approximation 3.1 Sources of approximation error
Example 4.2 (One of the key problems in Scientific Computing)Consider solving the system of linear equations:
Ax = b, (4)
where the input consists of
• nonsingular n×n matrix A
• b ∈ Rn
The task is to calculate – an approximate solution: x ∈ Rn.Suppose, instead of exact matrix A – given its approximation A = A+δA, but (for
simplicity) b known exactly. The solution x = x+δx satisfies the system of equations
(A+δA)(x+δx) = b. (5)
40 Approximation 3.1 Sources of approximation error
Then from (4),(5) it follows that
(A+δA)δx =−(δA)x.
Multiplying it with (A+δA)−1 and taking norms, we estimate
‖δx‖ ≤ ‖(A+δA)−1‖‖δA‖‖x‖.
It follows that if x 6= 0 and A 6= 0, we have:
‖δx‖‖x‖
≤ ‖(A+δA)−1‖‖A‖‖δA‖‖A‖
∼= ‖A−1‖‖A‖‖δA‖‖A‖
, (6)
which is satisfied with δA sufficiently small.
41 Approximation 3.1 Sources of approximation error
• =⇒for calculation of x an important factor is relative condition numberκ(A) := ‖A−1‖‖A‖.
– It is usually called as condition number of matrix A.
– Depends on norm ‖ · ‖
Therefore, common practice for forward error estimation is to:
• find an estimate to the backward error
• use the estimate (6)
42 Approximation 3.2 Floating-Point Numbers
3.2 Floating-Point Numbers
The number −3.1416 in scientific notation is −0.31416× 101 or (as computeroutput) -0.31416E01.
sign
exponent
−.31416 101
mantissa base
– floating point numbers in computer notation. Usually, base is 2 (with a few excep-tions like IBM 370 had a base 16; base 10 in most of hand-held calculators; 3 in anill-fated Russian computer).
For example, .101012×23 = 5.2510.(-: There are 10 kinds of people in the world – those who understand binary – and those who don’t :-)
Formally, a floating-point number system F, is characterised by four integers:
• Base (or radix) β > 1
• Precision p > 0
• Exponent range [L,U ]: L < 0 <U
43 Approximation 3.2 Floating-Point Numbers
Any floating-point number x ∈ F has the form
x =±{d0 +d1β−1 + ...+dp−1β
1−p}β E , (7)
where integers di satify
0≤ di ≤ β −1, i = 0, ..., p−1,
and E ∈ [L,U ] (E is positive, zero or negative integer). The number E is called anexponent and in the part in the brackets {·} is called mantissa
Example. In arithmetics with precision 4 and base 10 the number 2347 is repre-sented as
{2+3×10−1 +4×10−2 +7×10−3}103.
Is it possible to represent 2345 in precision 3 and base 10?Note that exact representation of 2347 in precision 3 and base 10 is not possible!
44 Approximation 3.3 Normalised floating-point numbers
3.3 Normalised floating-point numbers
A number is normalised if d0 > 0Example. The number .101012×23 is normalised, but .0101012×24 is notFloating point systems are usually normalised because:
• Representation of each number is then unique
• No digits are wasted on leading zeros
• In normalised binary (β = 2) system, the leading bit always 1 =⇒ no need tostore it!
Smallest positive normalised number in form (7) is 1×β L – underflow threashold.(In case of underflow, the result is smaller than the smallest representable floating-point number)
45 Approximation 3.3 Normalised floating-point numbers
Largest positive normalised number in form (7) is
(β −1){1+β−1 + ...+β
1−p}βU
= (1−β−p)βU+1.
– overflow threashold.If the result of an arithmetic operation is an exact number not represented in the
floating-point number system F, the result is represented as (hopefully close) elementof F. (Rounding)
46 Approximation 3.4 IEEE (Normalised) Arithmetics
3.4 IEEE (Normalised) Arithmetics
• β = 2 (binary)
• d0 = 1 always – not stored
Single precision:
• p = 24, L =−126, U = 127
• Underflow threashold = 2−126 ≈ 10−38
• Overflow threashold = 2127 · (2−2−23)≈ 2128 ≈ 1038
• One bit for sign, 23 for mantissa and 8 for exponent:
1 23 8
• – 32-bit word.
47 Approximation 3.4 IEEE (Normalised) Arithmetics
Double precision:
• p = 53, L =−1022, U = 1023
• Underflow threashold = 2−1022 ≈ 10−308
• Overflow threashold= 21023 · (2−2−52)≈ 21024 ≈ 10308
• One bit for sign, 52 for mantissa and 11 for exponent:
1 52 11
– 64-bit word
• IEEE arithmetics standard – rounding towards the nearest element in F.
• (If the result is exactly between the two elements, the rounding is towards thenumber which has the least significant bit equal to 0 – rounding towards theclosest even number)
48 Approximation 3.4 IEEE (Normalised) Arithmetics
IEEE subnormal numbers - unnormalised numbers with minimal possible expo-nent.
• Between 0 and the smallest normalised floating point value.
• Guarantees that f l(x− y) (the result of operation x− y in floating point arith-metics) in case x 6= y never zero – to avoid underflow in such situatons
IEEE symbols Inf and NaN – Inf (±∞), NaN (Not a Number)
• Inf - in case of overflow
– x/±∞ = 0 in case of arbitrary finite floating/point x
– +∞+∞ =+∞, etc.
• NaN is returned when operation does not have a well/defined finite or ininitevalue, for example
49 Approximation 3.4 IEEE (Normalised) Arithmetics
– ∞−∞
– 00
–√−1
– NaN�x (where � – one of operations: +, - , *, / ), etc
IEEE defines also double extended floating-point values
• 64 bit mantissa; 15 bit exponent
• most of the compilers do not support it
• Many platforms support also quadruple precision (double*16)
– often emulated with lower precision and therefore slow performance
50 Python in SC 4.1 Numerical Python (NumPy)
4 Python in Scientfic Computing
4.1 Numerical Python (NumPy)
• NumPy enables efficient numerical computing in Python
• NumPy is a package of modules, which offers efficient arrays (contiguous stor-age) with associated array operations coded in C or Fortran
• There are three implementations of Numerical Python
• Numeric from the mid 90s
• numarray from about 2000
• numpy from 2006 (the new and leading implementation)
• numpy (by Travis Oliphant) – recommended
51 Python in SC 4.1 Numerical Python (NumPy)
� �1 # A taste of NumPy: a least-squares procedure
2 from numpy import *3 n = 100; x = linspace(0.0, 1.0, n) # coordinates
4 y_line = -2*x + 3
5 y = y_line + random.normal(0, 0.55, n) # line with noise
6 # create and solve least squares system:
7 A = array([x, ones(n)])
8 A = A.transpose()
9 result = linalg.lstsq(A, y)
10 # result is a 4-tuple, the solution (a,b) is the 1st entry:
11 a, b = result[0]
12 p=[(x[i],y[i]) for i in range(len(x))]
13 p0 = (0,a*0 + b); p1 = (1,a*1 + b)
14 G=list_plot(p,color=’red’)+line([(0,3),(1,1)],color=’blue’)
15 G=G+line([p0, p1], color=’red’)
16 G=G+text(’Blue - original line -2*x+3’, (0.7, 3.5), color=’blue’) G=
G+text(’Red - line fitted to data’, (0.3, 0.5), color=’red’)
17 show(G) # note: retype symbols "’" when copy-pasting code to sage�
52 Python in SC 4.1 Numerical Python (NumPy)
Resulting plot:
53 Python in SC 4.1 Numerical Python (NumPy)
4.1.1 NumPy: making arrays� �>>> from numpy import *>>> n = 4
>>> a = zeros(n) # one-dim. array of length n
>>> print a # str(a), float (C double) is default type
[ 0. 0. 0. 0.]
>>> a # repr(a)
array([ 0., 0., 0., 0.])
>>> p = q = 2
>>> a = zeros((p,q,3)) # p*q*3 three-dim. array
>>> print a
[[[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]]]
>>> a.shape # a’s dimension
(2, 2, 3)�
54 Python in SC 4.1 Numerical Python (NumPy)
4.1.2 NumPy: making float, int, complex arrays� �>>> a = z e r o s ( 3 )>>> p r i n t a . dtype # a ’ s da ta t y p ef l o a t 6 4>>> a = z e r o s ( 3 , i n t )>>> p r i n t a , a . dtype[0 0 0 ] i n t 6 4( or i n t 3 2 , depend ing on a r c h i t e c t u r e )>>> a = z e r o s ( 3 , f l o a t 3 2 ) # s i n g l e p r e c i s i o n>>> p r i n t a[ 0 . 0 . 0 . ]>>> p r i n t a . dtypef l o a t 3 2>>> a = z e r o s ( 3 , complex ) ; aarray ( [ 0 . + 0 . j , 0 . + 0 . j , 0 . + 0 . j ] )>>> a . dtypedtype ( ’ complex128 ’ )�
55 Python in SC 4.1 Numerical Python (NumPy)
• Given an array a, make a new array of same dimension and data type:
� �>>> x = zeros(a.shape, a.dtype)�
4.1.3 Array with a sequence of numbers
• linspace(a, b, n) generates n uniformly spaced coordinates, startingwith a and ending with b
� �>>> x = linspace(-5, 5, 11)
>>> print x
[-5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5.]�
56 Python in SC 4.1 Numerical Python (NumPy)
• arange works like range� �>>> x = arange(-5, 5, 1, float)
>>> print x # upper limit 5 is not included
[-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]�
4.1.4 Warning: arange is dangerous
• arange’s upper limit may or may not be included (due to round-off errors)
4.1.5 Array construction from a Python list
array(list, [datatype]) generates an array from a list:� �>>> pl = [0, 1.2, 4, -9.1, 5, 8]
>>> a = array(pl)�
57 Python in SC 4.1 Numerical Python (NumPy)
• The array elements are of the simplest possible type:
� �>>> z = array([1, 2, 3])
>>> print z # int elements possible
[1 2 3]
>>> z = array([1, 2, 3], float)
>>> print z
[ 1. 2. 3.]�• A two-dim. array from two one-dim. lists:
� �>>> x = [0, 0.5, 1]; y = [-6.1, -2, 1.2] # Python lists
>>> a = array([x, y]) # form array with x and y as rows�
58 Python in SC 4.1 Numerical Python (NumPy)
• From array to list:� �alist = a.tolist()�
4.1.6 From “anything” to a NumPy array
• Given an object a,� �a = asarray(a)�
converts a to a NumPy array (if possible/necessary)
• Arrays can be ordered as in C (default) or Fortran:� �a = asarray(a, order=’Fortran’)
isfortran(a) # returns True of a’s order is Fortran�
59 Python in SC 4.1 Numerical Python (NumPy)
• Use asarray to, e.g., allow flexible arguments in functions:
� �def myfunc(some_sequence, ...):
a = asarray(some_sequence)
# work with a as array
myfunc([1,2,3], ...)
myfunc((-1,1), ...)
myfunc(zeros(10), ...)�
60 Python in SC 4.1 Numerical Python (NumPy)
4.1.7 Changing array dimensions� �>>> a = array([0, 1.2, 4, -9.1, 5, 8])
>>> a.shape = (2,3) # turn a into a 2x3 matrix
>>> a.shape
(2, 3)
>>> a.size
6
>>> a.shape = (a.size,) # turn a into a vector of length
6 again
>>> a.shape
(6,)
>>> a = a.reshape(2,3) # same effect as setting a.shape
>>> a.shape
(2, 3)�
61 Python in SC 4.1 Numerical Python (NumPy)
4.1.8 Array initialization from a Python function� �>>> def myfunc(i, j):
... return (i+1)*(j+4-i)
...
>>> # make 3x6 array where a[i,j] = myfunc(i,j):
>>> a = fromfunction(myfunc, (3,6))
>>> a
array([[ 4., 5., 6., 7., 8., 9.],
[ 6., 8., 10., 12., 14., 16.],
[ 6., 9., 12., 15., 18., 21.]])�
62 Python in SC 4.1 Numerical Python (NumPy)
4.1.9 Basic array indexing� �a = linspace(-1, 1, 6)
# array([-1. , -0.6, -0.2, 0.2, 0.6, 1. ])
a[2:4] = -1 # set a[2] and a[3] equal to -1
a[-1] = a[0] # set last element equal to first one
a[:] = 0 # set all elements of a equal to 0
a.fill(0) # set all elements of a equal to 0
a.shape = (2,3) # turn a into a 2x3 matrix
print a[0,1] # print element (0,1)
a[i,j] = 10 # assignment to element (i,j)
a[i][j] = 10 # equivalent syntax (slower)
print a[:,k] # print column with index k
print a[1,:] # print second row
a[:,:] = 0 # set all elements of a equal to 0�
63 Python in SC 4.1 Numerical Python (NumPy)
4.1.10 More advanced array indexing� �>>> a = linspace(0, 29, 30)
>>> a.shape = (5,6)
>>> a
array([[ 0., 1., 2., 3., 4., 5.,]
[ 6., 7., 8., 9., 10., 11.,]
[ 12., 13., 14., 15., 16., 17.,]
[ 18., 19., 20., 21., 22., 23.,]
[ 24., 25., 26., 27., 28., 29.,]])
>>> a[1:3,:-1:2] # a[i,j] for i=1,2 and j=0,2,4
array([[ 6., 8., 10.],
[ 12., 14., 16.]])
>>> a[::3,2:-1:2] # a[i,j] for i=0,3 and j=2,4
array([[ 2., 4.],
[ 20., 22.]])
64 Python in SC 4.1 Numerical Python (NumPy)
>>> i = slice(None, None, 3); j = slice(2, -1, 2)
>>> a[i,j]
array([[ 2., 4.],
[ 20., 22.]])�
4.1.11 Slices refer the array data
• With a as list, a[:] makes a copy of the data
• With a as array, a[:] is a reference to the data!!!� �>>> b = a[1,:] # extract 2nd column of a
>>> print a[1,1]
12.0
>>> b[1] = 2
>>> print a[1,1]
65 Python in SC 4.1 Numerical Python (NumPy)
2.0 # change in b is reflected in a�• Take a copy to avoid referencing via slices:
� �>>> b = a[1,:].copy()
>>> print a[1,1]
12.0
>>> b[1] = 2 # b and a are two different arrays now
>>> print a[1,1]
12.0 # a is not affected by change in b�
66 Python in SC 4.1 Numerical Python (NumPy)
4.1.12 Integer arrays as indices
• An integer array or list can be used as (vectorized) index� �>>> a = linspace(1, 8, 8)
>>> a
array([ 1., 2., 3., 4., 5., 6., 7., 8.])
>>> a[[1,6,7]] = 10
>>> a # ?
array([ 1., 10., 3., 4., 5., 6., 10., 10.])
>>> a[range(2,8,3)] = -2
>>> a # ?
array([ 1., 10., -2., 4., 5., -2., 10., 10.])
>>> a[a < 0] # pick out the negative elements of a
array([-2., -2.])
>>> a[a < 0] = a.max()
>>> a # ?
67 Python in SC 4.1 Numerical Python (NumPy)
array([ 1., 10., 10., 4., 5., 10., 10., 10.])�• Such array indices are important for efficient vectorized code
4.1.13 Loops over arrays
• Standard loop over each element:
� �for i in xrange(a.shape[0]):
for j in xrange(a.shape[1]):
a[i,j] = (i+1)*(j+1)*(j+2)
print ’a[%d,%d]=%g ’ % (i,j,a[i,j]),
print # newline after each row�
68 Python in SC 4.1 Numerical Python (NumPy)
• A standard for loop iterates over the first index:� �>>> print a
[[ 2. 6. 12.]
[ 4. 12. 24.]]
>>> for e in a:
... print e
...
[ 2. 6. 12.]
[ 4. 12. 24.]�• View array as one-dimensional and iterate over all elements:� �
for e in a.flat:
print e�
69 Python in SC 4.1 Numerical Python (NumPy)
• For loop over all index tuples and values:
� �>>> for index, value in ndenumerate(a):
... print index, value
...
(0, 0) 2.0
(0, 1) 6.0
(0, 2) 12.0
(1, 0) 4.0
(1, 1) 12.0
(1, 2) 24.0�
70 Python in SC 4.1 Numerical Python (NumPy)
4.1.14 Array computations
• Arithmetic operations can be used with arrays:
� �b = 3*a - 1 # a is array, b becomes array�
1) compute t1 = 3*a, 2) compute t2= t1 - 1, 3) set b = t2
71 Python in SC 4.1 Numerical Python (NumPy)
• Array operations are much faster than element-wise operations:
� �>>> import time # module for measuring CPU time
>>> a = linspace(0, 1, 1E+07) # create some array
>>> t0 = time.clock()
>>> b = 3*a -1
>>> t1 = time.clock() # t1-t0 is the CPU time of 3*a-1
>>> for i in xrange(a.size): b[i] = 3*a[i] - 1
>>> t2 = time.clock()
>>> print ’3*a-1: %g sec, loop: %g sec’ % (t1-t0, t2-t1)
3*a-1: 2.09 sec, loop: 31.27 sec�4.1.15 In-place array arithmetics
• Expressions like 3*a-1 generates temporary arrays
72 Python in SC 4.1 Numerical Python (NumPy)
• With in-place modifications of arrays, we can avoid temporary arrays (to someextent)
� �b = a
b *= 3 # or multiply(b, 3, b)
b -= 1 # or subtract(b, 1, b)�Note: a is changed, use b = a.copy()
73 Python in SC 4.1 Numerical Python (NumPy)
• In-place operations:� �a *= 3.0 # multiply a’s elements by 3
a -= 1.0 # subtract 1 from each element
a /= 3.0 # divide each element by 3
a += 1.0 # add 1 to each element
a **= 2.0 # square all elements�• Assign values to all elements of an existing array:
� �a[:] = 3*c - 1�
74 Python in SC 4.1 Numerical Python (NumPy)
4.1.16 Standard math functions can take array arguments� �# let b be an array
c = sin(b)
c = arcsin(c)
c = sinh(b)
# same functions for the cos and tan families
c = b**2.5 # power function
c = log(b)
c = exp(b)
c = sqrt(b)�
75 Python in SC 4.1 Numerical Python (NumPy)
4.1.17 Other useful array operations� �# a is an array
a.clip(min=3, max=12) # clip elements
a.mean(); mean(a) # mean value
a.var(); var(a) # variance
a.std(); std(a) # standard deviation
median(a)
cov(x,y) # covariance
trapz(a) # Trapezoidal integration
diff(a) # finite differences (da/dx)�� �# more Matlab-like functions:
corrcoeff, cumprod, diag, eig, eye, fliplr, flipud, max,
min,
prod, ptp, rot90, squeeze, sum, svd, tri, tril, triu�
76 Python in SC 4.1 Numerical Python (NumPy)
4.1.18 Temporary arrays
• Let us evaluate f1(x) for a vector x:
� �def f1(x):
return exp(-x*x)*log(1+x*sin(x))�1. temp1 = -x
2. temp2 = temp1*x
3. temp3 = exp(temp2)
4. temp4 = sin(x)
5. temp5 = x*temp4
6. temp6 = 1 + temp4
7. temp7 = log(temp5)
8. result = temp3*temp7
77 Python in SC 4.1 Numerical Python (NumPy)
4.1.19 More useful array methods and attributes� �>>> a = zeros(4) + 3
>>> a
array([ 3., 3., 3., 3.]) # float data
>>> a.item(2) # more efficient than a[2]
3.0
>>> a.itemset(3,-4.5) # more efficient than a[3]=-4.5
>>> a
array([ 3. , 3. , 3. , -4.5])
>>> a.shape = (2,2)
>>> a
array([[ 3. , 3. ],
[ 3. , -4.5]])
78 Python in SC 4.1 Numerical Python (NumPy)
>>> a.ravel() # from multi-dim to one-dim
array([ 3. , 3. , 3. , -4.5])
>>> a.ndim # no of dimensions
2
>>> len(a.shape) # no of dimensions
2
>>> rank(a) # no of dimensions
2
>>> a.size # total no of elements
4
>>> b = a.astype(int) # change data type
>>> b
array([3, 3, 3, 3])�
79 Python in SC 4.1 Numerical Python (NumPy)
4.1.20 Complex number computing� �>>> from math import sqrt
>>> sqrt(-1) # ?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
>>> from numpy import sqrt
>>> sqrt(-1) # ?
Warning: invalid value encountered in sqrt
nan
>>> from cmath import sqrt # complex math functions
>>> sqrt(-1) # ?
1j
>>> sqrt(4) # cmath functions always return complex...
(2+0j)
80 Python in SC 4.1 Numerical Python (NumPy)
>>> from numpy.lib.scimath import sqrt
>>> sqrt(4)
2.0 # real when possible
>>> sqrt(-1)
1j # otherwise complex�
81 Python in SC 4.1 Numerical Python (NumPy)
4.1.21 A root function� �# Goal: compute roots of a parabola, return real when possible,
# otherwise complex
def roots(a, b, c):
# compute roots of a*x^2 + b*x + c = 0
from numpy.lib.scimath import sqrt
q = sqrt(b**2 - 4*a*c) # q is real or complex
r1 = (-b + q)/(2*a)
r2 = (-b - q)/(2*a)
return r1, r2
>>> a = 1; b = 2; c = 100
>>> roots(a, b, c) # complex roots
((-1+9.94987437107j), (-1-9.94987437107j))
>>> a = 1; b = 4; c = 1
>>> roots(a, b, c) # real roots
(-0.267949192431, -3.73205080757)�
82 Python in SC 4.1 Numerical Python (NumPy)
4.1.22 Array type and data type� �>>> import numpy
>>> a = numpy.zeros(5)
>>> type(a)
<type ’numpy.ndarray’>
>>> isinstance(a, ndarray) # is a of type ndarray?
True
>>> a.dtype # data (element) type object
dtype(’float64’)
>>> a.dtype.name
’float64’
>>> a.dtype.char # character code
’d’
>>> a.dtype.itemsize # no of bytes per array element
8
83 Python in SC 4.1 Numerical Python (NumPy)
>>> b = zeros(6, float32)
>>> a.dtype == b.dtype # do a and b have the same data type?
False
>>> c = zeros(2, float)
>>> a.dtype == c.dtype
True�
84 Python in SC 4.1 Numerical Python (NumPy)
4.1.23 Matrix objects
• NumPy has an array type, matrix, much like Matlab’s array type� �>>> x1 = array([1, 2, 3], float)
>>> x2 = matrix(x) # or just mat(x)
>>> x2 # row vector
matrix([[ 1., 2., 3.]])
>>> x3 = mat(x).transpose() # column vector
>>> x3
matrix([[ 1.],
[ 2.],
[ 3.]])
>>> type(x3)
<class ’numpy.core.defmatrix.matrix’>
>>> isinstance(x3, matrix)
True�
85 Python in SC 4.1 Numerical Python (NumPy)
• Only 1- and 2-dimensional arrays can be matrix
• For matrix objects, the * operator means matrix-matrix or matrix-vector multi-plication (not elementwise multiplication):� �
>>> A = eye(3) # identity matrix
>>> A = mat(A) # turn array to matrix
>>> A
matrix([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
>>> y2 = x2*A # vector-matrix product
>>> y2
matrix([[ 1., 2., 3.]])
>>> y3 = A*x3 # matrix-vector product
>>> y3
matrix([[ 1.],
[ 2.],
[ 3.]])�
86 Python in SC 4.2 NumPy: Vectorisation
4.2 NumPy: Vectorisation
• Loops over an array run slowly
• Vectorization = replace explicit loops by functions calls such that the whole loopis implemented in C (or Fortran)
• Explicit loops:� �r = zeros(x.shape, x.dtype)
for i in xrange(x.size):
r[i] = sin(x[i])�• Vectorised version:� �
r = sin(x)�
87 Python in SC 4.2 NumPy: Vectorisation
• Arithmetic expressions work for both scalars and arrays
• Many fundamental functions work for scalars and arrays
• Ex: x**2 + abs(x) works for x scalar or array
A mathematical function written for scalar arguments can (normally) take a arrayarguments:� �>>> def f(x):
... return x**2 + sinh(x)*exp(-x) + 1
...
>>> # scalar argument:
>>> x = 2
>>> f(x)
5.4908421805556333
>>> # array argument:
>>> y = array([2, -1, 0, 1.5])
88 Python in SC 4.2 NumPy: Vectorisation
>>> f(y)
array([ 5.49084218, -1.19452805, 1. ,
3.72510647])�
4.2.1 Vectorisation of functions with if tests; problem
• Consider a function with an if test:� �def somefunc(x):
if x < 0:
return 0
else:
return sin(x)
# or
def somefunc(x): return 0 if x < 0 else sin(x)�
89 Python in SC 4.2 NumPy: Vectorisation
• This function works with a scalar x but not an array
• Problem: x<0 results in a boolean array, not a boolean value that can be used inthe if test� �
>>> x = linspace(-1, 1, 3); print x
[-1. 0. 1.]
>>> y = x < 0
>>> y
array([ True, False, False], dtype=bool)
>>> ’ok’ if y else ’not ok’ # test of y in scalar
boolean context
...
ValueError: The truth value of an array with more than
one
element is ambiguous. Use a.any() or a.all()�
90 Python in SC 4.2 NumPy: Vectorisation
4.2.2 Vectorisation of functions with if tests; solutions
A. Simplest remedy: call NumPy’s vectorize function to allow array arguments toa function:� �>>> somefuncv = vectorize(somefunc, otypes=’d’)
>>> # test:
>>> x = linspace(-1, 1, 3); print x
[-1. 0. 1.]
>>> somefuncv(x) # ?
array([ 0. , 0. , 0.84147098])�Note: The data type must be specified as a character
• The speed of somefuncv is unfortunately quite slow
91 Python in SC 4.2 NumPy: Vectorisation
B. A better solution, using where:� �def somefunc_NumPy2(x):
x1 = zeros(x.size, float)
x2 = sin(x)
return where(x < 0, x1, x2)�
92 Python in SC 4.2 NumPy: Vectorisation
4.2.3 General vectorization of if-else tests� �def f(x): # scalar x
if condition:
x = <expression1>
else:
x = <expression2>
return x�� �def f_vectorized(x): # scalar or array x
x1 = <expression1>
x2 = <expression2>
return where(condition, x1, x2)�
93 Python in SC 4.2 NumPy: Vectorisation
4.2.4 Vectorization via slicing
• Consider a recursion scheme (which arises from a one-dimensional diffusionequation)
• Straightforward (slow) Python implementation:
� �n = size(u)-1
for i in xrange(1,n,1):
u_new[i] = beta*u[i-1] + (1-2*beta)*u[i] + beta*u[i+1]�• Slices enable us to vectorize the expression:
� �u[1:n] = beta*u[0:n-1] + (1-2*beta)*u[1:n] + beta*u[2:n+1]�
94 Python in SC 4.3 NumPy: Random numbers
4.3 NumPy: Random numbers
• Drawing scalar random numbers:� �import random
random.seed(2198) # control the seed
print ’uniform random number on (0,1):’, random.random()
print ’uniform random number on (-1,1):’, random.uniform(-1,1)
print ’Normal(0,1) random number:’, random.gauss(0,1)�• Vectorized drawing of random numbers (arrays):� �
from numpy import random
random.seed(12) # set seed
u = random.random(n) # n uniform numbers on (0,1)
u = random.uniform(-1, 1, n) # n uniform numbers on (-1,1)
u = random.normal(m, s, n) # n numbers from N(m,s)�
95 Python in SC 4.3 NumPy: Random numbers
• Note that both modules have the name random! A remedy:
� �import random as random_number # rename random for scalars
from numpy import * # random is now numpy.random�
96 Python in SC 4.4 NumPy: Basic linear algebra
4.4 NumPy: Basic linear algebra
NumPy contains the linalg module for
• solving linear systems
• computing the determinant of a matrix
• computing the inverse of a matrix
• computing eigenvalues and eigenvectors of a matrix
• solving least-squares problems
• computing the singular value decomposition of a matrix
• computing the Cholesky decomposition of a matrix
97 Python in SC 4.4 NumPy: Basic linear algebra
4.4.1 A linear algebra session� �1 from numpy import * # includes import of linalg
2 n=100 # fill matrix A and vectors x and b:
3 A=random.uniform(0.0,1.0,(n,n)); x=random.uniform(-1,1,n)
4 b = dot(A, x) # matrix-vector product
5 y = linalg.solve(A, b) # solve A*y = b
6 if allclose(x, y, atol=1.0E-12, rtol=1.0E-12):
7 print ’--correct solution’
8 d = linalg.det(A); B = linalg.inv(A)
9 # check result:
10 R = dot(A, B) - eye(n) # residual
11 R_norm = linalg.norm(R) # Frobenius norm of matrix R
12 print ’Residual R = A*A-inverse - I:’, R_norm
13 A_eigenvalues = linalg.eigvals(A) # eigenvalues only
14 A_eigenvalues, A_eigenvectors = linalg.eig(A)
15 for e, v in zip(A_eigenvalues, A_eigenvectors):
16 print ’eigenvalue %g has corresponding vector\n%s’ % (e, v)�
98 Python in SC 4.5 Python: Plotting modules
4.5 Python: Plotting modules
By default python environments come with:
• Interface to Gnuplot (curve plotting, 2D scalar and vector fields)
• Matplotlib (curve plotting, 2D scalar and vector fields)
• 3D: Tachyon (ray-tracing) Jmol (interactive plotting)
Available Python interfaces to:
• Interface to Vtk (2D/3D scalar andvector fields)
• Interface to OpenDX (2D/3D scalarand vector fields)
• Interface to IDL
• Interface to Grace
• Interface to Matlab
• Interface to R
• Interface to Blender
• PyX (PostScript/TEX-like drawing)
99 Python in SC 4.5 Python: Plotting modules
� �from numpy import *n = 100 ; x = linspace(0.0, 1.0, n); y = linspace(0.0,
1.0, n)
a=-2; b=3; c=7
z_line = a*x +b*y + c
rscal=0.05
xx = x + random.normal(0, rscal, n)
yy = y + random.normal(0, rscal, n)
zz = z_line + random.normal(0, rscal, n)
A = array([xx, yy, ones(n)])
A = A.transpose()
result = linalg.lstsq(A, zz)
aa, bb, cc = result[0]
p0 = (x[0], y[0], a*x[0]+b*y[0]+c)
p1 = (x[n-1],y[n-1],a*x[n-1]+b*y[n-1]+c)
100 Python in SC 4.5 Python: Plotting modules
pp=[(xx[i],yy[i],zz[i]) for i in range(len(x))]
p=[(x[i],y[i],z_line[i]) for i in range(len(x))]
pp0 = (xx[0], yy[0], aa*xx[0]+bb*yy[0]+cc); pp1 = (xx[n
-1],yy[n-1],aa*xx[n-1]+bb*yy[n-1]+cc)
G=line3d([p0,p1],color=’blue’)
G=G+list_plot(pp,color=’red’,opacity=0.2)
G=G+line3d([pp0, pp1], color=’red’)
G=G+text3d(’Blue - original line: ’+’%.4f*x+%.4f*y+%.4f’
%(a,b,c), (p[0][0], p[0][1], p[0][2]), color=’blue’)
G=G+text3d(’Red - fitted line: ’+’%.4f*x+%.4f*y+%.4f’ %
(aa,bb,cc), (p[n-1][0], p[n-1][1], p[n-1][2]), color=’
red’)
show(G)�
101 Python in SC 4.5 Python: Plotting modules
102 Python in SC 4.6 I/O
4.6 I/O
4.6.1 File I/O with arrays; plain ASCII format
• Plain text output to file (just dump repr(array)):� �a = linspace(1, 21, 21); a.shape = (2,10)
# In case of Sage Notebook, use the variable DATA, which
holds the current working directory name for current
worksheet
file = open(DATA+’tmp.dat’, ’w’)
file.write(’Here is an array a:\n’)
file.write(repr(a)) # dump string representation of a
file.close()�(If you need the objects in a different worksheet, use the directory name that was
stored in variable DATA of the original worksheet...)
103 Python in SC 4.6 I/O
• Plain text input (just take eval on input line):
� �file = open(DATA+’tmp.dat’, ’r’)
file.readline() # load the first line (a comment)
b = eval(file.read())
file.close()�
104 Python in SC 4.6 I/O
4.6.2 File I/O with arrays; binary pickling
• Dump (serialized) arrays with cPickle:
� �# a1 and a2 are two arrays
import cPickle
file = open(DATA+’tmp.dat’, ’wb’)
file.write(’This is the array a1:\n’)
cPickle.dump(a1, file)
file.write(’Here is another array a2:\n’)
cPickle.dump(a2, file)
file.close()�
105 Python in SC 4.6 I/O
Read in the arrays again (in correct order):� �file = open(DATA+’tmp.dat’, ’rb’)
file.readline() # swallow the initial comment line
b1 = cPickle.load(file)
file.readline() # swallow next comment line
b2 = cPickle.load(file)
file.close()�Almost all Python object x can be saved in compressed form to disk using
save(x,filename) (or in many cases x.save(filename))� �A=matrix(RR,10,range(100))
save(A,’A’)�� �B=load(’A’)�
106 Python in SC 4.7 SciPy
4.7 SciPy
4.7.1 Overview
• SciPy is a comprehensive package (by Eric Jones, Travis Oliphant, Pearu Peter-son) for scientific computing with Python
• Much overlap with ScientificPython
• SciPy interfaces many classical Fortran packages from Netlib (QUADPACK,ODEPACK, MINPACK, ...)
• Functionality: special functions, linear algebra, numerical integration, ODEs,random variables and statistics, optimization, root finding, interpolation, ...
• May require some installation efforts (applies ATLAS)
See SciPy homepage (http://www.scipy.org)