Eigen关于稀疏矩阵

2023-05-16

处理和解决稀疏问题涉及各种模块,总结如下:

模块

头文件

内容

SparseCore

#include <Eigen/SparseCore>

SparseMatrix 和 SparseVector 类、矩阵组装、

基本稀疏线性代数(包括稀疏三角求解器)

SparseCholesky

#include <Eigen/SparseCholesky>

直接用稀疏 LLT 和 LDLT Cholesky 分解来解决稀疏自伴随正定问题

SparseLU

#include<Eigen/SparseLU>

稀疏 LU 分解来解决一般平方稀疏系统

SparseQR

#include<Eigen/SparseQR

用于解决稀疏线性最小二乘问题的稀疏 QR 分解

IterativeLinearSolvers

#include <Eigen/IterativeLinearSolvers>

求解大型一般线性平方问题的迭代求解器(包括自伴随正定问题)

Sparse

#include <Eigen/Sparse>

包含以上所有模块

矩阵稀疏格式

在许多应用中(例如,有限元方法),通常处理非常大的矩阵,其中只有少数系数不为零。 在这种情况下,可以通过使用仅存储非零系数的专用表示来减少内存消耗并提高性能。 这样的矩阵称为稀疏矩阵。

SparseMatrix

SparseMatrix 类是 Eigen 稀疏模块的主要稀疏矩阵表示; 它提供高性能和低内存使用率。 它实现了广泛使用的压缩列(或行)存储方案的更通用的变体。 它由四个紧凑的数组组成:

  • Values:存储非零系数值。
  • InnerIndices:存储非零的行(或列)索引。
  • OuterStarts:为每一列(或行)存储前两个数组中第一个非零的索引。
  • InnerNNZs:存储每列(相应行)的非零数。 inner指的是一个内部向量,它是列主矩阵的列,或行主矩阵的行。 外部这个词指的是另一个方向。

目前,给定内部向量的元素保证总是通过增加内部索引进行排序。 “_”表示可以快速插入新元素的可用空间。 假设不需要重新分配,随机元素的插入因此在 O(nnz_j) 中,其中 nnz_j 是相应内部向量的非零数。 另一方面,在给定的内部向量中插入具有增加内部索引的元素效率更高,因为这仅需要增加相应的 InnerNNZs 条目,即 O(1) 操作。

没有可用空间的情况是一种特殊情况,称为压缩模式。 它对应于广泛使用的压缩列(或行)存储方案(CCS 或 CRS)。 通过调用 SparseMatrix::makeCompressed() 函数,可以将任何 SparseMatrix 转换为这种形式。 在这种情况下,可以注意到 InnerNNZs 数组与 OuterStarts 是冗余的,因为我们等式:InnerNNZs[j] = OuterStarts[j+1]-OuterStarts[j]。 因此,实际上调用 SparseMatrix::makeCompressed() 会释放此缓冲区。

例子

在描述每个单独的类之前,让我们从以下典型示例开始:使用有限差分格式和狄利克雷边界条件在规则 2D 网格上求解拉普拉斯方程 Δu=0。 这样的问题可以数学表达为 Ax=b 形式的线性问题,其中 x 是 m 个未知数的向量(在我们的例子中,像素的值),b 是由边界条件产生的右侧向量,并且 A 是一个 m×m 矩阵,仅包含少数非零元素,这些元素是由 Laplacian 算子离散化产生的。

稀疏矩阵类

SparseMatrix 和 SparseVector 类采用三个模板参数:标量类型(例如,double)、存储顺序(ColMajor 或 RowMajor,默认为 ColMajor)、内部索引类型(默认为 int)。


  

SparseMatrix<std::complex<float> > mat(1000,2000); // declares a 1000x2000 column-major compressed sparse matrix of complex<float>

SparseMatrix<double,RowMajor> mat(1000,2000); // declares a 1000x2000 row-major compressed sparse matrix of double

SparseVector<std::complex<float> > vec(1000); // declares a column sparse vector of complex<float> of size 1000

SparseVector<double,RowMajor> vec(1000); // declares a row sparse vector of double of size 1000

可以使用以下函数查询矩阵的维度:

