· Web view[101] 020 Numerical Analysis Using M#math, 1 "

32
[101] 020 Numerical Analysis Using M#math, www.msharpmath.com "msharpmath" revised 2012.12.06 Numerical Analysis Using M#math //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++ // user functions for Numerical Analysis //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++ click a line and move to the definition // matrix adaptive_ode(double tol, t,tf,h, matrix y,fun(double t,matrix y)) // poly bairstow(a, double r,s) // double bisect(a,b, f(x)) // complex cnewton(z, cftn(z),cftn2(z)) // matrix divdiff(&x,&f) // double dnewton(x, ftn(x)) // matrix eig22(A) // void eighot(matrix A) // double eiginvpow(matrix A, &x) // void eigjac(matrix A) // matrix eiglast(&A) // poly eigpol(matrix& A) // double eigpow(matrix A, &x) // matrix gausselim(A) // matrix gaussjord(A) // matrix gausspivot(A) // double falsePos(a,b, f(x)) // double hermite(xx, matrix &x,&y,&y1) 1

Transcript of · Web view[101] 020 Numerical Analysis Using M#math, 1 "

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

"msharpmath" revised 2012.12.06

Numerical Analysis Using M#math

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// user functions for Numerical Analysis//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

click a line and move to the definition

// matrix adaptive_ode(double tol, t,tf,h, matrix y,fun(double t,matrix y))// poly bairstow(a, double r,s) // double bisect(a,b, f(x)) // complex cnewton(z, cftn(z),cftn2(z)) // matrix divdiff(&x,&f) // double dnewton(x, ftn(x)) // matrix eig22(A) // void eighot(matrix A) // double eiginvpow(matrix A, &x) // void eigjac(matrix A) // matrix eiglast(&A)// poly eigpol(matrix& A) // double eigpow(matrix A, &x) // matrix gausselim(A) // matrix gaussjord(A) // matrix gausspivot(A) // double falsePos(a,b, f(x)) // double hermite(xx, matrix &x,&y,&y1) // integ(a,b,f(x))// matrix jordelim(A)// double lagran(matrix x,f, double xx)// double modfalsePos(a,b, f(x)) // double muller(a,b,c, f(x))

1

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

// poly polreg(matrix &x,&f, double n) // double reldiff(a,b) = |a-b|/(1+|a|+|b|); // matrix seidel(&A,b)// void spline3(matrix &x,&f,poly *P)// poly tcheby(double a,b,n, f(x)) // matrix user_tdma(a,b,c,d, double na,nb) // double user_tdmares(matrix x, &a, &b, &c, &d) // void user_chol(matrix& A) // matrix user_hess(A) // void user_lu(matrix& A) // matrix user_ode(double t,tf,h, matrix y,fun(double t,matrix y))// matrix user_qr(matrix& A) // void bvp2nd(double a,b,nx, matrix &x,&f,&u)

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 1 Introduction//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 2 Solution of Nonlinear Equations//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

double reldiff(a,b) = |a-b|/(1+|a|+|b|); // relative difference, a.-.b

double bisect(a,b, ftn(x)) { eps = 1.e-6; ya = ftn(a); if( |ya| < eps ) return a; yb = ftn(b); if( |yb| < eps ) return b; if( ya*yb > 0 ) { "y(a)y(b) > 0"; return NaN; }

iter = 0; while(1) { if( ++iter > 200 ) { "bisection failed"; return NaN; } x = 0.5*(a+b);

2

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

y = ftn(x); [ iter,a,b,x,y ];; // display with double semicolons ;;

if( |y| > inf ) { "bisection diverged"; return NaN; } if( reldiff(a,b) < eps || |y| < eps ) break;

if( ya*y > 0 ) a = x; else b = x; } return x;}

#> reldiff;#> bisect;

//----------------------------------------------------------------------// Newton method//----------------------------------------------------------------------double dnewton(x, ftn(x)) { eps = 1.e-6; y = ftn(x); if( |y| < eps ) return x;

iter = 0; while(1) { if( ++iter > 200 ) { "newton solver failed"; return NaN; } deno = ftn'(x); // derivative if( |deno| < eps ) { "dfdx ~= 0"; return NaN; } dx = -y / deno; x += dx; y = ftn(x); [ iter,x,y ];; // display

if( x.-.(x-dx) < eps || |y| < eps ) break; // a.-.b } return x;}

#> dnewton;

//----------------------------------------------------------------------// Complex Newton method, cftn = complex function//----------------------------------------------------------------------complex cnewton(z, cftn(z),cftn2(z)) { eps = 1.e-6; w = cftn(z); if( |w| < eps ) return z;

3

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

iter = 0; while(1) { if( ++iter > 200 ) { "newton-solver failed"; return NaN ! ; } deno = cftn2(z); // derivative must be given by argument if( |deno| < eps ) { "dfdx ~= 0"; return NaN !; } dz = -w / deno; z += dz; w = cftn(z); [ iter, z, |w| ];; // display

if( |dz| < eps || |w| < eps ) break; } return z;}

