The easiest way to get the last item from a indexed parameter

Problems with syntax of GAMS
Post Reply
zhj0735
User
User
Posts: 16
Joined: 4 years ago

The easiest way to get the last item from a indexed parameter

Post by zhj0735 »

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
abhosekar
Moderator
Moderator
Posts: 295
Joined: 3 years ago

Re: The easiest way to get the last item from a indexed parameter

Post by abhosekar »

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
zhj0735
User
User
Posts: 16
Joined: 4 years ago

Re: The easiest way to get the last item from a indexed parameter

Post by zhj0735 »

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,
Last edited by zhj0735 3 years ago, edited 1 time in total.
zhj0735
User
User
Posts: 16
Joined: 4 years ago

Re: The easiest way to get the last item from a indexed parameter

Post by zhj0735 »

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,
abhosekar wrote: 3 years ago 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
User avatar
bussieck
Moderator
Moderator
Posts: 1033
Joined: 7 years ago

Re: The easiest way to get the last item from a indexed parameter

Post by bussieck »

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:

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;
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
zhj0735
User
User
Posts: 16
Joined: 4 years ago

Re: The easiest way to get the last item from a indexed parameter

Post by zhj0735 »

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:

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;
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
Fantastic! Thanks Michael for the best solution as always!
Post Reply