我有一个大循环,我试图计算DEM(4800x6000)中每个像素的某些属性。我正在调用一个函数demPHV,其中我已经向所有计算输出了一个包含26个字段的结构。我有4个核心,但也可以访问多核集群。我想加快运行这几周所需的时间。
Z是此示例的dem。 R是spatialref对象(例如,矢量)。 latlim和lonlim是美国西部海岸线的纬度和长度的矢量(在示例中组成了对)。 例如:
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
这包括在函数demPHV中使用的函数中的[r,c]=ind2sub(size(Z),i)
。
选项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行和列,因为我的函数使用周围的像素来计算一些属性。
所以,我的问题:
parfor不允许我包含原始循环的第二部分:
fn=fieldnames(dpv);
for k=1:length(fieldnames(dpv))
DEM_PHV.(fn{k}).{row,col}=dpv.(fn{k});
end
在此期间我将输出结构分配给另一个变量。最终目标是让变量DEM_PHV具有我需要的每个属性的字段,并且每个字段都是矩阵大小(Z),其中每个单元格是该属性的对应值。我试图让我的函数输出矩阵的正确单元格中的值,但是除了位置[]
的值之外,我得到一个带row,col
的矩阵大小(Z)。这似乎是一种非常低效的内存使用......任何更好的建议?我希望我涵盖了一切。
谢谢你的期待!
答案 0 :(得分: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
编辑:因为这可能是kludgey,以下工作用于重新分配变量。我很乐意采取一种更为“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