#> cnewton;

//----------------------------------------------------------------------// false position method//----------------------------------------------------------------------double falsePos(a,b, ftn(x)) { eps = 1.e-6; ya = ftn(a); if( |ya| < eps ) return a; yb = ftn(b); if( |yb| < eps ) return b; if( ya*yb > 0 ) { "y(a)y(b) > 0"; return NaN; }

iter = 0; while(1) { if( ++iter > 200 ) { "false-position failed"; return NaN; } x = a-ya*(a-b)/(ya-yb); y = ftn(x); [ iter,a,b,x,y ];; // display

if( |y| > inf ) { "false-position failed"; return NaN; } if( a.-.b < eps || |y| < eps ) break; // relative difference a.-.b

if( ya*y > 0 ) { a = x; ya = y; } else { b = x; yb = y; } } return x;}

#> falsePos;

//----------------------------------------------------------------------

4

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

// modified false position method//----------------------------------------------------------------------double modfalsePos(a,b, ftn(x)) { eps = 1.e-6; ya = ftn(a); if( |ya| < eps ) return a; yb = ftn(b); if( |yb| < eps ) return b; yc = ya; if( ya*yb > 0 ) { "y(a)y(b) > 0"; return NaN; }

iter = 0; while(1) { if( ++iter > 200 ) { "modified false position failed"; return NaN; } x = a-ya*(a-b)/(ya-yb); y = ftn (x); [ iter,a,b,x,y];; // display

if( |y| > inf ) { "modified false position failed"; return NaN; } if( a.-.b < eps || |y| < eps ) break; if( ya*y > 0 ) { a = x; ya = y; if( ya*yc > 0 ) yb *= 0.5; } else { b = x; yb = y; if( yc*yb > 0 ) ya *= 0.5; } } return x;}

#> modfalsePos;

//----------------------------------------------------------------------// Muller method//----------------------------------------------------------------------double muller(a,b,c, ftn(x)) { eps = 1.e-7; x = [a,b,c]; y = ftn++(x); // upgrade ‘double’ function to accept matrix

iter=0; while(1) { if(++iter > 100) { "muller failed"; return NaN; } k = 6 - x.max1k - x.min1k; // median index of x1,x2,x3 p = .interp(x,y) %% x(k); // synthetic division a = p[2]; b = p[1]; c = p[0]; det = b*b-4*a*c; if(det < 0) { "no real root in muller";; return NaN; }

if(b > 0) xx = x(k)-2*c/(b+sqrt(det)); else xx = x(k)-2*c/(b-sqrt(det)); // root of a quadratic, eq(45) yy = ftn(xx); d = |x-xx|.max1; k = |x-xx|.max1k;

5

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

x(k) = xx; // find and discard the farthermost point from xx y(k) = yy; // replace the discarded point with the root xx [ x, xx, yy ];; // display

if( |d| < eps || |yy| < eps ) break; } return xx;}

#> muller;

//----------------------------------------------------------------------// Bairstow method//----------------------------------------------------------------------poly bairstow(a, double r,s) { // poly bairstow(poly a, double r,s) a = a.monic; // make a leading coefficient a_n = 1 n = a.n; double b[100],br[100],bs[100]; b = 0; br = 0; bs = 0; iter = 0; for[500] { b[n] = a[n]; b[n-1] = a[n-1]-r*b[n]; for.i(n-2,1, -1) b[i] = a[i]-r*b[i+1]-s*b[i+2]; // for(i=n-2; i>=1; i--) b[0] = a[0]-s*b[2];

br[n-1] = -b[n]; br[n-2] = -b[n-1]-r*br[n-1]; bs[n-2] = -b[n]; for.i(n-3,1, -1) { // for(i = n-3; i >= 1; i--) br[i] = -b[i+1]-r*br[i+1]-s*br[i+2]; bs[i] = -b[i+2]-s*bs[i+2]-r*bs[i+1]; } br[0] = -s*br[2]; bs[0] = -b[2]-s*bs[2]; det = br[0]*bs[1]-br[1]*bs[0]; dr = (-b[0]*bs[1]+b[1]*bs[0])/det; ds = (-b[1]*br[0]+b[0]*br[1])/det;

r += dr; s += ds; [ iter, r, s ];; if( |dr|+|ds| < 1.e-6 ) break; } return poly(s,r,1);}

