将本征矩阵转换为C数组
本征库可以将现有内存映射到本征矩阵。
float array[3];
Map(array, 3).fill(10);
int data[4] = 1, 2, 3, 4;
Matrix2i mat2x2(data);
MatrixXi mat2x2 = Map(data);
MatrixXi mat2x2 = Map(data, 2, 2);
我的问题是,如何从特征矩阵(例如Matrix3f m)中获得c数组(例如float [] a)? 本征矩阵的实际布局是什么? 真实数据是否存储在普通c数组中?
lil asked 2020-01-20T01:19:50Z
6个解决方案
53 votes
您可以使用Eigen Matrix类的data()成员函数。 默认情况下,布局是多列的,而不是多维C数组的行(在创建Matrix对象时可以选择布局)。 对于稀疏矩阵,前面的句子显然不适用。
例:
ArrayXf v = ArrayXf::LinSpaced(11, 0.f, 10.f);
// vc is the corresponding C array. Here's how you can use it yourself:
float *vc = v.data();
cout << vc[3] << endl; // 3.0
// Or you can give it to some C api call that takes a C array:
some_c_api_call(vc, v.size());
// Be careful not to use this pointer after v goes out of scope! If
// you still need the data after this point, you must copy vc. This can
// be done using in the usual C manner, or with Eigen's Map<> class.
janneb answered 2020-01-20T01:20:22Z
15 votes
将普通数据类型转换为本征矩阵类型
double *X; // non-NULL pointer to some data
您可以使用Map功能创建nRows x nCols大小的双精度矩阵,如下所示:
MatrixXd eigenX = Map( X, nRows, nCols );
将本征矩阵类型转换为普通数据类型
MatrixXd resultEigen; // Eigen matrix with some result (non NULL!)
double *resultC; // NULL pointer
Map( resultC, resultEigen.rows(), resultEigen.cols() ) = resultEigen;
这样,您可以进入和退出特征矩阵。 完整的学分归[http://dovgalecs.com/blog/eigen-how-to-get-in-and-out-data-from-eigen-matrix/]
GPrathap answered 2020-01-20T01:20:56Z
3 votes
您需要再次使用地图功能。 请在此处查看示例:[http://forum.kde.org/viewtopic.php?f=74&t=95457]
Prashanth answered 2020-01-20T01:21:16Z
3 votes
如果数组是二维的,则需要注意存储顺序。 默认情况下,Eigen按列优先顺序存储矩阵。 但是,将数组直接转换为本征矩阵需要行大顺序。 如果此类转换在代码中频繁执行,则使用相应的typedef可能会有所帮助。
using namespace Eigen;
typedef Matrix RowMatrixXi;
有了这样的定义,就可以以一种简单而紧凑的方式从一个数组中获得一个本征矩阵,同时保留原始数组的顺序。
从C数组到Eigen :: Matrix
int nrow = 2, ncol = 3;
int arr[nrow][ncol] = { {1 ,2, 3}, {4, 5, 6} };
Map eig(&arr[0][0], nrow, ncol);
std::cout << "Eigen matrix:\n" << eig << std::endl;
// Eigen matrix:
// 1 2 3
// 4 5 6
在相反的方向上,可以使用eig将本征矩阵的元素直接转换为C型数组。
从Eigen :: Matrix到C数组
int arr2[nrow][ncol];
Map(&arr2[0][0], nrow, ncol) = eig;
std::cout << "C array:\n";
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
std::cout << arr2[i][j] << " ";
}
std::cout << "\n";
}
// C array:
// 1 2 3
// 4 5 6
请注意,在这种情况下,原始矩阵eig不需要存储在行占主导的布局中。 在Map中指定行主要顺序就足够了。
RHertel answered 2020-01-20T01:21:58Z
1 votes
尝试时使用Map上面的segfaults解决方案(请参阅上面的评论)。
相反,这是一个对我有用的解决方案,将数据从Eigen :: Matrix复制到std :: vector中。 我在向量中预分配了空间来存储Map / copy的结果。
Eigen::MatrixXf m(2, 2);
m(0, 0) = 3;
m(1, 0) = 2.5;
m(0, 1) = -1;
m(1, 1) = 0;
cout << m << "\n";
// Output:
// 3 -1
// 2.5 0
// Segfaults with this code:
//
// float* p = nullptr;
// Eigen::Map<:matrixxf>(p, m.rows(), m.cols()) = m;
// Better code, which also copies into a std::vector:
// Note that I initialize vec with the matrix size to begin with:
std::vector vec(m.size());
Eigen::Map<:matrixxf>(vec.data(), m.rows(), m.cols()) = m;
for (const auto& x : vec)
cout << x << ", ";
cout << "\n";
// Output: 3, 2.5, -1, 0
eraoul answered 2020-01-20T01:22:23Z
-2 votes
ComplexEigenSolver < MyMatrix > es;
complex *eseig;
es.compute(H);
es.eigenvalues().transpose();
eseig=(complex *)es.eigenvalues().data();
user3097951 answered 2020-01-20T01:22:38Z