Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 54.5% 24 / 0 / 44
Functions: -% 0 / 1 / 1
Branches: 52.6% 20 / 0 / 38

OMCompiler/Compiler/BackEnd/AdjacencyMatrix.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package AdjacencyMatrix
37
38 import BackendDAE;
39
40 protected
41 import Array;
42 import Debug;
43 import Flags;
44 import List;
45 import MetaModelica.Dangerous;
46
47 public function copyAdjacencyMatrix
48 input Option<BackendDAE.AdjacencyMatrix> inAdjacencyMatrix;
49 output Option<BackendDAE.AdjacencyMatrix> outAdjacencyMatrix;
50 algorithm
51 outAdjacencyMatrix := match inAdjacencyMatrix
52 local
53 BackendDAE.AdjacencyMatrix m;
54
55 case SOME(m) algorithm
56 40200 m := arrayCopy(m);
57 then SOME(m);
58
59 else NONE();
60 end match;
61 end copyAdjacencyMatrix;
62
63 public function copyAdjacencyMatrixT = copyAdjacencyMatrix;
64
65 public function traverseAdjacencyMatrix<T>
66 input BackendDAE.AdjacencyMatrix inM;
67 input FuncType func;
68 input T inTypeA;
69 output BackendDAE.AdjacencyMatrix outM;
70 output T outTypeA;
71 partial function FuncType
72 input BackendDAE.AdjacencyMatrixElement elem;
73 input Integer pos;
74 input T inTpl;
75 output list<Integer> outList;
76 output T outTpl;
77 end FuncType;
78 algorithm
79 ✗ (outM, outTypeA) := traverseAdjacencyMatrix1(inM, func, 1, arrayLength(inM), inTypeA);
80 end traverseAdjacencyMatrix;
81
82 protected function traverseAdjacencyMatrix1<T>
83 input BackendDAE.AdjacencyMatrix inM;
84 input FuncType func;
85 input Integer pos "iterated 1..len";
86 input Integer len "length of array";
87 input T inTypeA;
88 output BackendDAE.AdjacencyMatrix outM;
89 output T outTypeA;
90 partial function FuncType
91 input BackendDAE.AdjacencyMatrixElement elem;
92 input Integer pos;
93 input T inTpl;
94 output list<Integer> outList;
95 output T outTpl;
96 end FuncType;
97 algorithm
98 ✗ (outM, outTypeA) := traverseAdjacencyMatrix2(inM, func, pos, len, intGt(pos, len), inTypeA);
99 annotation(__OpenModelica_EarlyInline = true);
100 end traverseAdjacencyMatrix1;
101
102 protected function traverseAdjacencyMatrix2<T>
103 input BackendDAE.AdjacencyMatrix inM;
104 input FuncType func;
105 input Integer pos "iterated 1..len";
106 input Integer len "length of array";
107 input Boolean stop;
108 input T inTypeA;
109 output BackendDAE.AdjacencyMatrix outM;
110 output T outTypeA;
111 partial function FuncType
112 input BackendDAE.AdjacencyMatrixElement elem;
113 input Integer pos;
114 input T inTpl;
115 output list<Integer> outList;
116 output T outTpl;
117 end FuncType;
118 algorithm
119 (outM, outTypeA) := match stop
120 local
121 BackendDAE.AdjacencyMatrix m1, m2;
122 T extArg, extArg1, extArg2;
123 list<Integer> eqns, eqns1;
124
125 case true
126 then (inM, inTypeA);
127
128 case false algorithm
129 ✗ (eqns, extArg) := func(inM[pos], pos, inTypeA);
130 ✗ eqns1 := List.removeOnTrue(pos, intLt, eqns);
131 ✗ (m1, extArg1) := traverseAdjacencyMatrixList(eqns1, inM, func, arrayLength(inM), pos, extArg);
132 ✗ (m2, extArg2) := traverseAdjacencyMatrix2(m1, func, pos+1, len, intGt(pos+1, len), extArg1);
133 then (m2, extArg2);
134 end match;
135 end traverseAdjacencyMatrix2;
136
137 protected function traverseAdjacencyMatrixList<T>
138 input list<Integer> inLst "elements to traverse";
139 input BackendDAE.AdjacencyMatrix inM;
140 input FuncType func;
141 input Integer len "length of array";
142 input Integer maxpos "do not go further than this position";
143 input T inTypeA;
144 output BackendDAE.AdjacencyMatrix outM;
145 output T outTypeA;
146 partial function FuncType
147 input BackendDAE.AdjacencyMatrixElement elem;
148 input Integer pos;
149 input T inTpl;
150 output list<Integer> outList;
151 output T outTpl;
152 end FuncType;
153 algorithm
154 (outM, outTypeA) := matchcontinue inLst
155 local
156 BackendDAE.AdjacencyMatrix m;
157 T extArg, extArg1;
158 list<Integer> rest, eqns, eqns1, alleqns;
159 Integer pos;
160
161 case {}
162 ✗ then (inM, inTypeA);
163
164 case pos::rest algorithm
165 // do not leave the list
166 ✗ true := intLt(pos, len+1);
167 // do not more than necesary
168 ✗ true := intLt(pos, maxpos);
169 ✗ (eqns, extArg) := func(inM[pos], pos, inTypeA);
170 ✗ eqns1 := List.removeOnTrue(maxpos, intLt, eqns);
171 ✗ alleqns := List.unionOnTrueList({rest, eqns1}, intEq);
172 ✗ (m, extArg1) := traverseAdjacencyMatrixList(alleqns, inM, func, len, maxpos, extArg);
173 then (m, extArg1);
174
175 case pos::rest algorithm
176 // do not leave the list
177 ✗ true := intLt(pos, len+1);
178 ✗ (m, extArg) := traverseAdjacencyMatrixList(rest, inM, func, len, maxpos, inTypeA);
179 then (m, extArg);
180
181 else algorithm
182 ✗ true := Flags.isSet(Flags.FAILTRACE);
183 ✗ Debug.trace("- BackendDAEOptimize.traverseAdjacencyMatrixList failed\n");
184 ✗ then fail();
185 end matchcontinue;
186 end traverseAdjacencyMatrixList;
187
188 public function getOtherEqSysAdjacencyMatrix
189 "This function removes tvar and res from adjacency matrix."
190 input BackendDAE.AdjacencyMatrix m;
191 input Integer size;
192 input Integer index;
193 input array<Integer> skip;
194 input array<Integer> rowskip;
195 input BackendDAE.AdjacencyMatrix mnew;
196 output BackendDAE.AdjacencyMatrix outMNew;
197 algorithm
198 outMNew := match m
199 local
200 list<Integer> row;
201
202 case _ guard intGt(index, size)
203 then mnew;
204
205 case _ guard intGt(skip[index], 0)
206 algorithm
207
8/8
✓ Branch 1 taken 1016 times.
✓ Branch 2 taken 6 times.
✓ Branch 4 taken 218 times.
✓ Branch 5 taken 798 times.
✓ Branch 6 taken 1022 times.
✓ Branch 7 taken 414 times.
✓ Branch 8 taken 798 times.
✓ Branch 9 taken 414 times.
1436 row := list(r for r guard intGt(r,0) and intGt(rowskip[r], 0) in m[index]);
208 414 arrayUpdate(mnew, index, row);
209 414 then getOtherEqSysAdjacencyMatrix(m, size, index+1, skip, rowskip, mnew);
210
211 case _ algorithm
212 128 arrayUpdate(mnew,index,{});
213 128 then getOtherEqSysAdjacencyMatrix(m, size, index+1, skip, rowskip, mnew);
214 end match;
215 end getOtherEqSysAdjacencyMatrix;
216
217 protected function isAssigned
218 input array<Integer> ass;
219 input Integer i;
220 output Boolean b;
221 algorithm
222 ✗ b := intGt(ass[i], 0);
223 end isAssigned;
224
225 public function transposeAdjacencyMatrix
226 "Calculates the transpose of the adjacency matrix,
227 i.e. which equations each variable is present in."
228 input BackendDAE.AdjacencyMatrix m;
229 input Integer nRowsMt;
230 output BackendDAE.AdjacencyMatrixT mt;
231 protected
232 Integer i = 1;
233 algorithm
234 2577 mt := arrayCreate(nRowsMt, {});
235
2/2
✓ Branch 1 taken 1579814 times.
✓ Branch 2 taken 2577 times.
1582391 for e in m loop
236 1579814 (mt, i) := transposeRow(e, mt, i);
237 end for;
238 end transposeAdjacencyMatrix;
239
240 protected function transposeRow "author: PA
241 Helper function to transposeMatrix2.
242 Input: BackendDAE.AdjacencyMatrix (eqn => var)
243 Input: row number (variable)
244 Input: iterator (start with one)
245 inputs: (int list list, int /* row */,int /* iter */)
246 outputs: int list"
247 input list<Integer> row;
248 input output BackendDAE.AdjacencyMatrixT mt;
249 input output Integer indx;
250 algorithm
251 (mt, indx) := match row
252 local
253 Integer i, indx1, iabs;
254 list<Integer> res, col;
255
256 case {}
257
1/2
✓ Branch 0 taken 1579814 times.
✗ Branch 1 not taken.
1579814 then (mt, indx+1);
258
259 case i::res algorithm
260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2627826 times.
2627826 iabs := intAbs(i);
261 2627826 mt := Array.expand(iabs - arrayLength(mt), mt, {});
262 2627826 col := mt[iabs];
263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2627826 times.
2627826 indx1 := if intLt(i, 0) then -indx else indx;
264 2627826 arrayUpdate(mt, iabs, indx1::col);
265 2627826 then transposeRow(res, mt, indx);
266 end match;
267 end transposeRow;
268
269 public function absAdjacencyMatrix "author: PA
270 Applies absolute value to all entries in the adjacency matrix.
271 This can be used when e.g. der(x) and x are considered the same variable."
272 input BackendDAE.AdjacencyMatrix m;
273 output BackendDAE.AdjacencyMatrix res;
274 protected
275 Integer i = 1;
276 Integer minn;
277 algorithm
278 123176 res := Dangerous.arrayCreateNoInit(arrayLength(m),{});
279
2/2
✓ Branch 1 taken 925676 times.
✓ Branch 2 taken 123176 times.
1048852 for v in m loop
280 925676 minn := List.fold(v,intMin,0);
281
2/2
✓ Branch 0 taken 87479 times.
✓ Branch 1 taken 838197 times.
925676 if minn < 0 then
282 87479 Dangerous.arrayUpdateNoBoundsChecking(res, i, List.map(v,intAbs));
283 else
284 Dangerous.arrayUpdateNoBoundsChecking(res, i, v);
285 end if;
286 925676 i := i+1;
287 end for;
288 end absAdjacencyMatrix;
289
290 public function isEmpty
291 input BackendDAE.AdjacencyMatrix m;
292 output Boolean b = true;
293 algorithm
294
2/2
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 1 time.
53 for element in m loop
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if not listEmpty(element) then
296 b := false;
297 ✗ return;
298 end if;
299 end for;
300 end isEmpty;
301
302 annotation(__OpenModelica_Interface="backend");
303 end AdjacencyMatrix;
304