use scirs2_core::ndarray::Array1;
use sklears_utils::{
array_utils::{array_standardize, safe_indexing_2d},
data_generation::{make_classification, make_regression},
metrics::{euclidean_distance, manhattan_distance},
parallel::ParallelIterator,
preprocessing::{FeatureScaler, OutlierDetector},
random::{set_random_state, train_test_split_indices},
validation::check_array_2d,
};
#[test]
#[allow(non_snake_case)]
fn test_end_to_end_classification_workflow() {
set_random_state(42);
let (X, _y) = make_classification(1000, 20, 5, None, None, 0.1, 1.0, Some(42))
.expect("operation should succeed");
assert!(check_array_2d(&X).is_ok());
let (train_indices, _test_indices) =
train_test_split_indices(X.nrows(), 0.2, true, Some(42)).expect("operation should succeed");
let X_train = safe_indexing_2d(&X, &train_indices).expect("operation should succeed");
let (X_train_scaled, _means, _stds) =
FeatureScaler::standard_scale(&X_train).expect("operation should succeed");
for i in 0..std::cmp::min(10, X_train_scaled.nrows()) {
for j in (i + 1)..std::cmp::min(10, X_train_scaled.nrows()) {
let row1 = X_train_scaled.row(i).to_owned();
let row2 = X_train_scaled.row(j).to_owned();
let euclidean_dist = euclidean_distance(&row1, &row2);
let manhattan_dist = manhattan_distance(&row1, &row2);
assert!(euclidean_dist >= 0.0);
assert!(manhattan_dist >= 0.0);
}
}
println!("End-to-end classification workflow completed successfully");
}
#[test]
#[allow(non_snake_case)]
fn test_end_to_end_regression_workflow() {
set_random_state(123);
let (X, y) =
make_regression(500, 15, None, 0.1, 1.0, Some(42)).expect("operation should succeed");
assert!(check_array_2d(&X).is_ok());
let (train_indices, _test_indices) = train_test_split_indices(X.nrows(), 0.3, true, Some(123))
.expect("operation should succeed");
let X_train = safe_indexing_2d(&X, &train_indices).expect("operation should succeed");
let y_train = Array1::from_vec(train_indices.iter().map(|&i| y[i]).collect::<Vec<_>>());
let (X_train_scaled, means, stds) =
FeatureScaler::standard_scale(&X_train).expect("operation should succeed");
assert_eq!(means.len(), X_train.ncols());
assert_eq!(stds.len(), X_train.ncols());
for col_idx in 0..X_train_scaled.ncols() {
let column = X_train_scaled.column(col_idx);
let mean = column.sum() / column.len() as f64;
let variance = column.map(|&x| (x - mean).powi(2)).sum() / column.len() as f64;
assert!(
(mean.abs()) < 1e-10,
"Mean should be close to 0 after standardization"
);
assert!(
(variance - 1.0).abs() < 1e-10,
"Variance should be close to 1 after standardization"
);
}
let outlier_indices = OutlierDetector::iqr_outliers(&y_train.view(), 1.5);
assert!(outlier_indices.len() < y_train.len() / 5);
println!("End-to-end regression workflow completed successfully");
}
#[test]
#[allow(non_snake_case)]
fn test_parallel_processing_integration() {
set_random_state(456);
let (X, _y) = make_classification(2000, 50, 10, None, None, 0.05, 1.0, Some(456))
.expect("operation should succeed");
let sample_indices: Vec<usize> = (0..std::cmp::min(100, X.nrows())).collect();
let parallel_iter = ParallelIterator::new(sample_indices.clone());
let distances: Vec<f64> = parallel_iter
.map(move |i| {
let row = X.row(i).to_owned();
let first_row = X.row(0).to_owned();
euclidean_distance(&row, &first_row)
})
.expect("operation should succeed");
assert_eq!(distances.len(), sample_indices.len());
assert_eq!(distances[0], 0.0);
for &dist in &distances {
assert!(dist >= 0.0);
}
println!("Parallel processing integration test completed successfully");
}
#[test]
#[allow(non_snake_case)]
fn test_data_validation_pipeline() {
set_random_state(789);
let (X, _y) = make_classification(300, 10, 3, None, None, 0.0, 1.0, Some(789))
.expect("operation should succeed");
assert!(check_array_2d(&X).is_ok());
println!("Data validation pipeline test completed successfully");
}
#[test]
#[allow(non_snake_case)]
fn test_cross_module_data_flow() {
set_random_state(999);
let (X, _y) =
make_regression(400, 8, None, 0.1, 1.0, Some(999)).expect("operation should succeed");
let original_stats =
array_standardize(&X.column(0).to_owned()).expect("operation should succeed");
let mean = original_stats.sum() / original_stats.len() as f64;
assert!(
mean.abs() < 1e-8,
"Mean should be close to 0 after standardization"
);
let (X_scaled, _means, _stds) =
FeatureScaler::standard_scale(&X).expect("operation should succeed");
let sample1 = X_scaled.row(0).to_owned();
let sample2 = X_scaled.row(1).to_owned();
let distance = euclidean_distance(&sample1, &sample2);
assert!(distance >= 0.0);
let (train_indices, test_indices) = train_test_split_indices(X.nrows(), 0.2, true, Some(999))
.expect("operation should succeed");
assert!(!train_indices.is_empty());
assert!(!test_indices.is_empty());
println!("Cross-module data flow test completed successfully");
}
#[test]
#[allow(non_snake_case)]
fn test_performance_integration() {
use std::time::Instant;
set_random_state(2024);
let start = Instant::now();
let (X, _y) = make_classification(10000, 100, 10, None, None, 0.0, 1.0, Some(2024))
.expect("operation should succeed");
let data_generation_time = start.elapsed();
let start = Instant::now();
let (X_scaled, _means, _stds) =
FeatureScaler::standard_scale(&X).expect("operation should succeed");
let scaling_time = start.elapsed();
let start = Instant::now();
let sample1 = X_scaled.row(0).to_owned();
let sample2 = X_scaled.row(1).to_owned();
let _distance = euclidean_distance(&sample1, &sample2);
let distance_time = start.elapsed();
assert!(
data_generation_time.as_millis() < 15000,
"Data generation took too long: {:?}ms",
data_generation_time.as_millis()
);
assert!(
scaling_time.as_millis() < 3000,
"Scaling took too long: {:?}ms",
scaling_time.as_millis()
);
assert!(
distance_time.as_micros() < 5000,
"Distance computation took too long: {:?}μs",
distance_time.as_micros()
);
println!("Performance integration test completed successfully");
println!(" Data generation: {:?}", data_generation_time);
println!(" Scaling: {:?}", scaling_time);
println!(" Distance: {:?}", distance_time);
}