Skip to content

JacobiSVD fails to compile with vector types

Submitted by Gael Guennebaud @ggael

Assigned to Nobody

Link to original bugzilla bug (#1387)
Version: 3.3 (current stable)

Description

As reported by Ose Pedro:

In JacobiSVD's use of ColPivHouseholderQR when _MatrixType is a dynamic vector. In particular, attempting to compile the following code:
#include "eigen3.3.2/Eigen/Core"
#include "eigen3.3.2/Eigen/SVD"

int main() {
using Vec=Eigen::Matrix<double,Eigen::Dynamic,1>;
Eigen::JacobiSVD<Vec> svd;
return 0;
}
produces the following error:
In file included from eigen3.3.2/Eigen/Core:343:0,
from test.cpp:1:
eigen3.3.2/Eigen/src/Core/PlainObjectBase.h: In instantiation of ‘static void Eigen::PlainObjectBase<Derived>::_check_template_params() [with Derived = Eigen::Matrix<double, 1, -1, 0, 1, -1>]’:
eigen3.3.2/Eigen/src/Core/Matrix.h:261:36: required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix() [with _Scalar = double; int _Rows = 1; int _Cols = -1; int _Options = 0; int _MaxRows = 1; int _MaxCols = -1]’
eigen3.3.2/Eigen/src/SVD/JacobiSVD.h:193:7: required from ‘Eigen::JacobiSVD<MatrixType, QRPreconditioner>::JacobiSVD() [with _MatrixType = Eigen::Matrix<double, -1, 1>; int QRPreconditioner = 2]’
test.cpp:6:25: required from here
eigen3.3.2/Eigen/src/Core/util/StaticAssert.h:32:40: error: static assertion failed: INVALID_MATRIX_TEMPLATE_PARAMETERS
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
^
eigen3.3.2/Eigen/src/Core/PlainObjectBase.h:891:7: note: in expansion of macro ‘EIGEN_STATIC_ASSERT’
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
As you can see, this occurs with Eigen 3.3.2. I attempted to compile it in GCC 4.9.4 in 64-bit Ubuntu 14.04. I've also tried compiling it with Eigen 3.2.0 (i.e. the version provided through the Ubuntu package repository), and I get the same error.

A temporary workaround, for users like me who wish to find an orthogonal basis in which one vector is parallel to a dynamic vector x, is to compute the SVD of a 2-column matrix, where the first column is x and the second column is full of zeros. I.e.:
#include "eigen3/Eigen/Core"
#include "eigen3/Eigen/SVD"
#include <iostream>

int main() {
using Vec=Eigen::Matrix<double,Eigen::Dynamic,1>;
using Mat=Eigen::Matrix<double,Eigen::Dynamic,2>;

Vec x=Eigen::Vector3d(1,2,3).normalized();
Mat x0(x.size(),2);
x0<<x,Eigen::Vector3d::Zero();
Eigen::JacobiSVD<Mat> svd(x0, Eigen::ComputeFullU|Eigen::ComputeFullV);
std::cout<<"x = \n"<<x<<std::endl;
std::cout<<"u = \n"<<svd.matrixU()<<std::endl;
return 0;
}

Edited by Antonio Sánchez