GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
sv2u1v.c
Go to the documentation of this file.
00001 /*  sv2u1v.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 sv2u1v(double *d, double *a, int m, double *v, int n)
00011 {
00012     double *p, *p1, *q, *pp, *w, *e;
00013 
00014     double s, t, h, r, sv;
00015 
00016     int i, j, k, mm, nm, ms;
00017 
00018     if (m < n)
00019         return -1;
00020     w = (double *)calloc(m + n, sizeof(double));
00021     e = w + m;
00022     for (i = 0, mm = m, p = a; i < n; ++i, --mm, p += n + 1) {
00023         if (mm > 1) {
00024             sv = h = 0.;
00025             for (j = 0, q = p, s = 0.; j < mm; ++j, q += n) {
00026                 w[j] = *q;
00027                 s += *q * *q;
00028             }
00029             if (s > 0.) {
00030                 h = sqrt(s);
00031                 if (*p < 0.)
00032                     h = -h;
00033                 s += *p * h;
00034                 s = 1. / s;
00035                 t = 1. / (w[0] += h);
00036                 sv = 1. + fabs(*p / h);
00037                 for (k = 1, ms = n - i; k < ms; ++k) {
00038                     for (j = 0, q = p + k, r = 0.; j < mm; q += n)
00039                         r += w[j++] * *q;
00040                     r = r * s;
00041                     for (j = 0, q = p + k; j < mm; q += n)
00042                         *q -= r * w[j++];
00043                 }
00044                 for (j = 1, q = p; j < mm;)
00045                     *(q += n) = w[j++] * t;
00046             }
00047             *p = sv;
00048             d[i] = -h;
00049         }
00050         if (mm == 1)
00051             d[i] = *p;
00052     }
00053     for (i = 0, q = v, p = a; i < n; ++i) {
00054         for (j = 0; j < n; ++j, ++q, ++p) {
00055             if (j < i)
00056                 *q = 0.;
00057             else if (j == i)
00058                 *q = d[i];
00059             else
00060                 *q = *p;
00061         }
00062     }
00063     atou1(a, m, n);
00064     for (i = 0, mm = n, nm = n - 1, p = v; i < n; ++i, --mm, --nm, p += n + 1) {
00065         if (i && mm > 1) {
00066             sv = h = 0.;
00067             for (j = 0, q = p, s = 0.; j < mm; ++j, q += n) {
00068                 w[j] = *q;
00069                 s += *q * *q;
00070             }
00071             if (s > 0.) {
00072                 h = sqrt(s);
00073                 if (*p < 0.)
00074                     h = -h;
00075                 s += *p * h;
00076                 s = 1. / s;
00077                 t = 1. / (w[0] += h);
00078                 sv = 1. + fabs(*p / h);
00079                 for (k = 1, ms = n - i; k < ms; ++k) {
00080                     for (j = 0, q = p + k, r = 0.; j < mm; q += n)
00081                         r += w[j++] * *q;
00082                     for (j = 0, q = p + k, r *= s; j < mm; q += n)
00083                         *q -= r * w[j++];
00084                 }
00085                 for (k = 0, p1 = a + i; k < m; ++k, p1 += n) {
00086                     for (j = 0, q = p1, r = 0.; j < mm;)
00087                         r += w[j++] * *q++;
00088                     for (j = 0, q = p1, r *= s; j < mm;)
00089                         *q++ -= r * w[j++];
00090                 }
00091             }
00092             *p = sv;
00093             d[i] = -h;
00094         }
00095         if (mm == 1)
00096             d[i] = *p;
00097         p1 = p + 1;
00098         if (nm > 1) {
00099             sv = h = 0.;
00100             for (j = 0, q = p1, s = 0.; j < nm; ++j, ++q)
00101                 s += *q * *q;
00102             if (s > 0.) {
00103                 h = sqrt(s);
00104                 if (*p1 < 0.)
00105                     h = -h;
00106                 sv = 1. + fabs(*p1 / h);
00107                 s += *p1 * h;
00108                 s = 1. / s;
00109                 t = 1. / (*p1 += h);
00110                 for (k = n, ms = n * (n - i); k < ms; k += n) {
00111                     for (j = 0, q = p1, pp = p1 + k, r = 0.; j < nm; ++j)
00112                         r += *q++ * *pp++;
00113                     for (j = 0, q = p1, pp = p1 + k, r *= s; j < nm; ++j)
00114                         *pp++ -= r * *q++;
00115                 }
00116                 for (j = 1, q = p1 + 1; j < nm; ++j)
00117                     *q++ *= t;
00118             }
00119             *p1 = sv;
00120             e[i] = -h;
00121         }
00122         if (nm == 1)
00123             e[i] = *p1;
00124     }
00125     atovm(v, n);
00126     qrbdu1(d, e, a, m, v, n);
00127     for (i = 0; i < n; ++i) {
00128         if (d[i] < 0.) {
00129             d[i] = -d[i];
00130             for (j = 0, p = v + i; j < n; ++j, p += n)
00131                 *p = -*p;
00132         }
00133     }
00134     free(w);
00135     return 0;
00136 }