Flow of Control
In a calc section, model statements are normally executed sequentially. Flow of control statements can be used to alter the execution order of statements. In effect, this gives you a programming, or scripting, capability within the LINGO environment.
@IFC and @ELSE
These statements provide you with conditional IF/THEN/ELSE branching capabilities. The syntax is as follows:
@IFC( <conditional-exp>:
statement_1[; …; statement_n;]
[@ELSE
statement_1[; …; statement_n;]]
);
with the @ELSE block of statements being optional in case a pure if statement is desired.
Note: | Be aware of the use of the letter ‘C’ in @IFC. This is to distinguish the flow of control if statement (@IFC) from the arithmetic if (@IF). |
To illustrate, the following sample code uses if/else blocks as part of a binary search for a key value in an array:
@IFC( KEY #EQ# X( inew):
loc = inew;
@else
@ifC( key #lt# x( inew):
ie = inew;
@else
ib = inew;
);
);
@FOR
You’ve encountered the @FOR set looping statement previously as a way to generate constraints in the model section. @FOR is also allowed in the calc section to perform looping. The main difference is that @FOR does not generate constraints when used in the calc section. Instead, it immediately executes any assignment statements contained within its scope. The following example shows a @FOR loop extracted from a portfolio model. The loop is used to solve the portfolio model for a number of different levels of desired return. For each level of return, the model minimizes variance, and the variance is stored for later use.
@FOR( POINTS( I):
! Compute new return level;
RET_LIM = RET_MIN + (I-1)*INTERVAL;
! Re-solve the model;
@SOLVE();
! Store the return value;
YRET( I) = RET_LIM;
! Store the variance too;
XSTD( I) = VARIANCE^0.5;
);
@WHILE
The @WHILE statement is used for looping over a group of statements until some termination criterion is met. The syntax is as follows:
@WHILE( <conditional-exp>: statement_1[; …; statement_n;]);
As long as the conditional expression is true, the @WHILE function will keep looping over its block of statements.
As an example, the following code uses an @WHILE loop to search for a key value in an array as part of a binary search procedure:
@while( key #ne# x( loc):
inew = @floor( ( ie + ib) / 2);
@ifc ( key #eq# x( inew):
loc = inew;
@else
@ifC( key #lt# x( inew):
ie = inew - 1;
@else
ib = inew + 1;
);
);
);
In this case, the loop executes until the current value selected from the array, X(LOC), is equal to the key value, KEY.
@BREAK
The @BREAK statement is used to break out of the current loop. Execution resumes at the first statement immediately following the end of the current loop. The @BREAK statement is valid only within @FOR and @WHILE loops in calc sections and does not take any arguments. As an example, we extend the @WHILE loop in the binary search example above to include an @BREAK statement that will be executed when the key value can’t be found:
@while( key #ne# x( loc):
!exit loop if key can’t be found;
@ifc( ie – IB #LE# 1:
@PAUSE( 'Unable to find key!!!');
@break;
);
inew = @floor( ( ie + ib) / 2);
@ifc ( key #eq# x( inew):
loc = inew;
@else
@ifC( key #lt# x( inew):
ie = inew - 1;
@else
ib = inew + 1;
);
);
);
@STOP( [‘MESSAGE’])
The @STOP statement terminates execution of the current model. The @STOP statement is valid only within calc sections and takes on optional text argument. When an @STOP is executed, LINGO will display error message 258:
[Error Code: 258]
Model execution halted. STOP statement encountered.
If a text argument is included in the @STOP, then it will also be displayed as part of this error message.
As an example, we extend the @WHILE loop in the binary search example above to include an @STOP statement that will be executed when the key value can’t be found:
@while( key #ne# x( loc):
!exit if key can’t be found;
@ifc( ie –IB #LE# 1:
@STOP( 'Unable to find key!!!');
);
inew = @floor( ( ie + ib) / 2);
@ifc ( key #eq# x( inew):
loc = inew;
@else
@ifC( key #lt# x( inew):
ie = inew;
@else
ib = inew;
);
);
);