Arcane  v3.16.8.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
UniformInt.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* UniformInt.h (C) 2000-2025 */
9/* */
10/* Randomiser 'UniformInt'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13#ifndef ARCANE_CORE_RANDOM_UNIFORMONINT_H
14#define ARCANE_CORE_RANDOM_UNIFORMONINT_H
15/*---------------------------------------------------------------------------*/
16/*---------------------------------------------------------------------------*/
17
18#include "arcane/utils/FatalErrorException.h"
19
20#include "arcane/core/random/UniformSmallInt.h"
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25namespace Arcane::random
26{
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31/*
32 * Copyright Jens Maurer 2000-2001
33 * Permission to use, copy, modify, sell, and distribute this software
34 * is hereby granted without fee provided that the above copyright notice
35 * appears in all copies and that both that copyright notice and this
36 * permission notice appear in supporting documentation,
37 *
38 * Jens Maurer makes no representations about the suitability of this
39 * software for any purpose. It is provided "as is" without express or
40 * implied warranty.
41 *
42 * See http://www.boost.org for most recent version including documentation.
43 *
44 * $Id: UniformInt.h 3932 2004-08-23 08:45:03Z grospelx $
45 *
46 * Revision history
47 * 2001-02-18 moved to individual header files
48 */
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53// uniform integer distribution on [min, max]
54template<class UniformRandomNumberGenerator,class IntType = int>
55class UniformInt
56{
57public:
58 typedef UniformRandomNumberGenerator base_type;
59 typedef IntType result_type;
60 static const bool has_fixed_range = false;
61
62 UniformInt(base_type & rng, IntType min, IntType max)
63 : _rng(rng), _min(min), _max(max), _range(_max - _min),
64 _bmin(_rng.min()), _brange(_rng.max() - _bmin)
65 {
66 if(utils::equal_signed_unsigned(_brange, _range))
67 _range_comparison = 0;
68 else if(utils::lessthan_signed_unsigned(_brange, _range))
69 _range_comparison = -1;
70 else
71 _range_comparison = 1;
72 }
73 result_type operator()();
74 result_type min() const { return _min; }
75 result_type max() const { return _max; }
76 private:
77 typedef typename base_type::result_type base_result;
78 base_type & _rng;
79 result_type _min, _max, _range;
80 base_result _bmin, _brange;
81 int _range_comparison;
82};
83
84template<class UniformRandomNumberGenerator, class IntType>
85inline IntType UniformInt<UniformRandomNumberGenerator, IntType>::operator()()
86{
87 if(_range_comparison == 0) {
88 // this will probably never happen in real life
89 // basically nothing to do; just take care we don't overflow / underflow
90 return static_cast<result_type>(_rng() - _bmin) + _min;
91 } else if(_range_comparison < 0) {
92 // use rejection method to handle things like 0..3 --> 0..4
93 for(;;) {
94 // concatenate several invocations of the base RNG
95 // take extra care to avoid overflows
96 result_type limit;
97 if(_range == std::numeric_limits<result_type>::max()) {
98 limit = _range/(static_cast<result_type>(_brange)+1);
99 if(_range % static_cast<result_type>(_brange)+1 == static_cast<result_type>(_brange))
100 ++limit;
101 } else {
102 limit = (_range+1)/(static_cast<result_type>(_brange)+1);
103 }
104 // we consider "result" as expressed to base (_brange+1)
105 // for every power of (_brange+1), we determine a random factor
106 result_type result = 0;
107 result_type mult = 1;
108 while(mult <= limit) {
109 result += (_rng() - _bmin) * mult;
110 mult *= static_cast<result_type>(_brange)+1;
111 }
112 if(mult == limit)
113 // _range+1 is an integer power of _brange+1: no rejections required
114 return result;
115 // _range/mult < _brange+1 -> no endless loop
116 result += UniformInt<base_type,result_type>(_rng, 0, _range/mult)() * mult;
117 if(result <= _range)
118 return result + _min;
119 }
120 } else { // brange > range
121 if(_brange / _range > 4 /* quantization_cutoff */ ) {
122 // the new range is vastly smaller than the source range,
123 // so quantization effects are not relevant
124 return UniformSmallInt<base_type,result_type>(_rng, _min, _max)();
125 } else {
126 // use rejection method to handle things like 0..5 -> 0..4
127 for(;;) {
128 base_result result = _rng() - _bmin;
129 // result and range are non-negative, and result is possibly larger
130 // than range, so the cast is safe
131 if(result <= static_cast<base_result>(_range))
132 return result + _min;
133 }
134 }
135 }
136}
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
141}
142
143/*---------------------------------------------------------------------------*/
144/*---------------------------------------------------------------------------*/
145
146#endif
void mult(ArrayView< T > lhs, ConstArrayView< T > copy_array)
Multiplie terme à terme les éléments de l'instance par les éléments du tableau copy_array.
Definition MathUtils.h:963