eigen(一) 简介

2023-10-30

一、概况

Eigen是有关线性代数(矩阵、向量等)的c++模板库。支持SSE2/3/4, ARM NEON (32-bit and 64-bit), PowerPC AltiVec/VSX (32-bit and 64-bit) instruction sets, S390x SIMD (ZVector)

(一)安装

所有的源码在头文件,无需编译

(二)优化

  1. 使用vectorization
    x86使用-msse2编译选项
    x86-64默认支持SSE2
    32-bit ARM NEON使用-mfpu=neon -mfloat-abi=softfp|hard
    64-bit ARM SIMD默认支持
  2. 小矩阵(维度为2-4)使用fixed-size
  3. 注意temporary objects的创建
  4. 矩阵表达式的写法

二、使用流程

1.包含头文件
头文件模块,简单的矩阵乘法使用#include <Eigen/Eigen>

#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
int main()
{
  MatrixXd m(2,2);
  m(0,0) = 3;
  m(1,0) = 2.5;
  m(0,1) = -1;
  m(1,1) = m(1,0) + m(0,1);
  std::cout << m << std::endl;
}

2.编译指定eigen在本机的安装路径

g++ -I /path/to/eigen/ my_program.cpp -o my_program

三、数据类型

数据类型包括两类Matrix和Array。

typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyMatrixType;
typedef Array<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyArrayType;

存储顺序默认使用列存储,可以使用data()函数获得存储数据的首地址.

1. Matrix

Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
维度可以是fixed szie(编译时已知)或者dynamic size(运行时变量)

//使用case
Matrix<double, 6, Dynamic>                  // Dynamic number of columns (heap allocation)
Matrix<double, Dynamic, 2>                  // Dynamic number of rows (heap allocation)
Matrix<double, Dynamic, Dynamic, RowMajor>  // Fully dynamic, row major (heap allocation)
Matrix<double, 13, 3>                       // Fully fixed (usually allocated on stack)
//typedef简化
Matrix<float,Dynamic,Dynamic>   <=>   MatrixXf
Matrix<double,Dynamic,1>        <=>   VectorXd
Matrix<int,1,Dynamic>           <=>   RowVectorXi
Matrix<float,3,3>               <=>   Matrix3f
Matrix<float,4,1>               <=>   Vector4f

2.Array

定义类似于Matrix,支持coefficient-wise运算,比如每个元素加一个常数;两个矩阵对应的元素相乘。

//typdef 简化
Array<float,Dynamic,Dynamic>    <=>   ArrayXXf
Array<double,Dynamic,1>         <=>   ArrayXd
Array<int,1,Dynamic>            <=>   RowArrayXi
Array<float,3,3>                <=>   Array33f
Array<float,4,1>                <=>   Array4f

3.Matrix和Array之间相互转化

matrix=>array: matrix的.array()函数
array=>matrix: array的.matrix()函数
eigen不允许在表达式中混合使用matrix和array,但是允许使用=进行隐式转化,比如:

MatrixXf m(2,2);
MatrixXf n(2,2);
MatrixXf result(2,2);
result = m.array() * n.array();

matrix自身有成员函数.cwiseProduct()可以执行coefficient-wise product。

四、初始化

1.构造函数

Vector4d  v4;
Vector2f  v1(x, y);
Array3i   v2(x, y, z);
Vector4d  v3(x, y, z, w);
MatrixXf  m5; // empty object
MatrixXf  m6(nb_rows, nb_columns);

2.comma

Vector3f  v1;     v1 << x, y, z;
ArrayXf   v2(4);  v2 << 1, 2, 3, 4;
Matrix3f  m1;   m1 << 1, 2, 3,
                      4, 5, 6,
                      7, 8, 9;

3. map

对于原始的数据,可以使用Map复用原来的数据地址。

//pf为float*
Map<MatrixXf> mf(pf,rows,columns);
//pi为int*
Map<const Vector4i> mi(pi);

使用map

float data[] = {1,2,3,4};
Map<Vector3f> v1(data);       // uses v1 as a Vector3f object
Map<ArrayXf>  v2(data,3);     // uses v2 as a ArrayXf object
Map<Array22f> m1(data);       // uses m1 as a Array22f object
Map<MatrixXf> m2(data,2,2);   // uses m2 as a MatrixXf object

