notes.rst (13063B)
1 # vim: set tw=80:noautoindent 2 3 For Jacobi exercise: Use atan2(). 4 5 11-4: Introduction 6 ##### 7 Deadline for exercises: ~2 weeks after assignment 8 9 All exercises must be done on Lifa: 10 lifa.phys.au.dk 11 Ethernet: vlifa01 or vlifa02 12 You need RSA keys to login from outside net. 13 Login from inside: NFIT credentials. 14 15 Alternative server: molveno 16 Dedicated for numerical course. 17 18 Lifa will have approx. 5 year old software, molveno is updated. 19 20 All phys.au.dk servers have NFS shared home folders. 21 22 Dmitri answers: 23 http://www.phys.au.dk/~fedorov/numeric/ 24 25 Bash: Last command starting with e.g. 'v': !v 26 27 Exercises are weighted 75% and the exam 25%. You do need to complete at least 28 51% of the exam. 29 30 02: >51% 31 4: >60% 32 7: >80% 33 10: >90% 34 12: 100% 35 36 16-4: Interpolation 37 #### 38 Makefiles_: 39 For all project, use makefiles, the project is evaluated by `make clean; make`. 40 41 General structure of Makefile: 42 Definitions of variables 43 all: my_target 44 Target(s): Dependenc(y,ies) 45 <-tab-> Command(s) 46 47 Strings are denoted without decoration, variables as $(VAR). 48 To use the CC system linker to link C++ objects, add libraries: 49 LDLIBS += -lstdc++ 50 If you use e.g. g++ as the linker, the above command is not needed. 51 52 If an object file is required as a dependency, the Makefile will issue a CC 53 command, compiling the source code file with the same basename. `make -p | less` 54 will show all build rules, even build in. 55 56 Interpolation_: 57 When you have a discrete set of datapoints, and you want a function that 58 describes the points. 59 60 If a function is analytical and continuous, and an infinitely large table of 61 datapoints in an interval, the complete analytical function can be found from a 62 taylor-series of _all_ derivatives in the interval. 63 64 k-Polynomial: k+1 unknowns (variables). High polynomials tend to oscillate. 65 66 Cubic interpolation: The interval between points can be described by a function 67 of three polynomials. 68 69 Spline interpolation: Also made of polynomials. First order spline (a0+x*a1), 70 simply connects the data points linearly. The splines for each inter-datapoint 71 interval must have the same values at the data points. The derivates are 72 discontinuous. 73 74 Solving linear splines: 75 Datapoints: {x_i,y_i}, i = 1,...,n 76 Splines (n-1): S_i(x) = a_i + b_i (x - x_i) 77 S_i(x_i) = y_i (n equations) 78 S_i(x_{i+1}) = S_{i+1}(x_i) (n-2 equations (inner points)) 79 Unkowns: a,b: 2n-2 variables. Solution: 80 => a_i = y_i 81 S_i(x) = y_i + b_i (x-x_i) 82 S_i(x_{i+1}) = y_i + b_i (x_{i+1} - x_i) 83 => b_i = (y_{i+1} - y_i) / (x_{i+1} - x_i) 84 85 Start of by searching which interval x is located in. Optionally, remember the 86 interval, as the next value will probably lie in the same interval. 87 88 Binary search: Is x between x_1 and x_n? If not, error: Extrapolation. 89 Continuously divide the interval into two, and find out if the x is in the 90 larger or smaller part. 91 DO A BINARY SEARCH. 92 93 Second order spline: 94 S_i(x) = a_i + b_i(x-x_i) + c_i(x-x_i)^2 95 Unknowns: 3(n-1) = 3*n-3 96 Equations: 3*n-4 97 The derivatives are also continuous. 98 99 Solution: 100 a_i = y_i 101 \delta x = (x-x_i) 102 y_i + b_i \delta x_i + c_i \delta x_i^2 = y_{i+1} 103 b_i + 2 c_i \delta x_i = b_{i+1} 104 Suppose you know b_i, you can find c_i. From that you can find b_{i+1}, and in 105 turn, c_{i+1}. Through recursion you find all unknowns by stepping forward. 106 The backwards solution can be found from the last data-point (y_n) by solving 107 the two equations with c_{n-1} and b_{n-1} as the two unkowns. 108 109 Symmetry can be used as an extra condition. 110 111 112 18-4: 113 ############## 114 Interpolation exercise, plotting optionally in gnuplot, or graph (from 115 plotutils): 116 graph -T png points.dat > plot.png 117 In makefile, example: 118 plot.png: points.dat 119 graph --display-type png $^ > $@ 120 Each dataset in points.dat needs a header, e.g. # m=1, S=0 121 122 lspline.cc: Linear spline 123 qspline.cc: Quadratic spline 124 cspline.cc: Cubic spline 125 126 Linear spline: 127 S(x) = S_i(x) it x in [x_i,x_(i+1)] 128 S_i(x) = a_i + b_i (x-x_i) 129 S_i(x) = y_i + (\delta y_i)/(\delta x_i) (x-x_i) 130 S_i(x_i) = y_i 131 \delta y_i = y_(i+1) - y_i 132 S_i (x_(i+1)) = y_(i+1) 133 134 In C++: 135 std::vector<double> x,y,p; 136 Maybe typecasting? Could be fun. 137 138 Procedural programming: 139 -- 140 struct lspline { 141 int n; 142 vector<double> x,y,p; 143 }; 144 145 Make a function: 146 struct lspline* construct_lspline(vector<double>&x, vector<double>&y) 147 double evaluate_lspline(struct lspline * asdf, double z) 148 free_lspline(); 149 150 Object-oriented programming: 151 -- 152 If you want to take the structural approach, you keep the functions and 153 structures seperate. If you take a OO approach, put the functions inside the 154 structure (or class): 155 struct lspline { 156 int n; 157 vector<double> x,y,p; 158 lspline(...,..); // Constructor, same name as struct 159 double eval(double z); 160 }; 161 struct lspline ms(x,y); 162 ms.eval(z); 163 164 See Dmitri's cubic spline example which uses OO. 165 166 Functional programming (in C++11), compile with -std=c++0x: 167 -- 168 The functions can return functions: 169 170 #include <functional> 171 using namespace std; 172 173 function<double(double)> flspline (vector<double>&x, vector<double>&y); 174 175 auto my_spline = flspline(x,y); 176 my_spline(5,0); 177 178 179 System of linear equations: 180 ------- 181 A*x = b 182 183 A_i,j x_j = b_i 184 185 Solve by finding A^(-1): x = A^(-1) * b 186 Numerically, you calculate the inverse by solving Ax=b. 187 We will assume that the matrixes are not singular. 188 189 Turn the system into a triangular form. 190 The main diagonal is non-zero, all lower values are 0, and upper values are 191 denoted T_nn. 192 T_nn * x_n = b_n => x_n = 1/T_nn * b_nn 193 T_(n-1,n-1) x_(n-1) + T_(n-1,n) x_n = b_(n-1) 194 T_ii x_i + sum^n_(j=i+1) T_(i,j) x_j = b_i 195 x_i = 1/T_ii (b_i - sum^n_(j=i+1) T_ij, x_j) 196 197 The simplest triangulation is by Gauss elimination. Numerically, the simplest 198 method is LU decomposition (Lower Upper). 199 A = LU, where L=lower triangle, U=upper triangle. 200 n^2 equations. 201 L and U contain "(n^2 - n)/2 + n" elements. 202 L+U = n^2/2 + n/2 = (n(n+1))/2 203 204 The diagonals in L are all equal to 1: L_ii = 1. 205 See Dolittle algorithm in the lecture notes, which with the LU system is the 206 most used, and fastest method for solving a linear equation. 207 208 Ax = b 209 LUx = b, Ux=y 210 211 Another method: QR decomposition: R=Right triangle (equal to U). 212 A = QR 213 Q^T Q = 1 (orthogonal) 214 215 Ax = b 216 QRx = b 217 Rx = Q^T b 218 219 Gram-Schmidt (spelling?) orthogonalization: 220 Consider the columns of your matrix A. Normalize them. Orthogonalize all other 221 columns to the first column. 222 223 Normalizing the column: ||a_1|| = sqrt(a_1 dot a_i) 224 Orthoginalize columns: a_2/||a_1|| -> q_1 225 226 Numerically: 227 for j=2 to m: 228 a_j - dot(dot(q_1,a_j),q_1) -> a_j 229 a_2 -> a_2/||a_2|| = q_2 230 231 Find inverse matrix: 232 A A^-1 = diag(1) 233 234 235 236 30-4: Diagonalization 237 ######################### 238 239 Runtime comparison: Do a number of comparisons with different matrix sizes 240 etc.numeric-2012 241 242 Easiest way to diagonalize a matrix: Orthogonal transformation 243 A -> Q^T A Q = D 244 Q matrix can be built with e.g. QR decomposition. Rotation: Computers to cyclic 245 sweep, which is faster than the classic rotation. 246 Cyclic: Zero all elements above the diagonal, and do your rotations until the 247 matrix is diagonal. The matrix is converged if none of the eigenvalues have 248 changed more than machine precision. You will destroy the upper half plus the 249 diagonal. If you store the diagonal in another vector, you can preserve the 250 matrix values. 251 In the beginning, you look for the largest element in each row, and create an 252 index which is a column that keeps the numbers of the largest elements. 253 With an index, you can perform the operation fast. You have to update the index 254 after each operation. 255 256 For very large matrixes, > system memory: 257 Krylov subspace methods: You use only a subspace of the whole space, and 258 diagonalize the matrix in the subspace. 259 260 261 02-5: Ordinary Differential Equations (ODEs) 262 ############################################ 263 264 dy/dx = f(x,y) 265 266 Usually coupled equations: 267 dy_1/dx = f_1(x,y_1,y_2) 268 dy_2/dx = f_1(x,y_1,y_2) 269 [y_1, ..., y_n] = y 270 [f_1(x,y), ..., f_n(x,y) = f(x,y) 271 y' = f(x,y) 272 x is usually time. If f has the above form, it is a ODE. 273 Sine function: 274 y'' = -y 275 In this form, it is not a ODE, because it has a second derivative. 276 You can redifine it to be an ODE: 277 => y = u_1 -> u'_1 = u_2 278 y' = u_2 -> u'_2 = -u_1 279 280 Solving ODEs with a starting condition: 281 y' = f(x,y) 282 y(x_0) = y_0 283 a->b (Shape of the function in the interval) 284 You can calculate the derivative at (x_0,y_0). You then make a step towards 285 x_0+h, and apply Euler's method: 286 y' \approx (\delta y)/(\delta x) = (y(x_0+h) - y_0)/h 287 y(x_0+h) \approx y(x_0) + h*f(x_0,y_0) 288 y(x) = y_0 + y'_0(x-x0) + 1/(2!) y''_0(x_0)(x-x_0)^2 + ... (Taylor exp.) 289 You can find the higher-order terms by sampling points around (x_0,y_0). 290 Estimate the new derivative half a step towards h, which is used for the first 291 point. You sample your function, and fit a polynomial. Higher order polynomiums 292 tend to oscillate. 293 When solving ODE's the many sampled points create a tabulated function. If you 294 want to do something further with the function, you interpolate the points by 295 e.g. splines. 296 Only three steps are needed if the equation is a parabola. Other functions are 297 called multi-step methods. You do not want to go to high in the 298 Taylor-expansion, as there lies a danger with the higher order terms 299 oscillating. 300 If the function is changing fast inside an interval, the step size h needs to be 301 small. This is done by a driver. 302 The Runge-kutta is single step, and the most widely used. 303 304 Absolute accuracy (delta) vs. relative accuracy (epsilon) can behave 305 significantly differently when the machine precision is reached. 306 The user usually specifies both, and the accuracy is satisfied, when one of the 307 conditions are met (the tolerance, tau). 308 tau = delta + epsilon*||y|| 309 310 Stepper: Must return y(x+h), e (error estimate). 311 Driver: x->x+h. If e is smaller than tau, it accepts the step. 312 The driver finds the size of the next h: 313 h_next = h(tau/e)^power * safety 314 power = 0.25 315 safety = 0.95 316 The driver thus increases the step size if the error was low relative to the 317 tolerance, and vice-versa. 318 319 Runge principle for determining the error: 320 e = C*h^(p+1) 321 You first do a full h step, then two h/2 steps. 322 2*c*(h/2)^(p+1) = c * (h^(p+1))/(2^p) 323 For the error, you calculate y_1 from full step, and then y_1 from two half steps: 324 e = ||y_1(full step) - y_1(2 half steps)|| 325 You can also instead use RK1 and RK2, and evaluate the difference between the 326 two for the same step. 327 328 The effectiveness of the driver and stepper is determined by how many times you 329 call the right-hand side of the ODEs. 330 331 Save the x and y values in a C++ vector, and add dynamically using the 332 push_back() function. 333 334 335 07-5: Nonlinear equations and optimization 336 ##### 337 Pipe stdin to program: 338 cat input.txt | ./my_prog 339 Redirect stdout to file: 340 ./my_prog > out.txt 341 Redirect stderr to file: 342 ./my_prog 2> err.txt 343 344 Jacobian matrix: Filled with partial derivatives. Used for linearizing the 345 problem. f(x+\delta x) \approx f + J \delta x 346 347 Machine precision: double: 2e-16. It is the largest number where 1 + eps = 1. 348 349 Quasi-Newton methods: Might be exam exercise. 350 351 352 14-5: Numerical integration 353 ##### 354 Examination problem: FFT or Multiprocessing 355 356 Functions for calculating: 357 \int_a^b f(x) dx 358 359 Often not possible analytically, thus numerical aproach. Most differential 360 operations are possible analytically. 361 362 Riemann integral: Numerical approximation. 363 You divide the interval into subintervals (t_1, ..., t_n). 364 Riemann sum: 365 S_n = \sum_{i=1}^n f(x_i) \Delta x_i 366 Approaching the integral as the interval approaches 0.0. The geometric 367 interpretation corresponds to rectangles with height f(x_i) and width \Delta 368 x_i. The function passes trough the middle of the top side of the rectangles. 369 The integral exists also for discontinuous functions. 370 371 Rectangle method: Stable, does no assumptions 372 \int_a^b f(x) dx \approx \sum_{i=1}^n f(x_i) \Delta x_i 373 Trapezum method: 374 Instead of one point inside the interval, two points are calculated, and the 375 average is used. 376 \int_a^b f(x) dx \approx \sum_{i=1}^n (f(x_{i+1} )+ f(x_i))/2 * \Delta x_i 377 Adaptive methods: 378 The \Delta x_i is adjusted to how flat the function is in an interval. 379 As few points as possible are used. 380 Polynomial functions: 381 Analytical solutions exist. Taylor series expansion. w_i: Weight. 382 \sum_{i=1}^n w_i f(x_i) => \int_a^b f(x) dx 383 `---- quadrature -----` 384 n functions: {\phi_1(x),...,\phi_n(x)} 385 Often the polynomials are chosen: {1,x,x^2,...,x^{n-1}} 386 \sum_{i=1}^n w_i \phi_k(x_i) = I_k 387 I_k = \int_a^b \phi_k (x) dx 388 Gauss methods: 389 Also use the quadratures as tuning parameters, as the polynomial method. 390 w_i,x_i as tuning parameters: 2*n tuning parameters. 391 \int_a^b f(x) w(x) dx 392 Functions like 1/sqrt(x) or sqrt(x) are handled through the weight function. 393 See the lecture notes for details. Both nodes and weights are adjusted. 394 395 The method to use is dependent on the problem at hand. 396 397 398