Ubuntu下的Eigen库的安装及基本使用教程

一、Eigen库介绍

简介

Eigen [1]目前最新的版本是3.4,除了C++标准库以外,不需要任何其他的依赖包。Eigen使用的CMake建立配置文件和单元测试,并自动安装。如果使用Eigen库,只需包特定模块的的头文件即可。

基本功能

Eigen适用范围广,支持包括固定大小、任意大小的所有矩阵操作,甚至是稀疏矩阵;支持所有标准的数值类型,并且可以扩展为自定义的数值类型;支持多种矩阵分解及其几何特征的求解;它不支持的模块生态系统 [2]提供了许多专门的功能,如非线性优化,矩阵功能,多项式解算器,快速傅立叶变换等。
Eigen支持多种编译环境,开发人员对库中的实例在多种编译环境下经过测试,以保证其在不同编译环境下的可靠性和实用性。

介绍来之百度百科,点这里

二、Eigen库的下载及安装

进入官方下载路径,点这里
在这里插入图片描述
下载eigen-3.4.0.tar.gz到本地,解压

tar -xzf eigen-3.4.0.tar.gz 

编译项目

# 进入eigen源码目录
cd eigen-3.4.0
# 创建文件夹build-编译用
mkdir build
# 进入build
cd build
# 开始构建
cmake ..

安装项目

# 执行安装 - 注意这里不需要make,原因前面解释过eigen是模式式编程
# 不需要真正的编译,只需要把头文件安装到系统include目录即可
make install

上面命令执行后,默认安装 Eigen采用源码的方式提供给用户使用,在使用时只需要包含Eigen的头文件即可进行使用。之所以采用这种方式,是因为Eigen采用模板方式实现,由于模板函数不支持分离编译,所以只能提供源码而不是动态库的方式供用户使用。到/usr/local/include/目录

三、Eigen基本使用

引入Eigen库

#include <iostream>
#include <Eigen/Core>
#include <Eigen/Dense>

1、定义矩阵、基本访问、为矩阵赋值、重置矩阵

// 1. 定义矩阵
Eigen::MatrixXd m(2,2);
Eigen::Vector3d vec3d;
Eigen::Vector4d vec4d(1.0, 2.0, 3.0, 4.0);// Matrix创建的矩阵默认是按列存储,Eigen在处理按列存储的矩阵时会更加高效,可通过如下方法修改优先存储方式
Matrix<int,3, 4, ColMajor> Acolmajor;
Matrix<int,3, 4, RowMajor> Arowmajor;// 2. 定义动态矩阵、静态矩阵
Eigen::MatrixXd matrixXd;  // 动态矩阵,通过mat.resise()重新修改矩阵大小
Eigen::Matrix3d matrix3d;// 3. 矩阵元素的访问
m(0, 0) = 1;
m(0, 1) = 2;
m(1, 0) = m(0, 0) + 3;
m(1, 1) = m(0, 0) * m(0, 1);
cout << m << endl << endl;// 4. 设置矩阵的元素
m << -5.5, 3.1,5.9, 1.0;
cout << m << endl << endl;
int row = 4;
int col = 5;
Eigen::MatrixXf matrixXf(row, col);
matrixXf << 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20;
cout << matrixXf << endl << endl;// 5. 重置矩阵
Eigen::MatrixXd matrixXd1(4,4);
cout << "原m的行列为:" << m.rows() << " ,  " << m.cols() << endl << endl;
m.resize(5,100); // 通过resize修改矩阵大小
cout << "新1的m行列为:" << m.rows() << " ,  " << m.cols() << endl << endl;
m = matrixXd1; // 通过直接赋值新矩阵,修改矩阵大小
cout << "新2的m行列为:" << m.rows() << " ,  " << m.cols() << endl << endl;

2、常用矩阵、及常用的基本矩阵运算
常用特殊矩阵:0矩阵、1矩阵、单位矩阵、随机矩阵

常用的矩阵运算:转置、共轭、共轭转置、求逆、求迹、求行列式、求模、求和、求均值、求乘积、求最小、求最大
点乘、叉乘

