for (i = 0, x = 0.0; i < ncols; i++)
{
y = fabs (diagonal[i]) + fabs (superdiagonal[i]); if (x < y)
x = y;
}
epsilon = x * DBL_EPSILON; for (k = ncols - 1; k >= 0; k--)
{
iteration_count = 0; while (1)
{
rotation_test = 1; for (m = k; m >= 0; m--)
{ if (fabs (superdiagonal[m]) <= epsilon)
{
rotation_test = 0; break;
} if (fabs (diagonal[m-1]) <= epsilon) break;
} if (rotation_test)
{
c = 0.0;
s = 1.0; for (i = m; i <= k; i++)
{
f = s * superdiagonal[i];
superdiagonal[i] *= c; if (fabs (f) <= epsilon) break;
g = diagonal[i];
h = sqrt (f*f + g*g);
diagonal[i] = h;
c = g / h;
s = -f / h; for (j = 0, pu = U; j < nrows; j++, pu += ncols)
{
y = *(pu + m - 1);
z = *(pu + i);
*(pu + m - 1 ) = y * c + z * s;
*(pu + i) = -y * s + z * c;
}
}
}
z = diagonal[k]; if (m == k)
{ if (z < 0.0)
{
diagonal[k] = -z; for (j = 0, pv = V; j < ncols; j++, pv += ncols)
*(pv + k) = - *(pv + k);
} break;
} else
{ if (iteration_count >= MAX_ITERATION_COUNT) return -1;
iteration_count++;
x = diagonal[m];
y = diagonal[k-1];
g = superdiagonal[k-1];
h = superdiagonal[k];
f = ((y - z) * ( y + z ) + (g - h) * (g + h))/(2.0 * h * y);
g = sqrt (f * f + 1.0); if (f < 0.0)
g = -g;
f = ((x - z) * (x + z) + h * (y / (f + g) - h)) / x;
c = 1.0;
s = 1.0; for (i = m + 1; i <= k; i++)
{
g = superdiagonal[i];
y = diagonal[i];
h = s * g;
g *= c;
z = sqrt (f * f + h * h);
superdiagonal[i-1] = z;
c = f / z;
s = h / z;
f = x * c + g * s;
g = -x * s + g * c;
h = y * s;
y *= c; for (j = 0, pv = V; j < ncols; j++, pv += ncols)
{
x = *(pv + i - 1);
z = *(pv + i);
*(pv + i - 1) = x * c + z * s;
*(pv + i) = -x * s + z * c;
}
z = sqrt (f * f + h * h);
diagonal[i - 1] = z; if (z != 0.0)
{
c = f / z;
s = h / z;
}
f = c * g + s * y;
x = -s * g + c * y; for (j = 0, pu = U; j < nrows; j++, pu += ncols)
{
y = *(pu + i - 1);
z = *(pu + i);
*(pu + i - 1) = c * y + s * z;
*(pu + i) = -s * y + c * z;
}
}
superdiagonal[m] = 0.0;
superdiagonal[k] = f;
diagonal[k] = x;
}
}
} return0;
}
/* Given a singular value decomposition *ofannrowsxncolsmatrixA=U*Diag(S)*Vt, *sortthevaluesofSbydecreasingvalue, *permutingVtomatch.
*/ staticvoid
sort_singular_values (int nrows, int ncols, double *S, double *U, double *V)
{ int i, j, max_index; double temp; double *p1, *p2;
assert (nrows >= 2);
assert (ncols >= 2);
for (i = 0; i < ncols - 1; i++)
{
max_index = i; for (j = i + 1; j < ncols; j++) if (S[j] > S[max_index])
max_index = j; if (max_index == i) continue;
temp = S[i];
S[i] = S[max_index];
S[max_index] = temp;
p1 = U + max_index;
p2 = U + i; for (j = 0; j < nrows; j++, p1 += ncols, p2 += ncols)
{
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
p1 = V + max_index;
p2 = V + i; for (j = 0; j < ncols; j++, p1 += ncols, p2 += ncols)
{
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
}
}
/* Compute a singular value decomposition of A, *A=U*Diag(S)*Vt * *Allmatricesareallocatedbythecaller * *Sizes: *A,U:nrowsxncols *S:ncols *V:ncolsxncols
*/ int
singular_value_decomposition (double *A, int nrows, int ncols, double *U, double *S, double *V)
{ double *superdiagonal;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.