1pub mod core;
51pub mod seq;
52pub mod slice_ops;
53
54pub mod arrays;
56pub mod distributions;
57pub mod distributions_unified;
58
59pub mod qmc;
61pub mod variance_reduction;
62
63pub mod parallel;
65pub mod secure;
66
67pub mod ml;
69pub mod prelude;
70pub mod quick;
71pub mod scientific;
72
73pub mod advanced_numerical;
75pub mod cutting_edge_mcmc;
76pub mod ecosystem_integration;
77pub mod neural_sampling;
78pub mod quantum_inspired;
79
80pub use self::core::{seeded_rng, thread_rng, DistributionExt};
83
84pub use rand_chacha::{ChaCha12Rng, ChaCha20Rng, ChaCha8Rng};
86
87pub use self::core::Random as CoreRandom;
89
90pub use slice_ops::{ScientificSliceRandom, SliceRandomExt};
92
93pub use distributions::{
100 Beta, Categorical, Dirichlet, GammaDist, MultivariateNormal, VonMises, WeightedChoice,
101};
102
103pub use distributions_unified::{
105 UnifiedBeta, UnifiedBinomial, UnifiedCauchy, UnifiedChiSquared, UnifiedDirichlet,
106 UnifiedDistribution, UnifiedDistributionError, UnifiedExp, UnifiedFisherF, UnifiedGamma,
107 UnifiedLogNormal, UnifiedNormal, UnifiedPoisson, UnifiedStudentT, UnifiedWeibull,
108};
109
110pub use arrays::{
112 random_exponential_array, random_gamma_array, random_he_weights, random_normal_array,
113 random_sparse_array, random_uniform_array, random_xavier_weights, OptimizedArrayRandom,
114};
115
116pub use variance_reduction::{
118 AntitheticSampling, CommonRatio, ControlVariate, ImportanceSplitting,
119};
120
121pub use qmc::{
123 HaltonGenerator, LatinHypercubeSampler, LowDiscrepancySequence, QmcError, SobolGenerator,
124};
125
126pub use secure::{utils as secure_utils, SecureRandom, SecureRngPool};
128
129pub use parallel::{BatchRng, DistributedRngPool, ParallelRng, ThreadLocalRngPool};
131
132pub use advanced_numerical::{
134 AdaptiveResult, AdaptiveSampler, ImportanceResult, ImportanceSampler, MLMCResult,
135 MultiLevelMonteCarlo, SequentialMonteCarlo,
136};
137
138pub use cutting_edge_mcmc::{
139 EllipticalSliceSampler, HamiltonianMonteCarlo, NoUTurnSampler, ParallelTempering,
140 SteinVariationalGradientDescent,
141};
142
143pub use neural_sampling::{
144 DiffusionConfig, EnergyBasedModel, NeuralPosteriorEstimation, NormalizingFlow,
145 ScoreBasedDiffusion,
146};
147
148pub use quantum_inspired::{
149 CoinParameters, QuantumAmplitudeAmplification, QuantumInspiredAnnealing,
150 QuantumInspiredEvolutionary, QuantumWalk,
151};
152
153pub use ecosystem_integration::{
154 AugmentationConfig, ExperimentalDesign, LinalgBridge, NeuralBridge, OptimizationBridge,
155 StatsBridge, SyntheticDataset,
156};
157
158pub use ::ndarray::Dimension;
160pub use rand::prelude as rand_prelude;
161pub use rand::rngs;
162pub use rand::seq::SliceRandom;
163pub use rand::{Rng, RngCore, SeedableRng};
164pub use rand_distr as rand_distributions;
165pub use rand_distr::uniform;
166
167pub fn random<T>() -> T
188where
189 rand::distr::StandardUniform: rand::distr::Distribution<T>,
190{
191 rand::random()
192}
193
194pub fn rng() -> rand::rngs::ThreadRng {
209 rand::rng()
210}
211
212pub use rand_distr::{
215 Alphanumeric,
217 Bernoulli as RandBernoulli,
219 Beta as RandBeta,
221 Binomial,
222 Cauchy,
223 ChiSquared,
224 Dirichlet as RandDirichlet,
226 Distribution,
228 Exp,
229 FisherF,
230 Gamma as RandGamma,
231 Geometric,
232 Hypergeometric,
233 InverseGaussian,
234 LogNormal,
235 Normal as RandNormal,
236 Open01,
237 OpenClosed01,
238 Pareto,
239 Pert,
240 Poisson,
241 StandardNormal,
242 StudentT,
243 Triangular,
244 Uniform as RandUniform,
245 UnitBall,
246 UnitCircle,
247 UnitDisc,
248 UnitSphere,
249 Weibull,
250 Zeta,
251 Zipf,
252};
253
254pub use rand_distr::weighted::WeightedIndex;
256
257pub use rand_distr::Bernoulli;
260pub use rand_distr::Exp as Exponential; pub use rand_distr::Gamma;
262pub use rand_distr::Normal;
263pub use rand_distr::Uniform;
264
265#[cfg(feature = "random")]
267pub use ndarray_rand::RandomExt;
268
269#[cfg(not(feature = "random"))]
271pub trait RandomExt<T, D> {
272 fn random_using<R: rand::Rng>(
273 shape: D,
274 distribution: impl rand_distr::Distribution<T>,
275 rng: &mut R,
276 ) -> Self;
277}
278
279#[cfg(not(feature = "random"))]
280impl<T, D> RandomExt<T, D> for crate::ndarray::ArrayBase<crate::ndarray::OwnedRepr<T>, D>
281where
282 D: crate::ndarray::Dimension,
283{
284 fn random_using<R: rand::Rng>(
285 shape: D,
286 distribution: impl rand_distr::Distribution<T>,
287 rng: &mut R,
288 ) -> Self {
289 let size = shape.size();
290 let mut data = Vec::with_capacity(size);
291 for _ in 0..size {
292 data.push(distribution.sample(rng));
293 }
294 Self::from_shape_vec(shape, data).expect("Operation failed")
295 }
296}
297
298pub mod legacy {
300 use super::*;
301 use rand_distr::Uniform;
302
303 pub fn rng() -> Random<rand::rngs::ThreadRng> {
305 Random { rng: rand::rng() }
306 }
307
308 pub fn f64() -> f64 {
310 rand::random::<f64>()
311 }
312
313 pub fn f32() -> f32 {
315 rand::random::<f32>()
316 }
317
318 pub fn usize(range: std::ops::Range<usize>) -> usize {
320 rand::rng().random_range(range)
321 }
322}
323
324pub mod convenience {
326 use super::*;
327 use ::ndarray::{Array, Dimension, IxDyn};
328 use rand_distr::{Distribution, Normal, Uniform};
329
330 pub fn uniform() -> f64 {
332 let mut rng = thread_rng();
333 rng.sample(Uniform::new(0.0, 1.0).expect("Operation failed"))
334 }
335
336 pub fn normal() -> f64 {
338 let mut rng = thread_rng();
339 rng.sample(Normal::new(0.0, 1.0).expect("Operation failed"))
340 }
341
342 pub fn integer(min: i64, max: i64) -> i64 {
344 let mut rng = thread_rng();
345 rng.sample(Uniform::new_inclusive(min, max).expect("Operation failed"))
346 }
347
348 pub fn boolean() -> bool {
350 let mut rng = thread_rng();
351 rng.random_bool(0.5)
352 }
353
354 pub fn uniform_array<Sh: Into<IxDyn>>(shape: Sh) -> Array<f64, IxDyn> {
356 let mut rng = thread_rng();
357 let shape = shape.into();
358 let size = shape.size();
359 let values: Vec<f64> = (0..size)
360 .map(|_| rng.sample(Uniform::new(0.0, 1.0).expect("Operation failed")))
361 .collect();
362 Array::from_shape_vec(shape, values).expect("Operation failed")
363 }
364
365 pub fn normal_array<Sh: Into<IxDyn>>(shape: Sh, mean: f64, std: f64) -> Array<f64, IxDyn> {
367 let mut rng = thread_rng();
368 let shape = shape.into();
369 let size = shape.size();
370 let values: Vec<f64> = (0..size)
371 .map(|_| rng.sample(Normal::new(mean, std).expect("Operation failed")))
372 .collect();
373 Array::from_shape_vec(shape, values).expect("Operation failed")
374 }
375}
376
377pub mod sampling {
379 use super::*;
380 use ::ndarray::{Array, Dimension, IxDyn};
381 use rand_distr::{Distribution, Exp, LogNormal, Normal, Uniform};
382
383 pub fn random_uniform01<R: rand::Rng>(rng: &mut Random<R>) -> f64 {
385 rng.sample(Uniform::new(0.0, 1.0).expect("Operation failed"))
386 }
387
388 pub fn random_standard_normal<R: rand::Rng>(rng: &mut Random<R>) -> f64 {
390 rng.sample(Normal::new(0.0, 1.0).expect("Operation failed"))
391 }
392
393 pub fn random_normal<R: rand::Rng>(rng: &mut Random<R>, mean: f64, stddev: f64) -> f64 {
395 rng.sample(Normal::new(mean, stddev).expect("Operation failed"))
396 }
397
398 pub fn random_lognormal<R: rand::Rng>(rng: &mut Random<R>, mean: f64, stddev: f64) -> f64 {
400 rng.sample(LogNormal::new(mean, stddev).expect("Operation failed"))
401 }
402
403 pub fn random_exponential<R: rand::Rng>(rng: &mut Random<R>, lambda: f64) -> f64 {
405 rng.sample(Exp::new(lambda).expect("Operation failed"))
406 }
407
408 pub fn random_integers<R: rand::Rng, Sh>(
410 rng: &mut Random<R>,
411 min: i64,
412 max: i64,
413 shape: Sh,
414 ) -> Array<i64, IxDyn>
415 where
416 Sh: Into<IxDyn>,
417 {
418 rng.sample_array(
419 Uniform::new_inclusive(min, max).expect("Operation failed"),
420 shape,
421 )
422 }
423
424 pub fn random_floats<R: rand::Rng, Sh>(
426 rng: &mut Random<R>,
427 min: f64,
428 max: f64,
429 shape: Sh,
430 ) -> Array<f64, IxDyn>
431 where
432 Sh: Into<IxDyn>,
433 {
434 rng.sample_array(Uniform::new(min, max).expect("Operation failed"), shape)
435 }
436
437 pub fn bootstrap_indices<R: rand::Rng>(
439 rng: &mut Random<R>,
440 data_size: usize,
441 sample_size: usize,
442 ) -> Vec<usize> {
443 let dist = Uniform::new(0, data_size).expect("Operation failed");
444 rng.sample_vec(dist, sample_size)
445 }
446
447 pub fn sample_without_replacement<R: rand::Rng>(
449 rng: &mut Random<R>,
450 data_size: usize,
451 sample_size: usize,
452 ) -> Vec<usize> {
453 use rand::seq::SliceRandom;
454 let mut indices: Vec<usize> = (0..data_size).collect();
455 indices.shuffle(&mut rng.rng);
456 indices.truncate(sample_size);
457 indices
458 }
459}
460
461pub mod importance_sampling {
463 use super::*;
464 use rand_distr::{Normal, Uniform};
465
466 #[derive(Debug)]
468 pub struct ImportanceSampler<R: rand::Rng> {
469 rng: Random<R>,
470 }
471
472 impl<R: rand::Rng> ImportanceSampler<R> {
473 pub fn new(rng: Random<R>) -> Self {
475 Self { rng }
476 }
477
478 pub fn sample_with_weights<F, G>(
480 &mut self,
481 target_pdf: F,
482 proposal_pdf: G,
483 proposal_sampler: impl Fn(&mut Random<R>) -> f64,
484 n_samples: usize,
485 ) -> (Vec<f64>, Vec<f64>)
486 where
487 F: Fn(f64) -> f64,
488 G: Fn(f64) -> f64,
489 {
490 let mut samples = Vec::with_capacity(n_samples);
491 let mut weights = Vec::with_capacity(n_samples);
492
493 for _ in 0..n_samples {
494 let sample = proposal_sampler(&mut self.rng);
495 let weight = target_pdf(sample) / proposal_pdf(sample);
496
497 samples.push(sample);
498 weights.push(weight);
499 }
500
501 (samples, weights)
502 }
503
504 pub fn estimate_expectation<F, G, H>(
506 &mut self,
507 function: F,
508 target_pdf: G,
509 proposal_pdf: H,
510 proposal_sampler: impl Fn(&mut Random<R>) -> f64,
511 n_samples: usize,
512 ) -> f64
513 where
514 F: Fn(f64) -> f64,
515 G: Fn(f64) -> f64,
516 H: Fn(f64) -> f64,
517 {
518 let (samples, weights) =
519 self.sample_with_weights(target_pdf, proposal_pdf, proposal_sampler, n_samples);
520
521 let weighted_sum: f64 = samples
522 .iter()
523 .zip(weights.iter())
524 .map(|(&x, &w)| function(x) * w)
525 .sum();
526
527 let weight_sum: f64 = weights.iter().sum();
528
529 weighted_sum / weight_sum
530 }
531
532 pub fn adaptive_sampling<F>(
534 &mut self,
535 target_log_pdf: F,
536 initial_samples: usize,
537 adaptation_rounds: usize,
538 ) -> Vec<f64>
539 where
540 F: Fn(f64) -> f64,
541 {
542 let mut samples = Vec::new();
543 let mut proposal_mean: f64 = 0.0;
544 let mut proposal_std: f64 = 1.0;
545
546 for round in 0..adaptation_rounds {
547 let round_samples = if round == 0 {
548 initial_samples
549 } else {
550 initial_samples / 2
551 };
552 let normal_dist =
553 Normal::new(proposal_mean, proposal_std).expect("Operation failed");
554
555 let mut round_sample_vec = Vec::new();
556 let mut weights = Vec::new();
557
558 for _ in 0..round_samples {
559 let sample = self.rng.sample(normal_dist);
560
561 let normal_log_pdf = -0.5 * ((sample - proposal_mean) / proposal_std).powi(2)
563 - 0.5 * (2.0 * std::f64::consts::PI).ln()
564 - proposal_std.ln();
565 let log_weight = target_log_pdf(sample) - normal_log_pdf;
566
567 round_sample_vec.push(sample);
568 weights.push(log_weight.exp());
569 }
570
571 let weight_sum: f64 = weights.iter().sum();
573 if weight_sum > 0.0 {
574 let normalized_weights: Vec<f64> =
575 weights.iter().map(|w| w / weight_sum).collect();
576
577 proposal_mean = round_sample_vec
578 .iter()
579 .zip(normalized_weights.iter())
580 .map(|(&x, &w)| x * w)
581 .sum();
582
583 let variance = round_sample_vec
584 .iter()
585 .zip(normalized_weights.iter())
586 .map(|(&x, &w)| w * (x - proposal_mean).powi(2))
587 .sum::<f64>();
588
589 proposal_std = variance.sqrt().max(0.1); }
591
592 samples.extend(round_sample_vec);
593 }
594
595 samples
596 }
597 }
598
599 impl ImportanceSampler<rand::rngs::ThreadRng> {
600 pub fn with_default_rng() -> Self {
602 Self::new(Random::default())
603 }
604 }
605}
606
607#[cfg(feature = "gpu")]
609pub mod gpu {
610 pub struct GpuRng;
613
614 impl Default for GpuRng {
615 fn default() -> Self {
616 Self::new()
617 }
618 }
619
620 impl GpuRng {
621 pub fn new() -> Self {
622 Self
623 }
624 }
625}
626
627#[derive(Debug)]
631pub struct Random<R: rand::Rng + ?Sized = rand::rngs::ThreadRng> {
632 pub(crate) rng: R,
633}
634
635impl Default for Random<rand::rngs::ThreadRng> {
636 fn default() -> Self {
637 Self { rng: rand::rng() }
638 }
639}
640
641impl<R: rand::Rng + Clone> Clone for Random<R> {
642 fn clone(&self) -> Self {
643 Self {
644 rng: self.rng.clone(),
645 }
646 }
647}
648
649impl<R: rand::Rng> Random<R> {
650 pub fn sample<D, T>(&mut self, distribution: D) -> T
652 where
653 D: rand_distr::Distribution<T>,
654 {
655 use rand_distr::Distribution;
656 distribution.sample(&mut self.rng)
657 }
658
659 pub fn random_range_bounds<T: rand_distr::uniform::SampleUniform + PartialOrd + Copy>(
661 &mut self,
662 min: T,
663 max: T,
664 ) -> T {
665 self.sample(rand_distr::Uniform::new(min, max).expect("Operation failed"))
666 }
667
668 pub fn gen_range<T, RNG>(&mut self, range: RNG) -> T
670 where
671 T: rand_distr::uniform::SampleUniform,
672 RNG: rand_distr::uniform::SampleRange<T>,
673 {
674 rand::Rng::random_range(&mut self.rng, range)
675 }
676
677 pub fn random_range<T, RNG>(&mut self, range: RNG) -> T
679 where
680 T: rand_distr::uniform::SampleUniform,
681 RNG: rand_distr::uniform::SampleRange<T>,
682 {
683 rand::Rng::random_range(&mut self.rng, range)
684 }
685
686 pub fn random_f64(&mut self) -> f64 {
688 self.sample(rand_distr::Uniform::new(0.0, 1.0).expect("Operation failed"))
689 }
690
691 pub fn random_f64_raw(&mut self) -> f64 {
693 rand::Rng::random(&mut self.rng)
694 }
695
696 pub fn random_bool(&mut self) -> bool {
698 use rand_distr::Distribution;
699 let dist = rand_distr::Bernoulli::new(0.5).expect("Operation failed");
700 dist.sample(&mut self.rng)
701 }
702
703 pub fn random_bool_with_chance(&mut self, prob: f64) -> bool {
705 use rand_distr::Distribution;
706 let dist = rand_distr::Bernoulli::new(prob).expect("Operation failed");
707 dist.sample(&mut self.rng)
708 }
709
710 pub fn shuffle<T>(&mut self, slice: &mut [T]) {
712 use rand::seq::SliceRandom;
713 slice.shuffle(&mut self.rng);
714 }
715
716 pub fn sample_vec<D, T>(&mut self, distribution: D, size: usize) -> Vec<T>
718 where
719 D: rand_distr::Distribution<T> + Copy,
720 {
721 (0..size)
722 .map(|_| distribution.sample(&mut self.rng))
723 .collect()
724 }
725
726 pub fn sample_array<D, T, Sh>(
728 &mut self,
729 distribution: D,
730 shape: Sh,
731 ) -> crate::ndarray::Array<T, crate::ndarray::IxDyn>
732 where
733 D: rand_distr::Distribution<T> + Copy,
734 Sh: Into<crate::ndarray::IxDyn>,
735 {
736 let shape = shape.into();
737 let size = shape.size();
738 let values = self.sample_vec(distribution, size);
739 crate::ndarray::Array::from_shape_vec(shape, values).expect("Operation failed")
740 }
741}
742
743impl Random<rand::rngs::ThreadRng> {
744 pub fn seed(seed: u64) -> Random<rand::rngs::StdRng> {
746 Random {
747 rng: rand::SeedableRng::seed_from_u64(seed),
748 }
749 }
750}
751
752impl<R: rand::RngCore> rand::RngCore for Random<R> {
754 fn next_u32(&mut self) -> u32 {
755 self.rng.next_u32()
756 }
757
758 fn next_u64(&mut self) -> u64 {
759 self.rng.next_u64()
760 }
761
762 fn fill_bytes(&mut self, dest: &mut [u8]) {
763 self.rng.fill_bytes(dest)
764 }
765}
766
767impl rand::SeedableRng for Random<rand::rngs::StdRng> {
768 type Seed = <rand::rngs::StdRng as rand::SeedableRng>::Seed;
769
770 fn from_seed(seed: Self::Seed) -> Self {
771 Random {
772 rng: rand::rngs::StdRng::from_seed(seed),
773 }
774 }
775
776 fn seed_from_u64(state: u64) -> Self {
777 Random {
778 rng: rand::rngs::StdRng::seed_from_u64(state),
779 }
780 }
781}
782
783use std::cell::RefCell;
785thread_local! {
786 static THREAD_RNG: RefCell<Random> = RefCell::new(Random::default());
787}
788
789#[allow(dead_code)]
791pub fn get_rng<F, R>(f: F) -> R
792where
793 F: FnOnce(&mut Random) -> R,
794{
795 THREAD_RNG.with(|rng| f(&mut rng.borrow_mut()))
796}
797
798pub struct DeterministicSequence {
800 seed: u64,
801 counter: u64,
802}
803
804impl DeterministicSequence {
805 pub fn seed(seed: u64) -> Self {
807 Self { seed, counter: 0 }
808 }
809
810 pub fn next_f64(&mut self) -> f64 {
812 let mut x = self.counter.wrapping_add(self.seed);
814 x = ((x >> 16) ^ x).wrapping_mul(0x45d9f3b);
815 x = ((x >> 16) ^ x).wrapping_mul(0x45d9f3b);
816 x = (x >> 16) ^ x;
817
818 self.counter = self.counter.wrapping_add(1);
819
820 (x as f64) / (u64::MAX as f64)
822 }
823
824 pub fn reset(&mut self) {
826 self.counter = 0;
827 }
828
829 pub fn get_vec(&mut self, size: usize) -> Vec<f64> {
831 (0..size).map(|_| self.next_f64()).collect()
832 }
833
834 pub fn get_array<Sh>(&mut self, shape: Sh) -> crate::ndarray::Array<f64, crate::ndarray::IxDyn>
836 where
837 Sh: Into<crate::ndarray::IxDyn>,
838 {
839 let shape = shape.into();
840 let size = shape.size();
841 let values = self.get_vec(size);
842 crate::ndarray::Array::from_shape_vec(shape, values).expect("Operation failed")
843 }
844}
845
846pub type ThreadRng = Random<rand::rngs::ThreadRng>;
852pub type StdRng = Random<rand::rngs::StdRng>;
853
854pub type UniformDist = rand_distributions::Uniform<f64>;
856pub type NormalDist = rand_distributions::Normal<f64>;
857pub type ExponentialDist = rand_distributions::Exp<f64>;
858
859pub type Array1D<T> = crate::ndarray::Array1<T>;
861pub type Array2D<T> = crate::ndarray::Array2<T>;
862pub type Array3D<T> = crate::ndarray::Array3<T>;
863
864pub use quick as rapid;
870
871pub use scientific as research;
873
874pub use ml as machine_learning;
876
877pub use secure as crypto;
879
880pub mod quasi_monte_carlo {
886 pub use crate::random::qmc::*;
887
888 pub type SobolSequence = crate::random::qmc::SobolGenerator;
890 pub type HaltonSequence = crate::random::qmc::HaltonGenerator;
891 pub type LatinHypercubeSampling = crate::random::qmc::LatinHypercubeSampler;
892}
893
894pub mod specialized_distributions {
896 pub use crate::random::distributions::*;
897}
898
899pub mod optimized_arrays {
901 pub use crate::random::arrays::*;
902}
903
904pub mod slice_random {
906 pub use crate::random::slice_ops::convenience::*;
907}
908
909pub mod essentials {
915 pub use crate::random::rand_distributions::{Normal, Uniform};
916 pub use crate::random::{
917 random_normal_array, random_uniform_array, seeded_rng, thread_rng, Beta, Categorical,
918 Random, Rng, RngCore, SeedableRng, WeightedChoice,
919 };
920}
921
922pub mod statistics {
924 pub use crate::random::{
925 AntitheticSampling, Beta, Categorical, CommonRatio, ControlVariate, Dirichlet,
926 ExponentialDist, GammaDist, HaltonGenerator, LatinHypercubeSampler, MultivariateNormal,
927 SobolGenerator, VonMises, WeightedChoice,
928 };
929}
930
931pub mod hpc {
933 pub use crate::random::{
934 random_he_weights, random_normal_array, random_uniform_array, random_xavier_weights,
935 BatchRng, DistributedRngPool, OptimizedArrayRandom, ParallelRng, ThreadLocalRngPool,
936 };
937}
938
939pub mod cutting_edge {
941 pub use crate::random::{
942 advanced_numerical::*, cutting_edge_mcmc::*, ecosystem_integration::*, neural_sampling::*,
943 quantum_inspired::*,
944 };
945}
946
947pub mod bayesian {
949 pub use crate::random::{
950 EllipticalSliceSampler, HamiltonianMonteCarlo, ImportanceSampler, NoUTurnSampler,
951 ParallelTempering, SteinVariationalGradientDescent,
952 };
953 }
955
956pub mod ai_sampling {
958 pub use crate::random::{
959 DiffusionConfig, EnergyBasedModel, NeuralBridge, NeuralPosteriorEstimation,
960 NormalizingFlow, ScoreBasedDiffusion,
961 };
962}
963
964pub mod quantum {
966 pub use crate::random::{
967 CoinParameters, QuantumAmplitudeAmplification, QuantumInspiredAnnealing,
968 QuantumInspiredEvolutionary, QuantumWalk,
969 };
970}
971
972pub mod numerical_methods {
974 pub use crate::random::{
975 AdaptiveResult, AdaptiveSampler, ImportanceResult, MLMCResult, MultiLevelMonteCarlo,
976 SequentialMonteCarlo,
977 };
978}
979
980pub mod bridges {
982 pub use crate::random::{
983 AugmentationConfig, ExperimentalDesign, LinalgBridge, NeuralBridge, OptimizationBridge,
984 StatsBridge, SyntheticDataset,
985 };
986}