num_bigint/bigrand/
distr.rs1#![allow(clippy::duplicate_mod)]
3
4use super::{rand, BigRng};
5use crate::{BigInt, BigUint, RandomBits, UniformBigInt, UniformBigUint};
6
7use rand::distr::uniform::{Error, SampleBorrow, SampleUniform, UniformSampler};
8use rand::distr::Distribution;
9use rand::Rng;
10
11impl SampleUniform for BigUint {
14 type Sampler = UniformBigUint;
15}
16
17impl UniformSampler for UniformBigUint {
19 type X = BigUint;
20
21 #[inline]
22 fn new<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, Error>
23 where
24 B1: SampleBorrow<Self::X> + Sized,
25 B2: SampleBorrow<Self::X> + Sized,
26 {
27 let low = low_b.borrow();
28 let high = high_b.borrow();
29 if low < high {
30 Ok(UniformBigUint {
31 len: high - low,
32 base: low.clone(),
33 })
34 } else {
35 Err(Error::EmptyRange)
36 }
37 }
38
39 #[inline]
40 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, Error>
41 where
42 B1: SampleBorrow<Self::X> + Sized,
43 B2: SampleBorrow<Self::X> + Sized,
44 {
45 let low = low_b.borrow();
46 let high = high_b.borrow();
47 if low <= high {
48 Ok(UniformBigUint {
49 len: high - low + 1u32,
50 base: low.clone(),
51 })
52 } else {
53 Err(Error::EmptyRange)
54 }
55 }
56
57 #[inline]
58 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
59 &self.base + rng.random_biguint_below(&self.len)
60 }
61
62 #[inline]
63 fn sample_single<R: Rng + ?Sized, B1, B2>(
64 low: B1,
65 high: B2,
66 rng: &mut R,
67 ) -> Result<Self::X, Error>
68 where
69 B1: SampleBorrow<Self::X> + Sized,
70 B2: SampleBorrow<Self::X> + Sized,
71 {
72 let low = low.borrow();
73 let high = high.borrow();
74 if low < high {
75 Ok(rng.random_biguint_range(low, high))
76 } else {
77 Err(Error::EmptyRange)
78 }
79 }
80
81 #[inline]
82 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
83 low: B1,
84 high: B2,
85 rng: &mut R,
86 ) -> Result<Self::X, Error>
87 where
88 B1: SampleBorrow<Self::X> + Sized,
89 B2: SampleBorrow<Self::X> + Sized,
90 {
91 let low = low.borrow();
92 let high = high.borrow();
93 if low <= high {
94 Ok(rng.random_biguint_range(low, &(high + 1u32)))
95 } else {
96 Err(Error::EmptyRange)
97 }
98 }
99}
100
101impl SampleUniform for BigInt {
104 type Sampler = UniformBigInt;
105}
106
107impl UniformSampler for UniformBigInt {
109 type X = BigInt;
110
111 #[inline]
112 fn new<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, Error>
113 where
114 B1: SampleBorrow<Self::X> + Sized,
115 B2: SampleBorrow<Self::X> + Sized,
116 {
117 let low = low_b.borrow();
118 let high = high_b.borrow();
119 if low < high {
120 Ok(UniformBigInt {
121 len: (high - low).into_parts().1,
122 base: low.clone(),
123 })
124 } else {
125 Err(Error::EmptyRange)
126 }
127 }
128
129 #[inline]
130 fn new_inclusive<B1, B2>(low_b: B1, high_b: B2) -> Result<Self, Error>
131 where
132 B1: SampleBorrow<Self::X> + Sized,
133 B2: SampleBorrow<Self::X> + Sized,
134 {
135 let low = low_b.borrow();
136 let high = high_b.borrow();
137 if low <= high {
138 Ok(UniformBigInt {
139 len: (high - low).into_parts().1 + 1u32,
140 base: low.clone(),
141 })
142 } else {
143 Err(Error::EmptyRange)
144 }
145 }
146
147 #[inline]
148 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
149 &self.base + BigInt::from(rng.random_biguint_below(&self.len))
150 }
151
152 #[inline]
153 fn sample_single<R: Rng + ?Sized, B1, B2>(
154 low: B1,
155 high: B2,
156 rng: &mut R,
157 ) -> Result<Self::X, Error>
158 where
159 B1: SampleBorrow<Self::X> + Sized,
160 B2: SampleBorrow<Self::X> + Sized,
161 {
162 let low = low.borrow();
163 let high = high.borrow();
164 if low < high {
165 Ok(rng.random_bigint_range(low, high))
166 } else {
167 Err(Error::EmptyRange)
168 }
169 }
170
171 #[inline]
172 fn sample_single_inclusive<R: Rng + ?Sized, B1, B2>(
173 low: B1,
174 high: B2,
175 rng: &mut R,
176 ) -> Result<Self::X, Error>
177 where
178 B1: SampleBorrow<Self::X> + Sized,
179 B2: SampleBorrow<Self::X> + Sized,
180 {
181 let low = low.borrow();
182 let high = high.borrow();
183 if low <= high {
184 Ok(rng.random_bigint_range(low, &(high + 1u32)))
185 } else {
186 Err(Error::EmptyRange)
187 }
188 }
189}
190
191impl Distribution<BigUint> for RandomBits {
192 #[inline]
193 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> BigUint {
194 rng.random_biguint(self.bits)
195 }
196}
197
198impl Distribution<BigInt> for RandomBits {
199 #[inline]
200 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> BigInt {
201 rng.random_bigint(self.bits)
202 }
203}