Statistiques
| Révision :

root / tmp / org.txm.analec.rcp / src / JamaPlus / SingularValueDecomposition.java0 @ 3095

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