определить и заполнить разреженную матрицу, используя Eigen Library в C ++ - PullRequest
0 голосов
/ 16 сентября 2018

Я пытаюсь построить матрицу лонжеронов с использованием библиотеки Eigen или Armadillo в C ++ для решения системы линейных уравнений Ax = b. A - матрица коэффициентов с размерностью n * n, а B - вектор правой части с размерностью n Матрица лонжеронов А выглядит следующим образом, см. Рисунок

Я посмотрел документ Eigen, но у меня проблема с определением и заполнением матрицы Spars в C ++.

Не могли бы вы дать пример кода, чтобы определить матрицу лонжеронов и как заполнить значения в матрице, используя библиотеку Eigen в c ++?

рассмотрим, например, простую матрицу лонжеронов A:

1 2 0 0

0 3 0 0

0 0 4 5

0 0 6 7

int main()
{
     SparseMatrix<double> A;

     // fill the A matrix ????

     VectorXd b, x;
     SparseCholesky<SparseMatrix<double> > solver;
     solver.compute(A);

     x = solver.solve(b);
     return 0;
} 

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Поскольку этот вопрос также задает вопрос о Armadillo , здесь приведен соответствующий код на основе Armadillo. Лучше всего использовать Armadillo версии 9.100+ или более поздней и связываться с SuperLU.

#include <armadillo>

using namespace arma; 

int main()
{
  sp_mat A(4,4);   // don't need to explicitly reserve the number of non-zeros

  // fill with direct element access
  A(0,0) = 1.0;
  A(0,1) = 2.0;
  A(1,1) = 3.0;
  A(2,2) = 4.0;
  A(2,3) = 5.0;
  A(3,2) = 6.0;
  A(3,3) = 7.0;  // etc

  // or load the sparse matrix from a text file with the data stored in coord format
  sp_mat AA;
  AA.load("my_sparse_matrix.txt", coord_ascii)

  vec b; // ... fill b here ...

  vec x = spsolve(A,b);  // solve sparse system

  return 0;
}

См. Также документацию для SpMat , доступ к элементу , .load () , spsolve () .

Формат файла координат прост. Он хранит ненулевые значения. Каждая строка содержит:

row col value

Количество строк и столбцов начинается с нуля. Пример:

  0 0 1.0
  0 1 2.0
  1 1 3.0
  2 2 4.0
  2 3 5.0
  3 2 6.0
  3 3 7.0
  1000 2000 9.0

Значения, не указанные явно, предполагаются равными нулю.

0 голосов
/ 16 сентября 2018

Разреженная матрица может быть заполнена значениями, упомянутыми в посте, с помощью функции-члена .coeffRef(), как показано в этой подпрограмме:

SparseMatrix<double> fillMatrix() {
  int N = 4;
  int M = 4;
  SparseMatrix<double> m1(N,M);
  m1.reserve(VectorXi::Constant(M, 4)); // 4: estimated number of non-zero enties per column
  m1.coeffRef(0,0) = 1;
  m1.coeffRef(0,1) = 2.;
  m1.coeffRef(1,1) = 3.;
  m1.coeffRef(2,2) = 4.;
  m1.coeffRef(2,3) = 5.;
  m1.coeffRef(3,2) = 6.;
  m1.coeffRef(3,3) = 7.;
  m1.makeCompressed();
  return m1;
}

Однако модуль SparseCholesky (SimplicialCholesky<SparseMatrix<double> >) в этом случае не будет работать, поскольку матрица не является эрмитовой. Система может быть решена с помощью решателя LU или BiCGStab. Также обратите внимание, что размеры x и b должны быть определены: VectorXd b(A.rows()), x(A.cols());

В случае больших разреженных матриц вы также можете посмотреть на функцию .reserve(), чтобы выделить память перед заполнением элементов. Функцию .reserve() можно использовать для оценки количества ненулевых записей на столбец (или строку, в зависимости от порядка хранения. По умолчанию используется значение comumn-major). В приведенном выше примере эта оценка равна 4, но она не имеет смысла в такой маленькой матрице. В документации говорится, что предпочтительно переоценивать количество ненулевых элементов в столбце .

...