2017-06-12 20 views
0

Iを繰り返し要素なし、VectorXd形態で対称行列の内容を返し、次のシグネチャベクタライズ対称行列

VectorXd vectorize (const MatrixXd&); 

と機能を記述したいと思います。例えば、

int n = 3; // n may be much larger in practice. 
MatrixXd sym(n, n); 
sym << 9, 2, 3, 
     2, 8, 4, 
     3, 4, 7; 

std::cout << vectorize(sym) << std::endl; 

は返す必要があります:

9 
2 
3 
8 
4 
7 

vec内の要素の順序は、それが体系的で提供し、重要ではありません。私の目的にとって重要なことは、symのデータを繰り返し要素なしで返すことです。なぜなら、symは常に対称であるとみなされるからです。つまり、symの上三角「ビュー」の要素をVectorXdという形式で返したいと考えています。

vectorizeはネストされたforループで実装されていますが、この機能はプログラム内で頻繁に呼び出されることがあります(100万回以上)。私の質問はこうです:vectorizeを書くのに最も計算効率の良い方法は何ですか?私はEigenのtriangularViewを使用したいと考えていましたが、私はどのように見えません。

ありがとうございます。

+1

あなたは 'TriangularView'と' Map'を使う必要があるようです。 – TriskalJM

+1

この機能要求は関連しています:http://eigen.tuxfamily.org/bz/show_bug.cgi?id=42(別の方法として、特にコメント2を参照してください。多かれ少なかれ手動で、しかし)。 – chtz

答えて

1

効率について、あなたは列方向(したがって、ベクトル化)してforループの単一を書くことができコピー:実際には

VectorXd res(mat.rows()*(mat.cols()+1)/2); 
Index size = mat.rows(); 
Index offset = 0; 
for(Index j=0; j<mat.cols(); ++j) { 
    res.segment(offset,size) = mat.col(j).tail(size); 
    offset += size; 
    size--; 
} 

、私は、コンパイラは、すでに完全にあなたのネストされたループをベクトル化、ひいてはスピードことを期待大体同じでなければなりません。

+0

あなたの答えをありがとう。私は小さな間違いを編集しました: 'size - 'は 'offset + = size'の後に来るべきです。 – tmnol

+0

'int'の代わりに' Index'を使っている理由を説明してください。以前使用した 'Index'クラスは見たことがありません。 – tmnol

+2

@tmnol 'Eigen :: Index'(デフォルトでは)は' std :: ptrdiff_t'のtypedefです。これは64ビットのplattformの64ビット整数です。 – chtz