Modifying the Sparsity
Questions
Now that we’ve glanced at the execution engine’s inner workings, you may be wondering about the following questions.
Does sparse execution influence the results of a model?
Does AIMMS have sparse versions of operators that are dense by nature?
Sparse execution is correct
Sparse execution never changes the results of your model. AIMMS only applies sparse intersection or sparse union when it is applicable. It does not in any way influence the results of your model compared to simply considering all the possible combinations of the running indices, but only the efficiency with which these results are obtained.
Sparsity modifiers
AIMMS does support sparse versions of some dense operators, but this
time the sparse versions will in general lead to different results.
Adding $
characters to dense operators modify these operators to
sparse ones. That is why we call the $
characters added to these
operators sparsity modifiers.
Left and right operands
Sparsity modifiers may be added to the lefthand side of a dense operator, to the righthand side, or to both. It causes the operator only to return a nonzero result if the associated operand(s) are nonzero. Such a change to an operator may, however, change its results in a way you may, or may not, want.
A first example: the /$
operator
Let us now consider a few examples where such a modification is applicable. The first example of using a sparsity modifier is in the efficient guarding against division by zero errors. Without the use of sparsity modifiers, we can accomplish this as follows.
! Leave A(i,j) zero when C(i,j)+D(i,j) is zero in order to
! avoid division by zero errors.
! This is accomplished by repeating the denominator in the condition.
A(i,j) := ( B(i,j) / (C(i,j)+D(i,j)) ) $ (C(i,j)+D(i,j)) ;
In the example, we only divide by C(i)+D(i)
if this sum is nonzero.
Note that this subexpression is actually computed twice. AIMMS provides
a notational convenience in the form of $
sparsity modifiers as
follows.
! Leave A(i,j) zero when C(i,j)+D(i,j) is zero in order to
! avoid division by zero errors.
! This is accomplished by using the /$ division operator
! which sparsely skips 0.0's.
A(i,j) := B(i,j) /$ (C(i,j)+D(i,j)) ;
The /$
operator is defined as the /
operator except when the
right hand side is 0.0. In that case, the $
sparsity modifier
defines it as 0.0. An added advantage is that the subexpression
C(i)+D(i)
is only computed once.
The merge operator :=$
A second example is in the merging of new results in a set of existing results. Without the use of a sparsity modifier you can accomplish this as follows.
! Only overwrite elements of E(i,j) when the result
! F(i,j) + G(i,j) is nonzero.
! This is accomplished by repeating the RHS of the
! assignment as a domain condition.
E((i,j)  F(i,j)+G(i,j)) := F(i,j)+G(i,j) ;
Using the $
sparsity modifier this can be equivalently obtained as
follows.
! Only overwrite elements of E(i,j) when the result
! F(i,j) + G(i,j) is nonzero.
! This is accomplished by using the $ sparsity
! modifier on the assignment operator:
E(i,j) :=$ F(i,j)+G(i,j) ;
Where allowed?
this table summarizes the operators to which
the $
sparsity modifier can be applied, and whether it can be
applied to the lefthand side operand, to the righthand side operand,
or to both.
Operator 
Sparsity modifier allowed 






yes 
yes 

no 
no 

no 
yes 

no 
no 

yes 
yes 

yes 
yes 

yes 
no 

yes 
yes 

no 
no 
Modifying iterative operators
In addition to modifying the behavior of binary operators, the $
sparsity modifier can also be applied to iterative operators. The effect
in this case is that the iterative operator in the presence of a $
modifier will only be applied to tuples for which the expression yields
a nonzero value.
Example: the Min$
operator
The third and final example of the $
sparsity modifier provided here
is on the Min
operator. Suppose you want to find the smallest
nonzero distance between a particular node and other nodes. This can be
modeled as follows:
! Find the smallest nonzero distance:
MinimalDistance(i) := Min(j  Distance(i,j), Distance(i,j));
The ‘nonzero’ restriction is taken care of by repeating the argument of
the Min
operator in its domain condition. By using the $
sparsity modifier we can shorten the above as follows:
! Find the smallest nonzero distance:
MinimalDistance(i) := Min$(j, Distance(i,j));
Where allowed?
this table summarizes the iterative
operators to which the $
sparsity modifier can be applied.
Iterative operator 
Sparsity modifier allowed 




yes 

yes 
no 


yes 

no 

yes 
yes 

Statistical operators (see also this table) 
yes 

no 
Other logical operators (see also this table) 
no 
Usage of sparsity modifiers
To conclude, we can say that the $
sparsity modifier is notationally
a convenience which you may or may not like. In the end it is up to you
whether you use it or not. You decide this by weighing its advantage and
disadvantages. Our view on this is discussed briefly below.
Advantages
Using sparsity modifiers has the following advantages.
It enables a more compact notation. In the examples above, the domain condition is replaced by a strategically placed
$
sparsity modifier thereby reducing the overall expression. Many models have with multiple line subexpressions and with these the reduction is not insignificant.It is more efficient. There are usually abundant zeros in a model. You want them ignored so that the corresponding entries do not appear in the results. In addition, you want them to be ignored as quickly as possible: so as not to waste any computation time on them.
Disadvantages
As with any new notation it takes time to get used to it. This holds
both for you as a modeler and also for the people you want to
communicate your model to. In order to alleviate this disadvantage you
may want to add a few brief comments on the modified operators you use
such as
:=$ operator used here to merge the result into the existing data
.