Statistiques
| Révision :

root / tmp / org.txm.analec.rcp / src matt / JamaPlus / SingularValueDecomposition.java @ 3244

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

1 481 mdecorde
package JamaPlus;
2 481 mdecorde
import JamaPlus.util.*;
3 481 mdecorde
4 481 mdecorde
   /** Singular Value Decomposition.
5 481 mdecorde
   <P>
6 481 mdecorde
   For an m-by-n matrix A with m >= n, the singular value decomposition is
7 481 mdecorde
   an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
8 481 mdecorde
   an n-by-n orthogonal matrix V so that A = U*S*V'.
9 481 mdecorde
   <P>
10 481 mdecorde
   The singular values, sigma[k] = S[k][k], are ordered so that
11 481 mdecorde
   sigma[0] >= sigma[1] >= ... >= sigma[n-1].
12 481 mdecorde
   <P>
13 481 mdecorde
   The singular value decompostion always exists, so the constructor will
14 481 mdecorde
   never fail.  The matrix condition number and the effective numerical
15 481 mdecorde
   rank can be computed from this decomposition.
16 481 mdecorde
   */
17 481 mdecorde
18 481 mdecorde
public class SingularValueDecomposition implements java.io.Serializable {
19 481 mdecorde
20 481 mdecorde
/* ------------------------
21 481 mdecorde
   Class variables
22 481 mdecorde
 * ------------------------ */
23 481 mdecorde
24 481 mdecorde
   /** Arrays for internal storage of U and V.
25 481 mdecorde
   @serial internal storage of U.
26 481 mdecorde
   @serial internal storage of V.
27 481 mdecorde
   */
28 481 mdecorde
   private double[][] U, V;
29 481 mdecorde
30 481 mdecorde
   /** Array for internal storage of singular values.
31 481 mdecorde
   @serial internal storage of singular values.
32 481 mdecorde
   */
33 481 mdecorde
   private double[] s;
34 481 mdecorde
35 481 mdecorde
   /** Row and column dimensions.
36 481 mdecorde
   @serial row dimension.
37 481 mdecorde
   @serial column dimension.
38 481 mdecorde
   */
39 481 mdecorde
   private int m, n;
40 481 mdecorde
41 481 mdecorde
   private boolean transpose; // pour éviter les bugs quand m<n (cf.ci-dessous)
42 481 mdecorde
43 481 mdecorde
/* ------------------------
44 481 mdecorde
   Constructor
45 481 mdecorde
 * ------------------------ */
46 481 mdecorde
47 481 mdecorde
   /** Construct the singular value decomposition
48 481 mdecorde
   @param A    Rectangular matrix
49 481 mdecorde
   @return     Structure to access U, S and V.
50 481 mdecorde
   */
51 481 mdecorde
52 481 mdecorde
   public SingularValueDecomposition (Matrix Arg) {
53 481 mdecorde
54 481 mdecorde
      // Derived from LINPACK code.
55 481 mdecorde
      // Initialize.
56 481 mdecorde
      /* Apparently the failing cases are only a proper subset of (m<n),
57 481 mdecorde
         so let's not throw error.  Correct fix to come later?
58 481 mdecorde
      if (m<n) {
59 481 mdecorde
          throw new IllegalArgumentException("Jama SVD only works for m >= n"); }
60 481 mdecorde
      */
61 481 mdecorde
      /*
62 481 mdecorde
       * Une façon très simple de contourner le problème ci-dessus :
63 481 mdecorde
       * si m < n on transpose A
64 481 mdecorde
       * (ce qui revient à échanger U et V, S restant inchangé)
65 481 mdecorde
       */
66 481 mdecorde
   transpose = Arg.getColumnDimension()>Arg.getRowDimension();
67 481 mdecorde
    Matrix M = transpose ? Arg.transpose() : Arg.copy();
68 481 mdecorde
69 481 mdecorde
     double[][] A = M.getArray();
70 481 mdecorde
      m = M.getRowDimension();
71 481 mdecorde
      n = M.getColumnDimension();
72 481 mdecorde
73 481 mdecorde
      s = new double [n];
74 481 mdecorde
      U = new double [m][n];
75 481 mdecorde
      V = new double [n][n];
76 481 mdecorde
      double[] e = new double [n];
77 481 mdecorde
      double[] work = new double [m];
78 481 mdecorde
      boolean wantu = true;
79 481 mdecorde
      boolean wantv = true;
80 481 mdecorde
81 481 mdecorde
      // Reduce A to bidiagonal form, storing the diagonal elements
82 481 mdecorde
      // in s and the super-diagonal elements in e.
83 481 mdecorde
84 481 mdecorde
      int nct = Math.min(m-1,n);
85 481 mdecorde
      int nrt = Math.max(0,Math.min(n-2,m));
86 481 mdecorde
      for (int k = 0; k < Math.max(nct,nrt); k++) {
87 481 mdecorde
         if (k < nct) {
88 481 mdecorde
89 481 mdecorde
            // Compute the transformation for the k-th column and
90 481 mdecorde
            // place the k-th diagonal in s[k].
91 481 mdecorde
            // Compute 2-norm of k-th column without under/overflow.
92 481 mdecorde
            s[k] = 0;
93 481 mdecorde
            for (int i = k; i < m; i++) {
94 481 mdecorde
               s[k] = Math.hypot(s[k],A[i][k]);
95 481 mdecorde
            }
96 481 mdecorde
            if (s[k] != 0.0) {
97 481 mdecorde
               if (A[k][k] < 0.0) {
98 481 mdecorde
                  s[k] = -s[k];
99 481 mdecorde
               }
100 481 mdecorde
               for (int i = k; i < m; i++) {
101 481 mdecorde
                  A[i][k] /= s[k];
102 481 mdecorde
               }
103 481 mdecorde
               A[k][k] += 1.0;
104 481 mdecorde
            }
105 481 mdecorde
            s[k] = -s[k];
106 481 mdecorde
         }
107 481 mdecorde
         for (int j = k+1; j < n; j++) {
108 481 mdecorde
            if ((k < nct) & (s[k] != 0.0))  {
109 481 mdecorde
110 481 mdecorde
            // Apply the transformation.
111 481 mdecorde
112 481 mdecorde
               double t = 0;
113 481 mdecorde
               for (int i = k; i < m; i++) {
114 481 mdecorde
                  t += A[i][k]*A[i][j];
115 481 mdecorde
               }
116 481 mdecorde
               t = -t/A[k][k];
117 481 mdecorde
               for (int i = k; i < m; i++) {
118 481 mdecorde
                  A[i][j] += t*A[i][k];
119 481 mdecorde
               }
120 481 mdecorde
            }
121 481 mdecorde
122 481 mdecorde
            // Place the k-th row of A into e for the
123 481 mdecorde
            // subsequent calculation of the row transformation.
124 481 mdecorde
125 481 mdecorde
            e[j] = A[k][j];
126 481 mdecorde
         }
127 481 mdecorde
         if (wantu & (k < nct)) {
128 481 mdecorde
129 481 mdecorde
            // Place the transformation in U for subsequent back
130 481 mdecorde
            // multiplication.
131 481 mdecorde
132 481 mdecorde
            for (int i = k; i < m; i++) {
133 481 mdecorde
               U[i][k] = A[i][k];
134 481 mdecorde
            }
135 481 mdecorde
         }
136 481 mdecorde
         if (k < nrt) {
137 481 mdecorde
138 481 mdecorde
            // Compute the k-th row transformation and place the
139 481 mdecorde
            // k-th super-diagonal in e[k].
140 481 mdecorde
            // Compute 2-norm without under/overflow.
141 481 mdecorde
            e[k] = 0;
142 481 mdecorde
            for (int i = k+1; i < n; i++) {
143 481 mdecorde
               e[k] = Math.hypot(e[k],e[i]);
144 481 mdecorde
            }
145 481 mdecorde
            if (e[k] != 0.0) {
146 481 mdecorde
               if (e[k+1] < 0.0) {
147 481 mdecorde
                  e[k] = -e[k];
148 481 mdecorde
               }
149 481 mdecorde
               for (int i = k+1; i < n; i++) {
150 481 mdecorde
                  e[i] /= e[k];
151 481 mdecorde
               }
152 481 mdecorde
               e[k+1] += 1.0;
153 481 mdecorde
            }
154 481 mdecorde
            e[k] = -e[k];
155 481 mdecorde
            if ((k+1 < m) & (e[k] != 0.0)) {
156 481 mdecorde
157 481 mdecorde
            // Apply the transformation.
158 481 mdecorde
159 481 mdecorde
               for (int i = k+1; i < m; i++) {
160 481 mdecorde
                  work[i] = 0.0;
161 481 mdecorde
               }
162 481 mdecorde
               for (int j = k+1; j < n; j++) {
163 481 mdecorde
                  for (int i = k+1; i < m; i++) {
164 481 mdecorde
                     work[i] += e[j]*A[i][j];
165 481 mdecorde
                  }
166 481 mdecorde
               }
167 481 mdecorde
               for (int j = k+1; j < n; j++) {
168 481 mdecorde
                  double t = -e[j]/e[k+1];
169 481 mdecorde
                  for (int i = k+1; i < m; i++) {
170 481 mdecorde
                     A[i][j] += t*work[i];
171 481 mdecorde
                  }
172 481 mdecorde
               }
173 481 mdecorde
            }
174 481 mdecorde
            if (wantv) {
175 481 mdecorde
176 481 mdecorde
            // Place the transformation in V for subsequent
177 481 mdecorde
            // back multiplication.
178 481 mdecorde
179 481 mdecorde
               for (int i = k+1; i < n; i++) {
180 481 mdecorde
                  V[i][k] = e[i];
181 481 mdecorde
               }
182 481 mdecorde
            }
183 481 mdecorde
         }
184 481 mdecorde
      }
185 481 mdecorde
186 481 mdecorde
      // Set up the final bidiagonal matrix or order p.
187 481 mdecorde
188 481 mdecorde
      int p = Math.min(n,m+1);
189 481 mdecorde
      if (nct < n) {
190 481 mdecorde
         s[nct] = A[nct][nct];
191 481 mdecorde
      }
192 481 mdecorde
      if (m < p) {
193 481 mdecorde
         s[p-1] = 0.0;
194 481 mdecorde
      }
195 481 mdecorde
      if (nrt+1 < p) {
196 481 mdecorde
         e[nrt] = A[nrt][p-1];
197 481 mdecorde
      }
198 481 mdecorde
      e[p-1] = 0.0;
199 481 mdecorde
200 481 mdecorde
      // If required, generate U.
201 481 mdecorde
202 481 mdecorde
      if (wantu) {
203 481 mdecorde
         for (int j = nct; j < n; j++) {
204 481 mdecorde
            for (int i = 0; i < m; i++) {
205 481 mdecorde
               U[i][j] = 0.0;
206 481 mdecorde
            }
207 481 mdecorde
            U[j][j] = 1.0;
208 481 mdecorde
         }
209 481 mdecorde
         for (int k = nct-1; k >= 0; k--) {
210 481 mdecorde
            if (s[k] != 0.0) {
211 481 mdecorde
               for (int j = k+1; j < n; j++) {
212 481 mdecorde
                  double t = 0;
213 481 mdecorde
                  for (int i = k; i < m; i++) {
214 481 mdecorde
                     t += U[i][k]*U[i][j];
215 481 mdecorde
                  }
216 481 mdecorde
                  t = -t/U[k][k];
217 481 mdecorde
                  for (int i = k; i < m; i++) {
218 481 mdecorde
                     U[i][j] += t*U[i][k];
219 481 mdecorde
                  }
220 481 mdecorde
               }
221 481 mdecorde
               for (int i = k; i < m; i++ ) {
222 481 mdecorde
                  U[i][k] = -U[i][k];
223 481 mdecorde
               }
224 481 mdecorde
               U[k][k] = 1.0 + U[k][k];
225 481 mdecorde
               for (int i = 0; i < k-1; i++) {
226 481 mdecorde
                  U[i][k] = 0.0;
227 481 mdecorde
               }
228 481 mdecorde
            } else {
229 481 mdecorde
               for (int i = 0; i < m; i++) {
230 481 mdecorde
                  U[i][k] = 0.0;
231 481 mdecorde
               }
232 481 mdecorde
               U[k][k] = 1.0;
233 481 mdecorde
            }
234 481 mdecorde
         }
235 481 mdecorde
      }
236 481 mdecorde
237 481 mdecorde
      // If required, generate V.
238 481 mdecorde
239 481 mdecorde
      if (wantv) {
240 481 mdecorde
         for (int k = n-1; k >= 0; k--) {
241 481 mdecorde
            if ((k < nrt) & (e[k] != 0.0)) {
242 481 mdecorde
               for (int j = k+1; j < n; j++) {
243 481 mdecorde
                  double t = 0;
244 481 mdecorde
                  for (int i = k+1; i < n; i++) {
245 481 mdecorde
                     t += V[i][k]*V[i][j];
246 481 mdecorde
                  }
247 481 mdecorde
                  t = -t/V[k+1][k];
248 481 mdecorde
                  for (int i = k+1; i < n; i++) {
249 481 mdecorde
                     V[i][j] += t*V[i][k];
250 481 mdecorde
                  }
251 481 mdecorde
               }
252 481 mdecorde
            }
253 481 mdecorde
            for (int i = 0; i < n; i++) {
254 481 mdecorde
               V[i][k] = 0.0;
255 481 mdecorde
            }
256 481 mdecorde
            V[k][k] = 1.0;
257 481 mdecorde
         }
258 481 mdecorde
      }
259 481 mdecorde
260 481 mdecorde
      // Main iteration loop for the singular values.
261 481 mdecorde
262 481 mdecorde
      int pp = p-1;
263 481 mdecorde
      int iter = 0;
264 481 mdecorde
      double eps = Math.pow(2.0,-52.0);
265 481 mdecorde
      double tiny = Math.pow(2.0,-966.0);
266 481 mdecorde
      while (p > 0) {
267 481 mdecorde
         int k,kase;
268 481 mdecorde
269 481 mdecorde
         // Here is where a test for too many iterations would go.
270 481 mdecorde
271 481 mdecorde
         // This section of the program inspects for
272 481 mdecorde
         // negligible elements in the s and e arrays.  On
273 481 mdecorde
         // completion the variables kase and k are set as follows.
274 481 mdecorde
275 481 mdecorde
         // kase = 1     if s(p) and e[k-1] are negligible and k<p
276 481 mdecorde
         // kase = 2     if s(k) is negligible and k<p
277 481 mdecorde
         // kase = 3     if e[k-1] is negligible, k<p, and
278 481 mdecorde
         //              s(k), ..., s(p) are not negligible (qr step).
279 481 mdecorde
         // kase = 4     if e(p-1) is negligible (convergence).
280 481 mdecorde
281 481 mdecorde
         for (k = p-2; k >= -1; k--) {
282 481 mdecorde
            if (k == -1) {
283 481 mdecorde
               break;
284 481 mdecorde
            }
285 481 mdecorde
            if (Math.abs(e[k]) <=
286 481 mdecorde
                  tiny + eps*(Math.abs(s[k]) + Math.abs(s[k+1]))) {
287 481 mdecorde
               e[k] = 0.0;
288 481 mdecorde
               break;
289 481 mdecorde
            }
290 481 mdecorde
         }
291 481 mdecorde
         if (k == p-2) {
292 481 mdecorde
            kase = 4;
293 481 mdecorde
         } else {
294 481 mdecorde
            int ks;
295 481 mdecorde
            for (ks = p-1; ks >= k; ks--) {
296 481 mdecorde
               if (ks == k) {
297 481 mdecorde
                  break;
298 481 mdecorde
               }
299 481 mdecorde
               double t = (ks != p ? Math.abs(e[ks]) : 0.) +
300 481 mdecorde
                          (ks != k+1 ? Math.abs(e[ks-1]) : 0.);
301 481 mdecorde
               if (Math.abs(s[ks]) <= tiny + eps*t)  {
302 481 mdecorde
                  s[ks] = 0.0;
303 481 mdecorde
                  break;
304 481 mdecorde
               }
305 481 mdecorde
            }
306 481 mdecorde
            if (ks == k) {
307 481 mdecorde
               kase = 3;
308 481 mdecorde
            } else if (ks == p-1) {
309 481 mdecorde
               kase = 1;
310 481 mdecorde
            } else {
311 481 mdecorde
               kase = 2;
312 481 mdecorde
               k = ks;
313 481 mdecorde
            }
314 481 mdecorde
         }
315 481 mdecorde
         k++;
316 481 mdecorde
317 481 mdecorde
         // Perform the task indicated by kase.
318 481 mdecorde
319 481 mdecorde
         switch (kase) {
320 481 mdecorde
321 481 mdecorde
            // Deflate negligible s(p).
322 481 mdecorde
323 481 mdecorde
            case 1: {
324 481 mdecorde
               double f = e[p-2];
325 481 mdecorde
               e[p-2] = 0.0;
326 481 mdecorde
               for (int j = p-2; j >= k; j--) {
327 481 mdecorde
                  double t = Math.hypot(s[j],f);
328 481 mdecorde
                  double cs = s[j]/t;
329 481 mdecorde
                  double sn = f/t;
330 481 mdecorde
                  s[j] = t;
331 481 mdecorde
                  if (j != k) {
332 481 mdecorde
                     f = -sn*e[j-1];
333 481 mdecorde
                     e[j-1] = cs*e[j-1];
334 481 mdecorde
                  }
335 481 mdecorde
                  if (wantv) {
336 481 mdecorde
                     for (int i = 0; i < n; i++) {
337 481 mdecorde
                        t = cs*V[i][j] + sn*V[i][p-1];
338 481 mdecorde
                        V[i][p-1] = -sn*V[i][j] + cs*V[i][p-1];
339 481 mdecorde
                        V[i][j] = t;
340 481 mdecorde
                     }
341 481 mdecorde
                  }
342 481 mdecorde
               }
343 481 mdecorde
            }
344 481 mdecorde
            break;
345 481 mdecorde
346 481 mdecorde
            // Split at negligible s(k).
347 481 mdecorde
348 481 mdecorde
            case 2: {
349 481 mdecorde
               double f = e[k-1];
350 481 mdecorde
               e[k-1] = 0.0;
351 481 mdecorde
               for (int j = k; j < p; j++) {
352 481 mdecorde
                  double t = Math.hypot(s[j],f);
353 481 mdecorde
                  double cs = s[j]/t;
354 481 mdecorde
                  double sn = f/t;
355 481 mdecorde
                  s[j] = t;
356 481 mdecorde
                  f = -sn*e[j];
357 481 mdecorde
                  e[j] = cs*e[j];
358 481 mdecorde
                  if (wantu) {
359 481 mdecorde
                     for (int i = 0; i < m; i++) {
360 481 mdecorde
                        t = cs*U[i][j] + sn*U[i][k-1];
361 481 mdecorde
                        U[i][k-1] = -sn*U[i][j] + cs*U[i][k-1];
362 481 mdecorde
                        U[i][j] = t;
363 481 mdecorde
                     }
364 481 mdecorde
                  }
365 481 mdecorde
               }
366 481 mdecorde
            }
367 481 mdecorde
            break;
368 481 mdecorde
369 481 mdecorde
            // Perform one qr step.
370 481 mdecorde
371 481 mdecorde
            case 3: {
372 481 mdecorde
373 481 mdecorde
               // Calculate the shift.
374 481 mdecorde
375 481 mdecorde
               double scale = Math.max(Math.max(Math.max(Math.max(
376 481 mdecorde
                       Math.abs(s[p-1]),Math.abs(s[p-2])),Math.abs(e[p-2])),
377 481 mdecorde
                       Math.abs(s[k])),Math.abs(e[k]));
378 481 mdecorde
               double sp = s[p-1]/scale;
379 481 mdecorde
               double spm1 = s[p-2]/scale;
380 481 mdecorde
               double epm1 = e[p-2]/scale;
381 481 mdecorde
               double sk = s[k]/scale;
382 481 mdecorde
               double ek = e[k]/scale;
383 481 mdecorde
               double b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
384 481 mdecorde
               double c = (sp*epm1)*(sp*epm1);
385 481 mdecorde
               double shift = 0.0;
386 481 mdecorde
               if ((b != 0.0) | (c != 0.0)) {
387 481 mdecorde
                  shift = Math.sqrt(b*b + c);
388 481 mdecorde
                  if (b < 0.0) {
389 481 mdecorde
                     shift = -shift;
390 481 mdecorde
                  }
391 481 mdecorde
                  shift = c/(b + shift);
392 481 mdecorde
               }
393 481 mdecorde
               double f = (sk + sp)*(sk - sp) + shift;
394 481 mdecorde
               double g = sk*ek;
395 481 mdecorde
396 481 mdecorde
               // Chase zeros.
397 481 mdecorde
398 481 mdecorde
               for (int j = k; j < p-1; j++) {
399 481 mdecorde
                  double t = Math.hypot(f,g);
400 481 mdecorde
                  double cs = f/t;
401 481 mdecorde
                  double sn = g/t;
402 481 mdecorde
                  if (j != k) {
403 481 mdecorde
                     e[j-1] = t;
404 481 mdecorde
                  }
405 481 mdecorde
                  f = cs*s[j] + sn*e[j];
406 481 mdecorde
                  e[j] = cs*e[j] - sn*s[j];
407 481 mdecorde
                  g = sn*s[j+1];
408 481 mdecorde
                  s[j+1] = cs*s[j+1];
409 481 mdecorde
                  if (wantv) {
410 481 mdecorde
                     for (int i = 0; i < n; i++) {
411 481 mdecorde
                        t = cs*V[i][j] + sn*V[i][j+1];
412 481 mdecorde
                        V[i][j+1] = -sn*V[i][j] + cs*V[i][j+1];
413 481 mdecorde
                        V[i][j] = t;
414 481 mdecorde
                     }
415 481 mdecorde
                  }
416 481 mdecorde
                  t = Math.hypot(f,g);
417 481 mdecorde
                  cs = f/t;
418 481 mdecorde
                  sn = g/t;
419 481 mdecorde
                  s[j] = t;
420 481 mdecorde
                  f = cs*e[j] + sn*s[j+1];
421 481 mdecorde
                  s[j+1] = -sn*e[j] + cs*s[j+1];
422 481 mdecorde
                  g = sn*e[j+1];
423 481 mdecorde
                  e[j+1] = cs*e[j+1];
424 481 mdecorde
                  if (wantu && (j < m-1)) {
425 481 mdecorde
                     for (int i = 0; i < m; i++) {
426 481 mdecorde
                        t = cs*U[i][j] + sn*U[i][j+1];
427 481 mdecorde
                        U[i][j+1] = -sn*U[i][j] + cs*U[i][j+1];
428 481 mdecorde
                        U[i][j] = t;
429 481 mdecorde
                     }
430 481 mdecorde
                  }
431 481 mdecorde
               }
432 481 mdecorde
               e[p-2] = f;
433 481 mdecorde
               iter = iter + 1;
434 481 mdecorde
            }
435 481 mdecorde
            break;
436 481 mdecorde
437 481 mdecorde
            // Convergence.
438 481 mdecorde
439 481 mdecorde
            case 4: {
440 481 mdecorde
441 481 mdecorde
               // Make the singular values positive.
442 481 mdecorde
443 481 mdecorde
               if (s[k] <= 0.0) {
444 481 mdecorde
                  s[k] = (s[k] < 0.0 ? -s[k] : 0.0);
445 481 mdecorde
                  if (wantv) {
446 481 mdecorde
                     for (int i = 0; i <= pp; i++) {
447 481 mdecorde
                        V[i][k] = -V[i][k];
448 481 mdecorde
                     }
449 481 mdecorde
                  }
450 481 mdecorde
               }
451 481 mdecorde
452 481 mdecorde
               // Order the singular values.
453 481 mdecorde
454 481 mdecorde
               while (k < pp) {
455 481 mdecorde
                  if (s[k] >= s[k+1]) {
456 481 mdecorde
                     break;
457 481 mdecorde
                  }
458 481 mdecorde
                  double t = s[k];
459 481 mdecorde
                  s[k] = s[k+1];
460 481 mdecorde
                  s[k+1] = t;
461 481 mdecorde
                  if (wantv && (k < n-1)) {
462 481 mdecorde
                     for (int i = 0; i < n; i++) {
463 481 mdecorde
                        t = V[i][k+1]; V[i][k+1] = V[i][k]; V[i][k] = t;
464 481 mdecorde
                     }
465 481 mdecorde
                  }
466 481 mdecorde
                  if (wantu && (k < m-1)) {
467 481 mdecorde
                     for (int i = 0; i < m; i++) {
468 481 mdecorde
                        t = U[i][k+1]; U[i][k+1] = U[i][k]; U[i][k] = t;
469 481 mdecorde
                     }
470 481 mdecorde
                  }
471 481 mdecorde
                  k++;
472 481 mdecorde
               }
473 481 mdecorde
               iter = 0;
474 481 mdecorde
               p--;
475 481 mdecorde
            }
476 481 mdecorde
            break;
477 481 mdecorde
         }
478 481 mdecorde
      }
479 481 mdecorde
   }
480 481 mdecorde
481 481 mdecorde
/* ------------------------
482 481 mdecorde
   Public Methods
483 481 mdecorde
 * ------------------------ */
484 481 mdecorde
485 481 mdecorde
   /** Return the left singular vectors
486 481 mdecorde
   @return     U
487 481 mdecorde
   */
488 481 mdecorde
489 481 mdecorde
   public Matrix getU () {
490 481 mdecorde
      return transpose ? new Matrix(V,n,n) : new Matrix(U,m,n);
491 481 mdecorde
   }
492 481 mdecorde
493 481 mdecorde
   /** Return the right singular vectors
494 481 mdecorde
   @return     V
495 481 mdecorde
   */
496 481 mdecorde
497 481 mdecorde
   public Matrix getV () {
498 481 mdecorde
      return transpose ? new Matrix(U,m,n) : new Matrix(V,n,n);
499 481 mdecorde
   }
500 481 mdecorde
501 481 mdecorde
   /** Return the one-dimensional array of singular values
502 481 mdecorde
   @return     diagonal of S.
503 481 mdecorde
   */
504 481 mdecorde
505 481 mdecorde
   public double[] getSingularValues () {
506 481 mdecorde
      return s;
507 481 mdecorde
   }
508 481 mdecorde
509 481 mdecorde
   /** Return the diagonal matrix of singular values
510 481 mdecorde
   @return     S
511 481 mdecorde
   */
512 481 mdecorde
513 481 mdecorde
   public Matrix getS () {
514 481 mdecorde
      Matrix X = new Matrix(n,n);
515 481 mdecorde
      double[][] S = X.getArray();
516 481 mdecorde
      for (int i = 0; i < n; i++) {
517 481 mdecorde
         for (int j = 0; j < n; j++) {
518 481 mdecorde
            S[i][j] = 0.0;
519 481 mdecorde
         }
520 481 mdecorde
         S[i][i] = this.s[i];
521 481 mdecorde
      }
522 481 mdecorde
      return X;
523 481 mdecorde
   }
524 481 mdecorde
525 481 mdecorde
   /** Two norm
526 481 mdecorde
   @return     max(S)
527 481 mdecorde
   */
528 481 mdecorde
529 481 mdecorde
   public double norm2 () {
530 481 mdecorde
      return s[0];
531 481 mdecorde
   }
532 481 mdecorde
533 481 mdecorde
   /** Two norm condition number
534 481 mdecorde
   @return     max(S)/min(S)
535 481 mdecorde
   */
536 481 mdecorde
537 481 mdecorde
   public double cond () {
538 481 mdecorde
      return s[0]/s[Math.min(m,n)-1];
539 481 mdecorde
   }
540 481 mdecorde
541 481 mdecorde
   /** Effective numerical matrix rank
542 481 mdecorde
   @return     Number of nonnegligible singular values.
543 481 mdecorde
   */
544 481 mdecorde
545 481 mdecorde
   public int rank () {
546 481 mdecorde
      double eps = Math.pow(2.0,-52.0);
547 481 mdecorde
      double tol = Math.max(m,n)*s[0]*eps;
548 481 mdecorde
      int r = 0;
549 481 mdecorde
      for (int i = 0; i < s.length; i++) {
550 481 mdecorde
         if (s[i] > tol) {
551 481 mdecorde
            r++;
552 481 mdecorde
         }
553 481 mdecorde
      }
554 481 mdecorde
      return r;
555 481 mdecorde
   }
556 481 mdecorde
}