Sunday, August 10, 2008

GAMS bug in ifthen

   1  scalar a,b,c;
2 a=1;
3 b=0;
4 c = ifthen(b<=0,1,a/b);
5
6 display a,b,c;




This gives:


**** Exec Error at line 4: division by zero (0)
**** Exec Error at line 4: IfThen: cannot be called with special value UNDF in arg3



Work-around: don't use ifthen in cases like this, but something like:
*
* alternative 1: split into two parts
*
c=1;
c$(b>0) = a/b;
*
* alternative 2 :use an extra condition inside the ifthen
*
c = ifthen(b<=0,1,[a/b]$b);
*
* alternative 3: use an if statement
*
if(b<=0,
c=1;
else
c=a/b;
);


Some of these reformulations may be slower. So remember ifthen does not do what one would expect e.g. when comparing with AMPL's if-then-else: both branches are evaluated and can lead to runtime errors. I believe this can be fixed by a smarter implementation of ifthen. That would both benefit the usefulness, predictability and performance of this construct.

Note: ifthen has similar limitations when used inside NLP equations. Unfortunately it cannot be used to prevent domain errors etc.

I hit this problem when automatically translating Excel's if() function to GAMS. Excel implements the if() as one would expect and unfortunately this does not translate directly into the GAMS ifthen() function.