boost中由compressed_matrix分配的空间

时间:2010-09-20 19:37:28

标签: c++ boost sparse-matrix

boost compressed_matrix分配了多少空间?它是否只为非零元素分配空间?如果这是真的,我不明白为什么以下代码给出bad_alloc错误。

namespace bubla = boost::numeric::ublas; 
typedef double value_type; 
typedef bubla::compressed_matrix<value_type> SparseMatrix; 
unsigned int m = 10000*10000; 
SparseMatrix D(m,m,3*m), X; 

它应该只为3 * m = 3 * 10000 * 10000元素分配空间吗?

你能帮忙澄清一下吗? boost中的哪种数据结构可用于仅为非零元素分配空间。其次,如何设置非零元素的值?

非常感谢。

3 个答案:

答案 0 :(得分:1)

请注意,您在上面的示例中将m定义为10000 * 10000,这意味着您尝试分配3亿个双倍或2.4 GB(假设每个双字节为8个字节)。

如果您只想要一个稀疏的10000 x 10000矩阵,只需定义“m = 10000”。

答案 1 :(得分:1)

CRS格式

首先是压缩格式的一分钟介绍。给定矩阵

+---+---+---+---+
| A | 0 | B | 0 |
+---+---+---+---+
| 0 | C | 0 | 0 |
+---+---+---+---+
| 0 | 0 | D | E |
+---+---+---+---+

你可以非常有效地将它存储在压缩行存储(CRS)格式(这是 ublas::compressed_matrix的默认格式),如果存储每行的非零数,列索引和每个非零条目的值:

                     +---+---+---+
number of non-zeros  | 2 | 1 | 2 |
                     +---+---+---+
                     +---+---+---+---+---+
column index         | 0 | 2 | 1 | 2 | 3 |
                     +---+---+---+---+---+
                     +---+---+---+---+---+
value                | A | B | C | D | E |
                     +---+---+---+---+---+

注意:有不同的变体,例如您可以为每一行存储索引到column indexvalue向量中的第一个元素,而不是非零(NNZ)的数量。或者,您可以存储指向新行开始的这些值的指针,依此类推。但是,它们都需要或多或少相同的内存量。

内存要求

CRS格式所需的内存大致是

memoryRequired = numberOfRows * sizeof(index_type) 
                 + NNZ * sizeof(index_type) 
                 + NNZ * sizeof(value_type)

加上一些开销来存储数组的长度,指向数据的指针等等。然而,与数据本身所需的内存相比,并且考虑到压缩矩阵往往非常大(无论如何你都可以使用密集矩阵),这种开销通常可以忽略不计。

为您的例子

您正尝试使用m行,m列和3*m非零条目分配CRS矩阵,其中m10^8。这将需要以下内存量,假设您使用uint32作为索引的类型,并使用double作为条目的类型:

NNZ vector              m * 4 =  381.5 MB
column index vector   3*m * 4 = 1144.4 MB
value vector          3*m * 8 = 2288.8 MB
-----------------------------------------
total                           3814.7 MB

所以你的矩阵已经需要大约4 GB的内存。如果您还想存储一些向量,那么传统桌面计算机很快就会出现内存不足。

答案 2 :(得分:0)

3*m = 300000000