Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
UniformSmallInt.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* UniformSmallInt.h (C) 2000-2025 */
9/* */
10/* Randomize 'UniformSmallInt'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13#ifndef ARCANE_CORE_RANDOM_UNIFORMONSMALLINT_H
14#define ARCANE_CORE_RANDOM_UNIFORMONSMALLINT_H
15/*---------------------------------------------------------------------------*/
16/*---------------------------------------------------------------------------*/
17
18#include "arcane/utils/FatalErrorException.h"
19
20#include "arcane/core/random/NormalDistribution.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: UniformSmallInt.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 a small range [min, max]
54template <class UniformRandomNumberGenerator, class IntType = int>
55class UniformSmallInt
56{
57 public:
58
59 typedef UniformRandomNumberGenerator base_type;
60 typedef IntType result_type;
61 static const bool has_fixed_range = false;
62
63 UniformSmallInt(base_type& rng, IntType min, IntType max);
64 result_type operator()()
65 {
66 // we must not use the low bits here, because LCGs perform very poorly then
67 return ((_rng() - _rng.min()) / _factor) % _range + _min;
68 }
69 result_type min() const { return _min; }
70 result_type max() const { return _max; }
71
72 private:
73
74 typedef typename base_type::result_type base_result;
75 base_type& _rng;
76 IntType _min, _max;
77 base_result _range;
78 int _factor;
79};
80
81template <class UniformRandomNumberGenerator, class IntType>
83UniformSmallInt(base_type& rng, IntType min, IntType max)
84: _rng(rng)
85, _min(min)
86, _max(max)
87, _range(static_cast<base_result>(_max - _min) + 1)
88, _factor(1)
89{
90 // LCGs perform poorly when only taking the low bits.
91 // (probably put this logic into a partial template specialization)
92 // Check how many low bits we can ignore before we get too much
93 // quantization error.
94 base_result r_base = _rng.max() - _rng.min();
95 if (r_base == std::numeric_limits<base_result>::max()) {
96 _factor = 2;
97 r_base /= 2;
98 }
99 r_base += 1;
100 if (r_base % _range == 0) {
101 // No quantization effects, good
102 _factor = r_base / _range;
103 }
104 else {
105 // carefully avoid overflow; pessimizing heree
106 for (; r_base / _range / 32 >= _range; _factor *= 2)
107 r_base /= 2;
108 }
109}
110
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
113
114} // namespace Arcane::random
115
116/*---------------------------------------------------------------------------*/
117/*---------------------------------------------------------------------------*/
118
119#endif