GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
svdval.c
Go to the documentation of this file.
00001 /*  svdval.c    CCMATH mathematics library source code.
00002  *
00003  *  Copyright (C)  2000   Daniel A. Atkinson    All rights reserved.
00004  *  This code may be redistributed under the terms of the GNU library
00005  *  public license (LGPL). ( See the lgpl.license file for details.)
00006  * ------------------------------------------------------------------------
00007  */
00008 #include <stdlib.h>
00009 #include "ccmath.h"
00010 int svdval(double *d, double *a, int m, int n)
00011 {
00012     double *p, *p1, *q, *w, *v;
00013 
00014     double s, h, u;
00015 
00016     int i, j, k, mm, nm, ms;
00017 
00018     if (m < n)
00019         return -1;
00020     w = (double *)calloc(m, sizeof(double));
00021     for (i = 0, mm = m, nm = n - 1, p = a; i < n; ++i, --mm, --nm, p += n + 1) {
00022         if (mm > 1) {
00023             for (j = 0, q = p, s = 0.; j < mm; ++j, q += n) {
00024                 w[j] = *q;
00025                 s += *q * *q;
00026             }
00027             if (s > 0.) {
00028                 h = sqrt(s);
00029                 if (*p < 0.)
00030                     h = -h;
00031                 s += *p * h;
00032                 s = 1. / s;
00033                 w[0] += h;
00034                 for (k = 1, ms = n - i; k < ms; ++k) {
00035                     for (j = 0, q = p + k, u = 0.; j < mm; q += n)
00036                         u += w[j++] * *q;
00037                     u *= s;
00038                     for (j = 0, q = p + k; j < mm; q += n)
00039                         *q -= u * w[j++];
00040                 }
00041                 *p = -h;
00042             }
00043         }
00044         p1 = p + 1;
00045         if (nm > 1) {
00046             for (j = 0, q = p1, s = 0.; j < nm; ++j, ++q)
00047                 s += *q * *q;
00048             if (s > 0.) {
00049                 h = sqrt(s);
00050                 if (*p1 < 0.)
00051                     h = -h;
00052                 s += *p1 * h;
00053                 s = 1. / s;
00054                 *p1 += h;
00055                 for (k = n, ms = n * (m - i); k < ms; k += n) {
00056                     for (j = 0, q = p1, v = p1 + k, u = 0.; j < nm; ++j)
00057                         u += *q++ * *v++;
00058                     u *= s;
00059                     for (j = 0, q = p1, v = p1 + k; j < nm; ++j)
00060                         *v++ -= u * *q++;
00061                 }
00062                 *p1 = -h;
00063             }
00064         }
00065     }
00066 
00067     for (j = 0, p = a; j < n; ++j, p += n + 1) {
00068         d[j] = *p;
00069         if (j != n - 1)
00070             w[j] = *(p + 1);
00071         else
00072             w[j] = 0.;
00073     }
00074     qrbdi(d, w, n);
00075     for (i = 0; i < n; ++i)
00076         if (d[i] < 0.)
00077             d[i] = -d[i];
00078     free(w);
00079     return 0;
00080 }