001    package jcolibri.extensions.textual.IE.common.crn.matrix;
002    
003    
004    import java.io.PrintWriter;
005    import java.text.DecimalFormat;
006    import java.text.DecimalFormatSymbols;
007    import java.text.NumberFormat;
008    import java.util.Locale;
009    
010    /**
011       Jama = Java Matrix class.
012    <P>
013       The Java Matrix Class provides the fundamental operations of numerical
014       linear algebra.  Various constructors create Matrices from two dimensional
015       arrays of double precision floating point numbers.  Various "gets" and
016       "sets" provide access to submatrices and matrix elements.  Several methods 
017       implement basic matrix arithmetic, including matrix addition and
018       multiplication, matrix norms, and element-by-element array operations.
019       Methods for reading and printing matrices are also included.  All the
020       operations in this version of the Matrix Class involve real matrices.
021       Complex matrices may be handled in a future version.
022    <P>
023       Five fundamental matrix decompositions, which consist of pairs or triples
024       of matrices, permutation vectors, and the like, produce results in five
025       decomposition classes.  These decompositions are accessed by the Matrix
026       class to compute solutions of simultaneous linear equations, determinants,
027       inverses and other matrix functions.  The five decompositions are:
028    <P><UL>
029       <LI>Cholesky Decomposition of symmetric, positive definite matrices.
030       <LI>LU Decomposition of rectangular matrices.
031       <LI>QR Decomposition of rectangular matrices.
032       <LI>Singular Value Decomposition of rectangular matrices.
033       <LI>Eigenvalue Decomposition of both symmetric and nonsymmetric square matrices.
034    </UL>
035    <DL>
036    <DT><B>Example of use:</B></DT>
037    <P>
038    <DD>Solve a linear system A x = b and compute the residual norm, ||b - A x||.
039    <P><PRE>
040          double[][] vals = {{1.,2.,3},{4.,5.,6.},{7.,8.,10.}};
041          Matrix A = new Matrix(vals);
042          Matrix b = Matrix.random(3,1);
043          Matrix x = A.solve(b);
044          Matrix r = A.times(x).minus(b);
045          double rnorm = r.normInf();
046    </PRE></DD>
047    </DL>
048    
049    @author The MathWorks, Inc. and the National Institute of Standards and Technology.
050    @version 5 August 1998
051    */
052    
053    public class FloatMatrix implements Cloneable, java.io.Serializable, Matrix {
054    
055    /* ------------------------
056       Class variables
057     * ------------------------ */
058    
059        private static final long serialVersionUID = 1L;
060    
061    /** Array for internal storage of elements.
062       @serial internal array storage.
063       */
064       private float[][] A;
065    
066       /** Row and column dimensions.
067       @serial row dimension.
068       @serial column dimension.
069       */
070       private int m, n;
071    
072    /* ------------------------
073       Constructors
074     * ------------------------ */
075    
076       /** Construct an m-by-n matrix of zeros. 
077       @param m    Number of rows.
078       @param n    Number of colums.
079       */
080    
081       public FloatMatrix (int m, int n) {
082          this.m = m;
083          this.n = n;
084          A = new float[m][n];
085       }
086    
087       /** Construct an m-by-n constant matrix.
088       @param m    Number of rows.
089       @param n    Number of colums.
090       @param s    Fill the matrix with this scalar value.
091       */
092    
093       public FloatMatrix (int m, int n, float s) {
094          this.m = m;
095          this.n = n;
096          A = new float[m][n];
097          for (int i = 0; i < m; i++) {
098             for (int j = 0; j < n; j++) {
099                A[i][j] = s;
100             }
101          }
102       }
103    
104       /** Construct a matrix from a 2-D array.
105       @param A    Two-dimensional array of floats.
106       @exception  IllegalArgumentException All rows must have the same length
107       @see        #constructWithCopy
108       */
109    
110       public FloatMatrix (float[][] A) {
111          m = A.length;
112          n = A[0].length;
113          for (int i = 0; i < m; i++) {
114             if (A[i].length != n) {
115                throw new IllegalArgumentException("All rows must have the same length.");
116             }
117          }
118          this.A = A;
119       }
120    
121       /** Construct a matrix quickly without checking arguments.
122       @param A    Two-dimensional array of floats.
123       @param m    Number of rows.
124       @param n    Number of colums.
125       */
126    
127       public FloatMatrix (float[][] A, int m, int n) {
128          this.A = A;
129          this.m = m;
130          this.n = n;
131       }
132    
133       /** Construct a matrix from a one-dimensional packed array
134       @param vals One-dimensional array of floats, packed by columns (ala Fortran).
135       @param m    Number of rows.
136       @exception  IllegalArgumentException Array length must be a multiple of m.
137       */
138    
139       public FloatMatrix (float vals[], int m) {
140          this.m = m;
141          n = (m != 0 ? vals.length/m : 0);
142          if (m*n != vals.length) {
143             throw new IllegalArgumentException("Array length must be a multiple of m.");
144          }
145          A = new float[m][n];
146          for (int i = 0; i < m; i++) {
147             for (int j = 0; j < n; j++) {
148                A[i][j] = vals[i+j*m];
149             }
150          }
151       }
152    
153    /* ------------------------
154       Public Methods
155     * ------------------------ */
156    
157       /** Construct a matrix from a copy of a 2-D array.
158       @param A    Two-dimensional array of floats.
159       @exception  IllegalArgumentException All rows must have the same length
160       */
161    
162       public static FloatMatrix constructWithCopy(float[][] A) {
163          int m = A.length;
164          int n = A[0].length;
165          FloatMatrix X = new FloatMatrix(m,n);
166          float[][] C = X.getArray();
167          for (int i = 0; i < m; i++) {
168             if (A[i].length != n) {
169                throw new IllegalArgumentException
170                   ("All rows must have the same length.");
171             }
172             for (int j = 0; j < n; j++) {
173                C[i][j] = A[i][j];
174             }
175          }
176          return X;
177       }
178    
179       /** Make a deep copy of a matrix
180       */
181    
182       public FloatMatrix copy () {
183           FloatMatrix X = new FloatMatrix(m,n);
184          float[][] C = X.getArray();
185          for (int i = 0; i < m; i++) {
186             for (int j = 0; j < n; j++) {
187                C[i][j] = A[i][j];
188             }
189          }
190          return X;
191       }
192    
193       /** Clone the Matrix object.
194       */
195    
196       public Object clone () {
197          return this.copy();
198       }
199    
200       /** Access the internal two-dimensional array.
201       @return     Pointer to the two-dimensional array of matrix elements.
202       */
203    
204       public float[][] getArray () {
205          return A;
206       }
207    
208       /** Copy the internal two-dimensional array.
209       @return     Two-dimensional array copy of matrix elements.
210       */
211    
212       public float[][] getArrayCopy () {
213          float[][] C = new float[m][n];
214          for (int i = 0; i < m; i++) {
215             for (int j = 0; j < n; j++) {
216                C[i][j] = A[i][j];
217             }
218          }
219          return C;
220       }
221    
222       /** Make a one-dimensional column packed copy of the internal array.
223       @return     Matrix elements packed in a one-dimensional array by columns.
224       */
225    
226       public float[] getColumnPackedCopy () {
227          float[] vals = new float[m*n];
228          for (int i = 0; i < m; i++) {
229             for (int j = 0; j < n; j++) {
230                vals[i+j*m] = A[i][j];
231             }
232          }
233          return vals;
234       }
235    
236       /** Make a one-dimensional row packed copy of the internal array.
237       @return     Matrix elements packed in a one-dimensional array by rows.
238       */
239    
240       public float[] getRowPackedCopy () {
241          float[] vals = new float[m*n];
242          for (int i = 0; i < m; i++) {
243             for (int j = 0; j < n; j++) {
244                vals[i*n+j] = A[i][j];
245             }
246          }
247          return vals;
248       }
249    
250       /** Get row dimension.
251       @return     m, the number of rows.
252       */
253    
254       public int getRowDimension () {
255          return m;
256       }
257    
258       /** Get column dimension.
259       @return     n, the number of columns.
260       */
261    
262       public int getColumnDimension () {
263          return n;
264       }
265    
266       /** Get a single element.
267       @param i    Row index.
268       @param j    Column index.
269       @return     A(i,j)
270       @exception  ArrayIndexOutOfBoundsException
271       */
272    
273       public float get (int i, int j) {
274          return A[i][j];
275       }
276    
277       /** Get a submatrix.
278       @param i0   Initial row index
279       @param i1   Final row index
280       @param j0   Initial column index
281       @param j1   Final column index
282       @return     A(i0:i1,j0:j1)
283       @exception  ArrayIndexOutOfBoundsException Submatrix indices
284       */
285    
286       public FloatMatrix getMatrix (int i0, int i1, int j0, int j1) {
287           FloatMatrix X = new FloatMatrix(i1-i0+1,j1-j0+1);
288          float[][] B = X.getArray();
289          try {
290             for (int i = i0; i <= i1; i++) {
291                for (int j = j0; j <= j1; j++) {
292                   B[i-i0][j-j0] = A[i][j];
293                }
294             }
295          } catch(ArrayIndexOutOfBoundsException e) {
296             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
297          }
298          return X;
299       }
300    
301       /** Get a submatrix.
302       @param r    Array of row indices.
303       @param c    Array of column indices.
304       @return     A(r(:),c(:))
305       @exception  ArrayIndexOutOfBoundsException Submatrix indices
306       */
307    
308       public FloatMatrix getMatrix (int[] r, int[] c) {
309           FloatMatrix X = new FloatMatrix(r.length,c.length);
310          float[][] B = X.getArray();
311          try {
312             for (int i = 0; i < r.length; i++) {
313                for (int j = 0; j < c.length; j++) {
314                   B[i][j] = A[r[i]][c[j]];
315                }
316             }
317          } catch(ArrayIndexOutOfBoundsException e) {
318             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
319          }
320          return X;
321       }
322    
323       /** Get a submatrix.
324       @param i0   Initial row index
325       @param i1   Final row index
326       @param c    Array of column indices.
327       @return     A(i0:i1,c(:))
328       @exception  ArrayIndexOutOfBoundsException Submatrix indices
329       */
330    
331       public FloatMatrix getMatrix (int i0, int i1, int[] c) {
332           FloatMatrix X = new FloatMatrix(i1-i0+1,c.length);
333          float[][] B = X.getArray();
334          try {
335             for (int i = i0; i <= i1; i++) {
336                for (int j = 0; j < c.length; j++) {
337                   B[i-i0][j] = A[i][c[j]];
338                }
339             }
340          } catch(ArrayIndexOutOfBoundsException e) {
341             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
342          }
343          return X;
344       }
345    
346       /** Get a submatrix.
347       @param r    Array of row indices.
348       @param i0   Initial column index
349       @param i1   Final column index
350       @return     A(r(:),j0:j1)
351       @exception  ArrayIndexOutOfBoundsException Submatrix indices
352       */
353    
354       public FloatMatrix getMatrix (int[] r, int j0, int j1) {
355           FloatMatrix X = new FloatMatrix(r.length,j1-j0+1);
356          float[][] B = X.getArray();
357          try {
358             for (int i = 0; i < r.length; i++) {
359                for (int j = j0; j <= j1; j++) {
360                   B[i][j-j0] = A[r[i]][j];
361                }
362             }
363          } catch(ArrayIndexOutOfBoundsException e) {
364             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
365          }
366          return X;
367       }
368    
369       /** Set a single element.
370       @param i    Row index.
371       @param j    Column index.
372       @param s    A(i,j).
373       @exception  ArrayIndexOutOfBoundsException
374       */
375    
376       public void set (int i, int j, float s) {
377          A[i][j] = s;
378       }
379    
380       /** Set a submatrix.
381       @param i0   Initial row index
382       @param i1   Final row index
383       @param j0   Initial column index
384       @param j1   Final column index
385       @param X    A(i0:i1,j0:j1)
386       @exception  ArrayIndexOutOfBoundsException Submatrix indices
387       */
388    
389       public void setMatrix (int i0, int i1, int j0, int j1, FloatMatrix X) {
390          try {
391             for (int i = i0; i <= i1; i++) {
392                for (int j = j0; j <= j1; j++) {
393                   A[i][j] = X.get(i-i0,j-j0);
394                }
395             }
396          } catch(ArrayIndexOutOfBoundsException e) {
397             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
398          }
399       }
400    
401       /** Set a submatrix.
402       @param r    Array of row indices.
403       @param c    Array of column indices.
404       @param X    A(r(:),c(:))
405       @exception  ArrayIndexOutOfBoundsException Submatrix indices
406       */
407    
408       public void setMatrix (int[] r, int[] c, FloatMatrix X) {
409          try {
410             for (int i = 0; i < r.length; i++) {
411                for (int j = 0; j < c.length; j++) {
412                   A[r[i]][c[j]] = X.get(i,j);
413                }
414             }
415          } catch(ArrayIndexOutOfBoundsException e) {
416             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
417          }
418       }
419    
420       /** Set a submatrix.
421       @param r    Array of row indices.
422       @param j0   Initial column index
423       @param j1   Final column index
424       @param X    A(r(:),j0:j1)
425       @exception  ArrayIndexOutOfBoundsException Submatrix indices
426       */
427    
428       public void setMatrix (int[] r, int j0, int j1, FloatMatrix X) {
429          try {
430             for (int i = 0; i < r.length; i++) {
431                for (int j = j0; j <= j1; j++) {
432                   A[r[i]][j] = X.get(i,j-j0);
433                }
434             }
435          } catch(ArrayIndexOutOfBoundsException e) {
436             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
437          }
438       }
439    
440       /** Set a submatrix.
441       @param i0   Initial row index
442       @param i1   Final row index
443       @param c    Array of column indices.
444       @param X    A(i0:i1,c(:))
445       @exception  ArrayIndexOutOfBoundsException Submatrix indices
446       */
447    
448       public void setMatrix (int i0, int i1, int[] c, FloatMatrix X) {
449          try {
450             for (int i = i0; i <= i1; i++) {
451                for (int j = 0; j < c.length; j++) {
452                   A[i][c[j]] = X.get(i-i0,j);
453                }
454             }
455          } catch(ArrayIndexOutOfBoundsException e) {
456             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
457          }
458       }
459    
460       /** Matrix transpose.
461       @return    A'
462       */
463    
464       public FloatMatrix transpose () {
465           FloatMatrix X = new FloatMatrix(n,m);
466          float[][] C = X.getArray();
467          for (int i = 0; i < m; i++) {
468             for (int j = 0; j < n; j++) {
469                C[j][i] = A[i][j];
470             }
471          }
472          return X;
473       }
474    
475       /** One norm
476       @return    maximum column sum.
477       */
478    
479       public float norm1 () {
480          float f = 0;
481          for (int j = 0; j < n; j++) {
482             float s = 0;
483             for (int i = 0; i < m; i++) {
484                s += Math.abs(A[i][j]);
485             }
486             f = Math.max(f,s);
487          }
488          return f;
489       }
490    
491    //   /** Two norm
492    //   @return    maximum singular value.
493    //   */
494    //
495    //   public float norm2 () {
496    //      return (new SingularValueDecomposition(this).norm2());
497    //   }
498    
499       /** Infinity norm
500       @return    maximum row sum.
501       */
502    
503       public float normInf () {
504          float f = 0;
505          for (int i = 0; i < m; i++) {
506             float s = 0;
507             for (int j = 0; j < n; j++) {
508                s += Math.abs(A[i][j]);
509             }
510             f = Math.max(f,s);
511          }
512          return f;
513       }
514    
515    //   /** Frobenius norm
516    //   @return    sqrt of sum of squares of all elements.
517    //   */
518    //
519    //   public float normF () {
520    //      float f = 0;
521    //      for (int i = 0; i < m; i++) {
522    //         for (int j = 0; j < n; j++) {
523    //            f = Maths.hypot(f,A[i][j]);
524    //         }
525    //      }
526    //      return f;
527    //   }
528    
529       /**  Unary minus
530       @return    -A
531       */
532    
533       public FloatMatrix uminus () {
534           FloatMatrix X = new FloatMatrix(m,n);
535          float[][] C = X.getArray();
536          for (int i = 0; i < m; i++) {
537             for (int j = 0; j < n; j++) {
538                C[i][j] = -A[i][j];
539             }
540          }
541          return X;
542       }
543    
544       /** C = A + B
545       @param B    another matrix
546       @return     A + B
547       */
548    
549       public FloatMatrix plus (FloatMatrix B) {
550          checkMatrixDimensions(B);
551          FloatMatrix X = new FloatMatrix(m,n);
552          float[][] C = X.getArray();
553          for (int i = 0; i < m; i++) {
554             for (int j = 0; j < n; j++) {
555                C[i][j] = A[i][j] + B.A[i][j];
556             }
557          }
558          return X;
559       }
560    
561       /** A = A + B
562       @param B    another matrix
563       @return     A + B
564       */
565    
566       public FloatMatrix plusEquals (FloatMatrix B) {
567          checkMatrixDimensions(B);
568          for (int i = 0; i < m; i++) {
569             for (int j = 0; j < n; j++) {
570                A[i][j] = A[i][j] + B.A[i][j];
571             }
572          }
573          return this;
574       }
575    
576       /** C = A - B
577       @param B    another matrix
578       @return     A - B
579       */
580    
581       public FloatMatrix minus (FloatMatrix B) {
582          checkMatrixDimensions(B);
583          FloatMatrix X = new FloatMatrix(m,n);
584          float[][] C = X.getArray();
585          for (int i = 0; i < m; i++) {
586             for (int j = 0; j < n; j++) {
587                C[i][j] = A[i][j] - B.A[i][j];
588             }
589          }
590          return X;
591       }
592    
593       /** A = A - B
594       @param B    another matrix
595       @return     A - B
596       */
597    
598       public FloatMatrix minusEquals (FloatMatrix B) {
599          checkMatrixDimensions(B);
600          for (int i = 0; i < m; i++) {
601             for (int j = 0; j < n; j++) {
602                A[i][j] = A[i][j] - B.A[i][j];
603             }
604          }
605          return this;
606       }
607    
608       /** Element-by-element multiplication, C = A.*B
609       @param B    another matrix
610       @return     A.*B
611       */
612    
613       public FloatMatrix arrayTimes (FloatMatrix B) {
614          checkMatrixDimensions(B);
615          FloatMatrix X = new FloatMatrix(m,n);
616          float[][] C = X.getArray();
617          for (int i = 0; i < m; i++) {
618             for (int j = 0; j < n; j++) {
619                C[i][j] = A[i][j] * B.A[i][j];
620             }
621          }
622          return X;
623       }
624    
625       /** Element-by-element multiplication in place, A = A.*B
626       @param B    another matrix
627       @return     A.*B
628       */
629    
630       public FloatMatrix arrayTimesEquals (FloatMatrix B) {
631          checkMatrixDimensions(B);
632          for (int i = 0; i < m; i++) {
633             for (int j = 0; j < n; j++) {
634                A[i][j] = A[i][j] * B.A[i][j];
635             }
636          }
637          return this;
638       }
639    
640       /** Element-by-element right division, C = A./B
641       @param B    another matrix
642       @return     A./B
643       */
644    
645       public FloatMatrix arrayRightDivide (FloatMatrix B) {
646          checkMatrixDimensions(B);
647          FloatMatrix X = new FloatMatrix(m,n);
648          float[][] C = X.getArray();
649          for (int i = 0; i < m; i++) {
650             for (int j = 0; j < n; j++) {
651                C[i][j] = A[i][j] / B.A[i][j];
652             }
653          }
654          return X;
655       }
656    
657       /** Element-by-element right division in place, A = A./B
658       @param B    another matrix
659       @return     A./B
660       */
661    
662       public FloatMatrix arrayRightDivideEquals (FloatMatrix B) {
663          checkMatrixDimensions(B);
664          for (int i = 0; i < m; i++) {
665             for (int j = 0; j < n; j++) {
666                A[i][j] = A[i][j] / B.A[i][j];
667             }
668          }
669          return this;
670       }
671    
672       /** Element-by-element left division, C = A.\B
673       @param B    another matrix
674       @return     A.\B
675       */
676    
677       public FloatMatrix arrayLeftDivide (FloatMatrix B) {
678          checkMatrixDimensions(B);
679          FloatMatrix X = new FloatMatrix(m,n);
680          float[][] C = X.getArray();
681          for (int i = 0; i < m; i++) {
682             for (int j = 0; j < n; j++) {
683                C[i][j] = B.A[i][j] / A[i][j];
684             }
685          }
686          return X;
687       }
688    
689       /** Element-by-element left division in place, A = A.\B
690       @param B    another matrix
691       @return     A.\B
692       */
693    
694       public FloatMatrix arrayLeftDivideEquals (FloatMatrix B) {
695          checkMatrixDimensions(B);
696          for (int i = 0; i < m; i++) {
697             for (int j = 0; j < n; j++) {
698                A[i][j] = B.A[i][j] / A[i][j];
699             }
700          }
701          return this;
702       }
703    
704       /** Multiply a matrix by a scalar, C = s*A
705       @param s    scalar
706       @return     s*A
707       */
708    
709       public FloatMatrix times (float s) {
710          FloatMatrix X = new FloatMatrix(m,n);
711          float[][] C = X.getArray();
712          for (int i = 0; i < m; i++) {
713             for (int j = 0; j < n; j++) {
714                C[i][j] = s*A[i][j];
715             }
716          }
717          return X;
718       }
719    
720       /** Multiply a matrix by a scalar in place, A = s*A
721       @param s    scalar
722       @return     replace A by s*A
723       */
724    
725       public FloatMatrix timesEquals (float s) {
726          for (int i = 0; i < m; i++) {
727             for (int j = 0; j < n; j++) {
728                A[i][j] = s*A[i][j];
729             }
730          }
731          return this;
732       }
733    
734       /** Linear algebraic matrix multiplication, A * B
735       @param B    another matrix
736       @return     FloatMatrix product, A * B
737       @exception  IllegalArgumentException FloatMatrix inner dimensions must agree.
738       */
739    
740       public FloatMatrix times (FloatMatrix B) {
741          if (B.m != n) {
742             throw new IllegalArgumentException("FloatMatrix inner dimensions must agree.");
743          }
744          FloatMatrix X = new FloatMatrix(m,B.n);
745          float[][] C = X.getArray();
746          float[] Bcolj = new float[n];
747          for (int j = 0; j < B.n; j++) {
748             for (int k = 0; k < n; k++) {
749                Bcolj[k] = B.A[k][j];
750             }
751             for (int i = 0; i < m; i++) {
752                float[] Arowi = A[i];
753                float s = 0;
754                for (int k = 0; k < n; k++) {
755                   s += Arowi[k]*Bcolj[k];
756                }
757                C[i][j] = s;
758             }
759          }
760          return X;
761       }
762    
763    //   /** LU Decomposition
764    //   @return     LUDecomposition
765    //   @see LUDecomposition
766    //   */
767    //
768    //   public LUDecomposition lu () {
769    //      return new LUDecomposition(this);
770    //   }
771    //
772    //   /** QR Decomposition
773    //   @return     QRDecomposition
774    //   @see QRDecomposition
775    //   */
776    //
777    //   public QRDecomposition qr () {
778    //      return new QRDecomposition(this);
779    //   }
780    //
781    //   /** Cholesky Decomposition
782    //   @return     CholeskyDecomposition
783    //   @see CholeskyDecomposition
784    //   */
785    //
786    //   public CholeskyDecomposition chol () {
787    //      return new CholeskyDecomposition(this);
788    //   }
789    //
790    //   /** Singular Value Decomposition
791    //   @return     SingularValueDecomposition
792    //   @see SingularValueDecomposition
793    //   */
794    //
795    //   public SingularValueDecomposition svd () {
796    //      return new SingularValueDecomposition(this);
797    //   }
798    //
799    //   /** Eigenvalue Decomposition
800    //   @return     EigenvalueDecomposition
801    //   @see EigenvalueDecomposition
802    //   */
803    //
804    //   public EigenvalueDecomposition eig () {
805    //      return new EigenvalueDecomposition(this);
806    //   }
807    //
808    //   /** Solve A*X = B
809    //   @param B    right hand side
810    //   @return     solution if A is square, least squares solution otherwise
811    //   */
812    //
813    //   public FloatMatrix solve (FloatMatrix B) {
814    //      return (m == n ? (new LUDecomposition(this)).solve(B) :
815    //                       (new QRDecomposition(this)).solve(B));
816    //   }
817    //
818    //   /** Solve X*A = B, which is also A'*X' = B'
819    //   @param B    right hand side
820    //   @return     solution if A is square, least squares solution otherwise.
821    //   */
822    //
823    //   public FloatMatrix solveTranspose (FloatMatrix B) {
824    //      return transpose().solve(B.transpose());
825    //   }
826    //
827    //   /** FloatMatrix inverse or pseudoinverse
828    //   @return     inverse(A) if A is square, pseudoinverse otherwise.
829    //   */
830    //
831    //   public FloatMatrix inverse () {
832    //      return solve(identity(m,m));
833    //   }
834    //
835    //   /** FloatMatrix determinant
836    //   @return     determinant
837    //   */
838    //
839    //   public float det () {
840    //      return new LUDecomposition(this).det();
841    //   }
842    //
843    //   /** FloatMatrix rank
844    //   @return     effective numerical rank, obtained from SVD.
845    //   */
846    //
847    //   public int rank () {
848    //      return new SingularValueDecomposition(this).rank();
849    //   }
850    //
851    //   /** FloatMatrix condition (2 norm)
852    //   @return     ratio of largest to smallest singular value.
853    //   */
854    //
855    //   public float cond () {
856    //      return new SingularValueDecomposition(this).cond();
857    //   }
858    
859       /** FloatMatrix trace.
860       @return     sum of the diagonal elements.
861       */
862    
863       public float trace () {
864          float t = 0;
865          for (int i = 0; i < Math.min(m,n); i++) {
866             t += A[i][i];
867          }
868          return t;
869       }
870    
871       /** Generate matrix with random elements
872       @param m    Number of rows.
873       @param n    Number of colums.
874       @return     An m-by-n matrix with uniformly distributed random elements.
875       */
876    
877       public static FloatMatrix random (int m, int n) {
878          FloatMatrix A = new FloatMatrix(m,n);
879          float[][] X = A.getArray();
880          for (int i = 0; i < m; i++) {
881             for (int j = 0; j < n; j++) {
882                X[i][j] = (float)Math.random();
883             }
884          }
885          return A;
886       }
887    
888       /** Generate identity matrix
889       @param m    Number of rows.
890       @param n    Number of colums.
891       @return     An m-by-n matrix with ones on the diagonal and zeros elsewhere.
892       */
893    
894       public static FloatMatrix identity (int m, int n) {
895          FloatMatrix A = new FloatMatrix(m,n);
896          float[][] X = A.getArray();
897          for (int i = 0; i < m; i++) {
898             for (int j = 0; j < n; j++) {
899                X[i][j] = (float)(i == j ? 1.0 : 0.0);
900             }
901          }
902          return A;
903       }
904    
905    
906       /** Print the matrix to stdout.   Line the elements up in columns
907         * with a Fortran-like 'Fw.d' style format.
908       @param w    Column width.
909       @param d    Number of digits after the decimal.
910       */
911    
912       public void print (int w, int d) {
913          print(new PrintWriter(System.out,true),w,d); }
914    
915       /** Print the matrix to the output stream.   Line the elements up in
916         * columns with a Fortran-like 'Fw.d' style format.
917       @param output Output stream.
918       @param w      Column width.
919       @param d      Number of digits after the decimal.
920       */
921    
922       public void print (PrintWriter output, int w, int d) {
923          DecimalFormat format = new DecimalFormat();
924          format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
925          format.setMinimumIntegerDigits(1);
926          format.setMaximumFractionDigits(d);
927          format.setMinimumFractionDigits(d);
928          format.setGroupingUsed(false);
929          print(output,format,w+2);
930       }
931    
932       /** Print the matrix to stdout.  Line the elements up in columns.
933         * Use the format object, and right justify within columns of width
934         * characters.
935         * Note that is the matrix is to be read back in, you probably will want
936         * to use a NumberFormat that is set to US Locale.
937       @param format A  Formatting object for individual elements.
938       @param width     Field width for each column.
939       @see java.text.DecimalFormat#setDecimalFormatSymbols
940       */
941    
942       public void print (NumberFormat format, int width) {
943          print(new PrintWriter(System.out,true),format,width); }
944    
945       // DecimalFormat is a little disappointing coming from Fortran or C's printf.
946       // Since it doesn't pad on the left, the elements will come out different
947       // widths.  Consequently, we'll pass the desired column width in as an
948       // argument and do the extra padding ourselves.
949    
950       /** Print the matrix to the output stream.  Line the elements up in columns.
951         * Use the format object, and right justify within columns of width
952         * characters.
953         * Note that is the matrix is to be read back in, you probably will want
954         * to use a NumberFormat that is set to US Locale.
955       @param output the output stream.
956       @param format A formatting object to format the matrix elements 
957       @param width  Column width.
958       @see java.text.DecimalFormat#setDecimalFormatSymbols
959       */
960    
961       public void print (PrintWriter output, NumberFormat format, int width) {
962          output.println();  // start on new line.
963          for (int i = 0; i < m; i++) {
964             for (int j = 0; j < n; j++) {
965                String s = format.format(A[i][j]); // format the number
966                int padding = Math.max(1,width-s.length()); // At _least_ 1 space
967                for (int k = 0; k < padding; k++)
968                   output.print(' ');
969                output.print(s);
970             }
971             output.println();
972          }
973          output.println();   // end with blank line.
974       }
975    
976     
977    
978    
979    /* ------------------------
980       Private Methods
981     * ------------------------ */
982    
983       /** Check if size(A) == size(B) **/
984    
985       private void checkMatrixDimensions (FloatMatrix B) {
986          if (B.m != m || B.n != n) {
987             throw new IllegalArgumentException("FloatMatrix dimensions must agree.");
988          }
989       }
990    
991    public int getColumns()
992    {
993        
994        return n;
995    }
996    
997    public Matrix getDeepTraspose()
998    {
999        return this.transpose();
1000    }
1001    
1002    public int getRows()
1003    {
1004        // TODO Auto-generated method stub
1005        return m;
1006    }
1007    
1008    public Matrix getShallowTraspose()
1009    {
1010        
1011        return this.transpose();
1012    }
1013    
1014    public float getValue(int row, int column)
1015    {
1016        // TODO Auto-generated method stub
1017        return this.get(row, column);
1018    }
1019    
1020    public Matrix multiply(Matrix other)
1021    {
1022        if (other.getRows() != this.getColumns()) {
1023            throw new IllegalArgumentException("FloatMatrix inner dimensions must agree.");
1024         }
1025         FloatMatrix X = new FloatMatrix(this.getRows(),other.getColumns());
1026         float[][] C = X.getArray();
1027         float[] Bcolj = new float[n];
1028         for (int j = 0; j < other.getColumns(); j++) {
1029            for (int k = 0; k < n; k++) {
1030               Bcolj[k] = other.getValue(k,j);
1031            }
1032            for (int i = 0; i < m; i++) {
1033               float[] Arowi = A[i];
1034               float s = 0;
1035               for (int k = 0; k < n; k++) {
1036                  s += Arowi[k]*Bcolj[k];
1037               }
1038               C[i][j] = s;
1039            }
1040         }
1041         return X;
1042    }
1043    
1044    public void setValue(int row, int column, float value)
1045    {
1046        this.set(row, column, value);
1047        
1048    }
1049    
1050    public float multiply(Matrix other, int thisRow, int otherColumn)
1051    {
1052        float sum = 0;
1053        for(int i=0; i<other.getRows(); i++)
1054            sum = other.getValue(i, otherColumn)*this.getValue(thisRow, i);
1055        return sum;
1056    }
1057    
1058    }
1059