将上层MatrixXd复制到较低的MatrixXd(Eigen3)C ++库

时间:2012-08-22 13:52:48

标签: c++ eigen eigenvector eigenvalue

我有一个下三角形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

但我还不能得到我想要的东西......

7 个答案:

答案 0 :(得分:4)

我在这里假设您指的是使用Eigen3 c ++库。您的问题并不清楚。如果没有,你应该考虑它。在任何情况下,在Eigen内,不需要实际复制三角形部分,以获得自相关矩阵。 Eigen具有视图的概念,您可以使用self adjoint view来执行类似的操作。

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的结果相同。只是没有必要复制原始矩阵中的值以使其自我连接。

答案 1 :(得分:3)

如果selfadjointView不是您的选项,解决方案是在目标矩阵上使用triangularView:

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

答案 2 :(得分: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

问候。

答案 3 :(得分:1)

我认为你正在以正确的方式做到这一点。如果您了解矩阵中数据的内存布局的一些细节,则可以使用一些低级优化。其中一项技术是loop tiling

答案 4 :(得分:1)

如果速度是一个大问题,我不会复制任何东西只是装饰/包装矩阵对象与坐标反转对象,将(x,y)翻转为(y,x)。如果你使()运算符成为一个内联函数,当你使用它时不会产生任何重大的代价。

答案 5 :(得分:1)

简单地:

m = m.selfadjointView<Upper>();

答案 6 :(得分:0)

这很有效,你可以削减一些东西,但你需要至少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 );
}