Matrix.java

Download: project files

This is a Java implementation of a Matrix class, similar to our C++ version

Reference

JAMA: A Java Matrix Package


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.java


01: 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: }


Results

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