Standard
dimensions
mat.rows()mat.cols()vec.size()
Sizes along the
inner/outer dimensions
mat.innerSize()mat.outerSize()
Number of non
zero coefficients
mat.nonZeros()vec.nonZeros()

迭代非零系数

可以通过 coeffRef(i,j) 函数随机访问稀疏对象的元素。 但是,此功能涉及相当昂贵的二分搜索。 在大多数情况下,人们只想迭代非零元素。 这是通过外部维度上的标准循环来实现的,然后通过 InnerIterator 迭代当前内部向量的非零值。 因此,必须以与存储顺序相同的顺序访问非零条目。 下面是一个例子:


  

SparseMatrix<double> mat(rows,cols);

for (int k=0; k<mat.outerSize(); ++k)

for (SparseMatrix<double>::InnerIterator it(mat,k); it; ++it)

{

it.value();

it.row(); // row index

it.col(); // col index (here it is equal to k)

it.index(); // inner index, here it is equal to it.row()

}

填充稀疏矩阵

由于 SparseMatrix 的特殊存储方案,在添加新的非零条目时必须特别小心。 例如,单个纯随机插入到 SparseMatrix 的成本是 O(nnz),其中 nnz 是当前非零系数的数量。

创建稀疏矩阵同时保证良好性能的最简单方法是首先构建所谓的三元组列表,然后将其转换为 SparseMatrix。

一下是一个简单的例子


  

typedef Eigen::Triplet<double>T;

std::vector.reserve(estimation_of_entries);

for(...)

{

//...

tripletList.push_back(T(i,j,v_ij));

}

SparseMatrixType mat(rows,cols);

mat.setFromTriplets(tripletList.begin(), tripletList.end());

// mat is ready to go!

The std::vector of triplets might contain the elements in arbitrary order, and might even contain duplicated elements that will be summed up by setFromTriplets(). See the SparseMatrix::setFromTriplets() function and class Triplet for more details.

但是,在某些情况下,可以通过将非零值直接插入目标矩阵来实现稍微更高的性能和更低的内存消耗。 这种方法的典型场景如下图所示:


  

SparseMatrix<double> mat(rows,cols); // default is column major

mat.reserve(VectorXi::Constant(cols,6));

for each i,j such that v_ij != 0

mat.insert(i,j) = v_ij; // alternative: mat.coeffRef(i,j) += v_ij;

mat.makeCompressed(); // optional

第 4 行执行排序插入。 在此示例中,理想情况是第 j 列未满且包含内部索引小于 i 的非零值。 在这种情况下,此操作归结为简单的 O(1) 操作。

调用 insert(i,j) 时,元素 i ,j 必须不存在,否则使用 coeffRef(i,j) 方法,该方法将允许例如累加值。 此方法首先执行二分查找,如果元素不存在,则最后调用 insert(i,j)。 它比 insert() 更灵活,但成本也更高。

第 5 行抑制了剩余的空白空间,并将矩阵转换为压缩的列存储。

支持的运算符和函数

由于其特殊的存储格式,稀疏矩阵无法提供与密集矩阵相同级别的灵活性。 在 Eigen 的稀疏模块中,下面sm表示稀疏矩阵,sv表示稀疏向量,dm表示稠密矩阵,dv表示稠密向量。

Eigen 支持各种稀疏矩阵乘积,总结如下:

  • sparse-dense:

dv2 = sm1 * dv1;

dm2 = dm1 * sm1.adjoint();

dm2 = 2. * sm1 * dm1;

对称稀疏密集。 稀疏对称矩阵与稠密矩阵(或向量)的乘积也可以通过使用 selfadjointView() 指定对称性来优化:


  

dm2 = sm1.selfadjointView<>() * dm1; // if all coefficients of A are stored

dm2 = A.selfadjointView<Upper>() * dm1; // if only the upper part of A is stored

dm2 = A.selfadjointView<Lower>() * dm1; // if only the lower part of A is stored

Block operations

关于读取访问,稀疏矩阵公开与密集矩阵相同的 API,以访问子矩阵,例如块、列和行。 详细介绍见块操作。 然而,出于性能原因,写入子稀疏矩阵的限制要大得多,目前只有列主(分别为行主)稀疏矩阵的连续列集(分别为行)是可写的。 此外,必须在编译时知道这些信息,省去诸如 block(...) 和 corner*(...) 之类的方法。 对 SparseMatrix 进行写访问的可用 API 总结如下:


  