// 1. 其他常用特殊的矩阵
Eigen::Matrix3d m3;
m3 = Eigen::Matrix3d::Zero();
cout << "Zero() : " << endl << m3 << endl << endl;m3 = Eigen::Matrix3d::Identity();
cout << "Identity() : " << endl << m3 << endl << endl;m3 = Eigen::Matrix3d::Random();
cout << "Random() : " << endl << m3 << endl << endl;// 2. 直接设置为常用特殊矩阵
m3.setRandom(); // 随机矩阵
m3.setOnes();   // 全1矩阵
m3.setZero();   // 全0矩阵
m3.setIdentity();  // 单位矩阵// 3. 矩阵的运算1
Eigen::Matrix3d new_m3; 
new_m3 = m3.transpose();
cout << "============================================" << endl << endl;
cout << "m3.transpose() - 转置: " << endl << new_m3 << endl << endl;new_m3 = m3.conjugate();
cout << "m3.conjugate() - 共轭: " << endl << new_m3 << endl << endl;new_m3 = m3.adjoint();
cout << "m3.adjoint() - 伴随矩阵(共轭转置): " << endl << new_m3 << endl << endl;
// 对于实数矩阵,conjugate不执行任何操作,adjoint等价于transposecout << "m3.inverse() - 求逆: " << endl << m3.inverse(); << endl << endl;
cout << "m3.trace() - 求迹: " << endl << m3.trace() << endl << endl;
cout << "m3.determinant() - 求行列式: " << endl << m3.determinant() << endl << endl;
cout << "m3.norm() - 求模: " << endl << m3.norm() << endl << endl;
cout << "m3.sum() - 求和: " << endl << m3.sum() << endl << endl;
cout << "m3.mean() - 求均值: " << endl << m3.mean() << endl << endl;
cout << "m3.prod() - 求乘积: " << endl << m3.prod() << endl << endl;
cout << "m3.minCoeff() - 求最小: " << endl << m3.minCoeff() << endl << endl;
cout << "m3.maxCoeff() - 求最大: " << endl << m3.maxCoeff() << endl << endl;// 3. 矩阵的运算2
Eigen::Vector3d v1(1, 2, 3);
Eigen::Vector3d v2(2, 1, 2);// 点乘
double a;
a = v1.dot(v2);
cout << "v1.dot(v2) - 点乘: " << endl << a << endl << endl;// 叉乘
cout << "v1.cross(v2) - 叉乘: " << endl << v1.cross(v2) << endl << endl;

四、Eigen的应用

1、求矩阵的特征值及特征向量

// 求解特征值及特征向量
Eigen::Matrix2f matrix2f;
matrix2f << 1, 2, 3, 4;
Eigen::SelfAdjointEigenSolver<Eigen::Matrix2f> eigenSolver(matrix2f);
cout<< "SelfAdjointEigenSolver: " << eigenSolver.info() << endl; 
if (eigenSolver.info() == Eigen::Success ) {cout << eigenSolver.eigenvalues() << endl << endl;cout << eigenSolver.eigenvectors() << endl << endl;
}

2、求解线性方程组Ax=b
方法一:直接法求线性方程组(求逆法)

const int n = 4;
Eigen::Matrix<double, n, n > A; 
A = A.Random() * 10;
Eigen::Matrix<double, n, 1> b;
b = b.Random() * 10;// 定义未知x
Eigen::Matrix<double, n, 1> x;
x = A.inverse() * b; // 直接取逆 (这种效率很低,不推荐使用)
cout << "A=" << endl << A << endl << "b=" << b << endl << endl;
cout << "x=" << x << endl << endl;

注意上面例子,直接求逆法是低效的,一般情况不推荐选择求逆法,且直接对A.inverse(),可能会取逆失败,无法完成A.inverse()*b的运算操作

方法二:QR分解法(推荐)

// const int n = 4;
// Eigen::Matrix<double, n, n > A; 
// A = A.Random() * 10;
// Eigen::Matrix<double, n, 1> b;
// b = b.Random() * 10;// case-1:使用前面的A、b矩阵,定义未知x2
Eigen::Matrix<double, n, 1> x2;
x2 = A.colPivHouseholderQr().solve(b);
cout << "QR分解法" <<endl;
cout << "x=" << x2 << endl << endl;// case-2:当然有时为了使用QR分解对象,也可以用下面方法计算,
Eigen::ColPivHouseholderQR<Eigen::MatrixXd> qrDec(A);
x = qrDec.solve(b);// case-3 或者采用分离式分布构造
Eigen::ColPivHouseholderQR<Eigen::MatrixXd> qrDec2;  // 只声明,不待入参,并不立即构造分解
qrDec2.compute(A); // 执行计算进行分解
x = qrDec2.solve(b);  // 求解

上面三种使用方法,任取一种即可

3、如何评估或计算解的精度

// 继续前面的计算,我们可以采用下面的方式计算精度
double relative_error = (A*x - b).norm() / b.norm();
std::cout << "The relative error is:\n" << relative_error << std::endl;

