Решение большой разреженной линейной системы методом Холецкого в Эйгене - PullRequest
0 голосов
/ 06 апреля 2019

Я на самом деле пытаюсь решить большую разреженную линейную систему, используя метод Холецкого в Eigen.Я скачал разреженную матрицу (cfd1) с этого сайта .Я попытался решить линейную систему Ax = b, определенную следующим образом: A - это матрица cfd1, b = A * xe, где xe - это вектор единиц с одинаковым размером матрицы и числом строк.В заключение, используя обозначение Matlab, я хотел бы решить: x = A\b.Вот код:

#include <iostream>
#include <Eigen/Dense>
#include <unsupported/Eigen/SparseExtra>
#include<Eigen/SparseCholesky>

using namespace std;
using namespace Eigen;
int main()
{

   SparseMatrix<double> mat;
   VectorXd x;
   loadMarket(mat, "Path of downloaded matrix");

   cout << "Number of Rows:\n" << mat.rows() << endl;

   ArrayXd xe = ArrayXd::Constant(mat.rows(), 1);
   cout << xe << endl;
   SparseVector<double> b = mat*xe;

   SimplicialLLT<SparseMatrix<double> > solver;
   x = solver.compute(mat).solve(b);
   cout << x << endl;



}

Проблема в том, что при компиляции я получаю текущую ошибку:

error: invalid operands to binary expression
      ('SparseMatrix<double>' and 'Eigen::ArrayXd' (aka 'Array<double, Dynamic,
      1>'))
   SparseVector<double> b = mat*xe;
                            ~~~^~~
/Users/anto/Desktop/example/eigen-eigen-323c052e1731/Eigen/src/SparseCore/../plugins/CommonCwiseBinaryOps.h:50:29:
note: 
      candidate function template not viable: no known conversion from
      'Eigen::ArrayXd' (aka 'Array<double, Dynamic, 1>') to 'const
      Eigen::SparseMatrixBase<Eigen::SparseMatrix<double, 0, int>
      >::StorageBaseType' (aka 'const
      Eigen::SparseMatrixBase<Eigen::SparseMatrix<double, 0, int> >') for 2nd
      argument

Может кто-нибудь помочь мне исправить это?

1 Ответ

0 голосов
/ 06 апреля 2019

Две вещи:

  • Нельзя смешивать Array и Matrix в выражениях продукта, т. Е. Заменить ArrayXd на VectorXd.
  • Произведение разреженной матрицы на плотный вектор, как правило, плотное, поэтому вам нужно присвоить произведение плотной VectorXd вместо SparseVector

следующие компиляции

SparseMatrix<double> mat;
loadMarket(mat, "Path of downloaded matrix");

cout << "Number of Rows:\n" << mat.rows() << endl;

VectorXd xe = VectorXd::Constant(mat.rows(), 1);
cout << xe << endl;
VectorXd b = mat*xe;

SimplicialLLT<SparseMatrix<double> > solver;
VectorXd x = solver.compute(mat).solve(b);
cout << x << endl;
...