Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 用于寻址大型阵列的内存不足算法_Matlab_File Io_Memory Management_Out Of Memory - Fatal编程技术网

Matlab 用于寻址大型阵列的内存不足算法

Matlab 用于寻址大型阵列的内存不足算法,matlab,file-io,memory-management,out-of-memory,Matlab,File Io,Memory Management,Out Of Memory,我正在尝试处理一个非常大的数据集。我有k=~4200个矩阵(大小不同),它们必须进行组合比较,跳过非唯一和自比较。每个k(k-1)/2比较都会产生一个矩阵,该矩阵必须针对其父级进行索引(即,可以找出它的来源)。实现这一点的便捷方法是(三角形地)用每次比较的结果填充一个k×k单元数组。这些平均为~100x~100个矩阵。使用单精度浮点运算,它的总容量达到400 GB。 我需要1)生成一个或多个单元格数组,而无需将整个内容放在内存中;2)以类似方式访问其元素(及其元素)。由于依赖MATLAB的eva

我正在尝试处理一个非常大的数据集。我有k=~4200个矩阵(大小不同),它们必须进行组合比较,跳过非唯一和自比较。每个k(k-1)/2比较都会产生一个矩阵,该矩阵必须针对其父级进行索引(即,可以找出它的来源)。实现这一点的便捷方法是(三角形地)用每次比较的结果填充一个k×k单元数组。这些平均为~100x~100个矩阵。使用单精度浮点运算,它的总容量达到400 GB。
我需要1)生成一个或多个单元格数组,而无需将整个内容放在内存中;2)以类似方式访问其元素(及其元素)。由于依赖MATLAB的
eval()
以及循环中出现的
save
clear
,我的尝试效率低下

for i=1:k
    [~,m] = size(data{i});
    cur_var = ['H' int2str(i)];
    %# if i == 1; save('FileName'); end; %# If using a single MAT file and need to create it.
    eval([cur_var ' = cell(1,k-i);']);
    for j=i+1:k
        [~,n] = size(data{j});
        eval([cur_var '{i,j} = zeros(m,n,''single'');']);
        eval([cur_var '{i,j} = compare(data{i},data{j});']);
    end
    save(cur_var,cur_var); %# Add '-append' when using a single MAT file.
    clear(cur_var);
end
我做的另一件事是在
mod((I+j-1)/2,max(factor(k(k-1)/2))==0时执行拆分。这将结果划分为最大数量的相同大小的块,这似乎是合乎逻辑的。索引稍微复杂一点,但也不太糟糕,因为可以使用线性索引


有人知道/看到更好的方法吗?

您可以通过分别分配文件名来摆脱
eval
clear
调用

for i=1:k
    [~,m] = size(data{i});
    file_name = ['H' int2str(i)];    
    cur_var = cell(1, k-i);
    for j=i+1:k
        [~,n] = size(data{j});
        cur_var{i,j} = zeros(m, n, 'single');
        cur_var{i,j} = compare(data{i}, data{j});
    end
    save(file_name, cur_var); 
end
如果需要保存的变量采用不同的名称,请使用
-struct
选项进行保存

str.(file_name);
save(file_name, '-struct', str); 

这是一个结合快速运行和使用最小内存的版本

我使用fwrite/fread,这样您仍然可以使用
parfor
(这一次,我确保它可以工作:)


在这个问题中,我/我们正在尝试制作一个内存版本/fast/:使用
EVAL
创建具有动态生成名称的变量是一种不好的做法,请使用
STRUCT
和动态字段引用:不幸的是,
save()
不能在
parfor
@reve\u etrange:Oops中调用。啊,那么你必须使用例如fwrite。
%# assume data is loaded an k is known

%# find the index pairs for comparisons. This could be done more elegantly, I guess.
%# I'm constructing a lower triangular array, i.e. an array that has ones wherever
%# we want to compare i (row) and j (col). Then I use find to get i and j
[iIdx,jIdx] = find(tril(ones(k,k),-1));

%# create a directory to store the comparisons
mkdir('H_matrix_elements')
savePath = fullfile(pwd,'H_matrix_elements');

%# loop through all comparisons in parallel. This way there may be a bit more overhead from
%# the individual function calls. However, parfor is most efficient if there are 
%# a lot of relatively similarly fast iterations.
parfor ct = 1:length(iIdx)

   %# make the comparison - do double b/c there shouldn't be a memory issue 
   currentComparison = compare(data{iIdx(ct)},data{jIdx{ct});

   %# create save-name as H_i_j, e.g. H_104_23
   saveName = fullfile(savePath,sprintf('H_%i_%i',iIdx(ct),jIdx(ct)));

   %# save. Since 'save' is not allowed, use fwrite to write the data to disk
   fid = fopen(saveName,'w');

   %# for simplicity: save data as vector, add two elements to the beginning
   %# to store the size of the array
   fwrite(fid,[size(currentComparison)';currentComparison(:)]);  % ' #SO formatting

   %# close file
   fclose(fid)
end



%# to read e.g. comparison H_104_23
fid = fopen(fullfile(savePath,'H_104_23'),'r');
tmp = fread(fid);
fclose(fid);

%# reshape into 2D array.
data = reshape(tmp(3:end),tmp(1),tmp(2));