James,
The crux is that you are making a lot of comparisons (in the range of card(h) x card(h)) in the equation body. Also, you are doing that for every z where the condition is completely independent from z.
It is faster to precompute a mapping set outside the equation body.
Basically you want for every pair (h,non_vre) from the quation domain, the corresponing elements of h_alias. So you could take the dollar condition from the equation to get a 3 dimensional mapping map(h,non_vre,h_alias):
version 1:
set map1(h,non_vre,h);
map1(h,non_vre,h_alias) = ord(h_alias) ge (ord(h) - gen_minup(non_vre)+1) and ord(h_alias) lt ord(h);
eq_uc_gen_minup1(h,z,non_vre) .. sum(map1(h,non_vre,h_alias), var_up_units(h_alias,z,non_vre)) =L= var_com_units(h,z,non_vre);
While that speeds up the generation of the equation, calculatig the mapping map1 is expensive.
You can speed that up using some tricks in combination with lag and lead operators:
You mention that gen_minup(non_vre) takes at most a value of 24. That means for a particular h (let’s say h100), you do not have to look at h_alias=h1…h8760 but only at the 24 preceeding elements h76…h99. This is a bit tricky but doable:
version 2:
set map2(h,non_vre,h)
hh(h) max minup hours / h1*h24 /;
map2(h,non_vre,h_alias+(ord(h)-gen_minup(non_vre)))$[hh(h_alias) and ord (h_alias)<gen_minup(non_vre)] = yes;
I attached an example, that generates some dummy models consisting only of that particular equation (plus a dummy objective). It allows easy experiments with the different formulations. I also enabled profiling (https://www.gams.com/latest/docs/UG_GamsCall.html#GAMSAOprofile) in this example. You don’t say anything about the cardinality of sets z and non_vre. With cardinality 5 for both sets we get a the following profile summary
--- Profile Summary (38 records processed)
167.421 0.429GB 38 Equation eq_uc_gen_minup (219000)
27.141 0.017GB 22 Assignment map1 (463887)
0.703 0.475GB 40 Equation eq_uc_gen_minup1 (219000)
0.703 0.491GB 42 Equation eq_uc_gen_minup2 (219000)
...
Generating the original equation takes 167.421 seconds. This is reduced to 0.703 seconds with a precomputed mapping where computing the mapping like in version 1 takes 27.141 seconds while in version 2 this step takes about 0.1 seconds and is too fast to show up in the profile summary.
I hope this helps!
Fred
james.gms (2.66 KB)