singular_value_decomposition.hxx
|
|
37 #ifndef VIGRA_SINGULAR_VALUE_DECOMPOSITION_HXX
38 #define VIGRA_SINGULAR_VALUE_DECOMPOSITION_HXX
41 #include "array_vector.hxx"
73 template <
class T,
class C1,
class C2,
class C3,
class C4>
82 vigra_precondition(rows >= cols,
83 "singularValueDecomposition(): Input matrix A must be rectangular with rowCount >= columnCount.");
85 "singularValueDecomposition(): Output S must be column vector with rowCount == columnCount(A).");
87 "singularValueDecomposition(): Output matrix U must have the same dimensions as input matrix A.");
89 "singularValueDecomposition(): Output matrix V must be square with n = columnCount(A).");
110 for (k = 0; k < std::max(nct,nrt); ++k)
118 for (i = k; i < m; ++i)
120 s(k) =
hypot(s(k), a(i, k));
128 for (i = k; i < m; ++i)
136 for (j = k+1; j < n; ++j)
138 if ((k < nct) && (s(k) != 0.0))
142 for (i = k; i < m; ++i)
144 t += a(i, k)*a(i, j);
147 for (i = k; i < m; ++i)
149 a(i, j) += t*a(i, k);
163 for (i = k; i < m; ++i)
174 for (i = k+1; i < n; ++i)
176 e[k] =
hypot(e[k],e[i]);
184 for (i = k+1; i < n; ++i)
191 if ((k+1 < m) & (e[k] != 0.0))
194 for (i = k+1; i < m; ++i)
198 for (j = k+1; j < n; ++j)
200 for (i = k+1; i < m; ++i)
202 work[i] += e[j]*a(i, j);
205 for (j = k+1; j < n; ++j)
207 Real t(-e[j]/e[k+1]);
208 for (i = k+1; i < m; ++i)
210 a(i, j) += t*work[i];
216 for (i = k+1; i < n; ++i)
228 s(nct) = a(nct, nct);
236 e[nrt] = a(nrt, p-1);
241 for (j = nct; j < nu; ++j)
243 for (i = 0; i < m; ++i)
249 for (k = nct-1; k >= 0; --k)
253 for (j = k+1; j < nu; ++j)
256 for (i = k; i < m; ++i)
258 t += U(i, k)*U(i, j);
261 for (i = k; i < m; ++i)
263 U(i, j) += t*U(i, k);
266 for (i = k; i < m; ++i )
270 U(k, k) = 1.0 + U(k, k);
271 for (i = 0; i < k-1; ++i)
278 for (i = 0; i < m; ++i)
287 for (k = n-1; k >= 0; --k)
289 if ((k < nrt) & (e[k] != 0.0))
291 for (j = k+1; j < nu; ++j)
294 for (i = k+1; i < n; ++i)
296 t += V(i, k)*V(i, j);
299 for (i = k+1; i < n; ++i)
301 V(i, j) += t*V(i, k);
305 for (i = 0; i < n; ++i)
316 Real eps = NumericTraits<Real>::epsilon()*2.0;
334 for (k = p-2; k >= -1; --k)
340 if (
abs(e[k]) <= eps*(
abs(s(k)) +
abs(s(k+1))))
353 for (ks = p-1; ks >= k; --ks)
359 Real t( (ks != p ?
abs(e[ks]) : 0.) +
360 (ks != k+1 ?
abs(e[ks-1]) : 0.));
361 if (
abs(s(ks)) <= eps*t)
391 for (j = p-2; j >= k; --j)
393 Real t(
hypot(s(j),f));
402 for (i = 0; i < n; ++i)
404 t = cs*V(i, j) + sn*V(i, p-1);
405 V(i, p-1) = -sn*V(i, j) + cs*V(i, p-1);
415 for (j = k; j < p; ++j)
417 Real t(
hypot(s(j),f));
423 for (i = 0; i < m; ++i)
425 t = cs*U(i, j) + sn*U(i, k-1);
426 U(i, k-1) = -sn*U(i, j) + cs*U(i, k-1);
435 Real scale = std::max(std::max(std::max(std::max(
438 Real sp = s(p-1)/scale;
439 Real spm1 = s(p-2)/scale;
440 Real epm1 = e[p-2]/scale;
441 Real sk = s(k)/scale;
442 Real ek = e[k]/scale;
443 Real b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
444 Real c = (sp*epm1)*(sp*epm1);
446 if ((b != 0.0) || (c != 0.0))
453 shift = c/(b + shift);
455 Real f = (sk + sp)*(sk - sp) + shift;
459 for (j = k; j < p-1; ++j)
468 f = cs*s(j) + sn*e[j];
469 e[j] = cs*e[j] - sn*s(j);
472 for (i = 0; i < n; ++i)
474 t = cs*V(i, j) + sn*V(i, j+1);
475 V(i, j+1) = -sn*V(i, j) + cs*V(i, j+1);
482 f = cs*e[j] + sn*s(j+1);
483 s(j+1) = -sn*e[j] + cs*s(j+1);
488 for (i = 0; i < m; ++i)
490 t = cs*U(i, j) + sn*U(i, j+1);
491 U(i, j+1) = -sn*U(i, j) + cs*U(i, j+1);
505 s(k) = (s(k) < 0.0 ? -s(k) : 0.0);
506 for (i = 0; i <= pp; ++i)
525 for (i = 0; i < n; ++i)
527 t = V(i, k+1); V(i, k+1) = V(i, k); V(i, k) = t;
532 for (i = 0; i < m; ++i)
534 t = U(i, k+1); U(i, k+1) = U(i, k); U(i, k) = t;
544 vigra_fail(
"vigra::svd(): Internal error.");
547 Real tol = std::max(m,n)*s(0)*eps;
548 unsigned int rank = 0;
549 for (i = 0; i < n; ++i)
565 #endif // VIGRA_SINGULAR_VALUE_DECOMPOSITION_HXX
MultiArrayIndex rowCount(const MultiArrayView< 2, T, C > &x)
Definition: matrix.hxx:671
Definition: matrix.hxx:123
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
FixedPoint16< IntBits, OverflowHandling > hypot(FixedPoint16< IntBits, OverflowHandling > v1, FixedPoint16< IntBits, OverflowHandling > v2)
Length of hypotenuse.
Definition: fixedpoint.hxx:1640
Definition: array_vector.hxx:58
MultiArrayIndex columnCount(const MultiArrayView< 2, T, C > &x)
Definition: matrix.hxx:684
MultiArrayView & init(const U &init)
Definition: multi_array.hxx:1206
unsigned int singularValueDecomposition(MultiArrayView< 2, T, C1 > const &A, MultiArrayView< 2, T, C2 > &U, MultiArrayView< 2, T, C3 > &S, MultiArrayView< 2, T, C4 > &V)
Definition: singular_value_decomposition.hxx:75
linalg::TemporaryMatrix< T > abs(MultiArrayView< 2, T, C > const &v)
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616
MultiArrayView< N-M, T, StrideTag > bindOuter(const TinyVector< Index, M > &d) const
Definition: multi_array.hxx:2184