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