2
0
mirror of https://gitlab.com/libeigen/eigen.git synced 2025-04-24 19:40:45 +08:00

Fix SVD for MSVC.

This commit is contained in:
Antonio Sánchez 2022-02-28 19:53:15 +00:00 committed by Rasmus Munk Larsen
parent 19c39bea29
commit f03df0df53
6 changed files with 44 additions and 37 deletions

@ -75,7 +75,7 @@ struct allocate_small_svd<MatrixType, 0> {
*
* \tparam MatrixType_ the type of the matrix of which we are computing the SVD decomposition
*
* \tparam Options this optional parameter allows one to specify options for computing unitaries \a U and \a V.
* \tparam Options_ this optional parameter allows one to specify options for computing unitaries \a U and \a V.
* Possible values are #ComputeThinU, #ComputeThinV, #ComputeFullU, #ComputeFullV.
* It is not possible to request both the thin and full version of \a U or \a V.
* By default, unitaries are not computed.
@ -93,8 +93,8 @@ struct allocate_small_svd<MatrixType, 0> {
*
* \sa class JacobiSVD
*/
template <typename MatrixType_, int Options>
class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options> > {
template <typename MatrixType_, int Options_>
class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options_> > {
typedef SVDBase<BDCSVD> Base;
public:
@ -104,17 +104,19 @@ public:
using Base::computeV;
typedef MatrixType_ MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef typename Base::Scalar Scalar;
typedef typename Base::RealScalar RealScalar;
typedef typename NumTraits<RealScalar>::Literal Literal;
enum {
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
DiagSizeAtCompileTime = internal::min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime),
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
MaxDiagSizeAtCompileTime = internal::min_size_prefer_fixed(MaxRowsAtCompileTime, MaxColsAtCompileTime),
MatrixOptions = MatrixType::Options
Options = Options_,
RowsAtCompileTime = Base::RowsAtCompileTime,
ColsAtCompileTime = Base::ColsAtCompileTime,
DiagSizeAtCompileTime = Base::DiagSizeAtCompileTime,
MaxRowsAtCompileTime = Base::MaxRowsAtCompileTime,
MaxColsAtCompileTime = Base::MaxColsAtCompileTime,
MaxDiagSizeAtCompileTime = Base::MaxDiagSizeAtCompileTime,
MatrixOptions = Base::MatrixOptions
};
typedef typename Base::MatrixUType MatrixUType;

@ -510,23 +510,24 @@ struct traits<JacobiSVD<MatrixType_, Options> > : svd_traits<MatrixType_, Option
*
* \sa MatrixBase::jacobiSvd()
*/
template <typename MatrixType_, int Options>
class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options> > {
template <typename MatrixType_, int Options_>
class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
typedef SVDBase<JacobiSVD> Base;
public:
typedef MatrixType_ MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef typename Base::Scalar Scalar;
typedef typename Base::RealScalar RealScalar;
enum {
Options = Options_,
QRPreconditioner = internal::get_qr_preconditioner(Options),
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
DiagSizeAtCompileTime = internal::min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime),
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
MaxDiagSizeAtCompileTime = internal::min_size_prefer_fixed(MaxRowsAtCompileTime, MaxColsAtCompileTime),
MatrixOptions = MatrixType::Options
RowsAtCompileTime = Base::RowsAtCompileTime,
ColsAtCompileTime = Base::ColsAtCompileTime,
DiagSizeAtCompileTime = Base::DiagSizeAtCompileTime,
MaxRowsAtCompileTime = Base::MaxRowsAtCompileTime,
MaxColsAtCompileTime = Base::MaxColsAtCompileTime,
MaxDiagSizeAtCompileTime = Base::MaxDiagSizeAtCompileTime,
MatrixOptions = Base::MatrixOptions
};
typedef typename Base::MatrixUType MatrixUType;
@ -591,7 +592,7 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options> > {
* \deprecated Will be removed in the next major Eigen version. Options should
* be specified in the \a Options template parameter.
*/
EIGEN_DEPRECATED
// EIGEN_DEPRECATED // TODO(cantonios): re-enable after fixing a few 3p libraries that error on deprecation warnings.
JacobiSVD(const MatrixType& matrix, unsigned int computationOptions) {
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
compute_impl(matrix, computationOptions);
@ -655,9 +656,9 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options> > {
"JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "
"Use the ColPivHouseholderQR preconditioner instead.")
template <typename MatrixType__, int Options_, bool IsComplex_>
template <typename MatrixType__, int Options__, bool IsComplex_>
friend struct internal::svd_precondition_2x2_block_to_be_real;
template <typename MatrixType__, int Options_, int QRPreconditioner_, int Case_, bool DoAnything_>
template <typename MatrixType__, int Options__, int QRPreconditioner_, int Case_, bool DoAnything_>
friend struct internal::qr_preconditioner_impl;
internal::qr_preconditioner_impl<MatrixType, Options, QRPreconditioner, internal::PreconditionIfMoreColsThanRows>

@ -32,10 +32,10 @@ constexpr int get_qr_preconditioner(int options) { return options & QRPreconditi
constexpr int get_computation_options(int options) { return options & ComputationOptionsBits; }
constexpr int should_svd_compute_thin_u(int options) { return options & ComputeThinU; }
constexpr int should_svd_compute_full_u(int options) { return options & ComputeFullU; }
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 bool should_svd_compute_thin_u(int options) { return (options & ComputeThinU) != 0; }
constexpr bool should_svd_compute_full_u(int options) { return (options & ComputeFullU) != 0; }
constexpr bool should_svd_compute_thin_v(int options) { return (options & ComputeThinV) != 0; }
constexpr bool should_svd_compute_full_v(int options) { return (options & ComputeFullV) != 0; }
template<typename MatrixType, int Options>
void check_svd_options_assertions(unsigned int computationOptions, Index rows, Index cols) {
@ -61,8 +61,9 @@ template<typename Derived> struct traits<SVDBase<Derived> >
enum { Flags = 0 };
};
template <typename MatrixType, int Options>
template <typename MatrixType, int Options_>
struct svd_traits : traits<MatrixType> {
static constexpr int Options = Options_;
static constexpr bool ShouldComputeFullU = internal::should_svd_compute_full_u(Options);
static constexpr bool ShouldComputeThinU = internal::should_svd_compute_thin_u(Options);
static constexpr bool ShouldComputeFullV = internal::should_svd_compute_full_v(Options);

@ -106,7 +106,8 @@ void msvc_workaround()
{
const Foo::Bar a;
const Foo::Bar b;
std::max EIGEN_NOT_A_MACRO (a,b);
const Foo::Bar c = std::max EIGEN_NOT_A_MACRO (a,b);
EIGEN_UNUSED_VARIABLE(c)
}
EIGEN_DECLARE_TEST(jacobisvd)

@ -113,9 +113,8 @@ void svd_least_square(const MatrixType& m) {
RhsType rhs = RhsType::Random(rows, internal::random<Index>(1, cols));
SvdType svd(m);
if (internal::is_same<RealScalar, double>::value)
svd.setThreshold(1e-8);
else if(internal::is_same<RealScalar,float>::value) svd.setThreshold(2e-4);
if (internal::is_same<RealScalar, double>::value) svd.setThreshold(RealScalar(1e-8));
else if(internal::is_same<RealScalar,float>::value) svd.setThreshold(RealScalar(2e-4));
SolutionType x = svd.solve(rhs);

@ -64,8 +64,11 @@ void svd_fill_random(MatrixType &m, int Option = 0)
}
Matrix<Scalar,Dynamic,1> samples(9);
samples << 0, four_denorms<RealScalar>(),
-RealScalar(1)/NumTraits<RealScalar>::highest(), RealScalar(1)/NumTraits<RealScalar>::highest(), (std::numeric_limits<RealScalar>::min)(), pow((std::numeric_limits<RealScalar>::min)(),0.8);
samples << Scalar(0), four_denorms<RealScalar>(),
-RealScalar(1)/NumTraits<RealScalar>::highest(),
RealScalar(1)/NumTraits<RealScalar>::highest(),
(std::numeric_limits<RealScalar>::min)(),
pow((std::numeric_limits<RealScalar>::min)(), RealScalar(0.8));
if(Option==Symmetric)
{