Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jmat/data/Matrix.java


1   package jmat.data;
2   
3   import jmat.data.arrayTools.*;
4   
5   import jmat.data.matrixDecompositions.*;
6   
7   import jmat.function.DoubleFunction;
8   
9   import jmat.io.data.MatrixFile;
10  import jmat.io.data.MatrixMMLFile;
11  import jmat.io.data.fileTools.MatrixMML;
12  import jmat.io.data.fileTools.MatrixString;
13  
14  import jmat.io.gui.FrameView;
15  import jmat.io.gui.MatrixPlot2D;
16  import jmat.io.gui.MatrixPlot3D;
17  import jmat.io.gui.MatrixTable;
18  
19  import java.io.File;
20  import java.io.Serializable;
21  
22  import org.jdom.Element;
23  
24  
25  /**
26  <P>
27     The Matrix Class provides the fundamental operations of numerical linear algebra (from the package JAMA),
28     basic manipulations, and visualization tools.
29     All the operations in this version of the Matrix Class involve only real matrices.
30  
31  @author Yann RICHET, matrix algebraic operations and decompositions are a copy of the package JAMA (by The MathWorks Inc. and the NIST).
32  @version 1.0
33  */
34  public class Matrix implements Cloneable, Serializable
35  {
36      //~ Instance fields ////////////////////////////////////////////////////////
37  
38      /* ------------------------
39         Class variables
40       * ------------------------ */
41  
42      /** Array for internal storage of elements.
43      @serial internal array storage.
44      */
45      protected double[][] A;
46  
47      /** Row and column dimensions.
48      @serial row dimension.
49      @serial column dimension.
50      */
51      protected int m;
52  
53      /** Row and column dimensions.
54      @serial row dimension.
55      @serial column dimension.
56      */
57      protected int n;
58  
59      //~ Constructors ///////////////////////////////////////////////////////////
60  
61      /* ------------------------
62         Constructors
63       * ------------------------ */
64  
65      /** Construct an m-by-n matrix of zeros.
66      @param m    Number of rows.
67      @param n    Number of colums.
68      */
69      public Matrix(int m, int n)
70      {
71          this.m = m;
72          this.n = n;
73          A = new double[m][n];
74      }
75  
76      /** Construct an m-by-n constant matrix.
77      @param m    Number of rows.
78      @param n    Number of colums.
79      @param s    Fill the matrix with this scalar value.
80      */
81      public Matrix(int m, int n, double s)
82      {
83          this.m = m;
84          this.n = n;
85          A = new double[m][n];
86  
87          for (int i = 0; i < m; i++)
88          {
89              for (int j = 0; j < n; j++)
90              {
91                  A[i][j] = s;
92              }
93          }
94      }
95  
96      /** Construct a matrix from a 2D-array.
97      @param B    Two-dimensional array of doubles.
98      @exception  IllegalArgumentException All rows must have the same length
99      @see        #constructWithCopy
100     */
101     public Matrix(double[][] B)
102     {
103         m = B.length;
104         n = B[0].length;
105         A = new double[m][n];
106 
107         for (int i = 0; i < m; i++)
108         {
109             if (B[i].length != n)
110             {
111                 throw new IllegalArgumentException(
112                     "All rows must have the same length : " + n);
113             }
114 
115             for (int j = 0; j < n; j++)
116             {
117                 A[i][j] = B[i][j];
118             }
119         }
120     }
121 
122     /** Construct a matrix from a 2D-array.
123     @param B    Two-dimensional array of doubles.
124     @param m    Number of rows.
125     @param n    Number of columns.
126     @exception  IllegalArgumentException All rows must have the same length
127     @see        #constructWithCopy
128     */
129     public Matrix(double[][] B, int m, int n)
130     {
131         this.m = m;
132         this.n = n;
133         A = new double[m][n];
134 
135         for (int i = 0; i < m; i++)
136         {
137             if (B[i].length < n)
138             {
139                 throw new IllegalArgumentException(
140                     "All rows must have a length >= " + n);
141             }
142 
143             for (int j = 0; j < n; j++)
144             {
145                 A[i][j] = B[i][j];
146             }
147         }
148     }
149 
150     /** Construct a matrix from a one-dimensional packed array
151     @param vals One-dimensional array of doubles, packed by columns (ala Fortran).
152     @param m    Number of rows.
153     @exception  IllegalArgumentException Array length must be a multiple of m.
154     */
155     public Matrix(double[] vals, int m)
156     {
157         this.m = m;
158         n = ((m != 0) ? (vals.length / m) : 0);
159 
160         if ((m * n) != vals.length)
161         {
162             throw new IllegalArgumentException(
163                 "Array length must be a multiple of " + m);
164         }
165 
166         A = new double[m][n];
167 
168         for (int i = 0; i < m; i++)
169         {
170             for (int j = 0; j < n; j++)
171             {
172                 A[i][j] = vals[i + (j * m)];
173             }
174         }
175     }
176 
177     //~ Methods ////////////////////////////////////////////////////////////////
178 
179     /** Check if indices have the same length.
180     @param i    Indices.
181     @param j    Indices.
182     */
183     public static void checkIndicesDimensions(int[][] i, int[][] j)
184     {
185         if ((i.length != j.length) || (i[0].length != j[0].length))
186         {
187             throw new IllegalArgumentException("Indices dimensions must equals");
188         }
189     }
190 
191     /** Check if indices have the same length.
192     @param i    Indices.
193     @param j    Indices.
194     */
195     public static void checkIndicesLengths(int[] i, int[] j)
196     {
197         if (i.length != j.length)
198         {
199             throw new IllegalArgumentException("Indices lenghts must equals");
200         }
201     }
202 
203     /** Generate identity matrix
204     @param m    Number of rows.
205     @param n    Number of colums.
206     @return     An m-by-n matrix with ones on the diagonal and zeros elsewhere.
207     */
208     public static Matrix identity(int m, int n)
209     {
210         Matrix X = new Matrix(m, n);
211         double[][] C = X.getArray();
212 
213         for (int i = 0; i < m; i++)
214         {
215             for (int j = 0; j < n; j++)
216             {
217                 C[i][j] = ((i == j) ? 1.0 : 0.0);
218             }
219         }
220 
221         return X;
222     }
223 
224     /** Generate a matrix with a constant pitch beetwen each row
225     @param m    Number of rows.
226     @param n    Number of colums.
227     @param begin    begining value to increment.
228     @param pitch    pitch to add.
229     @return     An m-by-n matrix.
230     */
231     public static Matrix increment(int m, int n, double begin, double pitch)
232     {
233         return incrementRows(m, n, begin, pitch);
234     }
235 
236     /** Generate a matrix with a constant pitch beetwen each column
237     @param m    Number of rows.
238     @param n    Number of colums.
239     @param begin    begining value to increment.
240     @param pitch    pitch to add.
241     @return     An m-by-n matrix.
242     */
243     public static Matrix incrementColumns(int m, int n, double begin,
244         double pitch)
245     {
246         Matrix X = new Matrix(m, n);
247         double[][] C = X.getArray();
248 
249         for (int i = 0; i < m; i++)
250         {
251             for (int j = 0; j < n; j++)
252             {
253                 C[i][j] = begin + (j * pitch);
254             }
255         }
256 
257         return X;
258     }
259 
260     /** Generate a matrix with a constant pitch beetwen each row
261     @param m    Number of rows.
262     @param n    Number of colums.
263     @param begin    begining value to increment.
264     @param pitch    pitch to add.
265     @return     An m-by-n matrix.
266     */
267     public static Matrix incrementRows(int m, int n, double begin, double pitch)
268     {
269         Matrix X = new Matrix(m, n);
270         double[][] C = X.getArray();
271 
272         for (int i = 0; i < m; i++)
273         {
274             for (int j = 0; j < n; j++)
275             {
276                 C[i][j] = begin + (i * pitch);
277             }
278         }
279 
280         return X;
281     }
282 
283     /** Generate a matrix from other matrix.
284     @param Xs    Matrix to merge.
285     @return     An m1+m2+...-by-n matrix.
286     */
287     public static Matrix merge(Matrix[] Xs)
288     {
289         return mergeRows(Xs);
290     }
291 
292     /** Generate a matrix from other matrix.
293     @param Xs    Matrix to merge.
294     @return     An m-by-n1+n2+... matrix.
295     */
296     public static Matrix mergeColumns(Matrix[] Xs)
297     {
298         int m = Xs[0].m;
299         int N = 0;
300 
301         for (int k = 0; k < Xs.length; k++)
302         {
303             N = N + Xs[k].n;
304         }
305 
306         Matrix X = new Matrix(m, N);
307         double[][] C = X.getArray();
308         int ind = 0;
309 
310         for (int k = 0; k < Xs.length; k++)
311         {
312             for (int i = 0; i < m; i++)
313             {
314                 for (int j = 0; j < Xs[k].n; j++)
315                 {
316                     C[i][j + ind] = Xs[k].A[i][j];
317                 }
318             }
319 
320             ind = ind + Xs[k].n;
321         }
322 
323         return X;
324     }
325 
326     /** Generate a matrix from other matrix.
327     @param Xs    Matrix to merge.
328     @return     An m1+m2+...-by-n matrix.
329     */
330     public static Matrix mergeRows(Matrix[] Xs)
331     {
332         int n = Xs[0].n;
333         int M = 0;
334 
335         for (int k = 0; k < Xs.length; k++)
336         {
337             M = M + Xs[k].m;
338         }
339 
340         Matrix X = new Matrix(M, n);
341         double[][] C = X.getArray();
342         int ind = 0;
343 
344         for (int k = 0; k < Xs.length; k++)
345         {
346             for (int i = 0; i < Xs[k].m; i++)
347             {
348                 for (int j = 0; j < n; j++)
349                 {
350                     C[i + ind][j] = Xs[k].A[i][j];
351                 }
352             }
353 
354             ind = ind + Xs[k].m;
355         }
356 
357         return X;
358     }
359 
360     /* ----------------------
361        Public Methods
362      * ---------------------- */
363 
364     //////////////////////////////////////////
365     //Static constructors for simple matrix.//
366     //////////////////////////////////////////
367 
368     /** Generate matrix with random elements
369     @param m    Number of rows.
370     @param n    Number of colums.
371     @return     An m-by-n matrix with uniformly distributed random elements.
372     */
373     public static Matrix random(int m, int n)
374     {
375         Matrix A = new Matrix(m, n);
376         double[][] X = A.getArray();
377 
378         for (int i = 0; i < m; i++)
379         {
380             for (int j = 0; j < n; j++)
381             {
382                 X[i][j] = Math.random();
383             }
384         }
385 
386         return A;
387     }
388 
389     /** Access the internal two-dimensional array.
390     @return     Pointer to the two-dimensional array of matrix elements.
391     */
392     public double[][] getArray()
393     {
394         return A;
395     }
396 
397     /** Copy the internal two-dimensional array.
398     @return     Two-dimensional array copy of matrix elements.
399     */
400     public double[][] getArrayCopy()
401     {
402         double[][] C = new double[m][n];
403 
404         for (int i = 0; i < m; i++)
405         {
406             for (int j = 0; j < n; j++)
407             {
408                 C[i][j] = A[i][j];
409             }
410         }
411 
412         return C;
413     }
414 
415     /** Set a column to an internal one-dimensional Column.
416     @param c    Column index
417     @param B    Column-matrix
418     */
419     public void setColumn(int c, Matrix B)
420     {
421         B.checkMatrixDimensions(m, 1);
422 
423         for (int i = 0; i < m; i++)
424         {
425             A[i][c] = B.A[i][0];
426         }
427     }
428 
429     /** Copy an internal one-dimensional array from a column.
430     @param c    Column index
431     @return     one-dimensional array copy of matrix elements.
432     */
433     public Matrix getColumn(int c)
434     {
435         Matrix X = new Matrix(m, 1);
436         double[][] C = X.getArray();
437 
438         for (int i = 0; i < m; i++)
439         {
440             C[i][0] = A[i][c];
441         }
442 
443         return X;
444     }
445 
446     /** Copy an internal one-dimensional array from a column.
447     @param c    Column index
448     @return     one-dimensional array copy of matrix elements.
449     */
450     public double[] getColumnArrayCopy(int c)
451     {
452         double[] C = new double[m];
453 
454         for (int i = 0; i < m; i++)
455         {
456             C[i] = A[i][c];
457         }
458 
459         return C;
460     }
461 
462     /** Get column dimension.
463     @return     n, the number of columns.
464     */
465     public int getColumnDimension()
466     {
467         return n;
468     }
469 
470     /** Make a one-dimensional column packed copy of the internal array.
471     @return     Matrix elements packed in a one-dimensional array by columns.
472     */
473     public double[] getColumnPackedCopy()
474     {
475         double[] C = new double[m * n];
476 
477         for (int i = 0; i < m; i++)
478         {
479             for (int j = 0; j < n; j++)
480             {
481                 C[i + (j * m)] = A[i][j];
482             }
483         }
484 
485         return C;
486     }
487 
488     /** Copy an internal one-dimensional array from a column.
489     @param c    Columns indexes
490     @param B    Columns-matrix
491     */
492     public void setColumns(int[] c, Matrix B)
493     {
494         B.checkMatrixDimensions(m, c.length);
495 
496         for (int j = 0; j < c.length; j++)
497         {
498             for (int i = 0; i < m; i++)
499             {
500                 A[i][c[j]] = B.A[i][j];
501             }
502         }
503     }
504 
505     /** Copy an internal one-dimensional array from a column.
506     @param c    Columns indexes
507     @return     one-dimensional array copy of matrix elements.
508     */
509     public Matrix getColumns(int[] c)
510     {
511         Matrix X = new Matrix(m, c.length);
512         double[][] C = X.getArray();
513 
514         for (int j = 0; j < c.length; j++)
515         {
516             for (int i = 0; i < m; i++)
517             {
518                 C[i][j] = A[i][c[j]];
519             }
520         }
521 
522         return X;
523     }
524 
525     /** Set a submatrix.
526     @param i0   Initial row index
527     @param j0   Initial column index
528     @param X   subMatrix to set
529     @exception  ArrayIndexOutOfBoundsException Submatrix indices
530     */
531     public void setMatrix(int i0, int j0, Matrix X)
532     {
533         try
534         {
535             for (int i = i0; i < (i0 + X.m); i++)
536             {
537                 for (int j = j0; j < (j0 + X.n); j++)
538                 {
539                     A[i][j] = X.A[i - i0][j - j0];
540                 }
541             }
542         }
543          catch (ArrayIndexOutOfBoundsException e)
544         {
545             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
546         }
547     }
548 
549     /** Set a submatrix.
550     @param I0   Initial row indexes
551     @param J0   Initial column indexes
552     @param X   subMatrix to set
553     @exception  ArrayIndexOutOfBoundsException Submatrix indices
554     */
555     public void setMatrix(int[] I0, int[] J0, Matrix X)
556     {
557         checkIndicesLengths(I0, J0);
558 
559         for (int k = 0; k < I0.length; k++)
560         {
561             int i0 = I0[k];
562             int j0 = J0[k];
563 
564             try
565             {
566                 for (int i = i0; i < (i0 + X.m); i++)
567                 {
568                     for (int j = j0; j < (j0 + X.n); j++)
569                     {
570                         A[i][j] = X.A[i - i0][j - j0];
571                     }
572                 }
573             }
574              catch (ArrayIndexOutOfBoundsException e)
575             {
576                 throw new ArrayIndexOutOfBoundsException("Submatrix indices");
577             }
578         }
579     }
580 
581     /** Set a submatrix.
582     @param i0   Initial row index
583     @param i1   Final row index
584     @param j0   Initial column index
585     @param j1   Final column index
586     @param v    Value to set in the submatrix
587     @exception  ArrayIndexOutOfBoundsException Submatrix indices
588     */
589     public void setMatrix(int i0, int i1, int j0, int j1, double v)
590     {
591         try
592         {
593             for (int i = i0; i <= i1; i++)
594             {
595                 for (int j = j0; j <= j1; j++)
596                 {
597                     A[i][j] = v;
598                 }
599             }
600         }
601          catch (ArrayIndexOutOfBoundsException e)
602         {
603             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
604         }
605     }
606 
607     /** Set a submatrix.
608     @param i0   Initial row index
609     @param i1   Final row index
610     @param j0   Initial column index
611     @param j1   Final column index
612     @param X    A(i0:i1,j0:j1)
613     @exception  ArrayIndexOutOfBoundsException Submatrix indices
614     */
615     public void setMatrix(int i0, int i1, int j0, int j1, Matrix X)
616     {
617         X.checkMatrixDimensions(i1 - i0 + 1, j1 - j0 + 1);
618 
619         try
620         {
621             for (int i = i0; i <= i1; i++)
622             {
623                 for (int j = j0; j <= j1; j++)
624                 {
625                     A[i][j] = X.A[i - i0][j - j0];
626                 }
627             }
628         }
629          catch (ArrayIndexOutOfBoundsException e)
630         {
631             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
632         }
633     }
634 
635     /** Get a submatrix.
636     @param i0   Initial row index
637     @param i1   Final row index
638     @param j0   Initial column index
639     @param j1   Final column index
640     @return     A(i0:i1,j0:j1)
641     @exception  ArrayIndexOutOfBoundsException Submatrix indices
642     */
643     public Matrix getMatrix(int i0, int i1, int j0, int j1)
644     {
645         Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1);
646         double[][] B = X.getArray();
647 
648         try
649         {
650             for (int i = i0; i <= i1; i++)
651             {
652                 for (int j = j0; j <= j1; j++)
653                 {
654                     B[i - i0][j - j0] = A[i][j];
655                 }
656             }
657         }
658          catch (ArrayIndexOutOfBoundsException e)
659         {
660             throw new ArrayIndexOutOfBoundsException("Submatrix indices");
661         }
662 
663         return X;
664     }
665 
666     /** Copy an internal one-dimensional array from a row.
667     @param l    Row index
668     @param B    Row-matrix
669     */
670     public void setRow(int l, Matrix B)
671     {
672         B.checkMatrixDimensions(1, n);
673 
674         for (int j = 0; j < n; j++)
675         {
676             A[l][j] = B.A[0][j];
677         }
678     }
679 
680     /** Copy an internal one-dimensional array from a row.
681     @param l    Row index
682     @return     one-dimensional array copy of matrix elements.
683     */
684     public Matrix getRow(int l)
685     {
686         Matrix X = new Matrix(1, n);
687         double[][] C = X.getArray();
688 
689         for (int j = 0; j < n; j++)
690         {
691             C[0][j] = A[l][j];
692         }
693 
694         return X;
695     }
696 
697     /** Copy an internal one-dimensional array from a row.
698     @param l    Row index
699     @return     one-dimensional array copy of matrix elements.
700     */
701     public double[] getRowArrayCopy(int l)
702     {
703         double[] C = new double[n];
704 
705         for (int i = 0; i < n; i++)
706         {
707             C[i] = A[l][i];
708         }
709 
710         return C;
711     }
712 
713     /** Get row dimension.
714     @return     m, the number of rows.
715     */
716     public int getRowDimension()
717     {
718         return m;
719     }
720 
721     /** Make a one-dimensional row packed copy of the internal array.
722     @return     Matrix elements packed in a one-dimensional array by rows.
723     */
724     public double[] getRowPackedCopy()
725     {
726         double[] C = new double[m * n];
727 
728         for (int i = 0; i < m; i++)
729         {
730             for (int j = 0; j < n; j++)
731             {
732                 C[(i * n) + j] = A[i][j];
733             }
734         }
735 
736         return C;
737     }
738 
739     /** Copy an internal one-dimensional array from many rows.
740     @param l    Rows indexes
741     @param B    Rows-matrix
742     */
743     public void setRows(int[] l, Matrix B)
744     {
745         B.checkMatrixDimensions(l.length, n);
746 
747         for (int i = 0; i < l.length; i++)
748         {
749             for (int j = 0; j < n; j++)
750             {
751                 A[l[i]][j] = B.A[i][j];
752             }
753         }
754     }
755 
756     /** Copy an internal one-dimensional array from many rows.
757     @param l    Rows indexes
758     @return     one-dimensional array copy of matrix elements.
759     */
760     public Matrix getRows(int[] l)
761     {
762         Matrix X = new Matrix(l.length, n);
763         double[][] C = X.getArray();
764 
765         for (int i = 0; i < l.length; i++)
766         {
767             for (int j = 0; j < n; j++)
768             {
769                 C[i][j] = A[l[i]][j];
770             }
771         }
772 
773         return X;
774     }
775 
776     /** Check if number of Columns(A) == number of Columns(B).
777     @param B    Matrix to test.
778     */
779     public void checkColumnDimension(Matrix B)
780     {
781         if (B.n != n)
782         {
783             throw new IllegalArgumentException(
784                 "Matrix Columns dimensions must equals " + B.n);
785         }
786     }
787 
788     /** Check if number of Columns(A) == column.
789     @param column    number of columns.
790     */
791     public void checkColumnDimension(int column)
792     {
793         if (column != n)
794         {
795             throw new IllegalArgumentException(
796                 "Matrix Columns dimensions must equals " + column);
797         }
798     }
799 
800     /////////////////////////////////////
801     //Matrix Test and checking methods.//
802     /////////////////////////////////////
803 
804     /** Check if size(A) == size(B).
805     @param B    Matrix to test.
806     */
807     public void checkMatrixDimensions(Matrix B)
808     {
809         if ((B.m != m) || (B.n != n))
810         {
811             throw new IllegalArgumentException("Matrix dimensions must equals " +
812                 B.m + " x " + B.n);
813         }
814     }
815 
816     /** Check if size(A) == m2*n2.
817     @param m2    Number of rows.
818     @param n2    Number of columns.
819     */
820     public void checkMatrixDimensions(int m2, int n2)
821     {
822         if ((m2 != m) || (n2 != n))
823         {
824             throw new IllegalArgumentException("Matrix dimensions must equals " +
825                 m2 + " x " + n2);
826         }
827     }
828 
829     /** Check if number of Rows(A) == number of Rows(B).
830     @param B    Matrix to test.
831     */
832     public void checkRowDimension(Matrix B)
833     {
834         if (B.m != m)
835         {
836             throw new IllegalArgumentException(
837                 "Matrix Rows dimensions must equals " + B.m);
838         }
839     }
840 
841     /** Check if number of Rows(A) == row.
842     @param row    number of rows.
843     */
844     public void checkRowDimension(int row)
845     {
846         if (row != m)
847         {
848             throw new IllegalArgumentException(
849                 "Matrix Rows dimensions must equals " + row);
850         }
851     }
852 
853     /** Cholesky Decomposition
854     @return     CholeskyDecomposition
855     @see CholeskyDecomposition
856     */
857     public CholeskyDecomposition chol()
858     {
859         return new CholeskyDecomposition(this);
860     }
861 
862     /** Clone the Matrix object.
863     @return     A matrix Object.
864     */
865     public Object clone()
866     {
867         return this.copy();
868     }
869 
870     /** Matrix condition (2 norm)
871     @return     ratio of largest to smallest singular value.
872     */
873     public double cond()
874     {
875         return new SingularValueDecomposition(this).cond();
876     }
877 
878     ///////////////////////////////////////////////////////////////////////
879     //Basic methods to create, convert into array, clone, or copy matrix.//
880     ///////////////////////////////////////////////////////////////////////
881 
882     /** Make a deep copy of a matrix
883     @return     A matrix.
884     */
885     public Matrix copy()
886     {
887         Matrix X = new Matrix(m, n);
888         double[][] C = X.getArray();
889 
890         for (int i = 0; i < m; i++)
891         {
892             for (int j = 0; j < n; j++)
893             {
894                 C[i][j] = A[i][j];
895             }
896         }
897 
898         return X;
899     }
900 
901     /** Matrix determinant
902     @return     determinant
903     */
904     public double det()
905     {
906         return new LUDecomposition(this).det();
907     }
908 
909     /** Matrix diagonal extraction.
910     @return     An d*1 Matrix of diagonal elements, d = min(m,n).
911     */
912     public Matrix diag()
913     {
914         int d = Math.min(m, n);
915         Matrix X = new Matrix(d, 1);
916         double[][] C = X.getArray();
917 
918         for (int i = 0; i < d; i++)
919         {
920             C[i][0] = A[i][i];
921         }
922 
923         return X;
924     }
925 
926     /** Matrix diagonal extraction.
927     @param num    diagonal number.
928     @return     Matrix of the n-th diagonal elements.
929     */
930     public Matrix diag(int num)
931     {
932         int l = 0;
933 
934         if (n < m)
935         {
936             if (num >= 0)
937             {
938                 l = n - num;
939             }
940             else if (num < (n - m))
941             {
942                 l = m + num;
943             }
944             else
945             {
946                 l = n;
947             }
948         }
949         else
950         {
951             if (num <= 0)
952             {
953                 l = m + num;
954             }
955             else if (num > (n - m))
956             {
957                 l = n - num;
958             }
959             else
960             {
961                 l = m;
962             }
963         }
964 
965         Matrix X = new Matrix(l, 1);
966         double[][] C = X.getArray();
967 
968         for (int i = 0; i < l; i++)
969         {
970             C[i][0] = (num > 0) ? (A[i][i + num]) : (A[i - num][i]);
971         }
972 
973         return X;
974     }
975 
976     /** Generate a matrix, each column contents the Euclidian distance between the columns.
977     @param B    Matrix
978     @return     An m-by-B.m matrix.
979     */
980     public Matrix dist(Matrix B)
981     {
982         return distRows(B);
983     }
984 
985     /** Generate a matrix, each line contents the Euclidian distance between the lines.
986     @param B    Matrix
987     @return     An B.n-by-n matrix.
988     */
989     public Matrix distColumns(Matrix B)
990     {
991         checkRowDimension(B);
992 
993         Matrix X = new Matrix(n, B.n);
994         double[][] C = X.getArray();
995 
996         for (int j = 0; j < n; j++)
997         {
998             for (int k = 0; k < B.n; k++)
999             {
1000                double s = 0;
1001
1002                for (int i = 0; i < m; i++)
1003                {
1004                    s = s + ((A[i][j] - B.A[i][k]) * (A[i][j] - B.A[i][k]));
1005                }
1006
1007                C[k][j] = Math.sqrt(s);
1008            }
1009        }
1010
1011        return X;
1012    }
1013
1014    /** Generate a matrix, each column contents the Euclidian distance between the columns.
1015    @param B    Matrix
1016    @return     An m-by-B.m matrix.
1017    */
1018    public Matrix distRows(Matrix B)
1019    {
1020        checkColumnDimension(B);
1021
1022        Matrix X = new Matrix(m, B.m);
1023        double[][] C = X.getArray();
1024
1025        for (int i = 0; i < m; i++)
1026        {
1027            for (int k = 0; k < B.m; k++)
1028            {
1029                double s = 0;
1030
1031                for (int j = 0; j < n; j++)
1032                {
1033                    s = s + ((A[i][j] - B.A[k][j]) * (A[i][j] - B.A[k][j]));
1034                }
1035
1036                C[i][k] = Math.sqrt(s);
1037            }
1038        }
1039
1040        return X;
1041    }
1042
1043    /** Divide a matrix by a scalar, C = A/s
1044    @param s    scalar
1045    @return     A/s
1046    */
1047    public Matrix divide(double s)
1048    {
1049        Matrix X = new Matrix(m, n);
1050        double[][] C = X.getArray();
1051
1052        for (int i = 0; i < m; i++)
1053        {
1054            for (int j = 0; j < n; j++)
1055            {
1056                C[i][j] = A[i][j] / s;
1057            }
1058        }
1059
1060        return X;
1061    }
1062
1063    /** Linear algebraic matrix division, A / B
1064    @param B    another matrix
1065    @return     Matrix division, A / B
1066    @exception  IllegalArgumentException Matrix inner dimensions must agree.
1067    @exception  IllegalArgumentException Matrix inner dimensions must agree.
1068    */
1069    public Matrix divide(Matrix B)
1070    {
1071        B = B.inverse();
1072
1073        if (B.m != n)
1074        {
1075            throw new IllegalArgumentException(
1076                "Matrix inner dimensions must agree.");
1077        }
1078
1079        return times(B);
1080    }
1081
1082    /**Element-by-element inverse
1083    @return     A.^-1
1084     */
1085    public Matrix ebeAbs()
1086    {
1087        Matrix X = new Matrix(m, n);
1088        double[][] C = X.getArray();
1089
1090        for (int i = 0; i < m; i++)
1091        {
1092            for (int j = 0; j < n; j++)
1093            {
1094                C[i][j] = Math.abs(A[i][j]);
1095            }
1096        }
1097
1098        return X;
1099    }
1100
1101    /**Element-by-element cosinus
1102    @return     cos.(A)
1103     */
1104    public Matrix ebeCos()
1105    {
1106        Matrix X = new Matrix(m, n);
1107        double[][] C = X.getArray();
1108
1109        for (int i = 0; i < m; i++)
1110        {
1111            for (int j = 0; j < n; j++)
1112            {
1113                C[i][j] = Math.cos(A[i][j]);
1114            }
1115        }
1116
1117        return X;
1118    }
1119
1120    /** Divide a matrix by a scalar, C = A/s
1121    @param s    scalar
1122    @return     A/s
1123    */
1124    public Matrix ebeDivide(double s)
1125    {
1126        Matrix X = new Matrix(m, n);
1127        double[][] C = X.getArray();
1128
1129        for (int i = 0; i < m; i++)
1130        {
1131            for (int j = 0; j < n; j++)
1132            {
1133                C[i][j] = A[i][j] / s;
1134            }
1135        }
1136
1137        return X;
1138    }
1139
1140    /** Element-by-element right division, C = A./B
1141    @param B    another matrix
1142    @return     A./B
1143    */
1144    public Matrix ebeDivide(Matrix B)
1145    {
1146        checkMatrixDimensions(B);
1147
1148        Matrix X = new Matrix(m, n);
1149        double[][] C = X.getArray();
1150
1151        for (int i = 0; i < m; i++)
1152        {
1153            for (int j = 0; j < n; j++)
1154            {
1155                C[i][j] = A[i][j] / B.A[i][j];
1156            }
1157        }
1158
1159        return X;
1160    }
1161
1162    /**Element-by-element exponential
1163    @return     exp.(A)
1164     */
1165    public Matrix ebeExp()
1166    {
1167        Matrix X = new Matrix(m, n);
1168        double[][] C = X.getArray();
1169
1170        for (int i = 0; i < m; i++)
1171        {
1172            for (int j = 0; j < n; j++)
1173            {
1174                C[i][j] = Math.exp(A[i][j]);
1175            }
1176        }
1177
1178        return X;
1179    }
1180
1181    /**Element-by-element methodName evaluation
1182    @param fun    methodName to apply
1183    @return     f.(A)
1184     */
1185    public Matrix ebeFun(DoubleFunction fun)
1186    {
1187        fun.checkArgNumber(1);
1188
1189        Matrix X = new Matrix(m, n);
1190        double[][] C = X.getArray();
1191
1192        for (int i = 0; i < m; i++)
1193        {
1194            for (int j = 0; j < n; j++)
1195            {
1196                double[] arg = {A[i][j]};
1197                C[i][j] = fun.eval(arg);
1198            }
1199        }
1200
1201        return X;
1202    }
1203
1204    /**Element-by-element indicial methodName evaluation
1205    @param fun    methodName to apply
1206    @return     f.(A)
1207     */
1208    public Matrix ebeIndFun(DoubleFunction fun)
1209    {
1210        fun.checkArgNumber(3);
1211
1212        Matrix X = new Matrix(m, n);
1213        double[][] C = X.getArray();
1214
1215        for (int i = 0; i < m; i++)
1216        {
1217            for (int j = 0; j < n; j++)
1218            {
1219                double[] args = {A[i][j], i, j};
1220                C[i][j] = fun.eval(args);
1221            }
1222        }
1223
1224        return X;
1225    }
1226
1227    /**Element-by-element inverse
1228    @return     A.^-1
1229     */
1230    public Matrix ebeInv()
1231    {
1232        Matrix X = new Matrix(m, n);
1233        double[][] C = X.getArray();
1234
1235        for (int i = 0; i < m; i++)
1236        {
1237            for (int j = 0; j < n; j++)
1238            {
1239                C[i][j] = 1 / (A[i][j]);
1240            }
1241        }
1242
1243        return X;
1244    }
1245
1246    /**Element-by-element neperian logarithm
1247    @return     log.(A)
1248     */
1249    public Matrix ebeLog()
1250    {
1251        Matrix X = new Matrix(m, n);
1252        double[][] C = X.getArray();
1253
1254        for (int i = 0; i < m; i++)
1255        {
1256            for (int j = 0; j < n; j++)
1257            {
1258                C[i][j] = Math.log(A[i][j]);
1259            }
1260        }
1261
1262        return X;
1263    }
1264
1265    /** Sub a scalar to each element of a matrix, C = A .- B
1266    @param s    double
1267    @return     A .- s
1268    */
1269    public Matrix ebeMinus(double s)
1270    {
1271        Matrix X = new Matrix(m, n);
1272        double[][] C = X.getArray();
1273
1274        for (int i = 0; i < m; i++)
1275        {
1276            for (int j = 0; j < n; j++)
1277            {
1278                C[i][j] = A[i][j] - s;
1279            }
1280        }
1281
1282        return X;
1283    }
1284
1285    /////////////////////////////////////////////
1286    //Element-by-elements Functions for Matrix.//
1287    /////////////////////////////////////////////
1288
1289    /** Add a scalar to each element of a matrix, C = A .+ s
1290    @param s    double
1291    @return     A .+ s
1292    */
1293    public Matrix ebePlus(double s)
1294    {
1295        Matrix X = new Matrix(m, n);
1296        double[][] C = X.getArray();
1297
1298        for (int i = 0; i < m; i++)
1299        {
1300            for (int j = 0; j < n; j++)
1301            {
1302                C[i][j] = A[i][j] + s;
1303            }
1304        }
1305
1306        return X;
1307    }
1308
1309    /**Element-by-element power
1310    @param p    double
1311    @return     A.^p
1312     */
1313    public Matrix ebePow(double p)
1314    {
1315        Matrix X = new Matrix(m, n);
1316        double[][] C = X.getArray();
1317
1318        for (int i = 0; i < m; i++)
1319        {
1320            for (int j = 0; j < n; j++)
1321            {
1322                C[i][j] = Math.pow(A[i][j], p);
1323            }
1324        }
1325
1326        return X;
1327    }
1328
1329    /**Element-by-element power
1330    @param B    another matrix
1331    @return     A.^B
1332     */
1333    public Matrix ebePow(Matrix B)
1334    {
1335        checkMatrixDimensions(B);
1336
1337        Matrix X = new Matrix(m, n);
1338        double[][] C = X.getArray();
1339
1340        for (int i = 0; i < m; i++)
1341        {
1342            for (int j = 0; j < n; j++)
1343            {
1344                C[i][j] = Math.pow(A[i][j], B.A[i][j]);
1345            }
1346        }
1347
1348        return X;
1349    }
1350
1351    /**Element-by-element sinus
1352    @return     sin.(A)
1353     */
1354    public Matrix ebeSin()
1355    {
1356        Matrix X = new Matrix(m, n);
1357        double[][] C = X.getArray();
1358
1359        for (int i = 0; i < m; i++)
1360        {
1361            for (int j = 0; j < n; j++)
1362            {
1363                C[i][j] = Math.sin(A[i][j]);
1364            }
1365        }
1366
1367        return X;
1368    }
1369
1370    /**Element-by-element inverse
1371    @return     A.^-1
1372     */
1373    public Matrix ebeSqrt()
1374    {
1375        Matrix X = new Matrix(m, n);
1376        double[][] C = X.getArray();
1377
1378        for (int i = 0; i < m; i++)
1379        {
1380            for (int j = 0; j < n; j++)
1381            {
1382                C[i][j] = Math.sqrt(A[i][j]);
1383            }
1384        }
1385
1386        return X;
1387    }
1388
1389    /** Multiply a matrix by a scalar, C = s*A
1390    @param s    scalar
1391    @return     s*A
1392    */
1393    public Matrix ebeTimes(double s)
1394    {
1395        Matrix X = new Matrix(m, n);
1396        double[][] C = X.getArray();
1397
1398        for (int i = 0; i < m; i++)
1399        {
1400            for (int j = 0; j < n; j++)
1401            {
1402                C[i][j] = s * A[i][j];
1403            }
1404        }
1405
1406        return X;
1407    }
1408
1409    /** Element-by-element multiplication, C = A.*B
1410    @param B    another matrix
1411    @return     A.*B
1412    */
1413    public Matrix ebeTimes(Matrix B)
1414    {
1415        checkMatrixDimensions(B);
1416
1417        Matrix X = new Matrix(m, n);
1418        double[][] C = X.getArray();
1419
1420        for (int i = 0; i < m; i++)
1421        {
1422            for (int j = 0; j < n; j++)
1423            {
1424                C[i][j] = A[i][j] * B.A[i][j];
1425            }
1426        }
1427
1428        return X;
1429    }
1430
1431    /** Eigenvalue Decomposition
1432    @return     EigenvalueDecomposition
1433    @see EigenvalueDecomposition
1434    */
1435    public EigenvalueDecomposition eig()
1436    {
1437        return new EigenvalueDecomposition(this);
1438    }
1439
1440    /** Find an element
1441    @param e    Element (value) to find
1442    @return     A list of indices where this element is found.
1443    */
1444    public int[][] find(double e)
1445    {
1446        Find f = new Find(getArrayCopy(), e);
1447
1448        return f.getIndices();
1449    }
1450
1451    /** Find elements verifying a boolean test
1452    @param test    Test to apply: < > =...
1453    @param e    Element (value) to compare
1454    @return     A list of indices where this element is found.
1455    */
1456    public int[][] find(String test, double e)
1457    {
1458        Find f = new Find(getArrayCopy(), test, e);
1459
1460        return f.getIndices();
1461    }
1462
1463    /** Find an element
1464    @param e    Element (value) to find
1465    @return     A list of indices where this element is found.
1466    */
1467    public Matrix findMatrix(double e)
1468    {
1469        Find f = new Find(getArrayCopy(), e);
1470
1471        return new Matrix(f.getDoubleArray());
1472    }
1473
1474    /** Find elements verifying a boolean test
1475    @param test    Test to apply: < > =...
1476    @param e    Element (value) to compare
1477    @return     A list of indices where this element is found.
1478    */
1479    public Matrix findMatrix(String test, double e)
1480    {
1481        Find f = new Find(getArrayCopy(), test, e);
1482
1483        return new Matrix(f.getDoubleArray());
1484    }
1485
1486    /** Load the Matrix from a file.
1487    @param fileName    filename of the file to load.
1488    @return      A matrix.
1489    */
1490    public static Matrix fromFile(String fileName)
1491    {
1492        MatrixFile mf = new MatrixFile(fileName);
1493
1494        return mf.getMatrix();
1495    }
1496
1497    /** Load the Matrix from a file
1498    @param file    file to load
1499    @return      A matrix
1500    */
1501    public static Matrix fromFile(File file)
1502    {
1503        MatrixFile mf = new MatrixFile(file);
1504
1505        return mf.getMatrix();
1506    }
1507
1508    /** Load the Matrix from a MathML Element
1509    @param e    Element <matrix> to load
1510    @return      A matrix
1511    */
1512    public static Matrix fromMMLElement(Element e)
1513    {
1514        Matrix m = MatrixMML.readMatrix(e);
1515
1516        return m;
1517    }
1518
1519    /** Load the Matrix from a MathML File
1520    @param file    XML File to load
1521    @return      A matrix
1522    */
1523    public static Matrix fromMMLFile(File file)
1524    {
1525        MatrixMMLFile mf = new MatrixMMLFile(file);
1526
1527        return mf.getMatrix();
1528    }
1529
1530    /** Load the Matrix from a String
1531    @param s    String to load
1532    @return      A matrix
1533    */
1534    public static Matrix fromString(String s)
1535    {
1536        Matrix m = MatrixString.readMatrix(s);
1537
1538        return m;
1539    }
1540
1541    ////////////////////////////////////////////////////////////
1542    //Basic and advanced Get methods for matrix and submatrix.//
1543    ////////////////////////////////////////////////////////////
1544
1545    /** Get a single element.
1546    @param i    Row index.
1547    @param j    Column index.
1548    @return     A(i,j)
1549    @exception  ArrayIndexOutOfBoundsException
1550    */
1551    public double get(int i, int j)
1552    {
1553        return A[i][j];
1554    }
1555
1556    /** Get a several elements in Column.
1557    @param I    Row index.
1558    @param J    Column index.
1559    @return     A(I(:),J(:))
1560    @exception  ArrayIndexOutOfBoundsException
1561    */
1562    public Matrix get(int[] I, int[] J)
1563    {
1564        checkIndicesLengths(I, J);
1565
1566        Matrix X = new Matrix(I.length, 1);
1567        double[][] B = X.getArray();
1568
1569        for (int i = 0; i < I.length; i++)
1570        {
1571            B[i][0] = A[I[i]][J[i]];
1572        }
1573
1574        return X;
1575    }
1576
1577    /** Get a several elements.
1578    @param I    Row index.
1579    @param J    Column index.
1580    @return     A(I(:,:),J(:,:))
1581    @exception  ArrayIndexOutOfBoundsException
1582    */
1583    public Matrix get(int[][] I, int[][] J)
1584    {
1585        checkIndicesDimensions(I, J);
1586
1587        Matrix X = new Matrix(I.length, I[0].length);
1588        double[][] B = X.getArray();
1589
1590        for (int i = 0; i < I.length; i++)
1591        {
1592            for (int j = 0; j < I[i].length; j++)
1593            {
1594                B[i][j] = A[I[i][j]][J[i][j]];
1595            }
1596        }
1597
1598        return X;
1599    }
1600
1601    /** Matrix inverse or pseudoinverse
1602    @return     inverse(A) if A is square, pseudoinverse otherwise.
1603    */
1604    public Matrix inverse()
1605    {
1606        return solve(identity(m, m));
1607    }
1608
1609    ///////////////////////////////////////////////
1610    //Advanced Decompositions methods for Matrix.//
1611    ///////////////////////////////////////////////
1612
1613    /** LU Decomposition
1614    @return     LUDecomposition
1615    @see LUDecomposition
1616    */
1617    public LUDecomposition lu()
1618    {
1619        return new LUDecomposition(this);
1620    }
1621
1622    /** Generate a row matrix, each column contents the maximum value of the columns.
1623    @return     An 1-by-n matrix.
1624    */
1625    public Matrix max()
1626    {
1627        return maxRows();
1628    }
1629
1630    /** Generate a column matrix, each line contents the maximum value of the lines.
1631    @return     An m-by-1 matrix.
1632    */
1633    public Matrix maxColumns()
1634    {
1635        Matrix X = new Matrix(m, 1);
1636        double[][] C = X.getArray();
1637
1638        for (int i = 0; i < m; i++)
1639        {
1640            double maxval = A[i][0];
1641
1642            for (int j = 0; j < n; j++)
1643            {
1644                maxval = Math.max(maxval, A[i][j]);
1645            }
1646
1647            C[i][0] = maxval;
1648        }
1649
1650        return X;
1651    }
1652
1653    /** Generate a row matrix, each column contents the maximum value of the columns.
1654    @return     An 1-by-n matrix.
1655    */
1656    public Matrix maxRows()
1657    {
1658        Matrix X = new Matrix(1, n);
1659        double[][] C = X.getArray();
1660
1661        for (int j = 0; j < n; j++)
1662        {
1663            double maxval = A[0][j];
1664
1665            for (int i = 0; i < m; i++)
1666            {
1667                maxval = Math.max(maxval, A[i][j]);
1668            }
1669
1670            C[0][j] = maxval;
1671        }
1672
1673        return X;
1674    }
1675
1676    /** Matrix merge.
1677    @param B    matrix to merge
1678    @return     An m.B.m-by-n matrix
1679    */
1680    public Matrix merge(Matrix B)
1681    {
1682        return mergeRows(B);
1683    }
1684
1685    /** Matrix merge.
1686    @param B    matrix to merge
1687    @return     An m-by-n+B.n matrix
1688    */
1689    public Matrix mergeColumns(Matrix B)
1690    {
1691        checkRowDimension(B);
1692
1693        Matrix X = new Matrix(m, n + B.n);
1694        double[][] C = X.getArray();
1695
1696        for (int i = 0; i < m; i++)
1697        {
1698            for (int j = 0; j < n; j++)
1699            {
1700                C[i][j] = A[i][j];
1701            }
1702        }
1703