Возвращаемое значение решателя Eigen Sparse LU

У меня проблема со следующим фрагментом кода, после некоторых исследований я выделил проблему в отдельную строку, но теперь не уверен, как ее решить.

typedef double ComplexType;

typedef std::complex<ComplexType> Complex;

typedef Eigen::SparseMatrix<Complex, Eigen::ColMajor, long long> SparseMatrixT; 

typedef Eigen::SparseVector<Complex, Eigen::ColMajor, long long> SparseVectorC;

typedef Eigen::SparseLU<SparseMatrixT, Eigen::COLAMDOrdering< long long>> SolverT;


SparseVectorC Solve(const Eigen::Ref<const SparseVectorC>& Rhs)
{
    auto _Result = m_LU.solve(Rhs); //SolverT m_LU; defined and "prepared" elsewhere

    SparseVectorC Result = _Result; // cause error C2512

    return Result;
}

ошибка показывает

\eigen\src\core\solve.h(125): ошибка C2512: 'Eigen::internal::evaluator‹ Eigen::SparseVector‹ Complex,0, long long > >': нет подходящего конструктора по умолчанию

Как я могу получить результат в векторе Sparse или Dense (поскольку он не должен быть разреженным, в отличие от Rhs). Размер матрицы (может быть) огромен, поэтому дополнительная копия была бы неприятной.
Переменная _Result, по-видимому, разрежена, однако ни присваивания (с приведением или без приведения) к разреженному или плотному вектору (с использованием доступного метода toDense(), который наверное сделать копию) не работает.


person Michael Medvinsky    schedule 05.11.2016    source источник


Ответы (1)


Несмотря на то, что SparseLU::solve принимает разреженные матрицы в качестве правых, для них нет специального пути, потому что, как вы также заметили, в большинстве случаев результат все равно определяется. Итак, внутренне, если rhs является разреженной матрицей, она внутренне преобразуется в плотные векторы до фактического решения. Затем числовые нули отбрасываются, чтобы вывести разреженную матрицу. Так что в вашем случае лучше скопировать Rhs в VectorXcd и пусть Solve тоже вернет плотное VectorXcd.

Чтобы ответить на ошибку компиляции, это проблема в Eigen (Edit: исправлено в наборе изменений 80c2b4346260). Если вы все еще хотите придерживаться разреженных правых и результатов, вы можете обойти это, заменив Ref<const SparseVectorC> на Ref<const SparseMatrixT>. Не будет никаких накладных расходов по сравнению с использованием SparseVectorC.

person ggael    schedule 05.11.2016