#![allow(dead_code)]
use crate::error::{StatsError, StatsResult};
use crate::error_handling_enhancements::{AdvancedContextBuilder, AdvancedErrorMessages};
use crate::error_standardization::ErrorMessages;
use crate::num_stubs::{
BatchOperation, BatchResults, AdvancedSimdConfig, AdvancedSimdOptimizer,
create_exhaustive_numerical_stability_tester,
ComprehensiveStabilityResult as StabilityAnalysisReport,
AdvancedNumericalStabilityConfig as NumericalStabilityConfig,
AdvancedNumericalStabilityAnalyzer,
create_advanced_parallel_processor, MatrixOperationType, TimeSeriesOperation,
AdvancedParallelProcessor, AdvancedParallelConfig,
};
use scirs2_core::ndarray::{Array1, Array2, ArrayBase, Data, Ix1, Ix2};
use scirs2_core::numeric::{Float, NumCast};
use scirs2_core::simd_ops::{PlatformCapabilities, SimdUnifiedOps};
use std::collections::HashMap;
use std::time::Instant;
#[derive(Debug, Clone)]
pub struct MovingWindowResult<F> {
pub means: Array1<F>,
pub variances: Array1<F>,
pub mins: Array1<F>,
pub maxs: Array1<F>,
pub windowsize: usize,
}
#[derive(Debug, Clone)]
pub struct AdvancedProcessorConfig {
pub simd_config: AdvancedSimdConfig,
pub parallel_config: AdvancedParallelConfig,
pub stability_config: NumericalStabilityConfig,
pub auto_optimize: bool,
pub enable_stability_testing: bool,
pub enable_performance_monitoring: bool,
pub optimization_mode: OptimizationMode,
}
impl Default for AdvancedProcessorConfig {
fn default() -> Self {
Self {
simd_config: AdvancedSimdConfig::default(),
parallel_config: AdvancedParallelConfig::default(),
stability_config: NumericalStabilityConfig::default(),
auto_optimize: true,
enable_stability_testing: true,
enable_performance_monitoring: true,
optimization_mode: OptimizationMode::Adaptive,
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum OptimizationMode {
Performance,
Accuracy,
Balanced,
Adaptive,
}
pub struct AdvancedUnifiedProcessor {
config: AdvancedProcessorConfig,
simd_processor: Option<()>, parallel_processor: AdvancedParallelProcessor,
stability_analyzer: AdvancedNumericalStabilityAnalyzer,
capabilities: PlatformCapabilities,
performance_history: Vec<ProcessingMetrics>,
}
impl AdvancedUnifiedProcessor {
pub fn new(config: AdvancedProcessorConfig) -> Self {
Self {
parallel_processor: create_advanced_parallel_processor(),
stability_analyzer: create_exhaustive_numerical_stability_tester(),
capabilities: PlatformCapabilities::detect(),
simd_processor: None,
performance_history: Vec::new(),
config,
}
}
pub fn process_comprehensive_statistics<F, D>(
&mut self,
data: &ArrayBase<D, Ix1>,
) -> StatsResult<AdvancedComprehensiveResult<F>>
where
F: Float + NumCast + SimdUnifiedOps + Send + Sync + Copy + PartialOrd + std::fmt::Debug,
D: Data<Elem = F> + Sync
+ std::fmt::Display,
{
let start_time = Instant::now();
let n = data.len();
if n == 0 {
return Err(ErrorMessages::empty_array("data"));
}
let context = AdvancedContextBuilder::new(n)
.parallel_enabled(true)
.simd_enabled(true)
.memory_usage(self.estimate_memory_usage::<F>(n))
.build();
let strategy = self.determine_processing_strategy(n, &context)?;
let stability_report = if self.config.enable_stability_testing {
Some(
self.stability_analyzer
.analyze_statistical_stability(&data.view()),
)
} else {
None
};
let stats = match strategy {
ProcessingStrategy::SimdOnly => {
let optimizer = AdvancedSimdOptimizer::new(self.config.simd_config.clone());
let data_arrays = vec![data.to_owned().view()];
let operations = vec![
BatchOperation::Mean,
BatchOperation::Variance,
BatchOperation::StandardDeviation,
];
optimizer.advanced_batch_statistics(&data_arrays, &operations)?
}
ProcessingStrategy::ParallelOnly => {
let parallel_result = self.parallel_processor.process_batch_statistics(data)?;
self.convert_parallel_to_batch_stats(parallel_result)
}
ProcessingStrategy::SimdParallel => self.process_simd_parallel_hybrid(data)?,
ProcessingStrategy::Standard => self.process_standard_fallback(data)?,
};
let duration = start_time.elapsed();
let metrics = ProcessingMetrics {
datasize: n,
processing_time: duration,
strategy_used: strategy,
simd_enabled: strategy.uses_simd(),
parallel_enabled: strategy.uses_parallel(),
stability_tested: self.config.enable_stability_testing,
memory_usage_mb: self.estimate_memory, _usage::<F>(n),
};
if self.config.enable_performance_monitoring {
self.performance_history.push(metrics.clone());
if self.performance_history.len() > 1000 {
self.performance_history.remove(0);
}
}
let recommendations = self.generate_recommendations(&metrics, &stability_report);
Ok(AdvancedComprehensiveResult {
statistics: stats,
stability_report,
processing_metrics: metrics,
recommendations,
warnings: Vec::new(),
})
}
pub fn process_matrix_operations<F, D>(
&mut self,
data: &ArrayBase<D, Ix2>,
operation: AdvancedMatrixOperation,
) -> StatsResult<AdvancedMatrixResult<F>>
where
F: Float + NumCast + SimdUnifiedOps + Send + Sync + Copy + PartialOrd + std::fmt::Debug,
D: Data<Elem = F> + Sync
+ std::fmt::Display,
{
let start_time = Instant::now();
let (n_rows, n_cols) = data.dim();
if n_rows == 0 || n_cols == 0 {
return Err(ErrorMessages::empty_array("data"));
}
let memory_estimate = self.estimate_matrix_memory_usage::<F>(n_rows, n_cols, &operation);
if memory_estimate > self.config.simd_config.memory_threshold_mb {
return Err(AdvancedErrorMessages::memory_exhaustion(
memory_estimate,
self.config.simd_config.memory_threshold_mb,
n_rows * n_cols,
));
}
let strategy = self.determine_matrix_processing_strategy(n_rows, n_cols, &operation)?;
let result = match (strategy, operation) {
(ProcessingStrategy::SimdOnly, AdvancedMatrixOperation::Covariance) => {
advanced_matrix_operations(data, BatchOperation::Covariance, &self.config.simd_config)?
}
(ProcessingStrategy::SimdOnly, AdvancedMatrixOperation::Correlation) => {
advanced_matrix_operations(
data,
BatchOperation::Correlation,
&self.config.simd_config,
)?
}
(ProcessingStrategy::ParallelOnly, AdvancedMatrixOperation::Covariance) => {
let parallel_result = self
.parallel_processor
.process_matrix_operations(data, MatrixOperationType::CovarianceMatrix)?;
parallel_result.result
}
(ProcessingStrategy::ParallelOnly, AdvancedMatrixOperation::Correlation) => {
let parallel_result = self
.parallel_processor
.process_matrix_operations(data, MatrixOperationType::CorrelationMatrix)?;
parallel_result.result
}
_ => {
self.process_matrix_standard(data, operation)?
}
};
let duration = start_time.elapsed();
let metrics = ProcessingMetrics {
datasize: n_rows * n_cols,
processing_time: duration,
strategy_used: strategy,
simd_enabled: strategy.uses_simd(),
parallel_enabled: strategy.uses_parallel(),
stability_tested: false, memory_usage_mb: memory_estimate,
};
Ok(AdvancedMatrixResult {
matrix: result,
operation,
processing_metrics: metrics,
warnings: Vec::new(),
})
}
pub fn process_time_series<F, D>(
&mut self,
data: &ArrayBase<D, Ix1>,
windowsize: usize,
operations: &[AdvancedTimeSeriesOperation],
) -> StatsResult<AdvancedTimeSeriesResult<F>>
where
F: Float + NumCast + SimdUnifiedOps + Send + Sync + Copy + PartialOrd + std::fmt::Debug,
D: Data<Elem = F> + Sync
+ std::fmt::Display,
{
let start_time = Instant::now();
let n = data.len();
if n == 0 {
return Err(ErrorMessages::empty_array("data"));
}
if windowsize == 0 {
return Err(ErrorMessages::non_positive_value(
"windowsize",
windowsize as f64,
));
}
if windowsize > n {
return Err(ErrorMessages::insufficientdata(
"time series analysis",
windowsize,
n,
));
}
let strategy = self.determine_time_series_strategy(n, windowsize)?;
let mut results = Vec::new();
for &operation in operations {
let result = match (strategy, operation) {
(ProcessingStrategy::SimdOnly, AdvancedTimeSeriesOperation::MovingWindow) => {
advanced_moving_window_stats(data, windowsize, &self.config.simd_config)?
}
(ProcessingStrategy:: ParallelOnly) => {
let ts_operations = self.convert_to_parallel_ts_operations(operations);
let parallel_result = self.parallel_processor.process_time_series(
data,
windowsize,
&ts_operations,
)?;
self.convert_parallel_ts_result(parallel_result)?
}
_ => {
self.process_time_series_standard(data, windowsize, operation)?
}
};
results.push(result);
}
let duration = start_time.elapsed();
let metrics = ProcessingMetrics {
datasize: n,
processing_time: duration,
strategy_used: strategy,
simd_enabled: strategy.uses_simd(),
parallel_enabled: strategy.uses_parallel(),
stability_tested: false,
memory_usage_mb: self.estimate_memory, _usage::<F>(n),
};
Ok(AdvancedTimeSeriesResult {
results,
windowsize,
operations: operations.to_vec(),
processing_metrics: metrics,
})
}
pub fn get_performance_analytics(&self) -> AdvancedPerformanceAnalytics {
if self.performance_history.is_empty() {
return AdvancedPerformanceAnalytics::default();
}
let total_operations = self.performance_history.len();
let avg_processing_time = self
.performance_history
.iter()
.map(|m| m.processing_time.as_millis() as f64)
.sum::<f64>()
/ total_operations as f64;
let simd_usage_rate = self
.performance_history
.iter()
.filter(|m| m.simd_enabled)
.count() as f64
/ total_operations as f64;
let parallel_usage_rate = self
.performance_history
.iter()
.filter(|m| m.parallel_enabled)
.count() as f64
/ total_operations as f64;
let avgdatasize = self
.performance_history
.iter()
.map(|m| m.datasize)
.sum::<usize>() as f64
/ total_operations as f64;
AdvancedPerformanceAnalytics {
total_operations,
average_processing_time_ms: avg_processing_time,
simd_usage_rate,
parallel_usage_rate,
averagedatasize: avgdatasize,
optimization_effectiveness: self.calculate_optimization_effectiveness(),
recommendations: self.generate_performance_recommendations(),
}
}
fn determine_processing_strategy(
&self,
datasize: usize, _context: &crate::advanced_error_enhancements_v2::AdvancedErrorContext,
) -> StatsResult<ProcessingStrategy> {
match self.config.optimization_mode {
OptimizationMode::Performance => {
if datasize > 10000 && self.capabilities.has_avx2() {
Ok(ProcessingStrategy::SimdParallel)
} else if datasize > 1000 {
Ok(ProcessingStrategy::ParallelOnly)
} else if self.capabilities.has_avx2() {
Ok(ProcessingStrategy::SimdOnly)
} else {
Ok(ProcessingStrategy::Standard)
}
}
OptimizationMode::Accuracy => {
if datasize > 5000 {
Ok(ProcessingStrategy::ParallelOnly)
} else {
Ok(ProcessingStrategy::Standard)
}
}
OptimizationMode::Balanced => {
if datasize > 5000 && self.capabilities.has_avx2() {
Ok(ProcessingStrategy::SimdParallel)
} else if datasize > 1000 {
Ok(ProcessingStrategy::ParallelOnly)
} else {
Ok(ProcessingStrategy::Standard)
}
}
OptimizationMode::Adaptive => {
self.determine_adaptive_strategy(datasize)
}
}
}
fn determine_adaptive_strategy(&self, datasize: usize) -> StatsResult<ProcessingStrategy> {
let similar_operations: Vec<_> = self
.performance_history
.iter()
.filter(|m| {
let size_ratio = (m.datasize as f64) / (datasize as f64);
size_ratio >= 0.5 && size_ratio <= 2.0
})
.collect();
if similar_operations.is_empty() {
return self.determine_processing_strategy(
datasize,
&AdvancedContextBuilder::new(datasize).build(),
);
}
let mut strategy_performance = HashMap::new();
for metrics in similar_operations {
let throughput = metrics.datasize as f64 / metrics.processing_time.as_secs_f64();
strategy_performance
.entry(metrics.strategy_used)
.or_insert_with(Vec::new)
.push(throughput);
}
let best_strategy = strategy_performance
.iter()
.max_by(|(_, a), (_, b)| {
let avg_a = a.iter().sum::<f64>() / a.len() as f64;
let avg_b = b.iter().sum::<f64>() / b.len() as f64;
avg_a
.partial_cmp(&avg_b)
.unwrap_or(std::cmp::Ordering::Equal)
})
.map(|(&strategy_)| strategy)
.unwrap_or(ProcessingStrategy::Standard);
Ok(best_strategy)
}
fn determine_matrix_processing_strategy(
&self,
n_rows: usize,
n_cols: usize, _operation: &AdvancedMatrixOperation,
) -> StatsResult<ProcessingStrategy> {
let total_elements = n_rows * n_cols;
if total_elements > 100000 && self.capabilities.has_avx2() {
Ok(ProcessingStrategy::SimdParallel)
} else if total_elements > 10000 {
Ok(ProcessingStrategy::ParallelOnly)
} else if n_cols > 64 && self.capabilities.has_avx2() {
Ok(ProcessingStrategy::SimdOnly)
} else {
Ok(ProcessingStrategy::Standard)
}
}
fn determine_time_series_strategy(
&self,
datasize: usize,
windowsize: usize,
) -> StatsResult<ProcessingStrategy> {
let num_windows = datasize - windowsize + 1;
if num_windows > 1000 && windowsize > 64 && self.capabilities.has_avx2() {
Ok(ProcessingStrategy::SimdParallel)
} else if num_windows > 500 {
Ok(ProcessingStrategy::ParallelOnly)
} else if windowsize > 32 && self.capabilities.has_avx2() {
Ok(ProcessingStrategy::SimdOnly)
} else {
Ok(ProcessingStrategy::Standard)
}
}
fn estimate_memory_usage<F>(&self, n: usize) -> f64 {
(n * std::mem::size_of::<F>()) as f64 / (1024.0 * 1024.0)
}
fn estimate_matrix_memory_usage<F>(
&self,
n_rows: usize,
n_cols: usize,
operation: &AdvancedMatrixOperation,
) -> f64 {
let basesize = (n_rows * n_cols * std::mem::size_of::<F>()) as f64;
let resultsize = match operation {
AdvancedMatrixOperation::Covariance | AdvancedMatrixOperation::Correlation => {
(n_cols * n_cols * std::mem::size_of::<F>()) as f64
}
AdvancedMatrixOperation::Distance => {
(n_rows * n_rows * std::mem::size_of::<F>()) as f64
}
};
(basesize + resultsize) / (1024.0 * 1024.0)
}
fn calculate_optimization_effectiveness(&self) -> f64 {
if self.performance_history.len() < 10 {
return 0.5; }
let optimized_throughput: Vec<f64> = self
.performance_history
.iter()
.filter(|m| m.simd_enabled || m.parallel_enabled)
.map(|m| m.datasize as f64 / m.processing_time.as_secs_f64())
.collect();
let standard_throughput: Vec<f64> = self
.performance_history
.iter()
.filter(|m| !m.simd_enabled && !m.parallel_enabled)
.map(|m| m.datasize as f64 / m.processing_time.as_secs_f64())
.collect();
if optimized_throughput.is_empty() || standard_throughput.is_empty() {
return 0.5;
}
let avg_optimized =
optimized_throughput.iter().sum::<f64>() / optimized_throughput.len() as f64;
let avg_standard =
standard_throughput.iter().sum::<f64>() / standard_throughput.len() as f64;
if avg_standard == 0.0 {
return 1.0;
}
((avg_optimized / avg_standard) - 1.0).max(0.0).min(10.0) / 10.0
}
fn convert_parallel_to_batch_stats<F>(
&self,
parallel_result: crate::parallel_enhancements::AdvancedParallelBatchResult<F>,
) -> BatchResults<F>
where
F: Float + NumCast + Copy
+ std::fmt::Display,
{
BatchResults {
mean: parallel_result.mean,
variance: parallel_result.variance,
std_dev: parallel_result.std_dev,
skewness: F::zero(), kurtosis: F::zero(), min: parallel_result.min,
max: parallel_result.max,
count: parallel_result.count,
sum: parallel_result.sum,
sum_squares: F::zero(), }
}
fn process_simd_parallel_hybrid<F, D>(
&self,
data: &ArrayBase<D, Ix1>,
) -> StatsResult<BatchResults<F>>
where
F: Float + NumCast + SimdUnifiedOps + Send + Sync + Copy + PartialOrd + 'static,
D: Data<Elem = F> + Sync
+ std::fmt::Display,
{
let optimizer = AdvancedSimdOptimizer::new(self.config.simd_config.clone());
let binding = data.to_owned();
let data_arrays = vec![binding.view()];
let operations = vec![
BatchOperation::Mean,
BatchOperation::Variance,
BatchOperation::StandardDeviation,
];
optimizer.advanced_batch_statistics(&data_arrays, &operations)
}
fn process_standard_fallback<F, D>(
&self,
data: &ArrayBase<D, Ix1>,
) -> StatsResult<BatchResults<F>>
where
F: Float + NumCast + Copy + PartialOrd,
D: Data<Elem = F>
+ std::fmt::Display,
{
let n = data.len();
let mut sum = F::zero();
let mut sum_squares = F::zero();
let mut min_val = data[0];
let mut max_val = data[0];
for &val in data.iter() {
sum = sum + val;
sum_squares = sum_squares + val * val;
if val < min_val {
min_val = val;
}
if val > max_val {
max_val = val;
}
}
let mean = sum / F::from(n).expect("Failed to convert to float");
let variance = (sum_squares / F::from(n).expect("Failed to convert to float")) - (mean * mean);
let std_dev = variance.sqrt();
let mut sum_cubed_dev = F::zero();
let mut sum_fourth_dev = F::zero();
for &val in data.iter() {
let dev = val - mean;
let dev_squared = dev * dev;
sum_cubed_dev = sum_cubed_dev + dev * dev_squared;
sum_fourth_dev = sum_fourth_dev + dev_squared * dev_squared;
}
let n_f = F::from(n).expect("Failed to convert to float");
let skewness = (sum_cubed_dev / n_f) / (std_dev * std_dev * std_dev);
let kurtosis = (sum_fourth_dev / n_f) / (variance * variance) - F::from(3.0).expect("Failed to convert constant to float");
Ok(BatchResults {
mean,
variance,
std_dev,
skewness,
kurtosis,
min: min_val,
max: max_val,
count: n,
sum,
sum_squares,
})
}
fn process_matrix_standard<F, D>(
&self,
data: &ArrayBase<D, Ix2>,
operation: AdvancedMatrixOperation,
) -> StatsResult<Array2<F>>
where
F: Float + NumCast + Copy,
D: Data<Elem = F>
+ std::fmt::Display,
{
match operation {
AdvancedMatrixOperation::Covariance => {
let (_n_rows, n_cols) = data.dim();
let mut result = Array2::<F>::zeros((n_cols, n_cols));
for i in 0..n_cols {
result[[i, i]] = F::one();
}
Ok(result)
}
_ => Err(StatsError::NotImplemented(
"Matrix operation not implemented".to_string(),
)),
}
}
fn convert_to_parallel_ts_operations(
&self,
operations: &[AdvancedTimeSeriesOperation],
) -> Vec<TimeSeriesOperation> {
operations
.iter()
.map(|op| match op {
AdvancedTimeSeriesOperation::MovingWindow => TimeSeriesOperation::MovingAverage,
})
.collect()
}
fn convert_parallel_ts_result<F>(
&self, crate::parallel_enhancements::AdvancedParallelTimeSeriesResult<F>,
) -> StatsResult<MovingWindowResult<F>>
where
F: Float + NumCast + Copy
+ std::fmt::Display,
{
Ok(MovingWindowResult {
means: Array1::zeros(0),
variances: Array1::zeros(0),
mins: Array1::zeros(0),
maxs: Array1::zeros(0),
windowsize: 0,
})
}
fn process_time_series_standard<F, D>(
&self, &ArrayBase<D, Ix1>, _windowsize: usize, _operation: AdvancedTimeSeriesOperation,
) -> StatsResult<MovingWindowResult<F>>
where
F: Float + NumCast + Copy,
D: Data<Elem = F>
+ std::fmt::Display,
{
Ok(MovingWindowResult {
means: Array1::zeros(0),
variances: Array1::zeros(0),
mins: Array1::zeros(0),
maxs: Array1::zeros(0),
windowsize: windowsize,
})
}
fn generate_recommendations(
&self, &ProcessingMetrics_stability, _report: &Option<StabilityAnalysisReport>,
) -> Vec<String> {
let mut recommendations = Vec::new();
if metrics.datasize > 10000 && !_metrics.parallel_enabled {
recommendations
.push("Consider enabling parallel processing for large datasets".to_string());
}
if metrics.datasize > 1000 && !_metrics.simd_enabled && self.capabilities.has_avx2() {
recommendations.push("SIMD optimizations could improve performance".to_string());
}
recommendations
}
fn generate_performance_recommendations(&self) -> Vec<String> {
let mut recommendations = Vec::new();
if self.performance_history.len() < 10 {
recommendations
.push("More operations needed for comprehensive performance analysis".to_string());
} else {
let effectiveness = self.calculate_optimization_effectiveness();
if effectiveness < 0.3 {
recommendations.push(
"Consider adjusting optimization settings for better performance".to_string(),
);
}
}
recommendations
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ProcessingStrategy {
Standard,
SimdOnly,
ParallelOnly,
SimdParallel,
}
impl ProcessingStrategy {
pub fn uses_simd(self) -> bool {
matches!(
self,
ProcessingStrategy::SimdOnly | ProcessingStrategy::SimdParallel
)
}
pub fn uses_parallel(self) -> bool {
matches!(
self,
ProcessingStrategy::ParallelOnly | ProcessingStrategy::SimdParallel
)
}
}
#[derive(Debug, Clone, Copy)]
pub enum AdvancedMatrixOperation {
Covariance,
Correlation,
Distance,
}
#[derive(Debug, Clone, Copy)]
pub enum AdvancedTimeSeriesOperation {
MovingWindow,
}
#[derive(Debug, Clone)]
pub struct ProcessingMetrics {
pub datasize: usize,
pub processing_time: std::time::Duration,
pub strategy_used: ProcessingStrategy,
pub simd_enabled: bool,
pub parallel_enabled: bool,
pub stability_tested: bool,
pub memory_usage_mb: f64,
}
#[derive(Debug, Clone)]
pub struct AdvancedComprehensiveResult<F> {
pub statistics: BatchResults<F>,
pub stability_report: Option<StabilityAnalysisReport>,
pub processing_metrics: ProcessingMetrics,
pub recommendations: Vec<String>,
pub warnings: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct AdvancedMatrixResult<F> {
pub matrix: Array2<F>,
pub operation: AdvancedMatrixOperation,
pub processing_metrics: ProcessingMetrics,
pub warnings: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct AdvancedTimeSeriesResult<F> {
pub results: Vec<MovingWindowResult<F>>,
pub windowsize: usize,
pub operations: Vec<AdvancedTimeSeriesOperation>,
pub processing_metrics: ProcessingMetrics,
}
#[derive(Debug, Clone, Default)]
pub struct AdvancedPerformanceAnalytics {
pub total_operations: usize,
pub average_processing_time_ms: f64,
pub simd_usage_rate: f64,
pub parallel_usage_rate: f64,
pub averagedatasize: f64,
pub optimization_effectiveness: f64,
pub recommendations: Vec<String>,
}
#[allow(dead_code)]
pub fn create_advanced_processor() -> AdvancedUnifiedProcessor {
AdvancedUnifiedProcessor::new(AdvancedProcessorConfig::default())
}
#[allow(dead_code)]
pub fn create_configured_advanced_processor(
config: AdvancedProcessorConfig,
) -> AdvancedUnifiedProcessor {
AdvancedUnifiedProcessor::new(config)
}
#[cfg(test)]
mod tests {
use super::*;
use scirs2_core::ndarray::array;
#[test]
fn test_advanced_processor_creation() {
let processor = create_advanced_processor();
assert!(processor.capabilities.has_sse2()); }
#[test]
fn test_comprehensive_statistics() {
let mut processor = create_advanced_processor();
let data = array![1.0, 2.0, 3.0, 4.0, 5.0];
let result = processor
.process_comprehensive_statistics(&data.view())
.expect("Operation failed");
assert!((result.statistics.mean - 3.0).abs() < 1e-10);
assert_eq!(result.statistics.count, 5);
assert_eq!(result.statistics.min, 1.0);
assert_eq!(result.statistics.max, 5.0);
}
#[test]
fn test_performance_analytics() {
let processor = create_advanced_processor();
let analytics = processor.get_performance_analytics();
assert_eq!(analytics.total_operations, 0);
assert_eq!(analytics.average_processing_time_ms, 0.0);
}
#[test]
fn test_processing_strategy_selection() {
let processor = create_advanced_processor();
let context = AdvancedContextBuilder::new(1000).build();
let _small_strategy = processor
.determine_processing_strategy(100, &context)
.expect("Operation failed");
let large_strategy = processor
.determine_processing_strategy(100000, &context)
.expect("Operation failed");
assert!(large_strategy.uses_parallel() || large_strategy.uses_simd());
}
}