Этот вопрос относится к cast from Eigen::CwiseBinaryOp to MatrixXd causes segfault. Вероятно, это будет простое решение, как первое.Как отслеживать объекты Eigen посредством решения()?
В этом минимальном примере я определяю Holder
, который содержит и собственную матрицу, и возвращает его через функцию-член get()
. Точно так же, Decomp
это шаблон выражение для разложения LDLT этой матрицы, а Solve
решает для AX = B, получая X.
#include <Eigen/Dense>
#include <Eigen/Cholesky>
template <class EigenType> class Holder {
public:
typedef EigenType result_type;
private:
result_type in_;
public:
Holder(const EigenType& in) : in_(in) {}
const result_type& get() const { return in_; }
};
template <class Hold> class Decomp {
public:
typedef typename Eigen::LDLT
<typename Eigen::MatrixBase<typename Hold::result_type>::PlainObject>
result_type;
private:
Hold mat_;
public:
Decomp(const Hold& mat) : mat_(mat) {}
result_type get() const { return mat_.get().ldlt(); }
};
template <class Derived, class OtherDerived> class Solve {
public:
typedef typename Eigen::internal::solve_retval
<typename Derived::result_type, typename OtherDerived::result_type>
result_type;
private:
Derived decomp_;
// typename Derived::result_type decomp_;
OtherDerived mat_;
public:
Solve(const Derived& decomp, const OtherDerived& mat)
: decomp_(decomp), mat_(mat) {}
//: decomp_(decomp.get()), mat_(mat) {}
result_type get() const { return decomp_.get().solve(mat_.get()); }
// result_type get() const { return decomp_.solve(mat_.get()); }
};
typedef Holder<Eigen::MatrixXd> MatrixHolder;
typedef Decomp<MatrixHolder> MatrixDecomp;
typedef Solve<MatrixDecomp, MatrixHolder> SimpleSolve;
Следующий тест терпит неудачу на X.get()
#include "Simple.h"
#include <Eigen/Dense>
#include <iostream>
int main(int, char * []) {
MatrixHolder A(Eigen::MatrixXd::Identity(3, 3));
MatrixHolder B(Eigen::MatrixXd::Random(3, 2));
MatrixDecomp ldlt(A);
SimpleSolve X(ldlt, B);
std::cout << X.get() << std::endl;
return 0;
}
, но если использовать прокомментированные строки в файле заголовка, все работает нормально. К сожалению, это переводит оценку разложения на конструкцию решателя, что не подходит для моего использования. Как правило, я хочу построить сложное выражение expr
с участием этого Solve
и позвонить по телефону expr.get()
позже.
Как я могу решить эту проблему? Существует ли общее правило, чтобы избежать дальнейших связанных вопросов?
Думаю, было бы разумнее сохранить это в классе Decomp. А как насчет обобщения? Когда я должен хранить? Когда я должен проходить как const ref? – yannick
Я имел в виду * магазин * как const ref vs store как значение. – yannick
Право, я упростил пример и прокомментировал общее правило в приведенном выше ответе. – ggael