代码之家  ›  专栏  ›  技术社区  ›  ggkmath

如何降低matlab“find”函数的内存需求?

  •  1
  • ggkmath  · 技术社区  · 14 年前

    我在Matlab中有一行代码:

      output = find(input);
    

    其中,列向量“output”包含列向量“input”中元素非零的所有索引。例如,如果:

     input = [1 3 4 0 0 2 0];
    

    那么,输出=查找(输入);的结果是:

     output = 
         1
         2
         3
         6
    

    对应于非零数组“input”的第一个(“1”)、第二个(“3”)、第三个(“4”)和第六个(“2”)索引。

    由于我的“输入”数组非常大,这一行代码消耗了我所有的本地RAM加上大量的虚拟内存,导致系统缓慢地爬行。

    有人知道一个好方法(或任何方法)来减少这种操作的内存需求吗?我考虑将“查找”代码放入循环中,但是由于数组“输出”(因此对该数组进行索引)的大小取决于“查找”操作的结果,所以我不知道如何才能这样做。没有想法了。

    提前感谢您的意见/建议。GKK

    2 回复  |  直到 14 年前
        1
  •  2
  •   Jonas    14 年前

    如果您有足够的RAM来容纳一个大小相同的数组 input ,您可以将呼叫替换为 find 通过

    output = 1:length(input);
    output = output(input~=0);
    

    如果 输入 少于2^32-1个元素,可以将其初始化为 uint32 从而进一步节省内存。

    更好的方法可能是转换 输入 数组到 sparse ,如果 输入 包含大量零,然后使用 找到 在这一点上,即

    input = sparse(input);
    output = find(input);
    

    编辑

    执行 找到 分块操作,我将执行以下操作:

    nIn = length(input);
    blockLength = 100000;
    nBlocks = ceil(nIn/blockLength); %# work in chunks of 100k entries
    out = cell(nBlocks,1);
    for i=1:nBlocks
       out{i} = (i-1)*blockLength+1:i*blockLength; %# assign as your favorite integer format here
       out{i} = out{i}(input(out{i})~=0);
    end
    out = cat(1,out{:});
    
        2
  •  3
  •   Amro    14 年前

    如果非零值多于零,则可以使用补码,即: output=find(input==0) 而不是等同于 output=find(input~=0)

    此外,还可以使用逻辑索引,比较:

    >> output1 = find(input);
    >> output2 = (input~=0);
    >> whos output*
      Name         Size            Bytes  Class      Attributes
    
      output1      1x4                32  double               
      output2      1x7                 7  logical    
    

    注意它是如何存储为“booleans”的向量的,每个“booleans”是一个字节(而“double”是8个字节)。