SparseMatrix<double,ColMajor> sm1;

sm1.col(j) = ...;

sm1.leftCols(ncols) = ...;

sm1.middleCols(j,ncols) = ...;

sm1.rightCols(ncols) = ...;

SparseMatrix<double,RowMajor> sm2;

sm2.row(i) = ...;

sm2.topRows(nrows) = ...;

sm2.middleRows(i,nrows) = ...;

sm2.bottomRows(nrows) = ...;

 

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

Eigen关于稀疏矩阵 的相关文章

  • Reactor 3 参考文档

    Reactor 3 参考文档 Stephane Maldini 64 smaldini Simon Basl 64 simonbasle3 2 0 BUILD SNAPSHOT xff08 译者加 xff09 本文档的一些典型的名词如下 x
  • 在Ubuntu/Linux环境下使用MySQL:开放/修改3306端口、开放访问权限

    操作系统 Ubuntu 17 04 64位 MySQL版本 MySQL 5 7 一 查看3306端口是否开放 netstat an grep 3306 如果看到下图这样的 说明端口并未打开 nbsp 二 修改访问权限 进入目录 etc my
  • 使用nohup后台运行并获取pid

    启动 nohup command gt command log 2 gt amp 1 amp echo gt command pid 注意 nohup运行后需要按回车键 xff0c 不然强行ctrl 43 C会退出 停止 kill 96 c
  • YAML——基本语法

    功能 编辑 YAML的语法和其他高级语言类似 xff0c 并且可以简单表达清单 散列表 xff0c 标量等数据形态 4 它使用空白符号缩进和大量依赖外观的特色 xff0c 特别适合用来表达或编辑数据结构 各种配置文件 倾印调试内容 文件大纲
  • 推荐一些socket工具,TCP、UDP调试、抓包工具

    推荐一些socket工具 xff0c TCP UDP调试 抓包工具 转载 还记得我在很久很久以前和大家推荐的Fiddler和Charles debugger么 他们都是HTTP的神器级调试工具 xff0c 非常非常的好用 好工具能让你事半功
  • Docker学习笔记(3)-- 如何使用Dockerfile构建镜像

    Dockfile是一种被Docker程序解释的脚本 xff0c Dockerfile由一条一条的指令组成 xff0c 每条指令对应Linux下面的一条命令 Docker程序将这些Dockerfile指令翻译真正的Linux命令 Docker
  • Ubuntu部署安装Jenkins

    1 概述 安装jenkins需要有java的环境 xff0c 因此需要先安装jdk 2 安装OpenJDK 11 2 1 安装JDK 更新apt sudo apt get update 安装 sudo apt get install ope
  • softmax函数详解

    softmax函数 1 softmax函数理解 我们知道Logistic回归只能进行二分类 xff0c 因为它的随机变量的取值只能是0或者1 xff0c 那么如果我们面对多分类问题怎么 办 xff1f 比如要将一封新收到的邮件分为垃圾邮件
  • PX4 固件改造【持续更新】

    1 修改IMU三轴信息 xff1a 可修改两个CPP文件里的三轴信息 如下图 xff09 xff1a 修改的信息如下 xff08 见下图 xff09 xff1a accel x accel samples 61 accel x xff1b
  • 网络部分之Physical Layer

    2 Physical Layer Physical layer需要将 data 转换成 signal xff0c 所以需要 2 steps xff1a Step 1 xff0c 叫做 information coding xff0c 来对数
  • 树莓派 软键盘matchbox-keyboard 安装

    我的树莓派3b在第二步和第三步执行都 出现问题 但是顺序执行下去 最终虚拟键盘还是可以使用 1 安装必需文件 sudo apt get install libfakekey dev libpng dev y 2 安装编译虚拟键盘ato sa
  • Pi3 E14中国版 MySQL安装详细过程

    硬件环境 xff1a 树莓派 xff1a Pi3 E14中国版 Usb键鼠 10 1 1280 800电视机 xff08 集成HDMI xff09 wifi路由器 笔记本电脑 软件环境 xff1a 树莓派Linux raspberrypi
  • 在Ubuntu下进行安卓开发遇到“insufficient permissions for device: user in plugdev group; ”问题的解决办法

    开发环境 Ubuntu 16 04 IDE Android Studio 开发语言 Java 在接入设备进行联机调试的时候 遇到了这样的问题 insufficient permissions for device user in plugd
  • 谈谈技术在日常工作生活中的重要性

    我从事 技术方面 的工作也有10多年了 从最初的一个软件工程师 xff0c 也逐渐成长为项目经理 xff0c 部门经理 无论岗位怎么变换 xff0c 但是我还是没有离开技术方面的工作 xff0c 一直对技术的研究有很大热情 Csdn是非常棒
  • JSP中的网页编写格式——MIME TYPE?

    一 首先 xff0c 我们要了解浏览器是如何处理内容的 在浏览器中显示的内容有 HTML 有 XML 有 GIF 还有 Flash 那么 xff0c 浏览器是如何区分它们 xff0c 决定什么内容用什么形式来显示呢 xff1f 答案是 MI
  • 安卓开发05:Activity之间链接和传递参数

    Activity之间链接和传递参数主要通过Intent安卓的一个对象来实现 首先我们创建一个MainActivity xff1a java view plain copy print package com example androidt
  • 安卓开发06:布局-线性布局 LinearLayout

    LinearLayout把视图组织成一行或一列 子视图能被安排成垂直的或水平的 线性布局是非常常用的一种布局方式 请看一个布局例子 xff1a html view plain copy print lt LinearLayout xmlns
  • 可以带到2015年的几点思考

    1 自己的事情永远得自己出头 我从小就是个很独立的人 我不知道这种独立是什么时候培养起来的 xff0c 但清楚的记得一件事情 上小学那会儿 xff0c 有一年母亲生病了 xff0c 在医院 xff0c 家里就我一个人 xff0c 有时候 x
  • 纪事2011—中国,建大,家,我

    前言 2011 年就要真的成为我记忆了 xff0c 我一直在想该怎样总结我的2011 xff0c 我的2011留下的是什么 xff0c 收获的又是什么 xff0c 这365天的句号我该怎么画上 xff0c 是圆是扁 xff0c 还是有缺口
  • 用java做的一个小游戏—黑白反斗棋(适合菜鸟)

    用Java做的一个小游戏 xff0c 黑白反斗棋 xff0c 我玩过了5 5和10 10的 是学习之后做的 xff0c 不是自己原始开发的 import java awt Color import java awt FlowLayout i

