zl程序教程

您现在的位置是:首页 >  工具

当前栏目

Eigen库学习(五)块运算

学习 运算 Eigen
2023-09-27 14:27:31 时间

eigen中的矩阵块(block)既可以作为左值也可以作为右值,就和普通表达式一样,经过编译器优化能够达到运行时达到0抽象成本。

一、使用块运算

eigen中最常使用的块操作是block()方法,该方法有两种形式:

说明动态块形式固定块形式
从(i,j)开始的大小为(p,q)的块matrix.block(i,j,p,q)matrix.block<p,q>(i,j)

matrix和array都有该方法。
注:如果总的大小<16,推荐使用fix-size以提高效率。

#include <Eigen/Dense>
#include <iostream>
 
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 << "Block in the middle" << endl;
  cout << m.block<2,2>(1,1) << endl << endl;
  for (int i = 1; i <= 3; ++i)
  {
    cout << "Block of size " << i << "x" << i << endl;
    cout << m.block(0,0,i,i) << endl << endl;
  }
}

eigen库在运行时知道的信息越多,就越有可能进行优化。

二、行列块运算

主要就是两个:row和col方法。

块运算方法
第i行matrix.row(i)
第j行matrix.col(j)
#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 adding 3 times the first column into the third column, the matrix m is:\n";
  cout << m << endl;
}

三、边角块元素

前面说到的选取要么是一行,要么是一列。我们可以根据方位来进行选取,如左上角数 p × q p\times q p×q矩阵matrix.toLeftCorner(p,q)或者另外一种形式matrix.toLeftCorner<p,q>();再如左边起前 p p p列:matrix.leftCols(p),也可以写成固定块运算matrix.bo

块运算动态块运算固定块运算
Top-left p by q block *matrix.topLeftCorner(p,q)matrix.topLeftCorner<p,q>()
Bottom-left p by q block *matrix.bottomLeftCorner(p,q)matrix.bottomLeftCorner<p,q>()
Top-right p by q block *matrix.topRightCorner(p,q)matrix.topRightCorner<p,q>()
Bottom-right p by q block *matrix.bottomRightCorner(p,q)matrix.bottomRightCorner<p,q>()
Block containing the first q rows *matrix.topRows(q)matrix.topRows<q>()
Block containing the last q rows *matrix.bottomRows(q)matrix.bottomRows<q>()
Block containing the first p columns *matrix.leftCols (p)matrix.leftCols<p>()
Block containing the last q columns *matrix.rightCols(q)matrix.rightCols<q>()
#include <Eigen/Dense>
#include <iostream>
 
using namespace std;
 
int main()
{
  Eigen::Matrix4f m;
  m << 1, 2, 3, 4,
       5, 6, 7, 8,
       9, 10,11,12,
       13,14,15,16;
  cout << "m.leftCols(2) =" << endl << m.leftCols(2) << endl << endl;
  cout << "m.bottomRows<2>() =" << endl << m.bottomRows<2>() << endl << endl;
  m.topLeftCorner(1,3) = m.bottomRightCorner(3,1).transpose();
  cout << "After assignment, m = " << endl << m << endl;
}

四、vector的块运算

块运算动态块运算固定块运算
Block containing the first n elements *vector.head(n)vector.head<n>()
Block containing the last n elements *vector.tail(n)vector.tail<n>()
Block containing n elements, starting at position i *vector.segment(i,n)vector.segment<n>(i)
#include <Eigen/Dense>
#include <iostream>
 
using namespace std;
 
int main()
{
  Eigen::ArrayXf v(6);
  v << 1, 2, 3, 4, 5, 6;
  cout << "v.head(3) =" << endl << v.head(3) << endl << endl;
  cout << "v.tail<3>() = " << endl << v.tail<3>() << endl << endl;
  v.segment(1,4) *= 2;
  cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl;
}