3

少し前に、ユーザーggaelが eigen::vectorXf を eigen::matrixXf にマッピングする問題に答えました。

今、私は似たようなことをする必要がありますが、既存のマトリックスに対して、例えば私はできることを知っています:

for(int i=0;i<p;++i){
    VectorXf vec=q.col(i);
    /*q is a p**2 by n matrix*/ 
    Map<MatrixXf> qi(vec.data(),p,p);
    /*run function that uses qi to produce a scalare and store that scalar*/
}

qiしかし(私には思えます)ループの外側で一度だけ作成し、同じものqiを何度も使用する方が効率的です(そうですか?)

また、マッピング先の中間ステップが本当に必要なのだろうq.col(i)vec...

最近の回答では、次のことを提案しています。

qi=Map<MatrixXd>(vec.data(),p,p);

しかし、それを行うと、次のようになります。

In function ‘Eigen::VectorXi DepType(const MatrixXf&, const MatrixXf&, const int&)’:
DeC.cpp:279:34: error: no matching function for call to ‘Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >::Map(Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar*, int&, int&)’
DeC.cpp:279:34: note: candidates are:
/eigen/Eigen/src/Core/Map.h:179:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*, Eigen::Map<MatrixType, MapOptions, StrideType>::Index = long int]
/home/kaveh/Desktop/work/p1/geqw4/vi3/out/sp/ccode/eigen/Eigen/src/Core/Map.h:179:12: note:   no known conversion for argument 1 from ‘Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar* {aka float*}’ to ‘double*’
/eigen/Eigen/src/Core/Map.h:166:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*, Eigen::Map<MatrixType, MapOptions, StrideType>::Index = long int]
/eigen/Eigen/src/Core/Map.h:166:12: note:   no known conversion for argument 1 from ‘Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar* {aka float*}’ to ‘double*’
/eigen/Eigen/src/Core/Map.h:154:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*]
/eigen/Eigen/src/Core/Map.h:154:12: note:   candidate expects 2 arguments, 3 provided
/eigen/Eigen/src/Core/Map.h:119:79: note: Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >::Map(const Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >&)
/eigen/Eigen/src/Core/Map.h:119:79: note:   candidate expects 1 argument, 3 provided

たとえば、Eigenqiベクトルだと考えているようです ....:(

4

1 に答える 1

9

以下:

qi=Map<MatrixXd>(vec.data(),p,p);

Map(vec.data(),p,p) の係数を qi によって参照される行列にコピーすることを意味します。ただし、実際に必要なのは Map<> オブジェクトを再初期化することです。これを行うには、C++ の新しい構文を構築して、コンストラクターを再度呼び出す必要があります。

new (&qi) Map<MatrixXd>(vec.data(),p,p);

さらに、Map<> オブジェクトは非常に軽量であると言わざるを得ません。スタックに静的に割り当てられるのは、1 つのポインターと 2 つの整数のみです。そのため、 Map<> qi の宣言をループの外に移動しても、パフォーマンスにはまったく影響しません。一方、q.col(i) を一時バッファーにコピーする必要がないことに注意してください。q が列優先の場合、次のように直接実行できます。

Map<MatrixXf> qi(q.col(i).data(),p,p);
于 2013-01-10T18:37:37.430 に答える