Eigen子矩阵操作
1 子矩阵操作简介
子矩阵操作又称块操作,在矩阵运算中,子矩阵的提取和操作应用也十分广泛。因此Eigen中也提供了相关操作的方法。提取的子矩阵在操作过程中既可以用作左值也可以用作右值。
2 块操作的一般使用方法
在Eigen中最基本的快操作运算是用.block()
完成的。提取的子矩阵同样分为动态大小和固定大小。
|块操作|构建动态大小子矩阵|构建固定大小子矩阵|
|:-|:-|
|提取块大小为(p,q),起始于(i,j)|matrix.block(i,j,p,q)
|matrix.block<p,q>(i,j)
|
同样需要注意的是在Eigen中,索引是从0开始。所有的操作方法都可以适用于Array.同样使用固定大小的操作方式在小型矩阵运算时更加的快,但要求在编译时就要知道矩阵的大小。
下面是一个使用示例:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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 middle
6 7
10 11
Block of size 1x1
1
Block of size 2x2
1 2
5 6
Block of size 3x3
1 2 3
5 6 7
9 10 11
上面的示例中,.block()
被应用为左值操作,即从中读取数据。事实上,它也可以被用作为右值操作,即也可往里面写入数据。下面是一个右值应用实例。
#include <iostream>
#include "Eigen/Dense"
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;
}
执行结果如下:
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中还为一些常用的特殊操作提供了特殊的函数。从运行速度的方面来看,你应该在编译阶段尽可能的提供更多的信息。比如,如果你需要操作的块是一个列,那么你可以使用.col()
函数。这样Eigen可以得知这个信息以便进行更多的优化。
这些特殊操作方法总结如下。
3 行子式和列子式
我们可以使用.col()
和.row()
方法来操作或者提取一个列或者行。
块操作 | 方法 |
---|---|
第i行 | matrix.row(i); |
第j列 | matrix.col(j); |
下面是一个使用示例:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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 third column,the matrix m is:\n";
cout<<m<<endl;
}
执行结果如下:
Here is the matrix m:
1 2 3
4 5 6
7 8 9
2nd Row:4 5 6
After adding 3 times the first column into third column,the matrix m is:
1 2 6
4 5 18
7 8 30
4 边角子矩阵
Eigen提供了从边角开始提取子矩阵的方法,比如.topLeftCorner()
表示从左上角开始提取子矩阵。这些操作总结如下:
块操作 | 动态矩阵版本 | 固定矩阵版本 |
---|---|---|
左上角pxq | matrix.topLeftCorner(p,q); |
matrix.topLeftCorner<p,q>(); |
左下角pxq | matrix.bottomLeftCorner(p,q); |
matrix.bbottomLeftCorner<p,q>(); |
右上角pxq | matrix.topRightCorner(p,q); |
matrix.topRightCorner<p,q>(); |
右下角pxq | matrix.bottomRightCorner(p,q); |
matrix.bottomRightCorner<p,q>(); |
前p行 | matrix.topRows(p); |
matrix.topRows<p>(); |
后p行 | matrix.bottomRows(p); |
matrix.bottomRows<p>(); |
前q列 | matrix.leftCols(q); |
matrix.leftCols<q>(); |
后q列 | matrix.rightCols(q); |
matrix.rightCols<q>(); |
下面是一个使用示例:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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;
}
执行结果如下:
m.leftCols(2)=
1 2
5 6
9 10
13 14
m.bottomRows<2>()=
9 10 11 12
13 14 15 16
After assignment,m=
8 12 16 4
5 6 7 8
9 10 11 12
13 14 15 16
5 向量的子向量操作
Eigen中同样也为向量提供了一些子式的操作方法,总结如下:
块操作 | 固定向量版本 | 动态向量版本 |
---|---|---|
前n个元素 | vector.head(n); |
vector.head<n>(); |
后n个元素 | vector.tail(n); |
vector.tail<n>(); |
从i开始取n个元素 | vector.segment(i,n) |
vector.segment<n>(i); |
再次说明一下,所有对矩阵的操作同样适用于Array,所有对列向量的操作同样适用于行向量。
下面是一个使用示例:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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;
}
执行结果如下:
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
Eigen子矩阵操作的更多相关文章
- eigen矩阵操作练习
// // Created by qian on 19-7-16. // /* 相机位姿用四元数表示 q = [0.35, 0.2, 0.3, 0.1] x,y,z,w * 注意:输入时Quatern ...
- [uva11992]Fast Matrix Operations(多延迟标记,二维线段树,区间更新)
题目链接:https://vjudge.net/problem/UVA-11992 题意:n*m的矩阵,每次对一个子矩阵操作,有三种操作:加x,设置为x,查询.查询返回子矩阵和.最小值.最大值 n很小 ...
- 从零开始一起学习SLAM | 三维空间刚体的旋转
刚体,顾名思义,是指本身不会在运动过程中产生形变的物体,如相机的运动就是刚体运动,运动过程中同一个向量的长度和夹角都不会发生变化.刚体变换也称为欧式变换. 视觉SLAM中使用的相机就是典型的刚体,相机 ...
- UVA 11992 Fast Matrix Operations (降维)
题意:对一个矩阵进行子矩阵操作. 元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作. 一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测 ...
- POJ 2155:Matrix 二维树状数组
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 21757 Accepted: 8141 Descripti ...
- Eigen库实现简单的旋转、平移操作
本来课程要求用GUI界面来实现Eigen的旋转.平移操作的,但是接触GUI编程时间太短,虽然要求很简单,但是做了几天还是没有完成.就把命令行下面的简单的贴一下吧. main.cpp #include ...
- Eigen 学习之块操作
Eigen 为 Matrix .Array 和 Vector提供了块操作方法.块区域可以被用作 左值 和 右值.在Eigen中最常用的块操作函数是 .block() . block() 方法的定义如 ...
- Eigen介绍及简单使用
博客转载自:https://blog.csdn.net/fengbingchun/article/details/47378515 Eigen是可以用来进行线性代数.矩阵.向量操作等运算的C++库,它 ...
- MATLAB常用操作
1.点乘,点除,点乘方 点乘(对应元素相乘),必须同维或者其中一个是标量,a.*b 点除,a.\b表示矩阵b的每个元素除以a中对应元素或者除以常数a,a./b表示常数a除以矩阵b中每个元素或者矩阵a除 ...
随机推荐
- Spring Cloud(Dalston.SR5)--Zuul 网关-Hystrix 回退
当我们对网关进行配置让其调用集群的服务时,将会执行 Ribbon 路由过滤器,该过滤器在进行转发时会封装为一个 Hystrix 命令予以执行,Hystrix 命令具有容错的功能,如果"源服务 ...
- jenkins构建触发器详解-不登录触发远程构建详解
利用jenkins的远程构建功能,我们可以使用任何脚本,甚至定制一个Web页来控制Job的执行,但是远程构建你如果直接使用的话,老是需要登录才能执行,如何避免登录?稍微折腾了一下,调通了. 1.首先去 ...
- Win7系统安装Centos7.0双系统(三)
4.6语言选择 4.7安装信息设置,除以下几项改动其他都可默认. 软件选择(默认最小):带GUI的服务器或GNOME桌面,可根据使用需要选择安装软件. 磁盘分区:Linux默认可分为3个分区,分别是b ...
- ss客户端以及tcp,udp,dns代理ss-tproxy本地安装版--centos7.3 x64以上(7.3-7.6x64测试通过)
因为下载的文件,从cn下载很慢,或者下不动,所以我弄了一个本地安装版 本地安装的文件,我是从网上单独下载了,这里就不提供了. 记得在最后设置允许访问的局域网IP段 ## iptables 配置ipta ...
- 搭建Tomcat应用服务器、tomcat虚拟主机及Tomcat多实例部署
一.环境准备 系统版本:CentOS release 6.6 (Final) x86_64 Tomcat版本:tomcat- JDK版本:jdk-8u25-linux-x64 关闭防火墙 软件包下载地 ...
- Java的synchronized的同步代码块和同步方法的区别
synchronized同步方法和同步代码块的区别 同步方法默认使用this或者当前类做为锁. 同步代码块可以选择以什么来加锁,比同步方法更精确,我们可以选择只有会在同步发生同步问题的代码加锁,而并不 ...
- (7)linux文件常用操作命令
ls / 查看根目录下的子节点(文件夹和文件)信息ls -al -a是显示隐藏文件 -l是以更详细的列表形式显示 **切换目录cd /home cd .. 返回上一级 **创建文件夹mkdir aaa ...
- 编程语言分类,安装python解释器,变量
1.编程语言分类 机器语言:直接使用二进制指令去编写程序,直接操作硬件 优点:执行效率高 缺点:开发效率低 汇编语言:用英文标签取代二进制指令去编写程序,直接进操作硬件 优点:开发效率高于机器语言 缺 ...
- leetcode494
public class Solution { public int FindTargetSumWays(int[] nums, int S) { Queue<int> Q = new Q ...
- php获取微信的openid
https://www.cnblogs.com/wxfallstar/p/6826886.html https://www.cnblogs.com/liangxiblog/p/5909432.html