#> bairstow;

6

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 3 Numerical Linear Algebra//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

cut;"Chapter 3";

//----------------------------------------------------------------------// Gauss-elimination, user code for A.gausselim//----------------------------------------------------------------------matrix gausselim(A) { // copy An = A.m; for.k(1,n-1) { // for(k = 1; k < n; k++) if( |A(k,k)| < _eps ) break; prow = A.row(k)/A(k,k); for.i(k+1,n) { // for(i = k+1; i <= n; i++) A.row(i) -= A(i,k)*prow; A(i,k) = 0; A;; // display } cut;; } return A;}#> gausselim;

//----------------------------------------------------------------------// Gauss-Jordan elimination without pivot//----------------------------------------------------------------------matrix jordelim(A) { // copy An = A.m; for.k(1,n) { // for(k = 1; k <= n; k++) if( |A(k,k)| < _eps ) break; // _eps = 2.22e-16 A.row(k) /= A(k,k); for.i(1,n) { // for(i = 1; i <= n; i++) if( i == k ) continue; // skip if k=i A.row(i) -= A(i,k)*A.row(k); A(i,k) = 0.; A;; // display } cut;; } return A;}#> jordelim;

//----------------------------------------------------------------------// Gauss-Jordan elimination with pivot, user code for A.gaussjord//----------------------------------------------------------------------

7

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

matrix gaussjord(A) { // copy An = A.m; for.k(1,n) { // for(k = 1; k <= n; k++) up to the last line // pivoting procedure below //imax = k; //pmax = |A(k,k)|; //for(i = k+1; i <= n; i++) { // if( pmax < |A(i,k)| ) { pmax = |A(i,k)|; imax = i; } //} imax = A..(k:n)(k).maxentryk +k-1; // maxentryk if( imax != k ) { [ k,imax ];; A = A.swap(imax,k);; } // elimination procedure if( |A(k,k)| < _eps ) continue; // _eps = 2.22e-16 A.row(k) /= A(k,k); for.i(1,n) { // for(i = 1; i <= n; i++) if( i == k ) continue; // skip if k=i A.row(i) -= A(i,k)*A.row(k); A(i,k) = 0.; A;; // display } cut;; } return A;}#> gaussjord;

//----------------------------------------------------------------------// Gauss elimination with pivot, user code for A.gausspivot//----------------------------------------------------------------------matrix gausspivot(A) { // copy A n = A.m; for.k(1,n-1) { // for(k = 1; k < n; k++) // pivoting procedure below //imax = k; //pmax = |A(k,k)|; //for(i = k+1; i <= n; i++) { // if( pmax < |A(i,k)| ) { pmax = |A(i,k)|; imax = i; } //} imax = A..(k:n)(k).maxentryk +k-1; // maxentryk if( imax != k ) { [ k,imax ];; A = A.swap(imax,k);; } // elimination procedure if( |A(k,k)| < _eps ) continue; // _eps = 2.22e-16 prow = A.row(k)/A(k,k); for.i(k+1,n) { // for(i = k+1; i <= n; i++) A.row(i) -= A(i,k)*prow; A(i,k) = 0.; A;; // display } cut;; }

8

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

return A;}#> gausspivot;

//----------------------------------------------------------------------// Gauss-Seidel iteration procedure//----------------------------------------------------------------------matrix seidel(&A,b) { // refer A, copy bn = A.n; x = .zeros(n,1); d = A.diag(0); for.iter(1,10000) { delx = ( b - A*x ) ./ d; x += delx; sum = delx.norm2; if( iter <= 2 ) { x.tr ;; } // display ;; if( sum < 1.e-6 ) { iter;; break; } // display ;; } return x;}

#> seidel;

//----------------------------------------------------------------------// tridiagonal matrix algorithm (TDMA)// a(i)*x(i) + b(i)*x(i-1) + c(i)*x(i+1) = d(i), b(1) = c(n) = 0//----------------------------------------------------------------------matrix user_tdma(a,b,c,d, double na,nb) { n = a.mn; P = Q = x = .zeros(1,n); P(na) = -c(na)/a(na); Q(na) = d(na)/a(na); for.i(na+1,nb) { // for(i = na+1; i <= nb; i++) den = 1/( a(i) + b(i)*P(i-1) + _eps ); P(i) = -c(i) * den; Q(i) = (d(i) - b(i) * Q(i-1))*den; } x(nb) = Q(nb); for.i(nb-1,na,-1) x(i) = P(i)*x(i+1)+Q(i); // for(i = nb-1; i >= na; i--) return x;}

#> user_tdma;

