1 /* Siconos is a program dedicated to modeling, simulation and control
2  * of non smooth dynamical systems.
3  *
4  * Copyright 2021 INRIA.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17 */
18 
19 #include "NumericsArrays.h"
20 #include <stdio.h>   // for size_t, printf
21 #include <stdlib.h>  // for rand
22 
NA_diffns(int * na,int * a,int * nb,int * b,int * nc,int * c)23 void NA_diffns(int *na, int *a, int *nb, int * b, int *nc, int *c)
24 {
25 
26   int pta, ptb, ptc;
27   int aa, i;
28 
29   pta = 0;
30   ptb = 0;
31   ptc = 0;
32 
33   if(*nb == 0)
34   {
35 
36     for(i = 0 ; i < *na ; i++)
37       c[i] = a[i];
38     *nc  = *na;
39 
40   }
41 
42   else
43   {
44 
45     for(i = 0 ; i < *na ; i++)
46       c[i] = -1;
47 
48     while((pta < *na) && (ptb < *nb))
49     {
50 
51       aa  = a[pta];
52 
53       if(b[ptb] > aa)
54       {
55 
56         c[ptc] = aa ;
57         ptc    = ptc + 1 ;
58         pta = pta + 1;
59       }
60       else if(b[ptb] == aa)
61       {
62 
63         pta = pta + 1;
64 
65       }
66       else
67       {
68 
69         while((b[ptb] < aa) && (ptb < *nb))
70         {
71 
72 
73           ptb = ptb + 1;
74 
75           if(ptb >= *nb)
76           {
77 
78             c[ptc] = aa;
79             ptc    = ptc + 1;
80 
81             break;
82 
83           }
84         }
85 
86       }
87 
88 
89 
90     }
91 
92 
93 
94     for(i = pta + 1; i < *na ; i++)
95     {
96 
97 
98       c[ptc] = a[i];
99       ptc = ptc + 1;
100     }
101 
102     *nc = ptc;
103 
104   }
105 
106 }
107 
108 
NA_rm_duplicate(size_t * arr,size_t len)109 size_t NA_rm_duplicate(size_t *arr, size_t len)
110 {
111   size_t prev = 0;
112   size_t curr = 1;
113   size_t last = len - 1;
114   while(curr <= last)
115   {
116     for(prev = 0; prev < curr && arr[curr] != arr[prev]; ++prev);
117     if(prev == curr)
118     {
119       ++curr;
120     }
121     else
122     {
123       arr[curr] = arr[last];
124       --last;
125     }
126   }
127   return curr;
128 }
129 
130 
131 // Merge arr1[0..n1-1] and arr2[0..n2-1] into
132 // arr3[0..n1+n2-1]
NA_merge_sorted_arrays(size_t * arr1,size_t * arr2,size_t n1,size_t n2,size_t * arr3)133 void NA_merge_sorted_arrays(size_t * arr1, size_t * arr2, size_t n1,
134                             size_t n2, size_t *arr3)
135 {
136   size_t i = 0, j = 0, k = 0;
137 
138   // Traverse both array
139   while(i<n1 && j <n2)
140   {
141     // Check if current element of first
142     // array is smaller than current element
143     // of second array. If yes, store first
144     // array element and increment first array
145     // index. Otherwise do same with second array
146     if(arr1[i] < arr2[j])
147       arr3[k++] = arr1[i++];
148     else
149       arr3[k++] = arr2[j++];
150   }
151 
152   // Store remaining elements of first array
153   while(i < n1)
154     arr3[k++] = arr1[i++];
155 
156   // Store remaining elements of second array
157   while(j < n2)
158     arr3[k++] = arr2[j++];
159 }
160 
NA_swap(size_t * xp,size_t * yp)161 static void NA_swap(size_t *xp, size_t *yp)
162 {
163   size_t temp = *xp;
164   *xp = *yp;
165   *yp = temp;
166 }
167 
NA_sort_bubble(size_t * arr,size_t len)168 void NA_sort_bubble(size_t *arr, size_t len)
169 {
170   size_t i, j;
171   for(i = 0; i < len-1; i++)
172     for(j = 0; j < len-i-1; j++)
173       if(arr[j] > arr[j+1])
174         NA_swap(&arr[j], &arr[j+1]);
175 }
176 
177 
NA_merge_and_sort_sorted_arrays(size_t * arr1,size_t * arr2,size_t n1,size_t n2,size_t * arr3)178 size_t  NA_merge_and_sort_sorted_arrays(size_t * arr1, size_t * arr2, size_t n1,
179                                         size_t n2, size_t *arr3)
180 {
181   NA_merge_sorted_arrays(arr1, arr2,  n1, n2, arr3);
182   size_t n3 = NA_rm_duplicate(arr3, n1+n2);
183   NA_sort_bubble(arr3, n3);
184 
185   return n3;
186 }
187 
NA_display(size_t * arr1,size_t n1)188 void NA_display(size_t * arr1,  size_t n1)
189 {
190   printf("Array display:\t[");
191   for(size_t j =0 ; j< n1 ; j++)
192     printf("%zu\t",arr1[j]);
193   printf("]\n");
194 }
195 
196 
197 /* swap two indices */
uint_swap(unsigned int * a,unsigned int * b)198 void uint_swap(unsigned int *a, unsigned int *b)
199 {
200   unsigned int temp = *a;
201   *a = *b;
202   *b = temp;
203 }
204 
205 /* shuffle an unsigned array */
uint_shuffle(unsigned int * a,unsigned int n)206 void uint_shuffle(unsigned int *a, unsigned int n)
207 {
208 
209   for(unsigned int i = 0; i < n - 1; i++)
210   {
211     uint_swap(&a[i], &a[i + (unsigned int)rand()%(n - i)]);
212   }
213 }
214 
215