Matrix.javaDownload: project files
This is a Java implementation of a Matrix class, similar to our C++ version
001: //package Jama;
002:
003: import java.util.Locale;
004: import java.text.FieldPosition;
005: import java.io.PrintWriter;
006: import java.io.BufferedReader;
007: import java.io.StreamTokenizer;
008:
009: /**
010: Jama = Java Matrix class.
011: <P>
012: The Java Matrix Class provides the fundamental operations of numerical
013: linear algebra. Various constructors create Matrices from two dimensional
014: arrays of double precision floating point numbers. Various "gets" and
015: "sets" provide access to submatrices and matrix elements. Several methods
016: implement basic matrix arithmetic, including matrix addition and
017: multiplication, matrix norms, and element-by-element array operations.
018: Methods for reading and printing matrices are also included. All the
019: operations in this version of the Matrix Class involve real matrices.
020: Complex matrices may be handled in a future version.
021: <P>
022: Five fundamental matrix decompositions, which consist of pairs or triples
023: of matrices, permutation vectors, and the like, produce results in five
024: decomposition classes. These decompositions are accessed by the Matrix
025: class to compute solutions of simultaneous linear equations, determinants,
026: inverses and other matrix functions. The five decompositions are:
027: <P><UL>
028: <LI>Cholesky Decomposition of symmetric, positive definite matrices.
029: <LI>LU Decomposition of rectangular matrices.
030: <LI>QR Decomposition of rectangular matrices.
031: <LI>Singular Value Decomposition of rectangular matrices.
032: <LI>Eigenvalue Decomposition of both symmetric and nonsymmetric square matrices.
033: </UL>
034: <DL>
035: <DT><B>Example of use:</B></DT>
036: <P>
037: <DD>Solve a linear system A x = b and compute the residual norm, ||b - A x||.
038: <P><PRE>
039: double[][] vals = {{1.,2.,3},{4.,5.,6.},{7.,8.,10.}};
040: Matrix A = new Matrix(vals);
041: Matrix b = Matrix.random(3,1);
042: Matrix x = A.solve(b);
043: Matrix r = A.times(x).minus(b);
044: double rnorm = r.normInf();
045: </PRE></DD>
046: </DL>
047:
048: @author The MathWorks, Inc. and the National Institute of Standards and Technology.
049: @version 5 August 1998
050: */
051:
052: public class Matrix implements Cloneable, java.io.Serializable {
053:
054: /* ------------------------
055: Class variables
056: * ------------------------ */
057:
058: /** Array for internal storage of elements.
059: @serial internal array storage.
060: */
061: private double[][] A;
062:
063: /** Row and column dimensions.
064: @serial row dimension.
065: @serial column dimension.
066: */
067: private int m, n;
068:
069: /* ------------------------
070: Constructors
071: * ------------------------ */
072:
073: /** Construct an m-by-n matrix of zeros.
074: @param m Number of rows.
075: @param n Number of colums.
076: */
077:
078: public Matrix (int m, int n) {
079: this.m = m;
080: this.n = n;
081: A = new double[m][n];
082: }
083:
084: /** Construct an m-by-n constant matrix.
085: @param m Number of rows.
086: @param n Number of colums.
087: @param s Fill the matrix with this scalar value.
088: */
089:
090: public Matrix (int m, int n, double s) {
091: this.m = m;
092: this.n = n;
093: A = new double[m][n];
094: for (int i = 0; i < m; i++) {
095: for (int j = 0; j < n; j++) {
096: A[i][j] = s;
097: }
098: }
099: }
100:
101: /** Construct a matrix from a 2-D array.
102: @param A Two-dimensional array of doubles.
103: @exception IllegalArgumentException All rows must have the same length
104: @see #constructWithCopy
105: */
106:
107: public Matrix (double[][] A) {
108: m = A.length;
109: n = A[0].length;
110: for (int i = 0; i < m; i++) {
111: if (A[i].length != n) {
112: throw new IllegalArgumentException("All rows must have the same length.");
113: }
114: }
115: this.A = A;
116: }
117:
118: /** Construct a matrix quickly without checking arguments.
119: @param A Two-dimensional array of doubles.
120: @param m Number of rows.
121: @param n Number of colums.
122: */
123:
124: public Matrix (double[][] A, int m, int n) {
125: this.A = A;
126: this.m = m;
127: this.n = n;
128: }
129:
130: /** Construct a matrix from a 1-D array.
131: @param A one-dimensional array of doubles.
132: *
133: * This constructs a column vector [m x 1]
134: */
135:
136: public Matrix (double[] column) {
137: m = column.length;
138: n = 1;
139: A = new double[m][1];
140: for (int i = 0; i < m; i++) A[i][0] = column[i];
141: }
142:
143: /** Construct a matrix from a one-dimensional packed array
144: @param vals One-dimensional array of doubles, packed by columns (ala Fortran).
145: @param m Number of rows.
146: @exception IllegalArgumentException Array length must be a multiple of m.
147: */
148:
149: public Matrix (double vals[], int m) {
150: this.m = m;
151: n = (m != 0 ? vals.length/m : 0);
152: if (m*n != vals.length) {
153: throw new IllegalArgumentException("Array length must be a multiple of m.");
154: }
155: A = new double[m][n];
156: for (int i = 0; i < m; i++) {
157: for (int j = 0; j < n; j++) {
158: A[i][j] = vals[i+j*m];
159: }
160: }
161: }
162:
163: /* ------------------------
164: Public Methods
165: * ------------------------ */
166:
167: /** Construct a matrix from a copy of a 2-D array.
168: @param A Two-dimensional array of doubles.
169: @exception IllegalArgumentException All rows must have the same length
170: */
171:
172: public static Matrix constructWithCopy(double[][] A) {
173: int m = A.length;
174: int n = A[0].length;
175: Matrix X = new Matrix(m,n);
176: double[][] C = X.getArray();
177: for (int i = 0; i < m; i++) {
178: if (A[i].length != n) {
179: throw new IllegalArgumentException
180: ("All rows must have the same length.");
181: }
182: for (int j = 0; j < n; j++) {
183: C[i][j] = A[i][j];
184: }
185: }
186: return X;
187: }
188:
189: /** Make a deep copy of a matrix
190: */
191:
192: public Matrix copy () {
193: Matrix X = new Matrix(m,n);
194: double[][] C = X.getArray();
195: for (int i = 0; i < m; i++) {
196: for (int j = 0; j < n; j++) {
197: C[i][j] = A[i][j];
198: }
199: }
200: return X;
201: }
202:
203: /** Clone the Matrix object.
204: */
205:
206: public Object clone () {
207: return this.copy();
208: }
209:
210: /** Access the internal two-dimensional array.
211: @return Pointer to the two-dimensional array of matrix elements.
212: */
213:
214: public double[][] getArray () {
215: return A;
216: }
217:
218: /** Copy the internal two-dimensional array.
219: @return Two-dimensional array copy of matrix elements.
220: */
221:
222: public double[][] getArrayCopy () {
223: double[][] C = new double[m][n];
224: for (int i = 0; i < m; i++) {
225: for (int j = 0; j < n; j++) {
226: C[i][j] = A[i][j];
227: }
228: }
229: return C;
230: }
231:
232: /** Make a one-dimensional column packed copy of the internal array.
233: @return Matrix elements packed in a one-dimensional array by columns.
234: */
235:
236: public double[] getColumnPackedCopy () {
237: double[] vals = new double[m*n];
238: for (int i = 0; i < m; i++) {
239: for (int j = 0; j < n; j++) {
240: vals[i+j*m] = A[i][j];
241: }
242: }
243: return vals;
244: }
245:
246: /** Make a one-dimensional row packed copy of the internal array.
247: @return Matrix elements packed in a one-dimensional array by rows.
248: */
249:
250: public double[] getRowPackedCopy () {
251: double[] vals = new double[m*n];
252: for (int i = 0; i < m; i++) {
253: for (int j = 0; j < n; j++) {
254: vals[i*n+j] = A[i][j];
255: }
256: }
257: return vals;
258: }
259:
260: /** Get row dimension.
261: @return m, the number of rows.
262: */
263:
264: public int getRowDimension () {
265: return m;
266: }
267:
268: /** Get column dimension.
269: @return n, the number of columns.
270: */
271:
272: public int getColumnDimension () {
273: return n;
274: }
275:
276: /** Get a single element.
277: @param i Row index.
278: @param j Column index.
279: @return A(i,j)
280: @exception ArrayIndexOutOfBoundsException
281: */
282:
283: public double get (int i, int j) {
284: return A[i][j];
285: }
286:
287: /** Get a submatrix.
288: @param i0 Initial row index
289: @param i1 Final row index
290: @param j0 Initial column index
291: @param j1 Final column index
292: @return A(i0:i1,j0:j1)
293: @exception ArrayIndexOutOfBoundsException Submatrix indices
294: */
295:
296: public Matrix getMatrix (int i0, int i1, int j0, int j1) {
297: Matrix X = new Matrix(i1-i0+1,j1-j0+1);
298: double[][] B = X.getArray();
299: try {
300: for (int i = i0; i <= i1; i++) {
301: for (int j = j0; j <= j1; j++) {
302: B[i-i0][j-j0] = A[i][j];
303: }
304: }
305: } catch(ArrayIndexOutOfBoundsException e) {
306: throw new ArrayIndexOutOfBoundsException("Submatrix indices");
307: }
308: return X;
309: }
310:
311: /** Get a submatrix.
312: @param r Array of row indices.
313: @param c Array of column indices.
314: @return A(r(:),c(:))
315: @exception ArrayIndexOutOfBoundsException Submatrix indices
316: */
317:
318: public Matrix getMatrix (int[] r, int[] c) {
319: Matrix X = new Matrix(r.length,c.length);
320: double[][] B = X.getArray();
321: try {
322: for (int i = 0; i < r.length; i++) {
323: for (int j = 0; j < c.length; j++) {
324: B[i][j] = A[r[i]][c[j]];
325: }
326: }
327: } catch(ArrayIndexOutOfBoundsException e) {
328: throw new ArrayIndexOutOfBoundsException("Submatrix indices");
329: }
330: return X;
331: }
332:
333: /** Get a submatrix.
334: @param i0 Initial row index
335: @param i1 Final row index
336: @param c Array of column indices.
337: @return A(i0:i1,c(:))
338: @exception ArrayIndexOutOfBoundsException Submatrix indices
339: */
340:
341: public Matrix getMatrix (int i0, int i1, int[] c) {
342: Matrix X = new Matrix(i1-i0+1,c.length);
343: double[][] B = X.getArray();
344: try {
345: for (int i = i0; i <= i1; i++) {
346: for (int j = 0; j < c.length; j++) {
347: B[i-i0][j] = A[i][c[j]];
348: }
349: }
350: } catch(ArrayIndexOutOfBoundsException e) {
351: throw new ArrayIndexOutOfBoundsException("Submatrix indices");
352: }
353: return X;
354: }
355:
356: /** Get a submatrix.
357: @param r Array of row indices.
358: @param i0 Initial column index
359: @param i1 Final column index
360: @return A(r(:),j0:j1)
361: @exception ArrayIndexOutOfBoundsException Submatrix indices
362: */
363:
364: public Matrix getMatrix (int[] r, int j0, int j1) {
365: Matrix X = new Matrix(r.length,j1-j0+1);
366: double[][] B = X.getArray();
367: try {
368: for (int i = 0; i < r.length; i++) {
369: for (int j = j0; j <= j1; j++) {
370: B[i][j-j0] = A[r[i]][j];
371: }
372: }
373: } catch(ArrayIndexOutOfBoundsException e) {
374: throw new ArrayIndexOutOfBoundsException("Submatrix indices");
375: }
376: return X;
377: }
378:
379: /** Set a single element.
380: @param i Row index.
381: @param j Column index.
382: @param s A(i,j).
383: @exception ArrayIndexOutOfBoundsException
384: */
385:
386: public void set (int i, int j, double s) {
387: A[i][j] = s;
388: }
389:
390: /** Set a submatrix.
391: @param i0 Initial row index
392: @param i1 Final row index
393: @param j0 Initial column index
394: @param j1 Final column index
395: @param X A(i0:i1,j0:j1)
396: @exception ArrayIndexOutOfBoundsException Submatrix indices
397: */
398:
399: public void setMatrix (int i0, int i1, int j0, int j1, Matrix X) {
400: try {
401: for (int i = i0; i <= i1; i++) {
402: for (int j = j0; j <= j1; j++) {
403: A[i][j] = X.get(i-i0,j-j0);
404: }
405: }
406: } catch(ArrayIndexOutOfBoundsException e) {
407: throw new ArrayIndexOutOfBoundsException("Submatrix indices");
408: }
409: }
410:
411: /** Set a submatrix.
412: @param r Array of row indices.
413: @param c Array of column indices.
414: @param X A(r(:),c(:))
415: @exception ArrayIndexOutOfBoundsException Submatrix indices
416: */
417:
418: public void setMatrix (int[] r, int[] c, Matrix X) {
419: try {
420: for (int i = 0; i < r.length; i++) {
421: for (int j = 0; j < c.length; j++) {
422: A[r[i]][c[j]] = X.get(i,j);
423: }
424: }
425: } catch(ArrayIndexOutOfBoundsException e) {
426: throw new ArrayIndexOutOfBoundsException("Submatrix indices");
427: }
428: }
429:
430: /** Set a submatrix.
431: @param r Array of row indices.
432: @param j0 Initial column index
433: @param j1 Final column index
434: @param X A(r(:),j0:j1)
435: @exception ArrayIndexOutOfBoundsException Submatrix indices
436: */
437:
438: public void setMatrix (int[] r, int j0, int j1, Matrix X) {
439: try {
440: for (int i = 0; i < r.length; i++) {
441: for (int j = j0; j <= j1; j++) {
442: A[r[i]][j] = X.get(i,j-j0);
443: }
444: }
445: } catch(ArrayIndexOutOfBoundsException e) {
446: throw new ArrayIndexOutOfBoundsException("Submatrix indices");
447: }
448: }
449:
450: /** Set a submatrix.
451: @param i0 Initial row index
452: @param i1 Final row index
453: @param c Array of column indices.
454: @param X A(i0:i1,c(:))
455: @exception ArrayIndexOutOfBoundsException Submatrix indices
456: */
457:
458: public void setMatrix (int i0, int i1, int[] c, Matrix X) {
459: try {
460: for (int i = i0; i <= i1; i++) {
461: for (int j = 0; j < c.length; j++) {
462: A[i][c[j]] = X.get(i-i0,j);
463: }
464: }
465: } catch(ArrayIndexOutOfBoundsException e) {
466: throw new ArrayIndexOutOfBoundsException("Submatrix indices");
467: }
468: }
469:
470: /** Matrix transpose.
471: @return A'
472: */
473:
474: public Matrix transpose () {
475: Matrix X = new Matrix(n,m);
476: double[][] C = X.getArray();
477: for (int i = 0; i < m; i++) {
478: for (int j = 0; j < n; j++) {
479: C[j][i] = A[i][j];
480: }
481: }
482: return X;
483: }
484:
485: /** One norm
486: @return maximum column sum.
487: */
488:
489: public double norm1 () {
490: double f = 0;
491: for (int j = 0; j < n; j++) {
492: double s = 0;
493: for (int i = 0; i < m; i++) {
494: s += Math.abs(A[i][j]);
495: }
496: f = Math.max(f,s);
497: }
498: return f;
499: }
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 = 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: /** Matrix trace.
767: @return sum of the diagonal elements.
768: */
769:
770: public double trace () {
771: double t = 0;
772: for (int i = 0; i < Math.min(m,n); i++) {
773: t += A[i][i];
774: }
775: return t;
776: }
777:
778: /** Generate matrix with random elements
779: @param m Number of rows.
780: @param n Number of colums.
781: @return An m-by-n matrix with uniformly distributed random elements.
782: */
783:
784: public static Matrix random (int m, int n) {
785: Matrix A = new Matrix(m,n);
786: double[][] X = A.getArray();
787: for (int i = 0; i < m; i++) {
788: for (int j = 0; j < n; j++) {
789: X[i][j] = Math.random();
790: }
791: }
792: return A;
793: }
794:
795: /** Generate identity matrix
796: @param m Number of rows.
797: @param n Number of colums.
798: @return An m-by-n matrix with ones on the diagonal and zeros elsewhere.
799: */
800:
801: public static Matrix identity (int m, int n) {
802: Matrix A = new Matrix(m,n);
803: double[][] X = A.getArray();
804: for (int i = 0; i < m; i++) {
805: for (int j = 0; j < n; j++) {
806: X[i][j] = (i == j ? 1.0 : 0.0);
807: }
808: }
809: return A;
810: }
811:
812:
813: /** sqrt(a^2 + b^2) without under/overflow. **/
814:
815: public static double hypot(double a, double b) {
816: double r;
817: a = Math.abs(a);
818: b = Math.abs(b);
819: if (b > a) {
820: r = (b>0.0? a/b: 0.0);
821: a = b;
822: }
823: else r = (a>0.0? b/a : 0.0);
824: r = a*Math.sqrt(1.0+r*r);
825: return r;
826: }
827:
828:
829: /** Print the matrix to stdout. Line the elements up in columns
830: * with a Fortran-like 'Fw.d' style format.
831: @param w Column width.
832: @param d Number of digits after the decimal.
833: */
834:
835: public void print (String format) {
836: print(new PrintWriter(System.out,true),format); }
837:
838: /** Print the matrix to the output stream. Line the elements up in columns.
839: * Use the format object, and right justify within columns of width
840: * characters.
841: * Note that is the matrix is to be read back in, you probably will want
842: * to use a NumberFormat that is set to US Locale.
843: @param output the output stream.
844: @param format A formatting object to format the matrix elements
845: @param width Column width.
846: @see java.text.DecimalFormat#setDecimalFormatSymbols
847: */
848:
849: public void print (PrintWriter output, String format) {
850: output.println(); // start on new line.
851: for (int i = 0; i < m; i++) {
852: for (int j = 0; j < n; j++) {
853: output.printf(format,A[i][j]);
854: }
855: output.println();
856: }
857: output.println(); // end with blank line.
858: }
859:
860: /** Read a matrix from a stream. The format is the same the print method,
861: * so printed matrices can be read back in (provided they were printed using
862: * US Locale). Elements are separated by
863: * whitespace, all the elements for each row appear on a single line,
864: * the last row is followed by a blank line.
865: @param input the input stream.
866: */
867:
868: public static Matrix read (BufferedReader input) throws java.io.IOException {
869: StreamTokenizer tokenizer= new StreamTokenizer(input);
870:
871: // Although StreamTokenizer will parse numbers, it doesn't recognize
872: // scientific notation (E or D); however, Double.valueOf does.
873: // The strategy here is to disable StreamTokenizer's number parsing.
874: // We'll only get whitespace delimited words, EOL's and EOF's.
875: // These words should all be numbers, for Double.valueOf to parse.
876:
877: tokenizer.resetSyntax();
878: tokenizer.wordChars(0,255);
879: tokenizer.whitespaceChars(0, ' ');
880: tokenizer.eolIsSignificant(true);
881: java.util.Vector<Double> u = new java.util.Vector<Double>();
882:
883: // Ignore initial empty lines
884: while (tokenizer.nextToken() == StreamTokenizer.TT_EOL);
885: if (tokenizer.ttype == StreamTokenizer.TT_EOF)
886: throw new java.io.IOException("Unexpected EOF on matrix read.");
887: do {
888: Double d = Double.valueOf(tokenizer.sval);
889: u.addElement(d); // Read & store 1st row.
890: } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
891:
892: int n = u.size(); // Now we've got the number of columns!
893:
894: java.util.Vector<Double[]> v = new java.util.Vector<Double[]>();
895: Double row[] = new Double[n];
896: for (int j=0; j<n; j++) // extract the elements of the 1st row.
897: row[j]=u.elementAt(j);
898: v.addElement(row); // Start storing rows instead of columns.
899: while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) {
900: // While non-empty lines
901: row = new Double[n];
902: v.addElement(row);
903: int j = 0;
904: do {
905: if (j >= n) throw new java.io.IOException
906: ("Row " + v.size() + " is too long.");
907: row[j++] = Double.valueOf(tokenizer.sval);
908: } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
909: if (j < n) throw new java.io.IOException
910: ("Row " + v.size() + " is too short.");
911: }
912: int m = v.size(); // Now we've got the number of rows.
913: double[][] A = new double[m][n];
914: for (int i=0; i<m; i++) {
915: row = v.get(i);
916: for (int j=0; j<n; j++) A[i][j] = row[j];
917: }
918: return new Matrix(A);
919: }
920:
921:
922: /* ------------------------
923: Private Methods
924: * ------------------------ */
925:
926: /** Check if size(A) == size(B) **/
927:
928: private void checkMatrixDimensions (Matrix B) {
929: if (B.m != m || B.n != n) {
930: throw new IllegalArgumentException("Matrix dimensions must agree.");
931: }
932: }
933: }
mtest.java01: import java.io.*;
02:
03: public class mtest {
04: public static void main(String args[])
05: {
06: if (args.length>0) {
07: FileInputStream instream;
08: BufferedReader in;
09: try {
10: String filename = args[0];
11: System.out.println("Filename: " + filename);
12: instream = new FileInputStream(filename);
13: in = new BufferedReader(new InputStreamReader(instream));
14: Matrix A = Matrix.read(in);
15: A.print("\t%.2g");
16: } catch (IOException e) {
17: System.out.println( e);
18: }
19: }
20: else {
21: double a[][] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
22: Matrix A = new Matrix(a);
23: A.print("\t%.1g");
24: System.out.println("Test hypot(3,4): " + Matrix.hypot(3,4) + " " + Matrix.hypot(4,3));
25: }
26: }
27: }
Command:
java mtest
Results:
1 2 3 4 5 6 7 8 9 Test hypot(3,4): 5.0 5.0
Maintained by John Loomis, updated Mon Mar 24 13:38:14 2008