Statistiques
| Révision :

root / tmp / org.txm.analec.rcp / src / JamaPlus / Matrix.java @ 2086

Historique | Voir | Annoter | Télécharger (33,16 ko)

1 481 mdecorde
package JamaPlus;
2 481 mdecorde
3 481 mdecorde
import java.text.NumberFormat;
4 481 mdecorde
import java.text.DecimalFormat;
5 481 mdecorde
import java.text.DecimalFormatSymbols;
6 481 mdecorde
import java.util.Locale;
7 481 mdecorde
import java.io.PrintWriter;
8 481 mdecorde
import java.io.BufferedReader;
9 481 mdecorde
import java.io.StreamTokenizer;
10 481 mdecorde
import JamaPlus.util.*;
11 481 mdecorde
import java.util.ArrayList;
12 481 mdecorde
13 481 mdecorde
/**
14 481 mdecorde
Jama = Java Matrix class.
15 481 mdecorde
<P>
16 481 mdecorde
The Java Matrix Class provides the fundamental operations of numerical
17 481 mdecorde
linear algebra.  Various constructors create Matrices from two dimensional
18 481 mdecorde
arrays of double precision floating point numbers.  Various "gets" and
19 481 mdecorde
"sets" provide access to submatrices and matrix elements.  Several methods
20 481 mdecorde
implement basic matrix arithmetic, including matrix addition and
21 481 mdecorde
multiplication, matrix norms, and element-by-element array operations.
22 481 mdecorde
Methods for reading and printing matrices are also included.  All the
23 481 mdecorde
operations in this version of the Matrix Class involve real matrices.
24 481 mdecorde
Complex matrices may be handled in a future version.
25 481 mdecorde
<P>
26 481 mdecorde
Five fundamental matrix decompositions, which consist of pairs or triples
27 481 mdecorde
of matrices, permutation vectors, and the like, produce results in five
28 481 mdecorde
decomposition classes.  These decompositions are accessed by the Matrix
29 481 mdecorde
class to compute solutions of simultaneous linear equations, determinants,
30 481 mdecorde
inverses and other matrix functions.  The five decompositions are:
31 481 mdecorde
<P><UL>
32 481 mdecorde
<LI>Cholesky Decomposition of symmetric, positive definite matrices.
33 481 mdecorde
<LI>LU Decomposition of rectangular matrices.
34 481 mdecorde
<LI>QR Decomposition of rectangular matrices.
35 481 mdecorde
<LI>Singular Value Decomposition of rectangular matrices.
36 481 mdecorde
<LI>Eigenvalue Decomposition of both symmetric and nonsymmetric square matrices.
37 481 mdecorde
</UL>
38 481 mdecorde
<DL>
39 481 mdecorde
<DT><B>Example of use:</B></DT>
40 481 mdecorde
<P>
41 481 mdecorde
<DD>Solve a linear system A x = b and compute the residual norm, ||b - A x||.
42 481 mdecorde
<P><PRE>
43 481 mdecorde
double[][] vals = {{1.,2.,3},{4.,5.,6.},{7.,8.,10.}};
44 481 mdecorde
Matrix A = new Matrix(vals);
45 481 mdecorde
Matrix b = Matrix.random(3,1);
46 481 mdecorde
Matrix x = A.solve(b);
47 481 mdecorde
Matrix r = A.times(x).minus(b);
48 481 mdecorde
double rnorm = r.normInf();
49 481 mdecorde
</PRE></DD>
50 481 mdecorde
</DL>
51 481 mdecorde

52 481 mdecorde
@author The MathWorks, Inc. and the National Institute of Standards and Technology.
53 481 mdecorde
@version 5 August 1998
54 481 mdecorde
 */
