1

I know vectorized code is faster than using loops, so I've been trying to so with this code. I was hoping someone could show me how to improve these for and if loops. The program is meant to calculate the power load curve of a house, taking into account whether the different appliances are switch on or switch off at different hours of day, month, and year.

The ProbFanSummerWd, ProbCellChargerSummerWd, etc. are probability matrices used to decide if the appliance is on or off based on a previous random "choose"; TotalLoad is the resultant power curve. This function is repeated many times within a larger program and consumes much time.

How could I improve those for and if loops? How can I replace them with vectorization?

I hope someone will help me. Thank you very much.

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
DBinJP
  • 247
  • 5
  • 13

1 Answers1

4

It is helpful to work in small steps when vectorizing code. For example, in this code, you should start by trying only to vectorize only one if-statement in the innermost loop.

Take for example:

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

If you use the iterator in the code, I like to think about my goal is to replace all references to "h" (the iterator) with a ":" (vectorized version of the iterator).

If you do not use the iterator in the code, it is even easier. For example, the above code does not use the iterator, so we can simply rewrite the same in vectorized form, as:

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

That's it! No loops necessary!

Some other helpful vectorization tricks are available here. Once you have vectorized code, you can make it much faster using the GPU :)