source: src/main/java/agents/Jama/Matrix.java

Last change on this file was 1, checked in by Wouter Pasman, 6 years ago

Initial import : Genius 9.0.0

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