随机推荐

  • 我的精神分裂——普通青年用二-B的方式走文艺的范儿

    一直以来都是以一种低沉的文笔在写些我的垃圾生活 xff0c 垃圾感想 xff0c 每次都会放那些特定的音乐 xff0c 那是一种心境 xff0c 那些音乐带着我的手在敲动 今天我想换种音乐 xff0c 猜猜我在放什么音乐 xff0c 很Hi
  • 读书随笔(1)——《计较是贫穷的开始》

    xff08 读书之后写感 xff0c 本该是读书之后自然的一个延续 xff0c 但我却很少这样了 xff0c 这不能说是一个极其坏的习惯 xff0c 虽不知道我究竟能不能改了 xff0c 但还是希望能尽可能的写写 xff0c 对自己想法有个
  • 2012年终随笔

    时至年终 xff0c 按我此前的惯例 xff0c 该写篇年终总结性的文章 xff0c 在之前末日说沸沸扬扬的时候 xff0c 我在想是否该早点写 xff0c 写个末日遗言什么的 xff0c 但还是没有写 xff0c 觉得如果真的末日来临 x
  • Tomcat多端口映射配置

    1 多端口映射配置 在server xml中 xff0c 找到 lt Connector gt 标签 xff0c 默认情况下会有一个 8080 端口的 lt Connector gt 标签 xff1a lt Connector port 6
  • 10个艰难的Java面试题与答案

    10个最难回答的Java面试题 这是我收集的10个较难回答的 Java 面试题 这些问题主要来自 Java 核心部分 不涉及 Java EE 相关问题 这些问题都是容易在各种 Java 面试中被问到的 1 为什么 wait xff0c no
  • Spring Security 5.x兼容多种密码加密方式

    1 spring security PasswordEncoder spring security 5不需要配置密码的加密方式 xff0c 而是用户密码加前缀的方式表明加密方式 xff0c 如 xff1a MD5 88e2d8cd1e92f
  • linux把进程或线程绑定到特定cpu核上

    绑定进程到cpu核上运行 查看cpu有几个核 使用cat proc cpuinfo 查看cpu信息 xff0c 如下两个信息 xff1a processor xff0c 指明第几个cpu处理器cpu cores xff0c 指明每个处理器的
  • Suse重启samba指令

    重启前先查看后台进程 linux jzp3 home w210412 ps aux grep smbd root 4400 0 0 1 2 308428 22372 Ss 18 23 0 00 usr sbin smbd D F root
  • uIP和LwIP背后的那个牛逼男人

    在公众号给大家介绍过Uip和LwIP xff0c 如果使用过这两种TCP IP协议栈 xff0c 那么你一定会熟悉一个人Adam Dunkels亚当 邓克尔 瑞典计算机科学院的教授 xff0c 这两种开源的协议栈都出自他手 xff0c 现在
  • 一张表看懂uIP和lwIP的区别

    我们给大家介绍过目前比较流行的开源TCP IP开源协议栈uIP和lwIP 这两种都是由瑞典计算机科学研究院开发的 xff0c 广泛应用于嵌入式系统中 因为全功能的TCP IP协议是很庞大的 xff0c 在资源紧张的嵌入式上是很难实现的 xf
  • 小猿助你freeRTOS驱动开发

    主要介绍在移植好的基于NXP之kinetis K64 43 freeRTOS平台上添加Modbus驱动 对freeRTOS不懂或者移植不懂的可以看看之前公众号的文章 准备工作 xff1a 1 xff0c 基于之前移植好的K64 43 fre
  • 告诉过你PID很重要,你不听

    曾经在公众号 xff0c 多次提到在控制系统中经常用到的PID控制 xff0c 也在培训中讲过PID的应用和在软件中的实现以及调试 xff0c 但是现实中还是有很多工程师对PID很陌生 xff0c 如果你是搞电力电子 xff0c 电力变换
  • Windows 使用 VNC 远程连接 Ubuntu 桌面版

    前言 工作需要使用 Windows 远程桌面版的 Ubuntu xff0c 原来使用的 TeamViewer 现在经常被检测为商业用途 xff0c 就很麻烦 因此 xff0c 现在转战使用 VNC 进行远程 使用步骤参考地址 xff1a 法
  • IP第十天笔记 - - - BGP

    BGP 边界网关协议 AS 自治系统 由单一机构或组织管理的一系列IP网络及其设备的集合 1 网络范围太大 xff0c 协议跑不过来 xff0c 需要进行划分 xff1b 2 自治管理 为了方便区分和标定不同的AS xff0c 我们给每一个
  • Makefile(1)

    1 前言 有幸拜读了http blog csdn net haoel article details 2888 http www cnblogs com Anker p 3242207 html http www groad net bbs
  • 解决vnc客户端不能拷贝粘贴

    在vnc窗口里输入如下命令 vncconfig nowin amp 在一个node的vnc里发现vncconfig nowin amp 不工作 xff0c 但是vncconfig amp 工作 https blog csdn net qq
  • shell的等号两边不能有空格

    shell的等号在赋值的时候两边不能有空格 xff0c 在比较的时候两边必须有空格
  • uCOS上下文切换,PendSV中断函数

    摘自 xff1a http www stmcu org module forum thread 384142 1 1 html 介绍一 xff1a 移植详解1和2中主要讲了移植需要用到的基础知识 xff0c 本文则对具体的移植过程进行介绍
  • Eigen稀疏线性求解

    在 Eigen 中 xff0c 当系数矩阵稀疏时 xff0c 有多种方法可用于求解线性系统 由于此类矩阵的特殊表示 xff0c 应特别注意以获得良好的性能 有关 Eigen 中稀疏矩阵的详细介绍 xff0c 请参阅稀疏矩阵操作 此页面列出了
  • Eigen关于稀疏矩阵

    处理和解决稀疏问题涉及各种模块 xff0c 总结如下 xff1a 模块 头文件 内容 SparseCore include lt Eigen SparseCore gt SparseMatrix 和 SparseVector 类 矩阵组装