/* * pMatrix.java v0.02 May 16th, 1998 * * A general purpose matrix, with 3D thingies, * LU decomposition, inverse, linear system solver, * * (05/16/1998,05/17/1998,4/2005, 5/2008, 6/2008) * * Copyright(c) 1998-2008, Alex S, Particle */ // import java.text.*; /* // things to add: median filter detect edges draw line fill polygon weighted mean gaussian function convolve (kernel) variance standard deviation entropy min max quaternions svd dct/idct dwt/idwt zigzag non-negative matrix factorization sort (use 0 location as index) percentile median */ /** * pMatrix class, to handle all the matrix thingies. * * The 3d operations assume a 4x4 matrix. * Note: This thing is Right Handed!; just like OpenGL :-) */ public class pMatrix { public int rows,cols; private int pitch; private double[] arr; /** * the stack to hold working matrices. */ protected static java.util.Vector stack; /** * get the stack going... */ static{ stack = new java.util.Vector(); } /** * create new matrix of size: Rows x Cols */ public pMatrix(int r,int c){ rows = r <= 0 ? 1 : r; cols = c <= 0 ? 1 : c; pitch = (int)( Math.ceil(Math.log(cols)/Math.log(2)) ); arr = new double[rows * (1< * NOTE: no error checking is performed, you WILL * get a NoSuchElementException if you're not careful * and try to pop an empty stack. * * @return The freshly poped matrix. */ public pMatrix pop(){ pMatrix p = (pMatrix)stack.lastElement(); stack.removeElement(p); rows = p.rows; cols = p.cols; pitch = p.pitch; arr = p.arr; return this; } /** * efficient duplication */ public pMatrix dup(){ pMatrix v = new pMatrix(rows,cols); System.arraycopy(arr,0,v.arr,0,arr.length); return v; } /** * make identity matrix. */ public static pMatrix I(int rows,int cols){ pMatrix v = new pMatrix(rows,cols); for(int i=0;i 0.0 ? 1.0 : -1.0); } } return out; } /** * magnitude. */ public double mag(){ return Math.sqrt(dot(this)); } /** * normalize the whole thing. */ public pMatrix norm(){ return smult(1/mag()); } /** * normalize rows */ public pMatrix normRows(){ pMatrix c = new pMatrix(rows,cols); for(int i=0;i big) big = temp; } if(Math.abs(big) < 0.000001) // singular matrix. return false; vv[i] = 1.0 / big; } for(j=0;j= big) { big=temp; imax=i; } } if(j != imax){ for (k=0;k= 0){ for (j=ii;j<=i-1;j++) sum -= m[(i<=0;i--){ sum=b[i]; for (j=i+1;j= i ) ? 1 : 0 ); sj = dj + ( ( dj >= j ) ? 1 : 0 ); // copy element mb[di * 3 + dj] = mr[si * 4 + sj]; } } } private static double m4_det(double[] mr) { double det, result = 0, i = 1; double[] msub3 = new double[3*3]; int n; for ( n = 0; n < 4; n++, i *= -1 ){ m4_submat( mr, msub3, 0, n ); det = m3_det( msub3 ); result += mr[n] * det * i; } return result; } private static boolean m4_inverse(double[] mr, double[] ma ){ double mdet = m4_det( ma ); double[] mtemp = new double[3*3]; int i, j, sign; if (Math.abs( mdet ) < (double)0.0005 ){ // m4_identity( mr ); return false; } for ( i = 0; i < 4; i++ ) for ( j = 0; j < 4; j++ ){ sign = 1 - ( (i +j) % 2 ) * 2; m4_submat( ma, mtemp, i, j ); mr[i+j*4] = ( m3_det( mtemp ) * sign ) / mdet; } return true; } /** * output matrix in csv format */ public String toString(){ StringBuffer sb = new StringBuffer(); sb.append("pMatrix["+rows+"x"+cols+"][pitch="+pitch+"][len="+arr.length+"]:\n"); /* NumberFormat nf = NumberFormat.getInstance(); nf.setGroupingUsed(false); nf.setMaximumFractionDigits(0x6); nf.setMaximumIntegerDigits(0xFF); nf.setMinimumFractionDigits(0); nf.setMinimumIntegerDigits(1); */ for(int i=0;i