27
[101] 020 Numerical Analysis Using M#math, www.msharpmath.com 1 "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))

Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

Embed Size (px)

Citation preview

Page 1: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

1

"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))

Page 2: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

2

// double muller(a,b,c, f(x))

// 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) {

Page 3: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

3

if( ++iter > 200 ) { "bisection failed"; return NaN; }

x = 0.5*(a+b);

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;

Page 4: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

4

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

// 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;

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; }

Page 5: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

5

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;

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

// 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

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

Page 6: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

6

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;

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];

Page 7: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

7

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;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Chapter 3 Numerical Linear Algebra

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

cut;

"Chapter 3";

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

// Gauss-elimination, user code for A.gausselim

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

matrix gausselim(A) { // copy A

n = 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;;

}

Page 8: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

8

return A;

}

#> gausselim;

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

// Gauss-Jordan elimination without pivot

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

matrix jordelim(A) { // copy A

n = 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

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

matrix gaussjord(A) { // copy A

n = 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.;

Page 9: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

9

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;;

}

return A; }

#> gausspivot;

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

// Gauss-Seidel iteration procedure

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

matrix seidel(&A,b) { // refer A, copy b

n = A.n;

x = .zeros(n,1);

d = A.diag(0);

Page 10: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

10

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

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

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);

}

Page 11: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

11

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;

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

// QR decomposition

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

Page 12: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

12

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

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

double eigpow(matrix A, &x) { // A is copied, x is referred,

Page 13: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

13

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;

Page 14: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

14

u(k+1) += gamma;

P = .I(n) - alpha * u*u';

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;

Page 15: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

15

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;

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) {

Page 16: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

16

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

}

#> 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

Page 17: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

17

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

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 regression

poly polreg(matrix &x,&f, double n) {

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;

}

Page 18: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

18

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

}

#> 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;

}

Page 19: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

19

#> 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] {

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));

Page 20: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

20

a += h; b -= h;

h *= 0.5;

if( sum.-.sumo < 1.e-8) break;

}

}

sum *= flip;

return sum; }

#> integ;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Chapter 7 Initial Value Problems

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// prototype

matrix 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;

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

// 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;

Page 21: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

21

// ans = 127

#> ysol.endrow;

// ans = [ 20 2.00809 -0.0469113 0.000154643 ]

#> plot( ysol.col(1), ysol.col(2));

// Van der Pol equation with

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

#> 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));

// Van der Pol equation with

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

#> 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));

Page 22: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

22

// Van der Pol equation with

*/

//==========================================================================

// 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];

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;

Page 23: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

23

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

-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)

Page 24: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

24

// 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);

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

//==========================================================================

Page 25: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

25

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

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) ;

Page 26: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

26

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);

// 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;

Page 27: Numerical Analysis Using M#math€¦ · // Gauss-Jordan elimination without pivot ... // Gauss elimination with pivot, user code for A.gausspivot

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

27

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

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++