Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 24.8% 176 / 0 / 710
Functions: 32.4% 33 / 1 / 103
Branches: 13.8% 59 / 0 / 426

OMCompiler/SimulationRuntime/c/util/integer_array.c
Line Branch Exec Source
1 /*
2 * This file belongs to the OpenModelica Run-Time System
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings
5 * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights
6 * reserved.
7 *
8 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE
9 * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY
10 * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
11 * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL
12 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
13 *
14 * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License
15 * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs:
16 * http://www.openmodelica.org or https://github.com/OpenModelica/ or
17 * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU
18 * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW
19 * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause.
20 *
21 * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY
23 * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF
24 * OSMC-PL.
25 *
26 */
27
28
29 #include "integer_array.h"
30 #include "index_spec.h"
31 #include "../gc/omc_gc.h"
32 #include "division.h"
33 #include "generic_array.h"
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38 #include <math.h>
39
40 #include "omc_error.h"
41
42 static OMC_INLINE modelica_integer *integer_ptrget(const integer_array *a, size_t i)
43 {
44 ✗ return ((modelica_integer *) a->data) + i;
45 }
46
47 static OMC_INLINE void integer_set(integer_array *a, size_t i, modelica_integer r)
48 {
49 1016647 ((modelica_integer *) a->data)[i] = r;
50 20 }
51
52 2389105 modelica_integer integer_get(const integer_array a, size_t i)
53 {
54 2389105 return ((modelica_integer *) a.data)[i];
55 }
56
57 75247 modelica_integer integer_get_2D(const integer_array a, size_t i, size_t j)
58 {
59 75247 return integer_get(a, getIndex_2D(a.dim_size,i,j));
60 }
61
62 1061 modelica_integer integer_get_3D(const integer_array a, size_t i, size_t j, size_t k)
63 {
64 1061 return integer_get(a, getIndex_3D(a.dim_size,i,j,k));
65 }
66
67 ✗ modelica_integer integer_get_4D(const integer_array a, size_t i, size_t j, size_t k, size_t l)
68 {
69 ✗ return integer_get(a, getIndex_4D(a.dim_size,i,j,k,l));
70 }
71
72 ✗ modelica_integer integer_get_5D(const integer_array a, size_t i, size_t j, size_t k, size_t l, size_t m)
73 {
74 ✗ return integer_get(a, getIndex_5D(a.dim_size,i,j,k,l,m));
75 }
76
77 /** function: integer_array_create
78 **
79 ** sets all fields in a integer_array, i.e. data, ndims and dim_size.
80 **/
81 19782 void integer_array_create(integer_array *dest, modelica_integer *data,
82 int ndims, ...)
83 {
84 va_list ap;
85 19782 va_start(ap, ndims);
86 19782 base_array_create(dest, data, ndims, ap);
87 19782 va_end(ap);
88 19782 }
89
90
91 309222 void simple_alloc_1d_integer_array(integer_array* dest, int n)
92 {
93
1/2
✓ Branch 0 taken 309222 times.
✗ Branch 1 not taken.
309222 simple_alloc_1d_base_array(dest, n, n ? integer_alloc(n) : NULL);
94 309222 }
95
96 ✗ void simple_alloc_2d_integer_array(integer_array* dest, int r, int c)
97 {
98 ✗ simple_alloc_2d_base_array(dest, r, c, integer_alloc(r * c));
99 ✗ }
100
101 291735 void alloc_integer_array(integer_array* dest,int ndims,...)
102 {
103 size_t elements = 0;
104 va_list ap;
105 291735 va_start(ap, ndims);
106 291735 elements = alloc_base_array(dest, ndims, ap);
107 291735 va_end(ap);
108 291735 dest->data = integer_alloc(elements);
109 291735 }
110
111 78748 void alloc_integer_array_data(integer_array* a)
112 {
113 78748 a->data = integer_alloc(base_array_nr_of_elements(*a));
114 78748 }
115
116 2 void copy_integer_array_data_mem(const integer_array source,
117 modelica_integer *dest)
118 {
119 size_t i, nr_of_elements;
120
121
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 omc_assert_macro(base_array_ok(&source));
122
123 2 nr_of_elements = base_array_nr_of_elements(source);
124
125
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for(i = 0; i < nr_of_elements; ++i) {
126 4 dest[i] = integer_get(source, i);
127 }
128 2 }
129
130 2 void copy_integer_array(const integer_array source, integer_array *dest)
131 {
132 2 integer_array_alloc_copy(source,*dest);
133 2 }
134
135 40344 static modelica_integer integer_le(modelica_integer x, modelica_integer y)
136 {
137 40344 return (x <= y);
138 }
139
140 ✗ static modelica_integer integer_ge(modelica_integer x, modelica_integer y)
141 {
142 ✗ return (x >= y);
143 }
144
145 /* Creates an integer array from a range with a start, stop and step value.
146 * Ex: 1:2:6 => {1,3,5} */
147 39837 void create_integer_array_from_range(integer_array *dest, modelica_integer start, modelica_integer step, modelica_integer stop)
148 {
149 size_t elements;
150 size_t i;
151 modelica_integer (*comp_func)(modelica_integer, modelica_integer);
152
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39837 times.
39837 omc_assert_macro(step != 0);
154
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39837 times.
39837 comp_func = (step > 0) ? &integer_le : &integer_ge;
156
1/2
✓ Branch 1 taken 39837 times.
✗ Branch 2 not taken.
39837 elements = comp_func(start, stop) ? (((stop - start) / step) + 1) : 0;
157
158 39837 simple_alloc_1d_integer_array(dest, elements);
159
160
2/2
✓ Branch 0 taken 180576 times.
✓ Branch 1 taken 39837 times.
220413 for(i = 0; i < elements; start += step, ++i) {
161 integer_set(dest, i, start);
162 }
163 39837 }
164
165 /*
166 * Fills an integer array ROW from a range with a start, stop and step value.
167 * The last argument is the row/dimension to be filled.
168 * e.g: Integer a[10], b[2][10]; a := 1:2:6; b[1] := 1:10;
169 *
170 */
171 507 void fill_integer_array_from_range(integer_array *dest, modelica_integer start, modelica_integer step,
172 modelica_integer stop/*, size_t dim*/)
173 {
174 size_t elements;
175 size_t i;
176 modelica_integer value = start;
177 modelica_integer (*comp_func)(modelica_integer, modelica_integer);
178
179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 507 times.
507 omc_assert_macro(step != 0);
180
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 507 times.
507 comp_func = (step > 0) ? &integer_le : &integer_ge;
182
1/2
✓ Branch 1 taken 507 times.
✗ Branch 2 not taken.
507 elements = comp_func(start, stop) ? (((stop - start) / step) + 1) : 0;
183
184
2/2
✓ Branch 0 taken 1014 times.
✓ Branch 1 taken 507 times.
1521 for(i = 0; i < elements; value += step, ++i) {
185 integer_set(dest, i, value);
186 }
187 507 }
188
189 /*
190 a[1:3] := b;
191 */
192
193 static inline modelica_integer* calc_integer_index_spec(int ndims, const _index_t* idx_vec,
194 const integer_array * arr,
195 const index_spec_t* spec)
196 {
197 return integer_ptrget(arr, calc_base_index_spec(ndims, idx_vec, arr, spec));
198 }
199
200 /* Uses zero based indexing */
201 ✗ modelica_integer* calc_integer_index(int ndims, const _index_t* idx_vec,
202 const integer_array * arr)
203 {
204 ✗ return integer_ptrget(arr, calc_base_index(ndims, idx_vec, arr));
205 }
206
207 /* One based index*/
208 ✗ modelica_integer* calc_integer_index_va(const integer_array * source,int ndims,
209 va_list ap)
210 {
211 ✗ return integer_ptrget(source, calc_base_index_va(source, ndims, ap));
212 }
213
214 ✗ void print_integer_matrix(const integer_array * source)
215 {
216 _index_t i,j;
217 modelica_integer value;
218
219 ✗ if(source->ndims == 2) {
220 ✗ printf("%d X %d matrix:\n", (int) source->dim_size[0], (int) source->dim_size[1]);
221 ✗ for(i = 0; i < source->dim_size[0]; ++i) {
222 ✗ for(j = 0; j < source->dim_size[1]; ++j) {
223 ✗ value = integer_get(*source, (i * source->dim_size[1]) + j);
224 printf(OMC_INT_FORMAT "\t", value);
225 }
226 printf("\n");
227 }
228 } else {
229 printf("array with %d dimensions\n", source->ndims);
230 }
231 ✗ }
232
233 ✗ void print_integer_array(const integer_array * source)
234 {
235 _index_t i,j;
236 modelica_integer *data;
237 ✗ omc_assert_macro(base_array_ok(source));
238
239 ✗ data = (modelica_integer *) source->data;
240 ✗ if(source->ndims == 1) {
241 ✗ for(i = 1; i < source->dim_size[0]; ++i) {
242 ✗ printf(OMC_INT_FORMAT ", ",*data);
243 ✗ ++data;
244 }
245 ✗ if(0 < source->dim_size[0]) {
246 ✗ printf(OMC_INT_FORMAT,*data);
247 }
248 ✗ } else if(source->ndims > 1) {
249 size_t k, n;
250 ✗ n = base_array_nr_of_elements(*source) /
251 ✗ (source->dim_size[0] * source->dim_size[1]);
252 ✗ for(k = 0; k < n; ++k) {
253 ✗ for(i = 0; i < source->dim_size[1]; ++i) {
254 ✗ for(j = 0; j < source->dim_size[0]; ++j) {
255 ✗ printf(OMC_INT_FORMAT ", ",*data);
256 ✗ ++data;
257 }
258 ✗ if(0 < source->dim_size[0]) {
259 ✗ printf(OMC_INT_FORMAT,*data);
260 }
261 printf("\n");
262 }
263 ✗ if((k + 1) < n) {
264 printf("\n =================\n");
265 }
266 }
267 }
268 ✗ }
269
270 800816 void put_integer_element(modelica_integer value, int i1, integer_array* dest)
271 {
272 /* Assert that dest has correct dimension */
273 /* Assert that i1 is a valid index */
274 800816 integer_set(dest, i1, value);
275 800816 }
276
277 ✗ void put_integer_matrix_element(modelica_integer value, int r, int c,
278 integer_array* dest)
279 {
280 /* Assert that dest hast correct dimension */
281 /* Assert that r and c are valid indices */
282 ✗ integer_set(dest, (r * dest->dim_size[1]) + c, value);
283 /* printf("Index %d\n",r*dest->dim_size[1]+c); */
284 ✗ }
285
286 /* Zero based index */
287 ✗ void simple_indexed_assign_integer_array1(const integer_array * source,
288 int i1,
289 integer_array* dest)
290 {
291 /* Assert that source has the correct dimension */
292 /* Assert that dest has the correct dimension */
293 ✗ integer_set(dest, i1, integer_get(*source, i1));
294 ✗ }
295
296 ✗ void simple_indexed_assign_integer_array2(const integer_array * source,
297 int i1, int i2,
298 integer_array* dest)
299 {
300 size_t index;
301 /* Assert that source has correct dimension */
302 /* Assert that dest has correct dimension */
303 ✗ index = (i1 * source->dim_size[1]) + i2;
304 ✗ integer_set(dest, index, integer_get(*source, index));
305 ✗ }
306
307 ✗ void indexed_assign_integer_array(const integer_array source, integer_array* dest,
308 const index_spec_t* dest_spec)
309 {
310 _index_t *idx_vec1, *idx_size;
311 _index_t j, n;
312 ✗ indexed_assign_base_array_size_alloc(&source, dest, dest_spec, &idx_vec1, &idx_size);
313
314 ✗ n = base_array_nr_of_elements(source);
315 ✗ for (j = 0; j < n; j++) {
316 ✗ integer_set(dest,
317 calc_base_index_spec(dest->ndims, idx_vec1, dest, dest_spec),
318 integer_get(source, j));
319 ✗ next_index(dest_spec->ndims, idx_vec1, idx_size);
320 }
321
322 ✗ omc_rc_release_inline(idx_vec1);
323 ✗ omc_rc_release_inline(idx_size);
324 ✗ }
325
326 /*
327 function: index_integer_array
328 *
329 * Returns an subscript of the source array in the destination array.
330 * Assumes that both source array and destination array is properly
331 * allocated.
332 *
333 * a := b[1:3];
334 *
335 */
336
337 ✗ void index_integer_array(const integer_array * source,
338 const index_spec_t* source_spec,
339 integer_array* dest)
340 {
341 _index_t* idx_vec1;
342 _index_t* idx_vec2;
343 _index_t* idx_size;
344 int j;
345 int i;
346
347 ✗ omc_assert_macro(base_array_ok(source));
348 ✗ omc_assert_macro(base_array_ok(dest));
349 ✗ omc_assert_macro(index_spec_ok(source_spec));
350 ✗ omc_assert_macro(index_spec_fit_base_array(source_spec,source));
351 ✗ for(i = 0, j = 0; i < source->ndims; ++i) {
352 ✗ if((source_spec->index_type[i] == 'W')
353 ✗ ||
354 (source_spec->index_type[i] == 'A')) {
355 ✗ ++j;
356 }
357 }
358 ✗ omc_assert_macro(j == dest->ndims);
359 ✗ if (base_array_nr_of_elements(*dest) == 0) {
360 return;
361 }
362
363 ✗ idx_vec1 = size_alloc(source->ndims); /*indices in the source array*/
364 ✗ idx_vec2 = size_alloc(dest->ndims); /* indices in the destination array*/
365 ✗ idx_size = size_alloc(source_spec->ndims);
366
367 ✗ for(i = 0; i < source->ndims; ++i) {
368 ✗ idx_vec1[i] = 0;
369 }
370 ✗ for(i = 0; i < source_spec->ndims; ++i) {
371 ✗ if(source_spec->index_type[i] != 'W') {
372 ✗ idx_size[i] = imax(source_spec->dim_size[i],1);
373 } else {
374 ✗ idx_size[i] = source->dim_size[i];
375 }
376 }
377
378 do {
379 ✗ for(i = 0, j = 0; i < source->ndims; ++i) {
380 ✗ if((source_spec->index_type[i] == 'W')
381 ✗ ||
382 (source_spec->index_type[i] == 'A')) {
383 ✗ idx_vec2[j] = idx_vec1[i];
384 ✗ ++j;
385 }
386 }
387
388 ✗ integer_set(dest, calc_base_index(dest->ndims, idx_vec2, dest),
389 integer_get(*source,
390 calc_base_index_spec(source->ndims, idx_vec1,
391 source, source_spec)));
392
393 ✗ } while(0 == next_index(source->ndims, idx_vec1, idx_size));
394 ✗ omc_rc_release_inline(idx_vec1);
395 ✗ omc_rc_release_inline(idx_vec2);
396 ✗ omc_rc_release_inline(idx_size);
397 }
398
399 /*
400 * function: index_alloc_integer_array
401 *
402 * Returns an subscript of the source array in the destination array
403 * in the same manner as index_integer_array, except that the destination
404 * array is allocated.
405 *
406 *
407 * a := b[1:3];
408 */
409
410 ✗ void index_alloc_integer_array(const integer_array * source,
411 const index_spec_t* source_spec,
412 integer_array* dest)
413 {
414 ✗ index_alloc_base_array_size(source, source_spec, dest);
415 ✗ alloc_integer_array_data(dest);
416 ✗ index_integer_array(source, source_spec, dest);
417 ✗ }
418
419 /* idx(a[i,j,k]) = i * a->dim_size[1] * a->dim_size[2] + j * a->dim_size[2] + k */
420 /* Returns dest := source[i1,:,:...]*/
421 ✗ void simple_index_alloc_integer_array1(const integer_array * source, int i1,
422 integer_array* dest)
423 {
424 int i;
425 ✗ omc_assert_macro(base_array_ok(source));
426
427 ✗ dest->ndims = source->ndims - 1;
428 ✗ dest->dim_size = size_alloc(dest->ndims);
429 ✗ dest->owns_data = 1;
430
431 ✗ for(i = 0; i < dest->ndims; ++i) {
432 ✗ dest->dim_size[i] = source->dim_size[i+1];
433 }
434 ✗ alloc_integer_array_data(dest);
435
436 ✗ simple_index_integer_array1(source, i1, dest);
437 ✗ }
438
439 /* Returns dest := source[i1,:,:...]*/
440 ✗ void simple_index_integer_array1(const integer_array * source,
441 int i1,
442 integer_array* dest)
443 {
444 size_t i;
445 ✗ size_t nr_of_elements = base_array_nr_of_elements(*dest);
446 ✗ size_t off = nr_of_elements * i1;
447
448 ✗ omc_assert_macro(dest->ndims == (source->ndims - 1));
449
450 ✗ for(i = 0 ; i < nr_of_elements ; i++) {
451 ✗ integer_set(dest, i, integer_get(*source, off + i));
452 }
453 ✗ }
454
455 /* Returns dest := source[i1,i2,:,:...]*/
456 ✗ void simple_index_integer_array2(const integer_array * source,
457 int i1, int i2,
458 integer_array* dest)
459 {
460 size_t i;
461 ✗ size_t nr_of_elements = base_array_nr_of_elements(*dest);
462 ✗ size_t off = nr_of_elements * ((source->dim_size[1] * i1) + i2);
463
464 ✗ for(i = 0 ; i < nr_of_elements ; i++) {
465 ✗ integer_set(dest, i, integer_get(*source, off + i));
466 }
467 ✗ }
468
469 ✗ void array_integer_array(integer_array* dest,int n,integer_array first,...)
470 {
471 int i,j,c;
472 va_list ap;
473
474 ✗ integer_array *elts=(integer_array*)malloc(sizeof(integer_array) * n);
475 ✗ omc_assert_macro(elts);
476 /* collect all array ptrs to simplify traversal.*/
477 ✗ va_start(ap,first);
478 ✗ elts[0] = first;
479 ✗ for(i = 1; i < n; ++i) {
480 ✗ elts[i] = va_arg(ap, integer_array);
481 }
482 ✗ va_end(ap);
483
484 ✗ check_base_array_dim_sizes(elts,n);
485
486 ✗ for(i = 0, c = 0; i < n; ++i) {
487 ✗ int m = base_array_nr_of_elements(elts[i]);
488 ✗ for(j = 0; j < m; ++j) {
489 ✗ integer_set(dest, c, integer_get(elts[i], j));
490 ✗ c++;
491 }
492 }
493 ✗ free(elts);
494 ✗ }
495
496 ✗ void array_alloc_integer_array(integer_array* dest,int n,
497 integer_array first,...)
498 {
499 int i,j,c;
500 va_list ap;
501
502 ✗ integer_array *elts=(integer_array*)malloc(sizeof(integer_array) * n);
503 ✗ omc_assert_macro(elts);
504 /* collect all array ptrs to simplify traversal.*/
505 ✗ va_start(ap,first);
506 ✗ elts[0] = first;
507 ✗ for(i = 1; i < n; ++i) {
508 ✗ elts[i] = va_arg(ap, integer_array);
509 }
510 ✗ va_end(ap);
511
512 ✗ check_base_array_dim_sizes(elts,n);
513
514 ✗ if(first.ndims == 1) {
515 ✗ alloc_integer_array(dest, 2, n, first.dim_size[0]);
516 ✗ } else if(first.ndims == 2) {
517 ✗ alloc_integer_array(dest, 3, n, first.dim_size[0], first.dim_size[1]);
518 ✗ } else if(first.ndims == 3) {
519 ✗ alloc_integer_array(dest, 4, n, first.dim_size[0], first.dim_size[1], first.dim_size[2]);
520 ✗ } else if(first.ndims == 4) {
521 ✗ alloc_integer_array(dest, 5, n, first.dim_size[0], first.dim_size[1], first.dim_size[2], first.dim_size[3]);
522 } else {
523 ✗ omc_assert_macro(0 && "Dimension size > 4 not impl. yet");
524 }
525
526 ✗ for(i = 0, c = 0; i < n; ++i) {
527 ✗ int m = base_array_nr_of_elements(elts[i]);
528 ✗ for(j = 0; j < m; ++j) {
529 ✗ integer_set(dest, c, integer_get(elts[i], j));
530 ✗ c++;
531 }
532 }
533 ✗ free(elts);
534 ✗ }
535
536 /* array_alloc_scalar_integer_array
537 *
538 * Creates(incl allocation) an array from scalar elements.
539 */
540 228458 void array_alloc_scalar_integer_array(integer_array* dest, int n,
541 modelica_integer first,...)
542 {
543 int i;
544 va_list ap;
545 228458 simple_alloc_1d_integer_array(dest,n);
546 228458 va_start(ap,first);
547 228458 put_integer_element(first,0,dest);
548
2/2
✓ Branch 0 taken 572355 times.
✓ Branch 1 taken 228458 times.
800813 for(i = 1; i < n; ++i) {
549 572355 put_integer_element(va_arg(ap, modelica_integer),i,dest);
550 }
551 228458 va_end(ap);
552 228458 }
553
554 /* function: cat_integer_array
555 *
556 * Concatenates n integer arrays along the k:th dimension.
557 * k is one based
558 */
559 ✗ void cat_integer_array(int k, integer_array* dest, int n,
560 const integer_array* first,...)
561 {
562 va_list ap;
563 int i, j, r, c;
564 int n_sub = 1, n_super = 1;
565 int new_k_dim_size = 0;
566 ✗ const integer_array **elts = (const integer_array**)malloc(sizeof(integer_array *) * n);
567
568 ✗ omc_assert_macro(elts);
569 /* collect all array ptrs to simplify traversal.*/
570 ✗ va_start(ap, first);
571 ✗ elts[0] = first;
572
573 ✗ for(i = 1; i < n; i++) {
574 ✗ elts[i] = va_arg(ap,const integer_array*);
575 }
576 ✗ va_end(ap);
577
578 /* check dim sizes of all inputs and dest */
579 ✗ omc_assert_macro(elts[0]->ndims >= k);
580 ✗ for(i = 0; i < n; i++) {
581 ✗ omc_assert_macro(dest->ndims == elts[i]->ndims);
582 ✗ for(j = 0; j < (k - 1); j++) {
583 ✗ omc_assert_macro(dest->dim_size[j] == elts[i]->dim_size[j]);
584 }
585 ✗ new_k_dim_size += elts[i]->dim_size[k-1];
586 ✗ for(j = k; j < elts[0]->ndims; j++) {
587 ✗ omc_assert_macro(dest->dim_size[j] == elts[i]->dim_size[j]);
588 }
589 }
590 ✗ omc_assert_macro(dest->dim_size[k-1] == new_k_dim_size);
591
592 /* calculate size of sub and super structure in 1-dim data representation */
593 ✗ for(i = 0; i < (k - 1); i++) {
594 ✗ n_super *= elts[0]->dim_size[i];
595 }
596 ✗ for(i = k; i < elts[0]->ndims; i++) {
597 ✗ n_sub *= elts[0]->dim_size[i];
598 }
599
600 /* concatenation along k-th dimension */
601 j = 0;
602 ✗ for(i = 0; i < n_super; i++) {
603 ✗ for(c = 0; c < n; c++) {
604 ✗ int n_sub_k = n_sub * elts[c]->dim_size[k-1];
605 ✗ for(r = 0; r < n_sub_k; r++) {
606 ✗ integer_set(dest, j,
607 ✗ integer_get(*elts[c], r + (i * n_sub_k)));
608 ✗ j++;
609 }
610 }
611 }
612 ✗ free(elts);
613 ✗ }
614
615 /* function: cat_alloc_integer_array
616 *
617 * Concatenates n integer arrays along the k:th dimension.
618 * allocates space in dest array
619 * k is one based
620 */
621 ✗ void cat_alloc_integer_array(int k, integer_array* dest, int n,
622 const integer_array* first,...)
623 {
624 va_list ap;
625 int i, j, r, c;
626 int n_sub = 1, n_super = 1;
627 int new_k_dim_size = 0;
628 ✗ const integer_array **elts = (const integer_array**)malloc(sizeof(integer_array *) * n);
629
630 ✗ omc_assert_macro(elts);
631 /* collect all array ptrs to simplify traversal.*/
632 ✗ va_start(ap, first);
633 ✗ elts[0] = first;
634
635 ✗ for(i = 1; i < n; i++) {
636 ✗ elts[i] = va_arg(ap,const integer_array*);
637 }
638 ✗ va_end(ap);
639
640 /* check dim sizes of all inputs */
641 ✗ omc_assert_macro(elts[0]->ndims >= k);
642 ✗ new_k_dim_size = elts[0]->dim_size[k-1];
643 ✗ for(i = 1; i < n; i++) {
644 ✗ omc_assert_macro(elts[0]->ndims == elts[i]->ndims);
645 ✗ for(j = 0; j < (k - 1); j++) {
646 ✗ omc_assert_macro(elts[0]->dim_size[j] == elts[i]->dim_size[j]);
647 }
648 ✗ new_k_dim_size += elts[i]->dim_size[k-1];
649 ✗ for(j = k; j < elts[0]->ndims; j++) {
650 ✗ omc_assert_macro(elts[0]->dim_size[j] == elts[i]->dim_size[j]);
651 }
652 }
653
654 /* calculate size of sub and super structure in 1-dim data representation */
655 ✗ for(i = 0; i < (k - 1); i++) {
656 ✗ n_super *= elts[0]->dim_size[i];
657 }
658 ✗ for(i = k; i < elts[0]->ndims; i++) {
659 ✗ n_sub *= elts[0]->dim_size[i];
660 }
661 /* allocate dest structure */
662 ✗ dest->data = integer_alloc( n_super * new_k_dim_size * n_sub);
663 ✗ dest->ndims = elts[0]->ndims;
664 ✗ dest->dim_size = size_alloc(dest->ndims);
665 ✗ dest->owns_data = 1;
666 ✗ for(j = 0; j < dest->ndims; j++) {
667 ✗ dest->dim_size[j] = elts[0]->dim_size[j];
668 }
669 ✗ dest->dim_size[k-1] = new_k_dim_size;
670 /* concatenation along k-th dimension */
671 j = 0;
672 ✗ for(i = 0; i < n_super; i++) {
673 ✗ for(c = 0; c < n; c++) {
674 ✗ int n_sub_k = n_sub * elts[c]->dim_size[k-1];
675 ✗ for(r = 0; r < n_sub_k; r++) {
676 ✗ integer_set(dest, j,
677 ✗ integer_get(*elts[c], r + (i * n_sub_k)));
678 ✗ j++;
679 }
680 }
681 }
682 ✗ free(elts);
683 ✗ }
684
685 ✗ void range_alloc_integer_array(modelica_integer start, modelica_integer stop, modelica_integer inc, integer_array* dest)
686 {
687 int n;
688
689 ✗ n = (int)floor((stop-start)/inc)+1;
690 ✗ simple_alloc_1d_integer_array(dest,n);
691 ✗ range_integer_array(start,stop,inc,dest);
692 ✗ }
693
694 ✗ void range_integer_array(modelica_integer start, modelica_integer stop, modelica_integer inc, integer_array* dest)
695 {
696 size_t i;
697 /* Assert that dest has correct size */
698 ✗ for(i = 0; i < dest->dim_size[0]; ++i) {
699 ✗ integer_set(dest, i, start + (i * inc));
700 }
701 ✗ }
702
703 ✗ void usub_integer_array(integer_array* a)
704 {
705 size_t nr_of_elements, i;
706
707 ✗ nr_of_elements = base_array_nr_of_elements(*a);
708 ✗ for(i = 0; i < nr_of_elements; ++i)
709 {
710 ✗ integer_set(a, i, -integer_get(*a, i));
711 }
712 ✗ }
713
714 ✗ void usub_alloc_integer_array(const integer_array a, integer_array* dest)
715 {
716 size_t nr_of_elements, i;
717 clone_integer_array_spec(&a,dest);
718 ✗ alloc_integer_array_data(dest);
719
720 ✗ nr_of_elements = base_array_nr_of_elements(*dest);
721 ✗ for(i = 0; i < nr_of_elements; ++i)
722 {
723 ✗ integer_set(dest, i, -integer_get(a, i));
724 }
725 ✗ }
726
727 5 void add_integer_array(const integer_array * a, const integer_array * b, integer_array* dest)
728 {
729 size_t nr_of_elements;
730 size_t i;
731
732 5 nr_of_elements = base_array_nr_of_elements(*a);
733
734 /* Assert a and b are of the same size */
735
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 omc_assert_macro(base_array_nr_of_elements(*b) == nr_of_elements);
736 /* Assert that dest are of correct size */
737
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 omc_assert_macro(base_array_nr_of_elements(*dest) == nr_of_elements);
738
739
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 5 times.
17 for(i = 0; i < nr_of_elements; ++i) {
740 12 integer_set(dest, i, integer_get(*a, i)+integer_get(*b, i));
741 }
742 5 }
743
744 5 integer_array add_alloc_integer_array(const integer_array a, const integer_array b)
745 {
746 integer_array dest;
747 clone_integer_array_spec(&a,&dest);
748 5 alloc_integer_array_data(&dest);
749 5 add_integer_array(&a,&b,&dest);
750 5 return dest;
751 }
752
753 ✗ void sub_integer_array(const integer_array * a, const integer_array * b, integer_array* dest)
754 {
755 size_t nr_of_elements;
756 size_t i;
757
758 ✗ nr_of_elements = base_array_nr_of_elements(*a);
759
760 /* Assert a and b are of the same size */
761 ✗ omc_assert_macro(base_array_nr_of_elements(*b) == nr_of_elements);
762 /* Assert that dest are of correct size */
763 ✗ omc_assert_macro(base_array_nr_of_elements(*dest) == nr_of_elements);
764
765 ✗ for(i = 0; i < nr_of_elements; ++i) {
766 ✗ integer_set(dest, i, integer_get(*a, i)-integer_get(*b, i));
767 }
768 ✗ }
769
770 ✗ void sub_integer_array_data_mem(const integer_array * a, const integer_array * b,
771 modelica_integer* dest)
772 {
773 size_t nr_of_elements;
774 size_t i;
775
776 ✗ nr_of_elements = base_array_nr_of_elements(*a);
777
778 /* Assert a and b are of the same size */
779 ✗ omc_assert_macro(base_array_nr_of_elements(*b) == nr_of_elements);
780 /* Assert that dest are of correct size */
781
782 ✗ for(i = 0; i < nr_of_elements; ++i) {
783 ✗ dest[i] = integer_get(*a, i) - integer_get(*b, i);
784 }
785 ✗ }
786
787 ✗ integer_array sub_alloc_integer_array(const integer_array a, const integer_array b)
788 {
789 integer_array dest;
790 clone_integer_array_spec(&a, &dest);
791 ✗ alloc_integer_array_data(&dest);
792 ✗ sub_integer_array(&a, &b, &dest);
793 ✗ return dest;
794 }
795
796 ✗ void mul_scalar_integer_array(modelica_integer a,const integer_array * b,integer_array* dest)
797 {
798 size_t nr_of_elements;
799 size_t i;
800
801 ✗ nr_of_elements = base_array_nr_of_elements(*b);
802
803 /* Assert that dest has correct size*/
804 ✗ omc_assert_macro(base_array_nr_of_elements(*dest) == nr_of_elements);
805
806 ✗ for(i=0; i < nr_of_elements; ++i) {
807 ✗ integer_set(dest, i, a * integer_get(*b, i));
808 }
809 ✗ }
810
811 ✗ integer_array mul_alloc_scalar_integer_array(modelica_integer a, const integer_array b)
812 {
813 integer_array dest;
814 clone_integer_array_spec(&b,&dest);
815 ✗ alloc_integer_array_data(&dest);
816 ✗ mul_scalar_integer_array(a,&b,&dest);
817 ✗ return dest;
818 }
819
820 ✗ void mul_integer_array_scalar(const integer_array * a,modelica_integer b,integer_array* dest)
821 {
822 size_t nr_of_elements;
823 size_t i;
824
825 ✗ nr_of_elements = base_array_nr_of_elements(*a);
826
827 /* Assert that dest has correct size*/
828 ✗ omc_assert_macro(base_array_nr_of_elements(*dest) == nr_of_elements);
829
830 ✗ for(i=0; i < nr_of_elements; ++i) {
831 ✗ integer_set(dest, i, integer_get(*a, i) * b);
832 }
833 ✗ }
834
835 ✗ integer_array mul_alloc_integer_array(const integer_array a, integer_array b)
836 {
837 integer_array dest;
838 clone_integer_array_spec(&a,&dest);
839 ✗ alloc_integer_array_data(&dest);
840 ✗ mul_integer_array(&a,&b,&dest);
841 ✗ return dest;
842 }
843
844 ✗ void mul_integer_array(const integer_array *a,const integer_array *b,integer_array* dest)
845 {
846 size_t nr_of_elements;
847 size_t i;
848 /* Assert that a,b have same sizes? */
849 ✗ nr_of_elements = base_array_nr_of_elements(*a);
850 ✗ for(i=0; i < nr_of_elements; ++i) {
851 ✗ integer_set(dest, i, integer_get(*a, i) * integer_get(*b, i));
852 }
853 ✗ }
854
855
856 ✗ integer_array mul_alloc_integer_array_scalar(const integer_array a, modelica_integer b)
857 {
858 integer_array dest;
859 clone_integer_array_spec(&a,&dest);
860 ✗ alloc_integer_array_data(&dest);
861 ✗ mul_integer_array_scalar(&a,b,&dest);
862 ✗ return dest;
863 }
864
865
866 ✗ modelica_integer mul_integer_scalar_product(const integer_array a, const integer_array b)
867 {
868 size_t nr_of_elements;
869 size_t i;
870 modelica_integer res;
871
872 /* Assert that a and b are vectors */
873 ✗ omc_assert_macro(a.ndims == 1);
874 ✗ omc_assert_macro(b.ndims == 1);
875 /* Assert that vectors are of matching size */
876 ✗ omc_assert_macro(a.dim_size[0] == b.dim_size[0]);
877
878 ✗ nr_of_elements = base_array_nr_of_elements(a);
879 res = 0;
880 ✗ for(i = 0; i < nr_of_elements; ++i) {
881 ✗ res += integer_get(a, i)*integer_get(b, i);
882 }
883 ✗ return res;
884 }
885
886 ✗ void mul_integer_matrix_product(const integer_array * a,const integer_array * b,integer_array* dest)
887 {
888 modelica_integer tmp;
889 size_t i_size;
890 size_t j_size;
891 size_t k_size;
892 size_t i;
893 size_t j;
894 size_t k;
895
896 /* Assert that dest har correct size */
897 ✗ i_size = dest->dim_size[0];
898 ✗ j_size = dest->dim_size[1];
899 ✗ k_size = a->dim_size[1];
900
901 ✗ for(i = 0; i < i_size; ++i) {
902 ✗ for(j = 0; j < j_size; ++j) {
903 tmp = 0;
904 ✗ for(k = 0; k < k_size; ++k) {
905 ✗ tmp += integer_get(*a, (i * k_size) + k)*integer_get(*b, (k * j_size) + j);
906 }
907 ✗ integer_set(dest, (i * j_size) + j, tmp);
908 }
909 }
910 ✗ }
911
912 ✗ void mul_integer_matrix_vector(const integer_array * a, const integer_array * b,integer_array* dest)
913 {
914 size_t i;
915 size_t j;
916 size_t i_size;
917 size_t j_size;
918 modelica_integer tmp;
919
920 /* Assert a matrix */
921 ✗ omc_assert_macro(a->ndims == 2);
922 /* Assert b vector */
923 ✗ omc_assert_macro(b->ndims == 1);
924 /* Assert dest correct size (a vector)*/
925 ✗ omc_assert_macro(dest->ndims == 1);
926
927 ✗ i_size = a->dim_size[0];
928 ✗ j_size = a->dim_size[1];
929
930 ✗ for(i = 0; i < i_size; ++i) {
931 tmp = 0;
932 ✗ for(j = 0; j < j_size; ++j) {
933 ✗ tmp += integer_get(*a, (i * j_size) + j)*integer_get(*b, j);
934 }
935 integer_set(dest, i, tmp);
936 }
937 ✗ }
938
939
940 ✗ void mul_integer_vector_matrix(const integer_array * a, const integer_array * b,integer_array* dest)
941 {
942 size_t i;
943 size_t j;
944 size_t i_size;
945 size_t j_size;
946 modelica_integer tmp;
947
948 /* Assert a vector */
949 ✗ omc_assert_macro(a->ndims == 1);
950 /* Assert b matrix */
951 ✗ omc_assert_macro(b->ndims == 2);
952 /* Assert dest vector of correct size */
953
954 ✗ i_size = b->dim_size[1];
955 ✗ j_size = b->dim_size[0];
956
957 ✗ for(i = 0; i < i_size; ++i) {
958 tmp = 0;
959 ✗ for(j = 0; j < j_size; ++j) {
960 ✗ tmp += integer_get(*a, j) * integer_get(*b, (j * i_size) + i);
961 }
962 integer_set(dest, i, tmp);
963 }
964 ✗ }
965
966 ✗ integer_array mul_alloc_integer_matrix_product_smart(const integer_array a, const integer_array b)
967 {
968 integer_array dest;
969 ✗ if((a.ndims == 1) && (b.ndims == 2)) {
970 ✗ simple_alloc_1d_integer_array(&dest,b.dim_size[1]);
971 ✗ mul_integer_vector_matrix(&a,&b,&dest);
972 ✗ } else if((a.ndims == 2) && (b.ndims == 1)) {
973 ✗ simple_alloc_1d_integer_array(&dest,a.dim_size[0]);
974 ✗ mul_integer_matrix_vector(&a,&b,&dest);
975 ✗ } else if((a.ndims == 2) && (b.ndims == 2)) {
976 ✗ simple_alloc_2d_integer_array(&dest,a.dim_size[0],b.dim_size[1]);
977 ✗ mul_integer_matrix_product(&a,&b,&dest);
978 } else {
979 ✗ omc_assert_macro(0 == "Invalid size of matrix");
980 }
981 ✗ return dest;
982 }
983
984 ✗ void div_integer_array_scalar(const integer_array * a,modelica_integer b,integer_array* dest)
985 {
986 size_t nr_of_elements;
987 size_t i;
988
989 /* Do we need to check for b=0? */
990 ✗ nr_of_elements = base_array_nr_of_elements(*a);
991
992 /* Assert that dest has correct size*/
993 ✗ omc_assert_macro(nr_of_elements == base_array_nr_of_elements(*dest));
994
995 ✗ for(i=0; i < nr_of_elements; ++i) {
996 ✗ integer_set(dest, i, integer_get(*a, i)/b);
997 }
998 ✗ }
999
1000 ✗ integer_array div_alloc_integer_array_scalar(const integer_array a,modelica_integer b)
1001 {
1002 integer_array dest;
1003 clone_integer_array_spec(&a,&dest);
1004 ✗ alloc_integer_array_data(&dest);
1005 ✗ div_integer_array_scalar(&a,b,&dest);
1006 ✗ return dest;
1007 }
1008
1009 ✗ void division_integer_array_scalar(threadData_t *threadData, const integer_array * a,modelica_integer b,integer_array* dest, const char* division_str)
1010 {
1011 size_t nr_of_elements;
1012 size_t i;
1013
1014 ✗ nr_of_elements = base_array_nr_of_elements(*a);
1015
1016 /* Assert that dest has correct size*/
1017 ✗ omc_assert_macro(nr_of_elements == base_array_nr_of_elements(*dest));
1018
1019 ✗ for(i=0; i < nr_of_elements; ++i) {
1020 ✗ integer_set(dest, i, (modelica_integer)DIVISIONNOTIME(integer_get(*a, i),b,division_str));
1021 }
1022 ✗ }
1023
1024 ✗ integer_array division_alloc_integer_array_scalar(threadData_t *threadData,const integer_array a,modelica_integer b, const char* division_str)
1025 {
1026 integer_array dest;
1027 clone_integer_array_spec(&a,&dest);
1028 ✗ alloc_integer_array_data(&dest);
1029 ✗ division_integer_array_scalar(threadData,&a,b,&dest,division_str);
1030 ✗ return dest;
1031 }
1032
1033 ✗ void div_scalar_integer_array(modelica_integer a, const integer_array* b, integer_array* dest)
1034 {
1035 size_t nr_of_elements;
1036 size_t i;
1037 /* Assert that dest has correct size*/
1038 /* Do we need to check for b=0? */
1039 ✗ nr_of_elements = base_array_nr_of_elements(*b);
1040 ✗ for(i=0; i < nr_of_elements; ++i) {
1041 ✗ integer_set(dest, i, a / integer_get(*b, i));
1042 }
1043 ✗ }
1044
1045 ✗ integer_array div_alloc_scalar_integer_array(modelica_integer a, const integer_array b)
1046 {
1047 integer_array dest;
1048 clone_integer_array_spec(&b,&dest);
1049 ✗ alloc_integer_array_data(&dest);
1050 ✗ div_scalar_integer_array(a,&b,&dest);
1051 ✗ return dest;
1052 }
1053
1054 ✗ void pow_integer_array_scalar(const integer_array *a, modelica_integer b, integer_array* dest)
1055 {
1056 ✗ size_t nr_of_elements = base_array_nr_of_elements(*a);
1057 size_t i;
1058
1059 ✗ omc_assert_macro(nr_of_elements == base_array_nr_of_elements(*dest));
1060
1061 ✗ for(i = 0; i < nr_of_elements; ++i) {
1062 ✗ integer_set(dest, i, (modelica_integer)pow(integer_get(*a, i), b));
1063 }
1064 ✗ }
1065
1066 ✗ integer_array pow_alloc_integer_array_scalar(const integer_array a, modelica_integer b)
1067 {
1068 integer_array dest;
1069 clone_integer_array_spec(&a, &dest);
1070 ✗ alloc_integer_array_data(&dest);
1071 ✗ pow_integer_array_scalar(&a, b, &dest);
1072 ✗ return dest;
1073 }
1074
1075 ✗ void exp_integer_array(const integer_array * a, modelica_integer n, integer_array* dest)
1076 {
1077 /* Assert n>=0 */
1078 ✗ omc_assert_macro(n >= 0);
1079 /* Assert that a is a two dimensional square array */
1080 ✗ omc_assert_macro((a->ndims == 2) && (a->dim_size[0] == a->dim_size[1]));
1081 /* Assert that dest is a two dimensional square array with the same size as a */
1082 ✗ omc_assert_macro((dest->ndims == 2) && (dest->dim_size[0] == dest->dim_size[1]) && (a->dim_size[0] == dest->dim_size[0]));
1083
1084 ✗ if(n==0) {
1085 ✗ identity_integer_array(a->dim_size[0],dest);
1086 } else {
1087 ✗ if(n==1) {
1088 clone_integer_array_spec(a,dest);
1089 ✗ integer_array_copy_data(*a, *dest);
1090 ✗ } else if (n==2) {
1091 clone_integer_array_spec(a,dest);
1092 ✗ mul_integer_matrix_product(a,a,dest);
1093 } else {
1094 modelica_integer i;
1095
1096 integer_array tmp;
1097 integer_array * b;
1098 integer_array * c;
1099
1100 /* prepare temporary array */
1101 clone_integer_array_spec(a,&tmp);
1102 clone_integer_array_spec(a,dest);
1103
1104 ✗ if ((n&1) != 0) {
1105 b = &tmp;
1106 c = dest;
1107 } else {
1108 b = dest;
1109 c = &tmp;
1110 }
1111 ✗ mul_integer_matrix_product(a,a,b);
1112 ✗ for( i = 2; i < n; ++i) {
1113 integer_array * x;
1114
1115 ✗ mul_integer_matrix_product(a,b,c);
1116
1117 /* exchange b and c */
1118 x = b;
1119 b = c;
1120 c = x;
1121 }
1122 /* result is already in dest */
1123 }
1124 }
1125 ✗ }
1126
1127 ✗ integer_array exp_alloc_integer_array(const integer_array a,modelica_integer b)
1128 {
1129 integer_array dest;
1130 clone_integer_array_spec(&a,&dest);
1131 ✗ alloc_integer_array_data(&dest);
1132 ✗ exp_integer_array(&a,b,&dest);
1133 ✗ return dest;
1134 }
1135
1136 /* function: promote_alloc_integer_array
1137 *
1138 * Implementation of promote(A,n) same as promote_integer_array except
1139 * that the destination array is allocated.
1140 */
1141 503 void promote_alloc_integer_array(const integer_array * a, int n, integer_array* dest)
1142 {
1143 503 dest->flexible = a->flexible;
1144 503 promote_integer_array(a, n, dest);
1145 503 }
1146
1147 /* function: promote_integer_array.
1148 *
1149 * Implementation of promote(a,n)
1150 * Adds n onesized array dimensions to the array a to "the right of array dimensions".
1151 * For instance
1152 * promote_exp( {1,2},1) => {{1},{2}}
1153 * promote_exp( {1,2},2) => { {{1}},{{2}} }
1154 */
1155 503 void promote_integer_array(const integer_array * a, int n,integer_array* dest)
1156 {
1157 int i;
1158
1159 503 dest->dim_size = size_alloc(n+a->ndims);
1160 503 dest->data = a->data;
1161 503 dest->owns_data = a->owns_data;
1162
1/2
✓ Branch 0 taken 503 times.
✗ Branch 1 not taken.
503 if (dest->owns_data) {
1163 omc_rc_retain_inline(dest->data);
1164 }
1165 /* Assert a->ndims>=n */
1166
2/2
✓ Branch 0 taken 503 times.
✓ Branch 1 taken 503 times.
1006 for(i = 0; i < a->ndims; ++i) {
1167 503 dest->dim_size[i] = a->dim_size[i];
1168 }
1169
2/2
✓ Branch 0 taken 503 times.
✓ Branch 1 taken 503 times.
1006 for(i = a->ndims; i < (n + a->ndims); ++i) {
1170 503 dest->dim_size[i] = 1;
1171 }
1172 503 dest->ndims=n+a->ndims;
1173 503 }
1174
1175 /* function: promote_scalar_integer_array
1176 *
1177 * promotes a scalar value to an n dimensional array.
1178 */
1179 ✗ void promote_scalar_integer_array(modelica_integer s,int n,integer_array* dest)
1180 {
1181 int i;
1182
1183 /* Assert that dest is of correct dimension */
1184
1185 /* Alloc size */
1186 ✗ dest->dim_size = size_alloc(n);
1187 ✗ dest->owns_data = 1;
1188
1189 /* Alloc data */
1190 ✗ dest->data = integer_alloc(1);
1191
1192 ✗ dest->ndims = n;
1193 integer_set(dest, 0, s);
1194
1195 ✗ for(i = 0; i < n; ++i) {
1196 ✗ dest->dim_size[i] = 1;
1197 }
1198 ✗ }
1199
1200 /* return a vector of length ndims(a) containing the dimension sizes of a */
1201 ✗ void size_integer_array(const integer_array * a, integer_array* dest)
1202 {
1203 int i;
1204
1205 ✗ omc_assert_macro(dest->ndims == 1);
1206 ✗ omc_assert_macro(dest->dim_size[0] == a->ndims);
1207
1208 ✗ for(i = 0 ; i < a->ndims ; i++) {
1209 ✗ integer_set(dest, i, a->dim_size[i]);
1210 }
1211 ✗ }
1212
1213 ✗ modelica_integer scalar_integer_array(const integer_array * a)
1214 {
1215 ✗ omc_assert_macro(base_array_ok(a));
1216 ✗ omc_assert_macro(base_array_one_element_ok(a));
1217
1218 ✗ return integer_get(*a, 0);
1219 }
1220
1221 ✗ void vector_integer_array(const integer_array * a, integer_array* dest)
1222 {
1223 size_t i, nr_of_elements;
1224
1225 /* Assert that a has at most one dimension with dim_size>1*/
1226
1227 ✗ nr_of_elements = base_array_nr_of_elements(*a);
1228 ✗ for(i = 0; i < nr_of_elements; ++i) {
1229 ✗ integer_set(dest, i, integer_get(*a, i));
1230 }
1231 ✗ }
1232
1233 ✗ void vector_integer_scalar(modelica_integer a,integer_array* dest)
1234 {
1235 /* Assert that dest is a 1-vector */
1236 integer_set(dest, 0, a);
1237 ✗ }
1238
1239 ✗ void matrix_integer_array(const integer_array * a, integer_array* dest)
1240 {
1241 size_t i, cnt;
1242 /* Assert that size(A,i)=1 for 2 <i<=ndims(A)*/
1243 ✗ dest->dim_size[0] = a->dim_size[0];
1244 ✗ dest->dim_size[1] = (a->ndims < 2)? 1 : a->dim_size[1];
1245
1246 ✗ cnt = dest->dim_size[0] * dest->dim_size[1];
1247
1248 ✗ for(i = 0; i < cnt; ++i) {
1249 ✗ integer_set(dest, i, integer_get(*a, i));
1250 }
1251 ✗ }
1252
1253 ✗ void matrix_integer_scalar(modelica_integer a,integer_array* dest)
1254 {
1255 ✗ dest->ndims = 2;
1256 ✗ dest->dim_size[0] = 1;
1257 ✗ dest->dim_size[1] = 1;
1258 integer_set(dest, 0, a);
1259 ✗ }
1260
1261 /* function: transpose_alloc_integer_array
1262 *
1263 * Implementation of transpose(A) for matrix A. Same as transpose_integer_array
1264 * except that destionation array is allocated.
1265 */
1266
1267 ✗ void transpose_alloc_integer_array(const integer_array * a, integer_array* dest)
1268 {
1269 clone_integer_array_spec(a,dest); /* allocation*/
1270
1271 /* transpose only valid for matrices.*/
1272
1273 ✗ omc_assert_macro(a->ndims == 2);
1274 ✗ dest->dim_size[0]=a->dim_size[1];
1275 ✗ dest->dim_size[1]=a->dim_size[0];
1276 ✗ dest->ndims = 2;
1277
1278 ✗ alloc_integer_array_data(dest);
1279 ✗ transpose_integer_array(a,dest);
1280 ✗ }
1281
1282 /* function: transpose_integer_array
1283 *
1284 * Implementation of transpose(A) for matrix A.
1285 */
1286 78693 void transpose_integer_array(const integer_array * a, integer_array* dest)
1287 {
1288 size_t i;
1289 size_t j;
1290 /* size_t k;*/
1291 size_t n,m;
1292
1293
1/2
✓ Branch 0 taken 78693 times.
✗ Branch 1 not taken.
78693 if(a->ndims == 1) {
1294 78693 integer_array_copy_data(*a, *dest);
1295 78693 return;
1296 }
1297
1298 ✗ omc_assert_macro(a->ndims==2 && dest->ndims==2);
1299
1300 ✗ n = a->dim_size[0];
1301 ✗ m = a->dim_size[1];
1302
1303 ✗ omc_assert_macro(dest->dim_size[0] == m && dest->dim_size[1] == n);
1304
1305 ✗ for(i = 0; i < n; ++i) {
1306 ✗ for(j = 0; j < m; ++j) {
1307 ✗ integer_set(dest, (j * n) + i, integer_get(*a, (i * m) + j));
1308 }
1309 }
1310 }
1311
1312 ✗ void outer_product_integer_array(const integer_array * v1,const integer_array * v2, integer_array* dest)
1313 {
1314 size_t i;
1315 size_t j;
1316 size_t number_of_elements_a;
1317 size_t number_of_elements_b;
1318
1319 ✗ number_of_elements_a = base_array_nr_of_elements(*v1);
1320 ✗ number_of_elements_b = base_array_nr_of_elements(*v2);
1321
1322 /* Assert a is a vector */
1323 /* Assert b is a vector */
1324
1325 ✗ for(i = 0; i < number_of_elements_a; ++i) {
1326 ✗ for(j = 0; j < number_of_elements_b; ++j) {
1327 ✗ integer_set(dest, (i * number_of_elements_b) + j, integer_get(*v1, i)*integer_get(*v2, j));
1328 }
1329 }
1330 ✗ }
1331
1332 ✗ void outer_product_alloc_integer_array(const integer_array* v1, const integer_array* v2, integer_array* dest)
1333 {
1334 size_t dim1,dim2;
1335 ✗ omc_assert_macro(base_array_ok(v1));
1336 ✗ dim1 = base_array_nr_of_elements(*v1);
1337 ✗ dim2 = base_array_nr_of_elements(*v2);
1338 ✗ alloc_integer_array(dest,dim1,dim2);
1339 ✗ outer_product_integer_array(v1,v2,dest);
1340 ✗ }
1341
1342 /* Fills an array with a value. */
1343 505 void fill_alloc_integer_array(integer_array* dest, modelica_integer value, int ndims, ...)
1344 {
1345 size_t i;
1346 size_t elements = 0;
1347 va_list ap;
1348 505 va_start(ap, ndims);
1349 505 elements = alloc_base_array(dest, ndims, ap);
1350 505 va_end(ap);
1351 505 dest->data = integer_alloc(elements);
1352
1353
2/2
✓ Branch 0 taken 1515 times.
✓ Branch 1 taken 505 times.
2020 for(i = 0; i < elements; ++i) {
1354 integer_set(dest, i, value);
1355 }
1356 505 }
1357
1358 511 void identity_integer_array(int n, integer_array* dest)
1359 {
1360 int i;
1361 int j;
1362
1363
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 511 times.
511 omc_assert_macro(base_array_ok(dest));
1364
1365 /* Check that dest size is ok */
1366
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 511 times.
511 omc_assert_macro(dest->ndims==2);
1367
2/4
✓ Branch 0 taken 511 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 511 times.
✗ Branch 3 not taken.
511 omc_assert_macro((dest->dim_size[0]==n) && (dest->dim_size[1]==n));
1368
1369
2/2
✓ Branch 0 taken 4599 times.
✓ Branch 1 taken 511 times.
5110 for(i = 0; i < (n * n); ++i) {
1370 4599 integer_set(dest, i, 0);
1371 }
1372 j = 0;
1373
2/2
✓ Branch 0 taken 1533 times.
✓ Branch 1 taken 511 times.
2044 for(i = 0; i < n; ++i) {
1374 1533 integer_set(dest, j, 1);
1375 1533 j += n+1;
1376 }
1377 511 }
1378
1379 511 void identity_alloc_integer_array(int n,integer_array* dest)
1380 {
1381 511 alloc_integer_array(dest,2,n,n);
1382 511 identity_integer_array(n,dest);
1383 511 }
1384
1385 ✗ static void diagonal_integer_array_impl(const integer_array *v, integer_array* dest)
1386 {
1387 size_t i;
1388 size_t j;
1389 size_t n;
1390
1391 ✗ n = v->dim_size[0];
1392
1393 ✗ for(i = 0; i < (n * n); ++i) {
1394 integer_set(dest, i, 0);
1395 }
1396 j = 0;
1397 ✗ for(i = 0; i < n; ++i) {
1398 ✗ integer_set(dest, j, integer_get(*v, i));
1399 ✗ j += n + 1;
1400 }
1401 ✗ }
1402
1403 ✗ void diagonal_integer_array(const integer_array * v,integer_array* dest)
1404 {
1405 size_t n;
1406
1407 /* Assert that v is a vector */
1408 ✗ omc_assert_macro(v->ndims == 1);
1409
1410 /* Assert that dest is a nxn matrix */
1411 ✗ n = v->dim_size[0];
1412 ✗ omc_assert_macro(dest->ndims == 2);
1413 ✗ omc_assert_macro((dest->dim_size[0] == n) && (dest->dim_size[1] == n));
1414
1415 ✗ diagonal_integer_array_impl(v, dest);
1416 ✗ }
1417
1418 ✗ void diagonal_alloc_integer_array(const integer_array* v, integer_array* dest)
1419 {
1420 size_t n;
1421
1422 /* Assert that v is a vector */
1423 ✗ omc_assert_macro(v->ndims == 1);
1424
1425 /* Allocate a n*n matrix and fill it. */
1426 ✗ n = v->dim_size[0];
1427 ✗ alloc_integer_array(dest, 2, n, n);
1428 ✗ diagonal_integer_array_impl(v, dest);
1429 ✗ }
1430
1431 ✗ void fill_integer_array(integer_array* dest,modelica_integer s)
1432 {
1433 size_t nr_of_elements;
1434 size_t i;
1435
1436 ✗ nr_of_elements = base_array_nr_of_elements(*dest);
1437 ✗ for(i = 0; i < nr_of_elements; ++i) {
1438 integer_set(dest, i, s);
1439 }
1440 ✗ }
1441
1442 ✗ void linspace_integer_array(modelica_integer x1, modelica_integer x2, int n,
1443 integer_array* dest)
1444 {
1445 int i;
1446
1447 /* Assert n>=2 */
1448
1449 ✗ for(i = 0; i < (n - 1); ++i) {
1450 ✗ integer_set(dest, i, x1 + (((x2-x1)*(i-1))/(n-1)));
1451 }
1452 ✗ }
1453
1454 35 modelica_integer max_integer_array(const integer_array a)
1455 {
1456 size_t nr_of_elements;
1457 modelica_integer max_element = LONG_MIN;
1458
1459
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
35 omc_assert_macro(base_array_ok(&a));
1460
1461 35 nr_of_elements = base_array_nr_of_elements(a);
1462
1463
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 if(nr_of_elements > 0) {
1464 size_t i;
1465 35 max_element = integer_get(a, 0);
1466
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 35 times.
140 for(i = 1; i < nr_of_elements; ++i) {
1467
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 99 times.
105 if(max_element < integer_get(a, i)) {
1468 6 max_element = integer_get(a, i);
1469 }
1470 }
1471 }
1472
1473 35 return max_element;
1474 }
1475
1476 10 modelica_integer min_integer_array(const integer_array a)
1477 {
1478 size_t nr_of_elements;
1479 modelica_integer min_element = LONG_MAX;
1480
1481
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 omc_assert_macro(base_array_ok(&a));
1482
1483 10 nr_of_elements = base_array_nr_of_elements(a);
1484
1485
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(nr_of_elements > 0) {
1486 size_t i;
1487 10 min_element = integer_get(a, 0);
1488
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
20 for(i = 1; i < nr_of_elements; ++i) {
1489
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if(min_element > integer_get(a, i)) {
1490 ✗ min_element = integer_get(a, i);
1491 }
1492 }
1493 }
1494 10 return min_element;
1495 }
1496
1497 ✗ modelica_integer sum_integer_array(const integer_array a)
1498 {
1499 size_t i;
1500 size_t nr_of_elements;
1501 modelica_integer sum = 0;
1502
1503 ✗ omc_assert_macro(base_array_ok(&a));
1504
1505 ✗ nr_of_elements = base_array_nr_of_elements(a);
1506
1507 ✗ for(i = 0;i < nr_of_elements; ++i) {
1508 ✗ sum += integer_get(a, i);
1509 }
1510
1511 ✗ return sum;
1512 }
1513
1514 ✗ modelica_integer product_integer_array(const integer_array a)
1515 {
1516 size_t i;
1517 size_t nr_of_elements;
1518 modelica_integer product = 1;
1519
1520 ✗ omc_assert_macro(base_array_ok(&a));
1521
1522 ✗ nr_of_elements = base_array_nr_of_elements(a);
1523
1524 ✗ for(i = 0;i < nr_of_elements; ++i) {
1525 ✗ product *= integer_get(a, i);
1526 }
1527
1528 ✗ return product;
1529 }
1530
1531 ✗ void symmetric_integer_array(const integer_array * a,integer_array* dest)
1532 {
1533 size_t i;
1534 size_t j;
1535 size_t nr_of_elements;
1536
1537 ✗ nr_of_elements = base_array_nr_of_elements(*a);
1538
1539 /* Assert that a is a two dimensional square array */
1540 ✗ omc_assert_macro((a->ndims == 2) && (a->dim_size[0] == a->dim_size[1]));
1541 /* Assert that dest is a two dimensional square array with the same size as a */
1542 ✗ omc_assert_macro((dest->ndims == 2) && (dest->dim_size[0] == dest->dim_size[1]) && (a->dim_size[0] == dest->dim_size[0]));
1543
1544 ✗ for(i = 0; i < nr_of_elements; ++i) {
1545 ✗ for(j = 0; j < i; ++j) {
1546 ✗ integer_set(dest, (i * nr_of_elements) + j,
1547 ✗ integer_get(*a, (j * nr_of_elements) + i));
1548 }
1549 ✗ for( ; j < nr_of_elements; ++j) {
1550 ✗ integer_set(dest, (i * nr_of_elements) + j,
1551 ✗ integer_get(*a, (i * nr_of_elements) + j));
1552 }
1553 }
1554 ✗ }
1555
1556 /* integer_array_make_index_array
1557 *
1558 * Creates an integer array of indices to be used by e.g.
1559 ** create_index_spec defined in index_spec.c
1560 */
1561
1562 75178 _index_t* integer_array_make_index_array(const integer_array arr)
1563 {
1564 75178 return arr.data;
1565 }
1566
1567 /* Converts the elements of an integer_array to int and packs them. I.e. if the
1568 * array element type is 64 bits and int is 32 bits then the data will be packed
1569 * in the first half of the array. */
1570 78689 void pack_integer_array(integer_array *a)
1571 {
1572 if(sizeof(int) != sizeof(modelica_integer)) {
1573 long i;
1574 78689 int * int_data = (int*)a->data;
1575 78689 size_t n = base_array_nr_of_elements(*a);
1576
1577
2/2
✓ Branch 0 taken 236067 times.
✓ Branch 1 taken 78689 times.
314756 for(i = 0; i < n; ++i) {
1578 236067 int_data[i] = (int)integer_get(*a, i);
1579 }
1580 }
1581 78689 }
1582
1583 /* Unpacks an integer_array that was packed with pack_integer_array */
1584 6666 void unpack_integer_array(integer_array *a)
1585 {
1586 if(sizeof(int) != sizeof(modelica_integer)) {
1587 long i;
1588 6666 int * int_data = (int*)a->data;
1589 6666 long n = (long)base_array_nr_of_elements(*a);
1590
1591
2/2
✓ Branch 0 taken 26562 times.
✓ Branch 1 taken 6666 times.
33228 for(i = n - 1; i >= 0; --i) {
1592 26562 integer_set(a, i, int_data[i]);
1593 }
1594 }
1595 6666 }
1596
1597 /* Returns a modelica_integer array that can be treated as an int array. If the
1598 * size of int and modelica_integer is the same this means simply returning the
1599 * given array, but if int is smaller than modelica_integer a new array is
1600 * allocated and filled with the data from given array as if it was an int array.
1601 *
1602 * I.e. if int is 32 bit and modelica_integer is 64 bit then the data will be
1603 * packed into the first half of the new array.
1604 *
1605 * The case where int is larger than modelica_integer is not implemented. */
1606 50 void pack_alloc_integer_array(integer_array *a, integer_array *dest)
1607 {
1608 if (sizeof(int) == sizeof(modelica_integer)) {
1609 *dest = *a;
1610 } else {
1611 /* We only handle the case where int is smaller than modelica_integer. */
1612 omc_assert_macro(sizeof(int) < sizeof(modelica_integer));
1613
1614 /* Allocate a new array. */
1615 clone_integer_array_spec(a, dest);
1616 50 alloc_integer_array_data(dest);
1617
1618 /* Pretend that the new array is an int array and fill it with the values
1619 * from the given array. */
1620 50 int *int_data = (int*)dest->data;
1621 long i;
1622 50 size_t n = base_array_nr_of_elements(*a);
1623
1624
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 50 times.
167 for (i = 0; i < n; ++i) {
1625 117 int_data[i] = (int)integer_get(*a, i);
1626 }
1627 }
1628 50 }
1629
1630 /* Unpacks an integer_array that was packed with pack_integer_array into the
1631 * destination array. If packing hasn't been done, i.e. if the size of int and
1632 * modelica_integer is the same, then the function does nothing since both the
1633 * source and destination is assumed to be the same array. */
1634 ✗ void unpack_copy_integer_array(const integer_array *a, integer_array *dest)
1635 {
1636 if(sizeof(int) != sizeof(modelica_integer)) {
1637 long i;
1638 ✗ const int * int_data = (const int*)a->data;
1639 ✗ long n = (long)base_array_nr_of_elements(*a);
1640
1641 ✗ for(i = n - 1; i >= 0; --i) {
1642 ✗ integer_set(dest, i, int_data[i]);
1643 }
1644 }
1645 ✗ }
1646
1647 78689 void convert_alloc_integer_array_to_f77(const integer_array * a,
1648 integer_array* dest)
1649 {
1650 int i;
1651 clone_reverse_integer_array_spec(a,dest);
1652 78689 alloc_integer_array_data(dest);
1653 78689 transpose_integer_array (a,dest);
1654
1655 /* Assume that external fortran functions use int, and pack the array if
1656 * needed. */
1657 78689 pack_integer_array(dest);
1658
1659
2/2
✓ Branch 0 taken 78689 times.
✓ Branch 1 taken 78689 times.
157378 for(i = 0; i < dest->ndims; ++i) {
1660 78689 dest->dim_size[i] = a->dim_size[i];
1661 }
1662 78689 }
1663
1664 4 void convert_alloc_integer_array_from_f77(const integer_array * a,
1665 integer_array* dest)
1666 {
1667 int i;
1668 clone_reverse_integer_array_spec(a,dest);
1669 4 alloc_integer_array_data(dest);
1670
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for(i = 0; i < dest->ndims; ++i) {
1671 4 int tmp = dest->dim_size[i];
1672 4 dest->dim_size[i] = a->dim_size[i];
1673 4 a->dim_size[i] = tmp;
1674 }
1675 4 transpose_integer_array (a,dest);
1676
1677 /* Unpack the array if needed */
1678 4 unpack_integer_array(dest);
1679 4 }
1680
1681 10 void sizes_of_dimensions_base_array(const base_array_t *a, integer_array *dest)
1682 {
1683 10 int i = ndims_base_array(a);
1684 10 simple_alloc_1d_integer_array(dest, i);
1685
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 while(i--) {
1686 20 integer_set(dest, i, a->dim_size[i]);
1687 }
1688 10 }
1689
1690 4 static int integer_element_to_string(char *buffer, size_t bufsize, const void *data, _index_t i)
1691 {
1692 4 return snprintf(buffer, bufsize, OMC_INT_FORMAT, ((const modelica_integer *)data)[i]);
1693 }
1694
1695 /**
1696 * @brief Write integer vector into null-terminated string.
1697 *
1698 * @param source Integer vector to write to `buffer`.
1699 * @param isScalar Treat vector as scalar.
1700 * @param buffer Buffer to write into.
1701 * @param bufsize Length of `buffer`.
1702 */
1703 2 void integer_vector_to_string(const integer_array *source, modelica_boolean isScalar, char *buffer, size_t bufsize)
1704 {
1705 2 base_vector_to_string(source, isScalar, integer_element_to_string, buffer, bufsize);
1706 2 }
1707
1708 /**
1709 * @brief Resize a start attribute array to n elements, repeating its values.
1710 *
1711 * The start attribute of an array variable can hold a single broadcast value
1712 * or the values of an inner dimension only. Writing the start values of the
1713 * whole array needs one element per array element. If the array has more than
1714 * n elements, the first n are kept. Nothing is reallocated if the array
1715 * already has n elements.
1716 */
1717 ✗ void integer_array_ensure_size(integer_array *a, int n)
1718 {
1719 ✗ int m = (int) base_array_nr_of_elements(*a);
1720 integer_array tmp;
1721 int i;
1722 ✗ if (m == n) {
1723 ✗ return;
1724 }
1725 ✗ simple_alloc_1d_integer_array(&tmp, n);
1726 ✗ for (i = 0; i < n; ++i) {
1727 ✗ ((modelica_integer*) tmp.data)[i] = m > 0 ? ((modelica_integer*) a->data)[i % m] : 0;
1728 }
1729 ✗ omc_array_release(a);
1730 ✗ *a = tmp;
1731 }
1732