Miłosz Makowski
unread,Feb 3, 2022, 11:28:23 AM2/3/22Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Ceres Solver
Hi,
I am using Eigen for matrix multiplication in Ceres solver.
Suppose I have two matrices, one consists of Jet<double, N>, whereas the other consists of double. When I try to calculate the product of the two matrices, I'm getting a compilation error. In short, the error boils down to an attempt of Jet-to-double conversion.
Here's an example of code that fails to compile:
-------------------------------------
typedef ceres::Jet<double, 2> J;
Eigen::MatrixX<J> A;
A.resize(2, 2);
A << (J)1., (J)1., (J)1., (J)1.;
Eigen::MatrixXd B;
B.resize(2, 2);
B << 1., 1., 1., 1.;
Eigen::MatrixX<J> C;
C.noalias() = A * B;
-------------------------------------
Note, that in this simple case, I could use Matrix2<J> and Matrix2d instead, and it would work fine. However, I need to use matrices of much higher size, so it's not possible to use compilation-time defined size.
What's more, if both of matrices consist of Jets, the example compiles fine. However, for performance reason, I don't want to convert the matrix of doubles to Jets just to make it compile.
It's also worth noting, that the multiplication works, if matrix of Jets is a vector. For now, the workaround I'm using is to just loop over the rows like that:
-------------------------------------
C.resize(A.rows(), B.cols());
for (int i = 0; i < A.rows(); i++) C.row(i).noalias() = A.row(i) * B;
-------------------------------------
It's far from perfect though.
Does anyone know how to solve that issue?
Thanks in advance
P.S.
A fragment of compilation output of the first example looks like this:
*************************************
include/Eigen/src/Core/util/BlasUtil.h:43:79: error: cannot convert 'const ceres::Jet<double, 2>' to 'double' without a conversion operator
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE To run(const From& x) { return To(x); }
include/Eigen/src/Core/GeneralProduct.h:246:66: note: in instantiation of member function 'Eigen::internal::get_factor<ceres::Jet<double, 2>, double>::run' requested here
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
[...]
include/Eigen/src/Core/products/GeneralMatrixMatrix.h:445:7: note: in instantiation of function template specialization 'Eigen::internal::generic_product_impl<Eigen::Matrix<ceres::Jet<double, 2>, -1, -1, 0>, Eigen::Matrix<double, -1, -1, 0>, Eigen::DenseShape, Eigen::DenseShape, 8>::scaleAndAddTo<Eigen::Matrix<ceres::Jet<double, 2>, -1, -1, 0>>' requested here
scaleAndAddTo(dst, lhs, rhs, Scalar(1));
[...]
main.cpp:24:15: note: in instantiation of function template specialization 'Eigen::NoAlias<Eigen::Matrix<ceres::Jet<double, 2>, -1, -1, 0>, Eigen::MatrixBase>::operator=<Eigen::Product<Eigen::Matrix<ceres::Jet<double, 2>, -1, -1, 0>, Eigen::Matrix<double, -1, -1, 0>, 0>>' requested here
[build] C.noalias() = A * B;
*************************************