We’ve seen many examples in this chapter showing how arrays are indexed. So it might not seem necessary to have a section devoted to discussing how to index arrays. It is true that normally you would simply reference elements in an array using integer values for each subscript. But there are enough other ways to index arrays that it is worth spending some time to talk about them.
1-index
For array dimensions specified using integers, Modelica uses indices starting with 1. Some languages choose to use zero as the starting index, but it is important to point out from the start that Modelica follows the 1-index convention.
Obviously, the most directly way to index an array is to use an integer. For an array declared as:
Real x[5,4];
we can index elements of the array by providing an integer between 1 and 5 for the first subscript and 1 and 4 for the second subscript.
But it is worth pointing out that Modelica allows the subscripts to be vectors. To understand how vector indices work, first consider the following matrix:
In Modelica, such an array would be declared as follows:
parameter Real B[3,3] = [1, 2, 3; 4, 5, 6; 7, 8, 9];
Imagine we wish to extract a submatrix of B
as follows:
parameter Real C[2,2] = [B[1,1], B[1,2]; B[2,1], B[2,2]]; // [1, 2; 4, 5];
We could extract the same submatrix more easily using vector subscripts as follows:
parameter Real C[2,2] = B[{1,2},{1,2}]; // [1, 2; 4, 5];
By using vector subscripts we can extract or construct arbitrary sub-arrays. This is where Range Notation can be very useful. The same submatrix extraction could also be represented as:
parameter Real C[2,2] = B[1:2,1:2]; // [1, 2; 4, 5];
In our Chemical System examples, we saw how enumerations can be
used to specify array dimensions. Furthermore, we saw how the values
specified by an enumeration
type can be used to index the array.
In general, for an enumeration
like the following:
type Species = enumeration(A, B, X);
and then declare an array where that enumeration
is used to
specify a dimension, e.g.,
Real C[Species];
then we can use the enumeration values, Species.A
, Species.B
and Species.X
as indices. For example,
equation
der(C[Species.A]) = ...;
We can use the Boolean
type in much the same way as an
enumeration
. Given an array declared with Boolean
for a
dimension:
Real C[5,Boolean];
We can then use boolean values to index that dimension, e.g.,
equation
der(C[1,true]) = ...;
der(C[1,false]) = ...;
end
¶When specifying a subscript for an array, it is legal to use end
in the subscript expression. In this context, end
will take on
the value of the highest possible value for the corresponding array
dimension. The use of end
within expressions allows easy
reference to array elements with respect to the last element rather
than the first. For example, to reference the second from the last
element in a vector, the expression end-1
can be used a subscript.
Remember that end
takes on the value of the highest possible index
for the corresponding array dimension. So for the following
array:
Integer B[2,4] = [1, 2, 3, 4; 5, 6, 7, 8];
The following expressions would evaluate as follows:
B[1,end] // 4
B[end,1] // 5
B[end,end] // 8
B[2,end-1] // 7
There is another sophisticated way of indexing arrays in Modelica. But it doesn’t make sense to talk about it just yet. We will see it later when we start our discussion of Arrays of Component.