4、求矩阵的秩
计算秩,通常是使用各类分解算法提供的rank()方法计算,Eigen中的许多分解算法,都提供了rank()求秩

Eigen::MatrixXd A(3,3);
A << 1, 2, 5,2, 1, 4,3, 0, 3;
cout << "A=" << endl << A << endl << endl;
Eigen::ColPivHouseholderQR<Eigen::MatrixXd> qrDec;
// 分解
qrDec.compute(A);
// 计算秩
cout<< "A rank = " << endl << qrDec.rank() << endl << endl;

任何算法的秩的计算根据设置的阈值来进行的,也就是设置不同的阈值,对结果将造成影响;Eigen中秩的计算依赖于分解方法的阈值,并不是矩阵对角大小乘以机器的精度epsilon,可通过调用dec.setThreshold(th_val)设置;且注意,分解算法并不会依赖阈值的设定,也就是执行完成分解后,任可以任意设置阈值,并求解rank()得到正确的秩;

Eigen库提供了多种求解线性方程组的算法,如下所示
在这里插入图片描述

参考地址,点这里

在实际问题处理中,如何选择不同的方法,对求解效率将会较大的影响,可根据系数矩阵A的特征,选择不同的分解算法:

  • 如果系数矩阵是对于非对称、满秩的,则最适合的分解求解方法是PartialPivLU.
  • 如果系数矩阵是对称正定的,则最适合的分解方法是 LLT 或LDLT

各类算法的求解效率对比可参考如下:
在这里插入图片描述

参考地址,点这里

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18535.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Ansible一键部署Kubernetes集群

一、环境准备 主机 ip地址 角色 k8s-master 192.168.252.141 master k8s-node1 192.168.252.142 node k8s-node2 192.168.252.143 node 二、实战 Ansible部署 主节点安装Ansible yum -y install epel-release yum -y install ansible ansible --version 开启记…

Comfy UI Manager 自定义节点管理

在 Stable Diffusion Web UI 中&#xff0c;可以通过插件的方式&#xff0c;扩展更多的功能&#xff0c;如&#xff1a;tagger提示词反推、ControlNet 等。 同样的在 Comfy UI 中有类似的功能实现&#xff0c;不过在 Comfy UI 中叫做自定义节点。 通过安装自定义节点的方式&a…

第二十周:机器学习

目录 摘要 ABSTRACT 一、吴恩达机器学习exp2——逻辑回归 1、logistic函数 2、数据预处理 3、损失函数 4、梯度下降 5、设定评价指标 6、决策边界 7、正则化 二、动手深度学习pytorch——数据预处理 1、数据集读取 2、缺失值处理 3、转换为张量格式 总结 摘要…

从人-物到人-机再到人-AI

从 人-物 到 人-机 再到 人-AI &#xff0c;这一演化过程展现了人类与技术、工具的互动方式随着时代的发展而发生的深刻变化。这一变化不仅是技术进步的体现&#xff0c;更是社会、文化以及工作方式的根本转变。以下是这一演变的主要特点及其背后的影响&#xff1a; 1. 人-物时…

go-zero(三) 数据库操作

go-zero 数据库操作 在本篇文章中&#xff0c;我们将实现一个用户注册和登录的服务。我们将为此构建一个简单而高效的 API&#xff0c;包括请求参数和响应参数的定义。 一、Mysql连接 1. 创建数据库和表 在 MySQL 中创建名为 test_zero的数据库&#xff0c;并创建user 表 …

【ASR技术】WhisperX安装使用

介绍 WhisperX 是一个开源的自动语音识别&#xff08;ASR&#xff09;项目&#xff0c;由 m-bain 开发。该项目基于 OpenAI 的 Whisper 模型&#xff0c;通过引入批量推理、强制音素对齐和语音活动检测等技术。提供快速自动语音识别&#xff08;large-v2 为 70 倍实时&#xf…

【C++ 算法进阶】算法提升十六

目录 背包问题变种 &#xff08;动态规划&#xff09;题目题目分析 连续可组成数字题目题目分析 min-patches题目 最小补丁问题题目分析代码 逆序对个数 &#xff08;归并排序&#xff09;题目题目分析 约瑟夫环问题 &#xff08;公式&#xff09;题目题目分析 背包问题变种 &a…

链表的基本操作

链表&#xff0c;由若干个结点组成&#xff0c;每个结点包含数据域和指针域。结点结构如下图所示&#xff1a; 一般来讲&#xff0c;链表中只会有一个结点的指针域为空&#xff0c;该结点为尾结点&#xff0c;其他结点的指针域都会存储一个结点的内存地址。链表中也只会有一个结…