55 481 mdecorde
public class Matrix implements Cloneable, java.io.Serializable {
56 481 mdecorde
57 481 mdecorde
  /* ------------------------
58 481 mdecorde
  Class variables
59 481 mdecorde
   * ------------------------ */
60 481 mdecorde
  /** Array for internal storage of elements.
61 481 mdecorde
  @serial internal array storage.
62 481 mdecorde
   */
63 481 mdecorde
  private double[][] A;
64 481 mdecorde
  /** Row and column dimensions.
65 481 mdecorde
  @serial row dimension.
66 481 mdecorde
  @serial column dimension.
67 481 mdecorde
   */
68 481 mdecorde
  private int m, n;
69 481 mdecorde
70 481 mdecorde
  /* ------------------------
71 481 mdecorde
  Constructors
72 481 mdecorde
   * ------------------------ */
73 481 mdecorde
  /** Construct an m-by-n matrix of zeros.
74 481 mdecorde
  @param m    Number of rows.
75 481 mdecorde
  @param n    Number of colums.
76 481 mdecorde
   */
77 481 mdecorde
  public Matrix(int m, int n) {
78 481 mdecorde
    this.m = m;
79 481 mdecorde
    this.n = n;
80 481 mdecorde
    A = new double[m][n];
81 481 mdecorde
  }
82 481 mdecorde
83 481 mdecorde
  /** Construct an m-by-n constant matrix.
84 481 mdecorde
  @param m    Number of rows.
85 481 mdecorde
  @param n    Number of colums.
86 481 mdecorde
  @param s    Fill the matrix with this scalar value.
87 481 mdecorde
   */
88 481 mdecorde
  public Matrix(int m, int n, double s) {
89 481 mdecorde
    this.m = m;
90 481 mdecorde
    this.n = n;
91 481 mdecorde
    A = new double[m][n];
92 481 mdecorde
    for (int i = 0; i < m; i++) {
93 481 mdecorde
      for (int j = 0; j < n; j++) {
94 481 mdecorde
        A[i][j] = s;
95 481 mdecorde
      }
96 481 mdecorde
    }
97 481 mdecorde
  }
98 481 mdecorde
99 481 mdecorde
  /** Construct a matrix from a 2-D array.
100 481 mdecorde
  @param A    Two-dimensional array of doubles.
101 481 mdecorde
  @exception  IllegalArgumentException All rows must have the same length
102 481 mdecorde
  @see        #constructWithCopy
103 481 mdecorde
   */
104 481 mdecorde
  public Matrix(double[][] A) {
105 481 mdecorde
    m = A.length;
106 481 mdecorde
    n = A[0].length;
107 481 mdecorde
    for (int i = 0; i < m; i++) {
108 481 mdecorde
      if (A[i].length != n) {
109 481 mdecorde
        throw new IllegalArgumentException("All rows must have the same length.");
110 481 mdecorde
      }
111 481 mdecorde
    }
112 481 mdecorde
    this.A = A;
113 481 mdecorde
  }
114 481 mdecorde
115 481 mdecorde
  /** Construct a matrix quickly without checking arguments.
116 481 mdecorde
  @param A    Two-dimensional array of doubles.
117 481 mdecorde
  @param m    Number of rows.
118 481 mdecorde
  @param n    Number of colums.
119 481 mdecorde
   */
120 481 mdecorde
  public Matrix(double[][] A, int m, int n) {
121 481 mdecorde
    this.A = A;
122 481 mdecorde
    this.m = m;
123 481 mdecorde
    this.n = n;
124 481 mdecorde
  }
125 481 mdecorde
126 481 mdecorde
  /** Construct a matrix from a one-dimensional packed array
127 481 mdecorde
  @param vals One-dimensional array of doubles, packed by columns (ala Fortran).
128 481 mdecorde
  @param m    Number of rows.
129 481 mdecorde
  @exception  IllegalArgumentException Array length must be a multiple of m.
130 481 mdecorde
   */
131 481 mdecorde
  public Matrix(double vals[], int m) {
132 481 mdecorde
    this.m = m;
133 481 mdecorde
    n = (m != 0 ? vals.length / m : 0);
134 481 mdecorde
    if (m * n != vals.length) {
135 481 mdecorde
      throw new IllegalArgumentException("Array length must be a multiple of m.");
136 481 mdecorde
    }
137 481 mdecorde
    A = new double[m][n];
138 481 mdecorde
    for (int i = 0; i < m; i++) {
139 481 mdecorde
      for (int j = 0; j < n; j++) {
140 481 mdecorde
        A[i][j] = vals[i + j * m];
141 481 mdecorde
      }
142 481 mdecorde
    }
143 481 mdecorde
  }
144 481 mdecorde
145 481 mdecorde
  /* ------------------------
146 481 mdecorde
  Public Methods
147 481 mdecorde
   * ------------------------ */
148 481 mdecorde
  /** Construct a matrix from a copy of a 2-D array.
149 481 mdecorde
  @param A    Two-dimensional array of doubles.
150 481 mdecorde
  @exception  IllegalArgumentException All rows must have the same length
151 481 mdecorde
   */
152 481 mdecorde
  public static Matrix constructWithCopy(double[][] A) {
153 481 mdecorde
    int m = A.length;
154 481 mdecorde
    int n = A[0].length;
155 481 mdecorde
    Matrix X = new Matrix(m, n);
156 481 mdecorde
    double[][] C = X.getArray();
157 481 mdecorde
    for (int i = 0; i < m; i++) {
158 481 mdecorde
      if (A[i].length != n) {
159 481 mdecorde
        throw new IllegalArgumentException("All rows must have the same length.");
160 481 mdecorde
      }
161 481 mdecorde
      for (int j = 0; j < n; j++) {
162 481 mdecorde
        C[i][j] = A[i][j];
163 481 mdecorde
      }
164 481 mdecorde
    }
165 481 mdecorde
    return X;
166 481 mdecorde
  }
167 481 mdecorde
168 481 mdecorde
  /** Make a deep copy of a matrix
169 481 mdecorde
   */
170 481 mdecorde
  public Matrix copy() {
171 481 mdecorde
    Matrix X = new Matrix(m, n);
172 481 mdecorde
    double[][] C = X.getArray();
173 481 mdecorde
    for (int i = 0; i < m; i++) {
174 481 mdecorde
      System.arraycopy(A[i], 0, C[i], 0, n);
175 481 mdecorde
    }
176 481 mdecorde
    return X;
177 481 mdecorde
  }
178 481 mdecorde
179 481 mdecorde
  /** Clone the Matrix object.
180 481 mdecorde
   */
181 481 mdecorde
  public Object clone() {
182 481 mdecorde
    return this.copy();
183 481 mdecorde
  }
184 481 mdecorde
185 481 mdecorde
  /** Access the internal two-dimensional array.
186 481 mdecorde
  @return     Pointer to the two-dimensional array of matrix elements.
187 481 mdecorde
   */
188 481 mdecorde
  public double[][] getArray() {
189 481 mdecorde
    return A;
190 481 mdecorde
  }
191 481 mdecorde
192 481 mdecorde
  /** Copy the internal two-dimensional array.
193 481 mdecorde
  @return     Two-dimensional array copy of matrix elements.
194 481 mdecorde
   */
195 481 mdecorde
  public double[][] getArrayCopy() {
196 481 mdecorde
    double[][] C = new double[m][n];
197 481 mdecorde
    for (int i = 0; i < m; i++) {
198 481 mdecorde
      System.arraycopy(A[i], 0, C[i], 0, n);
199 481 mdecorde
    }
200 481 mdecorde
    return C;
201 481 mdecorde
  }
202 481 mdecorde
203 481 mdecorde
  /** Make a one-dimensional column packed copy of the internal array.
204 481 mdecorde
  @return     Matrix elements packed in a one-dimensional array by columns.
205 481 mdecorde
   */
206 481 mdecorde
  public double[] getColumnPackedCopy() {
207 481 mdecorde
    double[] vals = new double[m * n];
208 481 mdecorde
    for (int i = 0; i < m; i++) {
209 481 mdecorde
      for (int j = 0; j < n; j++) {
210 481 mdecorde
        vals[i + j * m] = A[i][j];
211 481 mdecorde
      }
212 481 mdecorde
    }
213 481 mdecorde
    return vals;
214 481 mdecorde
  }
215 481 mdecorde
216 481 mdecorde
  /** Make a one-dimensional row packed copy of the internal array.
217 481 mdecorde
  @return     Matrix elements packed in a one-dimensional array by rows.
218 481 mdecorde
   */
219 481 mdecorde
  public double[] getRowPackedCopy() {
220 481 mdecorde
    double[] vals = new double[m * n];
221 481 mdecorde
    for (int i = 0; i < m; i++) {
222 481 mdecorde
      for (int j = 0; j < n; j++) {
223 481 mdecorde
        vals[i * n + j] = A[i][j];
224 481 mdecorde
      }
225 481 mdecorde
    }
226 481 mdecorde
    return vals;
227 481 mdecorde
  }
228 481 mdecorde
229 481 mdecorde
  /** Get row dimension.
230 481 mdecorde
  @return     m, the number of rows.
231 481 mdecorde
   */
232 481 mdecorde
  public int getRowDimension() {
233 481 mdecorde
    return m;
234 481 mdecorde
  }
235 481 mdecorde
236 481 mdecorde
  /** Get column dimension.
237 481 mdecorde
  @return     n, the number of columns.
238 481 mdecorde
   */
239 481 mdecorde
  public int getColumnDimension() {
240 481 mdecorde
    return n;
241 481 mdecorde
  }
242 481 mdecorde
243 481 mdecorde
  /** Get a single element.
244 481 mdecorde
  @param i    Row index.
245 481 mdecorde
  @param j    Column index.
246 481 mdecorde
  @return     A(i,j)
247 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException
248 481 mdecorde
   */
249 481 mdecorde
  public double get(int i, int j) {
250 481 mdecorde
    return A[i][j];
251 481 mdecorde
  }
252 481 mdecorde
253 481 mdecorde
  /** Get a submatrix.
254 481 mdecorde
  @param i0   Initial row index
255 481 mdecorde
  @param i1   Final row index
256 481 mdecorde
  @param j0   Initial column index
257 481 mdecorde
  @param j1   Final column index
258 481 mdecorde
  @return     A(i0:i1,j0:j1)
259 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException Submatrix indices
260 481 mdecorde
   */
261 481 mdecorde
  public Matrix getMatrix(int i0, int i1, int j0, int j1) {
262 481 mdecorde
    Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1);
263 481 mdecorde
    double[][] B = X.getArray();
264 481 mdecorde
    try {
265 481 mdecorde
      for (int i = i0; i <= i1; i++) {
266 481 mdecorde
        for (int j = j0; j <= j1; j++) {
267 481 mdecorde
          B[i - i0][j - j0] = A[i][j];
268 481 mdecorde
        }
269 481 mdecorde
      }
270 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException e) {
271 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
272 481 mdecorde
    }
273 481 mdecorde
    return X;
274 481 mdecorde
  }
275 481 mdecorde
276 481 mdecorde
  /** Get a submatrix.
277 481 mdecorde
  @param r    Array of row indices.
278 481 mdecorde
  @param c    Array of column indices.
279 481 mdecorde
  @return     A(r(:),c(:))
280 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException Submatrix indices
281 481 mdecorde
   */
282 481 mdecorde
  public Matrix getMatrix(int[] r, int[] c) {
283 481 mdecorde
    Matrix X = new Matrix(r.length, c.length);
284 481 mdecorde
    double[][] B = X.getArray();
285 481 mdecorde
    try {
286 481 mdecorde
      for (int i = 0; i < r.length; i++) {
287 481 mdecorde
        for (int j = 0; j < c.length; j++) {
288 481 mdecorde
          B[i][j] = A[r[i]][c[j]];
289 481 mdecorde
        }
290 481 mdecorde
      }
291 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException e) {
292 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
293 481 mdecorde
    }
294 481 mdecorde
    return X;
295 481 mdecorde
  }
296 481 mdecorde
297 481 mdecorde
  /** Get a submatrix.
298 481 mdecorde
  @param i0   Initial row index
299 481 mdecorde
  @param i1   Final row index
300 481 mdecorde
  @param c    Array of column indices.
301 481 mdecorde
  @return     A(i0:i1,c(:))
302 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException Submatrix indices
303 481 mdecorde
   */
