1

ベクトル化されたコードはループを使用するよりも高速であることを知っているので、このコードでそうしようとしています。for誰かがこれらとifループを改善する方法を教えてくれることを望んでいました. このプログラムは、家の電力負荷曲線を計算することを目的としており、さまざまな電化製品が日、月、年のさまざまな時間にオンまたはオフになるかどうかを考慮します。

、などはProbFanSummerWdProbCellChargerSummerWd以前のランダムな「選択」に基づいてアプライアンスがオンかオフかを決定するために使用される確率行列です。TotalLoad結果の電力曲線です。この関数は、より大きなプログラム内で何度も繰り返され、多くの時間を消費します。

forそれらとifループをどのように改善できますか? それらをベクトル化に置き換えるにはどうすればよいですか?

誰かが私を助けてくれることを願っています。どうもありがとうございました。

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
4

1 に答える 1

4

コードをベクトル化するときは、小さなステップで作業すると便利です。たとえば、このコードでは、最も内側のループで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;

それでおしまい!ループは必要ありません!

他のいくつかの役立つベクトル化のトリックはここで利用できます。コードをベクトル化したら、GPUを使用してコードをはるかに高速化できます:)

于 2012-04-17T15:44:31.600 に答える