Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 61.3% 65 / 0 / 106
Functions: -% 0 / 1 / 1
Branches: 40.9% 27 / 0 / 66

OMCompiler/Compiler/Util/SBPWLinearMap.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 uniontype SBPWLinearMap
37 import SBAtomicSet;
38 import SBSet;
39 import SBLinearMap;
40 import SBPWAtomicLinearMap;
41
42 protected
43 import Array;
44 import MetaModelica.Dangerous.*;
45 import System;
46 import Vector;
47
48 public
49 record PW_LINEAR_MAP
50 array<SBSet> dom;
51 array<SBLinearMap> lmap;
52 Integer ndim;
53 end PW_LINEAR_MAP;
54
55 function new
56 input array<SBSet> dom;
57 input array<SBLinearMap> lmap;
58 output SBPWLinearMap map;
59 protected
60 Integer dim = 0;
61 Boolean same_dims = false;
62 algorithm
63
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 625 times.
625 if arrayLength(dom) <> arrayLength(lmap) then
64 // Warning: Domain size should be equal to map size.
65 ✗ map := newEmpty();
66 ✗ return;
67 end if;
68
69
1/2
✓ Branch 0 taken 625 times.
✗ Branch 1 not taken.
625 if not arrayEmpty(dom) then
70 625 dim := SBSet.ndim(dom[1]);
71
72
2/4
✓ Branch 4 taken 625 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 625 times.
625 same_dims := Array.all(dom, function SBSet.isDim(dim = dim)) and
73 Array.all(lmap, function SBLinearMap.isDim(dim = dim));
74 end if;
75
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 625 times.
625 if not same_dims then
77 // Warning: Sets and maps should have the same dimension.
78 ✗ map := newEmpty();
79 else
80 625 map := PW_LINEAR_MAP(arrayCopy(dom), arrayCopy(lmap), dim);
81 end if;
82 end new;
83
84 function newScalar
85 input SBSet dom;
86 input SBLinearMap lmap;
87 output SBPWLinearMap map;
88 algorithm
89
1/2
✓ Branch 2 taken 273 times.
✗ Branch 3 not taken.
273 if SBSet.ndim(dom) == SBLinearMap.ndim(lmap) then
90 273 map := PW_LINEAR_MAP(arrayCreate(1, dom), arrayCreate(1, lmap), 1);
91 else
92 // Warning: Sets and maps should have the same dimension.
93 ✗ map := newEmpty();
94 end if;
95 end newScalar;
96
97 function newEmpty
98 output SBPWLinearMap map;
99 algorithm
100 88 map := PW_LINEAR_MAP(listArray({}), listArray({}), 0);
101 end newEmpty;
102
103 function newIdentity
104 input SBSet set;
105 output SBPWLinearMap map;
106 protected
107 SBLinearMap lmap = SBLinearMap.newIdentity(SBSet.ndim(set));
108 algorithm
109 7 map := PW_LINEAR_MAP(arrayCreate(1, set), arrayCreate(1, lmap), 1);
110 end newIdentity;
111
112 function copy
113 input output SBPWLinearMap map;
114 algorithm
115 15 map.dom := Array.map(map.dom, SBSet.copy);
116 map.lmap := Array.map(map.lmap, SBLinearMap.copy);
117 end copy;
118
119 function dom
120 input SBPWLinearMap map;
121 output array<SBSet> dom = map.dom;
122 end dom;
123
124 function lmap
125 input SBPWLinearMap map;
126 output array<SBLinearMap> lmap = map.lmap;
127 end lmap;
128
129 function ndim
130 input SBPWLinearMap map;
131 output Integer ndim = map.ndim;
132 end ndim;
133
134 function isEmpty
135 input SBPWLinearMap map;
136 output Boolean empty = arrayEmpty(map.dom);
137 end isEmpty;
138
139 function image
140 input SBPWLinearMap map;
141 input SBSet set;
142 output SBSet outSet = SBSet.newEmpty();
143 protected
144 array<SBSet> dom = map.dom;
145 array<SBLinearMap> lmap = map.lmap;
146 SBSet ss, partial_res;
147 algorithm
148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 951 times.
4706 for i in 1:arrayLength(dom) loop
149 3755 ss := dom[i];
150 3755 ss := SBSet.intersection(ss, set);
151
152 3755 partial_res := UnorderedSet.fold(SBSet.asets(ss),
153 function imageAddSet(map = lmap[i]), SBSet.newEmpty());
154
155 3755 outSet := SBSet.union(outSet, partial_res);
156 end for;
157 end image;
158
159 function fullImage
160 "The image of the whole domain of the map."
161 input SBPWLinearMap map;
162 output SBSet outSet = SBSet.newEmpty();
163 protected
164 SBSet partial_res;
165 algorithm
166
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
47 for i in 1:arrayLength(map.dom) loop
167 27 partial_res := UnorderedSet.fold(SBSet.asets(map.dom[i]),
168 function imageAddSet(map = map.lmap[i]), SBSet.newEmpty());
169 27 outSet := SBSet.union(outSet, partial_res);
170 end for;
171 end fullImage;
172
173 function imageAddSet
174 input SBAtomicSet aset;
175 input SBLinearMap map;
176 input output SBSet set;
177 protected
178 SBPWAtomicLinearMap aux_map;
179 algorithm
180 1025 aux_map := SBPWAtomicLinearMap.new(aset, map);
181 1025 set := SBSet.addAtomicSet(SBPWAtomicLinearMap.image(aux_map, aset), set);
182 end imageAddSet;
183
184 function preImage
185 input SBPWLinearMap map;
186 input SBSet set;
187 output SBSet outSet = SBSet.newEmpty();
188 protected
189 array<SBSet> dom = map.dom;
190 array<SBLinearMap> lmap = map.lmap;
191 SBSet ss, partial_res;
192 array<SBAtomicSet> sets;
193
194 function add_set
195 input SBAtomicSet aset;
196 input SBLinearMap map;
197 input array<SBAtomicSet> sets;
198 input output SBSet set;
199 protected
200 SBPWAtomicLinearMap aux_map;
201 algorithm
202 3492 aux_map := SBPWAtomicLinearMap.new(aset, map);
203
204
2/2
✓ Branch 1 taken 778 times.
✓ Branch 2 taken 3492 times.
4270 for as2 in sets loop
205 778 set := SBSet.addAtomicSet(SBPWAtomicLinearMap.preImage(aux_map, as2), set);
206 end for;
207 end add_set;
208 algorithm
209 808 sets := UnorderedSet.toArray(SBSet.asets(set));
210
211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 808 times.
4297 for i in 1:arrayLength(dom) loop
212 3489 ss := dom[i];
213 3489 partial_res := SBSet.newEmpty();
214
215 3489 partial_res := UnorderedSet.fold(SBSet.asets(ss),
216 function add_set(map = lmap[i], sets = sets), SBSet.newEmpty());
217
218 3489 outSet := SBSet.union(outSet, partial_res);
219 end for;
220 end preImage;
221
222 function compPW
223 input SBPWLinearMap map1;
224 input SBPWLinearMap map2;
225 output SBPWLinearMap outMap;
226 protected
227 array<SBSet> dom1 = map1.dom, dom2 = map2.dom;
228 Vector<SBSet> ress;
229 array<SBLinearMap> lmap1 = map1.lmap, lmap2 = map2.lmap;
230 Vector<SBLinearMap> reslm;
231 SBSet aux_dom, new_dom, d1, d2;
232 SBLinearMap l1, l2, new_lm;
233 algorithm
234
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 94 times.
94 if SBPWLinearMap.isEmpty(map1) or SBPWLinearMap.isEmpty(map2) then
235 ✗ outMap := SBPWLinearMap.newEmpty();
236 ✗ return;
237 end if;
238
239 94 ress := Vector.new<SBSet>();
240 94 reslm := Vector.new<SBLinearMap>();
241
242
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
370 for i in 1:arrayLength(dom1) loop
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276 times.
276 d1 := arrayGetNoBoundsChecking(dom1, i);
244
245
1/2
✓ Branch 0 taken 276 times.
✗ Branch 1 not taken.
1072 for j in 1:arrayLength(dom2) loop
246 796 d2 := arrayGetNoBoundsChecking(dom2, j);
247
248 796 aux_dom := image(map2, d2);
249 796 aux_dom := SBSet.intersection(aux_dom, d1);
250 796 aux_dom := preImage(map2, aux_dom);
251 796 new_dom := SBSet.intersection(aux_dom, d2);
252
253
2/2
✓ Branch 1 taken 213 times.
✓ Branch 2 taken 583 times.
796 if not SBSet.isEmpty(new_dom) then
254 213 l1 := lmap1[i];
255 213 l2 := lmap2[j];
256 213 new_lm := SBLinearMap.compose(l1, l2);
257 213 Vector.push(ress, new_dom);
258 213 Vector.push(reslm, new_lm);
259 end if;
260 end for;
261 end for;
262
263 94 outMap := new(Vector.toArray(ress), Vector.toArray(reslm));
264 end compPW;
265
266 function minInvCompact
267 input SBPWLinearMap map;
268 output SBPWLinearMap outMap;
269 protected
270 SBSet aux_dom, dom_inv;
271 SBLinearMap aux_map, map_inv;
272 array<Integer> min;
273 array<Real> resg, reso, g, o;
274 algorithm
275 ✗ if arrayLength(map.dom) <> 1 then
276 // Warning: There should be only one component.
277 ✗ outMap := newEmpty();
278 ✗ return;
279 end if;
280
281 aux_dom := arrayGet(map.dom, 1);
282 ✗ dom_inv := image(map, aux_dom);
283 ✗ aux_map := arrayGet(map.lmap, 1);
284 ✗ map_inv := SBLinearMap.inverse(aux_map);
285 ✗ min := SBSet.minElem(aux_dom);
286
287 ✗ g := SBLinearMap.gain(map_inv);
288 ✗ o := SBLinearMap.offset(map_inv);
289
290 ✗ resg := arrayCreateNoInit(arrayLength(g), 0.0);
291 ✗ reso := arrayCreateNoInit(arrayLength(o), 0.0);
292
293 ✗ for i in 1:arrayLength(g) loop
294 ✗ if g[i] == intReal(System.intMaxLit()) then
295 ✗ resg[i] := 0;
296 ✗ reso[i] := intReal(min[i]);
297 else
298 ✗ resg[i] := g[i];
299 ✗ reso[i] := o[i];
300 end if;
301 end for;
302
303 ✗ outMap := new(arrayCreate(1, dom_inv), arrayCreate(1, SBLinearMap.new(resg, reso)));
304 end minInvCompact;
305
306 function wholeDom
307 input SBPWLinearMap map;
308 output SBSet set;
309 algorithm
310 221 set := SBSet.newEmpty();
311
312
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✓ Branch 3 taken 237 times.
✓ Branch 4 taken 221 times.
679 for s in map.dom loop
313 237 set := SBSet.union(set, s);
314 end for;
315 end wholeDom;
316
317 function combine
318 input SBPWLinearMap map1;
319 input SBPWLinearMap map2;
320 output SBPWLinearMap outMap;
321 protected
322 Vector<SBSet> sres;
323 Vector<SBLinearMap> lres;
324 array<SBSet> dom2;
325 array<SBLinearMap> lm2;
326 SBSet aux1, s2, new_dom;
327 algorithm
328
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
221 if SBPWLinearMap.isEmpty(map1) then
329 ✗ outMap := copy(map2);
330 ✗ return;
331 end if;
332
333
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
221 if SBPWLinearMap.isEmpty(map2) then
334 ✗ outMap := copy(map1);
335 ✗ return;
336 end if;
337
338 221 sres := Vector.fromArray(map1.dom);
339 221 lres := Vector.fromArray(map1.lmap);
340
341 221 dom2 := map2.dom;
342 221 lm2 := map2.lmap;
343 221 aux1 := wholeDom(map1);
344
345
1/2
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
608 for i in 1:arrayLength(dom2) loop
346 387 s2 := dom2[i];
347 387 new_dom := SBSet.complement(s2, aux1);
348
349
2/2
✓ Branch 1 taken 274 times.
✓ Branch 2 taken 113 times.
387 if not SBSet.isEmpty(new_dom) then
350 274 Vector.push(sres, new_dom);
351 274 Vector.push(lres, lm2[i]);
352 end if;
353 end for;
354
355 221 outMap := new(Vector.toArray(sres), Vector.toArray(lres));
356 end combine;
357
358 function atomize
359 input SBPWLinearMap map;
360 output SBPWLinearMap outMap;
361 protected
362 list<SBSet> dres = {};
363 array<SBSet> dom = map.dom;
364 list<SBLinearMap> lres = {};
365 array<SBLinearMap> lm = map.lmap;
366 SBSet d, aux;
367 SBLinearMap l;
368 array<SBAtomicSet> asets;
369 algorithm
370 ✗ for i in 1:arrayLength(dom) loop
371 ✗ d := dom[i];
372 ✗ l := lm[i];
373 ✗ asets := UnorderedSet.toArray(SBSet.asets(d));
374
375 ✗ for s in asets loop
376 ✗ aux := SBSet.newEmpty();
377 ✗ aux := SBSet.addAtomicSet(s, aux);
378
379 dres := aux :: dres;
380 lres := l :: lres;
381 end for;
382 end for;
383
384 ✗ outMap := new(listArray(listReverseInPlace(dres)),
385 listArray(listReverseInPlace(lres)));
386 end atomize;
387
388 function isEqual
389 input SBPWLinearMap map1;
390 input SBPWLinearMap map2;
391 output Boolean equal;
392 algorithm
393 ✗ equal := Array.isEqualOnTrue(map1.dom, map2.dom, SBSet.isEqual) and
394 Array.isEqualOnTrue(map1.lmap, map2.lmap, SBLinearMap.isEqual);
395 end isEqual;
396
397 function toString
398 input SBPWLinearMap map;
399 output String str;
400 protected
401 array<SBSet> dom = map.dom;
402 array<SBLinearMap> lmap = map.lmap;
403 list<String> strl = {};
404
405 function helper
406 input SBAtomicSet set;
407 input SBLinearMap lm;
408 output String str;
409 algorithm
410 ✗ str := "{" + SBPWAtomicLinearMap.toString(SBPWAtomicLinearMap.PW_ATOMIC_LINEAR_MAP(set, lm)) + "}";
411 end helper;
412 algorithm
413 ✗ for i in arrayLength(dom):-1:1 loop
414 ✗ strl := UnorderedSet.toString(SBSet.asets(dom[i]), function helper(lm = lmap[i]), "U") :: strl;
415 end for;
416
417 ✗ str := "[" + stringDelimitList(strl, ",") + "]";
418 end toString;
419
420 annotation(__OpenModelica_Interface="util");
421 end SBPWLinearMap;
422