> 文章列表 > [Eigen中文文档] 块操作

[Eigen中文文档] 块操作

嘿,别被那些矩阵和块操作吓到,它们其实比你的高中代数还要友好!Eigen的块操作就像是你从披萨上切下一小块,既可以直接吃掉(读取),也可以再放点料(赋值)。关键点在于,不论你切的披萨是固定大小还是动态大小,Eigen都能帮你搞定,而且还能让编译器在背后偷偷优化,速度快到让你怀疑人生!

问题来了:什么时候该用固定大小的块操作,什么时候用动态的呢?简单!如果你知道你要切的披萨块大小(比如2x2),那就用固定大小的版本,因为它在编译时就能优化好,速度更快。但如果披萨块的大小是动态的(比如用户决定的),那就用动态版本,灵活应对各种情况。

另外,块操作不仅仅是读取,还可以赋值!就像你可以在披萨的某一片上放上更多的配料,Eigen也允许你在矩阵的某个块上进行赋值操作。这在处理局部数据时特别有用,比如修改图片的某个区域或调整数据矩阵中的特定部分。

现在,你已经掌握了Eigen的块操作精髓,赶紧去试试吧!想象一下,你的代码正在优雅地切割矩阵,就像在切割一块美味的披萨。编程的乐趣,不就在于此吗?

[Eigen中文文档] 块操作

文档总目录

本文目录

      • 使用块操作
      • 列和行
      • 关于角的操作
      • 向量的块操作

英文原文(Block operations)

本文介绍了块操作。块是matrixarray的部分矩形元素。块表达式既可以用作右值也可以用作左值。与Eigen表达式一样,如果让编译器进行优化,则块操作的运行时间成本为零。

使用块操作

在Eigen中最常见的块操作是.block() ,这有两个版本,语法如下:

块操作 构建一个动态大小的块表达式 构建一个固定大小的块表达式
大小为 (p,q), 起始于 (i,j)的块 matrix.block(i,j,p,q); matrix.block<p,q>(i,j);

Eigen的索引是以0开始的。

这两个版本都可以用在固定大小和动态大小的matricesarray上。两种表达式在语义上是一致的,唯一的区别是,固定大小的版本会在块比较小的时候快一点,但要求块大小在编译的时候就知道。

以下程序使用动态大小和固定大小版本打印matrix中的几个块:

#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;}
}

输出如下:

Block in the middle6  7
10 11Block of size 1x1
1Block of size 2x2
1 2
5 6Block of size 3x31  2  35  6  79 10 11

在上述的例子中.block()函数被用作右值,即它只被读取。但块也可以用作左值,这意味着可以给块赋值。

以下示例中进行了说明。此示例还演示了数组中的块,其工作方式与上面演示的矩阵中的块完全相同。

#include <Eigen/Dense>
#include <iostream>int main()
{Eigen::Array22f m;m << 1,2,3,4;Eigen::Array44f a = Eigen::Array44f::Constant(0.6);std::cout << "Here is the array a:\\n" << a << "\\n\\n";a.block<2,2>(1,1) = m;std::cout << "Here is now a with m copied into its central 2x2 block:\\n" << a << "\\n\\n";a.bloc