Hello all,
I have a dynamic set "iter" that defines the parameter blend(iter). I would like to take the last value from the blend(iter) when the iter might increase as the simulation goes along.
I know that if we have a deterministic set iter=15, its easy to call blend('15'). But since iter is changing, I am not sure what is the best way to do. I am looking forward to any good idea of doing that.
Thanks,
Jia
The easiest way to get the last item from a indexed parameter
Re: The easiest way to get the last item from a indexed parameter
You can use card(.) operator to get cardinality of a set.
You can do card(iter) to get the last element.
for accessing parameter you can use condition $(ord(iter) eq card(iter)) whenever you want to deal with the last element.
Hope this helps.
- Atharv
You can do card(iter) to get the last element.
for accessing parameter you can use condition $(ord(iter) eq card(iter)) whenever you want to deal with the last element.
Hope this helps.
- Atharv
Re: The easiest way to get the last item from a indexed parameter
Hi Atharv,
Thanks for the answer. Maybe I should put it more clear about "dynamic".
The set "iter" is defined firstly with 15 different numbers /1*15/. So the card(iter) is always 15. But the parameter blend(iter) is dynamic and start to fill the space one by one, while the rest blend(iter) could be 0.
How can I pinpoint the last item that is not zero?
I think of one way:
alias (iter,iter2)
blend(iter)$(ord(iter) eq sum(iter2$blend(iter2),1))
Wondering any other way to do it?
Thanks,
Thanks for the answer. Maybe I should put it more clear about "dynamic".
The set "iter" is defined firstly with 15 different numbers /1*15/. So the card(iter) is always 15. But the parameter blend(iter) is dynamic and start to fill the space one by one, while the rest blend(iter) could be 0.
How can I pinpoint the last item that is not zero?
I think of one way:
alias (iter,iter2)
blend(iter)$(ord(iter) eq sum(iter2$blend(iter2),1))
Wondering any other way to do it?
Thanks,
Last edited by zhj0735 3 years ago, edited 1 time in total.
Re: The easiest way to get the last item from a indexed parameter
Hi Atharv,
Thanks for the answer. Maybe I should put it more clear about "dynamic".
The set "iter" is defined firstly with 15 different numbers /1*15/. So the card(iter) is always 15. But the parameter blend(iter) is dynamic and start to fill the space one by one, while the rest blend(iter) could be 0.
How can I pinpoint the last item that is not zero?
I think of one way:
alias (iter,iter2)
blend(iter)$(ord(iter) eq sum(iter2$blend(iter2),1))
Wondering any other way to do it?
Thanks,
Thanks for the answer. Maybe I should put it more clear about "dynamic".
The set "iter" is defined firstly with 15 different numbers /1*15/. So the card(iter) is always 15. But the parameter blend(iter) is dynamic and start to fill the space one by one, while the rest blend(iter) could be 0.
How can I pinpoint the last item that is not zero?
I think of one way:
alias (iter,iter2)
blend(iter)$(ord(iter) eq sum(iter2$blend(iter2),1))
Wondering any other way to do it?
Thanks,
Re: The easiest way to get the last item from a indexed parameter
You solution "blend(iter)$(ord(iter) eq sum(iter2$blend(iter2),1))" works but is expensive (quadratic effort). You can use .last (see https://www.gams.com/34/docs/UG_SetDefi ... Attributes) but this only works on sets not parameters. So you need to copy your blend to a set:
I also used a singleton set for lastIter. This has the advantage that you can use it without controlling the index, like in "scalar lastBlendValue; lastBlendValue = blend(lastIter);" which might be in handy in your case.
-Michael
Code: Select all
set iter / 1*15 /;
parameter blend(iter);
blend(iter)$(uniform(0,1)<0.1) = uniformInt(1,10);
* Find the last iter in blend<>0:
set sblend(iter) 'set of non-zeros in blend'; sblend(iter) = blend(iter);
singleton set lastIter(iter);
lastIter(sblend) = sblend.last
display lastIter;
-Michael
Re: The easiest way to get the last item from a indexed parameter
Fantastic! Thanks Michael for the best solution as always!bussieck wrote: ↑3 years ago You solution "blend(iter)$(ord(iter) eq sum(iter2$blend(iter2),1))" works but is expensive (quadratic effort). You can use .last (see https://www.gams.com/34/docs/UG_SetDefi ... Attributes) but this only works on sets not parameters. So you need to copy your blend to a set:
I also used a singleton set for lastIter. This has the advantage that you can use it without controlling the index, like in "scalar lastBlendValue; lastBlendValue = blend(lastIter);" which might be in handy in your case.Code: Select all
set iter / 1*15 /; parameter blend(iter); blend(iter)$(uniform(0,1)<0.1) = uniformInt(1,10); * Find the last iter in blend<>0: set sblend(iter) 'set of non-zeros in blend'; sblend(iter) = blend(iter); singleton set lastIter(iter); lastIter(sblend) = sblend.last display lastIter;
-Michael