Преобразование Eigen::SparseMatrix<double> в deal.ii:: SparseMatrix<double>?

Это своего рода неясный вопрос, и я не ожидаю, что кто-нибудь ответит, но у меня есть этот метод, который принимает (и возвращает) Eigen:: SparseMatrix. Я хочу поместить его в библиотеку deal.ii, есть ли способ скопировать / преобразовать SparseMatrix из deal.ii/Eigen? Я знаю, что вы можете скопировать deal.ii в Trilinos SparseMatrix примерно так:

  `SparseMatrix<double> matrix(sparsity);
...//fill matrix

  Epetra_Map map(TrilinosWrappers::types::int_type(5),
                 TrilinosWrappers::types::int_type(5),
                 0,
                 Utilities::Trilinos::comm_world());

  TrilinosWrappers::SparseMatrix tmatrix;
  tmatrix.reinit (map, map, matrix, 0, false);`    

Есть ли аналогичный способ Eigen:: SparseMatrix? Я полагаю, что Эйген на самом деле не имеет такой поддержки в сделке. Так что, возможно, есть какой-то метод типа "грубой силы", такой как эта попытка кода, который явно не работает:

`

Eigen::SparseMatrix<double> ConvertToEigenMatrix(SparseMatrix<double> data)
{
    Eigen::SparseMatrix<double> eMatrix(data.m(), data.n());
    for (int i = 0; i < data.m(); ++i)
        eMatrix.row(i) =  Eigen::SparseMatrix<double> ::Map(&data[i][0], data.n());
    return eMatrix; 

`

Итак, я разобрался, как конвертировать из dealii::SparseMatrix -> Eigen::SparseMatrix.

  SparseMatrix<double>::iterator smi = matrix.begin();
  SparseMatrix<double>::iterator smi_end = matrix.end();

  unsigned int row,col;
  double val;
  for (; smi!=smi_end; ++smi)
  {
       row = smi->row();
       col = smi->column();
       val = smi->value();

       spMat.insert(row, col) = val; 
       std::cout << val << std::endl; 
  }

Нет, мне просто нужно выяснить обратное.

1 ответ

Решение

Этот вопрос старый, но, возможно, я все еще могу помочь. Я один из разработчиков сделки. Я не помню, чтобы я видел это в списке рассылки (который гораздо более активен для подобных вопросов, чем SO).

SparseMatrix в deal.II не хранит свой собственный шаблон разреженности: вместо этого он хранит указатель на SparsityPattern объект. Вам нужно будет дважды обойти собственную матрицу: один раз, чтобы настроить SparsityPattern и второй раз для копирования значений матрицы. Кажется, работает что-то вроде следующего:

#include <deal.II/lac/dynamic_sparsity_pattern.h>
#include <deal.II/lac/sparsity_pattern.h>
#include <deal.II/lac/sparse_matrix.h>

#include <eigen3/Eigen/Sparse>

#include <iostream>

int main()
{
  const std::size_t shape = 3;
  Eigen::SparseMatrix<double> matrix(shape, shape);
  matrix.insert(0, 0) = 1.0;
  matrix.insert(0, 1) = 2.0;
  matrix.insert(0, 2) = 1.0;
  matrix.insert(2, 2) = 2.0;
  matrix.makeCompressed();

  {
    dealii::SparsityPattern sparsity_pattern(matrix.rows(), matrix.cols());
    dealii::DynamicSparsityPattern dynamic_sparsity_pattern(matrix.rows(), matrix.cols());

    for (decltype(matrix.outerSize()) row_n = 0; row_n < matrix.outerSize(); ++row_n)
      for (Eigen::SparseMatrix<double>::InnerIterator it(matrix, row_n); it; ++it)
        dynamic_sparsity_pattern.add(it.row(), it.col());

    sparsity_pattern.copy_from(dynamic_sparsity_pattern);
    dealii::SparseMatrix<double> matrix2(sparsity_pattern);

    for (decltype(matrix.outerSize()) row_n = 0; row_n < matrix.outerSize(); ++row_n)
      for (Eigen::SparseMatrix<double>::InnerIterator it(matrix, row_n); it; ++it)
        matrix2.set(it.row(), it.col(), it.value());

    matrix2.print(std::cout); // prints the right matrix
  }
}

Вам придется управлять временем жизни SparsityPattern объект тоже.

deal.II не использует CSR или CSC: он использует свой собственный CSR-подобный формат, где запись на главной диагонали сначала сохраняется в массиве, содержащем записи матрицы для этой строки, поэтому нам действительно нужно копировать с интерфейсами итератора,

Другие вопросы по тегам