矩阵和向量的运算

提供一些概述和细节:关于矩阵、向量以及标量的运算。

1. 介绍

Eigen提供了matrix/vector的运算操作,既包括重载了c++的算术运算符+/-/*,也引入了一些特殊的运算比如点乘dot、叉乘cross等。

对于Matrix类(matrix和vectors)这些操作只支持线性代数运算,比如:matrix1*matrix2表示矩阵的乘机,vetor+scalar是不允许的。如果你想执行非线性代数操作,请看下一篇(暂时放下)。

2. 加减

左右两侧变量具有相同的尺寸(行和列),并且元素类型相同(Eigen不自动转化类型)操作包括:

  • 二元运算 + 如a+b
  • 二元运算 - 如a-b
  • 一元运算 - 如-a
  • 复合运算 += 如a+=b
  • 复合运算 -= 如a-=b
#include <iostream>#include <Eigen/Dense>using namespace Eigen;int main(){Matrix2d a;a << 1, 2,3, 4;MatrixXd b(2,2);b << 2, 3,1, 4;std::cout << "a + b =\n" << a + b << std::endl;std::cout << "a - b =\n" << a - b << std::endl;std::cout << "Doing a += b;" << std::endl;a += b;std::cout << "Now a =\n" << a << std::endl;Vector3d v(1,2,3);Vector3d w(1,0,0);std::cout << "-v + w - v =\n" << -v + w - v << std::endl;}

输出:

a + b =

3 5

4 8

a - b =

-1 -1

2  0

Doing a += b;

Now a =

3 5

4 8

-v + w - v =

-1

-4

-6

3. 标量乘法和除法

乘/除标量是非常简单的,如下:

  • 二元运算 * 如matrix*scalar
  • 二元运算 * 如scalar*matrix
  • 二元运算 / 如matrix/scalar
  • 复合运算 *= 如matrix*=scalar
  • 复合运算 /= 如matrix/=scalar
#include <iostream>#include <Eigen/Dense>using namespace Eigen;int main(){Matrix2d a;a << 1, 2,3, 4;Vector3d v(1,2,3);std::cout << "a * 2.5 =\n" << a * 2.5 << std::endl;std::cout << "0.1 * v =\n" << 0.1 * v << std::endl;std::cout << "Doing v *= 2;" << std::endl;v *= 2;std::cout << "Now v =\n" << v << std::endl;}

结果

a * 2.5 =

2.5   5

7.5  10

0.1 * v =

0.1

0.2

0.3

Doing v *= 2;

Now v =

2

4

6

4. 表达式模板

这里简单介绍,在高级主题中会详细解释。在Eigen中,线性运算比如+不会对变量自身做任何操作,会返回一个“表达式对象”来描述被执行的计算。当整个表达式被评估完(一般是遇到=号),实际的操作才执行。

这样做主要是为了优化,比如

VectorXf a(50), b(50), c(50), d(50);

...

a = 3*b + 4*c + 5*d;

Eigen会编译这段代码最终遍历一次即可运算完成。

for(int i = 0; i < 50; ++i)

a[i] = 3*b[i] + 4*c[i] + 5*d[i];

因此,我们不必要担心大的线性表达式的运算效率。

5. 转置和共轭

 表示transpose转置

 表示conjugate共轭

 表示adjoint(共轭转置) 伴随矩阵

MatrixXcf a = MatrixXcf::Random(2,2);cout << "Here is the matrix a\n" << a << endl;cout << "Here is the matrix a^T\n" << a.transpose() << endl;cout << "Here is the conjugate of a\n" << a.conjugate() << endl;cout << "Here is the matrix a^*\n" << a.adjoint() << endl;

输出

Here is the matrix a

(-0.211,0.68) (-0.605,0.823)

(0.597,0.566)  (0.536,-0.33)

Here is the matrix a^T

(-0.211,0.68)  (0.597,0.566)

(-0.605,0.823)  (0.536,-0.33)

Here is the conjugate of a

(-0.211,-0.68) (-0.605,-0.823)

(0.597,-0.566)    (0.536,0.33)

Here is the matrix a^*

(-0.211,-0.68)  (0.597,-0.566)

(-0.605,-0.823)    (0.536,0.33)

对于实数矩阵,conjugate不执行任何操作,adjoint等价于transpose。

transpose和adjoint会简单的返回一个代理对象并不对本省做转置。如果执行 b=a.transpose() ,a不变,转置结果被赋值给b。如果执行 a=a.transpose() Eigen在转置结束之前结果会开始写入a,所以a的最终结果不一定等于a的转置。

Matrix2i a; a << 1, 2, 3, 4;cout << "Here is the matrix a:\n" << a << endl;a = a.transpose(); // !!! do NOT do this !!!cout << "and the result of the aliasing effect:\n" << a << endl;

Here is the matrix a:

1 2

3 4

and the result of the aliasing effect:

1 2

2 4

这被称为“别名问题”。在debug模式,当assertions打开的情况加,这种常见陷阱可以被自动检测到。

对 a=a.transpose() 这种操作,可以执行in-palce转置。类似还有adjointInPlace。

MatrixXf a(2,3); a << 1, 2, 3, 4, 5, 6;cout << "Here is the initial matrix a:\n" << a << endl;a.transposeInPlace();cout << "and after being transposed:\n" << a << endl;

Here is the initial matrix a:

1 2 3

4 5 6

and after being transposed:

1 4

2 5

3 6

6. 矩阵-矩阵的乘法和矩阵-向量的乘法

向量也是一种矩阵,实质都是矩阵-矩阵的乘法。

  • 二元运算 *如a*b
  • 复合运算 *=如a*=b
#include <iostream>#include <Eigen/Dense>using namespace Eigen;int main(){Matrix2d mat;mat << 1, 2,3, 4;Vector2d u(-1,1), v(2,0);std::cout << "Here is mat*mat:\n" << mat*mat << std::endl;std::cout << "Here is mat*u:\n" << mat*u << std::endl;std::cout << "Here is u^T*mat:\n" << u.transpose()*mat << std::endl;std::cout << "Here is u^T*v:\n" << u.transpose()*v << std::endl;std::cout << "Here is u*v^T:\n" << u*v.transpose() << std::endl;std::cout << "Let's multiply mat by itself" << std::endl;mat = mat*mat;std::cout << "Now mat is mat:\n" << mat << std::endl;}

输出

Here is mat*mat:

7 10

15 22

Here is mat*u:

1

1

Here is u^T*mat:

2 2

Here is u^T*v:

-2

Here is u*v^T:

-2 -0

2  0

Let's multiply mat by itself

Now mat is mat:

7 10

15 22

m=m*m并不会导致别名问题,Eigen在这里做了特殊处理,引入了临时变量。实质将编译为:

tmp = m*m

m = tmp

如果你确定矩阵乘法是安全的(并没有别名问题),你可以使用noalias()函数来避免临时变量 c.noalias() += a*b 。

7. 点运算和叉运算

dot()执行点积,cross()执行叉积,点运算得到1*1的矩阵。当然,点运算也可以用u.adjoint()*v来代替。

#include <iostream>#include <Eigen/Dense>using namespace Eigen;using namespace std;int main(){Vector3d v(1,2,3);Vector3d w(0,1,2);cout << "Dot product: " << v.dot(w) << endl;double dp = v.adjoint()*w; // automatic conversion of the inner product to a scalarcout << "Dot product via a matrix product: " << dp << endl;cout << "Cross product:\n" << v.cross(w) << endl;}

输出

Dot product: 8

Dot product via a matrix product: 8

Cross product:

1

-2

1

注意:点积只对三维vector有效。对于复数,Eigen的点积是第一个变量共轭和第二个变量的线性积。

8. 基础的归约操作

Eigen提供了而一些归约函数:sum()、prod()、maxCoeff()和minCoeff(),他们对所有元素进行操作。

#include <iostream>#include <Eigen/Dense>using namespace std;int main(){Eigen::Matrix2d mat;mat << 1, 2,3, 4;cout << "Here is mat.sum():       " << mat.sum()       << endl;cout << "Here is mat.prod():      " << mat.prod()      << endl;cout << "Here is mat.mean():      " << mat.mean()      << endl;cout << "Here is mat.minCoeff():  " << mat.minCoeff()  << endl;cout << "Here is mat.maxCoeff():  " << mat.maxCoeff()  << endl;cout << "Here is mat.trace():     " << mat.trace()     << endl;}

输出

Here is mat.sum():       10

Here is mat.prod():      24

Here is mat.mean():      2.5

Here is mat.minCoeff():  1

Here is mat.maxCoeff():  4

Here is mat.trace():     5

trace表示矩阵的迹,对角元素的和等价于 a.diagonal().sum() 。

minCoeff和maxCoeff函数也可以返回结果元素的位置信息。

Matrix3f m = Matrix3f::Random();std::ptrdiff_t i, j;float minOfM = m.minCoeff(&i,&j);cout << "Here is the matrix m:\n" << m << endl;cout << "Its minimum coefficient (" << minOfM<< ") is at position (" << i << "," << j << ")\n\n";RowVector4i v = RowVector4i::Random();int maxOfV = v.maxCoeff(&i);cout << "Here is the vector v: " << v << endl;cout << "Its maximum coefficient (" << maxOfV<< ") is at position " << i << endl;

输出

Here is the matrix m:

0.68  0.597  -0.33

-0.211  0.823  0.536

0.566 -0.605 -0.444

Its minimum coefficient (-0.605) is at position (2,1)

Here is the vector v:  1  0  3 -3

Its maximum coefficient (3) is at position 2

9. 操作的有效性

Eigen会检测执行操作的有效性,在编译阶段Eigen会检测它们,错误信息是繁冗的,但错误信息会大写字母突出,比如:

Matrix3f m;Vector4f v;v = m*v;      // Compile-time error: YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES

当然动态尺寸的错误要在运行时发现,如果在debug模式,assertions会触发后,程序将崩溃。

MatrixXf m(3,3);VectorXf v(4);v = m * v; // Run-time assertion failure here: "invalid matrix product"

Eigen(4)矩阵基本运算相关推荐

  1. OpenCV的各种矩阵基本运算、基本操作及示例代码(加、减、乘、点乘、点除、乘方、开方、累加、转置、比较等)

    OpenCV的各种矩阵基本运算.基本操作及示例代码(加.减.乘.点乘.点除.乘方.开方.累加.转置.比较等) OpenCV的各种矩阵基本运算.基本操作及示例代码 目录 01-两个矩阵相加.矩阵和标量相 ...

  2. 技术图文:Matlab VS. Numpy 矩阵基本运算

    背景 前段时间在知识星球上立了一个Flag,至少写10篇关于 Python,Matlab 和 C# 对比的总结. 这是第 3 篇,对比 Matlab 与 Numpy 在矩阵基本运算方面的区别与联系. ...

  3. 【神经网络与深度学习】【C/C++】比较OpenBLAS,Intel MKL和Eigen的矩阵相乘性能

    比较OpenBLAS,Intel MKL和Eigen的矩阵相乘性能 对于机器学习的很多问题来说,计算的瓶颈往往在于大规模以及频繁的矩阵运算,主要在于以下两方面: (Dense/Sparse) Matr ...

  4. 2.2 矩阵基本运算

    矩阵基本运算 矩阵作为有序向量组的整体,可以进行运算,就如同向量作为有序数组的整体.主要运算包括相等,加法和数乘.矩阵运算规则都是根据矩阵乘以向量是矩阵向量组的线性组合推导出来的,即公式(1). 矩阵 ...

  5. python矩阵运算与线形代数_[译] 线性代数:矩阵基本运算

    线性代数:矩阵基本运算 在本文中,我们将介绍矩阵的大部分基本运算,依次是矩阵的加减法.矩阵的标量乘法.矩阵与矩阵的乘法.求转置矩阵,以及深入了解矩阵的行列式运算.本文将不会涉及逆矩阵.矩阵的秩等概念, ...

  6. MATLAB矩阵基本运算的实现(一)

    MATLAB是matrix&laboratory两个词的组合,意为矩阵工厂(矩阵实验室),强大的矩阵运算能力是MATLAB的一个重要的特点,下面我就为大家整理了一下利用MATLAB实现矩阵基本 ...

  7. C++Eigen库矩阵常见操作

    描述 使用C++语言的Eigen库进行一些常见操作 使用库时,请一定注意两点 定义清楚矩阵类型 矩阵乘法注意尺寸对应 代码 头文件声明 #include <Eigen/Dense> 1. ...

  8. python矩阵左除_技术图文:Matlab VS. Numpy 矩阵基本运算

    背景 前段时间在知识星球上立了一个Flag,至少写10篇关于 Python,Matlab 和 C# 对比的总结. 这是第 3 篇,对比 Matlab 与 Numpy 在矩阵基本运算方面的区别与联系. ...

  9. Python 矩阵基本运算【numpy】

    文章目录 一.实验说明 二.Python 矩阵基本运算 1. python矩阵操作 2. python矩阵乘法 3. python矩阵转置 4. python求方阵的迹 5. python方阵的行列式 ...

  10. Eigen入门系列 —— Eigen::Matrix矩阵点乘、叉乘、转置、求逆、求和、行列式、迹、数乘

    Eigen入门系列 -- Eigen::Matrix矩阵点乘.叉乘.转置.求逆.求和.行列式.迹.数乘 前言 程序说明 输出结果 代码示例 前言 随着工业自动化.智能化的不断推进,机器视觉(2D/3D ...

最新文章

  1. teamviewer设备数量上限_智能控制设备连接故障排除
  2. 【转】Weblogic的集群
  3. 2.42死锁的处理策略一预防死锁
  4. 从数据仓库到报表,再到可视化,数字化物流是这么设计架构的
  5. oracle怎么不让别的电脑连接,[转载]修改计算机名字导致oracle连接不上的解决方案...
  6. ASP.NET MVC的客户端验证:jQuery验证在Model验证中的实现
  7. 雅黑PHP探针Light,雅黑php探针
  8. python获取子窗口句柄
  9. 高德地图通过经纬度获取地区城市
  10. 二项分布的特征函数及期望与方差 - 随机过程
  11. php文件zend解密,php zend无法解密怎么办
  12. 中国白领最苦累的六大城市
  13. 大提顿国家公园美丽风景Mac动态壁纸
  14. html里怎么旋转视频教程,怎么把视频调正 视频倒了怎么正过来 旋转视频画面
  15. GPU 选择 深度学习 图像识别
  16. 单片机c语言波特率检测,基于MSP430系列微控制器串口通信时的波特率自动检测的实现...
  17. 懒人原则(Kepp it Semple Stupis)
  18. 森林资源保护类毕业论文文献包含哪些?
  19. 图库图库图库词典制作在线查看AI翻译
  20. 微商成功神器,python程序员教你,一键分析微信好友近期所有信息

热门文章

  1. 易语言 网页用什么编码_通常提到的编码器是干什么用的
  2. c语言中组合函数,排列组合c怎么算 公式是什么
  3. oracle查询最高一条记录,oracle 查询已有记录,上一条记录,下一条记录
  4. [渝粤教育] 中国地质大学 结晶学与矿物学 复习题 (2)
  5. 【渝粤题库】国家开放大学2021春2044教育研究方法题目
  6. mysql 横向分表合并_MySQL横向扩展-分库分表解决方案总结
  7. LaTeX indicator function
  8. 别克gl8服务器返回数据为空,老司机教学:别克GL8商务车总线控制系统故障解决...
  9. python自由职业可以做什么_我想成为自由职业者,但不知道做什么?
  10. 第十一届蓝桥杯A组省赛填空试题 A: 门牌制作(Java)