304 481 mdecorde
  public Matrix getMatrix(int i0, int i1, int[] c) {
305 481 mdecorde
    Matrix X = new Matrix(i1 - i0 + 1, c.length);
306 481 mdecorde
    double[][] B = X.getArray();
307 481 mdecorde
    try {
308 481 mdecorde
      for (int i = i0; i <= i1; i++) {
309 481 mdecorde
        for (int j = 0; j < c.length; j++) {
310 481 mdecorde
          B[i - i0][j] = A[i][c[j]];
311 481 mdecorde
        }
312 481 mdecorde
      }
313 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException e) {
314 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
315 481 mdecorde
    }
316 481 mdecorde
    return X;
317 481 mdecorde
  }
318 481 mdecorde
319 481 mdecorde
  /** Get a submatrix.
320 481 mdecorde
  @param r    Array of row indices.
321 481 mdecorde
  @param i0   Initial column index
322 481 mdecorde
  @param i1   Final column index
323 481 mdecorde
  @return     A(r(:),j0:j1)
324 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException Submatrix indices
325 481 mdecorde
   */
326 481 mdecorde
  public Matrix getMatrix(int[] r, int j0, int j1) {
327 481 mdecorde
    Matrix X = new Matrix(r.length, j1 - j0 + 1);
328 481 mdecorde
    double[][] B = X.getArray();
329 481 mdecorde
    try {
330 481 mdecorde
      for (int i = 0; i < r.length; i++) {
331 481 mdecorde
        for (int j = j0; j <= j1; j++) {
332 481 mdecorde
          B[i][j - j0] = A[r[i]][j];
333 481 mdecorde
        }
334 481 mdecorde
      }
335 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException e) {
336 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
337 481 mdecorde
    }
338 481 mdecorde
    return X;
339 481 mdecorde
  }
340 481 mdecorde
341 481 mdecorde
  /** Set a single element.
342 481 mdecorde
  @param i    Row index.
343 481 mdecorde
  @param j    Column index.
344 481 mdecorde
  @param s    A(i,j).
345 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException
346 481 mdecorde
   */
347 481 mdecorde
  public void set(int i, int j, double s) {
348 481 mdecorde
    A[i][j] = s;
349 481 mdecorde
  }
350 481 mdecorde
351 481 mdecorde
  /** Set a submatrix.
352 481 mdecorde
  @param i0   Initial row index
353 481 mdecorde
  @param i1   Final row index
354 481 mdecorde
  @param j0   Initial column index
355 481 mdecorde
  @param j1   Final column index
356 481 mdecorde
  @param X    A(i0:i1,j0:j1)
357 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException Submatrix indices
358 481 mdecorde
   */
359 481 mdecorde
  public void setMatrix(int i0, int i1, int j0, int j1, Matrix X) {
360 481 mdecorde
    try {
361 481 mdecorde
      for (int i = i0; i <= i1; i++) {
362 481 mdecorde
        for (int j = j0; j <= j1; j++) {
363 481 mdecorde
          A[i][j] = X.get(i - i0, j - j0);
364 481 mdecorde
        }
365 481 mdecorde
      }
366 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException e) {
367 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
368 481 mdecorde
    }
369 481 mdecorde
  }
370 481 mdecorde
371 481 mdecorde
  /** Set a submatrix.
372 481 mdecorde
  @param r    Array of row indices.
373 481 mdecorde
  @param c    Array of column indices.
374 481 mdecorde
  @param X    A(r(:),c(:))
375 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException Submatrix indices
376 481 mdecorde
   */
377 481 mdecorde
  public void setMatrix(int[] r, int[] c, Matrix X) {
378 481 mdecorde
    try {
379 481 mdecorde
      for (int i = 0; i < r.length; i++) {
380 481 mdecorde
        for (int j = 0; j < c.length; j++) {
381 481 mdecorde
          A[r[i]][c[j]] = X.get(i, j);
382 481 mdecorde
        }
383 481 mdecorde
      }
384 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException e) {
385 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
386 481 mdecorde
    }
387 481 mdecorde
  }
388 481 mdecorde
389 481 mdecorde
  /** Set a submatrix.
390 481 mdecorde
  @param r    Array of row indices.
391 481 mdecorde
  @param j0   Initial column index
392 481 mdecorde
  @param j1   Final column index
393 481 mdecorde
  @param X    A(r(:),j0:j1)
394 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException Submatrix indices
395 481 mdecorde
   */
396 481 mdecorde
  public void setMatrix(int[] r, int j0, int j1, Matrix X) {
397 481 mdecorde
    try {
398 481 mdecorde
      for (int i = 0; i < r.length; i++) {
399 481 mdecorde
        for (int j = j0; j <= j1; j++) {
400 481 mdecorde
          A[r[i]][j] = X.get(i, j - j0);
401 481 mdecorde
        }
402 481 mdecorde
      }
403 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException e) {
404 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
405 481 mdecorde
    }
406 481 mdecorde
  }
407 481 mdecorde
408 481 mdecorde
  /** Set a submatrix.
409 481 mdecorde
  @param i0   Initial row index
410 481 mdecorde
  @param i1   Final row index
411 481 mdecorde
  @param c    Array of column indices.
412 481 mdecorde
  @param X    A(i0:i1,c(:))
413 481 mdecorde
  @exception  ArrayIndexOutOfBoundsException Submatrix indices
414 481 mdecorde
   */
415 481 mdecorde
  public void setMatrix(int i0, int i1, int[] c, Matrix X) {
416 481 mdecorde
    try {
417 481 mdecorde
      for (int i = i0; i <= i1; i++) {
418 481 mdecorde
        for (int j = 0; j < c.length; j++) {
419 481 mdecorde
          A[i][c[j]] = X.get(i - i0, j);
420 481 mdecorde
        }
421 481 mdecorde
      }
422 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException e) {
423 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Submatrix indices");
424 481 mdecorde
    }
425 481 mdecorde
  }
426 481 mdecorde
427 481 mdecorde
  /** Matrix transpose.
428 481 mdecorde
  @return    A'
429 481 mdecorde
   */
430 481 mdecorde
  public Matrix transpose() {
431 481 mdecorde
    Matrix X = new Matrix(n, m);
432 481 mdecorde
    double[][] C = X.getArray();
433 481 mdecorde
    for (int i = 0; i < m; i++) {
434 481 mdecorde
      for (int j = 0; j < n; j++) {
435 481 mdecorde
        C[j][i] = A[i][j];
436 481 mdecorde
      }
437 481 mdecorde
    }
438 481 mdecorde
    return X;
439 481 mdecorde
  }
440 481 mdecorde
441 481 mdecorde
  /** One norm
442 481 mdecorde
  @return    maximum column sum.
443 481 mdecorde
   */
444 481 mdecorde
  public double norm1() {
445 481 mdecorde
    double f = 0;
446 481 mdecorde
    for (int j = 0; j < n; j++) {
447 481 mdecorde
      double s = 0;
448 481 mdecorde
      for (int i = 0; i < m; i++) {
449 481 mdecorde
        s += Math.abs(A[i][j]);
450 481 mdecorde
      }
451 481 mdecorde
      f = Math.max(f, s);
452 481 mdecorde
    }
453 481 mdecorde
    return f;
454 481 mdecorde
  }
455 481 mdecorde
456 481 mdecorde
  /** Two norm
457 481 mdecorde
  @return    maximum singular value.
458 481 mdecorde
   */
459 481 mdecorde
  public double norm2() {
460 481 mdecorde
    return (new SingularValueDecomposition(this).norm2());
461 481 mdecorde
  }
462 481 mdecorde
463 481 mdecorde
  /** Infinity norm
464 481 mdecorde
  @return    maximum row sum.
465 481 mdecorde
   */
466 481 mdecorde
  public double normInf() {
467 481 mdecorde
    double f = 0;
468 481 mdecorde
    for (int i = 0; i < m; i++) {
469 481 mdecorde
      double s = 0;
470 481 mdecorde
      for (int j = 0; j < n; j++) {
471 481 mdecorde
        s += Math.abs(A[i][j]);
472 481 mdecorde
      }
473 481 mdecorde
      f = Math.max(f, s);
474 481 mdecorde
    }
475 481 mdecorde
    return f;
476 481 mdecorde
  }
