GAMS Singleton Set Issue

There is a nasty problem with the singleton set in GAMS. A singleton set is a set that can contain only zero or one element. Adding more elements implies replacement. I don't use it very often. Here is a reason why. 

Consider the small example:


set i /i1*i20/;
parameter p(i);
p(i) = uniform(0,10);

* find last element >= 5
scalar threshold /5/;
singleton set k(i);
loop(i,
  k(i)$(p(i)>=threshold) =
yes;
);

display p,k;


I would expect to see as output for k the last element in p(i) that is larger than 5. However, we see:


----     12 PARAMETER p  

i1 1.717, i2 8.433, i3 5.504, i4 3.011, i5 2.922, i6 2.241, i7 3.498, i8 8.563
i9 0.671, i10 5.002, i11 9.981, i12 5.787, i13 9.911, i14 7.623, i15 1.307, i16 6.397
i17 1.595, i18 2.501, i19 6.689, i20 4.354


---- 12 SET k

( EMPTY )


The problem is that the dollar-controlled assignment to a singleton set is incorrectly implemented. The singleton set is cleared before the assignment without looking at the dollar condition. We can see this by using an alternative formulation of the loop:


loop(i,
 
if(p(i)>=threshold,
     k(i) =
yes;
  )
);



Now the output is correct:


----     19 PARAMETER p  

i1 1.717, i2 8.433, i3 5.504, i4 3.011, i5 2.922, i6 2.241, i7 3.498, i8 8.563
i9 0.671, i10 5.002, i11 9.981, i12 5.787, i13 9.911, i14 7.623, i15 1.307, i16 6.397
i17 1.595, i18 2.501, i19 6.689, i20 4.354


---- 19 SET k

i19

Conclusion

 

Beware when using singleton sets in GAMS: it can deliver unexpected results. A workaround for a dollar-controlled assignment is using an if statement.

Comments

Popular posts from this blog

Gove confirms mandatory housebuilding targets for councils will be abolished in face of Tory rebellion – UK politics live

Kotak Mahindra Bank Recruitment 2022 Released for Graduate Candidates And Apply Online