Working with submodels : One-sided relationship enumeration



One-sided relationship enumeration

One-sided relationship enumeration is a feature specifically to make
more efficient the creation of large rasters. A raster is a grid of pixels.
Each pixel is equivalent in size and shape. Usually, each pixel is square,
though it is also possible to work with other rasters. In this discussion,
we shall consider only square grids.

In a square grid, each pixel has potentially eight neighbours:
north-west, north, north-east, west, east, south-west, south and
south-east. However, pixels at the edge of the grid will have only a subset
of those neighbours. For example a pixel on the northern edge of the grid
will have five neighbours (west, east, south-west, south, and south-west)
and one in the south-west corner will have only three: (north, north-east
and east).

Conventionally in Simile, we represent the pixels as instances of a
multiple-instance submodel. The number of instances is equal to the width
of the grid (in pixels) multiplied by the height. Each pixel has an id
number, equal to the index of its position. The row and column that the
pixel is in can be calculated from the id number, knowing the width of the
grid.

Within each pixel, we can create an eight-instance submodel representing
each possible neighbour. To allow for edge effects, we can make the
existence of each of the eight conditional. Each (possible)
neighbour-instance has a row and column calculated from its position
relative to its parent pixel. Now each pixel has access to a list of its
neighbours.

To use this knowledge, we can create an association submodel,
representing the relationship of "neighbourhood" between the central pixel
and the (up to) eight pixels that border it. Two role arrows are drawn
between the pixel submodel and the neighbourhood submodel, representing the
pixel in the centre and the pixels in the border.

So far, it is important to emphasise that we have followed the procedure
that has been standard in Simile for many years. The final step, yet to be
presented, however, vastly increases the efficiency of the generated
code..

The final step is to create a condition in the neighbourhood model that
evaluates for each pixel whether any given pixel is in the neighbourhood.
Since each pixel has a list of its own neighbours, this condition is
simply:

any( index(1) is {neighbours_ids_border} )

In this expression, neighbours_ids is the list of neighbours, and
index(1) is the index of the pixel that is potentially in the border. The
condition is true (and the relationship therefore exists) for the pixel in
the border, if any of the elements of the list of the neighbour_ids equates
to the index of the pixel.

Previously, this expression would have been written with the equality
operator "==", instead of the key word "is". The new key word has been
introduced in order to invoke the efficient program generation that is
possible for rasters. This is not the only situation that is applicable: in
general, as the name implies, the feature is useful for any situation where
the relationship can be calculated in a loop over only ONE of the roles. In
this case, because each pixel is able to calculate its own list of
neighbours, it is not necessary to take each possible pair of pixels and
determine if they are neighbours. It is from this short cut that the
improvement in efficiency stems.

There is a model in the catalogue on Simulistics
web site, showing all this in practice. If, without looking at the example,
you could create an equivalent model, you are a graduate summa cum
laude
of Simile v4.0 use. The example can be used as a starting-point
for most work on rasters, grid squares and so on.

In: Contents >> Working with submodels >> Association submodels