scirs2_core/random/
mod.rs

1//! Ultra-advanced random number generation for SCIRS2 ecosystem
2//!
3//! This module provides the most comprehensive and cutting-edge random number generation
4//! capabilities available, designed specifically for scientific computing, machine learning,
5//! and quantum-inspired algorithms with unparalleled features for reproducibility,
6//! performance, and specialized ultra-modern distributions.
7//!
8//! ## Quick Start
9//!
10//! ```rust
11//! // For quick prototyping - use the quick module
12//! use scirs2_core::random::quick::*;
13//! let x = random_f64();
14//! let data = random_vector(100); // Use smaller data for doc tests
15//!
16//! // For scientific computing - use the prelude
17//! use scirs2_core::random::prelude::*;
18//! let mut rng = thread_rng();
19//! let sample = rng.sample(Normal::new(0.0, 1.0).expect("Operation failed"));
20//! ```
21//!
22//! ## Module Organization
23//!
24//! ### 🚀 **Cutting-Edge Modules**
25//! - [`cutting_edge_mcmc`] - HMC, NUTS, SVGD, and advanced MCMC methods
26//! - [`neural_sampling`] - Normalizing flows, VAE, diffusion models
27//! - [`quantum_inspired`] - Quantum algorithms for classical computation
28//! - [`advanced_numerical`] - Multi-level Monte Carlo, adaptive sampling
29//! - [`ecosystem_integration`] - Seamless SCIRS2 module interoperability
30//!
31//! ### 🎯 **Workflow-Based Modules**
32//! - [`prelude`] - Most commonly used items (Rust idiom)
33//! - [`quick`] - Rapid prototyping with minimal setup
34//! - [`scientific`] - Research and scientific computing workflows
35//! - [`ml`] - Machine learning specific utilities
36//!
37//! ### âš¡ **Core Implementation Modules**
38//! - [`core`] - Core Random struct and fundamental operations
39//! - [`distributions`] - Advanced statistical distributions
40//! - [`arrays`] - Optimized bulk array generation
41//! - [`slice_ops`] - Enhanced slice operations and sampling
42//!
43//! ### 🔬 **Specialized Modules**
44//! - [`qmc`] - Quasi-Monte Carlo sequences (Sobol, Halton, LHS)
45//! - [`variance_reduction`] - Monte Carlo variance reduction techniques
46//! - [`secure`] - Cryptographically secure random generation
47//! - [`parallel`] - Thread-safe parallel random generation
48
49// Core random functionality
50pub mod core;
51pub mod seq;
52pub mod slice_ops;
53
54// Advanced distributions and sampling
55pub mod arrays;
56pub mod distributions;
57pub mod distributions_unified;
58
59// Monte Carlo and variance reduction
60pub mod qmc;
61pub mod variance_reduction;
62
63// Security and parallel computing
64pub mod parallel;
65pub mod secure;
66
67// Enhanced workflow-based modules
68pub mod ml;
69pub mod prelude;
70pub mod quick;
71pub mod scientific;
72
73// Cutting-edge modules
74pub mod advanced_numerical;
75pub mod cutting_edge_mcmc;
76pub mod ecosystem_integration;
77pub mod neural_sampling;
78pub mod quantum_inspired;
79
80// Re-export core functionality (except Random which we redefine for compatibility)
81pub use core::{seeded_rng, thread_rng, DistributionExt};
82
83// Re-export RNG types for SCIRS2 POLICY compliance
84pub use rand_chacha::{ChaCha12Rng, ChaCha20Rng, ChaCha8Rng};
85
86// Re-export the core Random as CoreRandom for internal use
87pub use core::Random as CoreRandom;
88
89// Re-export enhanced slice operations
90pub use slice_ops::{ScientificSliceRandom, SliceRandomExt};
91
92// Note: seq module is available as scirs2_core::random::seq
93
94// Re-export slice convenience functions under different name to avoid conflict
95// pub use slice_ops::convenience as slice_convenience;
96
97// Re-export specialized distributions
98pub use distributions::{
99    Beta, Categorical, Dirichlet, GammaDist, MultivariateNormal, VonMises, WeightedChoice,
100};
101
102// Re-export unified distribution interface for ecosystem compatibility
103pub use distributions_unified::{
104    UnifiedBeta, UnifiedBinomial, UnifiedCauchy, UnifiedChiSquared, UnifiedDirichlet,
105    UnifiedDistribution, UnifiedDistributionError, UnifiedExp, UnifiedFisherF, UnifiedGamma,
106    UnifiedLogNormal, UnifiedNormal, UnifiedPoisson, UnifiedStudentT, UnifiedWeibull,
107};
108
109// Re-export optimized array operations
110pub use arrays::{
111    random_exponential_array, random_gamma_array, random_he_weights, random_normal_array,
112    random_sparse_array, random_uniform_array, random_xavier_weights, OptimizedArrayRandom,
113};
114
115// Re-export variance reduction techniques
116pub use variance_reduction::{
117    AntitheticSampling, CommonRatio, ControlVariate, ImportanceSplitting,
118};
119
120// Re-export QMC sequences
121pub use qmc::{
122    HaltonGenerator, LatinHypercubeSampler, LowDiscrepancySequence, QmcError, SobolGenerator,
123};
124
125// Re-export secure random generation
126pub use secure::{utils as secure_utils, SecureRandom, SecureRngPool};
127
128// Re-export parallel operations
129pub use parallel::{BatchRng, DistributedRngPool, ParallelRng, ThreadLocalRngPool};
130
131// Re-export cutting-edge algorithms
132pub use advanced_numerical::{
133    AdaptiveResult, AdaptiveSampler, ImportanceResult, ImportanceSampler, MLMCResult,
134    MultiLevelMonteCarlo, SequentialMonteCarlo,
135};
136
137pub use cutting_edge_mcmc::{
138    EllipticalSliceSampler, HamiltonianMonteCarlo, NoUTurnSampler, ParallelTempering,
139    SteinVariationalGradientDescent,
140};
141
142pub use neural_sampling::{
143    DiffusionConfig, EnergyBasedModel, NeuralPosteriorEstimation, NormalizingFlow,
144    ScoreBasedDiffusion,
145};
146
147pub use quantum_inspired::{
148    CoinParameters, QuantumAmplitudeAmplification, QuantumInspiredAnnealing,
149    QuantumInspiredEvolutionary, QuantumWalk,
150};
151
152pub use ecosystem_integration::{
153    AugmentationConfig, ExperimentalDesign, LinalgBridge, NeuralBridge, OptimizationBridge,
154    StatsBridge, SyntheticDataset,
155};
156
157// Re-export external dependencies for convenience
158pub use ::ndarray::Dimension;
159pub use rand::prelude as rand_prelude;
160pub use rand::rngs;
161pub use rand::seq::SliceRandom;
162pub use rand::{Rng, RngCore, SeedableRng};
163pub use rand_distr as rand_distributions;
164pub use rand_distr::uniform;
165
166/// Convenience function to generate a random value of the inferred type
167///
168/// This function generates a random value using the thread-local RNG.
169/// The type is inferred from context, or can be specified explicitly.
170///
171/// # Examples
172///
173/// ```
174/// use scirs2_core::random::random;
175///
176/// // Generate random f64
177/// let x: f64 = random();
178/// assert!(x >= 0.0 && x < 1.0);
179///
180/// // Generate random bool
181/// let b: bool = random();
182///
183/// // Explicit type annotation
184/// let y = random::<f32>();
185/// ```
186pub fn random<T>() -> T
187where
188    rand::distr::StandardUniform: rand::distr::Distribution<T>,
189{
190    rand::random()
191}
192
193/// Convenience function to create a thread-local RNG
194///
195/// This is equivalent to `thread_rng()` but provides a shorter name
196/// for compatibility with code that uses `rng()`.
197///
198/// # Examples
199///
200/// ```
201/// use scirs2_core::random::rng;
202/// use scirs2_core::random::Rng;
203///
204/// let mut rng = rng();
205/// let x: f64 = rng.random();
206/// ```
207pub fn rng() -> rand::rngs::ThreadRng {
208    rand::rng()
209}
210
211// Comprehensive re-export of ALL rand_distr distributions for SciRS2 ecosystem compatibility
212// This ensures other projects can access any distribution through scirs2-core
213pub use rand_distr::{
214    // Other distributions
215    Alphanumeric,
216    // Discrete distributions
217    Bernoulli as RandBernoulli,
218    // Continuous distributions
219    Beta as RandBeta,
220    Binomial,
221    Cauchy,
222    ChiSquared,
223    // Multivariate distributions
224    Dirichlet as RandDirichlet,
225    // Distribution trait
226    Distribution,
227    Exp,
228    FisherF,
229    Gamma as RandGamma,
230    Geometric,
231    Hypergeometric,
232    InverseGaussian,
233    LogNormal,
234    Normal as RandNormal,
235    Open01,
236    OpenClosed01,
237    Pareto,
238    Pert,
239    Poisson,
240    StandardNormal,
241    StudentT,
242    Triangular,
243    Uniform as RandUniform,
244    UnitBall,
245    UnitCircle,
246    UnitDisc,
247    UnitSphere,
248    Weibull,
249    Zeta,
250    Zipf,
251};
252
253// Re-export WeightedIndex from weighted submodule
254pub use rand_distr::weighted::WeightedIndex;
255
256// Clean, unprefixed type aliases for common distributions (for easier use)
257// These allow `use scirs2_core::random::Normal;` instead of `use scirs2_core::random::RandNormal;`
258pub use rand_distr::Bernoulli;
259pub use rand_distr::Exp as Exponential; // Exponential is just Exp in rand_distr
260pub use rand_distr::Gamma;
261pub use rand_distr::Normal;
262pub use rand_distr::Uniform;
263
264// Re-export ndarray-rand RandomExt trait if available
265#[cfg(feature = "random")]
266pub use ndarray_rand::RandomExt;
267
268// Compatibility layer for systems without random feature
269#[cfg(not(feature = "random"))]
270pub trait RandomExt<T, D> {
271    fn random_using<R: rand::Rng>(
272        shape: D,
273        distribution: impl rand_distr::Distribution<T>,
274        rng: &mut R,
275    ) -> Self;
276}
277
278#[cfg(not(feature = "random"))]
279impl<T, D> RandomExt<T, D> for crate::ndarray::ArrayBase<crate::ndarray::OwnedRepr<T>, D>
280where
281    D: crate::ndarray::Dimension,
282{
283    fn random_using<R: rand::Rng>(
284        shape: D,
285        distribution: impl rand_distr::Distribution<T>,
286        rng: &mut R,
287    ) -> Self {
288        let size = shape.size();
289        let mut data = Vec::with_capacity(size);
290        for _ in 0..size {
291            data.push(distribution.sample(rng));
292        }
293        Self::from_shape_vec(shape, data).expect("Operation failed")
294    }
295}
296
297/// Legacy compatibility functions for backward compatibility
298pub mod legacy {
299    use super::*;
300    use rand_distr::Uniform;
301
302    /// Compatibility wrapper for updated rand API
303    pub fn rng() -> Random<rand::rngs::ThreadRng> {
304        Random { rng: rand::rng() }
305    }
306
307    /// Generate a random f64 value between 0.0 and 1.0
308    pub fn f64() -> f64 {
309        rand::random::<f64>()
310    }
311
312    /// Generate a random f32 value between 0.0 and 1.0
313    pub fn f32() -> f32 {
314        rand::random::<f32>()
315    }
316
317    /// Generate a random usize value in the given range
318    pub fn usize(range: std::ops::Range<usize>) -> usize {
319        rand::rng().random_range(range)
320    }
321}
322
323/// High-level convenience functions for common operations
324pub mod convenience {
325    use super::*;
326    use ::ndarray::{Array, Dimension, IxDyn};
327    use rand_distr::{Distribution, Normal, Uniform};
328
329    /// Generate a uniform random number in [0, 1)
330    pub fn uniform() -> f64 {
331        let mut rng = thread_rng();
332        rng.sample(Uniform::new(0.0, 1.0).expect("Operation failed"))
333    }
334
335    /// Generate a standard normal random number (mean=0, std=1)
336    pub fn normal() -> f64 {
337        let mut rng = thread_rng();
338        rng.sample(Normal::new(0.0, 1.0).expect("Operation failed"))
339    }
340
341    /// Generate a random integer in the given range
342    pub fn integer(min: i64, max: i64) -> i64 {
343        let mut rng = thread_rng();
344        rng.sample(Uniform::new_inclusive(min, max).expect("Operation failed"))
345    }
346
347    /// Generate a random boolean
348    pub fn boolean() -> bool {
349        let mut rng = thread_rng();
350        rng.random_bool(0.5)
351    }
352
353    /// Generate a random array with uniform distribution
354    pub fn uniform_array<Sh: Into<IxDyn>>(shape: Sh) -> Array<f64, IxDyn> {
355        let mut rng = thread_rng();
356        let shape = shape.into();
357        let size = shape.size();
358        let values: Vec<f64> = (0..size)
359            .map(|_| rng.sample(Uniform::new(0.0, 1.0).expect("Operation failed")))
360            .collect();
361        Array::from_shape_vec(shape, values).expect("Operation failed")
362    }
363
364    /// Generate a random array with normal distribution
365    pub fn normal_array<Sh: Into<IxDyn>>(shape: Sh, mean: f64, std: f64) -> Array<f64, IxDyn> {
366        let mut rng = thread_rng();
367        let shape = shape.into();
368        let size = shape.size();
369        let values: Vec<f64> = (0..size)
370            .map(|_| rng.sample(Normal::new(mean, std).expect("Operation failed")))
371            .collect();
372        Array::from_shape_vec(shape, values).expect("Operation failed")
373    }
374}
375
376/// Sampling utilities for common statistical operations
377pub mod sampling {
378    use super::*;
379    use ::ndarray::{Array, Dimension, IxDyn};
380    use rand_distr::{Distribution, Exp, LogNormal, Normal, Uniform};
381
382    /// Sample uniformly from [0, 1)
383    pub fn random_uniform01<R: rand::Rng>(rng: &mut Random<R>) -> f64 {
384        rng.sample(Uniform::new(0.0, 1.0).expect("Operation failed"))
385    }
386
387    /// Sample from a standard normal distribution (mean 0, std dev 1)
388    pub fn random_standard_normal<R: rand::Rng>(rng: &mut Random<R>) -> f64 {
389        rng.sample(Normal::new(0.0, 1.0).expect("Operation failed"))
390    }
391
392    /// Sample from a normal distribution with given mean and standard deviation
393    pub fn random_normal<R: rand::Rng>(rng: &mut Random<R>, mean: f64, stddev: f64) -> f64 {
394        rng.sample(Normal::new(mean, stddev).expect("Operation failed"))
395    }
396
397    /// Sample from a log-normal distribution
398    pub fn random_lognormal<R: rand::Rng>(rng: &mut Random<R>, mean: f64, stddev: f64) -> f64 {
399        rng.sample(LogNormal::new(mean, stddev).expect("Operation failed"))
400    }
401
402    /// Sample from an exponential distribution
403    pub fn random_exponential<R: rand::Rng>(rng: &mut Random<R>, lambda: f64) -> f64 {
404        rng.sample(Exp::new(lambda).expect("Operation failed"))
405    }
406
407    /// Generate an array of random integers in a range
408    pub fn random_integers<R: rand::Rng, Sh>(
409        rng: &mut Random<R>,
410        min: i64,
411        max: i64,
412        shape: Sh,
413    ) -> Array<i64, IxDyn>
414    where
415        Sh: Into<IxDyn>,
416    {
417        rng.sample_array(
418            Uniform::new_inclusive(min, max).expect("Operation failed"),
419            shape,
420        )
421    }
422
423    /// Generate an array of random floating-point values in a range
424    pub fn random_floats<R: rand::Rng, Sh>(
425        rng: &mut Random<R>,
426        min: f64,
427        max: f64,
428        shape: Sh,
429    ) -> Array<f64, IxDyn>
430    where
431        Sh: Into<IxDyn>,
432    {
433        rng.sample_array(Uniform::new(min, max).expect("Operation failed"), shape)
434    }
435
436    /// Sample indices for bootstrapping (sampling with replacement)
437    pub fn bootstrap_indices<R: rand::Rng>(
438        rng: &mut Random<R>,
439        data_size: usize,
440        sample_size: usize,
441    ) -> Vec<usize> {
442        let dist = Uniform::new(0, data_size).expect("Operation failed");
443        rng.sample_vec(dist, sample_size)
444    }
445
446    /// Sample indices without replacement (for random subsampling)
447    pub fn sample_without_replacement<R: rand::Rng>(
448        rng: &mut Random<R>,
449        data_size: usize,
450        sample_size: usize,
451    ) -> Vec<usize> {
452        use rand::seq::SliceRandom;
453        let mut indices: Vec<usize> = (0..data_size).collect();
454        indices.shuffle(&mut rng.rng);
455        indices.truncate(sample_size);
456        indices
457    }
458}
459
460/// Importance sampling methods for efficient estimation
461pub mod importance_sampling {
462    use super::*;
463    use rand_distr::{Normal, Uniform};
464
465    /// Importance sampling estimator
466    #[derive(Debug)]
467    pub struct ImportanceSampler<R: rand::Rng> {
468        rng: Random<R>,
469    }
470
471    impl<R: rand::Rng> ImportanceSampler<R> {
472        /// Create a new importance sampler
473        pub fn new(rng: Random<R>) -> Self {
474            Self { rng }
475        }
476
477        /// Perform importance sampling with a given proposal distribution
478        pub fn sample_with_weights<F, G>(
479            &mut self,
480            target_pdf: F,
481            proposal_pdf: G,
482            proposal_sampler: impl Fn(&mut Random<R>) -> f64,
483            n_samples: usize,
484        ) -> (Vec<f64>, Vec<f64>)
485        where
486            F: Fn(f64) -> f64,
487            G: Fn(f64) -> f64,
488        {
489            let mut samples = Vec::with_capacity(n_samples);
490            let mut weights = Vec::with_capacity(n_samples);
491
492            for _ in 0..n_samples {
493                let sample = proposal_sampler(&mut self.rng);
494                let weight = target_pdf(sample) / proposal_pdf(sample);
495
496                samples.push(sample);
497                weights.push(weight);
498            }
499
500            (samples, weights)
501        }
502
503        /// Estimate expectation using importance sampling
504        pub fn estimate_expectation<F, G, H>(
505            &mut self,
506            function: F,
507            target_pdf: G,
508            proposal_pdf: H,
509            proposal_sampler: impl Fn(&mut Random<R>) -> f64,
510            n_samples: usize,
511        ) -> f64
512        where
513            F: Fn(f64) -> f64,
514            G: Fn(f64) -> f64,
515            H: Fn(f64) -> f64,
516        {
517            let (samples, weights) =
518                self.sample_with_weights(target_pdf, proposal_pdf, proposal_sampler, n_samples);
519
520            let weighted_sum: f64 = samples
521                .iter()
522                .zip(weights.iter())
523                .map(|(&x, &w)| function(x) * w)
524                .sum();
525
526            let weight_sum: f64 = weights.iter().sum();
527
528            weighted_sum / weight_sum
529        }
530
531        /// Adaptive importance sampling with mixture proposal
532        pub fn adaptive_sampling<F>(
533            &mut self,
534            target_log_pdf: F,
535            initial_samples: usize,
536            adaptation_rounds: usize,
537        ) -> Vec<f64>
538        where
539            F: Fn(f64) -> f64,
540        {
541            let mut samples = Vec::new();
542            let mut proposal_mean: f64 = 0.0;
543            let mut proposal_std: f64 = 1.0;
544
545            for round in 0..adaptation_rounds {
546                let round_samples = if round == 0 {
547                    initial_samples
548                } else {
549                    initial_samples / 2
550                };
551                let normal_dist =
552                    Normal::new(proposal_mean, proposal_std).expect("Operation failed");
553
554                let mut round_sample_vec = Vec::new();
555                let mut weights = Vec::new();
556
557                for _ in 0..round_samples {
558                    let sample = self.rng.sample(normal_dist);
559
560                    // Manual calculation of log PDF for normal distribution
561                    let normal_log_pdf = -0.5 * ((sample - proposal_mean) / proposal_std).powi(2)
562                        - 0.5 * (2.0 * std::f64::consts::PI).ln()
563                        - proposal_std.ln();
564                    let log_weight = target_log_pdf(sample) - normal_log_pdf;
565
566                    round_sample_vec.push(sample);
567                    weights.push(log_weight.exp());
568                }
569
570                // Update proposal parameters based on weighted samples
571                let weight_sum: f64 = weights.iter().sum();
572                if weight_sum > 0.0 {
573                    let normalized_weights: Vec<f64> =
574                        weights.iter().map(|w| w / weight_sum).collect();
575
576                    proposal_mean = round_sample_vec
577                        .iter()
578                        .zip(normalized_weights.iter())
579                        .map(|(&x, &w)| x * w)
580                        .sum();
581
582                    let variance = round_sample_vec
583                        .iter()
584                        .zip(normalized_weights.iter())
585                        .map(|(&x, &w)| w * (x - proposal_mean).powi(2))
586                        .sum::<f64>();
587
588                    proposal_std = variance.sqrt().max(0.1); // Prevent collapse
589                }
590
591                samples.extend(round_sample_vec);
592            }
593
594            samples
595        }
596    }
597
598    impl ImportanceSampler<rand::rngs::ThreadRng> {
599        /// Create importance sampler with default RNG
600        pub fn with_default_rng() -> Self {
601            Self::new(Random::default())
602        }
603    }
604}
605
606/// GPU-accelerated random number generation (when available)
607#[cfg(feature = "gpu")]
608pub mod gpu {
609    // GPU acceleration implementation would go here
610    // This is a placeholder for future GPU support
611    pub struct GpuRng;
612
613    impl Default for GpuRng {
614        fn default() -> Self {
615            Self::new()
616        }
617    }
618
619    impl GpuRng {
620        pub fn new() -> Self {
621            Self
622        }
623    }
624}
625
626/// Legacy Random struct wrapper for backward compatibility
627/// This provides the same interface as the original Random struct
628/// while delegating to the new modular implementation
629#[derive(Debug)]
630pub struct Random<R: rand::Rng + ?Sized = rand::rngs::ThreadRng> {
631    pub(crate) rng: R,
632}
633
634impl Default for Random<rand::rngs::ThreadRng> {
635    fn default() -> Self {
636        Self { rng: rand::rng() }
637    }
638}
639
640impl<R: rand::Rng + Clone> Clone for Random<R> {
641    fn clone(&self) -> Self {
642        Self {
643            rng: self.rng.clone(),
644        }
645    }
646}
647
648impl<R: rand::Rng> Random<R> {
649    /// Sample a value from a distribution
650    pub fn sample<D, T>(&mut self, distribution: D) -> T
651    where
652        D: rand_distr::Distribution<T>,
653    {
654        use rand_distr::Distribution;
655        distribution.sample(&mut self.rng)
656    }
657
658    /// Generate a random value between two bounds (inclusive min, exclusive max)
659    pub fn random_range_bounds<T: rand_distr::uniform::SampleUniform + PartialOrd + Copy>(
660        &mut self,
661        min: T,
662        max: T,
663    ) -> T {
664        self.sample(rand_distr::Uniform::new(min, max).expect("Operation failed"))
665    }
666
667    /// Generate a random value within the given range (using range syntax)
668    pub fn gen_range<T, RNG>(&mut self, range: RNG) -> T
669    where
670        T: rand_distr::uniform::SampleUniform,
671        RNG: rand_distr::uniform::SampleRange<T>,
672    {
673        rand::Rng::random_range(&mut self.rng, range)
674    }
675
676    /// Generate a random value within the given range (rand-compatible range syntax)
677    pub fn random_range<T, RNG>(&mut self, range: RNG) -> T
678    where
679        T: rand_distr::uniform::SampleUniform,
680        RNG: rand_distr::uniform::SampleRange<T>,
681    {
682        rand::Rng::random_range(&mut self.rng, range)
683    }
684
685    /// Generate a random f64 value between 0.0 and 1.0
686    pub fn random_f64(&mut self) -> f64 {
687        self.sample(rand_distr::Uniform::new(0.0, 1.0).expect("Operation failed"))
688    }
689
690    /// Generate a random f64 value using the underlying RNG (convenience method)
691    pub fn random_f64_raw(&mut self) -> f64 {
692        rand::Rng::random(&mut self.rng)
693    }
694
695    /// Generate a random boolean value
696    pub fn random_bool(&mut self) -> bool {
697        use rand_distr::Distribution;
698        let dist = rand_distr::Bernoulli::new(0.5).expect("Operation failed");
699        dist.sample(&mut self.rng)
700    }
701
702    /// Generate a random boolean with the given probability of being true
703    pub fn random_bool_with_chance(&mut self, prob: f64) -> bool {
704        use rand_distr::Distribution;
705        let dist = rand_distr::Bernoulli::new(prob).expect("Operation failed");
706        dist.sample(&mut self.rng)
707    }
708
709    /// Shuffle a slice randomly
710    pub fn shuffle<T>(&mut self, slice: &mut [T]) {
711        use rand::seq::SliceRandom;
712        slice.shuffle(&mut self.rng);
713    }
714
715    /// Generate a vector of values sampled from a distribution
716    pub fn sample_vec<D, T>(&mut self, distribution: D, size: usize) -> Vec<T>
717    where
718        D: rand_distr::Distribution<T> + Copy,
719    {
720        (0..size)
721            .map(|_| distribution.sample(&mut self.rng))
722            .collect()
723    }
724
725    /// Generate an crate::ndarray::Array from samples of a distribution
726    pub fn sample_array<D, T, Sh>(
727        &mut self,
728        distribution: D,
729        shape: Sh,
730    ) -> crate::ndarray::Array<T, crate::ndarray::IxDyn>
731    where
732        D: rand_distr::Distribution<T> + Copy,
733        Sh: Into<crate::ndarray::IxDyn>,
734    {
735        let shape = shape.into();
736        let size = shape.size();
737        let values = self.sample_vec(distribution, size);
738        crate::ndarray::Array::from_shape_vec(shape, values).expect("Operation failed")
739    }
740}
741
742impl Random<rand::rngs::ThreadRng> {
743    /// Create a new random number generator with a specific seed
744    pub fn seed(seed: u64) -> Random<rand::rngs::StdRng> {
745        Random {
746            rng: rand::SeedableRng::seed_from_u64(seed),
747        }
748    }
749}
750
751// Implement required traits for the legacy Random struct
752impl<R: rand::RngCore> rand::RngCore for Random<R> {
753    fn next_u32(&mut self) -> u32 {
754        self.rng.next_u32()
755    }
756
757    fn next_u64(&mut self) -> u64 {
758        self.rng.next_u64()
759    }
760
761    fn fill_bytes(&mut self, dest: &mut [u8]) {
762        self.rng.fill_bytes(dest)
763    }
764}
765
766impl rand::SeedableRng for Random<rand::rngs::StdRng> {
767    type Seed = <rand::rngs::StdRng as rand::SeedableRng>::Seed;
768
769    fn from_seed(seed: Self::Seed) -> Self {
770        Random {
771            rng: rand::rngs::StdRng::from_seed(seed),
772        }
773    }
774
775    fn seed_from_u64(state: u64) -> Self {
776        Random {
777            rng: rand::rngs::StdRng::seed_from_u64(state),
778        }
779    }
780}
781
782/// Thread-local random number generator for convenient access (legacy compatibility)
783use std::cell::RefCell;
784thread_local! {
785    static THREAD_RNG: RefCell<Random> = RefCell::new(Random::default());
786}
787
788/// Get a reference to the thread-local random number generator (legacy compatibility)
789#[allow(dead_code)]
790pub fn get_rng<F, R>(f: F) -> R
791where
792    F: FnOnce(&mut Random) -> R,
793{
794    THREAD_RNG.with(|rng| f(&mut rng.borrow_mut()))
795}
796
797/// Deterministic random sequence generator for testing (legacy compatibility)
798pub struct DeterministicSequence {
799    seed: u64,
800    counter: u64,
801}
802
803impl DeterministicSequence {
804    /// Create a new deterministic sequence with the given seed
805    pub fn seed(seed: u64) -> Self {
806        Self { seed, counter: 0 }
807    }
808
809    /// Generate the next value in the sequence
810    pub fn next_f64(&mut self) -> f64 {
811        // Simple deterministic hash function for testing purposes
812        let mut x = self.counter.wrapping_add(self.seed);
813        x = ((x >> 16) ^ x).wrapping_mul(0x45d9f3b);
814        x = ((x >> 16) ^ x).wrapping_mul(0x45d9f3b);
815        x = (x >> 16) ^ x;
816
817        self.counter = self.counter.wrapping_add(1);
818
819        // Convert to f64 in [0, 1) range
820        (x as f64) / (u64::MAX as f64)
821    }
822
823    /// Reset the sequence to its initial state
824    pub fn reset(&mut self) {
825        self.counter = 0;
826    }
827
828    /// Get a vector of deterministic values
829    pub fn get_vec(&mut self, size: usize) -> Vec<f64> {
830        (0..size).map(|_| self.next_f64()).collect()
831    }
832
833    /// Get an crate::ndarray::Array of deterministic values
834    pub fn get_array<Sh>(&mut self, shape: Sh) -> crate::ndarray::Array<f64, crate::ndarray::IxDyn>
835    where
836        Sh: Into<crate::ndarray::IxDyn>,
837    {
838        let shape = shape.into();
839        let size = shape.size();
840        let values = self.get_vec(size);
841        crate::ndarray::Array::from_shape_vec(shape, values).expect("Operation failed")
842    }
843}
844
845// ===============================
846// Enhanced Type Aliases & Exports
847// ===============================
848
849/// Convenient type aliases for common RNG types
850pub type ThreadRng = Random<rand::rngs::ThreadRng>;
851pub type StdRng = Random<rand::rngs::StdRng>;
852
853/// Common distribution type aliases
854pub type UniformDist = rand_distributions::Uniform<f64>;
855pub type NormalDist = rand_distributions::Normal<f64>;
856pub type ExponentialDist = rand_distributions::Exp<f64>;
857
858/// Array type aliases for convenience
859pub type Array1D<T> = crate::ndarray::Array1<T>;
860pub type Array2D<T> = crate::ndarray::Array2<T>;
861pub type Array3D<T> = crate::ndarray::Array3<T>;
862
863// ===============================
864// Workflow Module Aliases
865// ===============================
866
867/// Alias for quick access to rapid prototyping functions
868pub use quick as rapid;
869
870/// Alias for scientific computing workflows
871pub use scientific as research;
872
873/// Alias for machine learning workflows
874pub use ml as machine_learning;
875
876/// Alias for cryptographic random generation
877pub use secure as crypto;
878
879// ===============================
880// Legacy Compatibility Modules
881// ===============================
882
883/// Legacy module structure for backward compatibility
884pub mod quasi_monte_carlo {
885    pub use crate::random::qmc::*;
886
887    // Legacy type aliases for backward compatibility
888    pub type SobolSequence = crate::random::qmc::SobolGenerator;
889    pub type HaltonSequence = crate::random::qmc::HaltonGenerator;
890    pub type LatinHypercubeSampling = crate::random::qmc::LatinHypercubeSampler;
891}
892
893/// Legacy module structure for backward compatibility
894pub mod specialized_distributions {
895    pub use crate::random::distributions::*;
896}
897
898/// Legacy module structure for backward compatibility
899pub mod optimized_arrays {
900    pub use crate::random::arrays::*;
901}
902
903/// Legacy slice operations
904pub mod slice_random {
905    pub use crate::random::slice_ops::convenience::*;
906}
907
908// ===============================
909// Enhanced Feature-Based Exports
910// ===============================
911
912/// All essential items for most use cases
913pub mod essentials {
914    pub use crate::random::rand_distributions::{Normal, Uniform};
915    pub use crate::random::{
916        random_normal_array, random_uniform_array, seeded_rng, thread_rng, Beta, Categorical,
917        Random, Rng, RngCore, SeedableRng, WeightedChoice,
918    };
919}
920
921/// Advanced statistical functionality
922pub mod statistics {
923    pub use crate::random::{
924        AntitheticSampling, Beta, Categorical, CommonRatio, ControlVariate, Dirichlet,
925        ExponentialDist, GammaDist, HaltonGenerator, LatinHypercubeSampler, MultivariateNormal,
926        SobolGenerator, VonMises, WeightedChoice,
927    };
928}
929
930/// High-performance computing functionality
931pub mod hpc {
932    pub use crate::random::{
933        random_he_weights, random_normal_array, random_uniform_array, random_xavier_weights,
934        BatchRng, DistributedRngPool, OptimizedArrayRandom, ParallelRng, ThreadLocalRngPool,
935    };
936}
937
938/// 🚀 **Cutting-edge algorithms**
939pub mod cutting_edge {
940    pub use crate::random::{
941        advanced_numerical::*, cutting_edge_mcmc::*, ecosystem_integration::*, neural_sampling::*,
942        quantum_inspired::*,
943    };
944}
945
946/// Advanced MCMC and Bayesian inference
947pub mod bayesian {
948    pub use crate::random::{
949        EllipticalSliceSampler, HamiltonianMonteCarlo, ImportanceSampler, NoUTurnSampler,
950        ParallelTempering, SteinVariationalGradientDescent,
951    };
952    // AdaptiveMetropolisHastings is available through the cutting_edge module
953}
954
955/// Neural and AI-based sampling methods
956pub mod ai_sampling {
957    pub use crate::random::{
958        DiffusionConfig, EnergyBasedModel, NeuralBridge, NeuralPosteriorEstimation,
959        NormalizingFlow, ScoreBasedDiffusion,
960    };
961}
962
963/// Quantum-inspired computational methods
964pub mod quantum {
965    pub use crate::random::{
966        CoinParameters, QuantumAmplitudeAmplification, QuantumInspiredAnnealing,
967        QuantumInspiredEvolutionary, QuantumWalk,
968    };
969}
970
971/// Advanced numerical methods and optimization
972pub mod numerical_methods {
973    pub use crate::random::{
974        AdaptiveResult, AdaptiveSampler, ImportanceResult, MLMCResult, MultiLevelMonteCarlo,
975        SequentialMonteCarlo,
976    };
977}
978
979/// Ecosystem integration and bridge utilities
980pub mod bridges {
981    pub use crate::random::{
982        AugmentationConfig, ExperimentalDesign, LinalgBridge, NeuralBridge, OptimizationBridge,
983        StatsBridge, SyntheticDataset,
984    };
985}