//----------------------------------------------------------------------// residue of tridiagonal matrix algorithm (TDMA)// a(i)*x(i) + b(i)*x(i-1) + c(i)*x(i+1) = d(i), b(1) = c(n) = 0

9

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

//----------------------------------------------------------------------double user_tdmares(matrix x, &a, &b, &c, &d) { n = a.mn; res = d(1)-a(1)*x(1)-c(1)*x(2) + d(n)-a(n)*x(n)-b(n)*x(n-1); for.i(2,n-1) { // for(i = 2; i < n; i++) res += d(i) - a(i)*x(i) - b(i)*x(i-1) - c(i)*x(i+1); } return res;}

#> user_tdmares;

//----------------------------------------------------------------------// LU decomposition//----------------------------------------------------------------------void user_lu(matrix& A) { n = A.m; L = U = .zeros(n);

for.s(1,n) { // for(s=1; s<=n; s++) for.i(s,n) L(i,s) = A(i,s) - L..(i)(1:s-1) ** U..(1:s-1)(s); U(s,s) = 1; // horizontal direction for.j(s+1,n) U(s,j) = (A(s,j) - L..(s)(1:s-1) ** U..(1:s-1)(j))/L(s,s); [ L, U ] ;; // display L..(j:n)(j), U..(i)(i:n) }}

#> user_lu;

//----------------------------------------------------------------------// Choleski decomposition//----------------------------------------------------------------------void user_chol(matrix& A) { n = A.m; U = .zeros(n);

for.i(1,n) { sum = A(i,i) - U..(1:i-1)(i).norm22; if( sum < 0 ) { "negative diagonal in Choleski";; break; }

U(i,i) = sqrt(sum); for.j(i+1,n) U(i,j) = (A(i,j) - U..(1:i-1)(i) ** U..(1:i-1)(j))/U(i,i); U ;; // display U..(i)(i:n) }}

#> user_chol;

10

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

//----------------------------------------------------------------------// QR decomposition//----------------------------------------------------------------------matrix user_qr(matrix& A) { n = A.m; Q = A.unit; S = .I(n);

for.i(2,n) { // for(i=2; i<=n; i++) { x = Q.col(i-1); S -= x * x.tr; Q.col(i) = ( S * Q.col(i) ).unit.trun12; } return Q; }

#> user_qr;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 4 Matrix Eigenvalue Problems//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

cut;"Chapter 4";

//----------------------------------------------------------------------// user function equivalent to ‘A.eigpoly’//----------------------------------------------------------------------poly eigpol(matrix& A) { n = A.m; c = -(1:n+1).apoly; // to make c[n] = -1 B = A; c[n-1] = B.trace; for.k(2,n) { B = A*(B-c[n-k+1]*.I(n)) ;; // display c[n-k] = B.trace/k ; } return -c;}

#> eigpol;

//------------------------------------------------// power method//------------------------------------------------

11

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

double eigpow(matrix A, &x) { // A is copied, x is referred, lam = k = 0 ; x = .ones(A.m,1);

while( 1 ) { lamo = lam; y = A * x ; [ ++k, lam = y.maxentry , (x = y / lam )' ] ;; // to display if( lam ~= lamo ) break; // 6 digits identical } return lam;}

#> eigpow;

//------------------------------------------------// inverse power method//------------------------------------------------double eiginvpow(matrix A, &x) { // A is copied, x is referred, lam = k = 0 ; x = .ones(A.m,1);

while( 1 ) { lamo = lam; y = A \ x ; [ ++k, lam = y.maxentry , (x = y / lam )' ] ;; // to display if( lam .-. lamo < 1.e-6 ) break; // relative difference } return 1 / lam;}

#> eiginvpow;

//------------------------------------------------// Householder PAP transformation into Hessenberg form//------------------------------------------------matrix user_hess(A) { // A is copied n = A.m; for.k(1,n-2) {

gamma = A(k+1,k).sign * A..(k+1 : n)(k).norm2; alpha = 1/(gamma*(gamma+A(k+1,k))); u = A.col(k); u.(1:k) = 0; // u.entry(1:k) = 0; u(k+1) += gamma; P = .I(n) - alpha * u*u';

12

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

A = (P*A*P).trun12;; // display } return A;}

#> user_hess;

//------------------------------------------------// eigenvalues from the last 2 x 2 submatrix at the right-bottom//------------------------------------------------matrix eig22(A) { a1 = A.trace; d = a1^2 - 4 * A.det; // x^2 - a1 x + a2 = 0 if( d < 0 ) return [ 0.5*(a1-sqrt(-d)!); 0.5*(a1+sqrt(-d)!) ]; else return [ 0.5*(a1-sqrt( d)) ; 0.5*(a1+sqrt( d)) ];}

matrix eiglast(&A) {n = A.n;if( n == 1 ) return A;else if( n == 2) eig22(A);

for.iter(0,99) { A22 = A..(n-1:n)(n-1:n);

(Q,R) = (A*A - A22.trace *A + A22.det *.I(n) ) .qr; A = Q'*A*Q;; // display if( |A..(n-1:n)(1:n-2).maxentry| < 1.e-6 ) break; } return eig22( A..(n-1:n)(n-1:n) ); // last 2 x 2 matrix}

#> eiglast;

//------------------------------------------------// Hotelling Deflation Method//------------------------------------------------void eighot(matrix A) { n = A.m; x = .ones(n,1); lam = .zeros(n,1); X = .zeros(n,n);

for.k(1,n) { lam(k) = eigpow(A,x); X.col(k) = x; x = x.unit;

13

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

A -= lam(k)*x*x'; } cut;; lam;; X;; // display}

#> eighot;

//------------------------------------------------// Jacobi Method//------------------------------------------------void eigjac(matrix A) { eps = 1.e-7; n = A.m; X = .I(n);

iter=0; while(1) {

if(++iter > 100) { "failed in eigenjac";; break; }grs = 0;for.i(1,n-1) for.j(i+1,n)

if(|A(i,j)| > grs) { grs = |A(i,j)|; r = i; s = j; }if( |grs| < eps ) break; grr = A(r,r); gss = A(s,s); grs = A(r,s);if( grr ~= gss ) theta = 0.25*pi;else theta = 0.5*atan(2*grs/(grr-gss));cost = cos(theta);sint = sin(theta);A(r,r) = grr*cost*cost+gss*sint*sint+2*grs*sint*cost;A(s,s) = gss*cost*cost+grr*sint*sint-2*grs*sint*cost;A(r,s) = A(s,r) = 0;for.i(1,n) {

if(i != r && i != s) { gr = A(i,r); gs = A(i,s); A(i,r) = A(r,i) = gr*cost+gs*sint;A(i,s) = A(s,i) = gs*cost-gr*sint;

}gr=X(i,r); gs=X(i,s);X(i,r) = gr*cost+gs*sint;X(i,s) = gs*cost-gr*sint;

}if( iter == 1 ) { grs;; r;; s;; theta;; cost;; sint;; A;; X;; }

[ iter, theta, r, s ];; // just for comment } cut;; A.trun8;; X;; // display}

14

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

#> eigjac;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 5 Interpolation and Curve Fitting//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

cut;"Chapter 5";

//----------------------------------------------------------------------// Lagrangian interpolation//----------------------------------------------------------------------double lagran(matrix x,f, double xx) { n = x.len; yx = 0; for.i(1,n) { val = f(i); for.j(1,n) if( i != j ) val *= (xx-x(j))/(x(i)-x(j)); yx += val; } return yx;}

#> lagran;

//----------------------------------------------------------------------// divided difference table//----------------------------------------------------------------------matrix divdiff(&x,&f) { n = x.len; tab = f._1; // compulsory column vector

for.j(2,n) { tab |= 0; // one more column initialized by zero for.i(1,n-j+1) tab(i,j) = (tab(i+1,j-1)-tab(i,j-1))/(x(i+j-1)-x(i)); } return tab;}

//----------------------------------------------------------------------// polynomial regression//----------------------------------------------------------------------%> UU'a = Uf, polynomial regressionpoly polreg(matrix &x,&f, double n) {

15

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

U = x.vander(n); p = poly((U*U') \ (U*f')) ; // from matrix to poly return p;}

#> polreg;

//----------------------------------------------------------------------// spline interpolation//----------------------------------------------------------------------void spline3(matrix &x,&f,poly *P) { // polynomial array must be a priori declared n = x.len; a = b = c = d = .zeros(1,n); for.i(2,n-1) { b(i) = x(i)-x(i-1); c(i) = x(i+1)-x(i); a(i) = 2*(b(i)+c(i)); d(i) = 6*( (f(i+1)-f(i))/c(i) - (f(i)-f(i-1))/b(i) ); } icase = 0; // natural condition is default if( icase == 1 ) { a(2) += b(2); a(n-1) += c(n-1); } else if( icase == 2 ) { t = b(2)^2/c(2); a(2) += b(2)+t; c(2) -= t; t = c(n-1)^2/b(n-1); a(n-1) += c(n-1)+t; b(n-1) -= t; }

f2 = .tdma(a,b,c,d, 2,n-1); // built-in dot function ".tdma" for.i(2,n) { h = x(i)-x(i-1); P[i-1] =-f2(i-1)/(6*h)*.[1,-x(i) ]^3+(-f(i-1)/h+f2(i-1)*h/6)*.[1,-x(i)] +f2(i) /(6*h)*.[1,-x(i-1)]^3+( f(i )/h-f2(i )*h/6)*.[1,-x(i-1)]; }}

#> spline3;

//----------------------------------------------------------------------// Tchebyshev interpolation//----------------------------------------------------------------------poly tcheby(double a,b,n, ftn(x)) { x = y = .ones(n,1); for.k(1,n) { z = cos((n+0.5-k)*pi/n); x(k) = a+(b-a)/2*(z+1); y(k) = ftn(x(k)); } return .interp(x,y); // interpolation polynomial}

16

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

#> tcheby;

//----------------------------------------------------------------------// Hermite interpolation//----------------------------------------------------------------------double hermite(xx, matrix &x,&y,&y1) { // x : grid points // y : y(x) // y1 : y'(x) k = x.ipos(xx); // (xx-x(k))*(xx-x(k+1)) < 0 if( k == 0 ) return NaN; // out of interval h = x(k+1)-x(k); s = (xx-x(k))/h; a = s*s*(3-2*s); yy = (1-a)*y(k)+a*y(k+1)+h*s*(1-s)*( (1-s)*y1(k)-s*y1(k+1) ); return yy;}

#> hermite;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 6 Differentiation and Integration//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//----------------------------------------------------------------------// integration accounting for indefinite integral//----------------------------------------------------------------------double integ(a,b, f(x)) { aa = a; bb = b; flip = 1; if(a > b) { aa = b; bb = a; flip = -1; } sum = 0.; h = 0.05; alpha = 1.2; if( aa < -0.5*inf && 0.5*inf < bb ) { // -inf<x<inf a = 0; for[300] { sum += int.x(a,a+h) ( f(x) ) + int.x(-a-h,-a) ( f(x) ); a += h; h *= alpha; } } else if( aa < -0.5*inf ) { // -inf<x<bb a = bb; for[300] {

17

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

sum += int.x(a-h,a) ( f(x) ); a -= h; h *= alpha; } } else if( 0.5*inf < bb ) { // aa<x<inf a = aa; for[300] { sum += int.x(a,a+h) ( f(x) ); a += h; h *= alpha; } } else { // aa<x<bb a = b = 0.5*(aa+bb); h = 0.25*(bb-aa); for[30] { sumo = sum; sum += int.x(a,a+h) (f(x)) + int.x(b-h,b) (f(x)); a += h; b -= h; h *= 0.5; if( sum.-.sumo < 1.e-8) break; } }

sum *= flip; return sum;}

#> integ;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 7 Initial Value Problems//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// prototypematrix user_ode (double t,tf,h, matrix y,fun(double t,matrix y));matrix adaptive_ode (double t,tf,h, matrix y,fun(double t,matrix y), double tol);

/*//--------------------------------------------------------------------------// sample run//--------------------------------------------------------------------------%> "simple example of ODE";#> matrix fun1(double t, matrix y) = [ -y(1)-5*exp(-t)*sin(5*t) ];

#> ysol = user_ode( 0,3, 0.03, [ 1 ], fun1 );; #> ysol.plot;

18

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

//--------------------------------------------------------------------------// sample run for Van der Pol equation//--------------------------------------------------------------------------%> "stiff ODE with Van der Pol equation";#> matrix VanderPol1(double x, matrix y) = [ y(2), 1*(1-y(1)^2)*y(2)-y(1) ];#> ysol = adaptive_ode(0,20, 0.2, [ 2,0 ], VanderPol1, 0.01);; #> ysol.len;// ans = 127#> ysol.endrow;// ans = [ 20 2.00809 -0.0469113 0.000154643 ]#> plot( ysol.col(1), ysol.col(2));

// Van der Pol equation with μ=1

//----------------------------------------------------------------------------#> matrix VanderPol2(double x, matrix y) = [ y(2), 10*(1-y(1)^2)*y(2)-y(1) ];#> yans = adaptive_ode(0,60, 2, [ 2,0 ], VanderPol2, 0.01);; #> yans.len;// ans = 681#> yans.endrow;// ans = [ 60 1.801 -0.079977 2.29483e-006 ]#> plot( yans.col(1), yans.col(2));

19

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

// Van der Pol equation with μ=10

//----------------------------------------------------------------------------#> matrix vanderpol3(double t, matrix y) = [ y(2), 100*(1-y(1)^2)*y(2)-y(1) ];#> ysol = adaptive_ode(0,300, 2, [ 2,0 ], vanderpol3, 0.01 );; #> ysol.len; // number of time steps// ans = 15053#> ysol.endrow;// ans = [ 300 -1.53485 0.0111001 0.000871423 ]#> yfig = ysol.skiprow(10);; plot( yfig.col(1), yfig.col(2));

// Van der Pol equation with μ=100 */

//==========================================================================// user_odecoef:://==========================================================================double user_odecoef(double icase, matrix &A,&B,&C) { switch( icase ) { case 1: // Euler = 1st RK A = [1]; B = [0]; C = [ 0 ]; break;

case 2: // (modified Euler) predictor-corrector = 2nd RK A = [1,1]/2; B = [0,1];

20

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

C = [ 0; 1,0 ]; break;

case 3: // polygon = 2nd RK A = [0,1]; B = [0,1]/2; C = [ 0; 0.5,0 ]; break;

case 4: // Ralston = 2nd RK A = [1,2]/3; B = [0,3]/4; C = [ 0; 0.75,0 ]; break;

case 5: // 3rd RK A = [1,4,1]/6; B = [0,1,2]/2; C = [ 0; 0.5; -1,2,0 ]; break;

case 6: // Runge = 4th RK A = [1,2,2,1]/6; B = [0,1,1,2]/2; C = [ 0; 0.5; 0,0.5; 0,0,1,0 ]; break;

case 7: // Kutta = 4th RK A = [1,3,3,1]/8; B = [0,1,2,3]/3; C = [ 0; 1/3; -1/3,1; 1,-1,1,0 ]; break;

case 8: // Gill = 4th RK s = 1/sqrt(2); A = [0.5,1-s,1+s,0.5]/3; B = [0,1,1,2]/2; C = [ 0; 0.5; -0.5+s, 1-s; 0, -s, 1+s, 0 ]; break;

case 9: // Fehlberg = 4th RK A = [ 25/216, 0, 1408/2565, 2197/4104, -0.2 ]; B = [ 0, 0.25, 3/8, 12/13, 1 ]; C = [ 0; 0.25; 3/32, 9/32; // 3rd 1932/2197, -7200/2197, 7296/2197; // 4th 439/216, -8, 3680/513, -845/4104, 0 ]; // 5th break;

case 10: // Fehlberg = 5th RK A = [ 16/135, 0, 6656/12825, 28561/56430, -9/50, 2/55 ]; B = [ 0, 0.25, 3/8, 12/13, 1, 0.5 ]; C = [ 0; 0.25; 3/32, 9/32; // 3rd 1932/2197, -7200/2197, 7296/2197; // 4th 439/216, -8, 3680/513, -845/4104; // 5th

21

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

-8/27, 2, -3544/2565, 1859/4104, -11/40,0 ]; // 6th } return A.len; // A.len = A.length = A.longer}

//==========================================================================// user_odeRK:://==========================================================================void user_odeRK( double to,h, matrix &y,&yo, &A,&B,&C,&K, // ampersand & means 'refer' not 'copy' matrix fun(double t, matrix y)) {// to : previous time at whicvh solutions are known// h : magnitude of time step, h = t-to // yo : solution at previous time step// y : dependent variables for coupled ODEs, y(1),y(2), ... , y(numeq)// A,B,C : coefficients for integration scheme// K : generalized slopes for integration scheme

K.row(1) = fun(to,yo); // B(1) = C.row(1) = 0 for.i(2,A.len) { t = to + B(i)*h; y = yo + h*( C.row(i) * K ); K.row(i) = fun(t,y); } y = yo + h*( A * K );}

//==========================================================================// user_ode:: for positive h//==========================================================================matrix user_ode(double t,tf,h, matrix y,fun(double t,matrix y)){// t : initial time// tf : final time// h : size of time step// y : initial conditions, [ y(1), y(2), ... , y(n) ]// fun : ODE in matrix form, [ y'(1)=f1, y'(2)=f2, ... , y'(n)=fn ]

icase = 9; // Fehlberg 4th, change this manually sdim = user_odecoef(icase, A,B,C); K = .zeros(sdim,y.len);

22

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

yo = fun(t,y); if( yo.len != y.len ) "ode function is not valid in dimenension"; num = 0; ysol = [ t, y ]; while(1) { yo = y; if( t+h >= tf ) h = tf-t ; // stay exact at the final time user_odeRK(t,h, y,yo, A,B,C,K, fun); t += h; ysol _= [ t, y ]; // stack newly-obtained solutions if( t >= tf || t.-.tf < 1.e-6 || ++num > 10000 ) break; } return ysol;}#> user_ode;

//==========================================================================// adaptive_ode:: for positive h//==========================================================================matrix adaptive_ode(double t,tf,h, matrix y,fun(double t,matrix y), double tol){// t : initial time// tf : final time// h : size of time step// y : initial conditions, [ y(1), y(2), ... , y(n) ]// fun : ODE in matrix form, [ y'(1)=f1, y'(2)=f2, ... , y'(n)=fn ]

s = user_odecoef( 9, A5,B5,C5); K5 = .zeros(s,y.len); // Fehlberg 4th s = user_odecoef(10, A6,B6,C6); K6 = .zeros(s,y.len); // Fehlberg 5th E6 = [ 1/360, -128/4275, -2197/75240, 0, 1/50, 2/55 ];

yo = fun(t,y); if( yo.len != y.len ) "ode function is not valid in dimenension"; num = 0; ysol = [ t, y, 0 ]; while(1) { yo = y; if( t+h > tf ) h = tf-t ; // stay exact at the final time

do { user_odeRK(t,h, y,yo, A6,B6,C6,K6, fun); yerr = h * |(E6*K6).maxentry|; // error estimation if( yerr > tol) h *= 0.1; // reduce h where stiff } while( yerr > tol ); // y = yo + h*(A5 * K6..(1:5)()); // if prefered Fehlberg 4th

23

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

t += h; ysol _= [ t, y, yerr ]; // stack newly-obtained solutions

if( yerr < tol ) h *= 1.25; // increase h where plain if( t >= tf || t.-.tf < 1.e-6 || ++num > 100000 ) break; if( .mod(num,1000) == 0 ) "adaptive_ode is running" ;; } return ysol;}

#> adaptive_ode;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 8 Boundary Value Problems//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void bvp2nd(double a,b,nx, matrix &x,&f,&u) ;

matrix DE (double x,f,u) = [ 1, 2*x, 0, 0 ]; // [ cp, cu, cf, cs ]matrix BC1(double x,f,u) = [ 1,0,1 ]; // [ b1u, b1f, b1r ]matrix BC2(double x,f,u) = [ 0,1,1 ]; // [ b2u, b2f, b2r ]//---------------------------------------------------------------------- /*#> (a,b) = (0,1); nx = 5;#> bvp2nd(a,b,nx, x,f,u);#> f;#> plot(x,f);*/

//======================================================================// bvp2nd:://======================================================================void bvp2nd(double a,b,nx, matrix &x,&f,&u) {// 3 user-functions must be written //matrix DE (double x,f,u) = [ cp, cu, cf, cs ]//matrix BC1(double x,f,u) = [ b1u, b1f, b1r ]//matrix BC2(double x,f,u) = [ b2u, b2f, b2r ]

h = (b-a)/nx; x = (a,b).span(nx+1); f = u = .zeros(1,nx+1); A = B = C = R = .zeros(1,nx+1);

24

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

// boundary points are moved to 1 and nx+1 for matrix index for.i(2,nx) { // internal points 2,3,...,nx-1,nx c = DE(x(i),f(i),u(i)); // c = [ cp, cu, cf, cs ] c(1) /= h^2; c(2) /= 2*h; A(i) = -2*c(1)+ c(3); B(i) = c(1) - c(2); C(i) = c(1) + c(2); R(i) = -c(4); } bc = BC1(x(1),f(1),u(1)); // bc = [ b1u, b1f, b1r ] bc(1) /= 2*h; dn = 1 / (bc(2)-3*bc(1)); p0 = bc(3)*dn; R(2) -= B(2)*p0; p1 = -4*bc(1)*dn; A(2) += B(2)*p1; p2 = bc(1)*dn; C(2) += B(2)*p2;

bc = BC2(x(nx+1),f(nx+1),u(nx+1)); // bc = [ b2u, b2f, b2r ] bc(1) /= 2*h; dn = 1 / (bc(2)+3*bc(1)); q0 = bc(3)*dn; R(nx) -= C(nx)*q0; q1 = 4*bc(1)*dn; A(nx) += C(nx)*q1; q2 = -bc(1)*dn; B(nx) += C(nx)*q2;

f = .tdma(A,B,C,R, 2,nx); // dot function .tdma f( 1) = p0 + p1*f(2) + p2*f(3); f(nx+1) = q0 + q1*f(nx) + q2*f(nx-1); u( 1) = ( -f(3) + 4*f(2) - 3*f(1) )/(2*h); u(nx+1) = (f(nx-1) - 4*f(nx) + 3*f(nx+1))/(2*h);

for.i(2,nx) u(i) = (f(i+1)-f(i-1))/(2*h);}

#> bvp2nd;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 9 Eigenvalue Problems//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Chapter 10 Coupled Equations and Minimum Searching//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

25

[101] 020 Numerical Analysis Using M#math, www.msharpmath.com

++++++

26