C#高级:Winform中的自定义窗体输入

目录 一、多样式输入&#xff08;无封装&#xff09; 1.代码 2.效果 二、单输入框封装 1.使用 2.封装 3.效果 三、组合框批量输入封装 1.使用 2.封装 3.效果 一、多样式输入&#xff08;无封装&#xff09; 1.代码 private async void button1_Click(object send…

memblock内存分配器

一、简述 memblock 是 Linux 内核中的一个内存管理子系统&#xff0c;主要用于在系统启动早期阶段管理物理内存。它在内核初始化期间负责管理内存&#xff0c;直到更复杂的内存管理子系统&#xff08;如伙伴系统&#xff09;接管。 二、工作原理 初始化&#xff1a;在内核启…

【C++滑动窗口】1248. 统计「优美子数组」|1623

本文涉及的基础知识点 C算法&#xff1a;滑动窗口及双指针总结 LeetCode1248. 统计「优美子数组」 给你一个整数数组 nums 和一个整数 k。如果某个连续子数组中恰好有 k 个奇数数字&#xff0c;我们就认为这个子数组是「优美子数组」。 请返回这个数组中 「优美子数组」 的数…

⽂件内容的读写

文件 InputStream &#xff08;字节流读出 抽象类&#xff09; InputStream 只是⼀个抽象类&#xff0c;要使⽤还需要具体的实现类 FileInputStream&#xff08;字节流读出&#xff09; OutputStream&#xff08;字节流写入&#xff09; Reader&#xff08;字符流读入&#xff…

FreeRTOS消息队列实验与出现的问题

目录 实验名字&#xff1a;队列操作实验 1、实验目的 2、实验设计 3、实验工程 4、实验程序与分析 ●任务设置 ● 其他应用函数 ● main()函数 ● 任务函数 ●中断初始化及处理过程 5.程序运行结果分析 6.进行实验移植时所遇到的问题 1.项目中mymalloc等函数缺少 …

el-cascader 使用笔记

1.效果 2.官网 https://element.eleme.cn/#/zh-CN/component/cascader 3.动态加载&#xff08;官网&#xff09; <el-cascader :props"props"></el-cascader><script>let id 0;export default {data() {return {props: {lazy: true,lazyLoad (…

Linux之进程概念(2)

Linux之进程概念&#xff08;2&#xff09; 孤儿进程 父进程如果提前退出&#xff0c;那么子进程后退出&#xff0c;进入Z之后&#xff0c;那该如何处理呢&#xff1f; 父进程先退出&#xff0c;子进程就称之为“孤儿进程” 孤儿进程被1号init进程领养&#xff0c;当然要有in…

1+X应急响应(网络)日志分析:

日志分析&#xff1a; Web日志分析&#xff1a; http协议&#xff1a; http版本演变&#xff1a; http协议工作原理&#xff1a; http协议的特点&#xff1a; http请求报文&#xff1a; http请求方法&#xff1a; http响应报文&#xff1a; UserId&#xff1a;注册网站的序列号…

go-zero(二) api语法和goctl应用

go-zero api语法和goctl应用 在实际开发中&#xff0c;我们更倾向于使用 goctl 来快速生成代码。 goctl 可以根据 api快速生成代码模板&#xff0c;包括模型、逻辑、处理器、路由等&#xff0c;大幅提高开发效率。 一、构建api demo 现在我们通过 goctl 创建一个最小化的 HT…

计算机编程中的设计模式及其在简化复杂系统设计中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 计算机编程中的设计模式及其在简化复杂系统设计中的应用 计算机编程中的设计模式及其在简化复杂系统设计中的应用 计算机编程中的…

latex中,两个相邻的表格,怎样留一定的空白

目录 问题描述 问题解决 问题描述 在使用latex写论文时&#xff0c;经常表格需要置顶写&#xff0c;则会出现两个表格连在一起的情况。下一个表名容易与上面的横线相连&#xff0c;如何通过明令&#xff0c;留出一定的空白。 问题解决 在第二个表格的 \centering命令之后…

leetcode01——合并两个有序数组

0.本题学到的知识 1.python的操作中&#xff0c;哪些是在原数据上进行操作的&#xff1f; 新开辟的行为&#xff1a;list1list1[m:n] 原数据&#xff1a;list1[a:b]list1[m:n] 新开辟&#xff1a;list1list1list2 原数据&#xff1a;list1.append(list2[i]); list1.extend(list…