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

      

+1


source to share


1 answer


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);

      

+4


source







All Articles