2016-08-08 21 views
4

私は、ランタイムパフォーマンスが絶対的に重要な(リアルタイム制約を満たす必要がある)私が取り組んでいるプロジェクトにEigenを使用しています。Eigen:効率的なKroneckerプロダクト

これまでのところ、Eigenはかなり良いパフォーマンスを示しています。しかし、私はクロネッカー製品を評価する必要があります。私はEigenのサポートされていないKroneckerProductモジュールを使用していますが、私のニーズには最適ではないと考えています。

2つの行列私は、固定サイズ(コンパイル時に知られています)と構造を持つクロネッカー製品を計算しています。 1つの行列は正方行列で、対角行列です。それがIdentity行列であるとします。もう1つは小さな正方形の行列です。コードでは、このような:

MatrixXf I = MatrixXf::Identity(4,4); 
MatrixXf X = MatrixXf::Random(8,8); 
MatrixXf P = kroneckerProduct(I,X); 

私は我々だけ多くなるので、すべての要素を(計算するためにスカラー乗算で4行列を評価する必要があるため、我々はこれより早く作ることができることを、私は推測してい対角線であるので、ゼロである)。

Eigenでこれを行う最も迅速かつ効率的な方法は何ですか?

答えて

5

Eigen 3.3ベータでは、sparse Kronecker products(サポートされていない)サポートが追加されました。つまり、パフォーマンスが重要であれば、3.3ベータに移行することはまだ勧められません。さらに、Iが対角行列であることが分かっている場合は、自分自身でより良いパフォーマンスを得ることができます。さらに、サイズがコンパイル時にわかっていて大きすぎない場合は、MatrixXfMatrix4f(固定サイズで、ヒープではなくスタックに割り当てられます)に置き換えることができます。だから、一緒にそれをすべてロールバックし、あなたが得る:

Matrix4f I4 = Matrix4f::Identity(); 
MatrixXf P2(I4.rows() * X.rows(), I4.cols() * X.cols()); 
P2.setZero(); 

for (int i = 0; i < I4.RowsAtCompileTime; i++) 
{ 
    P2.block(i*X.rows(), i*X.cols(), X.rows(), X.cols()) = I4(i, i) * X; 
} 
+0

スピードアップ。私たちはRowsAtCompileTimeを参照しているので、コンパイラがそのループをアンロールできると仮定していますか? -march = native -mtune = native -O3(私はclang ++を使用しています)以外にどのオプションを使用する必要がありますか? – NOP

+0

'RowsAtCompileTime'を使用すると、コンパイラがループをアンロールするのに役立ちます。スピードアップは、対角線全体を計算するのではなく、ブロック全体を計算するだけであることから推測されます。アンロールされたループはおそらく実際にはスピードアップに寄与しません。この場合、I4.rows()が同じ定数になることは確かです。また、 'X'を固定サイズの行列にしてみてください。 –

-2

MatrixXfを継承し、I、X、Pの3つの行列を含むクラスを作成することを考えています。 Pは、サイズがPの2つの行列を含む構造体です。それらのうちの1つは、マトリックスの内容はブールになり、もう1つは製品と同じになります。

class MatrixXfExample : public MatrixXf { 

MatrixXf I,X; 
MatrixXfPair Data; 
} 

struct MatrixXfPair { 
MatrixXf Visited,Contant; 
} 

MatrixXfPairコンストラクタはVisitedをfalseに初期化し、コンテンツを単独(デフォルト)のままにします。

MatrixXfExampleコンストラクタは、デフォルトでコピーコンストラクタとデータでI、Xを開始します。

これで、Data.Visitedの内容がfalseであるかどうかを確認し、以前に計算されていない場合のみ複数の計算を行うようにoverrideするだけです。 (コードをコンパイルするというアイデアは、それを使用する場合にのみ実装してください)。

+0

これは実際には合理的に提供し、私は私はあなたが言っているものをフォローわからないんだけど、それはただ単純にクロネッカー積を計算するよりも、より効率的なようだ... – NOP