View
217
Download
0
Category
Preview:
Citation preview
[101] 020 Numerical Analysis Using Cemmath, www.msharpmath.com
"cemmath", "msharpmath" revised 2012.12.06
Numerical Analysis Using Cemmath
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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 Cemmath, 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
Recommended