Add assert for edge case if Thin U Requested at runtime

This commit is contained in:
Arthur 2022-02-23 05:35:19 +00:00 committed by Antonio Sánchez
parent 35727928ad
commit cd80e04ab7
4 changed files with 17 additions and 16 deletions

View File

@ -163,7 +163,7 @@ public:
*/ */
EIGEN_DEPRECATED EIGEN_DEPRECATED
BDCSVD(Index rows, Index cols, unsigned int computationOptions) : m_algoswap(16), m_numIters(0) { BDCSVD(Index rows, Index cols, unsigned int computationOptions) : m_algoswap(16), m_numIters(0) {
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions); internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, rows, cols);
allocate(rows, cols, computationOptions); allocate(rows, cols, computationOptions);
} }
@ -190,7 +190,7 @@ public:
*/ */
EIGEN_DEPRECATED EIGEN_DEPRECATED
BDCSVD(const MatrixType& matrix, unsigned int computationOptions) : m_algoswap(16), m_numIters(0) { BDCSVD(const MatrixType& matrix, unsigned int computationOptions) : m_algoswap(16), m_numIters(0) {
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions); internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
compute_impl(matrix, computationOptions); compute_impl(matrix, computationOptions);
} }
@ -214,7 +214,7 @@ public:
*/ */
EIGEN_DEPRECATED EIGEN_DEPRECATED
BDCSVD& compute(const MatrixType& matrix, unsigned int computationOptions) { BDCSVD& compute(const MatrixType& matrix, unsigned int computationOptions) {
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions); internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
return compute_impl(matrix, computationOptions); return compute_impl(matrix, computationOptions);
} }

View File

@ -568,7 +568,7 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options> > {
*/ */
EIGEN_DEPRECATED EIGEN_DEPRECATED
JacobiSVD(Index rows, Index cols, unsigned int computationOptions) { JacobiSVD(Index rows, Index cols, unsigned int computationOptions) {
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions); internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, rows, cols);
allocate(rows, cols, computationOptions); allocate(rows, cols, computationOptions);
} }
@ -593,7 +593,7 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options> > {
*/ */
EIGEN_DEPRECATED EIGEN_DEPRECATED
JacobiSVD(const MatrixType& matrix, unsigned int computationOptions) { JacobiSVD(const MatrixType& matrix, unsigned int computationOptions) {
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions); internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
compute_impl(matrix, computationOptions); compute_impl(matrix, computationOptions);
} }
@ -615,7 +615,7 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options> > {
*/ */
EIGEN_DEPRECATED EIGEN_DEPRECATED
JacobiSVD& compute(const MatrixType& matrix, unsigned int computationOptions) { JacobiSVD& compute(const MatrixType& matrix, unsigned int computationOptions) {
internal::check_svd_options_assertions<MatrixType, Options>(m_computationOptions); internal::check_svd_options_assertions<MatrixType, Options>(m_computationOptions, matrix.rows(), matrix.cols());
return compute_impl(matrix, computationOptions); return compute_impl(matrix, computationOptions);
} }

View File

@ -37,18 +37,19 @@ constexpr int should_svd_compute_full_u(int options) { return options & ComputeF
constexpr int should_svd_compute_thin_v(int options) { return options & ComputeThinV; } constexpr int should_svd_compute_thin_v(int options) { return options & ComputeThinV; }
constexpr int should_svd_compute_full_v(int options) { return options & ComputeFullV; } constexpr int should_svd_compute_full_v(int options) { return options & ComputeFullV; }
template <typename MatrixType, int Options> template<typename MatrixType, int Options>
void check_svd_options_assertions(unsigned int computationOptions) { void check_svd_options_assertions(unsigned int computationOptions, Index rows, Index cols) {
EIGEN_STATIC_ASSERT((Options & ComputationOptionsBits) == 0, EIGEN_STATIC_ASSERT((Options & ComputationOptionsBits) == 0,
"SVDBase: Cannot request U or V using both static and runtime options, even if they match. " "SVDBase: Cannot request U or V using both static and runtime options, even if they match. "
"Requesting unitaries at runtime is DEPRECATED: " "Requesting unitaries at runtime is DEPRECATED: "
"Prefer requesting unitaries statically, using the Options template parameter."); "Prefer requesting unitaries statically, using the Options template parameter.");
eigen_assert( eigen_assert(!(should_svd_compute_thin_u(computationOptions) && cols < rows && MatrixType::RowsAtCompileTime != Dynamic) &&
!(should_svd_compute_thin_u(computationOptions) && MatrixType::ColsAtCompileTime != Dynamic) && !(should_svd_compute_thin_v(computationOptions) && rows < cols && MatrixType::ColsAtCompileTime != Dynamic) &&
!(should_svd_compute_thin_v(computationOptions) && MatrixType::ColsAtCompileTime != Dynamic) && "SVDBase: If thin U is requested at runtime, your matrix must have more rows than columns or a dynamic number of rows."
"SVDBase: If U or V are requested at runtime, then thin U and V are only available when " "Similarly, if thin V is requested at runtime, you matrix must have more columns than rows or a dynamic number of columns.");
"your matrix has a dynamic number of columns.");
(void)computationOptions; (void)computationOptions;
(void)rows;
(void)cols;
} }
template<typename Derived> struct traits<SVDBase<Derived> > template<typename Derived> struct traits<SVDBase<Derived> >

View File

@ -482,9 +482,9 @@ void svd_compute_checks(const MatrixType& m) {
template <typename SvdType, typename MatrixType> template <typename SvdType, typename MatrixType>
void svd_check_constructor_options(const MatrixType& m, unsigned int computationOptions) { void svd_check_constructor_options(const MatrixType& m, unsigned int computationOptions) {
const bool thinUnitary = (computationOptions & ComputeThinU) != 0 || (computationOptions & ComputeThinV) != 0; const bool fixedRowAndThinU = SvdType::RowsAtCompileTime != Dynamic && (computationOptions & ComputeThinU) != 0 && m.cols() < m.rows();
const bool fixedColAndThinV = SvdType::ColsAtCompileTime != Dynamic && (computationOptions & ComputeThinV) != 0 && m.rows() < m.cols();
if (SvdType::ColsAtCompileTime != Dynamic && thinUnitary) { if (fixedRowAndThinU || fixedColAndThinV) {
VERIFY_RAISES_ASSERT(SvdType svd(m, computationOptions)); VERIFY_RAISES_ASSERT(SvdType svd(m, computationOptions));
return; return;
} }