Type error in ternary operator in Eigen
I am making a class in C ++ to generalize two sparse matrix solvers (SparseLU and Sparse Cholesky). When I try to use the ternary operator, it says that the types of the operands are not compatible, but if I use the If statement, the code compiles.
Error 2: the operand types are not compatible ("const Eigen :: Solve <Eigen :: SimplicialLDLT <Eigen :: SparseMatrix <double, 0, int>, 1, Eigen :: AMDOrdering <int →, Eigen :: Matrix <double, -1 , 1, 0, -1, 1 → "and" const Eigen :: Solve <Eigen :: SparseLU <Eigen :: SparseMatrix <double, 0, int>, Eigen :: COLAMDOrdering <int →, Eigen :: Matrix <double , -1, 1, 0, -1, 1 → ")
eigen::VectorXd solve(eigen::VectorXd &b) {
return is_cholesky ? cholesky.solve(b) : lu.solve(b); // ERROR
}
X
eigen::VectorXd solve(eigen::VectorXd &b) {
if (is_cholesky) {
return cholesky.solve(b);
}
else {
return lu.solve(b);
}
}
All code:
#pragma once
#ifndef SOLVER_H
#define SOLVER_H
#include <Eigen/Core>
#include <Eigen/Sparse>
#include <Eigen/SparseLU>
#include <Eigen/SparseCholesky>
#define eigen Eigen
class Solver {
private:
bool is_cholesky;
eigen::SimplicialLDLT<eigen::SparseMatrix<double>> cholesky;
eigen::SparseLU<eigen::SparseMatrix<double>> lu;
public:
Solver(bool is_choleski) {
this->is_cholesky = is_choleski;
}
eigen::ComputationInfo info() {
return is_cholesky ? cholesky.info() : lu.info();
}
void compute(eigen::SparseMatrix<double> &B) {
is_cholesky ? cholesky.compute(B) : lu.compute(B);
}
eigen::VectorXd solve(eigen::VectorXd &b) {
return is_cholesky ? cholesky.solve(b) : lu.solve(b); // ERROR HERE
}
};
#endif // SOLVER_H
source to share
The rules for expressing a type a ? b : c
require that it be either the type of the expression b
or the type of the expression c
.
Here it cholesky.solve(b)
has a type other than lu.solve(b)
, and has no implicit conversion to something else. The fact that the resulting expression needs to be converted to eigen::VectorXd
is ignored. Thus, the error "the types of the operands are incompatible".
return is_cholesky ? cholesky.solve(b) : lu.solve(b); // ERROR
Here, every expression must have a conversion to eigen::VectorXd
that exists.
if (is_cholesky) {
return cholesky.solve(b);
}
else {
return lu.solve(b);
}
You can force the type of the expression ?:
into eigen::VectorXd
by specifying it explicitly, eg.
return is_cholesky ? eigen::VectorXd{ cholesky.solve(b) } : lu.solve(b);
source to share