Programming & Numerical Analysis: Kai-Feng Chen
Programming & Numerical Analysis: Kai-Feng Chen
PROGRAMMING &
NUMERICAL ANALYSIS2014
Lecture 06:
Into numerical analysis
THE ART OF
NUMERICAL ANALYSIS
Wikipedia: numerical analysis is the study of algorithms that use
numerical approximation (as opposed to general symbolic
manipulations) for the problems of mathematical analysis.
This does not require a very precise calculation. Sometimes the key
THE ART OF
NUMERICAL ANALYSIS (II)
Thanks to the rapid development of computers, now we dont
THE FUN
This course would like to introduce you the merit of numerical
TECHNICALLY
SPEAKING...
In principle if you can find some
But if you think about this more carefully, find the key of a tune is
nothing magical but a Fourier transformation, right?
Done!
A CONCEPTUAL EXAMPLE
We need a reference wave file; lets get the pitch standard from
the Wikipedia:
http://en.wikipedia.org/wiki/A440_(pitch_standard)
Youll find a file with sine wave at 440 Hz. Convert it to a standard
wave file by ffmpeg or any other tool you may find.
10
A CONCEPTUAL EXAMPLE
(II)
Lets load the wave with SciPy and draw it with Matplotlib:
import scipy
import scipy.io.wavfile as wavfile
import matplotlib.pyplot as plt
rate, data = wavfile.read('Sine_wave_440.wav')
t = scipy.linspace(0.,1.,rate,endpoint=False)
plt.figure(figsize=(8,6), dpi=80)
plt.plot(t[:rate/100],data[:rate/100])
plt.xlabel('Time [sec]')
plt.ylabel('Amplitude')
plt.show()
11
A CONCEPTUAL EXAMPLE
(II)
Call the discrete Fourier transform package:
import
import
import
import
scipy
scipy.fftpack as fftpack
scipy.io.wavfile as wavfile
matplotlib.pyplot as plt
fm = 2
m 69
12
440Hz
14
STEP 3: FOURIER
TRANSFORMATION
Perform the Fourier transformation for each targeting frequency
for every time interval (here I use 1/16 second).
STEP 4: FILTERING
Here I use a very simple hand-made cleaning-up code.
For each time interval: sort the keys according to the amplitudes;
16
STEP 5: CONVERT TO
MIDI/SHEET MUSIC
Joint the block and write to a MIDI file (with the help of MidiUtil
package).
17
PERFORMANCE TEST
Surely we shall start with something much simpler in order to
ensure the code is working.
Test sample #1: 8 single notes, from C4 to C5, each note takes 1 sec
(with 1/4 sec mute time, sine wave only).
Original
WAVE
Converted
MIDI
output
18
Converted
MIDI
19
A REAL SONG?
How about a real song? Well, this is much harder...
Test song: Dvok: Humoresque In G Flat, Op. 101/7
(Yo-Yo Ma + Itzhak Perlman)
20
Converted
MIDI
Converted
MIDI
(lower threshold)
21
COMMENTS
You probably noticed this is not trivial to analyze a real song with
such a super naive code (but it is already fancy enough, right?)
With the support of NumPy and SciPy, doing all the work above
22
INTERMISSION
Anybody wants to sing a song and lets
convert it to a MIDI file?
ERRORS IN COMPUTATION
As you may already know:
24
Random errors:
Roundoff errors:
FLOATING POINT
ARITHMETIC
Floating-point numbers are represented in computer hardware as
base 2 (binary) fractions.
( 1)sign 2exponent
28
1023
1+
52
X
i=1
b52 i 2
FLOATING POINT
ARITHMETIC (II)
Given the fraction part of float point number has a limited
precision (up to 52+1 bits), the float point number cannot be 100%
precise for most of decimal fractions.
Some factors:
FLOATING POINT
ARITHMETIC (III)
It is good to keep in mind that there is no real continuous
real number in computation.
0.1000000000000000055511151231257827021181583404541015625.
>>> 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
0.9999999999999999
>>> 0.1+0.2-0.3
5.551115123125783e-17
Spoon is not real,
real number is also not real...
30
GIVE ME A
Let's practice a very classical calculation of %: approximating a
circle by polygons (Liu Hui method):
S0 =
R=1
S/2
rh
(S/2)2
i2
+ (S/2)2
(S/2)2
31
A NAIVE IMPLEMENTATION
Step 0: Hexagon
S6 = 1
3
diameter = 2
Step 1: Dodecagon
r
S12 =
p
1
S12
(S6 /2)2
q
= 2
i2
+ (S6 /2)2 =
3 0.5176
S12 12
3.1058
2
32
S62
A NAIVE IMPLEMENTATION
(II)
Coding time! Just a plain python code can do this:
import math
nsides = 6
length = 1.
for i in range(20):
length = (2. - (4. - length**2)**0.5)**0.5
nsides *= 2!!
pi = length*nsides/2.
print
print
print
print
'-'*30!
!
'Polygon of',nsides,'slides:'
'pi(calc) = %.15f' % pi
'diff = %.15f' % abs(math.pi-pi)
l6-example-01.py
33
RESULTS
Output:
Polygon of 12 slides:
pi(calc) = 3.105828541230250, diff = 0.035764112359543
Polygon of 24 slides:
Smaller
pi(calc) = 3.132628613281237, diff = 0.008964040308556
approximation
error with more
Polygon of 48 slides:
pi(calc) = 3.139350203046872, diff = 0.002242450542921 sides (closer to
a real circle).
Polygon of 96 slides:
pi(calc) = 3.141031950890530, diff = 0.000560702699263
Polygon of 192 slides:
pi(calc) = 3.141452472285344, diff = 0.000140181304449
34
RESULTS (II)
How about more steps?
384 slides:! ! pi(calc)
768 slides:! ! pi(calc)
1536 slides:! ! pi(calc)
3072 slides:! ! pi(calc)
6144 slides:! ! pi(calc)
12288 slides:!! pi(calc)
24576 slides:!! pi(calc)
49152 slides:!! pi(calc)
98304 slides:!! pi(calc)
196608 slides:! pi(calc)
393216 slides:! pi(calc)
786432 slides:! pi(calc)
1572864 slides:!pi(calc)
3145728 slides:!pi(calc)
6291456 slides:!pi(calc)
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
3.141557607911622,
3.141583892148936,
3.141590463236762,
3.141592106043048,
3.141592516588155,
3.141592618640789,
3.141592645321216,
3.141592645321216,
3.141592645321216,
3.141592645321216,
3.141593669849427,
3.141592303811738,
3.141608696224804,
3.141586839655041,
3.141674265021758,
diff
diff
diff
diff
diff
diff
diff
diff
diff
diff
diff
diff
diff
diff
diff
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
0.000035045678171
0.000008761440857
0.000002190353031
0.000000547546745
0.000000137001638
0.000000034949004
0.000000008268577
0.000000008268577
0.000000008268577
0.000000008268577
0.000001016259634
0.000000349778055
0.000016042635011
0.000005813934752
0.000081611431964
Oh-oh...
35
S0 =
S2
S2 4
10
12
36
LIEBNIZ FORMULA
Let's start from the trigonometric function:
tan
= 1 ! arctan(1) =
4
x3
x5
+
3
5
arctan(x) = x
! 1
1 1
+
3 5
1 1
+
7 9
x7
x9
+
7
9
...
1
X
( 1)n
... =
=
2n + 1
4
n=0
A LITTLE BIT OF
IMPROVEMENT (A TRICK!)
It's not really hard: we can just pick up a smaller x!
6
p
3
tan
1
= p ! arctan
3
x3
x5
+
3
5
arctan(x) = x
1
! p [1
3
1
1
+
33 59
1
p
3
x7
x9
+
7
9
1
1
+
7 27 9 81
=
6
...
...] =
6
A LITTLE BIT OF
IMPROVEMENT (II)
Coding time again!
import math
pi = 0.
numerator = 1./3.**0.5
for n in range(31):
pi += numerator/(2.*n+1.)*6.
numerator *= -1./3.
print
print
print
print
'-'*30!
!
'Sum up to',n,'step:'
'pi(calc) = %.15f' % pi
'diff = %.15f' % abs(math.pi-pi)
l6-example-02a.py
41
A LITTLE BIT OF
IMPROVEMENT (III)
With only <30 terms, the limit of precision already reached (Bravo!)
Sum up to 10 step:
pi(calc) = 3.141593304503083, diff = 0.000000650913289
Sum up to 20 step:
pi(calc) = 3.141592653595636, diff = 0.000000000005843
Sum up to 30 step:
pi(calc) = 3.141592653589794, diff = 0.000000000000001
REMARK:
HOW THE ERRORS BEHAVE
After N iterations of computing
Approximation errors:
approx
Roundoff errors:
roundo
N m
REMARK:
HOW THE ERRORS BEHAVE
Limitation of the total error:
total approx + roundo
+ N m
N
1
10 16
+ p
2
N
2 N
minimum 4 10
11
(when N~70,000,000,000)
It's actually just a rough guesstimation, but it's always good to keep
this idea in mind when you write your code!
44
HANDS-ON SESSION
Practice:
2
1
1
1
1
= 2 + 2 + 2 + 2 +
6
1
2
3
4
Modify l6-example-02.py to calculate % using this formula, and see
how accurate you can reach with 1000, 10000, 100000 terms.
45