sobol_qmc/
type_support.rs

1use crate::{
2    GaussianRender, InternalType, LossyFrom, MultiDimGaussianRender, Render, SobolType, UnitRender,
3};
4use statrs::distribution::ContinuousCDF as _;
5
6/// SobolType implementation for 32-bit floating-point values
7impl SobolType for f32 {
8    type IT = u32;
9    /// IEEE-754 "binary32" significand = 24 bits
10    const MAX_RESOLUTION: usize = 24;
11}
12impl Render<f32> for UnitRender {
13    fn render(&self, _: usize, val: u32) -> f32 {
14        // 4294967296 <-> u32::MAX + 1
15        (val as f32) / 4_294_967_296_f32
16    }
17}
18impl Render<f32> for GaussianRender {
19    fn render(&self, dim: usize, val: u32) -> f32 {
20        self.0
21            .inverse_cdf(<UnitRender as Render<f32>>::render(&UnitRender, dim, val) as f64)
22            as f32
23    }
24}
25impl Render<f32> for MultiDimGaussianRender {
26    fn render(&self, dim: usize, val: u32) -> f32 {
27        self.0[dim].inverse_cdf(<UnitRender as Render<f32>>::render(&UnitRender, dim, val) as f64)
28            as f32
29    }
30    fn support_dims(&self) -> Option<usize> {
31        Some(self.0.len())
32    }
33}
34
35/// SobolType implementation for 64-bit floating-point values
36impl SobolType for f64 {
37    type IT = u64;
38    /// IEEE-754 "binary64" significand = 53 bits
39    const MAX_RESOLUTION: usize = 53;
40}
41impl Render<f64> for UnitRender {
42    fn render(&self, _: usize, val: u64) -> f64 {
43        // 18446744073709551616 <-> u64::MAX + 1
44        (val as f64) / 18_446_744_073_709_551_616_f64
45    }
46}
47impl Render<f64> for GaussianRender {
48    fn render(&self, dim: usize, val: u64) -> f64 {
49        self.0
50            .inverse_cdf(<UnitRender as Render<f64>>::render(&UnitRender, dim, val))
51    }
52}
53impl Render<f64> for MultiDimGaussianRender {
54    fn render(&self, dim: usize, val: u64) -> f64 {
55        self.0[dim].inverse_cdf(<UnitRender as Render<f64>>::render(&UnitRender, dim, val))
56    }
57    fn support_dims(&self) -> Option<usize> {
58        Some(self.0.len())
59    }
60}
61
62/// SobolType implementation for 8-bit unsigned values
63impl SobolType for u8 {
64    type IT = u8;
65}
66impl Render<u8> for UnitRender {
67    fn render(&self, _: usize, val: u8) -> u8 {
68        val
69    }
70}
71
72/// SobolType implementation for 16-bit unsigned values
73impl SobolType for u16 {
74    type IT = u16;
75}
76impl Render<u16> for UnitRender {
77    fn render(&self, _: usize, val: u16) -> u16 {
78        val
79    }
80}
81
82/// SobolType implementation for 32-bit unsigned values
83impl SobolType for u32 {
84    type IT = u32;
85}
86impl Render<u32> for UnitRender {
87    fn render(&self, _: usize, val: u32) -> u32 {
88        val
89    }
90}
91
92/// SobolType implementation for 64-bit unsigned values
93impl SobolType for u64 {
94    type IT = u64;
95}
96impl Render<u64> for UnitRender {
97    fn render(&self, _: usize, val: u64) -> u64 {
98        val
99    }
100}
101
102/// SobolType implementation for 128-bit unsigned values
103impl SobolType for u128 {
104    type IT = u128;
105}
106impl Render<u128> for UnitRender {
107    fn render(&self, _: usize, val: u128) -> u128 {
108        val
109    }
110}
111
112/// SobolType implementation for 8-bit signed values
113impl SobolType for i8 {
114    type IT = u8;
115}
116impl Render<i8> for UnitRender {
117    fn render(&self, _: usize, val: u8) -> i8 {
118        (val ^ 0x80) as i8
119    }
120}
121
122/// SobolType implementation for 16-bit signed values
123impl SobolType for i16 {
124    type IT = u16;
125}
126impl Render<i16> for UnitRender {
127    fn render(&self, _: usize, val: u16) -> i16 {
128        (val ^ 0x8000) as i16
129    }
130}
131
132/// SobolType implementation for 32-bit signed values
133impl SobolType for i32 {
134    type IT = u32;
135}
136impl Render<i32> for UnitRender {
137    fn render(&self, _: usize, val: u32) -> i32 {
138        (val ^ 0x8000_0000) as i32
139    }
140}
141
142/// SobolType implementation for 64-bit signed values
143impl SobolType for i64 {
144    type IT = u64;
145}
146impl Render<i64> for UnitRender {
147    fn render(&self, _: usize, val: u64) -> i64 {
148        (val ^ 0x8000_0000_0000_0000) as i64
149    }
150}
151
152/// SobolType implementation for 128-bit signed values
153impl SobolType for i128 {
154    type IT = u128;
155}
156impl Render<i128> for UnitRender {
157    fn render(&self, _: usize, val: u128) -> i128 {
158        (val ^ 0x8000_0000_0000_0000_0000_0000_0000_0000) as i128
159    }
160}
161
162/// InternalType implementation for 8-bit values
163impl InternalType for u8 {
164    const BITS: usize = 8;
165}
166
167/// InternalType implementation for 16-bit values
168impl InternalType for u16 {
169    const BITS: usize = 16;
170}
171
172/// InternalType implementation for 32-bit values
173impl InternalType for u32 {
174    const BITS: usize = 32;
175}
176
177/// InternalType implementation for 64-bit values
178impl InternalType for u64 {
179    const BITS: usize = 64;
180}
181
182/// InternalType implementation for 128-bit values
183impl InternalType for u128 {
184    const BITS: usize = 128;
185}
186
187/// Reflexive `LossyFrom`
188impl<T> LossyFrom<T> for T {
189    fn lossy_from(val: T) -> T {
190        val
191    }
192}
193
194/// LossyFrom `u16` to `u8`
195impl LossyFrom<u16> for u8 {
196    fn lossy_from(val: u16) -> u8 {
197        val as u8
198    }
199}
200
201/// LossyFrom `u16` to `u32`
202impl LossyFrom<u16> for u32 {
203    fn lossy_from(val: u16) -> u32 {
204        u32::from(val)
205    }
206}
207
208/// LossyFrom `u16` to `u64`
209impl LossyFrom<u16> for u64 {
210    fn lossy_from(val: u16) -> u64 {
211        u64::from(val)
212    }
213}
214
215/// LossyFrom `u16` to `u128`
216impl LossyFrom<u16> for u128 {
217    fn lossy_from(val: u16) -> u128 {
218        u128::from(val)
219    }
220}
221
222/// LossyFrom `u32` to `u8`
223impl LossyFrom<u32> for u8 {
224    fn lossy_from(val: u32) -> u8 {
225        val as u8
226    }
227}
228
229/// LossyFrom `u32` to `u16`
230impl LossyFrom<u32> for u16 {
231    fn lossy_from(val: u32) -> u16 {
232        val as u16
233    }
234}
235
236/// LossyFrom `u32` to `u64`
237impl LossyFrom<u32> for u64 {
238    fn lossy_from(val: u32) -> u64 {
239        u64::from(val)
240    }
241}
242
243/// LossyFrom `u32` to `u128`
244impl LossyFrom<u32> for u128 {
245    fn lossy_from(val: u32) -> u128 {
246        u128::from(val)
247    }
248}
249
250/// LossyFrom `u64` to `u8`
251impl LossyFrom<u64> for u8 {
252    fn lossy_from(val: u64) -> u8 {
253        val as u8
254    }
255}
256
257/// LossyFrom `u64` to `u16`
258impl LossyFrom<u64> for u16 {
259    fn lossy_from(val: u64) -> u16 {
260        val as u16
261    }
262}
263
264/// LossyFrom `u64` to `u32`
265impl LossyFrom<u64> for u32 {
266    fn lossy_from(val: u64) -> u32 {
267        val as u32
268    }
269}
270
271/// LossyFrom `u64` to `u128`
272impl LossyFrom<u64> for u128 {
273    fn lossy_from(val: u64) -> u128 {
274        u128::from(val)
275    }
276}
277
278/// LossyFrom `u128` to `u8`
279impl LossyFrom<u128> for u8 {
280    fn lossy_from(val: u128) -> u8 {
281        val as u8
282    }
283}
284
285/// LossyFrom `u128` to `u16`
286impl LossyFrom<u128> for u16 {
287    fn lossy_from(val: u128) -> u16 {
288        val as u16
289    }
290}
291
292/// LossyFrom `u128` to `u32`
293impl LossyFrom<u128> for u32 {
294    fn lossy_from(val: u128) -> u32 {
295        val as u32
296    }
297}
298
299/// LossyFrom `u128` to `u64`
300impl LossyFrom<u128> for u64 {
301    fn lossy_from(val: u128) -> u64 {
302        val as u64
303    }
304}