将上矩阵Xd复制到下矩阵Xd(特征3)C++库
Copying upper MatrixXd to lower MatrixXd (Eigen3) C++ library
我有一个下三角矩阵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
但我还不能得到我想要的。。。
这里我假设您指的是使用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
时的结果相同。只是不需要复制原始矩阵中的值来使其自伴随。
如果selfattaintView不适合您,解决方案是在目标矩阵上使用triangularView:
m.triangularView<Lower>() = m.transpose();
我能想到的最简单的方法是复制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
谨致问候。
简单地说:
m = m.selfadjointView<Upper>();
我认为你的做法是正确的。如果您知道矩阵中数据的内存布局的一些细节,则可以使用一些低级优化。其中一种技术是循环平铺。
如果速度是个大问题,我不会复制任何东西,只会用坐标反转对象来装饰/包装矩阵对象,该对象会将(x,y)翻转为(y,x)。如果您将()运算符设为内联函数,则在使用它时不会产生任何重大成本。
这是有效的,你可以切割一些东西,但你需要至少n*m/2(更少的东西),所以只有2倍的
edit:我看到你使用了这个matrixd对象。。。语法不同,但算法是这样的,不管怎样
#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 );
}