2012-04-17 74 views
1

我知道矢量化的代碼比使用循環更快。所以我一直試圖用這個和平的計劃來做到這一點。我希望有人能告訴我如何改善這些和如果循環。該計劃旨在計算房屋的功率負載曲線,同時考慮到不同設備在一天,每月,每年的不同時段開啓或關閉。 ProbFanSummerWd,ProbCellChargerSummerWd等是基於先前的隨機「選擇」來決定設備是打開還是關閉的概率矩陣用途。 TotalLoad是合成的功率曲線。 這個函數在一個更大的程序中重複多次,並且消耗很多時間。 有沒有什麼建議可以改善那些和如果循環?也許將它們替換爲矢量化形式。 希望有人能幫助我。 非常感謝您矢量化和如果循環

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

這有利於向量化代碼時,一小步一小步工作。例如,在這段代碼中,您應該首先嚐試僅在最內層循環中僅矢量化一個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 :)

+0

非常感謝您的意見Mike Fineli,他們對我非常有幫助! – 2012-04-19 15:52:30

1

添加到Mike的答案,我建議你訪問this link。您可以在那裏找到一個非常有趣且經常使用的矢量化技巧(稱爲Tony's Trick)的解決方案。