1#![cfg_attr(
61 feature = "doc-images",
62 doc = embed_doc_image::embed_image!("vdc-sequence", "docs/images/vdc-sequence.png")
63)]
64#![cfg_attr(
65 feature = "doc-images",
66 doc = embed_doc_image::embed_image!("circle-points", "docs/images/circle-points.png")
67)]
68#![cfg_attr(
69 feature = "doc-images",
70 doc = embed_doc_image::embed_image!("disk-points", "docs/images/disk-points.png")
71)]
72#![cfg_attr(
73 feature = "doc-images",
74 doc = embed_doc_image::embed_image!("halton-2d-scatter", "docs/images/halton-2d-scatter.png")
75)]
76
77use std::f64::consts::PI;
78use std::sync::atomic::{AtomicU64, Ordering};
79
80pub const TWO_PI: f64 = 2.0 * PI;
82
83pub const MAX_DIGITS: usize = 64;
85
86pub fn vdc(count: u64, base: u64) -> f64 {
106 let mut count = count;
107 let mut reslt = 0.0;
108 let mut denom = 1.0;
109 let base_f64 = base as f64;
110
111 while count != 0 {
112 denom *= base_f64;
113 let remainder = (count % base) as f64;
114 count /= base;
115 reslt += remainder / denom;
116 }
117 reslt
118}
119
120#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
140))]
156#[derive(Debug)]
157pub struct VdCorput {
158 count: AtomicU64,
159 base: u64,
160 rev_lst: Vec<f64>,
161}
162
163impl VdCorput {
164 pub fn new(base: u64) -> Self {
170 assert!(base >= 2, "base must be >= 2, got {}", base);
171 let mut rev_lst = Vec::with_capacity(MAX_DIGITS);
172 let mut reverse = 1.0;
173 let base_f64 = base as f64;
174
175 for _ in 0..MAX_DIGITS {
176 reverse /= base_f64;
177 rev_lst.push(reverse);
178 }
179
180 Self {
181 count: AtomicU64::new(0),
182 base,
183 rev_lst,
184 }
185 }
186
187 pub fn pop(&mut self) -> f64 {
194 let count = self.count.fetch_add(1, Ordering::Relaxed) + 1; let mut count = count;
196 let mut res = 0.0;
197 let mut i = 0;
198
199 while count != 0 {
200 let remainder = (count % self.base) as f64;
201 count /= self.base;
202 if remainder != 0.0 {
203 res += remainder * self.rev_lst[i];
204 }
205 i += 1;
206 }
207 res
208 }
209
210 pub fn peek(&self) -> f64 {
216 let mut count = self.count.load(Ordering::Relaxed) + 1;
217 let mut res = 0.0;
218 let mut i = 0;
219
220 while count != 0 {
221 let remainder = (count % self.base) as f64;
222 count /= self.base;
223 if remainder != 0.0 {
224 res += remainder * self.rev_lst[i];
225 }
226 i += 1;
227 }
228 res
229 }
230
231 pub fn advance(&self, n: u64) {
237 self.count.fetch_add(n, Ordering::Relaxed);
238 }
239
240 pub fn get_index(&self) -> u64 {
242 self.count.load(Ordering::Relaxed)
243 }
244
245 pub fn reseed(&mut self, seed: u64) {
251 self.count.store(seed, Ordering::Relaxed);
252 }
253}
254
255impl Iterator for VdCorput {
256 type Item = f64;
257
258 fn next(&mut self) -> Option<Self::Item> {
262 Some(self.pop())
263 }
264}
265
266impl Default for VdCorput {
267 fn default() -> Self {
268 Self::new(2)
269 }
270}
271
272impl Clone for VdCorput {
273 fn clone(&self) -> Self {
278 Self {
279 count: AtomicU64::new(self.count.load(Ordering::Relaxed)),
280 base: self.base,
281 rev_lst: self.rev_lst.clone(),
282 }
283 }
284}
285
286#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
304))]
313pub struct Halton {
314 vdc0: VdCorput,
315 vdc1: VdCorput,
316}
317
318impl Halton {
319 pub fn new(base: [u64; 2]) -> Self {
325 Self {
326 vdc0: VdCorput::new(base[0]),
327 vdc1: VdCorput::new(base[1]),
328 }
329 }
330
331 pub fn pop(&mut self) -> [f64; 2] {
335 [self.vdc0.pop(), self.vdc1.pop()]
336 }
337
338 pub fn peek(&self) -> [f64; 2] {
340 [self.vdc0.peek(), self.vdc1.peek()]
341 }
342
343 pub fn advance(&self, n: u64) {
349 self.vdc0.advance(n);
350 self.vdc1.advance(n);
351 }
352
353 pub fn get_index(&self) -> u64 {
355 self.vdc0.get_index()
356 }
357
358 pub fn reseed(&mut self, seed: u64) {
364 self.vdc0.reseed(seed);
365 self.vdc1.reseed(seed);
366 }
367}
368
369impl Iterator for Halton {
370 type Item = [f64; 2];
371
372 fn next(&mut self) -> Option<Self::Item> {
376 Some(self.pop())
377 }
378}
379
380impl Clone for Halton {
381 fn clone(&self) -> Self {
386 Self {
387 vdc0: self.vdc0.clone(),
388 vdc1: self.vdc1.clone(),
389 }
390 }
391}
392#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
411))]
424pub struct Circle {
425 vdc: VdCorput,
426}
427
428impl Circle {
429 pub fn new(base: u64) -> Self {
435 assert!(base >= 2, "base must be >= 2, got {}", base);
436 Self {
437 vdc: VdCorput::new(base),
438 }
439 }
440
441 pub fn pop(&mut self) -> [f64; 2] {
449 let theta = self.vdc.pop() * TWO_PI; [theta.cos(), theta.sin()]
451 }
452
453 pub fn peek(&self) -> [f64; 2] {
457 let theta = self.vdc.peek() * TWO_PI;
458 [theta.cos(), theta.sin()]
459 }
460
461 pub fn advance(&self, n: u64) {
467 self.vdc.advance(n);
468 }
469
470 pub fn get_index(&self) -> u64 {
472 self.vdc.get_index()
473 }
474
475 pub fn reseed(&mut self, seed: u64) {
481 self.vdc.reseed(seed);
482 }
483}
484
485impl Iterator for Circle {
486 type Item = [f64; 2];
487
488 fn next(&mut self) -> Option<Self::Item> {
492 Some(self.pop())
493 }
494}
495
496impl Clone for Circle {
497 fn clone(&self) -> Self {
498 Self {
499 vdc: self.vdc.clone(),
500 }
501 }
502}
503
504#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
524))]
542pub struct Disk {
543 vdc0: VdCorput,
544 vdc1: VdCorput,
545}
546
547impl Disk {
548 pub fn new(base: [u64; 2]) -> Self {
554 Self {
555 vdc0: VdCorput::new(base[0]),
556 vdc1: VdCorput::new(base[1]),
557 }
558 }
559
560 pub fn pop(&mut self) -> [f64; 2] {
566 let theta = self.vdc0.pop() * TWO_PI; let radius = self.vdc1.pop().sqrt(); [radius * theta.cos(), radius * theta.sin()]
569 }
570
571 pub fn peek(&self) -> [f64; 2] {
575 let theta = self.vdc0.peek() * TWO_PI;
576 let radius = self.vdc1.peek().sqrt();
577 [radius * theta.cos(), radius * theta.sin()]
578 }
579
580 pub fn advance(&self, n: u64) {
586 self.vdc0.advance(n);
587 self.vdc1.advance(n);
588 }
589
590 pub fn get_index(&self) -> u64 {
592 self.vdc0.get_index()
593 }
594
595 pub fn reseed(&mut self, seed: u64) {
601 self.vdc0.reseed(seed);
602 self.vdc1.reseed(seed);
603 }
604}
605
606impl Iterator for Disk {
607 type Item = [f64; 2];
608
609 fn next(&mut self) -> Option<Self::Item> {
613 Some(self.pop())
614 }
615}
616
617impl Clone for Disk {
618 fn clone(&self) -> Self {
619 Self {
620 vdc0: self.vdc0.clone(),
621 vdc1: self.vdc1.clone(),
622 }
623 }
624}
625
626#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
646))]
664pub struct Sphere {
665 vdcgen: VdCorput,
666 cirgen: Circle,
667}
668
669impl Sphere {
670 pub fn new(base: [u64; 2]) -> Self {
676 Self {
677 vdcgen: VdCorput::new(base[0]),
678 cirgen: Circle::new(base[1]),
679 }
680 }
681
682 pub fn pop(&mut self) -> [f64; 3] {
691 let cosphi = 2.0 * self.vdcgen.pop() - 1.0; let sinphi = (1.0 - cosphi * cosphi).sqrt(); let [cos, sin] = self.cirgen.pop();
694 [sinphi * cos, sinphi * sin, cosphi]
695 }
696
697 pub fn peek(&self) -> [f64; 3] {
701 let cosphi = 2.0 * self.vdcgen.peek() - 1.0;
702 let sinphi = (1.0 - cosphi * cosphi).sqrt();
703 let [cos, sin] = self.cirgen.peek();
704 [sinphi * cos, sinphi * sin, cosphi]
705 }
706
707 pub fn advance(&self, n: u64) {
713 self.cirgen.advance(n);
714 self.vdcgen.advance(n);
715 }
716
717 pub fn get_index(&self) -> u64 {
719 self.vdcgen.get_index()
720 }
721
722 pub fn reseed(&mut self, seed: u64) {
728 self.cirgen.reseed(seed);
729 self.vdcgen.reseed(seed);
730 }
731}
732
733impl Iterator for Sphere {
734 type Item = [f64; 3];
735
736 fn next(&mut self) -> Option<Self::Item> {
740 Some(self.pop())
741 }
742}
743
744impl Clone for Sphere {
745 fn clone(&self) -> Self {
746 Self {
747 vdcgen: self.vdcgen.clone(),
748 cirgen: self.cirgen.clone(),
749 }
750 }
751}
752
753#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
775))]
797pub struct Sphere3Hopf {
798 vdc0: VdCorput,
799 vdc1: VdCorput,
800 vdc2: VdCorput,
801}
802
803impl Sphere3Hopf {
804 pub fn new(base: [u64; 3]) -> Self {
810 Self {
811 vdc0: VdCorput::new(base[0]),
812 vdc1: VdCorput::new(base[1]),
813 vdc2: VdCorput::new(base[2]),
814 }
815 }
816
817 pub fn pop(&mut self) -> [f64; 4] {
828 let phi = self.vdc0.pop() * TWO_PI; let psy = self.vdc1.pop() * TWO_PI; let vdc = self.vdc2.pop();
831 let cos_eta = vdc.sqrt();
832 let sin_eta = (1.0 - vdc).sqrt();
833 [
834 cos_eta * psy.cos(),
835 cos_eta * psy.sin(),
836 sin_eta * (phi + psy).cos(),
837 sin_eta * (phi + psy).sin(),
838 ]
839 }
840
841 pub fn peek(&self) -> [f64; 4] {
845 let phi = self.vdc0.peek() * TWO_PI;
846 let psy = self.vdc1.peek() * TWO_PI;
847 let vdc = self.vdc2.peek();
848 let cos_eta = vdc.sqrt();
849 let sin_eta = (1.0 - vdc).sqrt();
850 [
851 cos_eta * psy.cos(),
852 cos_eta * psy.sin(),
853 sin_eta * (phi + psy).cos(),
854 sin_eta * (phi + psy).sin(),
855 ]
856 }
857
858 pub fn advance(&self, n: u64) {
864 self.vdc0.advance(n);
865 self.vdc1.advance(n);
866 self.vdc2.advance(n);
867 }
868
869 pub fn get_index(&self) -> u64 {
871 self.vdc0.get_index()
872 }
873
874 pub fn reseed(&mut self, seed: u64) {
880 self.vdc0.reseed(seed);
881 self.vdc1.reseed(seed);
882 self.vdc2.reseed(seed);
883 }
884}
885
886impl Iterator for Sphere3Hopf {
887 type Item = [f64; 4];
888
889 fn next(&mut self) -> Option<Self::Item> {
893 Some(self.pop())
894 }
895}
896
897impl Clone for Sphere3Hopf {
898 fn clone(&self) -> Self {
899 Self {
900 vdc0: self.vdc0.clone(),
901 vdc1: self.vdc1.clone(),
902 vdc2: self.vdc2.clone(),
903 }
904 }
905}
906
907pub struct HaltonN {
923 vdcs: Vec<VdCorput>,
924}
925
926impl HaltonN {
927 pub fn new(base: &[u64]) -> Self {
933 let vdcs = base.iter().map(|&b| VdCorput::new(b)).collect();
934 Self { vdcs }
935 }
936
937 pub fn pop(&mut self) -> Vec<f64> {
941 let mut result = Vec::with_capacity(self.vdcs.len());
942 for vdc in &mut self.vdcs {
943 result.push(vdc.pop());
944 }
945 result
946 }
947
948 pub fn reseed(&mut self, seed: u64) {
954 for vdc in &mut self.vdcs {
955 vdc.reseed(seed);
956 }
957 }
958}
959
960impl Iterator for HaltonN {
961 type Item = Vec<f64>;
962
963 fn next(&mut self) -> Option<Self::Item> {
967 Some(self.pop())
968 }
969}
970
971impl Clone for HaltonN {
972 fn clone(&self) -> Self {
973 Self {
974 vdcs: self.vdcs.clone(),
975 }
976 }
977}
978
979pub const PRIME_TABLE: [u64; 1000] = [
983 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
984 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
985 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307,
986 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
987 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547,
988 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
989 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
990 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929,
991 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039,
992 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153,
993 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279,
994 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409,
995 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499,
996 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613,
997 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741,
998 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873,
999 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999,
1000 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113,
1001 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251,
1002 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371,
1003 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477,
1004 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647,
1005 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731,
1006 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857,
1007 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001,
1008 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163,
1009 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299,
1010 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407,
1011 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539,
1012 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659,
1013 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793,
1014 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919,
1015 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051,
1016 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201,
1017 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327,
1018 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463,
1019 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603,
1020 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733,
1021 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903,
1022 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009,
1023 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153,
1024 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303,
1025 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441,
1026 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569,
1027 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701,
1028 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843,
1029 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987,
1030 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131,
1031 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269,
1032 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373,
1033 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553,
1034 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691,
1035 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829,
1036 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967,
1037 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109,
1038 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247,
1039 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451,
1040 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559,
1041 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687,
1042 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841,
1043 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
1044];
1045
1046pub mod ilds;
1048
1049pub mod sphere_n;
1051
1052#[cfg(test)]
1053mod tests {
1054 use super::*;
1055 use approx::assert_relative_eq;
1056
1057 #[test]
1058 fn test_vdc_function() {
1059 assert_eq!(vdc(11, 2), 0.8125);
1060 assert_eq!(vdc(0, 2), 0.0);
1061 assert_eq!(vdc(1, 2), 0.5);
1062 assert_eq!(vdc(2, 2), 0.25);
1063 assert_eq!(vdc(3, 2), 0.75);
1064 }
1065
1066 #[test]
1067 fn test_vdcorput_pop() {
1068 let mut vgen = VdCorput::new(2);
1069 vgen.reseed(0);
1070 assert_eq!(vgen.pop(), 0.5);
1071 assert_eq!(vgen.pop(), 0.25);
1072 assert_eq!(vgen.pop(), 0.75);
1073 assert_eq!(vgen.pop(), 0.125);
1074 }
1075
1076 #[test]
1077 fn test_vdcorput_reseed() {
1078 let mut vgen = VdCorput::new(2);
1079 vgen.reseed(5);
1080 assert_eq!(vgen.pop(), 0.375);
1081 vgen.reseed(0);
1082 assert_eq!(vgen.pop(), 0.5);
1083 }
1084
1085 #[test]
1086 fn test_vdcorput_default() {
1087 let mut vgen = VdCorput::default();
1088 vgen.reseed(0);
1089 assert_eq!(vgen.pop(), 0.5);
1090 assert_eq!(vgen.pop(), 0.25);
1091 }
1092
1093 #[test]
1094 fn test_halton_pop() {
1095 let mut hgen = Halton::new([2, 3]);
1096 hgen.reseed(0);
1097 let res = hgen.pop();
1098 assert_eq!(res[0], 0.5);
1099 assert_relative_eq!(res[1], 1.0 / 3.0, epsilon = 1e-10);
1100
1101 let res = hgen.pop();
1102 assert_eq!(res[0], 0.25);
1103 assert_relative_eq!(res[1], 2.0 / 3.0, epsilon = 1e-10);
1104 }
1105
1106 #[test]
1107 fn test_circle_pop() {
1108 let mut cgen = Circle::new(2);
1109 cgen.reseed(0);
1110 let res = cgen.pop();
1111 assert_relative_eq!(res[0], -1.0, epsilon = 1e-10);
1113 assert_relative_eq!(res[1], 0.0, epsilon = 1e-10);
1114
1115 let res = cgen.pop();
1116 assert_relative_eq!(res[0], 0.0, epsilon = 1e-10);
1118 assert_relative_eq!(res[1], 1.0, epsilon = 1e-10);
1119 }
1120
1121 #[test]
1122 fn test_disk_pop() {
1123 let mut dgen = Disk::new([2, 3]);
1124 dgen.reseed(0);
1125 let res = dgen.pop();
1126
1127 let radius_sq = res[0] * res[0] + res[1] * res[1];
1129 assert!(radius_sq <= 1.0);
1130
1131 for _ in 0..10 {
1133 let res = dgen.pop();
1134 let radius_sq = res[0] * res[0] + res[1] * res[1];
1135 assert!(radius_sq <= 1.0);
1136 }
1137 }
1138
1139 #[test]
1140 fn test_sphere_pop() {
1141 let mut sgen = Sphere::new([2, 3]);
1142 sgen.reseed(0);
1143 let res = sgen.pop();
1144
1145 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
1147 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1148
1149 for _ in 0..5 {
1151 let res = sgen.pop();
1152 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
1153 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1154 }
1155 }
1156
1157 #[test]
1158 fn test_sphere3hopf_pop() {
1159 let mut sp3hgen = Sphere3Hopf::new([2, 3, 5]);
1160 sp3hgen.reseed(0);
1161 let res = sp3hgen.pop();
1162
1163 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2] + res[3] * res[3];
1165 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1166
1167 for _ in 0..5 {
1169 let res = sp3hgen.pop();
1170 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2] + res[3] * res[3];
1171 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1172 }
1173 }
1174
1175 #[test]
1176 fn test_haltonn_pop() {
1177 let mut hgen = HaltonN::new(&[2, 3, 5]);
1178 hgen.reseed(0);
1179 let res = hgen.pop();
1180
1181 assert_eq!(res[0], 0.5);
1182 assert_relative_eq!(res[1], 1.0 / 3.0, epsilon = 1e-10);
1183 assert_relative_eq!(res[2], 0.2, epsilon = 1e-10);
1184
1185 let res = hgen.pop();
1186 assert_eq!(res[0], 0.25);
1187 assert_relative_eq!(res[1], 2.0 / 3.0, epsilon = 1e-10);
1188 assert_relative_eq!(res[2], 0.4, epsilon = 1e-10);
1189 }
1190
1191 #[test]
1192 fn test_prime_table() {
1193 assert_eq!(PRIME_TABLE[0], 2);
1195 assert_eq!(PRIME_TABLE[1], 3);
1196 assert_eq!(PRIME_TABLE[2], 5);
1197 assert_eq!(PRIME_TABLE[3], 7);
1198 assert_eq!(PRIME_TABLE[4], 11);
1199
1200 assert_eq!(PRIME_TABLE.len(), 1000);
1202
1203 assert_eq!(PRIME_TABLE[999], 7919);
1205 }
1206
1207 #[test]
1210 fn test_vdc_function_edge_cases() {
1211 assert_eq!(vdc(0, 2), 0.0);
1213 assert_eq!(vdc(0, 3), 0.0);
1214 assert_eq!(vdc(0, 5), 0.0);
1215
1216 assert_eq!(vdc(1, 2), 0.5);
1218 assert_eq!(vdc(1, 3), 1.0 / 3.0);
1219 assert_eq!(vdc(1, 5), 0.2);
1220
1221 assert_eq!(vdc(10, 2), 0.3125); assert_eq!(vdc(10, 3), 0.37037037037037035); assert_eq!(vdc(10, 5), 0.08); let result = vdc(1000, 2);
1228 assert!((0.0..1.0).contains(&result));
1229
1230 assert_eq!(vdc(6, 7), 6.0 / 7.0);
1232 assert_eq!(vdc(12, 11), 0.09917355371900827);
1233 }
1234
1235 #[test]
1236 fn test_vdcorput_different_bases() {
1237 let mut vgen = VdCorput::new(3);
1239 vgen.reseed(0);
1240 assert_relative_eq!(vgen.pop(), 1.0 / 3.0, epsilon = 1e-10);
1241 assert_relative_eq!(vgen.pop(), 2.0 / 3.0, epsilon = 1e-10);
1242 assert_relative_eq!(vgen.pop(), 1.0 / 9.0, epsilon = 1e-10);
1243
1244 let mut vgen = VdCorput::new(5);
1246 vgen.reseed(0);
1247 assert_relative_eq!(vgen.pop(), 0.2, epsilon = 1e-10);
1248 assert_relative_eq!(vgen.pop(), 0.4, epsilon = 1e-10);
1249 assert_relative_eq!(vgen.pop(), 0.6, epsilon = 1e-10);
1250 assert_relative_eq!(vgen.pop(), 0.8, epsilon = 1e-10);
1251 assert_relative_eq!(vgen.pop(), 0.04, epsilon = 1e-10);
1252
1253 let mut vgen = VdCorput::new(7);
1255 vgen.reseed(0);
1256 assert_relative_eq!(vgen.pop(), 1.0 / 7.0, epsilon = 1e-10);
1257 assert_relative_eq!(vgen.pop(), 2.0 / 7.0, epsilon = 1e-10);
1258 }
1259
1260 #[test]
1261 fn test_vdcorput_large_values() {
1262 let mut vgen = VdCorput::new(2);
1263 vgen.reseed(1000);
1264
1265 for _ in 0..10 {
1267 let value = vgen.pop();
1268 assert!((0.0..1.0).contains(&value));
1269 }
1270 }
1271
1272 #[test]
1273 fn test_halton_different_bases() {
1274 let mut hgen = Halton::new([3, 5]);
1276 hgen.reseed(0);
1277 let res = hgen.pop();
1278 assert_relative_eq!(res[0], 1.0 / 3.0, epsilon = 1e-10);
1279 assert_relative_eq!(res[1], 0.2, epsilon = 1e-10);
1280
1281 let mut hgen = Halton::new([5, 7]);
1283 hgen.reseed(0);
1284 let res = hgen.pop();
1285 assert_relative_eq!(res[0], 0.2, epsilon = 1e-10);
1286 assert_relative_eq!(res[1], 1.0 / 7.0, epsilon = 1e-10);
1287 }
1288
1289 #[test]
1290 fn test_circle_different_bases() {
1291 let mut cgen = Circle::new(3);
1293 cgen.reseed(0);
1294 let res = cgen.pop();
1295 let radius_sq = res[0] * res[0] + res[1] * res[1];
1297 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1298
1299 let mut cgen = Circle::new(5);
1301 cgen.reseed(0);
1302 let res = cgen.pop();
1303 let radius_sq = res[0] * res[0] + res[1] * res[1];
1304 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1305 }
1306
1307 #[test]
1308 fn test_disk_different_bases() {
1309 let mut dgen = Disk::new([3, 5]);
1311 dgen.reseed(0);
1312 let res = dgen.pop();
1313 let radius_sq = res[0] * res[0] + res[1] * res[1];
1314 assert!(radius_sq <= 1.0);
1315
1316 let mut dgen = Disk::new([5, 7]);
1318 dgen.reseed(0);
1319 let res = dgen.pop();
1320 let radius_sq = res[0] * res[0] + res[1] * res[1];
1321 assert!(radius_sq <= 1.0);
1322 }
1323
1324 #[test]
1325 fn test_sphere_different_bases() {
1326 let mut sgen = Sphere::new([3, 5]);
1328 sgen.reseed(0);
1329 let res = sgen.pop();
1330 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
1331 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1332
1333 let mut sgen = Sphere::new([5, 7]);
1335 sgen.reseed(0);
1336 let res = sgen.pop();
1337 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
1338 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1339 }
1340
1341 #[test]
1342 fn test_sphere3hopf_different_bases() {
1343 let mut sgen = Sphere3Hopf::new([3, 5, 7]);
1345 sgen.reseed(0);
1346 let res = sgen.pop();
1347 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2] + res[3] * res[3];
1348 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1349
1350 let mut sgen = Sphere3Hopf::new([5, 7, 11]);
1352 sgen.reseed(0);
1353 let res = sgen.pop();
1354 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2] + res[3] * res[3];
1355 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1356 }
1357
1358 #[test]
1359 fn test_haltonn_different_bases() {
1360 let mut hgen = HaltonN::new(&[3, 5, 7, 11]);
1362 hgen.reseed(0);
1363 let res = hgen.pop();
1364 assert_eq!(res.len(), 4);
1365 assert_relative_eq!(res[0], 1.0 / 3.0, epsilon = 1e-10);
1366 assert_relative_eq!(res[1], 0.2, epsilon = 1e-10);
1367 assert_relative_eq!(res[2], 1.0 / 7.0, epsilon = 1e-10);
1368 assert_relative_eq!(res[3], 1.0 / 11.0, epsilon = 1e-10);
1369
1370 let mut hgen = HaltonN::new(&[2, 3, 5, 7, 11]);
1372 hgen.reseed(0);
1373 let res = hgen.pop();
1374 assert_eq!(res.len(), 5);
1375 assert_relative_eq!(res[0], 0.5, epsilon = 1e-10);
1376 assert_relative_eq!(res[1], 1.0 / 3.0, epsilon = 1e-10);
1377 assert_relative_eq!(res[2], 0.2, epsilon = 1e-10);
1378 assert_relative_eq!(res[3], 1.0 / 7.0, epsilon = 1e-10);
1379 assert_relative_eq!(res[4], 1.0 / 11.0, epsilon = 1e-10);
1380 }
1381
1382 #[test]
1383 fn test_default_implementations() {
1384 let mut vgen = VdCorput::default();
1386 vgen.reseed(0);
1387 assert_eq!(vgen.pop(), 0.5);
1388
1389 let vgen_default = VdCorput::default();
1391 let vgen_explicit = VdCorput::new(2);
1392 assert_eq!(vgen_default.base, vgen_explicit.base);
1393 }
1394
1395 #[test]
1396 fn test_sequence_properties() {
1397 let mut vgen = VdCorput::new(2);
1399 for _ in 0..100 {
1400 let value = vgen.pop();
1401 assert!((0.0..1.0).contains(&value));
1402 }
1403
1404 let mut hgen = Halton::new([2, 3]);
1406 for _ in 0..100 {
1407 let res = hgen.pop();
1408 assert!(res[0] >= 0.0 && res[0] < 1.0);
1409 assert!(res[1] >= 0.0 && res[1] < 1.0);
1410 }
1411
1412 let mut cgen = Circle::new(2);
1414 for _ in 0..100 {
1415 let res = cgen.pop();
1416 let radius_sq = res[0] * res[0] + res[1] * res[1];
1417 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1418 }
1419
1420 let mut dgen = Disk::new([2, 3]);
1422 for _ in 0..100 {
1423 let res = dgen.pop();
1424 let radius_sq = res[0] * res[0] + res[1] * res[1];
1425 assert!(radius_sq <= 1.0);
1426 }
1427
1428 let mut sgen = Sphere::new([2, 3]);
1430 for _ in 0..100 {
1431 let res = sgen.pop();
1432 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
1433 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1434 }
1435
1436 let mut sgen = Sphere3Hopf::new([2, 3, 5]);
1438 for _ in 0..100 {
1439 let res = sgen.pop();
1440 let radius_sq = res.iter().map(|&x| x * x).sum::<f64>();
1441 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1442 }
1443 }
1444
1445 #[test]
1446 fn test_reseed_consistency() {
1447 let mut vgen = VdCorput::new(2);
1449
1450 vgen.reseed(10);
1451 let seq1: Vec<_> = (0..5).map(|_| vgen.pop()).collect();
1452
1453 vgen.reseed(10);
1454 let seq2: Vec<_> = (0..5).map(|_| vgen.pop()).collect();
1455
1456 for i in 0..5 {
1457 assert_relative_eq!(seq1[i], seq2[i], epsilon = 1e-10);
1458 }
1459
1460 vgen.reseed(10);
1462 let seq3: Vec<_> = (0..5).map(|_| vgen.pop()).collect();
1463
1464 vgen.reseed(20);
1465 let seq4: Vec<_> = (0..5).map(|_| vgen.pop()).collect();
1466
1467 let mut different = false;
1468 for i in 0..5 {
1469 if (seq3[i] - seq4[i]).abs() > 1e-10 {
1470 different = true;
1471 break;
1472 }
1473 }
1474 assert!(
1475 different,
1476 "Sequences with different seeds should be different"
1477 );
1478 }
1479
1480 #[test]
1481 fn test_vdcorput_peek() {
1482 let mut vgen = VdCorput::new(2);
1483 vgen.reseed(0);
1484 let peeked = vgen.peek();
1485 assert_relative_eq!(peeked, 0.5, epsilon = 1e-10);
1486 let popped = vgen.pop();
1487 assert_relative_eq!(popped, 0.5, epsilon = 1e-10); assert_relative_eq!(vgen.peek(), 0.25, epsilon = 1e-10);
1489 }
1490
1491 #[test]
1492 fn test_vdcorput_advance() {
1493 let mut vgen = VdCorput::new(2);
1494 vgen.reseed(0);
1495 vgen.advance(3);
1496 assert_relative_eq!(vgen.pop(), 0.125, epsilon = 1e-10);
1497 vgen.reseed(0);
1498 vgen.advance(4);
1499 assert_relative_eq!(vgen.pop(), 0.625, epsilon = 1e-10);
1501 }
1502
1503 #[test]
1504 fn test_vdcorput_get_index() {
1505 let mut vgen = VdCorput::new(2);
1506 assert_eq!(vgen.get_index(), 0);
1507 vgen.pop();
1508 assert_eq!(vgen.get_index(), 1);
1509 vgen.pop();
1510 assert_eq!(vgen.get_index(), 2);
1511 vgen.reseed(5);
1512 assert_eq!(vgen.get_index(), 5);
1513 }
1514
1515 #[test]
1516 fn test_halton_peek() {
1517 let mut hgen = Halton::new([2, 3]);
1518 hgen.reseed(0);
1519 let peeked = hgen.peek();
1520 assert_relative_eq!(peeked[0], 0.5, epsilon = 1e-10);
1521 assert_relative_eq!(peeked[1], 1.0 / 3.0, epsilon = 1e-10);
1522 let popped = hgen.pop();
1523 assert_relative_eq!(popped[0], 0.5, epsilon = 1e-10);
1524 assert_relative_eq!(popped[1], 1.0 / 3.0, epsilon = 1e-10);
1525 }
1526
1527 #[test]
1528 fn test_halton_advance() {
1529 let mut hgen = Halton::new([2, 3]);
1530 hgen.reseed(0);
1531 hgen.advance(2);
1532 let popped = hgen.pop();
1533 assert_relative_eq!(popped[0], 0.75, epsilon = 1e-10);
1534 assert_relative_eq!(popped[1], 1.0 / 9.0, epsilon = 1e-10);
1535 }
1536
1537 #[test]
1538 fn test_halton_iterator() {
1539 let mut hgen = Halton::new([2, 3]);
1540 hgen.reseed(0);
1541 let values: Vec<[f64; 2]> = hgen.take(3).collect();
1542 assert_eq!(values.len(), 3);
1543 assert_relative_eq!(values[0][0], 0.5, epsilon = 1e-10);
1544 assert_relative_eq!(values[0][1], 1.0 / 3.0, epsilon = 1e-10);
1545 assert_relative_eq!(values[1][0], 0.25, epsilon = 1e-10);
1546 assert_relative_eq!(values[1][1], 2.0 / 3.0, epsilon = 1e-10);
1547 }
1548
1549 #[test]
1550 fn test_circle_peek() {
1551 let mut cgen = Circle::new(2);
1552 cgen.reseed(0);
1553 let peeked = cgen.peek();
1554 let popped = cgen.pop();
1555 assert_relative_eq!(peeked[0], popped[0], epsilon = 1e-10);
1556 assert_relative_eq!(peeked[1], popped[1], epsilon = 1e-10);
1557 }
1558
1559 #[test]
1560 fn test_circle_advance() {
1561 let mut cgen = Circle::new(2);
1562 cgen.reseed(0);
1563 cgen.advance(5);
1564 let res = cgen.pop();
1565 let radius_sq = res[0] * res[0] + res[1] * res[1];
1566 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1567 }
1568
1569 #[test]
1570 fn test_circle_get_index() {
1571 let mut cgen = Circle::new(2);
1572 assert_eq!(cgen.get_index(), 0);
1573 cgen.pop();
1574 assert_eq!(cgen.get_index(), 1);
1575 }
1576
1577 #[test]
1578 fn test_disk_peek() {
1579 let mut dgen = Disk::new([2, 3]);
1580 dgen.reseed(0);
1581 let peeked = dgen.peek();
1582 let popped = dgen.pop();
1583 assert_relative_eq!(peeked[0], popped[0], epsilon = 1e-10);
1584 assert_relative_eq!(peeked[1], popped[1], epsilon = 1e-10);
1585 }
1586
1587 #[test]
1588 fn test_disk_advance() {
1589 let mut dgen = Disk::new([2, 3]);
1590 dgen.reseed(0);
1591 dgen.advance(5);
1592 let res = dgen.pop();
1593 let radius_sq = res[0] * res[0] + res[1] * res[1];
1594 assert!(radius_sq <= 1.0);
1595 }
1596
1597 #[test]
1598 fn test_sphere_peek() {
1599 let mut sgen = Sphere::new([2, 3]);
1600 sgen.reseed(0);
1601 let peeked = sgen.peek();
1602 let popped = sgen.pop();
1603 assert_relative_eq!(peeked[0], popped[0], epsilon = 1e-10);
1604 assert_relative_eq!(peeked[1], popped[1], epsilon = 1e-10);
1605 assert_relative_eq!(peeked[2], popped[2], epsilon = 1e-10);
1606 }
1607
1608 #[test]
1609 fn test_sphere_advance() {
1610 let mut sgen = Sphere::new([2, 3]);
1611 sgen.reseed(0);
1612 sgen.advance(5);
1613 let res = sgen.pop();
1614 let radius_sq = res[0] * res[0] + res[1] * res[1] + res[2] * res[2];
1615 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1616 }
1617
1618 #[test]
1619 fn test_sphere3hopf_peek() {
1620 let mut sgen = Sphere3Hopf::new([2, 3, 5]);
1621 sgen.reseed(0);
1622 let peeked = sgen.peek();
1623 let popped = sgen.pop();
1624 for i in 0..4 {
1625 assert_relative_eq!(peeked[i], popped[i], epsilon = 1e-10);
1626 }
1627 }
1628
1629 #[test]
1630 fn test_sphere3hopf_advance() {
1631 let mut sgen = Sphere3Hopf::new([2, 3, 5]);
1632 sgen.reseed(0);
1633 sgen.advance(5);
1634 let res = sgen.pop();
1635 let radius_sq = res.iter().map(|&x| x * x).sum::<f64>();
1636 assert_relative_eq!(radius_sq, 1.0, epsilon = 1e-10);
1637 }
1638
1639 #[test]
1640 fn test_sphere3hopf_get_index() {
1641 let mut sgen = Sphere3Hopf::new([2, 3, 5]);
1642 assert_eq!(sgen.get_index(), 0);
1643 sgen.pop();
1644 assert_eq!(sgen.get_index(), 1);
1645 }
1646
1647 #[test]
1648 fn test_halton_get_index() {
1649 let mut hgen = Halton::new([2, 3]);
1650 assert_eq!(hgen.get_index(), 0);
1651 hgen.pop();
1652 assert_eq!(hgen.get_index(), 1);
1653 }
1654
1655 #[test]
1656 fn test_circle_clone() {
1657 let mut cgen = Circle::new(2);
1658 cgen.reseed(5);
1659 let mut cloned = cgen.clone();
1660 assert_eq!(cloned.pop(), cgen.pop());
1661 }
1662
1663 #[test]
1664 fn test_disk_clone() {
1665 let mut dgen = Disk::new([2, 3]);
1666 dgen.reseed(5);
1667 let mut cloned = dgen.clone();
1668 assert_eq!(cloned.pop(), dgen.pop());
1669 }
1670
1671 #[test]
1672 fn test_sphere_clone() {
1673 let mut sgen = Sphere::new([2, 3]);
1674 sgen.reseed(5);
1675 let mut cloned = sgen.clone();
1676 assert_eq!(cloned.pop(), sgen.pop());
1677 }
1678
1679 #[test]
1680 fn test_sphere3hopf_clone() {
1681 let mut sgen = Sphere3Hopf::new([2, 3, 5]);
1682 sgen.reseed(5);
1683 let mut cloned = sgen.clone();
1684 assert_eq!(cloned.pop(), sgen.pop());
1685 }
1686
1687 #[test]
1688 fn test_haltonn_clone() {
1689 let mut hgen = HaltonN::new(&[2, 3, 5]);
1690 hgen.reseed(5);
1691 let mut cloned = hgen.clone();
1692 assert_eq!(cloned.pop(), hgen.pop());
1693 }
1694}