[Eigen中文文档] 块操作
嘿,别被那些矩阵和块操作吓到,它们其实比你的高中代数还要友好!Eigen的块操作就像是你从披萨上切下一小块,既可以直接吃掉(读取),也可以再放点料(赋值)。关键点在于,不论你切的披萨是固定大小还是动态大小,Eigen都能帮你搞定,而且还能让编译器在背后偷偷优化,速度快到让你怀疑人生!
问题来了:什么时候该用固定大小的块操作,什么时候用动态的呢?简单!如果你知道你要切的披萨块大小(比如2x2),那就用固定大小的版本,因为它在编译时就能优化好,速度更快。但如果披萨块的大小是动态的(比如用户决定的),那就用动态版本,灵活应对各种情况。
另外,块操作不仅仅是读取,还可以赋值!就像你可以在披萨的某一片上放上更多的配料,Eigen也允许你在矩阵的某个块上进行赋值操作。这在处理局部数据时特别有用,比如修改图片的某个区域或调整数据矩阵中的特定部分。
现在,你已经掌握了Eigen的块操作精髓,赶紧去试试吧!想象一下,你的代码正在优雅地切割矩阵,就像在切割一块美味的披萨。编程的乐趣,不就在于此吗?
文档总目录
本文目录
-
-
- 使用块操作
- 列和行
- 关于角的操作
- 向量的块操作
-
英文原文(Block operations)
本文介绍了块操作。块是matrix
或array
的部分矩形元素。块表达式既可以用作右值也可以用作左值。与Eigen表达式一样,如果让编译器进行优化,则块操作的运行时间成本为零。
使用块操作
在Eigen中最常见的块操作是.block()
,这有两个版本,语法如下:
块操作 | 构建一个动态大小的块表达式 | 构建一个固定大小的块表达式 |
---|---|---|
大小为 (p,q) , 起始于 (i,j) 的块 |
matrix.block(i,j,p,q); | matrix.block<p,q>(i,j); |
Eigen的索引是以0开始的。
这两个版本都可以用在固定大小和动态大小的matrices
和array
上。两种表达式在语义上是一致的,唯一的区别是,固定大小的版本会在块比较小的时候快一点,但要求块大小在编译的时候就知道。
以下程序使用动态大小和固定大小版本打印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