Reputation: 7310
I want to rewrite to C++ eig function from Matlab:
[V,D] = eig(A,B) produces a diagonal matrix D of generalized
eigenvalues and a full matrix V whose columns are the corresponding
eigenvectors so that A*V = B*V*D.
I get positive results for Matrix4d class:
pair<Matrix4d, Vector4d> eig(const Matrix4d& A, const Matrix4d& B)
{
const Eigen::GeneralizedSelfAdjointEigenSolver<Matrix4d> solver(A, B);
const Matrix4d V = solver.eigenvectors();
const Vector4d D = solver.eigenvalues();
return pair<Matrix4d, Vector4d>(V, D);
}
The problem I face now is that eig in Matlab is capable of using complex numbers - what I need in my algorithm.
How can I change it to receive same/very similar effect with usage of Matrix4cd class instead of Matrix4d?
Upvotes: 0
Views: 1688
Reputation: 10596
If you don't/can't use auto
in davidhigh's solution try this
std::pair<Matrix4cd, Vector4d> eig(const Matrix4cd& A, const Matrix4cd& B)
{
Eigen::GeneralizedSelfAdjointEigenSolver<Matrix4cd> solver(A, B);
Matrix4cd V = solver.eigenvectors();
Vector4d D = solver.eigenvalues();
return std::make_pair(V, D);
}
Upvotes: 1
Reputation: 15468
Replace the MatrixXd
by the complex version of it, Matrix4cd
(which is actually a shortcut for Matrix< std::complex < double >, Dynamic, 4 >
, see here):
std::pair<Matrix4cd, Vector4d> eig(const Matrix4cd& A, const Matrix4cd& B)
{
Eigen::GeneralizedSelfAdjointEigenSolver<Matrix4cd> solver(A, B);
Matrix4cd V = solver.eigenvectors();
Vector4d D = solver.eigenvalues();
return std::make_pair(V, D);
}
This is it already. Note however that you cannot pass arbitrary matrices, but the matrix A
needs to be self-adjoint (also called hermitian) and B
needs to be positive definite.
EDIT: thanks to the comment by @AviGinsburg, I corrected the mistake that the eigenvalues are real (and thus should be mapped to a real Eigen vector). Here is a C++14 implementation which gets around this problem (and so supports my stupidity ;-) ):
auto eig(const Matrix4cd& A, const Matrix4cd& B)
{
Eigen::GeneralizedSelfAdjointEigenSolver<Matrix4cd> solver(A, B);
auto V = solver.eigenvectors();
auto D = solver.eigenvalues();
return std::make_pair(V, D);
}
Upvotes: 2