15static double at, bt, ct;
16static double maxarg1, maxarg2;
19 ((at = fabs(a)) > (bt = fabs(b)) \
20 ? (ct = bt / at, at * sqrt(1.0 + ct * ct)) \
21 : (bt ? (ct = at / bt, bt * sqrt(1.0 + ct * ct)) : 0.0))
23 (maxarg1 = (a), maxarg2 = (b), (maxarg1) > (maxarg2) ? (maxarg1) : (maxarg2))
24#define SIGNS(a, b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
27void svdcmp(
double **a,
int m,
int n,
double *w,
double **v) {
28 int flag, i, its, j, jj, k, l, nm;
29 double c, f, h, s, x, y, z;
30 double anorm = 0.0, g = 0.0, scale = 0.0;
33 if (m < n)
nrerror(
"SVDCMP: A must be augmented with extra zeros.");
37 for (i = 1; i <= n; i++)
45#pragma omp parallel for private(k) reduction(+ : scale)
47 for (k = i; k <= m; k++) scale += fabs(a[k][i]);
50#pragma omp parallel for private(k) reduction(+ : s)
52 for (k = i; k <= m; k++) {
54 s += a[k][i] * a[k][i];
58 g = -
SIGNS(sqrt(s), f);
63 for (j = l; j <= n; j++) {
66#pragma omp parallel for private(k) reduction(+ : s)
68 for (k = i; k <= m; k++) s += a[k][i] * a[k][j];
71#pragma omp parallel for private(k)
73 for (k = i; k <= m; k++) a[k][j] += f * a[k][i];
77#pragma omp parallel for private(k)
79 for (k = i; k <= m; k++) a[k][i] *= scale;
84 if (i <= m && i != n) {
86#pragma omp parallel for private(k) reduction(+ : scale)
88 for (k = l; k <= n; k++) scale += fabs(a[i][k]);
91#pragma omp parallel for private(k) reduction(+ : s)
93 for (k = l; k <= n; k++) {
95 s += a[i][k] * a[i][k];
98 g = -
SIGNS(sqrt(s), f);
102#pragma omp parallel for private(k)
104 for (k = l; k <= n; k++) rv1[k] = a[i][k] / h;
106 for (j = l; j <= m; j++) {
109#pragma omp parallel for private(k) reduction(+ : s)
111 for (k = l; k <= n; k++) s += a[j][k] * a[i][k];
113#pragma omp parallel for private(k)
115 for (k = l; k <= n; k++) a[j][k] += s * rv1[k];
119#pragma omp parallel for private(k)
121 for (k = l; k <= n; k++) a[i][k] *= scale;
124 anorm =
MAX(anorm, (fabs(w[i]) + fabs(rv1[i])));
127 for (i = n; i >= 1; i--)
132#pragma omp parallel for private(j)
134 for (j = l; j <= n; j++)
135 v[j][i] = (a[i][j] / a[i][l]) / g;
136 for (j = l; j <= n; j++) {
139#pragma omp parallel for private(k) reduction(+ : s)
141 for (k = l; k <= n; k++) s += a[i][k] * v[k][j];
143#pragma omp parallel for private(k)
145 for (k = l; k <= n; k++) v[k][j] += s * v[k][i];
149#pragma omp parallel for private(j)
151 for (j = l; j <= n; j++) v[i][j] = v[j][i] = 0.0;
158 for (i = n; i >= 1; i--)
164#pragma omp parallel for private(j)
166 for (j = l; j <= n; j++) a[i][j] = 0.0;
171 for (j = l; j <= n; j++) {
174#pragma omp parallel for private(k) reduction(+ : s)
176 for (k = l; k <= m; k++) s += a[k][i] * a[k][j];
177 f = (s / a[i][i]) * g;
179#pragma omp parallel for private(k)
181 for (k = i; k <= m; k++) a[k][j] += f * a[k][i];
185#pragma omp parallel for private(j)
187 for (j = i; j <= m; j++) a[j][i] *= g;
190#pragma omp parallel for private(j)
192 for (j = i; j <= m; j++) a[j][i] = 0.0;
198 for (k = n; k >= 1; k--)
199 for (its = 1; its <=
MAX_ITS; its++)
202 for (l = k; l >= 1; l--)
205 if ((
double)(fabs(rv1[l]) + anorm) == anorm) {
209 if ((
double)(fabs(w[nm]) + anorm) == anorm)
break;
214 for (i = l; i <= k; i++) {
217 if ((
double)(fabs(f) + anorm) == anorm)
break;
225#pragma omp parallel for private(j, y, z)
227 for (j = 1; j <= m; j++) {
230 a[j][nm] = y * c + z * s;
231 a[j][i] = z * c - y * s;
242#pragma omp parallel for private(j)
244 for (j = 1; j <= n; j++) v[j][k] = (-v[j][k]);
250 nrerror(
"no convergence in 1000 SVDCMP iterations.\n");
257 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
259 f = ((x - z) * (x + z) + h * ((y / (f +
SIGNS(g, f))) - h)) / x;
262 for (j = l; j <= nm; j++) {
277#pragma omp parallel for private(jj, x, z)
279 for (jj = 1; jj <= n; jj++) {
282 v[jj][j] = x * c + z * s;
283 v[jj][i] = z * c - x * s;
296#pragma omp parallel for private(jj, y, z)
298 for (jj = 1; jj <= m; jj++) {
301 a[jj][j] = y * c + z * s;
302 a[jj][i] = z * c - y * s;
NRGLOBAL void svdcmp(double **a, int matrow, int matcol, double *w, double **v)
void free_dvector(double *v, long nl, long)
double * dvector(long nl, long nh)