477 481 mdecorde
478 481 mdecorde
  /** Frobenius norm
479 481 mdecorde
  @return    sqrt of sum of squares of all elements.
480 481 mdecorde
   */
481 481 mdecorde
  public double normF() {
482 481 mdecorde
    double f = 0;
483 481 mdecorde
    for (int i = 0; i < m; i++) {
484 481 mdecorde
      for (int j = 0; j < n; j++) {
485 481 mdecorde
        f = Math.hypot(f, A[i][j]);
486 481 mdecorde
      }
487 481 mdecorde
    }
488 481 mdecorde
    return f;
489 481 mdecorde
  }
490 481 mdecorde
491 481 mdecorde
  /**  Unary minus
492 481 mdecorde
  @return    -A
493 481 mdecorde
   */
494 481 mdecorde
  public Matrix uminus() {
495 481 mdecorde
    Matrix X = new Matrix(m, n);
496 481 mdecorde
    double[][] C = X.getArray();
497 481 mdecorde
    for (int i = 0; i < m; i++) {
498 481 mdecorde
      for (int j = 0; j < n; j++) {
499 481 mdecorde
        C[i][j] = -A[i][j];
500 481 mdecorde
      }
501 481 mdecorde
    }
502 481 mdecorde
    return X;
503 481 mdecorde
  }
504 481 mdecorde
505 481 mdecorde
  /** C = A + B
506 481 mdecorde
  @param B    another matrix
507 481 mdecorde
  @return     A + B
508 481 mdecorde
   */
509 481 mdecorde
  public Matrix plus(Matrix B) {
510 481 mdecorde
    checkMatrixDimensions(B);
511 481 mdecorde
    Matrix X = new Matrix(m, n);
512 481 mdecorde
    double[][] C = X.getArray();
513 481 mdecorde
    for (int i = 0; i < m; i++) {
514 481 mdecorde
      for (int j = 0; j < n; j++) {
515 481 mdecorde
        C[i][j] = A[i][j] + B.A[i][j];
516 481 mdecorde
      }
517 481 mdecorde
    }
518 481 mdecorde
    return X;
519 481 mdecorde
  }
520 481 mdecorde
521 481 mdecorde
  /** A = A + B
522 481 mdecorde
  @param B    another matrix
523 481 mdecorde
  @return     A + B
524 481 mdecorde
   */
525 481 mdecorde
  public Matrix plusEquals(Matrix B) {
526 481 mdecorde
    checkMatrixDimensions(B);
527 481 mdecorde
    for (int i = 0; i < m; i++) {
528 481 mdecorde
      for (int j = 0; j < n; j++) {
529 481 mdecorde
        A[i][j] = A[i][j] + B.A[i][j];
530 481 mdecorde
      }
531 481 mdecorde
    }
532 481 mdecorde
    return this;
533 481 mdecorde
  }
534 481 mdecorde
535 481 mdecorde
  /** C = A - B
536 481 mdecorde
  @param B    another matrix
537 481 mdecorde
  @return     A - B
538 481 mdecorde
   */
539 481 mdecorde
  public Matrix minus(Matrix B) {
540 481 mdecorde
    checkMatrixDimensions(B);
541 481 mdecorde
    Matrix X = new Matrix(m, n);
542 481 mdecorde
    double[][] C = X.getArray();
543 481 mdecorde
    for (int i = 0; i < m; i++) {
544 481 mdecorde
      for (int j = 0; j < n; j++) {
545 481 mdecorde
        C[i][j] = A[i][j] - B.A[i][j];
546 481 mdecorde
      }
547 481 mdecorde
    }
548 481 mdecorde
    return X;
549 481 mdecorde
  }
550 481 mdecorde
551 481 mdecorde
  /** A = A - B
552 481 mdecorde
  @param B    another matrix
553 481 mdecorde
  @return     A - B
554 481 mdecorde
   */
555 481 mdecorde
  public Matrix minusEquals(Matrix B) {
556 481 mdecorde
    checkMatrixDimensions(B);
557 481 mdecorde
    for (int i = 0; i < m; i++) {
558 481 mdecorde
      for (int j = 0; j < n; j++) {
559 481 mdecorde
        A[i][j] = A[i][j] - B.A[i][j];
560 481 mdecorde
      }
561 481 mdecorde
    }
562 481 mdecorde
    return this;
563 481 mdecorde
  }
564 481 mdecorde
565 481 mdecorde
  /** Element-by-element multiplication, C = A.*B
566 481 mdecorde
  @param B    another matrix
567 481 mdecorde
  @return     A.*B
568 481 mdecorde
   */
569 481 mdecorde
  public Matrix arrayTimes(Matrix B) {
570 481 mdecorde
    checkMatrixDimensions(B);
571 481 mdecorde
    Matrix X = new Matrix(m, n);
572 481 mdecorde
    double[][] C = X.getArray();
573 481 mdecorde
    for (int i = 0; i < m; i++) {
574 481 mdecorde
      for (int j = 0; j < n; j++) {
575 481 mdecorde
        C[i][j] = A[i][j] * B.A[i][j];
576 481 mdecorde
      }
577 481 mdecorde
    }
578 481 mdecorde
    return X;
579 481 mdecorde
  }
580 481 mdecorde
581 481 mdecorde
  /** Element-by-element multiplication in place, A = A.*B
582 481 mdecorde
  @param B    another matrix
583 481 mdecorde
  @return     A.*B
584 481 mdecorde
   */
585 481 mdecorde
  public Matrix arrayTimesEquals(Matrix B) {
586 481 mdecorde
    checkMatrixDimensions(B);
587 481 mdecorde
    for (int i = 0; i < m; i++) {
588 481 mdecorde
      for (int j = 0; j < n; j++) {
589 481 mdecorde
        A[i][j] = A[i][j] * B.A[i][j];
590 481 mdecorde
      }
591 481 mdecorde
    }
592 481 mdecorde
    return this;
593 481 mdecorde
  }
594 481 mdecorde
595 481 mdecorde
  /** Element-by-element right division, C = A./B
596 481 mdecorde
  @param B    another matrix
597 481 mdecorde
  @return     A./B
598 481 mdecorde
   */
599 481 mdecorde
  public Matrix arrayRightDivide(Matrix B) {
600 481 mdecorde
    checkMatrixDimensions(B);
601 481 mdecorde
    Matrix X = new Matrix(m, n);
602 481 mdecorde
    double[][] C = X.getArray();
603 481 mdecorde
    for (int i = 0; i < m; i++) {
604 481 mdecorde
      for (int j = 0; j < n; j++) {
605 481 mdecorde
        C[i][j] = A[i][j] / B.A[i][j];
606 481 mdecorde
      }
607 481 mdecorde
    }
608 481 mdecorde
    return X;
609 481 mdecorde
  }
610 481 mdecorde
611 481 mdecorde
  /** Element-by-element right division in place, A = A./B
612 481 mdecorde
  @param B    another matrix
613 481 mdecorde
  @return     A./B
614 481 mdecorde
   */
615 481 mdecorde
  public Matrix arrayRightDivideEquals(Matrix B) {
616 481 mdecorde
    checkMatrixDimensions(B);
617 481 mdecorde
    for (int i = 0; i < m; i++) {
618 481 mdecorde
      for (int j = 0; j < n; j++) {
619 481 mdecorde
        A[i][j] = A[i][j] / B.A[i][j];
620 481 mdecorde
      }
621 481 mdecorde
    }
622 481 mdecorde
    return this;
623 481 mdecorde
  }
624 481 mdecorde
625 481 mdecorde
  /** Element-by-element left division, C = A.\B
626 481 mdecorde
  @param B    another matrix
627 481 mdecorde
  @return     A.\B
628 481 mdecorde
   */
