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