An array can be regarded as a collection of values, all of the same type. 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 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 [in order to permit strong type checking and efficient implementation.] However, the sizes of array dimensions can be computed at run-time, [allowing 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 distinguishing 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. n, m, p,… 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.
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 as well as declaration assignments 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 | # dimensions | Designation | Explanation |
---|---|---|---|---|
C x; | C x; | 0 | Scalar | Scalar |
C[n] x; | C x[n]; | 1 | Vector | n – Vector |
C[EB] x; | C x[EB] | 1 | Vector | Vector index by enumeration or Boolean type EB |
C[n, m] x; | C x[n, m]; | 2 | Matrix | n x m Matrix |
C[, ,…,] x; | C x[, ,…,]; | k | Array | Array with k dimensions (k>=0). |
[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 allow “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. [Special cases:
Modelica form 1 | Modelica form 2 | # dimensions | Designation | Explanation |
---|---|---|---|---|
C[1] x; | C x[1]; | 1 | Vector | 1 – Vector, representing a scalar |
C[1,1] x; | C x[1, 1]; | 2 | Matrix | 1 x 1 – Matrix, representing a scalar |
C[n,1] x; | C x[n, 1]; | 2 | Matrix | n x 1 – Matrix, representing a column |
C[1,n] x; | C x[1, n]; | 2 | Matrix | 1 x n – 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(i>=1 and i<=size(A,di), ... ) is generated, provided this assertion cannot be checked at compile time.
For efficiency reasons, these implicit assert statement 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 integers 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 following promote function cannot be used in Modelica, but is utilized below to define other array operators and functions:
promote(A,n) | Fills dimensions of size 1 from the right to array A upto dimension n, where ”n >= ndims(A)” is required. Let C = promote(A,n), with nA=ndims(A), then ndims(C) = n, size(C,j) = size(A,j) for 1 <= j <= nA, size(C,j) = 1 for nA+1 ¡= j ¡= n, C[i_1, …, i_nA, 1, …, 1] =A[i_1, …, i_nA] |
[The function promote cannot be used in Modelica, because the number of dimensions of the returned array cannot be determined at compile time if n is a variable. Below, promote is only used for constant n.
Some examples of using the functions defined in the following section 10.3.1 to section 10.3.5:
]
The following built-in functions for array dimensions and dimension sizes are provided:
Modelica | Explanation |
---|---|
ndims(A) | Returns the number of dimensions k of expression A, with k >= 0. |
size(A,i) | Returns the size of dimension i of array expression A where i shall be > 0 and <= ndims(A). |
size(A) | Returns a vector of length ndims(A) containing the dimension sizes of A. |
The following built-in conversion functions convert scalars, vectors, and arrays to scalars, vectors, or matrices by adding or removing 1-sized dimensions.
Modelica | Explanation |
---|---|
scalar(A) | Returns the single element of array A. size(A,i) = 1 is required for 1 <= i <= ndims(A). |
vector(A) | Returns a 1-vector, if A is a scalar and otherwise returns a vector containing all the elements of the array, provided there is at most one dimension size > 1. |
matrix(A) | Returns promote(A,2), if A is a scalar or vector and otherwise returns the elements of the first two dimensions as a matrix. size(A,i) = 1 is required for 2 < i <= ndims(A). |
An array constructor function constructs and returns an array computed from its arguments. Most of the constructor functions in the table 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.
Modelica | Explanation |
---|---|
identity(n) | Returns the n x n Integer identity matrix, with ones on the diagonal and zeros at the other places. |
diagonal(v) | Returns a square matrix with the elements of vector v on the diagonal and all other elements zero. |
zeros(n1,n2,n3,...) | Returns the x x x … Integer array with all elements equal to zero ( >= 0). The function need one or more arguments, that is zeros() is not legal. |
ones(n1,n2,n3,...) | Return the x x x … Integer array with all elements equal to one ( >=0 ). The function need one or more arguments, that is ones() is not legal. |
fill(s,n1,n2,n3,...) | Returns the x x x … array with all elements equal to scalar or array expression s ( >= 0). The returned array has the same type as s. Recursive definition: fill(s,,,,…) = fill(fill(s,,, …), ,); fill(s,n)={s,s,…, s} The function needs two or more arguments; that is fill(s) is not legal. |
linspace(x1,x2,n) | Returns a Real vector with n equally spaced elements, such that v=linspace(x1,x2,n), v[i] = x1 + (x2-x1)*(i-1)/(n-1) for 1 <= i <= n. It is required that n >= 2. The arguments x1 and x2 shall be numeric scalar expressions. |
A reduction function “reduces” 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 apply to the array elements/scalar inputs for the reduction operator with the same name.
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.
The following reduction functions are available:
Modelica | Explanation | |||||
---|---|---|---|---|---|---|
min(A) | Returns the least element of array expression A; as defined by <. | |||||
min(x,y) | Returns the least element of the scalars x and y; as defined by <. | |||||
|
|
|||||
max(A) | Returns the greatest element of array expression A; as defined by >. | |||||
max(x,y) | Returns the greatest element of the scalars x and y; as defined by >. | |||||
|
|
|||||
sum(A) |
|
|||||
|
|
|||||
product(A) |
|
|||||
|
|
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.
Function-name | Restriction on expression1 | Result if expression2 is empty | ||
---|---|---|---|---|
sum | Integer or Real | zeros(...) | ||
product | Scalar Integer or Real | 1 | ||
min | Scalar enumeration, Boolean, Integer or Real |
|
||
max | Scalar enumeration, Boolean, Integer or Real |
|
||
[Example:
]
The following set of built-in matrix and vector algebra functions are available. The function transpose can be applied to any matrix. The functions outerProduct, symmetric, cross and skew require Real/Integer vector(s) or matrix as input(s) and returns a Real vector or matrix:
Modelica | Explanation |
---|---|
transpose(A) | Permutes the first two dimensions of array A. It is an error, if array A does not have at least 2 dimensions. |
outerProduct(v1,v2) | Returns the outer product of vectors v1 and v2 ( = matrix(v1)*transpose( matrix(v2) ) ). |
symmetric(A) | Returns a matrix where the diagonal elements and the elements above the diagonal are identical to the corresponding elements of matrix A and where the elements below the diagonal are set equal to the elements above the diagonal of A, i.e., B := symmetric(A) -> B[i,j] := A[i,j], if i <= j, B[i,j] := A[j,i], if i > j. |
cross(x,y) | Returns the cross product of the 3-vectors x and y, i.e. cross(x,y) = vector( [ x[2]*y[3]-x[3]*y[2]; x[3]*y[1]-x[1]*y[3]; x[1]*y[2]-x[2]*y[1] ] ); |
skew(x) | Returns the 3 x 3 skew symmetric matrix associated with a 3-vector, i.e., cross(x,y) = skew(x)*y; skew(x) = [0, -x[3], x[2]; x[3], 0, -x[1]; -x[2], x[1], 0]; |
The 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.6) 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 [i.e., array() or {} is not defined].
[Examples:
]
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(k,A,B,C,...) concatenates arrays A,B,C,… along dimension k 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.6) 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.
k has to characterize an existing dimension, i.e., 1 <= k <= ndims(A) = ndims(B) = ndims(C); k shall be an integer number.
Size matching: Arrays A, B, C, … must have identical array sizes with the exception of the size of dimension k, i.e., size(A,j) = size(B,j), for 1 <= j <= ndims(A) and j <> k.
[Examples:
]
Concatenation is formally defined according to:
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)
[Examples:
]
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:
j : k is the Integer vector {j, j+1, …, k}, if j and k are of type Integer.
j : k is the Real vector {j, j+1.0, … n}, with n = floor(k-j), if j and/or k are of type Real.
j : k is a Real, Integer, Boolean, or enumeration type vector with zero elements, if j > k.
j : d : k is the Integer vector {j, j+d, …, j+n*d}, with n = div(k – j, d), if j, d, and k are of type Integer.
j : d : k is the Real vector {j, j+d, …, j+n*d}, with n = floor((k-j)/d), if j, d, or k 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.
j : d : k is a Real or Integer vector with zero elements, if d > 0 and j > k or if d < 0 and j < k.
false : true is the Boolean vector {false, true}.
j:j is {j} if j is Real, Integer, Boolean, or enumeration type.
E.ei : E.ej is the enumeration type vector { E.ei, … E.ej} where E.ej> E.ei, and ei and ej belong to some enumeration type E=enumeration(…ei,…ej,…).
[Examples:
]
The array indexing operator name[…] 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). [An indexing operation is assumed to take constant time, i.e., largely independent of the size of the array.] 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 expressions:
arrayname[indexexpr1, indexexpr2, …]
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. 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.
[Examples:
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).
]
[Examples given the declaration x[n,m], v[k], z[i,j,p]:
Expression | # dimensions | Type of value |
---|---|---|
x[1, 1] | Scalar | |
x[:, 1] | 1 | n – Vector |
x[1, :] or x[1] | 1 | m – Vector |
v[1:p] | 1 | p – Vector |
x[1:p, :] | 2 | p x m – Matrix |
x[1:1, :] | 2 | 1 x m - ”row” matrix |
x[{1, 3, 5\}, :] | 2 | 3 x m – Matrix |
x[: , v] | 2 | n x k – Matrix |
z[: , 3, :] | 2 | i x p – Matrix |
x[scalar([1]), :] | 1 | m – Vector |
x[vector([1]), :] | 2 | 1 x m - ”row” matrix |
]
Arrays can be indexed using values of enumeration types or the Boolean type, not only by integers. 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 i:th subscript of an array expression A it is equivalent to size(A,i) provided indices to A are a subtype of Integer. If used inside nested array subscripts it refers to the most closely nested array.
[Examples:
]
The mathematical operations defined on scalars, vectors, and matrices are the subject of linear algebra.
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.
The term numeric or numeric class is used below for a subtype of the Real or Integer type classes.
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. 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.
Type of a | Type of b | Result of a = b | Operation (j=1:n, k=1:m) |
---|---|---|---|
Scalar | Scalar | Scalar | a = b |
Vector[n] | Vector[n] | Vector[n] | a[j] = b[j] |
Matrix[n, m] | Matrix[n, m] | Matrix[n, m] | a[j, k] = b[j, k] |
Array[n, m, …] | Array[n, m, …] | Array[n, m, …] | a[j, k, …] = b[j, k, …] |
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).
Type of a | Type of b | Result of a +/- b | Operation c := a +/- b (j=1:n, k=1:m) |
---|---|---|---|
Scalar | Scalar | Scalar | c := a +/- b |
Vector[n] | Vector[n] | Vector[n] | c[j] := a[j] +/- b[j] |
Matrix[n, m] | Matrix[n, m] | Matrix[n, m] | c[j, k] := a[j, k] +/- b[j, k] |
Array[n, m, …] | Array[n, m, …] | Array[n, m, …] | c [j, k, …] := a[j, k, …] +/- b[j, k, …] |
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.
Type of a | Type of b | Result of a .+/.- b | Operation c := a .+/.- b (j=1:n, k=1:m) |
---|---|---|---|
Scalar | Scalar | Scalar | c := a +/- b |
Scalar | Array[n, m, …] | Array[n, m, …] | c[j, k, …] := a +/- b[j, k, …] |
Array[n, m, …] | Scalar | Array[n, m, …] | c[j, k, …] := a[j, k, …] +/- b |
Array[n, m, …] | Array[n, m, …] | Array[n, m, …] | c [j, k, …] := a[j, k, …] +/- b[j, k, …] |
Type of a | Result of +/- a | Operation c := +/- a (j=1:n, k=1:m) |
---|---|---|
Scalar | Scalar | c := +/- a |
Array[n, m, …] | Array[n, m, …] | c[j, k, …] := +/-a[j, k, …] |
Scalar multiplication s*a or a*s with numeric scalar s and numeric scalar, vector, matrix or array a is defined element-wise:
Type of s | Type of a | Type of s* a and a*s | Operation c := s*a or c := a*s (j=1:n, k=1:m) |
---|---|---|---|
Scalar | Scalar | Scalar | c := s * a |
Scalar | Vector [n] | Vector [n] | c[j] := s* a[j] |
Scalar | Matrix [n, m] | Matrix [n, m] | c[j, k] := s* a[j, k] |
Scalar | Array[n, m, …] | Array [n, m, …] | c[j, k, …] := s*a[j, k, …] |
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.
Type of a | Type of b | Type of a .* b | Operation c:=a .* b (j=1:n, k=1:m) |
---|---|---|---|
Scalar | Scalar | Scalar | c := a * b |
Scalar | Array[n, m, …] | Array[n, m, …] | c[j, k, …] := a* b[j, k, …] |
Array[n, m, …] | Scalar | Array[n, m, …] | c[j, k, …] := a[j, k, …]* b |
Array[n, m, …] | Array[n, m, …] | Array [n, m, …] | c[j, k, …] := a[j, k, …]* b[j, k, …] |
Multiplication a*b of numeric vectors and matrices is defined only for the following combinations:
Type of a | Type of b | Type of a* b | Operation c := a*b |
---|---|---|---|
Vector [n] | Vector [n] | Scalar | c := (a[k]*b[k]), k=1:n |
Vector [n] | Matrix [n, m] | Vector [m] | c[j] := (a[k]*b[k, j]), j=1:m, k=1:n |
Matrix [n, m] | Vector [m] | Vector [n] | c[j] := (a[j, k]*b[k]) |
Matrix [n, m] | Matrix [m, p] | Matrix [n, p] | c[i, j] = (a[i, k]*b[k, j]), i=1:n, k=1:m, j=1:p |
[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.
Type of a | Type of s | Result of a / s | Operation c := a / s (j=1:n, k=1:m) |
Scalar | Scalar | Scalar | c := a / s |
Vector[n] | Scalar | Vector[n] | c[k] := a[k] / s |
Matrix[n, m] | Scalar | Matrix[n, m] | c[j, k] := a[j, k] / s |
Array[n, m, …] | Scalar | Array[n, m, …] | c[j, k, …] := a[j, k, …] / 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.
Type of a | Type of b | Type of a ./ b | Operation c:=a ./ b (j=1:n, k=1:m) |
Scalar | Scalar | Scalar | c := a / b |
Scalar | Array[n, m, …] | Array[n, m, …] | c[j, k, …] := a / b[j, k, …] |
Array[n, m, …] | Scalar | Array[n, m, …] | c[j, k, …] := a[j, k, …] / b |
Array[n, m, …] | Array[n, m, …] | Array [n, m, …] | c[j, k, …] := a[j, k, …] / b[j, k, …] |
[Element-wise division by scalar (./) and division by scalar (/) are identical: a./s = a/s.
Example:
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 (a==0.0 and b<=0.0, a<0 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.
Type of a | Type of b | Type of a .^ b | Operation c:=a .^ b (j=1:n, k=1:m) |
---|---|---|---|
Scalar | Scalar | Scalar | c := a ^ b |
Scalar | Array[n, m, …] | Array[n, m, …] | c[j, k, …] := a ^ b[j, k, …] |
Array[n, m, …] | Scalar | Array[n, m, …] | c[j, k, …] := a[j, k, …] ^ b |
Array[n, m, …] | Array[n, m, …] | Array [n, m, …] | c[j, k, …] := a[j, k, …] ^ b[j, k, …] |
[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 s>=. 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.
Arrays may have dimension sizes of 0. E.g.
Empty matrices can be constructed with the fill function. E.g.
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 +, -, have also to be fulfilled if a dimension is zero. E.g.
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 n=0, p>0, q>0: Results in y = D*u
]