【C++】Eigen入门之密集矩阵 4 - 块操作

参考:https://blog.csdn.net/whereismatrix/article/details/104431596

简介

EigenMatrix/Array提供了.block()来进行block区块操作,这是面向系数提供的操作功能。

语法

Eigen中提供了2种语法,产生的结果是一致的。但存在性能上的不同,任何时候,使用fixed-size模式都会得到更好地性能优化。

分类语法说明
dynamic-sizematrix.block(i,j,p,q);执行时才知道维度大小(p,q)
fixed-sizematrix.block<p,q>(i,j);编译时指定维度大小(p,q)

解释区块的维度大小尺寸:(p,q)起始的位置:(i,j)。同样的,位置索引从0开始。

查看一个简单的示例:

//matrix_block1.cpp

#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
using namespace std;

int main()
{
  Eigen::MatrixXf m(4,4);
  m <<  1, 2, 3, 4,
        5, 6, 7, 8,
        9,10,11,12,
       13,14,15,16;
  
  cout << "matrix m:" << endl << m <<endl<<endl;

  cout<<"-----------------"<<endl;

  cout << "Block in the middle -- m.block<2,2>(1,1)" << endl;
  cout << m.block<2,2>(1,1) << endl << endl;

  cout<<"-----------------"<<endl;
  
  for (int i = 1; i <= 3; ++i)
  {
    cout << "Get from (0,0), Block of size " << i << "x" << i << endl;
    cout << m.block(0,0,i,i) << endl << endl;
  }

  cout<<"-----------------"<<endl;

  for (int i = 1; i <= 3; ++i)
  {
    cout << "Get from (1,1), Block of size " << i << "x" << i << endl;
    cout << m.block(1,1,i,i) << endl << endl;
  }
}

执行的结果:

$ g++   -I /usr/local/include/eigen3 matrix_block1.cpp -o matrix_block1
$ 
$ ./matrix_block1 

matrix m:
 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15 16

-----------------
Block in the middle -- m.block<2,2>(1,1)
 6  7
10 11

-----------------
Get from (0,0), Block of size 1x1
1

Get from (0,0), Block of size 2x2
1 2
5 6

Get from (0,0), Block of size 3x3
 1  2  3
 5  6  7
 9 10 11

-----------------
Get from (1,1), Block of size 1x1
6

Get from (1,1), Block of size 2x2
 6  7
10 11

Get from (1,1), Block of size 3x3
 6  7  8
10 11 12
14 15 16

block()不仅可以用于右值,也可以用于左值。下面来个Array的简单示例:

//matrix_block2.cpp

#include <Eigen/Dense>
#include <iostream>

using namespace std;
using namespace Eigen;

int main()
{
  Array22f m;
  m << 1,2,
       3,4;

  Array44f a = Array44f::Constant(0.6);
  cout << "Here is the array a:" << endl << a << endl << endl;

  a.block<2,2>(1,1) = m;
  cout << "Here is now a with m copied into its central 2x2 block:" << endl << a << endl << endl;
  
  a.block(0,0,2,3) = a.block(2,1,2,3);
  cout << "Here is now a with bottom-right 2x3 block copied into top-left 2x2 block:" << endl << a << endl << endl;
}

此示例中,在一个4X4的常量二维数组中,修改(2,2,1,1)区块的系数,此次修改操作对应大小指定为1X1了,取值来源区块为2X2数组。

执行结果如下,最后划线的部分是最后一次block区块替换的部分:

$ g++   -I /usr/local/include/eigen3 matrix_block2.cpp -o matrix_block2
$
$ ./matrix_block2
Here is the array a:
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6

Here is now a with m copied into its central 2x2 block:
0.6 0.6 0.6 0.6
0.6   1   2 0.6
0.6   3   4 0.6
0.6 0.6 0.6 0.6

Here is now a with bottom-right 2x3 block copied into top-left 2x2 block:
  3   4 0.6 0.6
-----------
0.6 0.6 0.6 0.6
-----------
0.6   3   4 0.6
0.6 0.6 0.6 0.6

行和列的操作

单个的行或者列操作是block的一种特殊形式,Eigen中提供了更好地API方法col(), row()

matrix.row(i) : 第 i 行;
matrix.col(j) : 第 j 列;

示例:

//matrix_block3.cpp
#include <Eigen/Dense>
#include <iostream>

using namespace std;

int main()
{
  Eigen::MatrixXf m(3,3);
  m << 1,2,3,
       4,5,6,
       7,8,9;
  cout << "Here is the matrix m:" << endl << m << endl;
  
  cout << "2nd Row: " << m.row(1) << endl;

  m.col(2) += 3 * m.col(0);
  cout << "After m.col(2) += 3 * m.col(0), the matrix m is:\n";
  cout << m << endl;
}

执行:

$ g++   -I /usr/local/include/eigen3 matrix_block3.cpp -o matrix_block3
promote:eigen david$ ./matrix_block3
Here is the matrix m:
1 2 3
4 5 6
7 8 9
2nd Row: 4 5 6
After m.col(2) += 3 * m.col(0), the matrix m is:
 1  2  6
 4  5 18
 7  8 30

边角操作

有时候,需要对矩阵的边角进行操作。Matrix提供了对应的方法函数,可以很变量地进行操作。

target动态固定尺寸
左上matrix.topLeftCorner(p,q);matrix.topLeftCorner<p,q> ();
左下matrix.bottomLeftCorner(p,q);matrix.bottomLeftCorner<p,q> ();
右上matrix.topRightCorner(p,q);matrix.topRightCorner<p,q> ();
右上matrix.bottomRightCorner(p,q);matrix.bottomRightCorner<p,q> ();
顶部q行matrix.topRows(q);matrix.topRows ();
底部q行matrix.bottomRows(q);matrix.bottomRows ();
左边p列matrix.leftCols§;matrix.leftCols()
右边p列matrix.rightCols(q);matrix.rightCols ();

向量的block块操作

针对向量、一维数组,Eigen还提供了一组特别的块操作。

操作Dynamic 模式fixed_size 模式
头部n个vector.head(n);vector.head();
尾部n个vector.tail(n);vector.tail();
自i起始的n个vector.segment(i,n);vector.segment(i);

示例:

//matrix_block4.cpp

#include <Eigen/Dense>
#include <iostream>

using namespace std;

int main()
{
  Eigen::ArrayXf v(6);
  v << 1, 2, 3, 4, 5, 6;

  Eigen::ArrayXf vv = v.head(3) ;
  cout << "v.head(3) =" << endl << vv << endl << endl;

  Eigen::ArrayXf vvv = v.tail<3>() ;
  cout << "v.tail<3>() = " << endl << vvv << endl << endl;

  v.segment(1,4) *= 2;
  cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl;
}

执行:

$ g++   -I /usr/local/include/eigen3 matrix_block4.cpp -o matrix_block4
promote:eigen david$ ./matrix_block4
v.head(3) =
1
2
3

v.tail<3>() = 
4
5
6

after 'v.segment(1,4) *= 2', v =
 1
 4
 6
 8
10
 6
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值