629 481 mdecorde
  public Matrix arrayLeftDivide(Matrix B) {
630 481 mdecorde
    checkMatrixDimensions(B);
631 481 mdecorde
    Matrix X = new Matrix(m, n);
632 481 mdecorde
    double[][] C = X.getArray();
633 481 mdecorde
    for (int i = 0; i < m; i++) {
634 481 mdecorde
      for (int j = 0; j < n; j++) {
635 481 mdecorde
        C[i][j] = B.A[i][j] / A[i][j];
636 481 mdecorde
      }
637 481 mdecorde
    }
638 481 mdecorde
    return X;
639 481 mdecorde
  }
640 481 mdecorde
641 481 mdecorde
  /** Element-by-element left division in place, A = A.\B
642 481 mdecorde
  @param B    another matrix
643 481 mdecorde
  @return     A.\B
644 481 mdecorde
   */
645 481 mdecorde
  public Matrix arrayLeftDivideEquals(Matrix B) {
646 481 mdecorde
    checkMatrixDimensions(B);
647 481 mdecorde
    for (int i = 0; i < m; i++) {
648 481 mdecorde
      for (int j = 0; j < n; j++) {
649 481 mdecorde
        A[i][j] = B.A[i][j] / A[i][j];
650 481 mdecorde
      }
651 481 mdecorde
    }
652 481 mdecorde
    return this;
653 481 mdecorde
  }
654 481 mdecorde
655 481 mdecorde
  /** Multiply a matrix by a scalar, C = s*A
656 481 mdecorde
  @param s    scalar
657 481 mdecorde
  @return     s*A
658 481 mdecorde
   */
659 481 mdecorde
  public Matrix times(double s) {
660 481 mdecorde
    Matrix X = new Matrix(m, n);
661 481 mdecorde
    double[][] C = X.getArray();
662 481 mdecorde
    for (int i = 0; i < m; i++) {
663 481 mdecorde
      for (int j = 0; j < n; j++) {
664 481 mdecorde
        C[i][j] = s * A[i][j];
665 481 mdecorde
      }
666 481 mdecorde
    }
667 481 mdecorde
    return X;
668 481 mdecorde
  }
669 481 mdecorde
670 481 mdecorde
  /** Multiply a matrix by a scalar in place, A = s*A
671 481 mdecorde
  @param s    scalar
672 481 mdecorde
  @return     replace A by s*A
673 481 mdecorde
   */
674 481 mdecorde
  public Matrix timesEquals(double s) {
675 481 mdecorde
    for (int i = 0; i < m; i++) {
676 481 mdecorde
      for (int j = 0; j < n; j++) {
677 481 mdecorde
        A[i][j] = s * A[i][j];
678 481 mdecorde
      }
679 481 mdecorde
    }
680 481 mdecorde
    return this;
681 481 mdecorde
  }
682 481 mdecorde
683 481 mdecorde
  /** Linear algebraic matrix multiplication, A * B
684 481 mdecorde
  @param B    another matrix
685 481 mdecorde
  @return     Matrix product, A * B
686 481 mdecorde
  @exception  IllegalArgumentException Matrix inner dimensions must agree.
687 481 mdecorde
   */
688 481 mdecorde
  public Matrix times(Matrix B) {
689 481 mdecorde
    if (B.m != n) {
690 481 mdecorde
      throw new IllegalArgumentException("Matrix inner dimensions must agree.");
691 481 mdecorde
    }
692 481 mdecorde
    Matrix X = new Matrix(m, B.n);
693 481 mdecorde
    double[][] C = X.getArray();
694 481 mdecorde
    double[] Bcolj = new double[n];
695 481 mdecorde
    for (int j = 0; j < B.n; j++) {
696 481 mdecorde
      for (int k = 0; k < n; k++) {
697 481 mdecorde
        Bcolj[k] = B.A[k][j];
698 481 mdecorde
      }
699 481 mdecorde
      for (int i = 0; i < m; i++) {
700 481 mdecorde
        double[] Arowi = A[i];
701 481 mdecorde
        double s = 0;
702 481 mdecorde
        for (int k = 0; k < n; k++) {
703 481 mdecorde
          s += Arowi[k] * Bcolj[k];
704 481 mdecorde
        }
705 481 mdecorde
        C[i][j] = s;
706 481 mdecorde
      }
707 481 mdecorde
    }
708 481 mdecorde
    return X;
709 481 mdecorde
  }
710 481 mdecorde
711 481 mdecorde
  /** LU Decomposition
712 481 mdecorde
  @return     LUDecomposition
713 481 mdecorde
  @see LUDecomposition
714 481 mdecorde
   */
715 481 mdecorde
  public LUDecomposition lu() {
716 481 mdecorde
    return new LUDecomposition(this);
717 481 mdecorde
  }
718 481 mdecorde
719 481 mdecorde
  /** QR Decomposition
720 481 mdecorde
  @return     QRDecomposition
721 481 mdecorde
  @see QRDecomposition
722 481 mdecorde
   */
723 481 mdecorde
  public QRDecomposition qr() {
724 481 mdecorde
    return new QRDecomposition(this);
725 481 mdecorde
  }
726 481 mdecorde
727 481 mdecorde
  /** Cholesky Decomposition
728 481 mdecorde
  @return     CholeskyDecomposition
729 481 mdecorde
  @see CholeskyDecomposition
730 481 mdecorde
   */
731 481 mdecorde
  public CholeskyDecomposition chol() {
732 481 mdecorde
    return new CholeskyDecomposition(this);
733 481 mdecorde
  }
734 481 mdecorde
735 481 mdecorde
  /** Singular Value Decomposition
736 481 mdecorde
  @return     SingularValueDecomposition
737 481 mdecorde
  @see SingularValueDecomposition
738 481 mdecorde
   */
739 481 mdecorde
  public SingularValueDecomposition svd() {
740 481 mdecorde
    return new SingularValueDecomposition(this);
741 481 mdecorde
  }
742 481 mdecorde
743 481 mdecorde
  /** Eigenvalue Decomposition
744 481 mdecorde
  @return     EigenvalueDecomposition
745 481 mdecorde
  @see EigenvalueDecomposition
746 481 mdecorde
   */
747 481 mdecorde
  public EigenvalueDecomposition eig() {
748 481 mdecorde
    return new EigenvalueDecomposition(this);
749 481 mdecorde
  }
750 481 mdecorde
751 481 mdecorde
  /** Solve A*X = B
752 481 mdecorde
  @param B    right hand side
753 481 mdecorde
  @return     solution if A is square, least squares solution otherwise
754 481 mdecorde
   */
755 481 mdecorde
  public Matrix solve(Matrix B) {
756 481 mdecorde
    return (m == n ? (new LUDecomposition(this)).solve(B) : (new QRDecomposition(this)).solve(B));
757 481 mdecorde
  }
758 481 mdecorde
759 481 mdecorde
  /** Solve X*A = B, which is also A'*X' = B'
760 481 mdecorde
  @param B    right hand side
761 481 mdecorde
  @return     solution if A is square, least squares solution otherwise.
762 481 mdecorde
   */
763 481 mdecorde
  public Matrix solveTranspose(Matrix B) {
764 481 mdecorde
    return transpose().solve(B.transpose());
765 481 mdecorde
  }
766 481 mdecorde
767 481 mdecorde
  /** Matrix inverse or pseudoinverse
768 481 mdecorde
  @return     inverse(A) if A is square, pseudoinverse otherwise.
769 481 mdecorde
   */
770 481 mdecorde
  public Matrix inverse() {
771 481 mdecorde
    return solve(identity(m, m));
772 481 mdecorde
  }
773 481 mdecorde
774 481 mdecorde
  /** Matrix determinant
775 481 mdecorde
  @return     determinant
776 481 mdecorde
   */
777 481 mdecorde
  public double det() {
778 481 mdecorde
    return new LUDecomposition(this).det();
779 481 mdecorde
  }
780 481 mdecorde
781 481 mdecorde
  /** Matrix rank
782 481 mdecorde
  @return     effective numerical rank, obtained from SVD.
783 481 mdecorde
   */
784 481 mdecorde
  public int rank() {
785 481 mdecorde
    return new SingularValueDecomposition(this).rank();
786 481 mdecorde
  }
