【问题标题】:Vectorization for and if loops向量化 for 和 if 循环
【发布时间】:2012-04-17 15:24:47
【问题描述】:

我知道矢量化代码比使用循环更快,所以我一直在尝试使用此代码。我希望有人能告诉我如何改进这些forif 循环。该程序旨在计算房屋的电力负荷曲线,同时考虑不同电器在一天、一个月和一年的不同时间打开或关闭。

ProbFanSummerWdProbCellChargerSummerWd 等是概率矩阵,用于根据先前的随机“选择”来决定设备是打开还是关闭; TotalLoad 是合成的功率曲线。 这个函数在一个较大的程序中会重复很多次,并且会消耗很多时间。

如何改进forif 循环?如何用矢量化替换它们?

我希望有人能帮助我。非常感谢。

HourCount = 0;
for DayYear = 1:size(Season,2)                              %LOOP - ONE YEAR

    if Season(DayYear) == 1                                 %LOOP - SUMMER SEASON

        if WeekDay(DayYear)>=1 && WeekDay(DayYear)<=5       %SUMMER WEEKDAY

            for Hour = 1:24                                 %LOOP - ONE DAY
                HourCount = HourCount+1;

                for h = 1:NumHouse                          %LOOP - HOUSE

                    Choose = rand(1);                   %CellCharger
                    if Choose <= ProbCellChargerSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowCellCharger;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByCellCharger;
                    end
                    Choose = rand(1);                       %Fan
                    if Choose <= ProbFanSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowFan;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByFan;
                    end
                    Choose = rand(1);                       %Fridge
                    if Choose <= ProbFridgeSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowFridge;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByFridge;
                    end
                    Choose = rand(1);                       %Heater
                    if Choose <= ProbHeaterSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowHeater;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByHeater;
                    end
                    Choose = rand(1);                       %Iron
                    if Choose <= ProbIronSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowIron;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByIron;
                    end
                    Choose = rand(1);                       %LampKitchen
                    if Choose <= ProbLampKitchenSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowLampKitchen;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByLampKitchen;
                    end
                    Choose = rand(1);                       %LampRoom
                    if Choose <= ProbLampRoomSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowLampRoom;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByLampRoom;
                    end
                    Choose = rand(1);                       %Radio
                    if Choose <= ProbRadioSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowRadio;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByRadio;
                    end
                    Choose = rand(1);                       %TV20
                    if Choose <= ProbTvSummerWd(Hour)
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowTv;
                    else
                        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByTv;
                    end
                end
            end

【问题讨论】:

    标签: matlab if-statement for-loop vectorization


    【解决方案1】:

    在对代码进行矢量化时,分步进行很有帮助。例如,在这段代码中,您应该首先尝试仅对最内层循环中的一个 if 语句进行向量化。

    举个例子:

    for h = 1:NumHouse                          %LOOP - HOUSE
      Choose = rand(1);                   %CellCharger
      if Choose <= ProbCellChargerSummerWd(Hour)
        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ PowCellCharger;
      else
        TotalLoad(1,HourCount) = TotalLoad(1,HourCount)+ StandByCellCharger;
      end
    end
    

    如果您在代码中使用迭代器,我想我的目标是将所有对“h”(迭代器)的引用替换为“:”(迭代器的矢量化版本)。

    如果你不在代码中使用迭代器,那就更简单了。比如上面的代码没有使用迭代器,所以我们可以简单的改写成向量化的形式,如下:

    Choose = rand(1, NumHouse);                   %CellCharger
    ChooseIdx = (Choose <= ProbCellChargerSummerWd(Hour));
    TotalLoad(1,HourCount) = TotalLoad(1,HourCount) + ...
                             ChooseIdx .* PowCellCharger + ...
                             ~ChooseIdx .* StandByCellCharger;
    

    就是这样!无需循环!

    其他一些有用的矢量化技巧是available here。一旦你有了矢量化代码,你可以让它更快using the GPU :)

    【讨论】:

    • 非常感谢您的 cmets Mike Fineli,他们对我很有帮助!!!
    猜你喜欢
    • 2015-07-19
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 2013-07-21
    • 1970-01-01
    相关资源
    最近更新 更多