use anyhow::Result;
use scirs2_core::array; use scirs2_core::ndarray_ext::{Array1, Array2, ArrayView1};
use scirs2_core::random::{
Rng, Random, seeded_rng, ThreadLocalRngPool, ScientificSliceRandom,
distributions::{Dirichlet, Beta, MultivariateNormal, Categorical, WeightedChoice, VonMises},
};
use scirs2_core::core::scientific::{DeterministicState, ReproducibleSequence};
use std::sync::Arc;
pub struct SciRS2CapabilitiesDemo {
rng_pool: Arc<ThreadLocalRngPool>,
deterministic_state: DeterministicState,
}
impl Beta3CapabilitiesDemo {
pub fn new(seed: u64) -> Self {
Self {
rng_pool: Arc::new(ThreadLocalRngPool::new(seed)),
deterministic_state: DeterministicState::new(seed),
}
}
pub fn demo_array_macro(&self) -> Result<()> {
let matrix = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
println!("✅ Array macro works directly: {:?}", matrix.shape());
Ok(())
}
pub fn demo_deterministic_rng(&self) -> Result<()> {
let mut rng1 = seeded_rng(12345);
let mut rng2 = seeded_rng(12345);
let sample1: Vec<f64> = (0..10).map(|_| rng1.random::<f64>()).collect();
let sample2: Vec<f64> = (0..10).map(|_| rng2.random::<f64>()).collect();
assert_eq!(sample1, sample2);
println!("✅ Deterministic RNG: Reproducible sequences verified");
Ok(())
}
pub fn demo_advanced_distributions(&self) -> Result<()> {
let mut rng = self.rng_pool.get();
let dirichlet = Dirichlet::new(vec![1.0, 2.0, 3.0])?;
let dirichlet_sample = dirichlet.sample(&mut rng);
println!("✅ Dirichlet sample: {:?}", dirichlet_sample);
let mvn = MultivariateNormal::new(
vec![0.0, 0.0],
vec![vec![1.0, 0.5], vec![0.5, 1.0]]
)?;
let mvn_sample = mvn.sample(&mut rng);
println!("✅ Multivariate Normal sample: {:?}", mvn_sample);
let von_mises = VonMises::new(0.0, 2.0)?;
let vm_sample = von_mises.sample(&mut rng);
println!("✅ Von Mises sample: {:.4}", vm_sample);
Ok(())
}
pub fn demo_collection_operations(&self) -> Result<()> {
let mut rng = self.rng_pool.get();
let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
data.scientific_shuffle(&mut rng);
println!("✅ Scientific shuffle: {:?}", data);
let original = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sample = original.scientific_choose_multiple(&mut rng, 5);
println!("✅ Floyd's sampling: {:?}", sample);
let items = vec!["apple", "banana", "cherry", "date"];
let weights = vec![0.1, 0.3, 0.4, 0.2];
let weighted_sample = items.scientific_weighted_sample(&mut rng, &weights, 3)?;
println!("✅ Weighted sampling: {:?}", weighted_sample);
let stream_data = (1..1000).collect::<Vec<_>>();
let reservoir = stream_data.scientific_reservoir_sample(&mut rng, 10);
println!("✅ Reservoir sampling: {:?}", reservoir);
Ok(())
}
pub fn demo_array_operations(&self) -> Result<()> {
let mut rng = self.rng_pool.get();
let random_matrix = Array2::<f64>::random((100, 50), &mut rng);
println!("✅ Random matrix shape: {:?}", random_matrix.shape());
let normal_array = Array1::<f64>::standard_normal(1000, &mut rng);
let mean = normal_array.sum() / normal_array.len() as f64;
println!("✅ Standard normal mean: {:.4} (should be ~0.0)", mean);
let uniform_array = Array2::<f64>::uniform((50, 50), -1.0, 1.0, &mut rng);
println!("✅ Uniform array shape: {:?}", uniform_array.shape());
let beta_array = Array1::<f64>::beta(100, 2.0, 5.0, &mut rng);
println!("✅ Beta array length: {}", beta_array.len());
let dirichlet_samples = Array2::<f64>::dirichlet((10, 3), &[1.0, 2.0, 3.0], &mut rng);
println!("✅ Dirichlet samples shape: {:?}", dirichlet_samples.shape());
Ok(())
}
pub fn demo_parallel_operations(&self) -> Result<()> {
use rayon::prelude::*;
let results: Vec<f64> = (0..1000).into_par_iter().map(|_| {
let mut rng = self.rng_pool.get();
rng.random::<f64>()
}).collect();
println!("✅ Parallel random generation: {} samples", results.len());
let deterministic_results1: Vec<f64> = (0..100).into_par_iter().map(|i| {
let mut rng = seeded_rng(i as u64);
rng.random::<f64>()
}).collect();
let deterministic_results2: Vec<f64> = (0..100).into_par_iter().map(|i| {
let mut rng = seeded_rng(i as u64);
rng.random::<f64>()
}).collect();
assert_eq!(deterministic_results1, deterministic_results2);
println!("✅ Deterministic parallel execution verified");
Ok(())
}
pub fn demo_reproducible_sequences(&self) -> Result<()> {
let sequence = ReproducibleSequence::new(42, 1000);
let samples1 = sequence.generate_f64_sequence();
let samples2 = sequence.generate_f64_sequence();
assert_eq!(samples1, samples2);
println!("✅ Reproducible sequences: {} samples match", samples1.len());
Ok(())
}
pub fn run_full_demo(&self) -> Result<()> {
println!("🚀 SciRS2 Beta.3 Capabilities Demonstration");
println!("==========================================");
self.demo_array_macro_fix()?;
self.demo_deterministic_rng()?;
self.demo_advanced_distributions()?;
self.demo_collection_operations()?;
self.demo_array_operations()?;
self.demo_parallel_operations()?;
self.demo_reproducible_sequences()?;
println!("🎯 All SciRS2 Beta.3 features successfully demonstrated!");
Ok(())
}
}
pub struct QueryOptimizationWithBeta3 {
rng_pool: Arc<ThreadLocalRngPool>,
}
impl QueryOptimizationWithBeta3 {
pub fn new(seed: u64) -> Self {
Self {
rng_pool: Arc::new(ThreadLocalRngPool::new(seed)),
}
}
pub fn estimate_cardinality_with_ml(&self, table_size: usize, selectivity: f64) -> Result<f64> {
let mut rng = self.rng_pool.get();
let beta_dist = Beta::new(selectivity * 10.0, (1.0 - selectivity) * 10.0)?;
let estimated_selectivity = beta_dist.sample(&mut rng);
let samples = Array1::<f64>::beta(1000, selectivity * 10.0, (1.0 - selectivity) * 10.0, &mut rng);
let confidence_interval = samples.mapv(|x| x * table_size as f64);
let mean_estimate = confidence_interval.mean().unwrap_or(0.0);
println!("✅ ML cardinality estimate: {:.0} (table size: {})", mean_estimate, table_size);
Ok(mean_estimate)
}
pub fn optimize_join_order(&self, tables: Vec<&str>) -> Result<Vec<&str>> {
let mut rng = self.rng_pool.get();
let weights: Vec<f64> = tables.iter().enumerate()
.map(|(i, _)| 1.0 / (i + 1) as f64) .collect();
let mut optimized_order = Vec::new();
let mut remaining_tables = tables;
while !remaining_tables.is_empty() {
let selected = remaining_tables.scientific_weighted_sample(&mut rng, &weights, 1)?;
if let Some(&table) = selected.first() {
optimized_order.push(table);
remaining_tables.retain(|&t| t != table);
}
}
println!("✅ Optimized join order: {:?}", optimized_order);
Ok(optimized_order)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_beta3_capabilities() -> Result<()> {
let demo = Beta3CapabilitiesDemo::new(12345);
demo.run_full_demo()
}
#[test]
fn test_query_optimization() -> Result<()> {
let optimizer = QueryOptimizationWithBeta3::new(54321);
let tables = vec!["users", "orders", "products", "reviews"];
let _order = optimizer.optimize_join_order(tables)?;
let _cardinality = optimizer.estimate_cardinality_with_ml(100000, 0.15)?;
Ok(())
}
#[test]
fn test_deterministic_reproducibility() -> Result<()> {
let mut rng1 = seeded_rng(999);
let mut rng2 = seeded_rng(999);
for _ in 0..100 {
assert_eq!(rng1.random::<f64>(), rng2.random::<f64>());
}
Ok(())
}
}