787 481 mdecorde
788 481 mdecorde
  /** Matrix condition (2 norm)
789 481 mdecorde
  @return     ratio of largest to smallest singular value.
790 481 mdecorde
   */
791 481 mdecorde
  public double cond() {
792 481 mdecorde
    return new SingularValueDecomposition(this).cond();
793 481 mdecorde
  }
794 481 mdecorde
795 481 mdecorde
  /** Matrix trace.
796 481 mdecorde
  @return     sum of the diagonal elements.
797 481 mdecorde
   */
798 481 mdecorde
  public double trace() {
799 481 mdecorde
    double t = 0;
800 481 mdecorde
    for (int i = 0; i < Math.min(m, n); i++) {
801 481 mdecorde
      t += A[i][i];
802 481 mdecorde
    }
803 481 mdecorde
    return t;
804 481 mdecorde
  }
805 481 mdecorde
806 481 mdecorde
  /** Generate matrix with random elements
807 481 mdecorde
  @param m    Number of rows.
808 481 mdecorde
  @param n    Number of colums.
809 481 mdecorde
  @return     An m-by-n matrix with uniformly distributed random elements.
810 481 mdecorde
   */
811 481 mdecorde
  public static Matrix random(int m, int n) {
812 481 mdecorde
    Matrix A = new Matrix(m, n);
813 481 mdecorde
    double[][] X = A.getArray();
814 481 mdecorde
    for (int i = 0; i < m; i++) {
815 481 mdecorde
      for (int j = 0; j < n; j++) {
816 481 mdecorde
        X[i][j] = Math.random();
817 481 mdecorde
      }
818 481 mdecorde
    }
819 481 mdecorde
    return A;
820 481 mdecorde
  }
821 481 mdecorde
822 481 mdecorde
  /** Generate identity matrix
823 481 mdecorde
  @param m    Number of rows.
824 481 mdecorde
  @param n    Number of colums.
825 481 mdecorde
  @return     An m-by-n matrix with ones on the diagonal and zeros elsewhere.
826 481 mdecorde
   */
827 481 mdecorde
  public static Matrix identity(int m, int n) {
828 481 mdecorde
    Matrix A = new Matrix(m, n);
829 481 mdecorde
    double[][] X = A.getArray();
830 481 mdecorde
    for (int i = 0; i < m; i++) {
831 481 mdecorde
      for (int j = 0; j < n; j++) {
832 481 mdecorde
        X[i][j] = (i == j ? 1.0 : 0.0);
833 481 mdecorde
      }
834 481 mdecorde
    }
835 481 mdecorde
    return A;
836 481 mdecorde
  }
837 481 mdecorde
838 481 mdecorde
  /** Print the matrix to stdout.   Line the elements up in columns
839 481 mdecorde
   * with a Fortran-like 'Fw.d' style format.
840 481 mdecorde
  @param w    Column width.
841 481 mdecorde
  @param d    Number of digits after the decimal.
842 481 mdecorde
   */
843 481 mdecorde
  public void print(int w, int d) {
844 481 mdecorde
    print(new PrintWriter(System.out, true), w, d);
845 481 mdecorde
  }
846 481 mdecorde
847 481 mdecorde
  /** Print the matrix to the output stream.   Line the elements up in
848 481 mdecorde
   * columns with a Fortran-like 'Fw.d' style format.
849 481 mdecorde
  @param output Output stream.
850 481 mdecorde
  @param w      Column width.
851 481 mdecorde
  @param d      Number of digits after the decimal.
852 481 mdecorde
   */
853 481 mdecorde
  public void print(PrintWriter output, int w, int d) {
854 481 mdecorde
    DecimalFormat format = new DecimalFormat();
855 481 mdecorde
    format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
856 481 mdecorde
    format.setMinimumIntegerDigits(1);
857 481 mdecorde
    format.setMaximumFractionDigits(d);
858 481 mdecorde
    format.setMinimumFractionDigits(d);
859 481 mdecorde
    format.setGroupingUsed(false);
860 481 mdecorde
    print(output, format, w + 2);
861 481 mdecorde
  }
862 481 mdecorde
863 481 mdecorde
  /** Print the matrix to stdout.  Line the elements up in columns.
864 481 mdecorde
   * Use the format object, and right justify within columns of width
865 481 mdecorde
   * characters.
866 481 mdecorde
   * Note that is the matrix is to be read back in, you probably will want
867 481 mdecorde
   * to use a NumberFormat that is set to US Locale.
868 481 mdecorde
  @param format A  Formatting object for individual elements.
869 481 mdecorde
  @param width     Field width for each column.
870 481 mdecorde
  @see java.text.DecimalFormat#setDecimalFormatSymbols
871 481 mdecorde
   */
872 481 mdecorde
  public void print(NumberFormat format, int width) {
873 481 mdecorde
    print(new PrintWriter(System.out, true), format, width);
874 481 mdecorde
  }
875 481 mdecorde
876 481 mdecorde
  // DecimalFormat is a little disappointing coming from Fortran or C's printf.
877 481 mdecorde
  // Since it doesn't pad on the left, the elements will come out different
878 481 mdecorde
  // widths.  Consequently, we'll pass the desired column width in as an
879 481 mdecorde
  // argument and do the extra padding ourselves.
880 481 mdecorde
  /** Print the matrix to the output stream.  Line the elements up in columns.
881 481 mdecorde
   * Use the format object, and right justify within columns of width
882 481 mdecorde
   * characters.
883 481 mdecorde
   * Note that is the matrix is to be read back in, you probably will want
884 481 mdecorde
   * to use a NumberFormat that is set to US Locale.
885 481 mdecorde
  @param output the output stream.
886 481 mdecorde
  @param format A formatting object to format the matrix elements
887 481 mdecorde
  @param width  Column width.
888 481 mdecorde
  @see java.text.DecimalFormat#setDecimalFormatSymbols
889 481 mdecorde
   */
890 481 mdecorde
  public void print(PrintWriter output, NumberFormat format, int width) {
891 481 mdecorde
    output.println();  // start on new line.
892 481 mdecorde
    for (int i = 0; i < m; i++) {
893 481 mdecorde
      for (int j = 0; j < n; j++) {
894 481 mdecorde
        String s = format.format(A[i][j]); // format the number
895 481 mdecorde
        int padding = Math.max(1, width - s.length()); // At _least_ 1 space
896 481 mdecorde
        for (int k = 0; k < padding; k++) {
897 481 mdecorde
          output.print(' ');
898 481 mdecorde
        }
899 481 mdecorde
        output.print(s);
900 481 mdecorde
      }
901 481 mdecorde
      output.println();
902 481 mdecorde
    }
903 481 mdecorde
    output.println();   // end with blank line.
904 481 mdecorde
  }
905 481 mdecorde
906 481 mdecorde
  /** Read a matrix from a stream.  The format is the same the print method,
907 481 mdecorde
   * so printed matrices can be read back in (provided they were printed using
908 481 mdecorde
   * US Locale).  Elements are separated by
909 481 mdecorde
   * whitespace, all the elements for each row appear on a single line,
910 481 mdecorde
   * the last row is followed by a blank line.
911 481 mdecorde
  @param input the input stream.
912 481 mdecorde
   */
913 481 mdecorde
  @SuppressWarnings("unchecked")
914 481 mdecorde
  public static Matrix read(BufferedReader input) throws java.io.IOException {
915 481 mdecorde
    StreamTokenizer tokenizer = new StreamTokenizer(input);
916 481 mdecorde
917 481 mdecorde
    // Although StreamTokenizer will parse numbers, it doesn't recognize
918 481 mdecorde
    // scientific notation (E or D); however, Double.valueOf does.
919 481 mdecorde
    // The strategy here is to disable StreamTokenizer's number parsing.
920 481 mdecorde
    // We'll only get whitespace delimited words, EOL's and EOF's.
921 481 mdecorde
    // These words should all be numbers, for Double.valueOf to parse.
922 481 mdecorde
923 481 mdecorde
    tokenizer.resetSyntax();
924 481 mdecorde
    tokenizer.wordChars(0, 255);
925 481 mdecorde
    tokenizer.whitespaceChars(0, ' ');
926 481 mdecorde
    tokenizer.eolIsSignificant(true);
927 481 mdecorde
    java.util.Vector v = new java.util.Vector();
928 481 mdecorde
929 481 mdecorde
    // Ignore initial empty lines
930 481 mdecorde
    while (tokenizer.nextToken() == StreamTokenizer.TT_EOL);
931 481 mdecorde
    if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
932 481 mdecorde
      throw new java.io.IOException("Unexpected EOF on matrix read.");
933 481 mdecorde
    }