float data[] = {1,2,3,4,5,6,7,8,9};
Map<VectorXf,0,InnerStride<2> >  v1(data,3);                      // = [1,3,5]
Map<VectorXf,0,InnerStride<> >   v2(data,3,InnerStride<>(3));     // = [1,4,7]
Map<MatrixXf,0,OuterStride<3> >  m2(data,2,3);                    // both lines     |1,4,7|
Map<MatrixXf,0,OuterStride<> >   m1(data,2,3,OuterStride<>(3));   // are equal to:  |2,5,8

map和原始数组之间的相互转化

//array=>Matrix
double *x;
MatrixXd m = Map<MatrixXd> (x, rows, cols);
//Matrix=>array
double *y;
MatrixXd n;
Map<MatrixXd>(y, n.rows(), n.cols())=n;

五、运算

1.aliasing

aliasing:如果等号的两边出现同一个matrix或者array,就会引起结果异常。
1.对于标量乘法、加减法,没有影响

mat = 2 * mat;      //no aliasing
arr = arr.square(); //no aliasing

2.只有matrix乘法,eigen认定肯定会出现aliasing
默认引入临时matrix来存放中间结果

//1.aliasing
matA=matA*matA
//eigen默认将上式分解成
temp=matA*matA
matA=temp

//2.no aliasing
//使用noalias()来避免上面的分解
matB=matA*matA //仍然会分解,虽然没有必要
matB.noalias()=matA*matA //不会分解

3.除了矩阵乘法以外的运算如果会出现aliasing问题,可以使用eval()函数或者xxxInPlace()函数避免

Matrix2i a; a << 1, 2, 3, 4;
a = a.transpose(); //error: aliasing
a = a.transpose().eval(); //ok
a.transposeInPlace(); //ok

2.尽量使用复杂表达式,eigen可以更好地优化

六、多线程

1.支持多线程

eigen的部分算法(矩阵乘法、PartialPivLU)支持多线程,编译的时候增加-fopenmp,可以通过以下方式设置使用的线程数:

OMP_NUM_THREADS=n ./my_program
omp_set_num_threads(n);
Eigen::setNbThreads(n);

也可以通过EIGEN_DONT_PARALLELIZE宏定义关闭eigen的多线程。
如果程序本身使用了多线程,需要使用以下方式初始化eigen

#include <Eigen/Core>
int main(int argc, char** argv)
{
  Eigen::initParallel();
  
  ...
}

2.使用mkl库

Intel mkl(Math Kernal Library)可以支持更高程度优化的多线程数学计算。eigen使用MKL流程:

  • define the EIGEN_USE_MKL_ALL macro before including any Eigen’s header
  • link your program to MKL libraries (see the MKL linking advisor)
  • on a 64bits system, you must use the LP64 interface (not the ILP64 one)
    MKL的优化适用于Dynamic的matrix,数据类型仅限于float/double/complex/complex,其他类型的数据或者real和complex混用的数据不会使用mkl优化,而是使用内置的算法优化。

后面的技术分享转移到微信公众号上面更新了,【欢迎扫码关注交流】

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

eigen(一) 简介 的相关文章

