22 , n_(inMatrix[0].size())
24 , eps_(
std::numeric_limits<double>::epsilon())
27 for (
uint04 i = 0; i < n_; i++)
32 tsh_ = 0.5 * std::sqrt(m_ + n_ + 1.) * s_[0] * eps_;
81 if (inInput.
size() != m_)
92 tsh_ = (inThresh >= 0. ? inThresh : 0.5 * std::sqrt(m_ + n_ + 1.) * s_[0] * eps_);
94 for (
uint04 j = 0; j < n_; j++)
99 for (
uint04 i = 0; i < m_; i++)
100 ss += u_[i][j] * inInput[i];
106 for (
uint04 j = 0; j < n_; j++)
109 for (
uint04 jj = 0; jj < n_; jj++)
111 ss += v_[j][jj] * tmp[jj];
130 static double SIGN(
double inA,
double inB)
noexcept
132 return inB >= 0 ? (inA >= 0 ? inA : -inA) : (inA >= 0 ? -inA : inA);
140 static bool essentiallyEqual(
double a,
double b)
142 if (
abs(a - b) < std::numeric_limits<double>::epsilon())
171 for (i = 0; i < n_; ++i)
179 for (k = i; k < m_; ++k)
181 scale += std::abs(u_[k][i]);
184 if (!essentiallyEqual(scale, 0.))
186 for (k = i; k < m_; ++k)
189 ss += u_[k][i] * u_[k][i];
193 g = -SIGN(std::sqrt(ss), f);
197 for (j = l - 1; j < n_; ++j)
199 for (ss = 0., k = i; k < m_; ++k)
201 ss += u_[k][i] * u_[k][j];
206 for (k = i; k < m_; ++k)
208 u_[k][j] += f * u_[k][i];
212 for (k = i; k < m_; ++k)
222 if (i + 1 <= m_ && i + 1 != n_)
224 for (k = l - 1; k < n_; ++k)
226 scale += std::abs(u_[i][k]);
229 if (!essentiallyEqual(scale, 0.))
231 for (k = l - 1; k < n_; ++k)
234 ss += u_[i][k] * u_[i][k];
238 g = -SIGN(std::sqrt(ss), f);
240 u_[i][l - 1] = f - g;
242 for (k = l - 1; k < n_; ++k)
244 rv1[k] = u_[i][k] / h;
247 for (j = l - 1; j < m_; ++j)
249 for (ss = 0., k = l - 1; k < n_; ++k)
251 ss += u_[j][k] * u_[i][k];
254 for (k = l - 1; k < n_; ++k)
256 u_[j][k] += ss * rv1[k];
260 for (k = l - 1; k < n_; ++k)
267 anorm = std::max(anorm, (std::abs(s_[i]) + std::abs(rv1[i])));
270 for (i = n_ - 1; i !=
static_cast<uint04>(-1); --i)
274 if (!essentiallyEqual(g, 0.))
276 for (j = l; j < n_; ++j)
278 v_[j][i] = (u_[i][j] / u_[i][l]) / g;
281 for (j = l; j < n_; ++j)
283 for (ss = 0., k = l; k < n_; ++k)
285 ss += u_[i][k] * v_[k][j];
288 for (k = l; k < n_; ++k)
290 v_[k][j] += ss * v_[k][i];
295 for (j = l; j < n_; ++j)
297 v_[i][j] = v_[j][i] = 0.;
306 for (i = std::min(m_, n_) - 1; i !=
static_cast<uint04>(-1); --i)
311 for (j = l; j < n_; ++j)
316 if (!essentiallyEqual(g, 0.))
320 for (j = l; j < n_; ++j)
322 for (ss = 0., k = l; k < m_; ++k)
324 ss += u_[k][i] * u_[k][j];
327 f = (ss / u_[i][i]) * g;
329 for (k = i; k < m_; ++k)
331 u_[k][j] += f * u_[k][i];
335 for (j = i; j < m_; ++j)
342 for (j = i; j < m_; ++j)
351 for (k = n_ - 1; k !=
static_cast<uint04>(-1); --k)
353 for (its = 0; its < 30; ++its)
356 for (l = k; l !=
static_cast<uint04>(-1); --l)
359 if (l == 0 || std::abs(rv1[l]) <= eps_ * anorm)
365 if (std::abs(s_[nm]) <= eps_ * anorm)
375 for (i = l; i < k + 1; ++i)
380 if (std::abs(f) <= eps_ * anorm)
392 for (j = 0; j < m_; ++j)
396 u_[j][nm] = y * c + z * ss;
397 u_[j][i] = z * c - y * ss;
408 for (j = 0; j < n_; ++j)
410 v_[j][k] = -v_[j][k];
418 throw Exception(
"no convergence in 30 svdcmp iterations");
426 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2. * h * y);
428 f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
431 for (j = l; j <= nm; j++)
447 for (jj = 0; jj < n_; ++jj)
451 v_[jj][j] = x * c + z * ss;
452 v_[jj][i] = z * c - x * ss;
458 if (!essentiallyEqual(z, 0.))
468 for (jj = 0; jj < m_; ++jj)
472 u_[jj][j] = y * c + z * ss;
473 u_[jj][i] = z * c - y * ss;
510 for (i = inc; i < n_; ++i)
513 for (k = 0; k < m_; ++k)
518 for (k = 0; k < n_; ++k)
524 while (s_[j - inc] < sw)
528 for (k = 0; k < m_; ++k)
530 u_[k][j] = u_[k][j - inc];
533 for (k = 0; k < n_; ++k)
535 v_[k][j] = v_[k][j - inc];
548 for (k = 0; k < m_; ++k)
553 for (k = 0; k < n_; ++k)
560 for (k = 0; k < n_; ++k)
564 for (i = 0; i < m_; i++)
572 for (j = 0; j < n_; ++j)
580 if (ss > (m_ + n_) / 2)
582 for (i = 0; i < m_; ++i)
584 u_[i][k] = -u_[i][k];
587 for (j = 0; j < n_; ++j)
589 v_[j][k] = -v_[j][k];
604 static double pythag(
double inA,
double inB)
noexcept
606 const double absa = std::abs(inA);
607 const double absb = std::abs(inB);
609 ? absa * std::sqrt(1. + (absb / absa) * (absb / absa))
610 : (essentiallyEqual(absb, 0.) ? 0. : absb * std::sqrt(1. + (absb / absa) * (absb / absa))));
612 static Buffer<double> lstsq(
const NdArray& inA,
const Buffer<double>& inB,
double inTolerance = 1e-12)
615 const double threshold = inTolerance * svdSolver.s()[0];
617 return svdSolver.solve(inB, threshold);