//============================================================= // Numerical Analysis Packages in Java // Matrix calculations class Matrix // Author : Dr. Turhan Coban //============================================================= //Turhan Coban import java.io.*; public class Matrix { // This class defines matrix and vector // calculation methods public static String toString(double left) { //arrange double to string conversion so that all the //matrix double variables nicely printed in the same column String s=""; if(left>=0) s=s+" "; s=s+left; double n=s.length(); while(n<15) { s=s+" "; n=s.length(); } return s; } public static String toString(double[][] left) { //return a string representation of a matrix int n,m; String b; b=""; n=left.length; m=left[0].length; for(int i=0;i= big) { big=Math.abs(b[j][k]); irow=j; icol=k; } } else if(ipiv[k] > 1 ) { System.out.println("error : inverse of the matrix : singular matrix-1"); for(ii=0;ii=0;l--) { if(indxr[l] != indxc[l]) for(k=0;kbig) big=Math.abs(a[i-1][j-1]); } if(big==0) {System.out.println("singular matrix");return a;} vv[i-1]=1.0/big; } for(j=1;j<=n;j++) { for(i=1;i=big) { imax=i; big=dum; } } //end of i=0 if(j != imax) { for(k=1;k<=n;k++) { dum=a[imax-1][k-1]; a[imax-1][k-1]=a[j-1][k-1]; a[j-1][k-1]=dum; } d[0]=-d[0]; vv[imax-1]=vv[j-1]; } //end of if indx[j-1]=imax; if(a[j-1][j-1]==0) a[j-1][j-1]=tiny; if(j!=n) { dum=1.0/a[j-1][j-1]; for(i=j+1;i<=n;i++) a[i-1][j-1]*=dum; }//endif } //end for j= return a; } public static double[] LUaxb(double a[][],double x[],int indx[]) { //solves AX=B system of linear equation of LU decomposed matrix a //(calculated by method LU) int ii=0; int i,j,ll=0; double sum=0; int n=a.length; double b[]; b=new double[n]; for(i=1;i<=n;i++) { b[i-1]=x[i-1]; } for(i=1;i<=n;i++) { ll=indx[i-1]; sum=b[ll-1]; b[ll-1]=b[i-1]; if(ii!=0) { for(j=ii;j<=(i-1);j++) { sum-=a[i-1][j-1]*b[j-1]; } } else if(sum!=0) ii=i; b[i-1]=sum; } for(i=n;i>=1;i--) { sum=b[i-1]; if(imax) max=x; } return max; } public static double norminf(double a[][]) { //infinite matrix norm double x; double max = 0; double total; int i,j; int n=a.length; for(i=0;imax) max=x; } return max; } public static double norm(double a[][]) { //matrix norm double x; double max = 0; double total; int i,j; int n=a.length; for(j=0;jmax) max=x; } return max; } public static double normE(double a[][]) { //Euclidian matrix norm double x; double total; int i,j; total=0; int n=a.length; for(j=0;j=m2) mMax=m1; else mMax=m2; if(n1>=n2) nMax=n1; else nMax=n2; double b[][]; b=new double[nMax][mMax]; for(i=0;i=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i=m2) mMax=m1; else mMax=m2; if(n1>=n2) nMax=n1; else nMax=n2; double b[][]; b=new double[nMax][mMax]; for(i=0;i=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;ig) { f/=radix; c/=sqrdx; } } //end of if(c != 0 && .... if( (c+r)/f < 0.95*s ) { last=0; g=1.0/f; for(j=1;j<=n;j++) { a[i-1][j-1]*=g; } for(j=1;j<=n;j++) { a[j-1][i-1]*=f; } } //end of if( ((c+r.. }//end of for(i=1;i<=n.... } //end of while last==0 return a; } public static double[][] Hessenberg(double b[][]) { // Calculates the hessenberg matrix // it is used in QR method to calculate eigenvalues // of a matrix(symmetric or non-symmetric) int m,j,i; int n=b.length; double a[][]; a=new double[n][n]; for(i=0;i2) { for(m=2;m<=(n-1);m++) { x=0.0; i=m; for(j=m;j<=n;j++) { if(Math.abs(a[j-1][m-2]) > Math.abs(x)) { x=a[j-1][m-2]; i=j; } //end of if(Math.abs(.. }//end of for(j=m,j<=n... if(i!=m) { for(j=(m-1);j<=n;j++) { y=a[i-1][j-1]; a[i-1][j-1]=a[m-1][j-1]; a[m-1][j-1]=y; }//end of for(j=(m-1).. for(j=1;j<=n;j++) { y=a[j-1][i-1]; a[j-1][i-1]=a[j-1][m-1]; a[j-1][m-1]=y; }//end of for(j=1;j<=n.... } //end of if(i!=m) if(x != 0.0) { for(i=(m+1);i<=n;i++) { y=a[i-1][m-2]; if(y!=0.0) { y=y/x; a[i-1][m-2]=y; for(j=m;j<=n;j++) { a[i-1][j-1]-=y*a[m-1][j-1]; } for(j=1;j<=n;j++) { a[j-1][m-1]+=y*a[j-1][i-1]; } }//end of if(y!=0.. }//end of for(i=(m+1)... } //end of if(x != 0.0... }//end of for(m=2;m<=(n-1).. }//end of Hessenberg for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(i>(j+1)) a[i-1][j-1]=0; } return a; } public static double[][] QR(double b[][]) { //calculates eigenvalues of a Hessenberg matrix int n=b.length; double rm[][]=new double[2][n]; double a[][]=new double[n+1][n+1]; double wr[]=new double[n+1]; double wi[]=new double[n+1]; int nn,m,l,k,j,its,i,mmin; double z,y,x,w,v,u,t,s,r=0,q=0,p=0,anorm; for(i=0;i= 1) { its=0; do { for (l=nn;l>=2;l--) { s=Math.abs(a[l-1][l-1])+Math.abs(a[l][l]); if (s == 0.0) s=anorm; if ((double)(Math.abs(a[l][l-1]) + s) == s) break; } x=a[nn][nn]; if (l == nn) { wr[nn]=x+t; wi[nn--]=0.0; } else { y=a[nn-1][nn-1]; w=a[nn][nn-1]*a[nn-1][nn]; if (l == (nn-1)) { p=0.5*(y-x); q=p*p+w; z=Math.sqrt(Math.abs(q)); x += t; if (q >= 0.0) { z=p+Matrix.SIGN(z,p); wr[nn-1]=wr[nn]=x+z; if (z!=0) wr[nn]=x-w/z; wi[nn-1]=wi[nn]=0.0; } else { wr[nn-1]=wr[nn]=x+p; wi[nn-1]= -(wi[nn]=z); } nn -= 2; } else { if (its == 30) System.out.println("Matrrix.java, module QR, Too many iterations in hqr"); if (its == 10 || its == 20) { t += x; for (i=1;i<=nn;i++) a[i][i] -= x; s=Math.abs(a[nn][nn-1])+Math.abs(a[nn-1][nn-2]); y=x=0.75*s; w = -0.4375*s*s; } ++its; for (m=(nn-2);m>=l;m--) { z=a[m][m]; r=x-z; s=y-z; p=(r*s-w)/a[m+1][m]+a[m][m+1]; q=a[m+1][m+1]-z-r-s; r=a[m+2][m+1]; s=Math.abs(p)+Math.abs(q)+Math.abs(r); p /= s; q /= s; r /= s; if (m == l) break; u=Math.abs(a[m][m-1])*(Math.abs(q)+Math.abs(r)); v=Math.abs(p)*(Math.abs(a[m-1][m-1])+ Math.abs(z)+Math.abs(a[m+1][m+1])); if ((double)(u+v) == v) break; } for (i=m+2;i<=nn;i++) { a[i][i-2]=0.0; if (i != (m+2)) a[i][i-3]=0.0; } for (k=m;k<=nn-1;k++) { if (k != m) { p=a[k][k-1]; q=a[k+1][k-1]; r=0.0; if (k != (nn-1)) r=a[k+2][k-1]; if ((x=Math.abs(p)+Math.abs(q)+Math.abs(r)) != 0.0) { p /= x; q /= x; r /= x; } } if ((s=Matrix.SIGN(Math.sqrt(p*p+q*q+r*r),p)) != 0.0) { if (k == m) { if (l != m) a[k][k-1] = -a[k][k-1]; } else a[k][k-1] = -s*x; p += s; x=p/s; y=q/s; z=r/s; q /= p; r /= p; for (j=k;j<=nn;j++) { p=a[k][j]+q*a[k+1][j]; if (k != (nn-1)) { p += r*a[k+2][j]; a[k+2][j] -= p*z; } a[k+1][j] -= p*y; a[k][j] -= p*x; } mmin = nn=2;i--) { l=i-1; h=scale=0.0; if (l > 1) { for (k=1;k<=l;k++) scale += Math.abs(a[i-1][k-1]); if (scale == 0.0) e[i-1]=a[i-1][l-1]; else { for (k=1;k<=l;k++) { a[i-1][k-1] /= scale; h += a[i-1][k-1]*a[i-1][k-1]; } f=a[i-1][l-1]; g=(f >= 0.0 ? -Math.sqrt(h) : Math.sqrt(h)); e[i-1]=scale*g; h -= f*g; a[i-1][l-1]=f-g; f=0.0; for (j=1;j<=l;j++) { a[j-1][i-1]=a[i-1][j-1]/h; g=0.0; for (k=1;k<=j;k++) g += a[j-1][k-1]*a[i-1][k-1]; for (k=j+1;k<=l;k++) g += a[k-1][j-1]*a[i-1][k-1]; e[j-1]=g/h; f += e[j-1]*a[i-1][j-1]; } hh=f/(h+h); for (j=1;j<=l;j++) { f=a[i-1][j-1]; e[j-1]=g=e[j-1]-hh*f; for (k=1;k<=j;k++) a[j-1][k-1] -= (f*e[k-1]+g*a[i-1][k-1]); } } } else e[i-1]=a[i-1][l-1]; d[i-1]=h; } d[1-1]=0.0; e[1-1]=0.0; /* Contents of this loop can be omitted if eigenvectors not wanted except for statement d[i-1]=a[i-1][i-1]; */ for (i=1;i<=n;i++) { l=i-1; if (d[i-1] != 0) { for (j=1;j<=l;j++) { g=0.0; for (k=1;k<=l;k++) g += a[i-1][k-1]*a[k-1][j-1]; for (k=1;k<=l;k++) a[k-1][j-1] -= g*a[k-1][i-1]; } } d[i-1]=a[i-1][i-1]; a[i-1][i-1]=1.0; for (j=1;j<=l;j++) a[j-1][i-1]=a[i-1][j-1]=0.0; } return a; } public static double pythag(double a, double b) { //this method is used by QL method double absa,absb; absa=Math.abs(a); absb=Math.abs(b); if (absa > absb) return absa*Math.sqrt(1.0+(absb/absa)*(absb/absa)); else return (absb==0.0 ? 0.0 : absb*Math.sqrt(1.0+(absa/absb)*(absa/absb))); } public static double[][] QL(double d[], double e[], double a[][]) { // QL algorithm : eigenvalues of a symmetric matrix reduced to tridiagonal // form by using method tridiagonal int n=d.length; int m,l,iter,i,j,k; double s,r,p,g,f,dd,c,b; for (i=2;i<=n;i++) e[i-2]=e[i-1]; e[n-1]=0.0; double z[][]=new double[n][n]; for(i=0;i=l;i--) { f=s*e[i-1]; b=c*e[i-1]; e[i]=(r=Matrix.pythag(f,g)); if (r == 0.0) { d[i] -= p; e[m-1]=0.0; break; } s=f/r; c=g/r; g=d[i ]-p; r=(d[i-1]-g)*s+2.0*c*b; d[i ]=g+(p=s*r); g=c*r-b; for (k=1;k<=n;k++) { f=z[k-1][i ]; z[k-1][i ]=s*z[k-1][i-1]+c*f; z[k-1][i-1]=c*z[k-1][i-1]-s*f; } } if (r == 0.0 && i >= l) continue; d[l-1] -= p; e[l-1]=g; e[m-1]=0.0; } } while (m != l); } return z; } public static double[][] eigenQL(double a[][]) { // QL algoritm to solve eigen value problems // symmetric matrices only (real eigen values) // first column of the matrix returns eigen values // second..n+1 column returns eigen vectors. // Note : If matrix is not symmetric DO NOT use // this method use eigenValue method (a QR algorithm) int i,j; int n=a.length; double sum[]=new double[n];; double d[]=new double[n]; double b[][]=new double[n][n]; double e[]=new double[n]; double z[][]=new double[n+1][n]; b=tridiagonal(a,d,e); b=QL(d,e,b); for(j=0;j