二重要素を持つものから複雑な要素を持つ Eigen3 行列を導出する状況があります。現時点では、行と列をループして、エントリを 1 つずつ入力します。誰かが次のようなアプローチを知っているかどうか疑問に思っていました:
complexMatrix = doubleMatrix.unaryExpr(transform)
Eigen には、castと呼ばれる演算子があります。テンプレートのせいで宣言が恐ろしく見えますが、使い方は至ってシンプルです。
これはうまくいくはずだと思います
complexMatrix = doubleMatrix.cast< std::complex<double> >();
編集、うーん、わかりました...これを行う方法があります。ドキュメントに例があります: http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html#a23fc4bf97168dee2516f85edcfd4cfe7
ただし、適切な型を取得するには、結合して関数化する必要があると私は信じていますcast
。
complexMatrix = doubleMatrix.cast< std::complex<double> >().unaryExpr( FUNCTOR );
もちろん、ファンクターは複合Scalar
型で動作するように設計されていることが期待されています。fnc_ptr
例に示すように、単純な関数でラッパーを使用することもできます。
注: double を受け入れて複素数を返す functor クラスを使用する場合はスキップできる可能性がcast
ありますが、すぐには実行できませんでした。それは難しいでしょう。cast
また、実際のオーバーヘッドが発生しない可能性があるため、必要もないと思います。
編集:作業例。
x
から前後に 2 回変換するdouble
ことで多少のオーバーヘッドが発生しcomplex
ますが、実際のファンクター本体と比較すると無視できると思います。
#include <Eigen/Core>
#include <iostream>
using namespace Eigen;
using namespace std;
std::complex<double> functor(double x){
//complicated stuff
return std::complex<double> (x, -2*x) ;
}
std::complex<double> wrapper(std::complex<double> x)
{
//nothing is lost here, as we expect x to have only real part
//from being upcasted from the original matrix
double xReal = x.real();
return functor(xReal);
}
int main(int, char**)
{
Matrix4d m1 = Matrix4d::Random();
cout << m1 << endl << "becomes: " << endl
<< m1.cast< std::complex<double> >().unaryExpr(ptr_fun(wrapper)) << endl;
return 0;
}
unaryExpr はファンクターから戻り値の型を推測できるため、次のことができます。
#include <Eigen/Core>
std::complex<double> functor(double x){
return std::complex<double> (-x, x) ;
}
int main(int, char**)
{
Eigen::Matrix3d m1 = Eigen::Matrix3d::Random();
Eigen::Matrix3cd m2 = m1.unaryExpr(std::ptr_fun(functor));
}
そしてファンクタークラスで:
#include <Eigen/Core>
struct Functor {
typedef std::complex<double> result_type;
std::complex<double> operator()(double x) const {
return std::complex<double> (-x, x) ;
}
};
int main(int, char**)
{
Eigen::Matrix3d m1 = Eigen::Matrix3d::Random();
Eigen::Matrix3cd m2 = m1.unaryExpr(Functor());
}