6

下三角行列MatrixXdがあり、対称行列になるので、下の値を上にコピーしたいと思います。どうすればいいですか?

これまでのところ、私は次のことを行いました。

 MatrixXd m(n,n); 
 .....
 //do something with m
 for(j=0; j < n; j++)
       {
         for(i=0; i<j; i++)
           {
             m(i,j) = m(j,i);

           }
       }

それを行うための最速の方法はありますか?下三角行列を上に「コピー」できる内部メソッドを考えていました。私がこの行列を持っているとしましょう、私たちは次のように呼びますm

1 2 3
4 5 6
7 8 9

私が取得する必要があるのmは:

1 4 7
4 5 8
7 8 9

また、マトリックスの上部または下部に何かを実行させることができることも知っています。

MatrixXd m1(n,n);
 m1 = m.triangularView<Eigen::Upper>();
cout << m1 <<endl;

1 2 3
0 5 6
0 0 9

しかし、私はまだ私が欲しいものを手に入れることができません...

4

7 に答える 7

4

ここでは、Eigen3c ++ライブラリの操作について言及していると想定しています。これはあなたの質問からは明らかではありません。そうでない場合は、それを検討する必要があります。いずれにせよ、Eigen内では、自己結合行列を取得するために、三角形の部分を実際にコピーする必要はありません。Eigenにはビューの概念があり、たとえば次のような操作を実行するために自己随伴ビューを使用できます。

using namespace Eigen;
MatrixXd m(m,n);
...
(generate uppper triangular entries in m)
...
VectorXd r(n), p(n);
r = m.selfadjointView<Upper>() * p;

これは、固定サイズの行列の使用を説明するための小さな例です。

#include <Eigen/Core>

using namespace std;
using namespace Eigen;

int main()
{
    Matrix2d m,c;
    m << 1, 2,
         0, 1;

    Vector2d x(0,2), r;

    // perform copy operation 
    c = m.selfadjointView<Upper>(); 
    cout << c << endl;

    // directly apply selfadjoint view in matrix operation
    // (no entries are copied)
    r = m.selfadjointView<Upper>() * x;
} 

出力は[1、2、2、1]になります。これで、の結果は、代わりにr使用した場合と同じになります。c * x元の行列の値をコピーして自己結合させる必要がないというだけです。

于 2012-08-23T08:16:16.877 に答える
4

selfadjointViewがオプションではない場合、解決策は宛先マトリックスでtriangleViewを使用することです。

m.triangularView<Lower>() = m.transpose();

于 2012-09-02T09:20:19.517 に答える
2

私が考えることができる最も簡単な方法は、上部に転置されたm行列の上部をコピーすることです。

    m.triangularView<Upper>() = m.transpose();

たとえば、次のコードです。

    MatrixXd m(3,3);
    m << 1, 2, 3, 4, 5, 6, 7, 8, 9;

    m.triangularView<Upper>() = m.transpose();
    std::cout << m << std::endl;

要求した出力を提供します。

1 4 7
4 5 8
7 8 9

よろしく。

于 2014-04-09T15:35:36.023 に答える
2

単に:

m = m.selfadjointView<Upper>();
于 2017-11-07T20:10:35.743 に答える
1

私はあなたがそれを正しい方法でやっていると思います。マトリックス内のデータのメモリレイアウトに関する詳細を知っている場合は、低レベルの最適化を使用できます。テクニックの1つはループタイリングです。

于 2012-08-22T14:25:45.670 に答える
1

速度が大きな問題である場合、(x、y)を(y、x)に反転する座標反転オブジェクトでマトリックスオブジェクトを装飾/ラップするだけでは何もコピーしません。()演算子をインライン関数にすると、使用時に大きなコストが発生することはありません。

于 2012-08-22T14:25:51.210 に答える
-1

これは機能します。何かをカットすることはできますが、少なくともn * m / 2(何かが少ない)が必要なので、2倍だけです。

編集:このマトリックス化されたオブジェクトを使用しているようです...構文は異なりますが、アルゴリズムはとにかくこれです

#include <stdio.h>


int main ( )
{
    int mat [ 4 ] [ 4 ];
    int i, j;

    mat [ 0 ] [ 0 ] = 0;
    mat [ 0 ] [ 1 ] = 1;
    mat [ 0 ] [ 2 ] = 2;
    mat [ 0 ] [ 3 ] = 3;
    mat [ 1 ] [ 0 ] = 4;
    mat [ 1 ] [ 1 ] = 5;
    mat [ 1 ] [ 2 ] = 6;
    mat [ 1 ] [ 3 ] = 7;
    mat [ 2 ] [ 0 ] = 8;
    mat [ 2 ] [ 1 ] = 9;
    mat [ 2 ] [ 2 ] = 10;
    mat [ 2 ] [ 3 ] = 11;
    mat [ 3 ] [ 0 ] = 12;
    mat [ 3 ] [ 1 ] = 13;
    mat [ 3 ] [ 2 ] = 14;
    mat [ 3 ] [ 3 ] = 15;

    for ( i = 0; i < 4; i++ )
    {
        for ( j = 0; j < 4; j++ )
            printf ( "%02d", mat [ i ] [ j ] );
        printf ( "\n" );
    }
    printf ( "\n" );

    for ( i = 1; i < 4; i++ )
    {
        for ( j = 0; j < i; j++ )
            mat [ j ] [ i ] = mat [ i ] [ j ];
    }

    for ( i = 0; i < 4; i++ )
    {
        for ( j = 0; j < 4; j++ )
            printf ( "%02d ", mat [ i ] [ j ] );
        printf ( "\n" );
    }
    printf ( "\n" );

    scanf ( "%d", &i );
}
于 2012-08-22T14:18:33.953 に答える