124 template <
typename Derived_>
125 friend struct internal::solve_assertion;
127 using MatrixType =
typename internal::traits<Derived>::MatrixType;
128 using Scalar =
typename MatrixType::Scalar;
129 using RealScalar =
typename NumTraits<typename MatrixType::Scalar>::Real;
130 using StorageIndex =
typename Eigen::internal::traits<SVDBase>::StorageIndex;
132 static constexpr bool ShouldComputeFullU = internal::traits<Derived>::ShouldComputeFullU;
133 static constexpr bool ShouldComputeThinU = internal::traits<Derived>::ShouldComputeThinU;
134 static constexpr bool ShouldComputeFullV = internal::traits<Derived>::ShouldComputeFullV;
135 static constexpr bool ShouldComputeThinV = internal::traits<Derived>::ShouldComputeThinV;
138 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
139 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
140 DiagSizeAtCompileTime = internal::min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime),
141 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
142 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
143 MaxDiagSizeAtCompileTime = internal::min_size_prefer_fixed(MaxRowsAtCompileTime, MaxColsAtCompileTime),
144 MatrixOptions = internal::traits<MatrixType>::Options,
145 MatrixUColsAtCompileTime = internal::traits<Derived>::MatrixUColsAtCompileTime,
146 MatrixVColsAtCompileTime = internal::traits<Derived>::MatrixVColsAtCompileTime,
147 MatrixUMaxColsAtCompileTime = internal::traits<Derived>::MatrixUMaxColsAtCompileTime,
148 MatrixVMaxColsAtCompileTime = internal::traits<Derived>::MatrixVMaxColsAtCompileTime
151 EIGEN_STATIC_ASSERT(!(ShouldComputeFullU && ShouldComputeThinU),
"SVDBase: Cannot request both full and thin U")
152 EIGEN_STATIC_ASSERT(!(ShouldComputeFullV && ShouldComputeThinV),
"SVDBase: Cannot request both full and thin V")
155 typename internal::make_proper_matrix_type<Scalar, RowsAtCompileTime, MatrixUColsAtCompileTime, MatrixOptions,
156 MaxRowsAtCompileTime, MatrixUMaxColsAtCompileTime>::type;
158 typename internal::make_proper_matrix_type<Scalar, ColsAtCompileTime, MatrixVColsAtCompileTime, MatrixOptions,
159 MaxColsAtCompileTime, MatrixVMaxColsAtCompileTime>::type;
161 using SingularValuesType =
typename internal::plain_diag_type<MatrixType, RealScalar>::type;
163 Derived& derived() {
return *
static_cast<Derived*
>(
this); }
164 const Derived& derived()
const {
return *
static_cast<const Derived*
>(
this); }
177 _check_compute_assertions();
178 eigen_assert(
computeU() &&
"This SVD decomposition didn't compute U. Did you ask for it?");
193 _check_compute_assertions();
194 eigen_assert(
computeV() &&
"This SVD decomposition didn't compute V. Did you ask for it?");
204 _check_compute_assertions();
205 return m_singularValues;
210 _check_compute_assertions();
211 return m_nonzeroSingularValues;
222 _check_compute_assertions();
223 if (m_singularValues.size() == 0)
return 0;
224 RealScalar premultiplied_threshold =
225 numext::maxi<RealScalar>(m_singularValues.coeff(0) *
threshold(), (std::numeric_limits<RealScalar>::min)());
226 Index i = m_nonzeroSingularValues - 1;
227 while (i >= 0 && m_singularValues.coeff(i) < premultiplied_threshold) --i;
246 m_usePrescribedThreshold =
true;
260 m_usePrescribedThreshold =
false;
269 eigen_assert(m_isInitialized || m_usePrescribedThreshold);
271 Index diagSize = (std::max<Index>)(1, m_diagSize);
272 return m_usePrescribedThreshold ? m_prescribedThreshold : RealScalar(diagSize) * NumTraits<Scalar>::epsilon();
276 inline bool computeU()
const {
return m_computeFullU || m_computeThinU; }
278 inline bool computeV()
const {
return m_computeFullV || m_computeThinV; }
280 inline Index rows()
const {
return m_rows.value(); }
281 inline Index cols()
const {
return m_cols.value(); }
282 inline Index diagSize()
const {
return m_diagSize.value(); }
284#ifdef EIGEN_PARSED_BY_DOXYGEN
295 template <
typename Rhs>
304 eigen_assert(m_isInitialized &&
"SVD is not initialized.");
308#ifndef EIGEN_PARSED_BY_DOXYGEN
309 template <
typename RhsType,
typename DstType>
310 void _solve_impl(
const RhsType& rhs, DstType& dst)
const;
312 template <
bool Conjugate,
typename RhsType,
typename DstType>
313 void _solve_impl_transposed(
const RhsType& rhs, DstType& dst)
const;
317 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
319 void _check_compute_assertions()
const { eigen_assert(m_isInitialized &&
"SVD is not initialized."); }
321 template <
bool Transpose_,
typename Rhs>
322 void _check_solve_assertion(
const Rhs& b)
const {
323 EIGEN_ONLY_USED_FOR_DEBUG(b);
324 _check_compute_assertions();
326 "SVDBase::solve(): Both unitaries U and V are required to be computed (thin unitaries suffice).");
327 eigen_assert((Transpose_ ? cols() : rows()) == b.rows() &&
328 "SVDBase::solve(): invalid number of rows of the right hand side matrix b");
332 bool allocate(
Index rows,
Index cols,
unsigned int computationOptions);
334 MatrixUType m_matrixU;
335 MatrixVType m_matrixV;
336 SingularValuesType m_singularValues;
338 bool m_isInitialized, m_isAllocated, m_usePrescribedThreshold;
339 bool m_computeFullU, m_computeThinU;
340 bool m_computeFullV, m_computeThinV;
341 unsigned int m_computationOptions;
342 Index m_nonzeroSingularValues;
343 internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
344 internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
345 internal::variable_if_dynamic<Index, DiagSizeAtCompileTime> m_diagSize;
346 RealScalar m_prescribedThreshold;
353 : m_matrixU(MatrixUType()),
354 m_matrixV(MatrixVType()),
355 m_singularValues(SingularValuesType()),
357 m_isInitialized(false),
358 m_isAllocated(false),
359 m_usePrescribedThreshold(false),
360 m_computeFullU(ShouldComputeFullU),
361 m_computeThinU(ShouldComputeThinU),
362 m_computeFullV(ShouldComputeFullV),
363 m_computeThinV(ShouldComputeThinV),
364 m_computationOptions(internal::traits<Derived>::Options),
365 m_nonzeroSingularValues(0),
366 m_rows(RowsAtCompileTime),
367 m_cols(ColsAtCompileTime),
368 m_diagSize(DiagSizeAtCompileTime),
369 m_prescribedThreshold(0) {}