Unable to compile the example for Eigen SVD
Asked Answered
C

1

8

I am trying to compile the example provided for Eigen::JacobiSVD and I am getting the following error,

/usr/local/include/eigen3/Eigen/src/SVD/JacobiSVD.h: In instantiation of ‘Eigen::JacobiSVD<MatrixType, QRPreconditioner>& Eigen::JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType&, unsigned int) [with _MatrixType = Eigen::Matrix<float, -1, -1>; int QRPreconditioner = 40; Eigen::JacobiSVD<MatrixType, QRPreconditioner>::MatrixType = Eigen::Matrix<float, -1, -1>]’:
/usr/local/include/eigen3/Eigen/src/SVD/JacobiSVD.h:549:14:   required from ‘Eigen::JacobiSVD<MatrixType, QRPreconditioner>::JacobiSVD(const MatrixType&, unsigned int) [with _MatrixType = Eigen::Matrix<float, -1, -1>; int QRPreconditioner = 40; Eigen::JacobiSVD<MatrixType, QRPreconditioner>::MatrixType = Eigen::Matrix<float, -1, -1>]’
demo.cpp:9:55:   required from here
/usr/local/include/eigen3/Eigen/src/SVD/JacobiSVD.h:692:27: error: ‘struct Eigen::internal::qr_preconditioner_impl<Eigen::Matrix<float, -1, -1>, 40, 0, true>’ has no member named ‘run’
     m_qr_precond_morecols.run(*this, m_scaledMatrix);
     ~~~~~~~~~~~~~~~~~~~~~~^~~
/usr/local/include/eigen3/Eigen/src/SVD/JacobiSVD.h:693:27: error: ‘struct Eigen::internal::qr_preconditioner_impl<Eigen::Matrix<float, -1, -1>, 40, 1, true>’ has no member named ‘run’
     m_qr_precond_morerows.run(*this, m_scaledMatrix);

Could you please help me with this? Thanks

Code :

#include <Eigen/Core>
#include <Eigen/SVD>
#include <iostream>
using namespace std;
using namespace Eigen;
int main () {
    MatrixXf m = MatrixXf::Random(3,2);
    cout << "Here is the matrix m:" << endl << m << endl;
    JacobiSVD<MatrixXf, ComputeThinU | ComputeThinV> svd(m);
    cout << "Its singular values are:" << endl << svd.singularValues() << endl;
    cout << "Its left singular vectors are the columns of the thin U matrix:" << endl << svd.matrixU() << endl;
    cout << "Its right singular vectors are the columns of the thin V matrix:" << endl << svd.matrixV() << endl;
    Vector3f rhs(1, 0, 0);
    cout << "Now consider this rhs vector:" << endl << rhs << endl;
    cout << "A least-squares solution of m*x = rhs is:" << endl << svd.solve(rhs) << endl;
}

g++ : 7.5

Eigen : 3.4.0

Cormorant answered 24/6, 2022 at 22:30 Comment(1)
I can reproduce this issue with gcc-11. Looks a lot like a bug. Weird that it is such an obvious issue. I think you should report it on gitlab.com/libeigen/eigen/-/issuesKauai
K
16

This looks very much like a bug. I looked at the code and there is no way it can work. I'll file a bug report.

As a workaround, this should work even though it is marked as deprecated:

JacobiSVD<MatrixXf> svd;
svd.compute(m, ComputeThinU | ComputeThinV);

The underlying issue is that during template-specialization, the code does not separate the Compute options from the QR preconditioner options. So it doesn't find a suitable implementation.

EDIT

The issue is with a disparity between the online documentation and the current release. The documentation is for 3.4.90 but the last released version is 3.4.0.

In 3.4.90 the compute parameters must be declared in either the template or the runtime parameters, but not both.

In 3.4.0 and earlier, the compute options must be declared in the runtime parameters.

// works in all versions but deprecation warning in 3.4.90
Eigen::JacobiSVD<Eigen::MatrixXf> svd;
svd.compute(m, Eigen::ComputeThinV | Eigen::ComputeThinU);
// or
Eigen::JacobiSVD<Eigen::MatrixXf> svd(m, Eigen::ComputeThinV | Eigen::ComputeThinU);

// works in 3.4.90
Eigen::JacobiSVD<Eigen::MatrixXf, Eigen::ComputeThinV | Eigen::ComputeThinU> svd;
svd.compute(m);
Kauai answered 25/6, 2022 at 10:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.