Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 70.2% 200 / 0 / 285
Functions: -% 0 / 1 / 1
Branches: 51.4% 75 / 0 / 146

OMCompiler/Compiler/Util/SBFunctions.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 SBFunctions
37 import SBAtomicSet;
38 import SBInterval;
39 import SBLinearMap;
40 import SBMultiInterval;
41 import SBPWLinearMap;
42 import SBSet;
43
44 protected
45 import Array;
46 import MetaModelica.Dangerous.*;
47 import System;
48 import Util;
49 import Vector;
50
51 public
52 function minAtomPW
53 input SBAtomicSet dom;
54 input SBLinearMap lm1;
55 input SBLinearMap lm2;
56 output SBPWLinearMap outMap;
57 protected
58 array<Real> g1, g2, resg;
59 array<Real> o1, o2, reso;
60 array<SBInterval> ints;
61 SBAtomicSet as_aux;
62 SBLinearMap lm_aux;
63 array<SBSet> dom_res;
64 array<SBLinearMap> lm_res;
65 SBSet d1, d2;
66 Real g1i, g2i, o1i, o2i, xinter;
67 SBInterval inti, i1, i2;
68
69 function make_result
70 input SBAtomicSet aset;
71 input SBLinearMap map;
72 output SBPWLinearMap outMap;
73 protected
74 array<SBSet> dom;
75 array<SBLinearMap> lm;
76 algorithm
77 147 dom := arrayCreate(1, SBSet.addAtomicSet(aset, SBSet.newEmpty()));
78 147 lm := arrayCreate(1, map);
79 147 outMap := SBPWLinearMap.new(dom, lm);
80 end make_result;
81 algorithm
82 147 g1 := SBLinearMap.gain(lm1);
83 147 o1 := SBLinearMap.offset(lm1);
84 147 g2 := SBLinearMap.gain(lm2);
85 147 o2 := SBLinearMap.offset(lm2);
86 147 ints := SBMultiInterval.intervals(SBAtomicSet.aset(dom));
87 147 as_aux := SBAtomicSet.copy(dom);
88 147 lm_aux := SBLinearMap.copy(lm1);
89 147 resg := arrayCopy(g1);
90 147 reso := arrayCopy(o1);
91
92
1/2
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
256 for i in 1:arrayLength(g1) loop
93 160 g1i := g1[i];
94 160 g2i := g2[i];
95 160 o1i := o1[i];
96 160 o2i := o2[i];
97 160 inti := ints[i];
98
99
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 137 times.
160 if g1i <> g2i then
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 xinter := (o2i - o1i) / (g1i - g2i);
101
102
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 5 times.
23 if xinter <= SBInterval.lowerBound(inti) then // Intersection before domain.
103
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 12 times.
18 if g2i < g1i then
104 6 lm_aux := SBLinearMap.copy(lm2);
105 end if;
106
107 18 outMap := make_result(as_aux, lm_aux);
108 elseif xinter >= SBInterval.upperBound(inti) then // Intersection after domain.
109
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
5 if g2i > g1i then
110 4 lm_aux := SBLinearMap.copy(lm2);
111 end if;
112
113 5 outMap := make_result(as_aux, lm_aux);
114 else // Intersection in domain.
115 ✗ i1 := SBInterval.new(SBInterval.lowerBound(inti),
116 SBInterval.stepValue(inti),
117 realInt(floor(xinter)));
118 ✗ i2 := SBInterval.new(SBInterval.upperBound(i1) + SBInterval.stepValue(i1),
119 SBInterval.stepValue(inti),
120 SBInterval.upperBound(inti));
121
122 ✗ d1 := SBSet.addAtomicSet(SBAtomicSet.replace(i1, i, as_aux), SBSet.newEmpty());
123 ✗ d2 := SBSet.addAtomicSet(SBAtomicSet.replace(i2, i, as_aux), SBSet.newEmpty());
124
125 ✗ dom_res := listArray({d1, d2});
126
127 ✗ if g1i > g2i then
128 ✗ lm_res := listArray({SBLinearMap.copy(lm1), SBLinearMap.copy(lm2)});
129 else
130 ✗ lm_res := listArray({SBLinearMap.copy(lm2), SBLinearMap.copy(lm1)});
131 end if;
132
133 ✗ outMap := SBPWLinearMap.new(dom_res, lm_res);
134 end if;
135
136 23 return;
137 elseif o1i <> o2i then
138
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 22 times.
28 if o2i < o1i then
139 6 lm_aux := SBLinearMap.copy(lm2);
140 end if;
141
142 28 outMap := make_result(as_aux, lm_aux);
143 28 return;
144 end if;
145 end for;
146
147 96 outMap := make_result(as_aux, lm_aux);
148 end minAtomPW;
149
150 function minPW
151 input SBSet dom;
152 input SBLinearMap lm1;
153 input SBLinearMap lm2;
154 output SBPWLinearMap outMap;
155 protected
156 array<SBSet> aux_dom;
157 array<SBLinearMap> aux_lm;
158 SBSet sres1, sres2, d;
159 SBLinearMap lres1, lres2, l;
160 array<SBAtomicSet> asets;
161 SBPWLinearMap aux;
162 SBAtomicSet as_aux;
163 list<SBSet> sres = {};
164 list<SBLinearMap> lres = {};
165 algorithm
166 147 sres1 := SBSet.newEmpty();
167 147 lres1 := SBLinearMap.newEmpty();
168 147 sres2 := SBSet.newEmpty();
169 147 lres2 := SBLinearMap.newEmpty();
170
171
1/2
✓ Branch 1 taken 147 times.
✗ Branch 2 not taken.
147 if not SBSet.isEmpty(dom) then
172 147 asets := UnorderedSet.toArray(SBSet.asets(dom));
173 as_aux := asets[1];
174 147 aux := minAtomPW(as_aux, lm1, lm2);
175
176
1/2
✓ Branch 1 taken 147 times.
✗ Branch 2 not taken.
147 if not SBPWLinearMap.isEmpty(aux) then
177 147 sres1 := arrayGet(SBPWLinearMap.dom(aux), 1);
178 147 lres1 := arrayGet(SBPWLinearMap.lmap(aux), 1);
179
180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 147 times.
147 for i in 2:arrayLength(asets) loop
181 ✗ aux := minAtomPW(asets[i], lm1, lm2);
182 ✗ aux_dom := SBPWLinearMap.dom(aux);
183 ✗ aux_lm := SBPWLinearMap.lmap(aux);
184
185 ✗ for i in 1:arrayLength(aux_dom) loop
186 ✗ d := aux_dom[i];
187 ✗ l := aux_lm[i];
188
189 ✗ if SBLinearMap.isEqual(l, lres1) then
190 ✗ sres1 := SBSet.union(sres1, d);
191 else
192 ✗ if SBSet.isEmpty(sres2) then
193 ✗ sres2 := SBSet.copy(d);
194 ✗ lres2 := SBLinearMap.copy(l);
195 else
196 ✗ sres2 := SBSet.union(sres2, d);
197 end if;
198 end if;
199 end for;
200 end for;
201 end if;
202 end if;
203
204
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 147 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
147 if not SBSet.isEmpty(sres2) and not SBLinearMap.isEmpty(lres2) then
205 sres := sres2 :: sres;
206 lres := lres2 :: lres;
207 end if;
208
209
2/4
✓ Branch 1 taken 147 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 147 times.
✗ Branch 5 not taken.
147 if not SBSet.isEmpty(sres1) and not SBLinearMap.isEmpty(lres1) then
210 sres := sres1 :: sres;
211 lres := lres1 :: lres;
212 end if;
213
214 147 outMap := SBPWLinearMap.new(listArray(sres), listArray(lres));
215 end minPW;
216
217 function minMap
218 input SBPWLinearMap pw1;
219 input SBPWLinearMap pw2;
220 output SBPWLinearMap outMap = SBPWLinearMap.newEmpty();
221 protected
222 array<SBSet> d1, d2;
223 array<SBLinearMap> lm1, lm2;
224 SBSet d1i, dom;
225 SBLinearMap lm1i;
226 SBPWLinearMap aux;
227 algorithm
228
2/4
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 88 times.
88 if SBPWLinearMap.isEmpty(pw1) or SBPWLinearMap.isEmpty(pw2) then
229 ✗ return;
230 end if;
231
232 88 d1 := SBPWLinearMap.dom(pw1);
233 88 lm1 := SBPWLinearMap.lmap(pw1);
234 88 d2 := SBPWLinearMap.dom(pw2);
235 88 lm2 := SBPWLinearMap.lmap(pw2);
236
237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
256 for i in 1:arrayLength(d1) loop
238 168 d1i := d1[i];
239 168 lm1i := lm1[i];
240
241
1/2
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
578 for j in 1:arrayLength(d2) loop
242 410 dom := SBSet.intersection(d1i, d2[j]);
243
244
2/2
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 263 times.
410 if not SBSet.isEmpty(dom) then
245 147 aux := minPW(dom, lm1i, lm2[j]);
246
2/2
✓ Branch 1 taken 74 times.
✓ Branch 2 taken 73 times.
147 outMap := if SBPWLinearMap.isEmpty(outMap) then
247 aux else SBPWLinearMap.combine(aux, outMap);
248 end if;
249 end for;
250 end for;
251 end minMap;
252
253 function reduceMapN
254 input SBPWLinearMap pw;
255 input Integer dim;
256 output SBPWLinearMap outMap;
257 protected
258 array<SBSet> dom, new_s;
259 Vector<SBSet> sres;
260 array<SBLinearMap> lmap, new_l;
261 Vector<SBLinearMap> lres;
262 SBPWLinearMap pw_copy, new_map;
263 SBSet di, new_domi;
264 SBLinearMap li;
265 Real gdim, odim;
266 Integer off;
267 SBMultiInterval mi;
268 SBInterval idim, new_inter;
269 Integer loint, hiint;
270 array<Real> resg, reso;
271 SBAtomicSet aux_as;
272 UnorderedSet<SBAtomicSet> aux_newd;
273 array<SBAtomicSet> asets;
274 algorithm
275 15 dom := SBPWLinearMap.dom(pw);
276 15 lmap := SBPWLinearMap.lmap(pw);
277
278 15 pw_copy := SBPWLinearMap.copy(pw);
279 15 sres := Vector.fromArray(SBPWLinearMap.dom(pw_copy));
280 15 lres := Vector.fromArray(SBPWLinearMap.lmap(pw_copy));
281
282
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
73 for i in 1:arrayLength(dom) loop
283 58 di := dom[i];
284 58 li := lmap[i];
285 58 gdim := arrayGet(SBLinearMap.gain(li), dim);
286 58 odim := arrayGet(SBLinearMap.offset(li), dim);
287
288
4/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 14 times.
58 if gdim == 1 and odim < 0 then
289 15 off := realInt(-odim);
290 15 asets := UnorderedSet.toArray(SBSet.asets(di));
291
292
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 15 times.
30 for adom in asets loop
293 15 mi := SBAtomicSet.aset(adom);
294 15 idim := arrayGet(SBMultiInterval.intervals(mi), dim);
295 15 loint := SBInterval.lowerBound(idim);
296 15 hiint := SBInterval.upperBound(idim);
297
298
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 14 times.
15 if intReal(hiint - loint) > intReal(off) * intReal(off) then
299 1 new_s := arrayCreateNoInit(off, di);
300 1 new_l := arrayCreateNoInit(off, li);
301
302
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
2 for k in 1:off loop
303 1 resg := arrayCopy(SBLinearMap.gain(li));
304 1 reso := arrayCopy(SBLinearMap.offset(li));
305 1 resg[dim] := 0;
306 1 reso[dim] := loint + k - off - 1;
307
308 1 new_l[k] := SBLinearMap.new(resg, reso);
309
310 1 new_inter := SBInterval.new(loint + k - 1, off, hiint);
311 1 aux_as := SBAtomicSet.replace(new_inter, dim, adom);
312 1 new_s[k] := SBSet.addAtomicSet(aux_as, SBSet.newEmpty());
313 end for;
314
315 1 new_map := SBPWLinearMap.new(new_s, new_l);
316
317 1 aux_newd := UnorderedSet.new(SBAtomicSet.hash, SBAtomicSet.isEqual);
318
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
2 for aux_asi in asets loop
319
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if not SBAtomicSet.isEqual(aux_asi, adom) then
320 ✗ UnorderedSet.add(aux_asi, aux_newd);
321 end if;
322 end for;
323
324 1 new_domi := SBSet.new(aux_newd);
325
326
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 if SBSet.isEmpty(new_domi) then
327
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 if i < Vector.size(sres) then
328 1 Vector.remove(sres, i);
329 1 Vector.remove(lres, i);
330 else
331 ✗ Vector.shrink(sres, i + 1);
332 ✗ Vector.shrink(lres, i + 1);
333 end if;
334 else
335 ✗ Vector.update(sres, i, new_domi);
336 end if;
337
338 1 Vector.appendArray(sres, SBPWLinearMap.dom(new_map));
339 1 Vector.appendArray(lres, SBPWLinearMap.lmap(new_map));
340 end if;
341 end for;
342 end if;
343 end for;
344
345 15 outMap := SBPWLinearMap.new(Vector.toArray(sres), Vector.toArray(lres));
346 end reduceMapN;
347
348 function mapInf
349 input SBPWLinearMap pw;
350 output SBPWLinearMap outMap;
351 protected
352 Integer max_it;
353 array<SBSet> dom;
354 array<SBLinearMap> lmap;
355 SBSet d;
356 SBLinearMap lm;
357 array<Real> gain, off;
358 Real a, b, its;
359
360 function max_inter
361 input SBAtomicSet aset;
362 input Real offset;
363 input Integer dim;
364 input output Real its;
365 protected
366 array<SBInterval> is;
367 SBInterval i;
368 Real hi, lo;
369 algorithm
370 14 is := SBMultiInterval.intervals(SBAtomicSet.aset(aset));
371 14 i := is[dim];
372 14 hi := SBInterval.upperBound(i);
373 14 lo := SBInterval.lowerBound(i);
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 its := max(its, ceil((hi - lo) / abs(offset)));
375 end max_inter;
376 algorithm
377
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if SBPWLinearMap.isEmpty(pw) then
378 ✗ outMap := SBPWLinearMap.newEmpty();
379 ✗ return;
380 end if;
381
382 13 outMap := reduceMapN(pw, 1);
383
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 11 times.
15 for i in 2:SBPWLinearMap.ndim(outMap) loop
384 2 outMap := reduceMapN(pw, i);
385 end for;
386
387 max_it := 0;
388 13 dom := SBPWLinearMap.dom(outMap);
389 13 lmap := SBPWLinearMap.lmap(outMap);
390
391
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
63 for i in 1:arrayLength(dom) loop
392 50 d := dom[i];
393 50 lm := lmap[i];
394 50 gain := SBLinearMap.gain(lm);
395 50 off := SBLinearMap.offset(lm);
396
397 a := 0;
398 b := gain[1];
399
400
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 for j in 1:arrayLength(gain) loop
401 58 a := realMax(a, gain[j] * abs(off[j]));
402 58 b := realMin(b, gain[j]);
403 end for;
404
405
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 36 times.
50 if a > 0 then
406 its := 0;
407
408
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
32 for dim in 1:SBPWLinearMap.ndim(outMap) loop
409
3/4
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 4 times.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
18 if gain[dim] == 1 and off[dim] < 0 then
410 14 its := UnorderedSet.fold(SBSet.asets(d),
411 function max_inter(offset = off[dim], dim = dim), its);
412 end if;
413 end for;
414
415 14 max_it := max_it + realInt(its);
416 elseif b == 0 then
417 23 max_it := max_it + 1;
418 end if;
419 end for;
420
421
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
37 for i in 1:Util.msb(max_it) loop
422 24 outMap := SBPWLinearMap.compPW(outMap, outMap);
423 end for;
424 end mapInf;
425
426 function minAdjCompMap
427 input SBPWLinearMap pw2;
428 input SBPWLinearMap pw1;
429 output SBPWLinearMap outMap;
430 protected
431 array<SBSet> dom;
432 array<SBLinearMap> lmap;
433 SBSet d, dom_inv, aux;
434 SBLinearMap lm_inv, aux_lm1, aux_lm2, lm_res;
435 SBPWLinearMap inv_pw, aux_inv, aux_res;
436 Real inf, g;
437 array<Integer> min_aux;
438 array<Real> resg, reso, gain, off, gres, oi, ginv;
439 algorithm
440 88 dom := SBPWLinearMap.dom(pw2);
441 88 lmap := SBPWLinearMap.lmap(pw2);
442
443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if arrayLength(dom) <> 1 then
444 // Warning: There should be only one pair in the map.
445 ✗ outMap := SBPWLinearMap.newEmpty();
446 ✗ return;
447 end if;
448
449 d := dom[1];
450 88 dom_inv := SBPWLinearMap.image(pw2, d);
451 88 lm_inv := SBLinearMap.inverse(lmap[1]);
452
453 88 inv_pw := SBPWLinearMap.newScalar(dom_inv, lm_inv);
454 88 inf := intReal(System.intMaxLit());
455
456
2/2
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 54 times.
88 if Array.maxElement(SBLinearMap.gain(lm_inv), realLt) < inf then
457 34 outMap := SBPWLinearMap.compPW(pw1, inv_pw);
458 elseif Array.minElement(SBLinearMap.gain(lm_inv), realLt) == inf then
459
1/2
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
44 if not SBPWLinearMap.isEmpty(pw2) then
460 44 aux := SBPWLinearMap.image(pw1, d);
461 44 min_aux := SBSet.minElem(aux);
462 44 resg := arrayCreate(arrayLength(min_aux), 0.0);
463 44 reso := Array.map(min_aux, intReal);
464 44 lm_res := SBLinearMap.new(resg, reso);
465 44 outMap := SBPWLinearMap.newScalar(dom_inv, lm_res);
466 else
467 ✗ outMap := SBPWLinearMap.newEmpty();
468 end if;
469 else
470 10 min_aux := SBSet.minElem(d);
471 10 gain := SBLinearMap.gain(lm_inv);
472 10 off := SBLinearMap.offset(lm_inv);
473 10 resg := arrayCreateNoInit(arrayLength(gain), 0.0);
474 10 reso := arrayCreateNoInit(arrayLength(gain), 0.0);
475
476
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
30 for i in 1:arrayLength(gain) loop
477
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 g := arrayGetNoBoundsChecking(gain, i);
478
479
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if g == inf then
480 10 resg[i] := 0.0;
481 10 reso[i] := intReal(min_aux[i]);
482 else
483 10 resg[i] := g;
484 10 reso[i] := off[i];
485 end if;
486 end for;
487
488 10 aux_lm1 := SBLinearMap.new(resg, reso);
489 10 aux_inv := SBPWLinearMap.newScalar(dom_inv, aux_lm1);
490 10 aux_res := SBPWLinearMap.compPW(pw1, aux_inv);
491
492
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if SBPWLinearMap.isEmpty(aux_res) then
493 ✗ outMap := SBPWLinearMap.newEmpty();
494 else
495 10 aux := SBPWLinearMap.image(pw1, d);
496 10 min_aux := SBSet.minElem(aux);
497 10 lm_res := arrayGet(SBPWLinearMap.lmap(aux_res), 1);
498 10 gres := SBLinearMap.gain(lm_res);
499 10 oi := SBLinearMap.offset(lm_res);
500 10 ginv := SBLinearMap.gain(lm_inv);
501
502
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
30 for i in 1:arrayLength(gain) loop
503
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 g := arrayGetNoBoundsChecking(gain, i);
504
505
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 if g == inf then
506 10 resg[i] := 0.0;
507 10 reso[i] := intReal(min_aux[i]);
508 else
509 10 resg[i] := gres[i];
510 10 reso[i] := oi[i];
511 end if;
512 end for;
513
514 10 aux_lm2 := SBLinearMap.new(resg, reso);
515 20 outMap := SBPWLinearMap.newScalar(arrayGet(SBPWLinearMap.dom(aux_res), 1), aux_lm2);
516 end if;
517 end if;
518 end minAdjCompMap;
519
520 function minAdjMap
521 input SBPWLinearMap pw2;
522 input SBPWLinearMap pw1;
523 output SBPWLinearMap outMap;
524 protected
525 array<SBSet> dom2;
526 array<SBLinearMap> lm2;
527 SBPWLinearMap map1, mapi, min_adj, min_m;
528 algorithm
529
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if SBPWLinearMap.isEmpty(pw2) then
530 ✗ outMap := SBPWLinearMap.newEmpty();
531 ✗ return;
532 end if;
533
534 26 dom2 := SBPWLinearMap.dom(pw2);
535 26 lm2 := SBPWLinearMap.lmap(pw2);
536 26 map1 := SBPWLinearMap.newScalar(dom2[1], lm2[1]);
537 26 outMap := minAdjCompMap(map1, pw1);
538
539
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
88 for i in 1:arrayLength(dom2) loop
540 62 mapi := SBPWLinearMap.newScalar(dom2[i], lm2[i]);
541 62 min_adj := minAdjCompMap(mapi, pw1);
542 62 min_m := minMap(outMap, min_adj);
543
544 62 outMap := SBPWLinearMap.combine(min_adj, outMap);
545
546
2/2
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 15 times.
62 if not SBPWLinearMap.isEmpty(min_m) then
547 47 outMap := SBPWLinearMap.combine(min_m, outMap);
548 end if;
549 end for;
550 end minAdjMap;
551
552 function connectedComponents
553 input SBSet vss;
554 input SBPWLinearMap emap1;
555 input SBPWLinearMap emap2;
556 output SBPWLinearMap outMap;
557 protected
558 SBPWLinearMap ermap1, ermap2, rmap1, rmap2, new_res;
559 SBSet last_im, new_im, diff_im;
560 algorithm
561 6 outMap := SBPWLinearMap.newIdentity(vss);
562
563 new_im := vss;
564 diff_im := vss;
565
566
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 6 times.
19 while not SBSet.isEmpty(diff_im) loop
567 13 ermap1 := SBPWLinearMap.compPW(outMap, emap1);
568 13 ermap2 := SBPWLinearMap.compPW(outMap, emap2);
569
570 13 rmap1 := minAdjMap(ermap1, ermap2);
571 13 rmap2 := minAdjMap(ermap2, ermap1);
572 13 rmap1 := SBPWLinearMap.combine(rmap1, outMap);
573 13 rmap2 := SBPWLinearMap.combine(rmap2, outMap);
574
575 // Without outMap two vertices can map onto each other.
576 13 new_res := minMap(minMap(rmap1, rmap2), outMap);
577 13 outMap := mapInf(new_res);
578
579 last_im := new_im;
580 13 new_im := SBPWLinearMap.image(outMap, vss);
581 13 diff_im := SBSet.complement(last_im, new_im);
582 end while;
583 end connectedComponents;
584
585
586 function test
587 algorithm
588 ✗ test1();
589 ✗ test2();
590 ✗ test3();
591 end test;
592
593 function make_set
594 input list<SBInterval> i;
595 output SBSet s;
596 protected
597 UnorderedSet<SBAtomicSet> ss;
598 algorithm
599 ✗ ss := UnorderedSet.new(SBAtomicSet.hash, SBAtomicSet.isEqual);
600 ✗ UnorderedSet.add(SBAtomicSet.new(SBMultiInterval.fromList(i)), ss);
601 ✗ s := SBSet.new(ss);
602 end make_set;
603
604 function make_pw
605 input list<SBInterval> i;
606 input list<Real> gain;
607 input list<Real> offset;
608 output SBPWLinearMap pw;
609 protected
610 SBSet dom;
611 SBLinearMap lmap;
612 algorithm
613 ✗ dom := make_set(i);
614 ✗ lmap := SBLinearMap.new(listArray(gain), listArray(offset));
615 ✗ pw := SBPWLinearMap.newScalar(dom, lmap);
616 end make_pw;
617
618 function test1
619 protected
620 SBSet vss;
621 SBPWLinearMap emap1, emap2;
622 list<SBSet> sets;
623 list<SBPWLinearMap> pws1, pws2;
624 SBPWLinearMap res;
625 algorithm
626 ✗ sets := {
627 make_set({SBInterval.new(1 , 1, 1)}),
628 make_set({SBInterval.new(2 , 1, 1001)}),
629 make_set({SBInterval.new(1002, 1, 1002)}),
630 make_set({SBInterval.new(1003, 1, 1003)}),
631 make_set({SBInterval.new(1004, 1, 2003)}),
632 make_set({SBInterval.new(2004, 1, 3003)}),
633 make_set({SBInterval.new(3004, 1, 4003)})
634 };
635
636 ✗ vss := SBSet.newEmpty();
637 ✗ for s in sets loop
638 ✗ vss := SBSet.union(vss, s);
639 end for;
640
641 ✗ pws1 := {
642 make_pw({SBInterval.new(1, 1, 1)} , {0.0}, {1.0}),
643 make_pw({SBInterval.new(2, 1, 2)} , {0.0}, {1002.0}),
644 make_pw({SBInterval.new(3, 1, 1001)} , {1.0}, {1001.0}),
645 make_pw({SBInterval.new(1002, 1, 2001)}, {1.0}, {1002.0}),
646 make_pw({SBInterval.new(2002, 1, 3001)}, {1.0}, {1002.0})
647 };
648
649 ✗ emap1 :: pws1 := pws1;
650 ✗ for pw in pws1 loop
651 ✗ emap1 := SBPWLinearMap.combine(pw, emap1);
652 end for;
653
654 ✗ pws2 := {
655 make_pw({SBInterval.new(1, 1, 1)} , {0.0}, {2.0}),
656 make_pw({SBInterval.new(2, 1, 2)} , {0.0}, {1003.0}),
657 make_pw({SBInterval.new(3, 1, 1001)} , {1.0}, {0.0}),
658 make_pw({SBInterval.new(1002, 1, 2001)}, {1.0}, {2.0}),
659 make_pw({SBInterval.new(2002, 1, 3001)}, {0.0}, {1003.0})
660 };
661
662 ✗ emap2 :: pws2 := pws2;
663 ✗ for pw in pws2 loop
664 ✗ emap2 := SBPWLinearMap.combine(pw, emap2);
665 end for;
666
667 ✗ res := connectedComponents(vss, emap1, emap2);
668 ✗ print(SBPWLinearMap.toString(res) + "\n");
669 end test1;
670
671 function test2
672 protected
673 SBSet vss;
674 SBPWLinearMap emap1, emap2;
675 list<SBSet> sets;
676 list<SBPWLinearMap> pws1, pws2;
677 SBPWLinearMap res;
678 algorithm
679 ✗ sets := {
680 make_set({SBInterval.new(1, 1, 1)}),
681 make_set({SBInterval.new(2, 1, 1001)}),
682 make_set({SBInterval.new(1002, 1, 1002)}),
683 make_set({SBInterval.new(1003, 1, 1003)}),
684 make_set({SBInterval.new(1004, 1, 2003)}),
685 make_set({SBInterval.new(2004, 1, 3003)}),
686 make_set({SBInterval.new(3004, 1, 4003)})
687 };
688
689 ✗ vss := SBSet.newEmpty();
690 ✗ for s in sets loop
691 ✗ vss := SBSet.union(vss, s);
692 end for;
693
694 ✗ pws1 := {
695 make_pw({SBInterval.new(1, 1, 1)} , {0.0}, {1.0}),
696 make_pw({SBInterval.new(2, 1, 2)} , {0.0}, {1002.0}),
697 make_pw({SBInterval.new(3, 1, 3)} , {0.0}, {1004.0}),
698 make_pw({SBInterval.new(4, 1, 1002)} , {1.0}, {2000.0}),
699 make_pw({SBInterval.new(1003, 1, 2001)}, {1.0}, {2.0}),
700 make_pw({SBInterval.new(2002, 1, 3001)}, {1.0}, {1002.0})
701 };
702
703 ✗ emap1 :: pws1 := pws1;
704 ✗ for pw in pws1 loop
705 ✗ emap1 := SBPWLinearMap.combine(pw, emap1);
706 end for;
707
708 ✗ pws2 := {
709 make_pw({SBInterval.new(1, 1, 1)} , {0.0}, {2.0}),
710 make_pw({SBInterval.new(2, 1, 2)} , {0.0}, {1003.0}),
711 make_pw({SBInterval.new(3, 1, 3)} , {0.0}, {1003.0}),
712 make_pw({SBInterval.new(4, 1, 1002)} , {1.0}, {-1.0}),
713 make_pw({SBInterval.new(1003, 1, 2001)}, {1.0}, {1.0}),
714 make_pw({SBInterval.new(2002, 1, 3001)}, {1.0}, {2.0})
715 };
716
717 ✗ emap2 :: pws2 := pws2;
718 ✗ for pw in pws2 loop
719 ✗ emap2 := SBPWLinearMap.combine(pw, emap2);
720 end for;
721
722 ✗ res := connectedComponents(vss, emap1, emap2);
723 ✗ print(SBPWLinearMap.toString(res) + "\n");
724 end test2;
725
726 function test3
727 protected
728 SBSet vss;
729 SBPWLinearMap emap1, emap2, res;
730 list<SBSet> sets;
731 list<SBPWLinearMap> pws1, pws2;
732 algorithm
733 ✗ sets := {
734 make_set({SBInterval.new(1, 1, 1000), SBInterval.new(1, 1, 100)}),
735 make_set({SBInterval.new(1001, 1, 2000), SBInterval.new(101, 1, 200)}),
736 make_set({SBInterval.new(2001, 1, 3000), SBInterval.new(201, 1, 300)}),
737 make_set({SBInterval.new(3001, 1, 4000), SBInterval.new(301, 1, 400)}),
738 make_set({SBInterval.new(4001, 1, 4001)}),
739 make_set({SBInterval.new(4002, 1, 4002)})
740 };
741
742 ✗ vss := SBSet.newEmpty();
743 ✗ for s in sets loop
744 ✗ vss := SBSet.union(vss, s);
745 end for;
746
747 ✗ pws1 := {
748 make_pw({SBInterval.new(1, 1, 999) , SBInterval.new(1, 1, 99)} , {1.0, 1.0}, {0.0, 0.0}),
749 make_pw({SBInterval.new(1000, 1, 1998), SBInterval.new(100, 1, 198)}, {1.0, 1.0}, {1001.0, 101.0}),
750 make_pw({SBInterval.new(1999, 1, 2998), SBInterval.new(199, 1, 199)}, {1.0, 0.0}, {-1998.0, 100.0}),
751 make_pw({SBInterval.new(2999, 1, 2999), SBInterval.new(200, 1, 299)}, {0.0, 1.0}, {3001.0, 101.0}),
752 make_pw({SBInterval.new(3000, 1, 3000), SBInterval.new(300, 1, 399)}, {0.0, 1.0}, {3000.0, -99.0})
753 };
754
755 ✗ emap1 :: pws1 := pws1;
756 ✗ for pw in pws1 loop
757 ✗ emap1 := SBPWLinearMap.combine(pw, emap1);
758 end for;
759
760 ✗ pws2 := {
761 make_pw({SBInterval.new(1, 1, 999) , SBInterval.new(1, 1, 99)} , {1.0, 1.0}, {1000.0, 101.0}),
762 make_pw({SBInterval.new(1000, 1, 1998), SBInterval.new(100, 1, 198)}, {1.0, 1.0}, {2002.0, 201.0}),
763 make_pw({SBInterval.new(1999, 1, 2998), SBInterval.new(199, 1, 199)}, {1.0, 0.0}, {-998.0, 101.0}),
764 make_pw({SBInterval.new(2999, 1, 2999), SBInterval.new(200, 1, 299)}, {0.0, 0.0}, {4001.0, 4001.0}),
765 make_pw({SBInterval.new(3000, 1, 3000), SBInterval.new(300, 1, 399)}, {0.0, 0.0}, {4002.0, 4002.0})
766 };
767
768 ✗ emap2 :: pws2 := pws2;
769 ✗ for pw in pws2 loop
770 ✗ emap2 := SBPWLinearMap.combine(pw, emap2);
771 end for;
772
773 ✗ res := connectedComponents(vss, emap1, emap2);
774 ✗ print(SBPWLinearMap.toString(res) + "\n");
775 end test3;
776 annotation(__OpenModelica_Interface="util");
777 end SBFunctions;
778