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.

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
     H: hashmap 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, particularly for dynamic arrays:
     forall(i in I,j in J | exists(A(i,j)))              ! fast
     forall(j in J,i in I | exists(H(i,j)))              ! slower
     forall(j in J,i in I | exists(A(i,j)))              ! slowest
  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