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