稀疏矩阵存储格式设计用于行/Col操作
Sparse matrix storage format designed for row/col manipulation?
我正在使用一个需要访问和存储数据在稀疏矩阵中的程序。矩阵的大约40-60%是非零的,尺寸为14k至22k元素方形。
这是我的问题 - 我将执行行和列操作的 lot 。主要添加,删除和交换。我已经查看了大多数现有的知名稀疏矩阵格式(CRS,CCS,COO,块格式等),并且大多数似乎对这类操作似乎不太容易接受。当您开始添加和删除整个行或列的那一刻,您就必须将所有元素更新到操纵行/col的任一侧,这是我想尝试避免的事情(我已经发生了您可能可以以这样的方式管理元素,以使其在矩阵中的坐标实际上被存储为一对指针到公共行或列索引,并通过简单地增加或减少该值来手动更新数千个元素,从而使自己免于手动更新数千个元素。
那里有类似的东西吗?
我将考虑一个间接层,作为交换,插入和删除行的有效机制。
这将类似于现代操作系统中虚拟内存的管理方式。这只是简短的:物理公羊地址被CPU的内存管理单元映射到线性地址空间中。在主机O/S的帮助下,MMU将实际的物理公羊地址映射到每个过程的虚拟地址空间中。指针和其他对象在每个过程中使用的地址不是真实的RAM地址,它们是虚拟的,并且由硬件MMU单元翻译成实际的物理RAM地址。这就是为什么当系统在空间上短时,主机操作系统可以将空闲过程分为交换文件或分区的原因知道发生了什么。
无论如何,回到主题,这将是一种类似的方法。
考虑一个普通的花园品种二维std::map
。这是您的稀疏矩阵:
std::map<size_t, std::map<size_t, value_t>>
第一个地图的维度或键是行,它为您提供了第二个地图,其尺寸/键是列,最终包含您的值。
这很简单。这里没有大地破坏。但是,如您所知:移动,交换和插入行和柱变成熊。
好吧,让我们介绍自己的个性化MMU:您的地图管理单元。它几乎可以像硬件MMU一样工作:
std::map<size_t, size_t> rows;
std::map<size_t, size_t> columns;
因此,在您的示例中,要查找虚拟行R
的值,列C
:
1)rows[R]
给您"物理"行号。
2)columns[C]
给您"物理"列号。
3)现在,您采用"物理"行和列号,然后转到二维std::map
,并在物理行和列中查找您的值。
那么,我们到达这里吗?好吧,现在移动整个行或列涉及对您的地图管理单元的简单更新。从rows
或columns
映射中删除一个值,然后用其他键,新的"逻辑"行或列将其放回原处。"物理",二维地图中的值保持不变。
就是这样。移动,交换或插入行成为MMU对象上的简单操作。
还有其他两个细节需要照顾:
a)跟踪哪些物理行和列未使用,可以在添加时分配给新的逻辑行和列。
b)根据您的用例,也可能有必要将物理行和列映射回虚拟行和列号。
这两者都是相当微不足道的直接任务,这可能是您的作业。
- 1d 智能指针不适用于语法 (*)++
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 用于访问容器<T>数据成员的正确 API
- 重载操作程序时出错>>用于类中的字符串 memebr
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- C++中的cin.ignore()函数不适用于整个流
- 没有用于初始化C++中的变量模板的匹配构造函数
- 用于C++中带有数组和指针的循环
- 为什么它不适用于Visual 2019的原因
- 使用在用于SFINAE的void_t中具有参数的方法
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 重载==不适用于二进制树
- Insert函数不适用于2 if语句C++
- 用于矢量处理的多个线程
- 使外部项目可用于find_package CMake
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- 为什么模数运算符不适用于该代码
- 并行用于C++17中数组索引范围内的循环
- 将fold表达式与std::一起用于两个元组
- 稀疏矩阵存储格式设计用于行/Col操作