尽管必须逐一检查每个元素,但如何避免出现此for循环?

时间:2019-07-06 14:15:50

标签: matlab performance for-loop vectorization

使用Matlab R2019a,尽管尺寸包含不同的元素,但仍必须避免检查以下代码中的for循环,以便必须检查每个元素吗? M是具有索引的向量,Inpts.payout是具有数字数据的5D数组。

for m = 1:length(M)-1
    for power = 1:noScenarios
        for production = 1:noScenarios
            for inflation = 1:noScenarios
                for interest = 1:noScenarios
                    if Inpts.payout(M(m),power,production,inflation,interest)<0
                        Inpts.payout(M(m+1),power,production,inflation,interest)=...
                            Inpts.payout(M(m+1),power,production,inflation,interest)...
                            +Inpts.payout(M(m),power,production,inflation,interest);
                        Inpts.payout(M(m),power,production,inflation,interest)=0;
                    end
                end
            end
        end
    end
end

2 个答案:

答案 0 :(得分:1)

删除内部4个循环非常简单。除非您有一个庞大的矩阵Inpts.payout,否则这将更加有效,因为必须生成一个新的索引矩阵。

以下代码从输入数据中提取两个相关的“平面”,对它们进行逻辑处理,然后将其写回:

for m = 1:length(M)-1
    payout_m = Inpts.payout(M(m),:,:,:,:);
    payout_m1 = Inpts.payout(M(m+1),:,:,:,:);
    indx = payout_m < 0;
    payout_m1(indx) = payout_m1(indx) + payout_m(indx);
    payout_m(indx) = 0;
    Inpts.payout(M(m),:,:,:,:) = payout_m;
    Inpts.payout(M(m+1),:,:,:,:) = payout_m1;
end

可以直接使用输入数据矩阵来避免提取“平面”并将其写回。但是,这会产生更复杂的代码。

但是,我们可以通过这种方式轻松避免某些索引操作:

payout_m = Inpts.payout(M(1),:,:,:,:);
for m = 1:length(M)-1
    payout_m1 = Inpts.payout(M(m+1),:,:,:,:);
    indx = payout_m < 0;
    payout_m1(indx) = payout_m1(indx) + payout_m(indx);
    payout_m(indx) = 0;
    Inpts.payout(M(m),:,:,:,:) = payout_m;
    payout_m = payout_m1;
end
Inpts.payout(M(m+1),:,:,:,:) = payout_m1;

答案 1 :(得分:0)

似乎没有办法避免这种情况。我假设每个for lop独立地更改主要计算中使用的变量参数。因此,需要具有这么多的for循环。我唯一的建议是,如果您担心外观,请将嵌套循环转换为函数。不知道这是否对运行时间有帮助。