是否有更优雅的方式来编写这些循环?

时间:2016-01-17 14:49:58

标签: matlab coding-style

我有一个脚本需要运行一些参数。我有兴趣在参数更改时探索结果,因此我在顶部定义了几个scan数组,将整个代码包装在多个for loops中,并将参数值设置为当前扫描值。

这很容易出错并且不够优雅。更改代码的过程是:1)在顶部重置scan个变量,2)注释掉例如b = scan2(j2)和3)取消注释b=b0

什么是允许将变量设置为数组,然后运行所有此类组合的代码的更好方法?我的代码示例现在:

close all
clear all

%scan1 = linspace(1,4,10);
scan1 = 0;
scan2 = linspace(0,1,10);
scan3 = linspace(-1,0,10);

for j3 = 1:length(scan3)
  for j2 = 1:length(scan2)
    for j1 = 1:length(scan1)

      a = a0;
      %b = scan2(j2);
      b = b0;
      %c = c0;
      c = scan3(j3);
      d = scan2(j2);

      %(CODE BLOCK THAT DEPENDS ON variables a,b,c,d...)

    end

  end

end

2 个答案:

答案 0 :(得分:4)

基于this idea使用一个for循环来模拟多个循环,我试着让它适应你的情况。在实现良好的内存效率和可用性的同时,此解决方案比使用单独的for循环要慢。

%define your parameters
p.a = 1;
p.b = linspace(1,4,4);
p.c = linspace(11,15,5);
p.d = linspace(101,104,4);
p.e = 5;
iterations=structfun(@numel,p);
iterator=cell(1,numel(iterations));
for jx = 1:prod(iterations)
    [iterator{:}]=ind2sub(iterations(:).',jx);%.'
    %This line uses itertor to extract the corresponding elemets of p and creates a struct which only contains scalars.
    q=cell2struct(cellfun(@(a,b)(a(b)),struct2cell(p),iterator(:),'uniform',false),fieldnames(p));
    %__ (CODE THAT DEPENDS ON q.a to q.e here) __

end

对于我测试的场景,它在每次迭代时增加0.0002 s以下的计算开销,总计为0.0002.*prod(iterations)

答案 1 :(得分:0)

一种方法是使用ndgrid制作包含所有参数组合的单个向量。对于足够大的参数扫描,这可能会成为一个内存问题,但在其他方面至少要更加清晰,只需要一个循环而后面的代码中不需要重新分配:

a0vec = 1;
b0vec = linspace(1,4,4);
c0vec = linspace(11,15,5);
d0vec = linspace(101,104,4);
e0vec = 5;

[a0s,b0s,c0s,d0s,e0s] = ndgrid(a0vec,b0vec,c0vec,d0vec,e0vec);    
N = numel(a0s);

for j = 1:N

    a0 = a0s(j);
    b0 = b0s(j);
    c0 = c0s(j);
    d0 = d0s(j);
    e0 = e0s(j);

    %__ (CODE THAT DEPENDS ON a0 - e0 here) __

end

仍然希望看到你的建议!