Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
ArrayUtils.h
1/*
2 * Copyright 2020 IFPEN-CEA
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 */
18
19#pragma once
20
21#include <arccore/base/ArrayView.h>
22#include <arccore/collections/Array.h>
23
24#include <algorithm>
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Alien
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
36namespace ArrayScan
37{
40
43 template <typename T>
44 inline Integer exhaustiveScan(const T& x, ConstArrayView<T> v);
45
48
51 template <typename T>
52 inline Integer linearScan(const T& x, ConstArrayView<T> v);
55
61 template <typename T>
62 inline Integer dichotomicScan(const T& x, ConstArrayView<T> v);
63
66
69 template <typename T>
70 inline Integer linearPositionScan(const T& x, ConstArrayView<T> v);
73
79 template <typename T>
80 inline Integer dichotomicPositionScan(const T& x, ConstArrayView<T> v);
81
84
87 template <typename T>
88 inline Integer linearIntervalScan(const T& x, const Integer n, const T* vptr);
89
92
97 template <typename T>
98 inline Integer dichotomicIntervalScan(const T& x, const Integer n, const T* vptr);
99} // namespace ArrayScan
100
101/*---------------------------------------------------------------------------*/
102
103/*---------------------------------------------------------------------------*/
104
105namespace ArrayScan
106{
107
108 template <typename T>
109 Integer exhaustiveScan(const T& x, ConstArrayView<T> v)
110 {
111 const Integer n = v.size();
112 for (Integer i = 0; i < n; ++i)
113 if (v[i] == x)
114 return i;
115 return -1;
116 }
117
118 template <typename T>
119 Integer linearScan(const T& x, ConstArrayView<T> v)
120 {
121 const Integer n = v.size();
122 Integer index = 0;
123 while (index < n and v[index] < x) {
124 ++index;
125 }
126 if (index == n or v[index] != x)
127 return -1;
128 else
129 return index;
130 }
131
132 template <typename T>
133 inline Integer dichotomicScan(const T& x, ConstArrayView<T> v)
134 {
135 const Integer n = v.size();
136
137 Integer ileft = 0;
138 Integer iright = n; // d�finit un intervale ouvert � droite
139 static const Integer n_linear = 20; // threshold to switch from dichotomic to linear
140 // scan \todo mettre cache line size
141
142 // Start dichotomy
143 if (n > n_linear) {
144 if (x < v[0] or x > v[n - 1])
145 return -1;
146 do {
147 const Integer imid = (iright + ileft) / 2;
148 const T& vmid = v[imid];
149 if (x < vmid) {
150 iright = imid;
151 }
152 else if (x >= vmid) {
153 ileft = imid;
154 }
155 } while (iright - ileft > n_linear);
156 }
157
158 // Switch to linear search
159 // (exhaustiveScan en alternative; gain mitig�)
160 while (ileft < iright and v[ileft] < x) {
161 ++ileft;
162 }
163 if (ileft >= iright or v[ileft] != x)
164 return -1;
165 else
166 return ileft;
167 }
168
169 /*---------------------------------------------------------------------------*/
170
171 template <typename T>
172 Integer linearPositionScan(const T& x, ConstArrayView<T> v)
173 {
174 const Integer n = v.size();
175 Integer index = 0;
176 while (index < n and v[index] < x) {
177 ++index;
178 }
179 return index;
180 }
181
182 template <typename T>
183 inline Integer dichotomicPositionScan(const T& x, ConstArrayView<T> v)
184 {
185 const Integer n = v.size();
186
187 Integer ileft = 0;
188 Integer iright = n; // d�finit un intervale ouvert � droite
189 static const Integer n_linear = 20; // threshold to switch from dichotomic to linear
190 // scan \todo mettre cache line size
191
192 // Start dichotomy
193 if (n > n_linear) {
194 if (x < v[0])
195 return 0;
196 if (x > v[n - 1])
197 return n;
198 do {
199 const Integer imid = (iright + ileft) / 2;
200 const T& vmid = v[imid];
201 if (x < vmid) {
202 iright = imid;
203 }
204 else if (x >= vmid) {
205 ileft = imid;
206 }
207 } while (iright - ileft > n_linear);
208 }
209
210 // Switch to linear search
211 // (exhaustiveScan en alternative; gain mitig�)
212 while (ileft < iright and v[ileft] < x) {
213 ++ileft;
214 }
215 return ileft;
216 }
217
218 /*---------------------------------------------------------------------------*/
219
220 template <typename T>
221 Integer linearIntervalScan(const T& x, [[maybe_unused]] const Integer n, const T* vptr)
222 {
223 // Prepare
224 Integer index = 0;
225
226 // Search
227 while (vptr[index + 1] <= x)
228 ++index;
229 return index;
230 }
231
232 template <typename T>
233 Integer dichotomicIntervalScan(const T& x, const Integer n, const T* vptr)
234 {
236
237 Integer ileft = 0;
238 Integer iright = n; // d�finit un intervalle ouvert � droite
239 static const Integer n_linear = 20; // threshold to switch from dichotomic to linear
240 // scan \todo mettre cache line size
241
242 // Start dichotomy
243 while (iright - ileft > n_linear) {
244 const Integer imid = (iright + ileft) / 2;
245 const T& vmid = vptr[imid];
246 if (x < vmid) {
247 iright = imid;
248 }
249 else {
250 ileft = imid;
251 }
252 }
253
254 // Switch to linear search
255 while (vptr[ileft + 1] <= x)
256 ++ileft;
257 return ileft;
258 }
259
260} // end of namespace ArrayScan
261
262/*---------------------------------------------------------------------------*/
263/*---------------------------------------------------------------------------*/
264
265namespace ArrayConversion
266{
267} // end of namespace ArrayConversion
268
269/*---------------------------------------------------------------------------*/
270/*---------------------------------------------------------------------------*/
271
272inline void
273insert(UniqueArray<Integer>& list, UniqueArray<Real>& value, Integer entry, Real eps = 0.)
274{
275 if (entry == 0) {
276 list[0] = 0;
277 return;
278 }
279 Integer size = entry;
280 Integer i = size;
281 Real z = value[entry];
282 for (Integer k = 0; k < size; k++) {
283 if (z - value[list[k]] >= eps) {
284 i = k;
285 break;
286 }
287 }
288 Integer last = entry;
289 for (Integer j = i; j < size; j++) {
290 Integer tmp = list[j];
291 list[j] = last;
292 last = tmp;
293 }
294 list[size] = last;
295}
296
297inline Real
298average(ArrayView<Real> x, ArrayView<Real> coef, Integer n)
299{
300 Real xx = 0.;
301 for (Integer i = 0; i < n; i++)
302 xx += coef[i] * x[i];
303 return xx;
304}
305
306/*---------------------------------------------------------------------------*/
307/*---------------------------------------------------------------------------*/
308
309} // namespace Alien
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
Recherche d'un �l�ment dans un tableau.
Definition ArrayUtils.h:37
Integer linearScan(const T &x, ConstArrayView< T > v)
Definition ArrayUtils.h:119
Integer linearPositionScan(const T &x, ConstArrayView< T > v)
Definition ArrayUtils.h:172
Integer exhaustiveScan(const T &x, ConstArrayView< T > v)
Definition ArrayUtils.h:109
Integer linearIntervalScan(const T &x, const Integer n, const T *vptr)
Definition ArrayUtils.h:221
Integer dichotomicScan(const T &x, ConstArrayView< T > v)
Definition ArrayUtils.h:133
Integer dichotomicIntervalScan(const T &x, const Integer n, const T *vptr)
Definition ArrayUtils.h:233
Integer dichotomicPositionScan(const T &x, ConstArrayView< T > v)
Definition ArrayUtils.h:183
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17