Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
RandomGlobal.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* RandomGlobal.h (C) 2000-2017 */
9/* */
10/* Namespace pour Random. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_RANDOM_RANDOMGLOBAL_H
13#define ARCANE_RANDOM_RANDOMGLOBAL_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
18#include <climits>
19#include <limits>
20
21#define RANDOM_BEGIN_NAMESPACE namespace random {
22#define RANDOM_END_NAMESPACE }
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27ARCANE_BEGIN_NAMESPACE
28RANDOM_BEGIN_NAMESPACE
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33
34/*
35 * Copyright Jens Maurer 2000-2001
36 * Permission to use, copy, modify, sell, and distribute this software
37 * is hereby granted without fee provided that the above copyright notice
38 * appears in all copies and that both that copyright notice and this
39 * permission notice appear in supporting documentation,
40 *
41 * Jens Maurer makes no representations about the suitability of this
42 * software for any purpose. It is provided "as is" without express or
43 * implied warranty.
44 *
45 * See http://www.boost.org for most recent version including documentation.
46 *
47 * $Id: RandomGlobal.h 3932 2004-08-23 08:45:03Z grospelx $
48 *
49 * Revision history
50 * 2001-02-18 moved to individual header files
51 */
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
56namespace utils {
57template<class T, T min_val, T max_val>
59{
60 public:
61 static const bool is_integral = true;
62 static const T const_min = min_val;
63 static const T const_max = max_val;
64};
65
66/*---------------------------------------------------------------------------*/
67/*---------------------------------------------------------------------------*/
68
69template<class T>
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
74
75template<>
77 : public std::numeric_limits<int>,
78 public integer_traits_base<int, INT_MIN, INT_MAX>
79{ };
80
81template<>
83 : public std::numeric_limits<unsigned int>,
84 public integer_traits_base<unsigned int, 0, UINT_MAX>
85{ };
86
87template<>
89 : public std::numeric_limits<long>,
90 public integer_traits_base<long, LONG_MIN, LONG_MAX>
91{ };
92
93template<>
95 : public std::numeric_limits<unsigned long>,
96 public integer_traits_base<unsigned long, 0, ULONG_MAX>
97{ };
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
102template<bool is_signed>
103struct do_add
104{ };
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108
109template<>
111{
112 template<class IntType>
113 static IntType add(IntType m, IntType x, IntType c)
114 {
115 x += (c-m);
116 if(x < 0)
117 x += m;
118 return x;
119 }
120};
121
122template<>
124{
125 template<class IntType>
126 static IntType add(IntType, IntType, IntType)
127 {
128 // difficult
129 throw FatalErrorException("const_mod::add with c too large");
130 return 0;
131 }
132};
133
134/*---------------------------------------------------------------------------*/
135/*---------------------------------------------------------------------------*/
136
137template<class IntType, IntType m>
139{
140public:
141 static IntType add(IntType x, IntType c)
142 {
143 if(c == 0)
144 return x;
145 else if(c <= traits::const_max - m) // i.e. m+c < max
146 return add_small(x, c);
147 else
148 return do_add<traits::is_signed>::add(m, x, c);
149 }
150
151 static IntType mult(IntType a, IntType x)
152 {
153 if(a == 1)
154 return x;
155 else if(m <= traits::const_max/a) // i.e. a*m <= max
156 return mult_small(a, x);
157 else if(traits::is_signed && (m%a < m/a))
158 return mult_schrage(a, x);
159 else {
160 // difficult
161#ifdef ARCANE_CHECK
162 throw FatalErrorException("const_mod::mult with a too large");
163#endif
164 return 0;
165 }
166 }
167
168 static IntType mult_add(IntType a, IntType x, IntType c)
169 {
170 if(m <= (traits::const_max-c)/a) // i.e. a*m+c <= max
171 return (a*x+c) % m;
172 else
173 return add(mult(a, x), c);
174 }
175
176 static IntType invert(IntType x)
177 { return x == 0 ? 0 : invert_euclidian(x); }
178
179private:
181
182 const_mod(); // don't instantiate
183
184 static IntType add_small(IntType x, IntType c)
185 {
186 x += c;
187 if(x >= m)
188 x -= m;
189 return x;
190 }
191
192 static IntType mult_small(IntType a, IntType x)
193 {
194 return a*x % m;
195 }
196
197 static IntType mult_schrage(IntType a, IntType value)
198 {
199 const IntType q = m / a;
200 const IntType r = m % a;
201
202 value = a*(value%q) - r*(value/q);
203 while(value <= 0)
204 value += m;
205 return value;
206 }
207
208 // invert c in the finite field (mod m) (m must be prime)
209 static IntType invert_euclidian(IntType c)
210 {
211 IntType l1 = 0;
212 IntType l2 = 1;
213 IntType n = c;
214 IntType p = m;
215 for(;;) {
216 IntType q = p / n;
217 l1 -= q * l2; // this requires a signed IntType!
218 p -= q * n;
219 if(p == 0)
220 return (l2 < 1 ? l2 + m : l2);
221 IntType q2 = n / p;
222 l2 -= q2 * l1;
223 n -= q2 * p;
224 if(n == 0)
225 return (l1 < 1 ? l1 + m : l1);
226 }
227 }
228};
229
230/*---------------------------------------------------------------------------*/
231/*---------------------------------------------------------------------------*/
232
233// The modulus is exactly the word size: rely on machine overflow handling.
234// Due to a GCC bug, we cannot partially specialize in the presence of
235// template value parameters.
236template<>
238{
239 typedef unsigned int IntType;
240public:
241 static IntType add(IntType x, IntType c) { return x+c; }
242 static IntType mult(IntType a, IntType x) { return a*x; }
243 static IntType mult_add(IntType a, IntType x, IntType c) { return a*x+c; }
244
245 // m is not prime, thus invert is not useful
246private: // don't instantiate
247 const_mod();
248};
249
250/*---------------------------------------------------------------------------*/
251/*---------------------------------------------------------------------------*/
252
253template<>
255{
256 typedef unsigned long IntType;
257public:
258 static IntType add(IntType x, IntType c) { return x+c; }
259 static IntType mult(IntType a, IntType x) { return a*x; }
260 static IntType mult_add(IntType a, IntType x, IntType c) { return a*x+c; }
261
262 // m is not prime, thus invert is not useful
263private: // don't instantiate
264 const_mod();
265};
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270/*
271 * Correctly compare two numbers whose types possibly differ in signedness.
272 * See boost::numeric_cast<> for the general idea.
273 * Most "if" statements involve only compile-time constants, so the
274 * optimizing compiler can do its job easily.
275 *
276 * With most compilers, the straightforward implementation produces a
277 * bunch of (legitimate) warnings. Some template magic helps, though.
278 */
279
280template<bool signed1, bool signed2>
282{ };
283
284template<>
286{
287 // cast to the larger type is automatic with built-in types
288 template<class T1, class T2>
289 static bool equal(T1 x, T2 y) { return x == y; }
290 template<class T1, class T2>
291 static bool lessthan(T1 x, T2 y) { return x < y; }
292};
293
294template<>
295struct do_compare<true, true> : public do_compare<false, false>
296{ };
297
298template<>
300{
301 template<class T1, class T2>
302 static bool equal(T1 x, T2 y) { return x >= 0 && static_cast<T2>(x) == y; }
303 template<class T1, class T2>
304 static bool lessthan(T1 x, T2 y) { return x < 0 || static_cast<T2>(x) < y; }
305};
306
307template<>
309{
310 template<class T1, class T2>
311 static bool equal(T1 x, T2 y) { return y >= 0 && x == static_cast<T1>(y); }
312 template<class T1, class T2>
313 static bool lessthan(T1 x, T2 y) { return y >= 0 && x < static_cast<T1>(y); }
314};
315
316template<class T1, class T2>
317int equal_signed_unsigned(T1 x, T2 y)
318{
319 typedef std::numeric_limits<T1> x_traits;
320 typedef std::numeric_limits<T2> y_traits;
322}
323
324template<class T1, class T2>
325int lessthan_signed_unsigned(T1 x, T2 y)
326{
327 typedef std::numeric_limits<T1> x_traits;
328 typedef std::numeric_limits<T2> y_traits;
329 return do_compare<x_traits::is_signed, y_traits::is_signed>::lessthan(x, y);
330}
331
332} // namespace utils
333
334/*---------------------------------------------------------------------------*/
335/*---------------------------------------------------------------------------*/
336
337RANDOM_END_NAMESPACE
338ARCANE_END_NAMESPACE
339
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
342
343#endif
344
Fichier de configuration d'Arcane.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Exception lorsqu'une erreur fatale est survenue.