9 #ifndef CUBBYFLOW_SVD_IMPL_H 10 #define CUBBYFLOW_SVD_IMPL_H 19 return (b >= 0.0) ? std::fabs(a) : -std::fabs(a);
33 result = at * std::sqrt(1 + ct * ct);
38 result = bt * std::sqrt(1 + ct * ct);
52 const int m =
static_cast<int>(a.
Rows());
53 const int n =
static_cast<int>(a.
Cols());
55 int i, j = 0, jj = 0, k = 0, l = 0, nm = 0;
56 T c = 0, f = 0, h = 0, s = 0, x = 0, y = 0, z = 0;
57 T anorm = 0, g = 0, scale = 0;
61 throw std::invalid_argument(
"Number of rows of input matrix must greater than or equal to columns.");
71 for (i = 0; i < n; i++)
80 for (k = i; k < m; k++)
82 scale += std::fabs(u(k, i));
87 for (k = i; k < m; k++)
90 s += u(k, i) * u(k, i);
100 for (j = l; j < n; j++)
102 for (s = 0, k = i; k < m; k++)
104 s += u(k, i) * u(k, j);
109 for (k = i; k < m; k++)
111 u(k, j) += f * u(k, i);
116 for (k = i; k < m; k++)
128 if (i < m && i != n - 1)
130 for (k = l; k < n; k++)
132 scale += std::fabs(u(i, k));
137 for (k = l; k < n; k++)
140 s += u(i, k) * u(i, k);
148 for (k = l; k < n; k++)
150 rv1[k] =
static_cast<T
>(u(i, k)) / h;
155 for (j = l; j < m; j++)
157 for (s = 0, k = l; k < n; k++)
159 s += u(j, k) * u(i, k);
162 for (k = l; k < n; k++)
164 u(j, k) += s * rv1[k];
169 for (k = l; k < n; k++)
176 anorm = std::max(anorm, (std::fabs(static_cast<T>(w[i])) + std::fabs(rv1[i])));
180 for (i = n - 1; i >= 0; i--)
186 for (j = l; j < n; j++)
188 v(j, i) = ((u(i, j) / u(i, l)) / g);
192 for (j = l; j < n; j++)
194 for (s = 0, k = l; k < n; k++)
196 s += u(i, k) * v(k, j);
199 for (k = l; k < n; k++)
201 v(k, j) += s * v(k, i);
206 for (j = l; j < n; j++)
208 v(i, j) = v(j, i) = 0;
218 for (i = n - 1; i >= 0; i--)
225 for (j = l; j < n; j++)
237 for (j = l; j < n; j++)
239 for (s = 0, k = l; k < m; k++)
241 s += u(k, i) * u(k, j);
244 f = (s / u(i, i)) * g;
246 for (k = i; k < m; k++)
248 u(k, j) += f * u(k, i);
253 for (j = i; j < m; j++)
255 u(j, i) = u(j, i) * g;
260 for (j = i; j < m; j++)
270 for (k = n - 1; k >= 0; k--)
273 for (
int its = 0; its < 30; its++)
278 for (l = k; l >= 0; l--)
283 if (std::fabs(rv1[l]) + anorm == anorm)
289 if (std::fabs(static_cast<T>(w[nm])) + anorm == anorm)
300 for (i = l; i <= k; i++)
304 if (std::fabs(f) + anorm != anorm)
308 w[i] =
static_cast<T
>(h);
313 for (j = 0; j < m; j++)
317 u(j, nm) = y * c + z * s;
318 u(j, i) = z * c - y * s;
334 for (j = 0; j < n; j++)
345 throw "No convergence after 30 iterations";
354 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2 * h * y);
356 f = ((x - z) * (x + z) + h * ((y / (f +
Internal::Sign(g, f))) - h)) / x;
361 for (j = l; j <= nm; j++)
377 for (jj = 0; jj < n; jj++)
381 v(jj, j) = x * c + z * s;
382 v(jj, i) = z * c - x * s;
395 f = (c * g) + (s * y);
396 x = (c * y) - (s * g);
398 for (jj = 0; jj < m; jj++)
402 u(jj, j) = y * c + z * s;
403 u(jj, i) = z * c - y * s;
414 template <
typename T,
size_t M,
size_t N>
415 void SVD(
const Matrix<T, M, N>& a,
Matrix<T, M, N>& u,
Vector<T, N>& w,
Matrix<T, N, N>& v)
417 const int m =
static_cast<int>(M);
418 const int n =
static_cast<int>(N);
420 int i, its, j = 0, jj = 0, k = 0, l = 0, nm = 0;
421 T c = 0, f = 0, h = 0, s = 0, x = 0, y = 0, z = 0;
422 T anorm = 0, g = 0, scale = 0;
424 static_assert(m >= n,
"Number of rows of input matrix must greater than or equal to columns.");
433 for (i = 0; i < n; i++)
442 for (k = i; k < m; k++)
444 scale += std::fabs(u(k, i));
449 for (k = i; k < m; k++)
452 s += u(k, i) * u(k, i);
462 for (j = l; j < n; j++)
464 for (s = 0, k = i; k < m; k++)
466 s += u(k, i) * u(k, j);
471 for (k = i; k < m; k++)
473 u(k, j) += f * u(k, i);
478 for (k = i; k < m; k++)
490 if (i < m && i != n - 1)
492 for (k = l; k < n; k++)
494 scale += std::fabs(u(i, k));
499 for (k = l; k < n; k++)
502 s += u(i, k) * u(i, k);
510 for (k = l; k < n; k++)
512 rv1[k] =
static_cast<T
>(u(i, k)) / h;
517 for (j = l; j < m; j++)
519 for (s = 0, k = l; k < n; k++)
521 s += u(j, k) * u(i, k);
524 for (k = l; k < n; k++)
526 u(j, k) += s * rv1[k];
531 for (k = l; k < n; k++)
537 anorm = std::max(anorm, (std::fabs(static_cast<T>(w[i])) + std::fabs(rv1[i])));
541 for (i = n - 1; i >= 0; i--)
547 for (j = l; j < n; j++)
549 v(j, i) = ((u(i, j) / u(i, l)) / g);
553 for (j = l; j < n; j++)
555 for (s = 0, k = l; k < n; k++)
557 s += u(i, k) * v(k, j);
560 for (k = l; k < n; k++)
562 v(k, j) += s * v(k, i);
567 for (j = l; j < n; j++)
569 v(i, j) = v(j, i) = 0;
579 for (i = n - 1; i >= 0; i--)
586 for (j = l; j < n; j++)
598 for (j = l; j < n; j++)
600 for (s = 0, k = l; k < m; k++)
602 s += u(k, i) * u(k, j);
605 f = (s / u(i, i)) * g;
607 for (k = i; k < m; k++)
609 u(k, j) += f * u(k, i);
614 for (j = i; j < m; j++)
616 u(j, i) = u(j, i) * g;
621 for (j = i; j < m; j++)
631 for (k = n - 1; k >= 0; k--)
634 for (its = 0; its < 30; its++)
639 for (l = k; l >= 0; l--)
644 if (std::fabs(rv1[l]) + anorm == anorm)
650 if (std::fabs(static_cast<T>(w[nm])) + anorm == anorm)
661 for (i = l; i <= k; i++)
665 if (std::fabs(f) + anorm != anorm)
669 w[i] =
static_cast<T
>(h);
674 for (j = 0; j < m; j++)
678 u(j, nm) = y * c + z * s;
679 u(j, i) = z * c - y * s;
695 for (j = 0; j < n; j++)
706 throw "No convergence after 30 iterations";
715 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2 * h * y);
717 f = ((x - z) * (x + z) + h * ((y / (f +
Internal::Sign(g, f))) - h)) / x;
722 for (j = l; j <= nm; j++)
738 for (jj = 0; jj < n; jj++)
742 v(jj, j) = x * c + z * s;
743 v(jj, i) = z * c - x * s;
755 f = (c * g) + (s * y);
756 x = (c * y) - (s * g);
758 for (jj = 0; jj < m; jj++)
762 u(jj, j) = y * c + z * s;
763 u(jj, i) = z * c - y * s;
T Sign(T a, T b)
Definition: SVD-Impl.h:17
Generic statically-sized N-D vector class.
Definition: Vector.h:33
size_t Cols() const
Returns number of columns of this matrix.
Definition: MatrixMxN-Impl.h:209
General purpose dynamically-sizedN-D vector class.
Definition: VectorN.h:27
Static-sized M x N matrix class.
Definition: Matrix.h:30
void Resize(size_t m, size_t n, const T &s=T(0))
Resizes to m x n matrix with initial value s.
Definition: MatrixMxN-Impl.h:59
Definition: pybind11Utils.h:24
void Resize(size_t n, const T &val=0)
Resizes to n dimensional vector with initial value val.
Definition: VectorN-Impl.h:57
T Pythag(T a, T b)
Definition: SVD-Impl.h:23
void SVD(const MatrixMxN< T > &a, MatrixMxN< T > &u, VectorN< T > &w, MatrixMxN< T > &v)
Singular value decomposition (SVD).
Definition: SVD-Impl.h:50
M x N matrix class.
Definition: MatrixMxN.h:26
size_t Rows() const
Returns number of rows of this matrix.
Definition: MatrixMxN-Impl.h:203