forked from modelica/ModelicaSpecification
-
Notifications
You must be signed in to change notification settings - Fork 0
/
arrays.tex
1280 lines (1126 loc) · 57.3 KB
/
arrays.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\chapter{Arrays}\doublelabel{arrays}
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.
\begin{nonnormative}
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.
\end{nonnormative}
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.
\begin{nonnormative}
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.
\end{nonnormative}
An array is allocated by declaring an array variable or calling an array
constructor. Elements of an array can be indexed by \lstinline!Integer!, \lstinline!Boolean!, or
\lstinline!enumeration! values.
\section{Array Declarations}\doublelabel{array-declarations}
The Modelica type system includes scalar number, vector, matrix (number
of dimensions, ndim=2), and arrays of more than two dimensions.
\begin{nonnormative}
There is no distinguishing between a row and column vector.
\end{nonnormative}
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 \lstinline!Real!, \lstinline!Integer!, \lstinline!Boolean!, \lstinline!String!, and enumeration
types. The type of a dimension upper bound expression, e.g.\ $n$, $m$, $p$, \ldots
in the table below, need to be a subtype of \lstinline!Integer! or EB for a class EB
that is an enumeration type or subtype of the \lstinline!Boolean! type.
Colon (:) indicates that the dimension upper bound is unknown and is a subtype of
\lstinline!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 \autoref{flexible-array-sizes-and-resizing-of-arrays-in-functions}.
The size cannot be determined from other equations or algorithm.
Upper and lower array dimension index bounds are described in \autoref{array-dimension-lower-and-upper-index-bounds}.
An array indexed by Boolean or enumeration type can only be used in the following ways:
\begin{itemize}
\item
Subscripted using expressions of the appropriate type (i.e.\ Boolean or
the enumerated type)
\item
Binding equations of the form \lstinline!x1 = x2! as well as declaration
assignments of the form \lstinline!x1 := x2! are allowed for arrays independent of
whether the index types of dimensions are subtypes of Integer,
Boolean, or enumeration types.
\end{itemize}
% IMPROVETOP
\begin{longtable}{|l|l|l|l|p{4cm}|}
\caption{General forms of declaration of arrays.}\\
\hline
\tablehead{Modelica form 1} & \tablehead{Modelica form 2} & \tablehead{\# dimensions} & \tablehead{Designation} & \tablehead{Explanation}\\ \hline
\endhead
C x; & C x; & 0 & Scalar & Scalar\\ \hline
C{[}$n${]} x; & C x{[}$n${]}; & 1 & Vector & $n$ -- Vector\\ \hline
C{[}EB{]} x; & C x{[}EB{]} & 1 & Vector & Vector index by enumeration or
Boolean type EB\\ \hline
C{[}$n$, $m${]} x; & C x{[}$n$, $m${]}; & 2 & Matrix & $n \times m$ Matrix\\ \hline
C{[}$n_1$, $n_{2}$,\ldots{},$n_k${]} x; & C x{[}$n_1$, $n_2$,\ldots{},$n_k${]}; & $k$ & Array & Array with $k$ dimensions
($k \geq 0$).\\ \hline
\end{longtable}
\begin{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++.
\begin{lstlisting}[language=modelica]
Real[:] v1, v2 // vectors v1 and v2 have unknown sizes. The actual sizes may be different.
\end{lstlisting}
It is possible to mix the two declaration forms although it might be confusing.
\begin{lstlisting}[language=modelica]
Real[3,2] x[4,5]; // x has type Real[4,5,3,2];
\end{lstlisting}
The reason for this order is given by examples such as:
\begin{lstlisting}[language=modelica]
type R3=Real[3];
R3 a;
R3 b[1]={a};
Real[3] c[1]=b;
\end{lstlisting}
Using a type for \lstinline!a! and \lstinline!b! in this way is normal, and
substituting a type by its definition allow \lstinline!c!.
A vector \lstinline!y! indexed by enumeration values
\begin{lstlisting}[language=modelica]
type TwoEnums = enumeration(one,two);
Real[TwoEnums] y;
\end{lstlisting}
\end{example}
Zero-valued dimensions are allowed, so: \lstinline!C x[0];! declares an empty vector and: \lstinline!C x[0,3]!; an empty matrix.
\begin{nonnormative}
Special cases:
\begin{longtable}{|l|l|l|l|p{3cm}|}
\caption{Declaration of arrays as 1-vectors, row-vectors, or
column-vectors of arrays.}\\
\hline
\tablehead{Modelica form 1} & \tablehead{Modelica form 2} & \tablehead{\# dimensions} &
\tablehead{Designation} & \tablehead{Explanation}\\ \hline
\endhead
C{[}1{]} x; & C x{[}1{]}; & 1 & Vector & 1 -- Vector, representing a scalar\\ \hline
C{[}1,1{]} x; & C x{[}1, 1{]}; & 2 & Matrix & 1 x 1 -- Matrix, representing a scalar\\ \hline
C{[}n,1{]} x; & C x{[}n, 1{]}; & 2 & Matrix & n x 1 -- Matrix, representing a column\\ \hline
C{[}1,n{]} x; & C x{[}1, n{]}; & 2 & Matrix & 1 x n -- Matrix, representing a row\\ \hline
\end{longtable}
\end{nonnormative}
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.
\begin{example}
\begin{lstlisting}[language=modelica]
type Voltage = Real(unit = "V");
type Current = Real(unit = "A");
connector Pin
Voltage v; // type class of v = Voltage, type of v = Real
flow Current i; // type class of i = Current, type of i = Real
end Pin;
type MultiPin = Pin[5];
MultiPin[4] p; // type class of p is MultiPin, type of p is Pin[4,5];
type Point = Real[3];
Point p1[10];
Real p2[10,3];
\end{lstlisting}
The components p1 and p2 have identical types.
\begin{lstlisting}[language=modelica]
p2[5] = p1[2]+ p2[4]; // equivalent to p2[5,:] = p1[2,:] + p2[4,:]
Real r[3] = p1[2]; // equivalent to r[3] = p1[2,:]
\end{lstlisting}
\end{example}
\begin{nonnormative}
Automatic assertions at simulation time:
Let \lstinline!A! be a declared array and \lstinline!i! be the declared maximum dimension
size of the \lstinline!di!-dimension, then an assert statement
\lstinline!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 \lstinline!A! be a declared array and \lstinline!i! be an index accessing an index of
the \lstinline!di!-dimension. Then for every such index-access an assert
statement \lstinline!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.
\end{nonnormative}
\subsection{Array Dimension Lower and Upper Index Bounds}\doublelabel{array-dimension-lower-and-upper-index-bounds}
The lower and upper index bounds for a dimension of an array indexed by
\lstinline!Integer!, \lstinline!Boolean!, or \lstinline!enumeration! values are as follows:
\begin{itemize}
\item
An array dimension indexed by integers has a lower bound of 1 and an
upper bound being the size of the dimension.
\item
An array dimension indexed by \lstinline!Boolean! values has the lower bound \lstinline!false!
and the upper bound \lstinline!true!.
\item
An array dimension indexed by \lstinline!enumeration! values of the type
\lstinline!E=enumeration!(\lstinline!e1!, \lstinline!e2!, ..., \lstinline!en!) has the lower bound \lstinline!E.e1! and the upper
bound \lstinline!E.en!.
\end{itemize}
\section{Flexible Array Sizes}\doublelabel{flexible-array-sizes}
Regarding flexible array sizes and resizing of arrays in functions, see
\autoref{flexible-array-sizes-and-resizing-of-arrays-in-functions}.
\section{Built-in Array Functions}\doublelabel{built-in-array-functions}
Modelica provides a number of built-in functions that are applicable to
arrays.
The following \lstinline!promote! function cannot be used in Modelica, but is
utilized below to define other array operators and functions:
\begin{longtable}[]{|l|p{9cm}|}
\caption{Promote function (cannot be used in Modelica).}\\
\hline \endhead
\lstinline!promote(A, n)! & Fills dimensions of size 1 from the right to array \lstinline!A! upto
dimension $n$, where $n \geq$ \lstinline!ndims(A)! is required. Let \lstinline!C = promote(A, n)!, with \lstinline!nA = ndims(A)!, then \lstinline!ndims(C) = n!, \lstinline!size(C, j) = size(A, j)! for $1 \leq \text{\lstinline!j!} \leq \text{\lstinline!nA!}$, $\text{\lstinline!size(C, j)!} = 1$ for $\text{\lstinline!nA!} + 1 \leq \text{\lstinline!j!} \leq \text{\lstinline!n!}$, \lstinline!C[i_1, ..., i_nA, 1, ..., 1]! = \lstinline!A[i_1, ..., i_nA]!\\ \hline
\end{longtable}
\begin{nonnormative}
The function \lstinline!promote! cannot be used in Modelica, because
the number of dimensions of the returned array cannot be determined at
compile time if \lstinline!n! is a variable. Below, \lstinline!promote! is only used for
constant \lstinline!n!.
\end{nonnormative}
\begin{nonnormative}
Some examples of using the functions defined in the following
\autoref{array-dimension-and-size-functions} to \autoref{matrix-and-vector-algebra-functions}:
\begin{lstlisting}[language=modelica]
Real x[4,1,6];
size(x,1) = 4;
size(x); // vector with elements 4, 1, 6
size(2*x+x ) = size(x);
Real[3] v1 = fill(1.0, 3);
Real[3,1] m = matrix(v1);
Real[3] v2 = vector(m);
Boolean check[3,4] = fill(true, 3, 4);
\end{lstlisting}
\end{nonnormative}
\subsection{Array Dimension and Size Functions}\doublelabel{array-dimension-and-size-functions}
The following built-in functions for array dimensions and dimension
sizes are provided:
\begin{longtable}[]{|l|p{9cm}|}
\caption{Built-in array dimension and size functions.}\\
\hline
\tablehead{Modelica} & \tablehead{Explanation}\\ \hline
\endhead
\lstinline!ndims(A)! &
Returns the number of dimensions $k$ of expression \lstinline!A!, with $k \geq 0$.
\\ \hline
\lstinline!size(A, i)! &
Returns the size of dimension \lstinline!i! of array expression \lstinline!A! where $0 \leq \text{\lstinline!i!} \leq \text{\lstinline!ndims(A)!}$.\\ \hline
\lstinline!size(A)! &
Returns a vector of length \lstinline!ndims(A)! containing the dimension sizes of \lstinline!A!.\\ \hline
\end{longtable}
\subsection{Dimensionality Conversion Functions}\doublelabel{dimensionality-conversion-functions}
The following built-in conversion functions convert scalars, vectors,
and arrays to scalars, vectors, or matrices by adding or removing
1-sized dimensions.
\begin{longtable}[]{|l|p{9cm}|}
\caption{Built-in dimensionality conversion functions.}\\
\hline
\tablehead{Modelica} & \tablehead{Explanation}\\ \hline
\endhead
\lstinline!scalar(A)! & Returns the single element of array \lstinline!A!. $\text{\lstinline!size(A, i)!} = 1$ is required for $1
\leq \text{\lstinline!i!} \leq \text{\lstinline!ndims(A)!}$.\\ \hline
\lstinline!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$.\\ \hline
\lstinline!matrix(A)!
&
Returns \lstinline!promote(A, 2)!, if \lstinline!A! is a scalar or vector and otherwise returns
the elements of the first two dimensions as a matrix. $\text{\lstinline!size(A, i)!} = 1$ is
required for $2 < \text{\lstinline!i!} \leq \text{\lstinline!ndims(A)!}$.\\ \hline
\end{longtable}
\subsection{Specialized Array Constructor Functions}\doublelabel{specialized-array-constructor-functions}
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 \lstinline!array! (\ldots{}) or \{\ldots{}\}
is described in \autoref{vector-matrix-and-array-constructors}.
\begin{longtable}[]{|l|p{11cm}|}
\caption{Specialized array constructor functions.}\\
\hline
\tablehead{Modelica} & \tablehead{Explanation}\\ \hline
\endhead
\lstinline[mathescape=true]!identity($n$)!
&
Returns the $n \times n$ \lstinline!Integer! identity matrix, with ones on the diagonal and
zeros at the other places.\\ \hline
\lstinline!diagonal(v)!
&
Returns a square matrix with the elements of vector v on the diagonal
and all other elements zero.\\ \hline
\lstinline[mathescape=true]!zeros($n_{1}$, $n_{2}$, $n_{3}$, $\ldots$)! &
Returns the $n_{1} \times n_{2} \times n_{3} \times \ldots$ \lstinline!Integer! array with all elements equal to zero ($n_{i} \geq 0$).
The function needs one or more arguments, that is \lstinline!zeros()! is not legal.\\ \hline
\lstinline[mathescape=true]!ones($n_{1}$, $n_{2}$, $n_{3}$, $\ldots$)! &
Return the $n_{1} \times n_{2} \times n_{3} \times \ldots$ \lstinline!Integer! array with all elements equal to one ($n_{i} \geq 0$).
The function needs one or more arguments, that is \lstinline!ones()! is not legal.\\ \hline
\lstinline[mathescape=true]!fill(s, $n_{1}$, $n_{2}$, $n_{3}$, $\ldots$)! &
Returns the $n_{1} \times n_{2} \times n_{3} \times \ldots$ array with all elements equal to scalar or array expression $s$
($n_{i} \geq 0$). The returned array has the same type as \lstinline!s!.
Recursive definition:
\lstinline[mathescape=true]!fill(s, $n_{1}$, $n_{2}$, $n_{3}$, $\ldots$)! =
\lstinline[mathescape=true]!fill(fill(s, $n_{2}$, $n_{3}$, $\ldots$), $n_{1}$)!;
\lstinline[mathescape=true]!fill(s, $n$)! = \lstinline[mathescape=true]!{s, s, $\ldots$, s}!
The function needs two or more arguments; that is \lstinline!fill(s)! is not legal.\\ \hline
\lstinline[mathescape=true]!linspace(x1, x2, $n$)!
&
Returns a \lstinline!Real! vector with $n$ equally spaced elements, such that
\lstinline[mathescape=true]!v = linspace(x1, x2, $n$)! results in
\lstinline[mathescape=true]!v[$i$] = x1 + (x2-x1)*($i$-1)/($n$-1)! for $1 \leq i \leq n$.
It is required that $n \geq 2$. The arguments \lstinline!x1! and \lstinline!x2! shall
be numeric scalar expressions.\\ \hline
\end{longtable}
\subsection{Reduction Functions and Operators}\doublelabel{reduction-functions-and-operators}
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 \autoref{reduction-expressions} 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:
\begin{longtable}{|p{4.1cm}|p{10.1cm}|}
\caption{Array reduction functions and operators.}\\
\hline
\tablehead{Modelica} & \tablehead{Explanation}\\ \hline
\endhead
\lstinline!min(A)!
&
Returns the least element of array expression \lstinline!A!; as defined by \lstinline!<!.\\ \hline
\lstinline!min(x,y)!
&
Returns the least element of the scalars \lstinline!x! and \lstinline!y!; as defined by \lstinline!<!.\\ \hline
\begin{tabular}{@{}p{4cm}@{}}
\lstinline!min(e(i, ..., j)!\\
\lstinline! for i in u,!\\
\lstinline! ..., j in v)!
\end{tabular}
&
\begin{tabular}{@{}p{10cm}@{}}
Also described in \autoref{reduction-expressions}\\
Returns the least value (as defined by \lstinline!<!) of the scalar
expression \lstinline!e(i, ..., j)! evaluated for all combinations of \lstinline!i! in \lstinline!u!, \ldots, \lstinline!j!
in \lstinline!v!:
\end{tabular}\\ \hline
\lstinline!max(A)!
&
Returns the greatest element of array expression \lstinline!A!; as defined by
\lstinline!>!.\\ \hline
\lstinline!max(x,y)!
&
Returns the greatest element of the scalars \lstinline!x! and \lstinline!y!; as defined by
\lstinline!>!.\\ \hline
\begin{tabular}{@{}p{4cm}@{}}
\lstinline!max(e(i, ..., j)!\\
\lstinline! for i in u,!\\
\lstinline! ..., j in v)!
\end{tabular}
&
\begin{tabular}{@{}p{10cm}@{}}
Also described in \autoref{reduction-expressions}
Returns the greatest value (as defined by \lstinline!>!) of the scalar
expression \lstinline!e(i, ..., j)! evaluated for all combinations of \lstinline!i! in \lstinline!u!, \ldots, \lstinline!j!
in \lstinline!v!:
\end{tabular}\\ \hline
\lstinline!sum(A)!
&
\begin{tabular}{@{}p{10cm}@{}}
Returns the scalar sum of all the elements of array expression:\\
\lstinline!=sum(A[j,k,...]) for j,k,...!
\end{tabular}\\ \hline
\begin{tabular}{@{}p{5cm}@{}}
\lstinline!sum(e(i, ..., j)!\\
\lstinline! for i in u,!\\
\lstinline! ..., j in v)!
\end{tabular}
&
\begin{tabular}{@{}p{10cm}@{}}
Also described in \autoref{reduction-expressions}\\
Returns the sum of the expression e(i, ..., j) evaluated for all
combinations of i in u, ..., j in v: For \lstinline!Integer! indexing this is
e(u{[}1{]},...
,v{[}1{]})+e(u{[}2{]},... ,v{[}1{]})+... +e(u{[}end{]},...
,v{[}1{]})+...+e(u{[}end{]},... ,v{[}end{]})
For non-\lstinline!Integer! indexing this uses all valid indices instead of 1..\lstinline!end!.
The type of sum(e(i, ..., j) for i in u, ..., j
in v) is the same as the type of e(i,...j).
\end{tabular}\\ \hline
\lstinline!product(A)!
&
\begin{tabular}{@{}p{10cm}@{}}
Returns the scalar product of all the elements of array expression A.\\
\lstinline!=product(A[j,k,...] for j,k,...!
\end{tabular}\\ \hline
\begin{tabular}{@{}p{4cm}@{}}
\lstinline!product(e(i, ..., j)!\\
\lstinline! for i in u,!\\
\lstinline! ..., j in v)!
\end{tabular}
&
\begin{tabular}{@{}p{10cm}@{}}
Also described in \autoref{reduction-expressions}.\\
Returns the product of the scalar expression e(i, ..., j) evaluated for
all combinations of i in u, ..., j in v: For \lstinline!Integer! indexing this is
\begin{lstlisting}[language=modelica]
e(u[1],...,v[1])*e(u[2],...,v[1])*...
*(u[end],...,v[1])*...*e(u[end],...,v[end])
\end{lstlisting}
For non-\lstinline!Integer! indexing this uses all valid indices instead of 1..\lstinline!end!.
The type of product(e(i, ..., j) for i in u, ..., j
in v) is the same as the type of e(i,...j).
\end{tabular}
\\ \hline
\end{longtable}
\subsubsection{Reduction Expressions}\doublelabel{reduction-expressions}
An expression:
\begin{lstlisting}[language=grammar]
function-name "(" expression1 for iterators ")"
\end{lstlisting}
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:
\begin{lstlisting}[language=grammar]
IDENT in expression2
\end{lstlisting}
the loop-variable, \lstinline!IDENT!, is in scope inside \lstinline!expression1!. The
loop-variable may hide other variables, as in for-clauses. The result
depends on the \lstinline!function-name!, and currently the only legal
function-names are the built-in operators \lstinline!array!, \lstinline!sum!,
\lstinline!product!, \lstinline!min!, and
\lstinline!max!. For array, see \autoref{vector-matrix-and-array-constructors}. If \lstinline!function-name! is
\lstinline!sum!, \lstinline!product!, \lstinline!min!,
or \lstinline!max! the result is of the same type as \lstinline!expression1! and is constructed
by evaluating \lstinline!expression1! for each value of the loop-variable and
computing the \lstinline!sum!, \lstinline!product!, \lstinline!min!, or
\lstinline!max! of the computed elements. For
deduction of ranges, see \autoref{implicit-iteration-ranges}; and for using types as ranges
see \autoref{types-as-iteration-ranges}.
\begin{longtable}{|p{3cm}|p{5cm}|p{6cm}|}
\caption{Reduction expressions with iterators.}\\
\hline
\tablehead{Function-name} & \tablehead{Restriction on expression1} & \tablehead{Result if expression2 is empty}\\ \hline
\endhead
\lstinline!sum! & \lstinline!Integer! or \lstinline!Real! & \lstinline[mathescape=true]!zeros($\ldots$)!\\ \hline
\lstinline!product! & Scalar \lstinline!Integer! or \lstinline!Real! & \lstinline!1!\\ \hline
\lstinline!min! & Scalar enumeration, \lstinline!Boolean!, \lstinline!Integer! or \lstinline!Real! &
\begin{tabular}{@{}p{6cm}@{}}
Greatest value of type\\
(\lstinline!Modelica.Constants.inf! for \lstinline!Real!)
\end{tabular}\\ \hline
\lstinline!max! & Scalar enumeration, \lstinline!Boolean!, \lstinline!Integer! or \lstinline!Real! &
\begin{tabular}{@{}p{6cm}@{}}
Least value of type\\
(\lstinline!-Modelica.Constants.inf! for \lstinline!Real!)
\end{tabular}\\ \hline
\end{longtable}
\begin{example}
% No frame since the math would break it.
\begin{lstlisting}[language=modelica, mathescape=true, frame=none]
sum(i for i in 1:10) // Gives $\sum_{i=1}^{10}i=$1+2+...+10=55
// Read it as: compute the sum of i for i in the range 1 to 10.
sum(i^2 for i in {1,3,7,6}) // Gives $\sum_{i\in \begin{Bmatrix}1&3&7&6\end{Bmatrix}}i^2=$1+9+49+36=95
{product(j for j in 1:i) for i in 0:4} // Gives {1,1,2,6,24}
max(i^2 for i in {3,7,6}) // Gives 49
\end{lstlisting}
\end{example}
\subsection{Matrix and Vector Algebra Functions}\doublelabel{matrix-and-vector-algebra-functions}
The following set of built-in matrix and vector algebra functions are
available. The function transpose and symmetric can be applied to any matrix. The
functions outerProduct, cross and skew require Real/Integer
vector(s) or matrix as input(s) and returns a Real/Integer vector or matrix (the result is only Integer
if the input/all inputs are Integer):
\begin{longtable}[]{|p{3.5cm}|p{11.5cm}|}
\caption{Matrix and vector algebra functions.}\\
\hline
\tablehead{Modelica} & \tablehead{Explanation}\\ \hline
\endhead
\lstinline!transpose(A)!
& Permutes the first two dimensions of array A. It is an error, if array A
does not have at least 2 dimensions.\\ \hline
\lstinline!outerProduct(v1,v2)!
& Returns the outer product of vectors v1 and v2 ( = matrix(v1)*transpose(
matrix(v2) ) ).\\ \hline
\lstinline!symmetric(A)!
& Returns a symmetric matrix which is identical to the square matrix \lstinline!A!
on and above the diagonal, i.e., \lstinline!B := symmetric(A) ->!
\lstinline!B[i,j] := A[i,j], if i <= j, ! \lstinline! B[i,j] := A[j,i], if i > j!.\\ \hline
\lstinline!cross(x,y)!
& Returns the cross product of the 3-vectors x and y, i.e.
\lstinline!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] ] );!\\ \hline
\lstinline!skew(x)!
& Returns the 3 x 3 skew symmetric matrix associated with a 3-vector,
i.e., \lstinline!cross(x,y) = skew(x)*y; skew(x) = [0, -x[3], x[2]; x[3], 0, -x[1]; -x[2], x[1], 0];!\\ \hline
\end{longtable}
\section{Vector, Matrix and Array Constructors}\doublelabel{vector-matrix-and-array-constructors}
The constructor function \lstinline!array(A,B,C,...)! constructs an array from its
arguments according to the following rules:
\begin{itemize}
\item
Size matching: All arguments must have the same sizes, i.e.,
\lstinline!size(A)=size(B)=size(C)=!...
\item
All arguments must be type compatible expressions (\autoref{type-compatible-expressions}) 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.
\item
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., \lstinline!ndims(array(A,B,C)) = ndims(A) + 1 = ndims(B) + 1, ...!
\item
\lstinline!{A, B, C, ...}! is a shorthand notation for \lstinline!array(A, B, C, ...)!.
\item
There must be at least one argument.
\begin{nonnormative}
The reason \lstinline!array()! or \lstinline!{}! is not defined is that at least one argument is
needed to determine the type of the resulting array.
\end{nonnormative}
\end{itemize}
\begin{example}
\begin{lstlisting}[language=modelica, escapechar=!]
{1,2,3} !\emph{is a 3-vector of type Integer}.!
{{11,12,13}, {21,22,23}} !\emph{is a 2x3 matrix of type Integer}!
{{{1.0, 2.0, 3.0}}} !\emph{is a 1x1x3 array of type Real}.!
Real[3] v = array(1, 2, 3.0);
type Angle = Real(unit="rad");
parameter Angle alpha = 2.0; // type of alpha is Real.
// array(alpha, 2, 3.0) or {alpha, 2, 3.0} is a 3-vector of type Real.
Angle[3] a = {1.0, alpha, 4}; // type of a is Real[3].
\end{lstlisting}
\end{example}
\subsection{Array Constructor with Iterators}\doublelabel{array-constructor-with-iterators}
An expression:
\begin{lstlisting}[language=grammar]
"{" expression for iterators "}"
\end{lstlisting}
or
\begin{lstlisting}[language=grammar]
array "(" expression for iterators ")"
\end{lstlisting}
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:
\begin{lstlisting}[language=modelica]
IDENT in array_expression
\end{lstlisting}
the loop-variable, \lstinline!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 \autoref{implicit-iteration-ranges}; and for using types as
range see \autoref{types-as-iteration-ranges}.
\subsubsection{Array Constructor with One Iterator}\doublelabel{array-constructor-with-one-iterator}
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.
\begin{example}
\begin{lstlisting}[language=modelica]
array(i for i in 1:10)
// Gives the vector 1:10={1,2,3,...,10}
{r for r in 1.0 : 1.5 : 5.5}
// Gives the vector 1.0:1.5:5.5={1.0, 2.5, 4.0, 5.5}
{i^2 for i in {1,3,7,6}}
// Gives the vector {1, 9, 49, 36}
\end{lstlisting}
\end{example}
\subsubsection{Array Constructor with Several Iterators}\doublelabel{array-constructor-with-several-iterators}
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 '\lstinline!,!' by '\lstinline!} for!' and prepending the array constructor with
a '\lstinline!{!'.
\begin{example}
\begin{lstlisting}[language=modelica]
Real hilb[:,:]= { 1/(i+j-1) for i in 1:n, j in 1:n};
Real hilb2[:,:]={{ 1/(i+j-1) for j in 1:n} for i in 1:n};
\end{lstlisting}
\end{example}
\subsection{Array Concatenation}\doublelabel{array-concatenation}
The function \lstinline[mathescape=true]!cat($k$, A, B, C, $\ldots$)! concatenates arrays
\lstinline!A!, \lstinline!B!, \lstinline!C!, \ldots along
dimension $k$ according to the following rules:
\begin{itemize}
\item
Arrays \lstinline!A!, \lstinline!B!, \lstinline!C!, \ldots must have the same number of dimensions, i.e.,
\lstinline!ndims(A)! = \lstinline!ndims(B)! = \ldots
\item
Arrays \lstinline!A!, \lstinline!B!, \lstinline!C!, \ldots must be type compatible expressions (\autoref{type-compatible-expressions})
giving the type of the elements of the result. The maximally expanded
types should be equivalent. \lstinline!Real! and \lstinline!Integer! subtypes can be mixed
resulting in a \lstinline!Real! result array where the \lstinline!Integer! numbers have been
transformed to \lstinline!Real! numbers.
\item
$k$ has to characterize an existing dimension, i.e., $1 \leq k \leq \text{\lstinline!ndims(A)!} = \text{\lstinline!ndims(B)!} = \text{\lstinline!ndims(C)!}$; $k$ shall be a parameter expression of \lstinline!Integer! type.
\item
Size matching: Arrays \lstinline!A!, \lstinline!B!, \lstinline!C!, \ldots must have identical array sizes
with the exception of the size of dimension $k$, i.e., \lstinline!size(A,j)! =
\lstinline!size(B,j)!, for $1 \leq j \leq \text{\lstinline!ndims(A)!}$ and $j \neq k$.
\end{itemize}
\begin{example}
\begin{lstlisting}[language=modelica]
Real[2,3] r1 = cat(1, {{1.0, 2.0, 3}}, {{4, 5, 6}});
Real[2,6] r2 = cat(2, r1, 2*r1);
\end{lstlisting}
\end{example}
Concatenation is formally defined according to:
\begin{lstlisting}[language=modelica, escapechar=!]
!Let! R = cat(k,A,B,C,...)!, and let! n = ndims(A) = ndims(B) = ndims(C) =
....!, then!
size(R,k) = size(A,k) + size(B,k) + size(C,k) + ...
size(R,j) = size(A,j) = size(B,j) = size(C,j) = ...., for 1 <=j <= n and j <> k.
R[i_1, ..., i_k, ..., i_n] = A[i_1, ..., i_k, ..., i_n], for i_k <= size(A,k),
R[i_1, ..., i_k, ..., i_n] = B[i_1, ..., i_k - size(A,i), ..., i_n], for i_k <= size(A,k) + size(B,k),
....
where 1 <= i_j <= size(R,j) for 1 <= j <= n.
\end{lstlisting}
\subsubsection{Array Concatenation along First and Second Dimensions}\doublelabel{array-concatenation-along-first-and-second-dimensions}
For convenience, a special syntax is supported for the concatenation
along the first and second dimensions.
\begin{itemize}
\item
\emph{Concatenation along first dimension}:\\
\lstinline![A; B; C; ...] = cat(1, promote(A,n), promote(B,n), promote(C,n), ...)!
where \lstinline!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.
\item
\emph{Concatenation along second dimension}:\\
\lstinline![A, B, C, ...] = cat(2, promote(A,n), promote(B,n), promote(C,n), ...)!
where \lstinline!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.
\item
The two forms can be mixed. \lstinline![...,...]! has higher precedence than
\lstinline![...;...]!, e.g., \lstinline![a, b; c, d]! is parsed as \lstinline![[a,b];[c,d]]!.
\item
\lstinline![A] = promote(A,max(2,ndims(A)))!, i.e., \lstinline![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.
\item
There must be at least one argument (i.e.\ \lstinline![]! is not defined)
\end{itemize}
\begin{example}
\begin{lstlisting}[language=modelica]
Real s1, s2, v1[n1], v2[n2], M1[m1,n],
M2[m2,n], M3[n,m1], M4[n,m2], K1[m1,n,k],
K2[m2,n,k];
[v1;v2] is a (n1+n2) x 1 matrix
[M1;M2] is a (m1+m2) x n matrix
[M3,M4] is a n x (m1+m2) matrix
[K1;K2] is a (m1+m2) x n x k array
[s1;s2] is a 2 x 1 matrix
[s1,s1] is a 1 x 2 matrix
[s1] is a 1 x 1 matrix
[v1] is a n1 x 1 matrix
Real[3] v1 = array(1, 2, 3);
Real[3] v2 = {4, 5, 6};
Real[3,2] m1 = [v1, v2];
Real[3,2] m2 = [v1, [4;5;6]]; // m1 = m2
Real[2,3] m3 = [1, 2, 3; 4, 5, 6];
Real[1,3] m4 = [1, 2, 3];
Real[3,1] m5 = [1; 2; 3];
\end{lstlisting}
\end{example}
\subsection{Vector Construction}\doublelabel{vector-construction}
Vectors can be constructed with the general array constructor, e.g.,
\begin{lstlisting}[language=modelica]
Real[3] v = {1,2,3}.
\end{lstlisting}
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:
\begin{itemize}
\item
\lstinline!j : k! is the \lstinline!Integer! vector \lstinline!{j, j+1, ..., k}!, if \lstinline!j! and \lstinline!k! are of type
\lstinline!Integer!.
\item
\lstinline!j : k! is the \lstinline!Real! vector \lstinline!{j, j+1.0, ..., j+n}!, with \lstinline!n = floor(k - j)!, if
\lstinline!j! and/or \lstinline!k! are of type \lstinline!Real!.
\item
\lstinline!j : k! is a \lstinline!Real!, \lstinline!Integer!, \lstinline!Boolean!, or \lstinline!enumeration! type vector with
zero elements, if $\text{\lstinline!j!} > \text{\lstinline!k!}$.
\item
\lstinline!j : d : k! is the \lstinline!Integer! vector \lstinline!{j, j+d, ..., j+n*d}!, with \lstinline!n = div(k - j, d)!, if \lstinline!j!, \lstinline!d!, and \lstinline!k! are of type \lstinline!Integer!.
\item
\lstinline!j : d : k! is the \lstinline!Real! vector \lstinline!{j, j+d, ..., j+n*d}!, with \lstinline!n = floor((k-j)/d)!, if \lstinline!j!, \lstinline!d!, or \lstinline!k! are of type \lstinline!Real!. In order to avoid rounding issues for the length it is recommended to use \lstinline!{j+d*i for i in 0:n}! or \lstinline!linspace(j, k, n+1)! --- if the number of elements are
known.
\item
\lstinline!j : d : k! is a \lstinline!Real! or \lstinline!Integer! vector with zero elements, if $\text{\lstinline!d!}
> 0$ and $\text{\lstinline!j!} > \text{\lstinline!k!}$ or if $\text{\lstinline!d!} < 0$ and $\text{\lstinline!j!}
< \text{\lstinline!k!}$.
\item
\lstinline!false : true! is the Boolean vector \lstinline!{false, true}!.
\item
\lstinline!j : j! is \lstinline!{j}! if \lstinline!j! is \lstinline!Real!, \lstinline!Integer!, \lstinline!Boolean!, or \lstinline!enumeration! type.
\item
\lstinline!E.ei : E.ej! is the enumeration type vector \lstinline!{E.ei, ... E.ej}! where
$\text{\lstinline!E.ej!} > \text{\lstinline!E.ei!}$, and \lstinline!ei! and \lstinline!ej! belong to some enumeration type
\lstinline!E = enumeration(...ei, ...ej, ...)!.
\end{itemize}
\begin{example}
\begin{lstlisting}[language=modelica]
Real v1[5] = 2.7 : 6.8;
Real v2[5] = {2.7, 3.7, 4.7, 5.7, 6.7}; // = same as v1
Boolean b1[2] = false:true;
Colors = enumeration (red,blue,green);
Colors ec[3] = Colors.red : Colors.green;
\end{lstlisting}
\end{example}
\section{Array Indexing}\doublelabel{array-indexing}
The array indexing operator \emph{name}\lstinline![!\emph{...}\lstinline!]! 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 (\autoref{array-dimension-lower-and-upper-index-bounds}). 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:
\lstinline[mathescape=true]!$\mathit{arrayname}$[$\mathit{indexexpr}_{1}$, $\mathit{indexexpr}_{2}$, $\ldots$]!
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 `\lstinline!:!'.
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.
\begin{nonnormative}
An indexing operation is assumed to take constant time, i.e., largely independent of the size of the array.
\end{nonnormative}
\begin{example}
% henrikt-ma: This listing needs to be cleaned up from confusing punctuation.
\begin{lstlisting}[language=modelica, escapechar=!]
a[:, j] !\emph{is a vector of the j-th column of a,}!
a[j] !\emph{is a vector of the j-th row of a:}! a[j, :]
a[j : k] is {[a[j], a[j+1], ... , a[k]}
a[:,j : k] is [a[:,j], a[:,j+1], ... , a[:,k]],
v[2:2:8] = v[ {2,4,6,8} ] .
v[{j,k}]:={2,3}; // Same as v[j]:=2; v[k]:=3;
v[{1,1}]:={2,3}; // Same as v[1]:=3;
\end{lstlisting}
If \lstinline!x! is a vector, \lstinline!x[1]! is a scalar, but the slice \lstinline!x[1:5]! is a vector
(a vector-valued or colon index expression causes a vector to be returned).
\end{example}
\begin{example}
Array slicing given the declaration \lstinline!x[n,m], v[k], z[i,j,p]!.
\begin{longtable}[]{|l|l|l|}
\caption{Examples of scalars vs.\ array slices created with the colon index.}\\
\hline
\tablehead{Expression} & \tablehead{\# dimensions} & \tablehead{Type of value}\\ \hline
\endhead
\lstinline!x[1, 1]! & \lstinline!0! & Scalar\\ \hline
\lstinline!x[:, 1]! & \lstinline!1! & n -- Vector\\ \hline
\lstinline!x[1, :] or x[1]! & \lstinline!1! & m -- Vector\\ \hline
\lstinline!v[1:p]! & \lstinline!1! & p -- Vector\\ \hline
\lstinline!x[1:p, :]! & \lstinline!2! & p x m -- Matrix\\ \hline
\lstinline!x[1:1, :]! & \lstinline!2! & 1 x m - ``row'' matrix\\ \hline
\lstinline!x[{1, 3, 5}, :]! & \lstinline!2! & 3 x m -- Matrix\\ \hline
\lstinline!x[: , v]! & \lstinline!2! & n x k -- Matrix\\ \hline
\lstinline!z[: , 3, :]! & \lstinline!2! & i x p -- Matrix\\ \hline
\lstinline!x[scalar([1]), :]! & \lstinline!1! & m -- Vector\\ \hline
\lstinline!x[vector([1]), :]! & \lstinline!2! & 1 x m - ``row'' matrix\\ \hline
\end{longtable}
\end{example}
\subsection{Indexing with Boolean or Enumeration Values}\doublelabel{indexing-with-boolean-or-enumeration-values}
Arrays can be indexed using values of enumeration types or the \lstinline!Boolean!
type, not only by integers. The type of the index should correspond to
the type used for declaring the dimension of the array.
\begin{example}
\begin{lstlisting}[language=modelica]
type ShirtSizes = enumeration(small, medium, large, xlarge);
Real[ShirtSizes] w;
Real[Boolean] b2;
algorithm
w[ShirtSizes.large] := 2.28; // Assign a value to an element of w
b2[true] := 10.0;
b2[ShirtSizes.medium] := 4; // Error, b2 was declared with Boolean dimension
w[1] := 3; // Error, w was declared with ShirtSizes dimension
\end{lstlisting}
\end{example}
\subsection{Indexing with end}\doublelabel{indexing-with-end}
The expression \lstinline!end! may only appear inside array subscripts, and if used
in the i:th subscript of an array expression \lstinline!A! it is equivalent to
\lstinline!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.
\begin{example}
\begin{lstlisting}[language=modelica, escapechar=!]
A[end -1,end] is A[size(A,1)-1,size(A,2)]
A[v[end ],end] is A[v[size(v,1)],size(A,2)] // !\emph{since the first}! end !\emph{is referring to end of v.}!
\end{lstlisting}
\end{example}
\section{Scalar, Vector, Matrix, and Array Operator Functions}\doublelabel{scalar-vector-matrix-and-array-operator-functions}
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 \autoref{standard-type-coercion} apply.
\subsection{Equality and Assignment}\doublelabel{equality-and-assignment}
Equality \lstinline!a=b! and assignment \lstinline!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.
\begin{longtable}[]{|l|l|l|l|}
\caption{Equality and assignment of arrays and scalars.}\\
\hline
\tablehead{Type of a} & \tablehead{Type of b} & \tablehead{Result of} a = b & \tablehead{Operation} (j=1:n, k=1:m)\\ \hline
\endhead
Scalar & Scalar & Scalar & a = b\\ \hline
Vector{[}n{]} & Vector{[}n{]} & Vector{[}n{]} & a{[}j{]} =
b{[}j{]}\\ \hline
Matrix{[}n, m{]} & Matrix{[}n, m{]} & Matrix{[}n, m{]} & a{[}j, k{]} =
b{[}j, k{]}\\ \hline
Array{[}n, m, \ldots{}{]} & Array{[}n, m, \ldots{}{]} & Array{[}n, m,
\ldots{}{]} & a{[}j, k, \ldots{}{]} = b{[}j, k,
\ldots{}{]}\\ \hline
\end{longtable}
\subsection{Array Element-wise Addition, Subtraction, and String Concatenation}\doublelabel{array-element-wise-addition-subtraction-and-string-concatenation}
Addition \lstinline!a+b! and subtraction \lstinline!a-b! of numeric scalars, vectors, matrices,
and arrays is defined element-wise and require \lstinline!size(a)=size(b)! and a
numeric type for \lstinline!a! and \lstinline!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 \lstinline!a!
and \lstinline!b!, and require \lstinline!size(a)=size(b)!.
\begin{longtable}[]{|l|l|l|l|}
\caption{Array addition, subtraction, and string concatenation.}\\
\hline
\tablehead{Type of a} & \tablehead{Type of b} & \tablehead{Result of a +/- b} &
\tablehead{Operation c := a +/- b (j=1:n, k=1:m)}\\ \hline
\endhead
Scalar & Scalar & Scalar & c := a +/- b\\ \hline
Vector{[}n{]} & Vector{[}n{]} & Vector{[}n{]} & c{[}j{]} := a{[}j{]} +/-
b{[}j{]}\\ \hline
Matrix{[}n, m{]} & Matrix{[}n, m{]} & Matrix{[}n, m{]} & c{[}j, k{]} :=
a{[}j, k{]} +/- b{[}j, k{]}\\ \hline
Array{[}n, m, \ldots{}{]} & Array{[}n, m, \ldots{}{]} & Array{[}n, m,
\ldots{}{]} & c {[}j, k, \ldots{}{]} := a{[}j, k, \ldots{}{]} +/- b{[}j,
k, \ldots{}{]}\\ \hline
\end{longtable}
Element-wise addition \lstinline!a.+b! and subtraction \lstinline!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 \lstinline!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.
\begin{longtable}[]{|l|l|l|l|}
\caption{Array element-wise addition, subtraction, and string concatenation.}\\
\hline
\tablehead{Type of a} & \tablehead{Type of b} & \tablehead{Result of a} \lstinline!.+/.-! \tablehead{b}
& \tablehead{Operation c := a .+/.- b (j=1:n, k=1:m)}\\ \hline
\endhead
Scalar & Scalar & Scalar & c := a +/- b\\ \hline
Scalar & Array{[}n, m, \ldots{}{]} & Array{[}n, m, \ldots{}{]} & c{[}j,
k, \ldots{}{]} := a +/- b{[}j, k, \ldots{}{]}\\ \hline
Array{[}n, m, \ldots{}{]} & Scalar & Array{[}n, m, \ldots{}{]} & c{[}j,
k, \ldots{}{]} := a{[}j, k, \ldots{}{]} +/- b\\ \hline
Array{[}n, m, \ldots{}{]} & Array{[}n, m, \ldots{}{]} & Array{[}n, m,
\ldots{}{]} & c {[}j, k, \ldots{}{]} := a{[}j, k, \ldots{}{]} +/- b{[}j,
k, \ldots{}{]}\\ \hline
\end{longtable}
\begin{longtable}[]{|l|l|l|}
\caption{Unary operators. The element-wise (.+, .-) and normal (+, -) operators give the same results.}\\
\hline
\tablehead{Type of a} & \tablehead{Result of} \lstinline!+/-! \tablehead{a} & \tablehead{Operation c :=
+/- a (j=1:n, k=1:m)}\\ \hline
\endhead
Scalar & Scalar & c := +/- a\\ \hline
Array{[}n, m, \ldots{}{]} & Array{[}n, m, \ldots{}{]} & c{[}j, k,
\ldots{}{]} := +/-a{[}j, k, \ldots{}{]}\\ \hline
\end{longtable}
\subsection{Array Element-wise Multiplication}\doublelabel{array-element-wise-multiplication}
Scalar multiplication \lstinline!s*a! or \lstinline!a*s! with numeric scalar s and numeric
scalar, vector, matrix or array \lstinline!a! is defined element-wise:
\begin{longtable}[]{|l|l|l|l|}
\caption{Scalar and scalar to array multiplication of numeric elements}\\
\hline
\tablehead{Type of s} & \tablehead{Type of a} & \tablehead{Type of s* a and a*s} &
\tablehead{Operation} c := s*a or c := a*s (j=1:n, k=1:m)\\ \hline
\endhead
Scalar & Scalar & Scalar & c := s * a\\ \hline
Scalar & Vector {[}n{]} & Vector {[}n{]} & c{[}j{]} := s*
a{[}j{]}\\ \hline
Scalar & Matrix {[}n, m{]} & Matrix {[}n, m{]} & c{[}j, k{]} := s*
a{[}j, k{]}\\ \hline
Scalar & Array{[}n, m, ...{]} & Array {[}n, m, ...{]} & c{[}j, k, ...{]}
:= s*a{[}j, k, ...{]}\\ \hline
\label{tab:product}
\end{longtable}
Element-wise multiplication \lstinline!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.
\begin{longtable}[]{|l|l|l|l|}
\caption{Array element-wise multiplication}\\
\hline
\tablehead{Type of a} & \tablehead{Type of b} & \tablehead{Type of a .* b} &
\tablehead{Operation} c:=a .* b (j=1:n, k=1:m)\\ \hline
\endhead
Scalar & Scalar & Scalar & c := a * b\\ \hline