934 481 mdecorde
    do {
935 481 mdecorde
      v.addElement(Double.valueOf(tokenizer.sval)); // Read & store 1st row.
936 481 mdecorde
    } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
937 481 mdecorde
938 481 mdecorde
    int n = v.size();  // Now we've got the number of columns!
939 481 mdecorde
    double row[] = new double[n];
940 481 mdecorde
    for (int j = 0; j < n; j++) // extract the elements of the 1st row.
941 481 mdecorde
    {
942 481 mdecorde
      row[j] = ((Double) v.elementAt(j)).doubleValue();
943 481 mdecorde
    }
944 481 mdecorde
    v.removeAllElements();
945 481 mdecorde
    v.addElement(row);  // Start storing rows instead of columns.
946 481 mdecorde
    while (tokenizer.nextToken() == StreamTokenizer.TT_WORD) {
947 481 mdecorde
      // While non-empty lines
948 481 mdecorde
      v.addElement(row = new double[n]);
949 481 mdecorde
      int j = 0;
950 481 mdecorde
      do {
951 481 mdecorde
        if (j >= n) {
952 481 mdecorde
          throw new java.io.IOException("Row " + v.size() + " is too long.");
953 481 mdecorde
        }
954 481 mdecorde
        row[j++] = Double.valueOf(tokenizer.sval).doubleValue();
955 481 mdecorde
      } while (tokenizer.nextToken() == StreamTokenizer.TT_WORD);
956 481 mdecorde
      if (j < n) {
957 481 mdecorde
        throw new java.io.IOException("Row " + v.size() + " is too short.");
958 481 mdecorde
      }
959 481 mdecorde
    }
960 481 mdecorde
    int m = v.size();  // Now we've got the number of rows.
961 481 mdecorde
    double[][] A = new double[m][];
962 481 mdecorde
    v.copyInto(A);  // copy the rows out of the vector
963 481 mdecorde
    return new Matrix(A);
964 481 mdecorde
  }
965 481 mdecorde
966 481 mdecorde
967 481 mdecorde
  /* ------------------------
968 481 mdecorde
  Private Methods
969 481 mdecorde
   * ------------------------ */
970 481 mdecorde
  /** Check if size(A) == size(B) **/
971 481 mdecorde
  private void checkMatrixDimensions(Matrix B) {
972 481 mdecorde
    if (B.m != m || B.n != n) {
973 481 mdecorde
      throw new IllegalArgumentException("Matrix dimensions must agree.");
974 481 mdecorde
    }
975 481 mdecorde
  }
976 481 mdecorde
977 481 mdecorde
  /* ---------------------------------
978 481 mdecorde
  Quelques méthodes supplémentaires
979 481 mdecorde
   * ---------------------------------*/
980 481 mdecorde
  private void checkLineDimension(Matrix B) {
981 481 mdecorde
    if (B.m != m) {
982 481 mdecorde
      throw new IllegalArgumentException("Matrix line dimension must agree.");
983 481 mdecorde
    }
984 481 mdecorde
  }
985 481 mdecorde
986 481 mdecorde
  private void checkColumnDimension(Matrix B) {
987 481 mdecorde
    if (B.n != n) {
988 481 mdecorde
      throw new IllegalArgumentException("Matrix column dimension must agree.");
989 481 mdecorde
    }
990 481 mdecorde
  }
991 481 mdecorde
992 481 mdecorde
  public long getNumberNonZeroValues() {
993 481 mdecorde
    long nnz = 0;
994 481 mdecorde
    for (int i = 0; i < m; i++) {
995 481 mdecorde
      for (int j = 0; j < n; j++) {
996 481 mdecorde
        if (A[i][j] != 0) nnz++;
997 481 mdecorde
      }
998 481 mdecorde
    }
999 481 mdecorde
    return nnz;
1000 481 mdecorde
  }
1001 481 mdecorde
1002 481 mdecorde
  public double minColumn(int j) {
1003 481 mdecorde
    double min = Double.POSITIVE_INFINITY;
1004 481 mdecorde
    for (int i = 0; i < m; i++) {
1005 481 mdecorde
      min = Math.min(min, A[i][j]);
1006 481 mdecorde
    }
1007 481 mdecorde
    return min;
1008 481 mdecorde
  }
1009 481 mdecorde
1010 481 mdecorde
  public double maxColumn(int j) {
1011 481 mdecorde
    double max = Double.NEGATIVE_INFINITY;
1012 481 mdecorde
    for (int i = 0; i < m; i++) {
1013 481 mdecorde
      max = Math.max(max, A[i][j]);
1014 481 mdecorde
    }
1015 481 mdecorde
    return max;
1016 481 mdecorde
  }
1017 481 mdecorde
1018 481 mdecorde
  public double elementSum() {
1019 481 mdecorde
    double s = 0;
1020 481 mdecorde
    for (int i = 0; i < m; i++) {
1021 481 mdecorde
      for (int j = 0; j < n; j++) {
1022 481 mdecorde
        s += A[i][j];
1023 481 mdecorde
      }
1024 481 mdecorde
    }
1025 481 mdecorde
    return s;
1026 481 mdecorde
  }
1027 481 mdecorde
1028 481 mdecorde
  public Matrix lineSum() {
1029 481 mdecorde
    Matrix S = new Matrix(m, 1);
1030 481 mdecorde
    double s[][] = S.getArray();
1031 481 mdecorde
    for (int i = 0; i < m; i++) {
1032 481 mdecorde
      for (int j = 0; j < n; j++) {
1033 481 mdecorde
        s[i][0] += A[i][j];
1034 481 mdecorde
      }
1035 481 mdecorde
    }
1036 481 mdecorde
    return S;
1037 481 mdecorde
  }
1038 481 mdecorde
1039 481 mdecorde
  public Matrix lineMean() {
1040 481 mdecorde
    Matrix S = new Matrix(m, 1);
1041 481 mdecorde
    double s[][] = S.getArray();
1042 481 mdecorde
    for (int i = 0; i < m; i++) {
1043 481 mdecorde
      for (int j = 0; j < n; j++) {
1044 481 mdecorde
        s[i][0] += A[i][j];
1045 481 mdecorde
      }
1046 481 mdecorde
      s[i][0] /= n;
1047 481 mdecorde
    }
1048 481 mdecorde
    return S;
1049 481 mdecorde
  }
1050 481 mdecorde
1051 481 mdecorde
  public Matrix columnSum() {
1052 481 mdecorde
    Matrix S = new Matrix(1, n);
1053 481 mdecorde
    double s[][] = S.getArray();
1054 481 mdecorde
    for (int j = 0; j < n; j++) {
1055 481 mdecorde
      for (int i = 0; i < m; i++) {
1056 481 mdecorde
        s[0][j] += A[i][j];
1057 481 mdecorde
      }
1058 481 mdecorde
    }
1059 481 mdecorde
    return S;
1060 481 mdecorde
  }
1061 481 mdecorde
1062 481 mdecorde
  public Matrix columnMean() {
1063 481 mdecorde
    Matrix S = new Matrix(1, n);
1064 481 mdecorde
    double s[][] = S.getArray();
1065 481 mdecorde
    for (int j = 0; j < n; j++) {
1066 481 mdecorde
      for (int i = 0; i < m; i++) {
1067 481 mdecorde
        s[0][j] += A[i][j];
1068 481 mdecorde
      }
1069 481 mdecorde
      s[0][j] /= m;
1070 481 mdecorde
    }
1071 481 mdecorde
    return S;
1072 481 mdecorde
  }
