Преобразование Eigen :: SparseMatrix & lt; double & gt; to deal.ii :: SparseMatrix & lt; double & gt ;?

Это своего рода неясный вопрос, и я не ожидаю, что кто-нибудь ответит, но у меня есть этот метод, который принимает (и возвращает) 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;
}

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

2

Решение

Этот вопрос старый, но, возможно, я все еще могу помочь. Я один из разработчиков сделки. Я не помню, чтобы я видел это в списке рассылки (который гораздо более активен для подобных вопросов, чем 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-подобный формат, где запись на главной диагонали сначала сохраняется в массиве, содержащем записи матрицы для этой строки, поэтому нам действительно нужно копировать с интерфейсами итератора ,

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]