随机推荐

  • 【OSS】阿里云对象存储OSS入门使用 JAVA SDK上传与下载 简单测试案例

    本文包括阿里云对象存储OSS入门使用 上传与下载以及简单测试案例的实现 首先 在阿里云中找到对象存储OSS 点击侧边栏的Bucket列表 创建Bucket列表 根据需求选择配置 创建完成后 点击进入查看概览 找到对应的Endpoint 在后
  • 【Python】JSON模块的使用

    JSON的基本使用 1 内置库 不需要额外安装 json模块是python内置的库 不需要额外安装就可以导入运行 json模块的主要功能是将序列化数据从文件里读取出来或者存入文件 四个函数 json模块的操作使用相对较为简单 该模块只有四个
  • vue3+ts极简教程

    一 依次执行以下四步 即可极速创建项目 跟着敲一次 你会放下2 x 1 npm init vitejs app my vite vue 2 cd my vite vue 3 npm install 4 npm run dev 二 通过两种不
  • 自定义控件——轮播图 ImageCycleView

    1 ImageCycleView Android 轮播图菜单 Huzz 出品 主要是对图片的循环播放 默认播放时间3秒 可以点击控制播放 添加JAR包 android smart image view 1 0 0 jar包 1 自定义类 i
  • 高校排课的数学模型

    一 高校排课面临的主要问题 1 1问题的提出 课程表问题又称时间表问题 课表编排是一个多指标的优化决策冋题 是组合规划中的典型问题 课程表的编排就是解决对时间和空间资源争夺而引起的冲突 20世纪60年代末 国外就有人开始研究课表编排问题 1
  • 黄金矿工—小游戏

    黄金矿工 使用easy x图形库制作 一 游戏思路 游戏的核心是如何让钩子动起来 怎么伸缩 怎么抓物品3个部分 1 钩子的转动 钩子的转动可以根据角度的变化来决定 我们让起始坐标不变 让钩子的结尾坐标变化 在限定角度的范围即可 求结尾坐标思
  • shap 模型_使用shap loss值调试监控模型

    shap 模型 Responsible AI has been a very hot topic in recent years Accountability and explainability now become the necess
  • 普通二叉树转换成二叉查找树方法

    d 转载于 https www cnblogs com sdnyzhl archive 2012 12 05 2803457 html
  • VMware虚拟机中安装Ubuntu18.04(linux发行版)【超详细图文教程】

    文章目录 零 前言 一 虚拟机VMware的下载与安装 1 0 简介 1 1 VMware的下载 1 2 VMware安装过程 二 在虚拟机中安装Ubuntu18 04 2 1 Ubuntu18 04镜像文件下载 2 2 在VMware中创
  • 【数据分析】如何构建指标体系 & 设计一份优质报表

    如何构建指标体系 设计一份优质报表 1 构建指标体系 1 数据人员如何创造价值 基于历史数据和业务背景构建指标体系或者模型 基于指标体系 监控线上业务数据并制定相应的监控规则 输出数据分析报告或者提供可执行策略 推动业务的发展 2 要构建一
  • 模拟搭建日志收集系统

    Hadoop 模拟搭建日志收集系统 一 技术点梳理 二 任务 2 1 调通单机版的thrift python版本 2 1 1 安装thrift 2 1 2 定义client和server通信的接口 2 1 3 根据接口 scheme 生成p
  • 在CXXLD libwebkitgtk-1.0.la时候发生 ld terminated with signal 9 [Killed]错误

    当时内存几乎用完了 发生这个错误是因为内存不够 编译不过来 系统是ubuntu 11 04 2G的物理内存不够 swap分区是1G CXXLD libwebkitgtk 1 0 la collect2 ld terminated with
  • 最全的搜索引擎登录入口(SEO必备)

    百度搜索网站登录口 http www baidu com search url submit html 百度单个网页提交入口 http zhanzhang baidu com sitesubmit 360搜索引擎登录入口 http info
  • sql查询中的包含【被包含】、模糊查询

    在mysql中提供了like的关键词可用于模糊查询 也可理解为某些指定字段包含在表中的的查询 select count from mysqlb client where name like 庆农 可查询出在name字段下所有包含 庆农 字样
  • maven怎么引入jdom_Maven环境配置

    1 Android Maven Plugin 参考网站 3 解压放到你想放的位置 例如 D Maven 目录 4 配置环境变量 MAVEN HOME D Maven 把MAVEN HOME加入到PATH中 MAVEN HOME bin 5
  • Unity 3D-learning 简单打飞碟游戏

    一 编写一个简单的打飞碟游戏 游戏内容要求 游戏有 n 个 round 每个 round 都包括10 次 trial 每个 trial 的飞碟的色彩 大小 发射位置 速度 角度 同时出现的个数都可能不同 它们由该 round 的 ruler
  • js多方框输入密码_简单JS代码实现输入密码访问页面

    一段js代码让你的网页拥有密码功能 访问页面必须输入密码才能正常浏览 分享三种JS代码 放在和中间即可 第一种 function password var testV 1 var pass1 prompt 请输入密码 while testV
  • 软件调试的艺术(Linux Unix平台软件调试权威著作)

    c 作 者 美 Norman Matloff Peter Jay Salzman 同作者作品 作译者介绍 译 者 张云 同译者作品 丛 书 名 图灵程序设计丛书 出 版 社 人民邮电出版社 书 号 9787115213969 上架时间 20
  • ResNet网络结构

    1 网络解决的问题 当更深的网络能够开始收敛时 一个退化问题就暴露出来了 随着网络深度的增加 精度达到饱和 然后开始退化 出乎意料的是 这种退化不是由过拟合引起的 向适当深度的模型中添加更多的层会导致更高的训练误差 经典网络的缺陷用以下图来
  • eigen(一) 简介

    一 概况 Eigen是有关线性代数 矩阵 向量等 的c 模板库 支持SSE2 3 4 ARM NEON 32 bit and 64 bit PowerPC AltiVec VSX 32 bit and 64 bit instruction