//=============================================================// // Numerical Analysis Package in Java // // Numerical analysis calculation class Numeric // // // // Author : Dr. Turhan Coban // // TUBİTAK Ulusal Metroloji Enstitüsü // // phone : 90-262-679 5013 // // email : turhan.coban@ume.tubitak.gov.tr // // turhan_coban@yahoo.com // //=============================================================// // import java.io.*; import java.text.*; import java.util.Locale; abstract class f_x { //single function single independent variable // example f=x*x abstract double func(double x); } abstract class f_xj { // single function multi independent variable // a single value is returned indiced to equation_ref // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x,1) returns the value of f[1] // func(x,0) returns the value of f[0] abstract double func(double x[]); } abstract class f_xa { // single function multi independent variable // a single value is returned indiced to equation_ref // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x,1) returns the value of f[1] // func(x,0) returns the value of f[0] abstract double func(double t,double x[]); } abstract class f_xi { // multifunction multi independent variable // a single value is returned indiced to equation_ref // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x,1) returns the value of f[1] // func(x,0) returns the value of f[0] abstract double func(double x[],int equation_ref); } abstract class fi_xi { // multifunction multi independent variable // vector of dependent variables are returned // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x) returns the value of f[0] and f[1] // as a two dimensional vector abstract double[] func(double x[]); } abstract class fij_xi { // multifunction multi independent variable // for n independent variable n*n matrix of // dependent variables are returned // example f[0][0]=x[0]+Math.sin(x[1]) f[0][1]=x[0]-x[1] // f[1][0]=x[0]*x[0]-x[1] f[1][1]=Math.exp(x[0]+x[1]*x[1] // func(x) returns the value of f[0][0], f[0][1] // f[1][0], f[1][1] // as a two dimensional matrix abstract double[][] func(double x[]); } public class Numeric { //This is a library of numerical methods // Minimisation (Optimisation) of a function public static double[] grads(f_xj Fn,fi_xi Gn,double P0[]) { return grads(Fn,Gn,P0,100,1.0e-10,1.0e-10,0); } public static double[] grads(f_xj Fn,fi_xi Gn,double P0[],double max1,double delta,double epsilon,int print) { //GRADS Gradient search for a minimum of non-linear multivariable function // Inputs // Fn name of the vector function // Gn gradient for Fn // P0 starting point // max1 maximum number of iterations // delta convergence tolerance for the independent variables // epsilon convergence tolerance for the dependent variable // show if show==1 the iterations are displayed // // P0 point V0 for the minimum // y0 function value Fn(V0) // h minimum step size // err error estimate //--------------------------------------------------------------------------- int n = P0.length; int maxj = 20; double big = 1e8; double h = 1.0; double len = Matrix.norm(P0); double y0 = Fn.func(P0); if (len > 1e4) { h = len / 1e4; } double err = 1; double cnt = 0; double cond = 0; double P[] = new double[n]; double P1[] = new double[n]; double P2[] = new double[n]; double Pmin[] = new double[n]; double Y, y1, y2, ymin, hmin; double S[]=new double[n]; double h0,h1,h2; double e0,e1,e2,d; int i; for(i=0;idelta || err>epsilon)) { double z[] = Gn.func(P0); for (i = 0; i < n; i++) { S[i] = z[i]; } P1 = Matrix.add(P0, Matrix.multiply(S, h)); P2 = Matrix.add(P0, Matrix.multiply(S, (2.0 * h))); y1 = Fn.func(P1); y2 = Fn.func(P2); cond = 0; int j = 0; while (j < maxj && cond == 0) { len = Matrix.norm(P0); if (y0 < y1) { for (i = 0; i < n; i++) { P2[i] = P1[i]; } y2 = y1; h = h / 2.0; P1 = Matrix.add(P0, Matrix.multiply(S, h)); y1 = Fn.func(P1); } else { if (y2 < y1) { for (i = 0; i < n; i++) { P1[i] = P2[i]; } y1 = y2; h = 2 * h; P2 = Matrix.add(P0, Matrix.multiply(S, (2.0 * h))); y2 = Fn.func(P2); } else cond = -1; } j++; if (h < delta) { cond = 1; } if (Math.abs(h) > big || len > big) {cond = 5;} } if (cond == 5) { for (i = 0; i < n; i++) { Pmin[i] = P1[i]; } ymin = y1; } else { d = 4 * y1 - 2 * y0 - 2 * y2; // Start of a long block: if (d < 0) {hmin = h * (4 * y1 - 3 * y0 - y2) / d;} else { cond = 4; hmin = h / 3.0; } Pmin = Matrix.add(P0, Matrix.multiply(S, hmin)); ymin = Fn.func(Pmin); h0 = Math.abs(hmin); h1 = Math.abs(hmin - h); h2 = Math.abs(hmin - 2.0 * h); if (h0 < h) { h = h0; } if (h1 < h) { h = h1; } if (h2 < h) { h = h2; } if (h == 0) { h = hmin; } if (h < delta) { cond = 1; } e0 = Math.abs(y0 - ymin); e1 = Math.abs(y1 - ymin); e2 = Math.abs(y2 - ymin); if (e0 != 0 && e0 < err) { err = e0; } if (e1 != 0 && e1 < err) { err = e1; } if (e2 != 0 && e2 < err) { err = e2; } if (e0 == 0 && e1 == 0 && e2 == 0) { err = 0; } if (err < epsilon) { cond = 2; } if (cond == 2 && h < delta) { cond = 3; } } //end of if(cond==5) cnt++; for (i = 0; i < n; i++) { P0[i] = Pmin[i]; } y0 = ymin; if(print==1) {System.out.println("x min = "+Matrix.toString(P0)+"/nymin = "+y0+"/nerror estimate ="+err+"/nminimum step size "+h); } } //end of while return P0; } public static double quadmin(f_x f,double a,double b,double epsilon) {return quadmin(f,a,b,epsilon,1.0e-10,0);} public static double quadmin(f_x f,double a,double b) {return quadmin(f,a,b,1.0e-10,1.0e-10,0);} public static double quadmin(f_x f,double a,double b,double epsilon,double delta,int print) { // Minimum of a single variable function by using polynomial quadratures double p0 = a; int maxj = 20; int maxk = 30; double big = 1e6; double err = 1; int k = 1; int cond = 0; double h = 1; double f1,p1,p2,pmin,y0,y1,y2,ymin,d,hmin,dh,h0,h1,h2; double e0,e1,e2; double p,dp,dy,yp; if (Math.abs(p0)>1e4) { h = Math.abs(p0)/1e4;} while (kepsilon && cond !=5 ) { f1 = (f.func(p0 + 0.00001) - f.func(p0 - 0.00001)) / 0.00002; if (f1 > 0) {h = -Math.abs(h);} p1 = p0 + h; p2 = p0 + 2 * h; pmin = p0; y0 = f.func(p0); y1 = f.func(p1); y2 = f.func(p2); ymin = y0; cond = 0; int j = 0; while (j < maxj && Math.abs(h) > delta && cond == 0) { if (y0 <= y1) { p2 = p1; y2 = y1; h = h / 2; p1 = p0 + h; y1 = f.func(p1); } else { if (y2 < y1) { p1 = p2; y1 = y2; h = 2 * h; p2 = p0 + 2 * h; y2 = f.func(p2); } else { cond = -1;} } //end of if(y0 <= y1) j = j + 1; if (Math.abs(h) > big || Math.abs(p0) > big) {cond = 5;} }//end of while(j big || Math.abs(pmin) > big) {cond = 5;} e0 = Math.abs(y0 - ymin); e1 = Math.abs(y1 - ymin); e2 = Math.abs(y2 - ymin); if (e0 != 0 && e0 < err) {err = e0;} if (e1 != 0 && e1 < err) {err = e1;} if (e2 != 0 && e2 < err) {err = e2;} if (e0 != 0 && e1 == 0 && e2 == 0) {err = 0;} if (err < epsilon) {cond = 2;} p0 = pmin; k = k + 1; } // End of the long else block. if (cond == 2 && h < delta) {cond = 3;} }//end of the while p = p0; dp = h; yp = f.func(p); dy = err; if(print==1) {System.out.println("x min = "+p+"ymin = "+yp+"error of x ="+dp+"error of y"+dy); } return p; } public static double golden(f_x f,double a,double b,double epsilon) {return golden(f,a,b,epsilon,1.0e-10,0);} public static double golden(f_x f,double a,double b) {return golden(f,a,b,1.0e-10,1.0e-10,0);} public static double golden(f_x f,double a,double b,double epsilon,double delta,int print) { // f abstract function of class f_x (f(x) type of single function single variable) // fibonacchi golden ratio search double r1 = (Math.sqrt(5.0)-1.0)/2.0; // golden ratio double r2 = r1*r1; double h = b - a; double ya = f.func(a); double yb = f.func(b); double c = a + r2*h; double d = a + r1*h; double yc = f.func(c); double yd = f.func(d); int k = 1; double dp,dy,p,yp; while ((Math.abs(yb-ya)>epsilon) || (h>delta)) { k++; if (yc fhi) {fhi=p[i][FUNC]; ihi=i;} } double fnhi = flo; inhi = ilo; for (int i=0; i fnhi)) {fnhi=p[i][FUNC]; inhi=i;} ////////// exit criterion ////////////// if ((iter % 4*NDIMS) == 0) { //standart error of yi should be less than set criteria (tolerance) //calculate average (including highest point) pavg=0; for(int i=0;i= fhi) /// over the top; try inside contraction { double cc[] = new double[NDIMS]; for (int j=0; j h(n,0); for(i=0;i h(n,0); for(i=0;i h(n,0); for(i=0;itol && jes)&&(iterxu) break; fx=y.func(xr); if(fx*fxr<0) { if(dxp tolerance ) { b=Matrix.multiply(Matrix.divide(y.func(x),dy.func(x)),-ti); x=Matrix.add(x,b); } if(i >= nmax) System.out.println("warning maximum number"+ " of iterations results may not be valid"); return x; } public static double[] newton( double x[],fi_xi y) { // xi solution matrix in fj(xi)=0 set of non-linear equation // derivative matrix dfj/dxi is calculated by derivative method //solution of nonlinear system of equations //by using newton raphson method. //this function does not require derivatives //it is utilised method derivative to calculate derivatives double ti=1.0; int i,ii,jj; int nmax=500; double tolerance=1.0e-15; int n=x.length; double b[]; b=new double[n]; double dy[][]; dy=new double[n][n]; i=0; for(i=0;i tolerance ) { for(ii=0;ii= nmax) System.out.println("warning maximum number of iterations"+ " results may not be valid" ); return x; } //========= least square curve fitting methods ========== //-------- polynomial least square curve fitting -------- public static double[] poly_least_square(double xi[],double yi[],int n) // data will be fit into // y=f(x)=a0+a1*x+a2*x2+a3*x^3+....+an*x^n // polynomial least square curve fitting // variables xi,yi vector of data points // degree of curve fitting { // data input variables: //xi vector of independent variable //yi vector of dependent variable //n : degree of curve fitting int l=xi.length; int i,j,k; int np1=n+1; double A[][]; A=new double[np1][np1]; double B[]; B=new double[np1]; double X[]; X=new double[np1]; for(i=0;i max) max = Math.abs(X[i]); for(i=0;i 0) && (Math.abs(X[i]/max) < 1.0e-100)) X[i]=0; return X; } public static double f_least_square(double e[],double x) { // this function calculates the value of // least square curve fitting function int n=e.length; double ff; if(n!=0.0) { ff=e[n-1]; for(int i=n-2;i>=0;i--) { ff=ff*x+e[i]; } } else ff=0; return ff; } public static double error(double x[],double y[],double e[]) { //calculates absolute square root error of a least square approach double n=x.length; int k; double total=0; for(k=0;k p(m+2,n,0); double p[][]; p=new double[mp2][n]; //vector gamma(m+1,0); double gamma[]; gamma=new double[mp1]; //vector beta(m+1,0); double beta[]; beta=new double[mp1]; //vector omega(m+1,0); double omega[]; omega=new double[mp1]; //vector alpha(m+1,0); double alpha[]; alpha=new double[mp1]; //vector b(m+1,0); double b[]; b=new double[mp1]; //vector wi(n,1.); double wi[]; wi=new double[n]; //matrix a(3,m+1); double a[][]; a=new double[3][mp1]; for(i=0;i q(m+2,0.0); for(k=m-1;k>=0;k--) { q[k]=a[0][k]+(x-a[1][k+1])*q[k+1]-a[2][k+1]*q[k+2]; yy=q[k]; } return yy; } // differential equation solutions public static double[] RK4(f_xi fp,double x0,double xn,double f0,int N) { //4th order Runge Kutta Method //fp :given derivative function df/dx(f,x) // xo : initial value of the independent variable // xn : final value of the independent variable // f0 : initial value of the dependent variable // N : number of dependent variable to be calculated // fi : dependent variable double h=(xn-x0)/N; double fi[]=new double[N+1]; double xi[]=new double[2]; double k[]; k=new double[4]; int i; double x; fi[0]=f0; for(x=x0,i=0;x xn) h=xn-fi[0][j]; xi[0]=fi[0][j]; xi[1]=fi[1][j]; k[0]=h*fp.func(xi,0); xi[0]=fi[0][j]+h/4.0; xi[1]=fi[1][j]+k[0]/4.0; k[1]=h*fp.func(xi,0); xi[0]=fi[0][j]+3.0/8.0*h; xi[1]=fi[1][j]+3.0/32.0*k[0]+9.0/32.0*k[1]; k[2]=h*fp.func(xi,0); xi[0]=fi[0][j]+12.0/13.0*h; xi[1]=fi[1][j]+1932.0/2197.0*k[0]-7200.0/2197.0*k[1]+7296.0/2197.0*k[2]; k[3]=h*fp.func(xi,0); xi[0]=fi[0][j]+h; xi[1]=fi[1][j]+439.0/216.0*k[0]-8.0*k[1]+3680.0/513.0*k[2]-845.0/4104.0*k[3]; k[4]=h*fp.func(xi,0); xi[0]=fi[0][j]+0.5*h; xi[1]=fi[1][j]-8.0/27.0*k[0]+2.0*k[1] -3544/2565*k[2]+1859.0/4104.0*k[3]-11.0/40.0*k[4]; k[5]=h*fp.func(xi,0); Err=Math.abs(1.0/360.0*k[0]-128/4275*k[2] -2197.0/75240*k[3]+1.0/5.0*k[4]+2.0/55.0*k[5]); if(Err(2*Hmin) ) h/=2.0; if(s>1.5 && Hmax >(2*h) ) h*=2.0; } } double fj[][]=new double[2][j+1]; for(int i=0;i<=j;i++) { fj[0][i]=fi[0][i]; fj[1][i]=fi[1][i]; } return fj; } static String toString(int n, int w) // converts an int to a string with given width. { String s = Integer.toString(n); while (s.length() < w) s = " " + s; return s; } static String toString(int left) // converts an int to a string with a constant width. { return toString(left,6); } public static String toString(double left, int w, int d) // converts a double to a string with given width and decimals. { NumberFormat df=NumberFormat.getInstance(Locale.US); df.setMaximumFractionDigits(d); df.setMinimumFractionDigits(d); df.setGroupingUsed(false); String s = df.format(left); while (s.length() < w) s = " " + s; if (s.length() > w) { s = ""; for (int i=0; i