在 Matlab 中使用 '.*' 操作时出现内存不足错误

Out of memory error when using '.*' operation in Matlab

下面是我在m.file中使用的代码:

for idx = i_start:i_end
    CheckTemp = (timeTick > time_tr(idx)) .* (timeTick <= time_tr(idx));
    CheckTemp2 = find(CheckTemp);
    IdxS = min(CheckTemp2);
    IdxE = max(CheckTemp2);
    ......

timeTick数组是一个双数组,大约100MBidx大约是20004000。因为我一步一步查看m文件,发现在循环之前,我的memroy commit charge是:817M/5422M。有很多免费的space,对吧?

但是我的 Matlab v6.5 告诉我:Error in '.*', out of memory...这让我很困惑。

另外,我之前是一行行执行代码的。并且没有发生错误。我真的不知道为什么。希望有人能帮忙...

如果您需要更多信息,请发表评论。

阅读 memory 的文档,您会注意到连续可用地址 space 是限制。您的 Matlab 版本不能使用您的全部内存,它被限制为 32 位地址 space。

我建议切换到最新的 64 位版本的 matlab 或开源克隆版 Octave。

MATLAB memory management page 有一些有用的信息,例如您系统上的进程内存限制。一般来说,在 运行 内存密集型操作之前 运行 clear all 是个好主意。因为,正如 Daniel 指出的那样,MATLAB 分配数组的能力是基于连续的可用内存,并且 clear 不保证垃圾回收,因此重新启动 MATLAB 可能是个好主意,尤其是在旧版本上。

附带说明一下,我怀疑您会发现 CheckTemp = (timeTick > time_tr(idx)) .* (timeTick <= time_tr(idx)); 总是会给您一个 logical 零数组。 .* 在逻辑数组上的作用类似于二进制 & 并且您可以通过比较一种情况下的 > 和另一种情况下的 <= 来保证不会有重叠。也许您打算对其中一个索引使用 time_tr(idx-1) 之类的东西?

如果timeTicktimeTr排序,可以这样做:

  1. 没有创建与timeTick
  2. 一样大的额外数组
  3. 单次遍历两个数组timeTicktimeTr
  4. 在 Matlab 2015b 中使用以下代码(在我的计算机上)在 150MB 双数组 timeTick 和 2000 条目数组 timeTr 中大约需要 0.29 秒。

代码如下(请注意,您必须设置 time_tr(end+1) = inf 才能使我的代码正常工作)。

%This code requires last entry of time_tr to be inf, eg. time_tr(end+1)=inf;
n_tick = length(timeTick);
n_tr   = length(time_tr);

IdxS = NaN(n_tr, 1);
IdxE = NaN(n_tr, 1);

i_tick = 1;
i_tr   = 1;

window_start_i_tick = 1; 
window_end    = time_tr(1);

while(i_tick <= n_tick)
   t = timeTick(i_tick);
   if(t > window_end)
      IdxS(i_tr) = window_start_i_tick;
      IdxE(i_tr) = i_tick - 1;

      window_start_i_tick = i_tick;

      i_tr = i_tr + 1;
      while(t > time_tr(i_tr)) %take care of case that we skip past a window/windows
          i_tr = i_tr + 1;
      end

      window_end = time_tr(i_tr);        
   end    
   i_tick = i_tick + 1;
end
IdxS(i_tr) = window_start_i_tick;
IdxE(i_tr) = i_tick;