1use scirs2_core::ndarray::{Array2, ArrayView2};
8use scirs2_core::numeric::{Float, FromPrimitive};
9use std::collections::HashMap;
10use std::fmt::Debug;
11use std::time::{Duration, Instant};
12
13use crate::advanced_fusion_algorithms::{AdvancedConfig, AdvancedState};
14use crate::error::{NdimageError, NdimageResult};
15
16#[derive(Debug, Clone)]
18pub struct ComprehensiveValidator {
19 config: ValidationConfig,
21 benchmarks: HashMap<String, PerformanceBenchmark>,
23 errorhistory: Vec<ValidationError>,
25}
26
27#[derive(Debug, Clone)]
29pub struct ValidationConfig {
30 pub strict_numerical: bool,
32 pub max_time_per_pixel: u64,
34 pub min_quality_threshold: f64,
36 pub monitor_memory: bool,
38 pub validate_quantum_coherence: bool,
40 pub validate_consciousnessstate: bool,
42}
43
44impl Default for ValidationConfig {
45 fn default() -> Self {
46 Self {
47 strict_numerical: true,
48 max_time_per_pixel: 1000, min_quality_threshold: 0.95,
50 monitor_memory: true,
51 validate_quantum_coherence: true,
52 validate_consciousnessstate: true,
53 }
54 }
55}
56
57#[derive(Debug, Clone)]
59pub struct PerformanceBenchmark {
60 pub operation: String,
62 pub avg_time: Duration,
64 pub memory_usage: usize,
66 pub quality_score: f64,
68 pub sample_count: usize,
70}
71
72#[derive(Debug, Clone)]
74pub struct ValidationError {
75 pub error_type: String,
77 pub message: String,
79 pub timestamp: Instant,
81 pub operation: String,
83}
84
85impl ComprehensiveValidator {
86 pub fn new() -> Self {
88 Self::with_config(ValidationConfig::default())
89 }
90
91 pub fn with_config(config: ValidationConfig) -> Self {
93 Self {
94 config,
95 benchmarks: HashMap::new(),
96 errorhistory: Vec::new(),
97 }
98 }
99
100 pub fn validate_config(&mut self, config: &AdvancedConfig) -> NdimageResult<()> {
102 if config.consciousness_depth == 0 || config.consciousness_depth > 20 {
104 return Err(NdimageError::ConfigurationError(
105 "Consciousness depth must be between 1 and 20".to_string(),
106 ));
107 }
108
109 if config.meta_learning_rate <= 0.0 || config.meta_learning_rate > 1.0 {
111 return Err(NdimageError::ConfigurationError(
112 "Meta-learning rate must be between 0.0 and 1.0".to_string(),
113 ));
114 }
115
116 if config.advanced_dimensions == 0 || config.advanced_dimensions > 64 {
118 return Err(NdimageError::ConfigurationError(
119 "Advanced-dimensions must be between 1 and 64".to_string(),
120 ));
121 }
122
123 if config.temporal_window > 1000 {
125 return Err(NdimageError::ConfigurationError(
126 "Temporal window too large (max 1000)".to_string(),
127 ));
128 }
129
130 if config.quantum_coherence_threshold < 0.0 || config.quantum_coherence_threshold > 1.0 {
132 return Err(NdimageError::ConfigurationError(
133 "Quantum coherence threshold must be between 0.0 and 1.0".to_string(),
134 ));
135 }
136
137 Ok(())
138 }
139
140 pub fn validate_inputimage<T>(&mut self, image: ArrayView2<T>) -> NdimageResult<()>
142 where
143 T: Float + FromPrimitive + Copy + Debug,
144 {
145 let (height, width) = image.dim();
146
147 if height < 2 || width < 2 {
149 return Err(NdimageError::DimensionError(
150 "Image must be at least 2x2 pixels".to_string(),
151 ));
152 }
153
154 if height > 10000 || width > 10000 {
156 return Err(NdimageError::DimensionError(
157 "Image too large for Advanced processing (max 10000x10000)".to_string(),
158 ));
159 }
160
161 if self.config.strict_numerical {
162 for &pixel in image.iter() {
164 if !pixel.is_finite() {
165 return Err(NdimageError::ComputationError(
166 "Input image contains non-finite values".to_string(),
167 ));
168 }
169 }
170 }
171
172 Ok(())
173 }
174
175 pub fn validate_output<T>(
177 &mut self,
178 output: &Array2<T>,
179 state: &AdvancedState,
180 processing_time: Duration,
181 ) -> NdimageResult<ValidationReport>
182 where
183 T: Float + FromPrimitive + Copy + Debug,
184 {
185 let mut report = ValidationReport::new();
186 let (height, width) = output.dim();
187 let total_pixels = height * width;
188
189 let time_per_pixel = processing_time.as_nanos() / total_pixels as u128;
191 if time_per_pixel > self.config.max_time_per_pixel as u128 {
192 report.warnings.push(format!(
193 "Processing _time per pixel ({} ns) exceeds threshold ({} ns)",
194 time_per_pixel, self.config.max_time_per_pixel
195 ));
196 }
197
198 if self.config.strict_numerical {
200 for &pixel in output.iter() {
201 if !pixel.is_finite() {
202 return Err(NdimageError::ComputationError(
203 "Output contains non-finite values".to_string(),
204 ));
205 }
206 }
207 }
208
209 let quality_score = self.compute_quality_score(output)?;
211 if quality_score < self.config.min_quality_threshold {
212 report.warnings.push(format!(
213 "Output quality ({:.3}) below threshold ({:.3})",
214 quality_score, self.config.min_quality_threshold
215 ));
216 }
217
218 if self.config.validate_consciousnessstate {
220 self.validate_consciousnessstate(state, &mut report)?;
221 }
222
223 self.update_benchmark("enhanced_processing", processing_time, 0, quality_score);
225
226 report.quality_score = quality_score;
227 report.processing_time = processing_time;
228 report.total_pixels = total_pixels;
229
230 Ok(report)
231 }
232
233 fn compute_quality_score<T>(&self, output: &Array2<T>) -> NdimageResult<f64>
235 where
236 T: Float + FromPrimitive + Copy,
237 {
238 let mean = output
239 .iter()
240 .map(|&x| x.to_f64().unwrap_or(0.0))
241 .sum::<f64>()
242 / output.len() as f64;
243
244 let variance = output
245 .iter()
246 .map(|&x| {
247 let val = x.to_f64().unwrap_or(0.0);
248 (val - mean).powi(2)
249 })
250 .sum::<f64>()
251 / output.len() as f64;
252
253 let std_dev = variance.sqrt();
254
255 let dynamic_range = if std_dev > 0.0 { std_dev.min(1.0) } else { 0.5 };
257 let mean_quality = if mean.is_finite() && mean >= 0.0 && mean <= 1.0 {
258 1.0
259 } else {
260 0.5
261 };
262
263 Ok((dynamic_range + mean_quality) / 2.0)
264 }
265
266 fn validate_consciousnessstate(
268 &self,
269 state: &AdvancedState,
270 report: &mut ValidationReport,
271 ) -> NdimageResult<()> {
272 if state.processing_cycles == 0 {
273 report
274 .warnings
275 .push("No processing cycles recorded".to_string());
276 }
277
278 if state.processing_cycles > 1000 {
279 report.warnings.push(format!(
280 "Excessive processing cycles: {}",
281 state.processing_cycles
282 ));
283 }
284
285 Ok(())
286 }
287
288 fn update_benchmark(&mut self, operation: &str, time: Duration, memory: usize, quality: f64) {
290 let benchmark =
291 self.benchmarks
292 .entry(operation.to_string())
293 .or_insert(PerformanceBenchmark {
294 operation: operation.to_string(),
295 avg_time: time,
296 memory_usage: memory,
297 quality_score: quality,
298 sample_count: 0,
299 });
300
301 let count = benchmark.sample_count as f64;
303 benchmark.avg_time = Duration::from_nanos(
304 ((benchmark.avg_time.as_nanos() as f64 * count + time.as_nanos() as f64)
305 / (count + 1.0)) as u64,
306 );
307 benchmark.memory_usage =
308 ((benchmark.memory_usage as f64 * count + memory as f64) / (count + 1.0)) as usize;
309 benchmark.quality_score = (benchmark.quality_score * count + quality) / (count + 1.0);
310 benchmark.sample_count += 1;
311 }
312
313 pub fn get_performance_summary(&self) -> PerformanceSummary {
315 PerformanceSummary {
316 benchmarks: self.benchmarks.clone(),
317 total_operations: self.benchmarks.values().map(|b| b.sample_count).sum(),
318 error_count: self.errorhistory.len(),
319 }
320 }
321}
322
323#[derive(Debug, Clone)]
325pub struct ValidationReport {
326 pub quality_score: f64,
328 pub processing_time: Duration,
330 pub total_pixels: usize,
332 pub warnings: Vec<String>,
334 pub passed: bool,
336}
337
338impl ValidationReport {
339 fn new() -> Self {
340 Self {
341 quality_score: 0.0,
342 processing_time: Duration::default(),
343 total_pixels: 0,
344 warnings: Vec::new(),
345 passed: true,
346 }
347 }
348
349 pub fn is_valid(&self) -> bool {
351 self.passed && self.warnings.is_empty()
352 }
353
354 pub fn get_pixels_per_second(&self) -> f64 {
356 if self.processing_time.as_secs_f64() > 0.0 {
357 self.total_pixels as f64 / self.processing_time.as_secs_f64()
358 } else {
359 0.0
360 }
361 }
362}
363
364#[derive(Debug, Clone)]
366pub struct PerformanceSummary {
367 pub benchmarks: HashMap<String, PerformanceBenchmark>,
369 pub total_operations: usize,
371 pub error_count: usize,
373}
374
375impl PerformanceSummary {
376 pub fn average_quality(&self) -> f64 {
378 if self.benchmarks.is_empty() {
379 return 0.0;
380 }
381
382 self.benchmarks
383 .values()
384 .map(|b| b.quality_score)
385 .sum::<f64>()
386 / self.benchmarks.len() as f64
387 }
388
389 pub fn total_processing_time(&self) -> Duration {
391 self.benchmarks
392 .values()
393 .map(|b| b.avg_time)
394 .fold(Duration::default(), |acc, t| acc + t)
395 }
396}
397
398pub type ComprehensiveSummary = PerformanceSummary;
403
404#[allow(dead_code)]
406pub fn validated_advanced_processing<T>(
407 image: ArrayView2<T>,
408 config: &AdvancedConfig,
409 previousstate: Option<AdvancedState>,
410 validator: &mut ComprehensiveValidator,
411) -> NdimageResult<(Array2<T>, AdvancedState, ValidationReport)>
412where
413 T: Float + FromPrimitive + Copy + Send + Sync + Debug,
414{
415 validator.validate_config(config)?;
417 validator.validate_inputimage(image)?;
418
419 let start_time = Instant::now();
420
421 let (output, state) =
423 crate::advanced_fusion_algorithms::fusion_processing(image, config, previousstate)?;
424
425 let processing_time = start_time.elapsed();
426
427 let report = validator.validate_output(&output, &state, processing_time)?;
429
430 Ok((output, state, report))
431}
432
433#[cfg(test)]
434mod tests {
435 use super::*;
436 use scirs2_core::ndarray::Array2;
437
438 #[test]
439 fn test_validator_creation() {
440 let validator = ComprehensiveValidator::new();
441 assert!(validator.benchmarks.is_empty());
442 assert!(validator.errorhistory.is_empty());
443 }
444
445 #[test]
446 fn test_input_validation() {
447 let mut validator = ComprehensiveValidator::new();
448 let validimage = Array2::<f64>::ones((10, 10));
449 assert!(validator.validate_inputimage(validimage.view()).is_ok());
450
451 let smallimage = Array2::<f64>::ones((1, 1));
452 assert!(validator.validate_inputimage(smallimage.view()).is_err());
453 }
454
455 #[test]
456 fn test_config_validation() {
457 let mut validator = ComprehensiveValidator::new();
458 let mut config = crate::advanced_fusion_algorithms::AdvancedConfig::default();
459
460 assert!(validator.validate_config(&config).is_ok());
462
463 config.consciousness_depth = 0;
465 assert!(validator.validate_config(&config).is_err());
466 }
467
468 #[test]
469 fn test_quality_score_computation() {
470 let validator = ComprehensiveValidator::new();
471 let output = Array2::<f64>::ones((10, 10));
472 let quality = validator
473 .compute_quality_score(&output)
474 .expect("Operation failed");
475 assert!(quality > 0.0 && quality <= 1.0);
476 }
477}