MATLAB Answers


How to make functions run in parts of for loop

Asked by Nils Norlander on 10 Feb 2017
Latest activity Edited by dpb
on 11 Feb 2017
Hello world!
I'm making a script to calculate the energy balance of a small electricity grid with PV, ESS, EV etc. for all hours of 2016. In this script I want certain calculations and simulations to run for the summer months t = (2161:6552) and others for the winter months.
Is there a way to include functions for certain parts of the year?
Also, I want certain tasks (storing ESS) to be performed at certain hours during the 24h of a day, is it possbile to be this specific without calculating what hours of the 8760 this should occur?
Warm thanks!


How do your data look like?
I have load data and PV production for 8760 hours in column vectors. Max energy storage capacity of houses and batteries and charge/discharge power.
This is parts of the code.
for i = 1:5
E_vp = E_vp+ P_vp_ch;
E_load2(i) = E_load(i) + P_vp_ch;
for i = 6:9
if E_load(i) > Allowed_winter
E_load2(i) = E_load(i)-E_vp;
for i = 10:15
if E_pv(i) >= E_load(i)
Ex_pv = E_pv(i)-E_load(i);
E_load2(i) = 0;
if E_bat < E_bat_max
if (0 < Ex_pv(i)) && (Ex_pv(i)) <= P_bat
E_bat = (min(E_bat + Ex_pv(i), P_bat));
E_bat2(i) = E_bat;
Ex_pv = Ex_pv-E_bat;
Pv_out(i) = Ex_pv;
elseif Ex_pv > P_bat
E_bat = min(E_bat + ExcessPV, E_bat_max);
Ex_pv(i) = Ex_pv(i)-E_bat;
E_bat2(i) = E_bat;
elseif E_pv(i) < E_load(i)
E_load2(i) = E_load(i)-E_pv(i);
if E_bat < E_bat_max
E_bat = min(E_bat+P_bat, E_bat_max);
E_load2(i) = E_load2(i)+ Ebat;
on 10 Feb 2017
If you'd store the data timestamps and use a table, you can likely do all without any loops or specific magic numbers at all...or at least cut it down to very few loops with only a couple of cases using logical addressing vectors for the two if...else...end branches.
Actually, given the description of "...have data and PV production for 8760 hours in column vectors", what are the magic numbers in the above loops of 1:5, 6:9, and 10:15 supposed to represent? They're surely not related to hours on further consideration as my initial reaction was as they don't cover the range at all.
Also the first loop has a very peculiar-looking expression of
E_vp = E_vp+ P_vp_ch;
inside where the LH side isn't defined a priori yet is also in the expression RHS. Plus, it's all in the loop and there are no subscripts making it dependent upon the loop index at all. It likely isn't doing what's intended one would guess.

Sign in to comment.

1 Answer

Answer by D. Plotnick on 10 Feb 2017

I don't know if there is a way to avoid having a bunch of if, elseif, else statements, although the idea of logical indexing is not a bad way of going (loops are something to avoid where possible). But, for simplifying the way you code, the below example should serve you well. You can write your code as a function and terminate the main function with an end (important). You can then write your special case functions below, again making sure to terminate them with an end statement. You can then call those cases from within the loop without as much code splatter. When you want a new case, just add its function below, and then use the appropriate if conditions to call it.
Note, you can also write functions that are called from within the case-functions.
function out = rootFun(in)
out = zeros(15,1);
for ii = 1:15
time = 24*rand(1); % lets just make up a random time
if ii < 5
out(ii) = summer(in(ii),time);
elseif ii>=5 && ii<10
out(ii) = winter(in(ii),time);
out(ii) = default(in,time);
function out = summer(in,time)
out = 2*in;
if time<12
out = timefun(out);
function out = winter(in,time)
out = sqrt(in);
if time > 8 && time <= 16.5
out = timefun(out);
function out = default(in,~)
out = in;
function out = timefun(in)
out = -in;


Sign in to comment.