1073 481 mdecorde
1074 481 mdecorde
  public Matrix columnCovariance() {
1075 481 mdecorde
    double mean[] = new double[n];
1076 481 mdecorde
    for (int j = 0; j < n; j++) {
1077 481 mdecorde
      for (int i = 0; i < m; i++) {
1078 481 mdecorde
        mean[j] += A[i][j];
1079 481 mdecorde
      }
1080 481 mdecorde
      mean[j] /= m;
1081 481 mdecorde
    }
1082 481 mdecorde
    Matrix X = new Matrix(n, n);
1083 481 mdecorde
    double[][] B = X.getArray();
1084 481 mdecorde
    double[] Acolj = new double[m];
1085 481 mdecorde
    int coef = m > 2 ? m-1 : 1;
1086 481 mdecorde
    for (int j = 0; j < n; j++) {
1087 481 mdecorde
      for (int k = 0; k < m; k++) {
1088 481 mdecorde
        Acolj[k] = A[k][j] - mean[j];
1089 481 mdecorde
      }
1090 481 mdecorde
      for (int i = 0; i < n; i++) {
1091 481 mdecorde
        double[] Atrowi = new double[m];
1092 481 mdecorde
        for (int k = 0; k < m; k++) {
1093 481 mdecorde
          Atrowi[k] = A[k][i] - mean[i];
1094 481 mdecorde
        }
1095 481 mdecorde
        double s = 0;
1096 481 mdecorde
        for (int k = 0; k < m; k++) {
1097 481 mdecorde
          s += Atrowi[k] * Acolj[k];
1098 481 mdecorde
        }
1099 481 mdecorde
        B[i][j] = s / coef;
1100 481 mdecorde
      }
1101 481 mdecorde
    }
1102 481 mdecorde
    return X;
1103 481 mdecorde
  }
1104 481 mdecorde
1105 481 mdecorde
public Matrix firstLineMinus(Matrix B) {
1106 481 mdecorde
     checkColumnDimension(B);
1107 481 mdecorde
    Matrix X = new Matrix(m, n);
1108 481 mdecorde
    double[][] C = X.getArray();
1109 481 mdecorde
    for (int i = 0; i < m; i++) {
1110 481 mdecorde
      for (int j = 0; j < n; j++) {
1111 481 mdecorde
        C[i][j] = A[i][j] - B.A[0][j];
1112 481 mdecorde
      }
1113 481 mdecorde
    }
1114 481 mdecorde
    return X;
1115 481 mdecorde
1116 481 mdecorde
}
1117 481 mdecorde
  public Matrix nulColumnSuppression() {
1118 481 mdecorde
    ArrayList<Integer> cols = new ArrayList<Integer>();
1119 481 mdecorde
    for (int j = 0; j < n; j++) {
1120 481 mdecorde
      for (int i = 0; i < m; i++) {
1121 481 mdecorde
        if (A[i][j] != 0) {
1122 481 mdecorde
          cols.add(j);
1123 481 mdecorde
          break;
1124 481 mdecorde
        }
1125 481 mdecorde
      }
1126 481 mdecorde
    }
1127 481 mdecorde
    int[] c = new int[cols.size()];
1128 481 mdecorde
    for (int i = 0; i < c.length; i++) {
1129 481 mdecorde
      c[i] = cols.get(i);
1130 481 mdecorde
    }
1131 481 mdecorde
    return getMatrix(0, m - 1, c);
1132 481 mdecorde
  }
1133 481 mdecorde
1134 481 mdecorde
  public Matrix arrayInverse() {
1135 481 mdecorde
    Matrix X = new Matrix(m, n);
1136 481 mdecorde
    double[][] C = X.getArray();
1137 481 mdecorde
    for (int i = 0; i < m; i++) {
1138 481 mdecorde
      for (int j = 0; j < n; j++) {
1139 481 mdecorde
        C[i][j] = 1 / A[i][j];
1140 481 mdecorde
      }
1141 481 mdecorde
    }
1142 481 mdecorde
    return X;
1143 481 mdecorde
  }
1144 481 mdecorde
1145 481 mdecorde
  public Matrix arraySqrt() {
1146 481 mdecorde
    Matrix X = new Matrix(m, n);
1147 481 mdecorde
    double[][] C = X.getArray();
1148 481 mdecorde
    for (int i = 0; i < m; i++) {
1149 481 mdecorde
      for (int j = 0; j < n; j++) {
1150 481 mdecorde
        C[i][j] = Math.sqrt(A[i][j]);
1151 481 mdecorde
      }
1152 481 mdecorde
    }
1153 481 mdecorde
    return X;
1154 481 mdecorde
  }
1155 481 mdecorde
1156 481 mdecorde
  public Matrix firstColumTimes(Matrix B) {
1157 481 mdecorde
    checkLineDimension(B);
1158 481 mdecorde
    Matrix X = new Matrix(m, n);
1159 481 mdecorde
    double[][] C = X.getArray();
1160 481 mdecorde
    for (int i = 0; i < m; i++) {
1161 481 mdecorde
      for (int j = 0; j < n; j++) {
1162 481 mdecorde
1163 481 mdecorde
        C[i][j] = A[i][j] * B.A[i][0];
1164 481 mdecorde
      }
1165 481 mdecorde
    }
1166 481 mdecorde
    return X;
1167 481 mdecorde
  }
1168 481 mdecorde
1169 481 mdecorde
  public Matrix firstColumnTimesEqual(Matrix B) {
1170 481 mdecorde
    checkLineDimension(B);
1171 481 mdecorde
    for (int i = 0; i < m; i++) {
1172 481 mdecorde
       for (int j = 0; j < n; j++) {
1173 481 mdecorde
1174 481 mdecorde
        A[i][j] *= B.A[i][0];
1175 481 mdecorde
      }
1176 481 mdecorde
    }
1177 481 mdecorde
    return this;
1178 481 mdecorde
  }
1179 481 mdecorde
1180 481 mdecorde
  public Matrix firstLineTimesEqual(Matrix B) {
1181 481 mdecorde
    checkColumnDimension(B);
1182 481 mdecorde
    for (int i = 0; i < m; i++) {
1183 481 mdecorde
      for (int j = 0; j < n; j++) {
1184 481 mdecorde
        A[i][j] *= B.A[0][j];
1185 481 mdecorde
      }
1186 481 mdecorde
    }
1187 481 mdecorde
    return this;
1188 481 mdecorde
  }
1189 481 mdecorde
1190 481 mdecorde
  public Matrix firstLineTimes(Matrix B) {
1191 481 mdecorde
    checkColumnDimension(B);
1192 481 mdecorde
    Matrix X = new Matrix(m, n);
1193 481 mdecorde
    double[][] C = X.getArray();
1194 481 mdecorde
    for (int i = 0; i < m; i++) {
1195 481 mdecorde
      for (int j = 0; j < n; j++) {
1196 481 mdecorde
        C[i][j] = A[i][j] * B.A[0][j];
1197 481 mdecorde
      }
1198 481 mdecorde
    }
1199 481 mdecorde
    return X;
1200 481 mdecorde
  }
1201 481 mdecorde
1202 481 mdecorde
  public void fixColumnSigns() {
1203 481 mdecorde
    for (int j = 0; j < n; j++) {
1204 481 mdecorde
      int i = 0;
1205 481 mdecorde
      while (i<m && A[i][j] == 0) i++;
1206 481 mdecorde
      if (i==m || A[i][j] > 0)  continue;
1207 481 mdecorde
      while (i < m) {
1208 481 mdecorde
        A[i][j] = -A[i][j];
1209 481 mdecorde
        i++;
1210 481 mdecorde
      }
1211 481 mdecorde
    }
1212 481 mdecorde
  }
1213 481 mdecorde
1214 481 mdecorde
  /** Analyse factorielle de correspondances
1215 481 mdecorde
  @return     Analyse factorielle de correspondances
1216 481 mdecorde
  @see Analyse factorielle de correspondances
1217 481 mdecorde
   */
1218 481 mdecorde
  public AFC afc() {
1219 481 mdecorde
    return new AFC(this);
1220 481 mdecorde
  }
1221 481 mdecorde
}