1

我有一个大循环,我试图计算 DEM (4800x6000) 中每个像素的某些属性。我正在调用一个函数 demPHV,在该函数中我对所有输出结构的计算进行了矢量化处理,该结构具有 26 个字段。我有 4 个内核,但也可以访问多核集群。我想加快运行它所需的几周时间。

Z 是此示例的 dem。R 是 spatialref 对象(例如,一个向量)。latlim 和 lonlim 是美国西部海岸线的 lat 和 long 的向量(在示例中成对)。例如:

Z=rand(48,60);
R=makerefmat(120,40,.5,.5)
latlim=[40:60]';
lonlim=[136:(143-136)/(length(latlim)-1):143]';

然后我原来的循环:

for col=11:size(Z,2)-11
    for row=11:size(Z,1)-11
        dpv=demPHV(Z,R,row,col,latlim,lonlim)

    fn=fieldnames(dpv);
    for k=1:length(fieldnames(dpv))
        DEM_PHV.(fn{k}).{row,col}=dpv.(fn{k});
    end
end

用于并行化的循环:

选项1:

[rows, cols] = meshgrid(12:(size(Z,1)-12), 12:(size(Z,2)-12));
inds = sub2ind(size(Z), rows, cols);
inds = inds(:)';
parfor i=inds(1):inds(end)
       dpv=demPHV(Z,R,i,latlim,lonlim)
end

这包括[r,c]=ind2sub(size(Z),i)在函数 demPHV 中使用的函数。

选项2:

parfor col=11:size(Z,2)-11
    for row=11:size(Z,1)-11
         dpv=demPHV(Z,R,row,col,latlim,lonlim)
    end
end

parfor 需要连续的整数,因此需要进行一些更改。我必须排除边界的 11 行和列,因为我的函数使用周围的像素来计算一些属性。

所以,我的问题:

  1. 您是否希望这两个选项中的任何一个比另一个更快?
  2. parfor 不允许我包含原始循环的第二部分:

    fn=fieldnames(dpv);

    for k=1:length(fieldnames(dpv))

    DEM_PHV.(fn{k}).{row,col}=dpv.(fn{k});

    end

在此期间,我将输出结构分配给另一个变量。最终目标是让变量 DEM_PHV 具有我需要的每个属性的字段,并且每个字段都是矩阵大小(Z),其中每个单元格都是该属性的相应值。我试图让我的函数在矩阵的正确单元格中输出值,但随后我得到一个矩阵大小(Z),[]除了 location 的值之外的所有地方row,col。这似乎是一种非常低效的内存使用......有更好的建议吗?我希望我涵盖了所有内容。感谢您的关注!

4

1 回答 1

0

我得到了以下代码来工作并将每个函数结果存储到一个结构数组中。不过可能有更好的方法,因为现在我需要从结构中的每个字段中提取每个值到它自己的矩阵中。

有没有人建议创建类似的东西:DEM_PHV = struct('field1',[dPHV{:}.field1],'field2',[dPHV{:}.field2])每个字段中的每个矩阵在哪里size(Z)。矩阵中的单元格将包含单个值或一对值,例如 [lat, long]。

dPHV=cell(110,110);
parfor col=11:110%size(Z,2)-11
    for row = 11:110%size(Z,1)-11
       pixel_attributes=demPHV(Z,R,row,col,latlim,lonlim); %function produces structure of variables, each iteration is another pixel
       dPHV{row,col}=structfun(@(x) x,pixel_attributes,'UniformOutput',false)   
    end
end  

编辑:尽管这可能很笨拙,但以下内容可用于重新分配变量。我很乐意接受更流畅的“MATLAB”方式的建议。

% find all field names and get size of output
fn=fieldnames(dPHV{11,11});
[I, J]=size(dPHV);

%initialize final output
for f=1:numel(fn)
    DEM_PHV.(fn{f})=cell(size(dPHV));
end
% loops through datastructure to populate new fields
for i=11:I-11
    for j=11:J-11
        for f=1:numel(fn)
            DEM_PHV.(fn{f}){i,j}=dPHV{i,j}.(fn{f});
        end
    end
end
于 2012-10-28T21:14:48.907 回答