A non-record array can be regarded as a collection of type compatible values, section 6.7. An array of records may contain scalar record values whose elements differ in their dimension sizes, but apart from that they must be of the same type. Such heterogenous arrays may only be used completely, sliced as specified, or indexed. An array of arrays must have the same dimension sizes for all of the arrays (with the same exception for records). Modelica arrays can be multidimensional and are “rectangular”, which in the case of matrices has the consequence that all rows in a matrix have equal length, and all columns have equal length.
Each array has a certain dimensionality, i.e., number of dimensions. The degenerate case of a scalar variable is not really an array, but can be regarded as an array with zero dimensions. Vectors have one dimension, matrices (sing. matrix) have two dimensions, etc.
So-called row vectors and column vectors do not exist in Modelica and cannot be distinguished since vectors have only one dimension. If distinguishing these is desired, row matrices and column matrices are available, being the corresponding two-dimensional entities. However, in practice this is seldom needed since the usual matrix arithmetic and linear algebra operations have been defined to give the expected behavior when operating on Modelica vectors and matrices.
Modelica is a strongly typed language, which also applies to array types. The number of dimensions of an array is fixed and cannot be changed at run-time. However, the sizes of array dimensions can be computed at run-time.
The fixed number of array dimensions permits strong type checking and efficient implementation. The non-fixed sizes of array dimensions on the other hand, allow fairly generic array manipulation code to be written as well as interfacing to standard numeric libraries implemented in other programming languages.
An array is allocated by declaring an array variable or calling an array constructor. Elements of an array can be indexed by Integer, Boolean, or enumeration values.
The Modelica type system includes scalar number, vector, matrix (number of dimensions, ndim=2), and arrays of more than two dimensions.
[There is no distinction between a row and column vector.]
The following table shows the two possible forms of declarations and defines the terminology. C is a placeholder for any class, including the built-in type classes Real, Integer, Boolean, String, and enumeration types. The type of a dimension upper bound expression, e.g. , , , …in the table below, need to be a subtype of Integer or EB for a class EB that is an enumeration type or subtype of the Boolean type.
Colon (:) indicates that the dimension upper bound is unknown and is a subtype of Integer. The size of such a variable can be determined from its binding equation, or the size of any of its array attributes, see also section 12.4.5. The size cannot be determined from other equations or algorithm.
Upper and lower array dimension index bounds are described in section 10.1.1.
An array indexed by Boolean or enumeration type can only be used in the following ways:
Subscripted using expressions of the appropriate type (i.e. Boolean or the enumerated type).
Binding equations of the form x1 = x2 are allowed for arrays independent of whether the index types of dimensions are subtypes of Integer, Boolean, or enumeration types.
Modelica form 1 | Modelica form 2 | # dims | Designation | Explanation |
---|---|---|---|---|
C x; | C x; | Scalar | Scalar | |
C[] x; | C x[]; | Vector | -vector | |
C[EB] x; | C x[EB] | Vector | Vector indexed by EB | |
C[, ] x; | C x[, ]; | Matrix | matrix | |
C[, , , ] x; | C x[, , , ]; | Array | General array |
A component declared with array dimensions, or where the element type is an array type, is called an array variable. It is a component whose components are array elements (see below). For an array variable, the ordering of its components matters: The :th element in the sequence of components of an array variable x is the array element with index k, denoted x[k]. All elements of an array have the same type. An array element may again be an array, i.e., arrays can be nested. An array element is hence referenced using indices in general, where is the number of dimensions of the array.
A component contained in an array variable is called an array element. An array element has no identifier. Instead they are referenced by array access expressions called indices that use enumeration values or positive integer index values.
[Example: The number of dimensions and the dimensions sizes are part of the type, and shall be checked for example at redeclarations. Declaration form 1 displays clearly the type of an array, whereas declaration form 2 is the traditional way of array declarations in languages such as Fortran, C, C++.
It is possible to mix the two declaration forms although it might be confusing.
The reason for this order is given by examples such as:
Using a type for a and b in this way is normal, and substituting a type by its definition allows c.
A vector y indexed by enumeration values
]
Zero-valued dimensions are allowed, so: C x[0]; declares an empty vector, and: C x[0, 3]; an empty matrix. Some examples of array dimensions of size one are given in table 10.2.
Modelica form 1 | Modelica form 2 | # dims | Designation | Explanation |
---|---|---|---|---|
C[1] x; | C x[1]; | Vector | 1-vector, representing a scalar | |
C[1, 1] x; | C x[1, 1]; | Matrix | -matrix, representing a scalar | |
C[, 1] x; | C x[, 1]; | Matrix | -matrix, representing a column | |
C[1, ] x; | C x[1, ]; | Matrix | -matrix, representing a row |
The type of an array of array is the multidimensional array which is constructed by taking the first dimensions from the component declaration and subsequent dimensions from the maximally expanded component type. A type is maximally expanded, if it is either one of the built-in types (Real, Integer, Boolean, String, enumeration type) or it is not a type class. Before operator overloading is applied, a type class of a variable is maximally expanded.
[Example:
The components p1 and p2 have identical types.
]
[Automatic assertions at simulation time:
Let A be a declared array and i be the declared maximum dimension size of the di-dimension, then an assert statement assert(i >= 0, ) is generated provided this assertion cannot be checked at compile time. It is a quality of implementation issue to generate a good error message if the assertion fails.
Let A be a declared array and i be an index accessing an index of the di-dimension. Then for every such index-access an assert statement assert(1 <= i and i <= size(A, di), ) is generated, provided this assertion cannot be checked at compile time.
For efficiency reasons, these implicit assert statements may be optionally suppressed.]
The lower and upper index bounds for a dimension of an array indexed by Integer, Boolean, or enumeration values are as follows:
An array dimension indexed by Integer values has a lower bound of 1 and an upper bound being the size of the dimension.
An array dimension indexed by Boolean values has the lower bound false and the upper bound true.
An array dimension indexed by enumeration values of the type E = enumeration(e1, e2, , en) has the lower bound E.e1 and the upper bound E.en.
Regarding flexible array sizes and resizing of arrays in functions, see section 12.4.5.
Modelica provides a number of built-in functions that are applicable to arrays.
The promote function listed below is utilized to define other array operators and functions.
Expression | Description | Details |
---|---|---|
promote(, ) | Append dimensions of size 1 (not Modelica) | Operator 10.1 |
Fills dimensions of size 1 from the right to array upto dimension , where ndims() is required.
Let C = promote(A, ), with = ndims(A), then ndims(C) = , size(C, ) = size(A, ) for , size(C, ) = for , C[, , , 1, , 1] = A[, , ]
The argument must be a constant that can be evaluated during translation, as it determines the number of dimensions of the returned array.
[An that is not a constant that can be evaluated during translation for promote complicates matrix handling as it can change matrix-equations in subtle ways (e.g. changing inner products to matrix multiplication).]
[Some examples of using the functions defined in the following section 10.3.1 to section 10.3.5:
]
The functions listed below operate on the array dimensions of the type of an expression:
Expression | Description | Details |
---|---|---|
ndims() | Number of dimensions | Operator 10.2 |
size(, ) | Size of single array dimension | Operator 10.3 |
size() | Sizes of all array dimensions | Operator 10.4 |
Returns the number of dimensions of expression , with .
Returns the size of dimension of array expression where ndims().
If refers to a component of an expandable connector, then the component must be a declared component of the expandable connector, and it must not use colon (:) to specify the array size of dimension .
Returns a vector of length ndims() containing the dimension sizes of .
If refers to a component of an expandable connector, then the component must be a declared component of the expandable connector, and it must not use colon (:) to specify the size of any array dimension.
The conversion functions listed below convert scalars, vectors, and arrays to scalars, vectors, or matrices by adding or removing 1-sized dimensions.
Expression | Description | Details |
---|---|---|
scalar() | Extract only element | Operator 10.5 |
vector() | Vector of all elements | Operator 10.6 |
matrix() | Two-dimensional array | Operator 10.7 |
Returns the single element of array . size(, i) is required for ndims().
Returns a 1-vector if is a scalar, and otherwise returns a vector containing all the elements of the array, provided there is at most one dimension size .
Returns promote(, 2) if is a scalar or vector, and otherwise returns the elements of the first two dimensions as a matrix. size(, i) is required for ndims().
An array constructor function constructs and returns an array computed from its arguments. Most of the constructor functions listed below construct an array by filling in values according to a certain pattern, in several cases just giving all array elements the same value. The general array constructor with syntax array() or {} is described in section 10.4.
Expression | Description | Details |
---|---|---|
identity() | Identity matrix | Operator 10.8 |
diagonal() | Diagonal matrix | Operator 10.9 |
zeros(, , , ) | Array with all elements being 0 | Operator 10.10 |
ones(, , , ) | Array with all elements being 1 | Operator 10.11 |
fill(, , , , ) | Array with all elements equal | Operator 10.12 |
linspace(, , ) | Vector with equally spaced elements | Operator 10.13 |
Returns the Integer identity matrix, with ones on the diagonal and zeros at the other places.
Returns a square matrix with the elements of vector on the diagonal and all other elements zero.
Returns the Integer array with all elements equal to zero (). The function needs one or more arguments, that is, zeros() is not legal.
Return the Integer array with all elements equal to one (). The function needs one or more arguments, that is, ones() is not legal.
Returns the array with all elements equal to scalar or array expression (). The returned array has the same type as .
Recursive definition: fill(, , , , ) = fill(fill(, , , ), ); fill(, ) = {, , , }.
The function needs two or more arguments; that is, fill() is not legal.
Returns a Real vector with equally spaced elements, such that v = linspace(, , ) results in
It is required that . The arguments and shall be numeric scalar expressions.
The reduction functions listed below “reduce” an array (or several scalars) to one value (normally a scalar, but the sum reduction function may give an array as result and also be applied to an operator record). Note that none of these operators (particularly min and max) generate events themselves (but arguments could generate events). The restriction on the type of the input in section 10.3.4.1 for reduction expressions also applies to the array elements/scalar inputs for the reduction operator with the same name.
Expression | Description | Details |
---|---|---|
min() | Least element or array | Operator 10.14 |
min(, ) | Least of two scalars | Operator 10.15 |
min( for ) | Reduction to least value | Operator 10.16 |
max() | Greatest element or array | Operator 10.17 |
max(, ) | Greatest of two scalars | Operator 10.18 |
max( for ) | Reduction to greatest value | Operator 10.19 |
sum() | Sum of scalar array elements | Operator 10.20 |
sum( for ) | Sum reduction | Operator 10.21 |
product() | Product of scalar array elements | Operator 10.22 |
product( for ) | Product reduction | Operator 10.23 |
Returns the least element of array expression ; as defined by <.
Returns the least element of the scalars and ; as defined by <.
Also described in section 10.3.4.1. Returns the least value (as defined by <) of the scalar expression (, , ) evaluated for all combinations of in , …, in .
Returns the greatest element of array expression ; as defined by >.
Returns the greatest element of the scalars and ; as defined by >.
Also described in section 10.3.4.1. Returns the greatest value (as defined by >) of the scalar expression (, , ) evaluated for all combinations of in , …, in .
Returns the scalar sum of all the elements of array expression A. Equivalent to sum reduction (see below, including application to operator records) over all array indices: sum([j, k, ] for j, k, )
Also described in section 10.3.4.1. Returns the sum of the expression (, , ) evaluated for all combinations of in , …, in .
The sum reduction function (both variants) may be applied to an operator record, provided that the operator record defines ’0’ and ’+’. It is then assumed to form an additive group.
For Integer indexing this is
For non-Integer indexing this uses all valid indices instead of 1..end.
The type of sum((, , ) for in , , in ) is the same as the type of (, , ).
Returns the scalar product of all the elements of array expression A. Equivalent to product reduction (see below) over all array indices: product([j, k, ] for j, k, )
Also described in section 10.3.4.1. Returns the product of the expression (, , ) evaluated for all combinations of in , …, in .
For Integer indexing this is
For non-Integer indexing this uses all valid indices instead of 1..end.
The type of product((, , ) for in , , in ) is the same as the type of (, , ).
An expression:
is a reduction-expression. The expressions in the iterators of a reduction-expression shall be vector expressions. They are evaluated once for each reduction-expression, and are evaluated in the scope immediately enclosing the reduction-expression.
For an iterator:
the loop-variable, IDENT, is in scope inside expression1. The loop-variable may hide other variables, as in for-clauses. The result depends on the function-name, and currently the only legal function-names are the built-in operators array, sum, product, min, and max. For array, see section 10.4. If function-name is sum, product, min, or max the result is of the same type as expression1 and is constructed by evaluating expression1 for each value of the loop-variable and computing the sum, product, min, or max of the computed elements. For deduction of ranges, see section 11.2.2.1; and for using types as ranges see section 11.2.2.2.
Reduction | Restriction on expression1 | Result for empty expression2 |
---|---|---|
sum | Integer or Real | zeros() |
product | Scalar Integer or Real | 1 |
min | Scalar enumeration, Boolean, Integer or Real | Greatest value of type |
max | Scalar enumeration, Boolean, Integer or Real | Least value of type |
[Example:
]
Functions for matrix and vector algebra are listed below. The function transpose can be applied to any matrix. The functions outerProduct, symmetric, cross and skew require Real vector(s) or matrix as input(s) and return a Real vector or matrix.
Expression | Description | Details |
---|---|---|
transpose() | Matrix transpose | Operator 10.24 |
outerProduct(, ) | Vector outer product | Function 10.1 |
symmetric() | Symmetric matrix, keeping upper part | Function 10.2 |
cross(, ) | Cross product | Function 10.3 |
skew() | Skew symmetric matrix associated with vector | Function 10.4 |
Permutes the first two dimensions of array . It is an error if array does not have at least 2 dimensions.
Returns the outer product of vectors and , that is: matrix() * transpose(matrix())
Returns a symmetric matrix which is identical to the square matrix on and above the diagonal.
That is, if B := symmetric(), then B is given by:
The array constructor function array(A, B, C, ) constructs an array from its arguments according to the following rules:
Size matching: All arguments must have the same sizes, i.e., size(A) = size(B) = size(C) = …
All arguments must be type compatible expressions (section 6.7) giving the type of the elements. The data type of the result array is the maximally expanded type of the arguments. Real and Integer subtypes can be mixed resulting in a Real result array where the Integer numbers have been transformed to Real numbers.
Each application of this constructor function adds a one-sized dimension to the left in the result compared to the dimensions of the argument arrays, i.e., ndims(array(A, B, C)) = ndims(A) + 1 = ndims(B) + 1,
{A, B, C, } is a shorthand notation for array(A, B, C, ).
There must be at least one argument.
[The reason array() or {} is not defined is that at least one argument is needed to determine the type of the resulting array.]
[Example:
]
An expression:
or
is an array constructor with iterators. The expressions inside the iterators of an array constructor shall be vector expressions. They are evaluated once for each array constructor, and are evaluated in the scope immediately enclosing the array constructor.
For an iterator:
the loop-variable, IDENT, is in scope inside expression in the array construction. The loop-variable may hide other variables, as in for-clauses. The loop-variable has the same type as the type of the elements of array_expression; and can be simple type as well as a record type. The loop-variable will have the same type for the entire loop – i.e., for an array_expression {1, 3.2} the iterator will have the type of the type-compatible expression (Real) for all iterations. For deduction of ranges, see section 11.2.2.1; and for using types as range see section 11.2.2.2.
If only one iterator is used, the result is a vector constructed by evaluating expression for each value of the loop-variable and forming an array of the result.
[Example:
]
The notation with several iterators is a shorthand notation for nested array constructors. The notation can be expanded into the usual form by replacing each ’,’ by ’} for’ and prepending the array constructor with a ’{’.
[Example:
]
The function cat(, A, B, C, ) concatenates arrays A, B, C, …along dimension according to the following rules:
Arrays A, B, C, …must have the same number of dimensions, i.e., ndims(A) = ndims(B) = …
Arrays A, B, C, …must be type compatible expressions (section 6.7) giving the type of the elements of the result. The maximally expanded types should be equivalent. Real and Integer subtypes can be mixed resulting in a Real result array where the Integer numbers have been transformed to Real numbers.
has to characterize an existing dimension, i.e., ; shall be a parameter expression of Integer type.
Size matching: Arrays A, B, C, …must have identical array sizes with the exception of the size of dimension , i.e., size(A, ) = size(B, ), for and .
Formally, the concatenation R = cat(, A, B, C, ) is defined as follows. Let = ndims(A) = ndims(B) = ndims(C) = …Then the size of R is given by
and the array elements of R are given by
where size(R,) for .
For convenience, a special syntax is supported for the concatenation along the first and second dimensions:
Concatenation along first dimension:
[A; B; C; ] = cat(1, promote(A, n), promote(B, n), promote(C, n), )
where n = max(2, ndims(A), ndims(B), ndims(C), ). If necessary, 1-sized
dimensions are added to the right of A, B, C before the operation is
carried out, in order that the operands have the same number of dimensions which will be at least two.
Concatenation along second dimension:
[A, B, C, ] = cat(2, promote(A, n), promote(B, n), promote(C, n), )
where n = max(2, ndims(A), ndims(B), ndims(C), ). If necessary, 1-sized
dimensions are added to the right of A, B, C before the operation is
carried out, especially that each operand has at least two dimensions.
The two forms can be mixed. [, ] has higher precedence than [; ], e.g., [a, b; c, d] is parsed as [[a, b]; [c, d]].
[A] = promote(A, max(2, ndims(A))), i.e., [A] = A, if A has 2 or more dimensions, and it is a matrix with the elements of A, if A is a scalar or a vector.
There must be at least one argument (i.e. [] is not defined).
[Example:
]
Vectors can be constructed with the general array constructor, e.g.,
The range vector operator or colon operator of simple-expression can be used instead of or in combination with this general constructor to construct Real, Integer, Boolean or enumeration type vectors. Semantics of the colon operator:
: is the Integer vector {, , , }, if and are of type Integer.
: is the Real vector {, , , }, with , if and/or are of type Real.
: is a Real, Integer, Boolean, or enumeration type vector with zero elements, if .
: : is the Integer vector {, , , }, with , if , , and are of type Integer.
: : is the Real vector {, , , }, with , if , , or are of type Real. In order to avoid rounding issues for the length it is recommended to use {j + d * i for i in 0 : n} or linspace(j, k, n + 1) – if the number of elements are known.
: : is a Real or Integer vector with zero elements, if and or if and .
false : true is the Boolean vector {false, true}.
: is {} if is Real, Integer, Boolean, or enumeration type.
E.ei : E.ej is the enumeration type vector {E.ei, , E.ej} where , and ei and ej belong to some enumeration type E = enumeration(, ei, , ej, ).
[Example:
]
The array indexing operator [] is used to access array elements for retrieval of their values or for updating these values. An indexing operation is subject to upper and lower array dimension index bounds (section 10.1.1). The indexing operator takes two or more operands, where the first operand is the array to be indexed and the rest of the operands are index (or subscript) expressions:
[, , ]
A colon (‘:’) is used to denote all indices of one dimension. A vector expression can be used to pick out selected rows, columns and elements of vectors, matrices, and arrays. The number of dimensions of the expression is reduced by the number of scalar index arguments. If the number of index arguments is smaller than the number of dimensions of the array, the trailing indices will use ‘:’.
It is also possible to use the array access operator to assign to element/elements of an array in algorithm sections. This is called an indexed assignment statement. If the index is an array the assignments take place in the order given by the index array. For assignments to arrays and elements of arrays, the entire right-hand side and the index on the left-hand side are evaluated before any element is assigned a new value.
[An indexing operation is assumed to take constant time, i.e., largely independent of the size of the array.]
[Example: Array indexing expressions:
The range vector operator is just a special case of a vector expression:
Array indexing in assignment statements:
If x is a vector, x[1] is a scalar, but the slice x[1:5] is a vector (a vector-valued or colon index expression causes a vector to be returned).]
Expression | # dims | Description |
---|---|---|
x[1, 1] | 0 | Scalar |
x[:, 1] | 1 | -vector |
x[1, :] or x[1] | 1 | -vector |
v[1:] | 1 | -vector |
x[1:, :] | 2 | matrix |
x[1:1, :] | 2 | “row” matrix |
x[{1, 3, 5}, :] | 2 | matrix |
x[:, v] | 2 | matrix |
z[:, 3, :] | 2 | matrix |
x[scalar([1]), :] | 1 | -vector |
x[vector([1]), :] | 2 | “row” matrix |
Arrays can be indexed using values of enumeration types or the Boolean type, not only by Integer. The type of the index should correspond to the type used for declaring the dimension of the array.
[Example:
]
The expression end may only appear inside array subscripts, and if used in the :th subscript of an array expression A it is equivalent to the upper bound of the :th dimension of A. If used inside nested array subscripts it refers to the most closely nested array.
[If indices to A are a subtype of Integer it is equivalent to size(A, i).]
[Example:
]
The mathematical operations defined on scalars, vectors, and matrices are the subject of linear algebra.
The term numeric or numeric class is used below for a subtype of the Real or Integer type classes. The standard type coercion defined in section 10.6.13 applies.
Equality a = b and assignment a := b of scalars, vectors, matrices, and arrays is defined element-wise and require both objects to have the same number of dimensions and corresponding dimension sizes. See section 10.5 regarding assignments to array variables with vector of subscripts.
The operands need to be type equivalent. This is legal for the simple types and all types satisfying the requirements for a record, and is in the latter case applied to each component-element of the records.
Size of a | Size of b | Size of a = b | Operation |
---|---|---|---|
Scalar | Scalar | Scalar | a = b |
-vector | -vector | -vector | a[] = b[] |
matrix | matrix | matrix | a[, ] = b[, ] |
a[, , ] = b[, , ] |
Addition a + b and subtraction a - b of numeric scalars, vectors, matrices, and arrays is defined element-wise and require size(a) = size(b) and a numeric type for a and b. Unary plus and minus are defined element-wise. Addition a + b of string scalars, vectors, matrices, and arrays is defined as element-wise string concatenation of corresponding elements from a and b, and require size(a) = size(b).
Size of a | Size of b | Size of a b | Operation c := a b |
---|---|---|---|
Scalar | Scalar | Scalar | c := a b |
-vector | -vector | -vector | c[] := a[] b[] |
matrix | matrix | matrix | c[, ] := a[, ] b[, ] |
c[, , ] := a[, , ] b[, , ] |
Element-wise addition a .+ b and subtraction a .- b of numeric scalars, vectors, matrices or arrays a and b requires a numeric type class for a and b and either size(a) = size(b) or scalar a or scalar b. Element-wise addition a .+ b of string scalars, vectors, matrices, and arrays is defined as element-wise string concatenation of corresponding elements from a and b, and require either size(a) = size(b) or scalar a or scalar b.
Size of a | Size of b | Size of a . b | Operation c := a . b |
---|---|---|---|
Scalar | Scalar | Scalar | c := a b |
Scalar | c[, , ] := a b[, , ] | ||
Scalar | c[, , ] := a[, , ] b | ||
c[, , ] := a[, , ] b[, , ] |
Size of a | Size of a | Operation c := a |
---|---|---|
Scalar | Scalar | c := a |
c[, , ] := a[, , ] |
Scalar multiplication s * a or a * s with numeric scalar s and numeric scalar, vector, matrix or array a is defined element-wise:
Size of s | Size of a | Size of s * a and a * s | Operation c := s * a or c := a * s |
---|---|---|---|
Scalar | Scalar | Scalar | c := s * a |
Scalar | -vector | -vector | c[] := s * a[] |
Scalar | matrix | matrix | c[, ] := s * a[, ] |
Scalar | c[, , ] := s * a[, , ] |
Element-wise multiplication a .* b of numeric scalars, vectors, matrices or arrays a and b requires a numeric type class for a and b and either size(a) = size(b) or scalar a or scalar b.
Size of a | Size of b | Size of a .* b | Operation c := a .* b |
---|---|---|---|
Scalar | Scalar | Scalar | c := a * b |
Scalar | c[, , ] := a * b[, , ] | ||
Scalar | c[, , ] := a[, , ] * b | ||
c[, , ] := a[, , ] * b[, , ] |
Multiplication a * b of numeric vectors and matrices is defined only for the following combinations:
Size of a | Size of b | Size of a * b | Operation c := a * b |
---|---|---|---|
-vector | -vector | Scalar | c := a[] * b[] |
-vector | matrix | -vector | c[] := a[] * b[, ] |
matrix | -vector | -vector | c[] := a[, ] * b[] |
matrix | matrix | matrix | c[, ] := a[, ] * b[, ] |
[Example:
]
Division a / s of numeric scalars, vectors, matrices, or arrays a and numeric scalars s is defined element-wise. The result is always of Real type. In order to get integer division with truncation, use the function div.
Size of a | Size of s | Size of a / s | Operation c := a / s |
---|---|---|---|
Scalar | Scalar | Scalar | c := a / s |
-vector | Scalar | -vector | c[] := a[] / s |
matrix | Scalar | matrix | c[, ] := a[, ] / s |
Scalar | c[, , ] := a[, , ] / s |
Element-wise division a ./ b of numeric scalars, vectors, matrices or arrays a and b requires a numeric type class for a and b and either size(a) = size(b) or scalar a or scalar b. The result is always of Real type. In order to get integer division with truncation, use the function div.
Size of a | Size of b | Size of a ./ b | Operation c := a ./ b |
---|---|---|---|
Scalar | Scalar | Scalar | c := a / b |
Scalar | c[, , ] := a / b[, , ] | ||
Scalar | c[, , ] := a[, , ] / b | ||
c[, , ] := a[, , ] / b[, , ] |
[Example: Element-wise division by scalar (./) and division by scalar (/) are identical: a ./ s = a / s:
This is a consequence of the parsing rules, since ‘2.’ is a lexical unit. Using a space after the literal solves the problem.]
Exponentiation a ^ b is defined as pow(double a, double b) in the ANSI C library if both a and b are Real scalars. A Real scalar value is returned. If a or b are Integer scalars, they are automatically promoted to Real. Consequences of exceptional situations, such as ( and , and b is not an integer) or overflow are undefined.
Element-wise exponentiation a .^ b of numeric scalars, vectors, matrices, or arrays a and b requires a numeric type class for a and b and either size(a) = size(b) or scalar a or scalar b.
Size of a | Size of b | Size of a .^ b | Operation c := a .^ b |
---|---|---|---|
Scalar | Scalar | Scalar | c := a ^ b |
Scalar | c[, , ] := a ^ b[, , ] | ||
Scalar | c[, , ] := a[, , ] ^ b | ||
c[, , ] := a[, , ] ^ b[, , ] |
[Example:
This is a consequence of the parsing rules, i.e. since 2. could be a lexical unit it seen as a lexical unit; using a space after literals solves the problem.]
Exponentiation a ^ s is defined if a is a square numeric matrix and s is a scalar as a subtype of Integer with . The exponentiation is done by repeated multiplication, e.g.:
[Non-Integer exponents are forbidden, because this would require computing the eigenvalues and eigenvectors of a and this is no longer an elementary operation.]
The following holds for slice operations:
If a is an array containing scalar components and m is a component of those components, the expression a.m is interpreted as a slice operation. It returns the array of components {a[1].m, }.
If m is also an array component, the slice operation is valid only if size(a[1].m) = size(a[2].m) = …
The slicing operation can be combined with indexing, e.g. a.m[1]. It returns the array of components {a[1].m[1], a[2].m[1], }, and does not require that size(a[1].m) = size(a[2].m). The number of subscripts on m must not be greater than the number of array dimension for m (the number can be smaller, in which case the missing trailing indices are assumed to be ‘:’), and is only valid if size(a[1].m[]) = size(a[2].m[]).
[Example: The size-restriction on the operand is only applicable if the indexing on the second operand uses vectors or colon as in the example:
In this example the different x1 vectors have different lengths, but it is still possible to perform some operations on them.]
Relational operators <, <=, >, >=, ==, <>, are only defined for scalar operands of simple types, not for arrays, see section 3.5
The operators and and or take expressions of Boolean type, which are either scalars or arrays of matching dimensions. The operator not takes an expression of Boolean type, which is either scalar or an array. The result is the element-wise logical operation. For short-circuit evaluation of and and or, see section 3.3.
See section 12.4.6.
In all contexts that require an expression which is a subtype of Real, an expression which is a subtype of Integer can also be used; the Integer expression is automatically converted to Real.
This also applies to arrays of Real, and for fields of record expressions. There is no similar rule for sub-typing.
[Example:
]
Arrays may have dimension sizes of 0. For example:
Empty matrices can be constructed with the fill function. For example:
It is not possible to access an element of an empty matrix, e.g. v[j, k] cannot be evaluated if v = [] because the assertion fails that the index must be bigger than one.
Size-requirements of operations, such as +, -, must also be fulfilled if a dimension is zero. For example:
Multiplication of two empty matrices results in a zero matrix of corresponding numeric type if the result matrix has no zero dimension sizes, i.e.,
[Example:
Assume , , : Results in y = D * u.]