Matrix 如何在倍频程中有效地存储和操作稀疏二进制矩阵?

Matrix 如何在倍频程中有效地存储和操作稀疏二进制矩阵?,matrix,octave,sparse-matrix,binary-matrix,Matrix,Octave,Sparse Matrix,Binary Matrix,我试图在GNU八度音阶中操作稀疏二进制矩阵,它使用的内存比我预期的要多,而且相关的稀疏矩阵函数的行为方式与我希望的不同。我明白了,这表明这个矩阵应该消耗更多的内存,但有助于解释(仅)这种情况的一部分 对于一个稀疏的二进制矩阵,我想不出任何方法使倍频程不存储值数组(它们总是隐式地1,因此不需要存储)可以这样做吗?倍频程似乎总是消耗值数组的内存 一个简化的示例演示了这种情况:创建随机稀疏矩阵,将其转换为“二进制”: 显示了这种情况。如果spones()创建了一个存储类数组double,并且如果所有索

我试图在GNU八度音阶中操作稀疏二进制矩阵,它使用的内存比我预期的要多,而且相关的稀疏矩阵函数的行为方式与我希望的不同。我明白了,这表明这个矩阵应该消耗更多的内存,但有助于解释(仅)这种情况的一部分

对于一个稀疏的二进制矩阵,我想不出任何方法使倍频程不存储值数组(它们总是隐式地
1
,因此不需要存储)可以这样做吗?倍频程似乎总是消耗值数组的内存

一个简化的示例演示了这种情况:创建随机稀疏矩阵,将其转换为“二进制”:

显示了这种情况。如果
spones()
创建了一个存储类数组
double
,并且如果所有索引都是32位的(即TotalStorageSize-RowIndexes-ColumnIndexes==NumNonZero*sizeof(double)),则消耗的大小与下面列出并展开的存储机制一致,不必要地存储这些值(所有
1
s作为
double
s)占这个3%稀疏对象消耗的总内存的一半以上

在撰写这个问题时,我把这个问题弄得一团糟(时间太长了),我发现了一些局部的解决办法,所以我将“自我回答”(仅)问题的一部分,以保持连续性(希望如此),但我没有找到对主要问题的充分答案:

如何创建高效存储的(“无/隐式值”)八度二进制矩阵?

关于存储格式的其他背景如下

Octave文档说使用格式。这似乎意味着存储以下数组(扩展,使用规范的
标签和调整):

  • 值(
    A
    ),存储类大小的非零(NNZ)条目的数量
  • 行号
    IA
    ),索引大小的NNZ条目(希望
    int64
    ,但可能
    int32
  • 每列的开始(
    JA
    ),列数加1个索引大小的条目)

在这种情况下,对于仅二进制存储,我希望有一种方法可以完全避免存储数组(
a
),但我无法找到它。

完全公开:如上所述,在撰写此问题时,我发现了一种减少内存使用的解决方法,因此我“自我回答”这是本文的一部分,但它仍然不能完全令人满意,所以我仍然在听一个更好的关于稀疏二进制矩阵存储的实际答案,而不需要一个简单、臃肿、不必要的值数组

要从类似数字的值中获取类似二进制的值并减少这种情况下的内存使用,请使用由
logical(X)
创建的“逻辑”存储。例如,从上面构建

logicalmys = logical(mys);
创建一个
稀疏布尔矩阵
,该矩阵占用更少的内存(值数组为1字节
逻辑
,而不是8字节

使用
whos\u line\u格式向
whos
信息添加更多信息有助于说明情况:默认字符串包括7个属性中的5个(有关更多信息)。我使用的是格式字符串

whos_line_format(" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:8; %e:10; %t:20;\n")
添加“元素”和“类型”的显示(与“类”不同)

因此,
whosmyslogicalmys
显示如下内容

 Attr Name            Size      Bytes Class      Elements                 Type
 ==== ====            ====      ===== =====      ========                 ==== 
      mys          1024x1024   391100 double        32250        sparse matrix
      logicalmys   1024x1024   165350 logical       32250   sparse bool matrix
因此,这显示了
稀疏矩阵
稀疏布尔矩阵
之间的区别。然而,
logicalmys
消耗的总内存与实际存储NNZ布尔数组(1字节)是一致的,即:

  • totalMemory减去RowIndex减去ColumnOffset,剩下NNZ字节
在数量上

  • 165350-32250*4-1025*4==32250
因此,我们仍在存储32250个元素,所有元素都是
1
。此外,如果您将
1
-元素之一设置为零,则会减少报告的存储!为了获得一个好的时间,请尝试:选择一个非零元素,例如
(42,1)
,然后将其归零:
logicalmys(42,1)=0;
然后
whos

我希望这是正确的,这为那些可能感兴趣的人澄清了一些事情。欢迎评论、更正或实际答案

whos_line_format(" %a:4; %ln:6; %cs:16:6:1; %rb:12; %lc:8; %e:10; %t:20;\n")
 Attr Name            Size      Bytes Class      Elements                 Type
 ==== ====            ====      ===== =====      ========                 ==== 
      mys          1024x1024   391100 double        32250        sparse matrix
      logicalmys   1024x1024   165350 logical       32250   sparse bool matrix