Initializing help system before first use

Use of exists

The Mosel compiler is able to identify sparse loops and optimizes them automatically, such as in the following example:

 declarations
  I=1..1000
  J=1..500
  A: dynamic array(I,J) of real
  x: array(I,J) of mpvar
 end-declarations

 initializations from "mydata.dat"
  A
 end-initializations

 C:= sum(i in I,j in J | exists(A(i,j))) A(i,j)*x(i,j) = 0

Notice that we obtain the same definition for the constraint C with the following variant of the code, but no loop optimization takes place:

 C:= sum(i in I,j in J) A(i,j)*x(i,j) = 0

Here all index tuples are enumerated and the corresponding entries of A are set to 0. Similarly, if not all entries of x are defined, the missing entries are interpreted as 0 by the sum operator (however, as distinct to all other types, the entries of decision variable arrays are not created implicitly when they get addressed).

The following rules have to be observed for efficient use of the function exists, :

  1. The arrays have to be indexed by named sets (here I and J):
     A: dynamic array(I,J) of real              ! can be optimized
     B: dynamic array(1..1000,1..500) of real   ! cannot be optimized
  2. The same sets have to be used in the loops:
     forall(i in I,j in J | exists(A(i,j)))              ! fast
     K:=I; forall(i in K,j in 1..500 | exists(A(i,j)))   ! slow
  3. The order of the sets has to be respected:
     forall(i in I,j in J | exists(A(i,j)))              ! fast
     forall(j in J,i in I | exists(A(i,j)))              ! slow
  4. The exists function calls have to be at the beginning of the condition:
     forall(i in I,j in I | exists(A(i,j)) and i+j<>10)  ! fast
     forall(i in J,j in J | i+j<>10 and exists(A(i,j)))  ! slow
  5. The optimization does not apply to or conditions:
     forall(i in I,j in J | exists(A(i,j)) and i+j<>10)  ! fast
     forall(i in I,j in J | exists(A(i,j)) or i+j<>10)   ! slow