Initializing help system before first use

Definition of subroutines

We now show a package (file solarraypkg.mos) that defines several versions of a subroutine, solarray, which copies the solution values of an array of decision variables of type mpvar into an array of real of the same size. For each desired number (1-3) and type (integer or string) of array indices we need to define a new version of this subroutine.

package solarraypkg

! **** Integer indices (including ranges) ****
 public procedure solarray(x:array(R:set of integer) of mpvar,
                           s:array(set of integer) of real)
  forall(i in R) s(i):=getsol(x(i))
 end-procedure

 public procedure solarray(x:array(R1:set of integer,
                                   R2:set of integer) of mpvar,
                           s:array(set of integer,
                                   set of integer) of real)
  forall(i in R1, j in R2) s(i,j):=getsol(x(i,j))
 end-procedure

 public procedure solarray(x:array(R1:set of integer,
                                   R2:set of integer,
                                   R3:set of integer) of mpvar,
                           s:array(set of integer,
                                   set of integer,
                                   set of integer) of real)
  forall(i in R1, j in R2, k in R3) s(i,j,k):=getsol(x(i,j,k))
 end-procedure

! ****String indices ****
 public procedure solarray(x:array(R:set of string) of mpvar,
                           s:array(set of string) of real)
  forall(i in R) s(i):=getsol(x(i))
 end-procedure

 public procedure solarray(x:array(R1:set of string,
                                   R2:set of string) of mpvar,
                           s:array(set of string,
                                   set of string) of real)
  forall(i in R1, j in R2) s(i,j):=getsol(x(i,j))
 end-procedure

 public procedure solarray(x:array(R1:set of string,
                                   R2:set of string,
                                   R3:set of string) of mpvar,
                           s:array(set of string,
                                   set of string,
                                   set of string) of real)
  forall(i in R1, j in R2, k in R3) s(i,j,k):=getsol(x(i,j,k))
 end-procedure
end-package

Using the package in a Mosel model (file solarr_test.mos):

model "Test solarray package"
 uses "solarraypkg", "mmxprs"

 declarations
  R1=1..2
  R2={6,7,9}
  R3={5,-1}
  x: array(R1,R2,R3) of mpvar
  sol: array(R1,R2,R3) of real
 end-declarations

! Define and solve a small problem
 sum(i in R1, j in R2, k in R3) (i+j+2*k) * x(i,j,k) <= 20
 forall(i in R1, j in R2, k in R3) x(i,j,k)<=1
 maximize(sum(i in R1, j in R2, k in R3) (i+2*j+k) * x(i,j,k))

! Get the solution array
 solarray(x,sol)

! Print the solution
 forall(i in R1, j in R2, k in R3)
  writeln(" (", i, ",", j, ",", k, ") ", sol(i,j,k), " ", getsol(x(i,j,k)))
 writeln(sol)

end-model

Output produced by this model:

 (1,6,-1) 1 1
 (1,6,5) 0 0
 (1,7,-1) 1 1
 (1,7,5) 0 0
 (1,9,-1) 1 1
 (1,9,5) 0 0
 (2,6,-1) 0,167 0,167
 (2,6,5) 0 0
 (2,7,-1) 0 0
 (2,7,5) 0 0
 (2,9,-1) 0 0
 (2,9,5) 0 0
[1,0,1,0,1,0,0.166667,0,0,0,0,0] 

This example may be classified as a `utility function' that eases tasks occurring in a similar way in several of your models. Another example of such a utility function could be a printing function that simply outputs the solution value of a decision variable with some fixed format (if you apply write/writeln to a decision variable of type mpvar you obtain the pointer of the variable, and not its solution value).

If we again make the comparison with the implementation as a module we see that both ways have their positive and negative points: the implementation as a module is clearly more technical, requiring a considerable amount of C code not immediately related to the implementation of the function itself. However, at the C level we simply check that the two arguments have the same index sets, without having to provide a separate implementation for every case, thus making the definition more general.