1use std::collections::HashMap;
8use std::time::Duration;
9
10use scirs2_core::ndarray::Array2;
11
12use super::results::{
13 AccuracyComparison, AlgorithmLevelResults, AnomalyDetectionResults, BarrenPlateauAnalysis,
14 BreakEvenAnalysis, CapacityPlanningResult, CapacityRecommendation, CentralityAnalysisResult,
15 CircuitLevelResults, ClassicalComparisonResult, ClassificationResults, ClusteringResults,
16 CommunityDetectionResult, ConnectivityAnalysisResult, ConvergenceAnalysis,
17 CorrelationAnalysisResult, CostAnalysisResult, CostMetrics, CostOptimizationAnalysisResult,
18 CrossEntropyResult, CrossPlatformAnalysis, CrossPlatformComparison, CrossValidationResult,
19 DepthScalingResult, EnsembleResult, ExponentialFit, FailurePattern, FeatureImportanceResults,
20 ForecastingResults, GateLevelResults, GraphAnalysisResult, HeavyOutputResult,
21 HypothesisTestResult, LinearRegressionResult, MLAnalysisResult, MLModelResult,
22 MLRegressionResults, ModelComparisonResult, NISQPerformanceResult, NonlinearRegressionResult,
23 OptimizationAnalysisResult, OptimizationResult, ParameterSensitivityAnalysis,
24 ParetoAnalysisResult, PerturbationResult, PlatformBenchmarkResult, PlatformPerformanceMetrics,
25 PlatformRanking, PolynomialFit, QuantumAdvantageResult, ROIAnalysis, ROIAnalysisResult,
26 RandomizedBenchmarkingResult, RegressionAnalysisResult, ReliabilityMetrics,
27 ResourceAnalysisResult, ResourceUtilizationMetrics, RobustnessAnalysisResult,
28 ScalabilityAnalysis, ScalingMetric, SciRS2AnalysisResult, SeasonalityAnalysisResult,
29 SensitivityAnalysisResult, StabilityAnalysis, StationarityTestResults,
30 StatisticalAnalysisResult, StatisticalSummary, SystemCostEfficiency, SystemLevelResults,
31 SystemReliabilityAnalysis, SystemResourceUtilization, SystemScalabilityAnalysis,
32 TimeSeriesAnalysisResult, TopologyOptimizationResult, TrendAnalysisResult,
33 UncertaintyPropagation, VariationalAlgorithmResult, VolumeBenchmarkResult, WidthScalingResult,
34};
35use super::types::QuantumPlatform;
36
37pub fn zero_statistical_summary() -> StatisticalSummary {
41 StatisticalSummary {
42 mean: 0.0,
43 std_dev: 0.0,
44 median: 0.0,
45 min: 0.0,
46 max: 0.0,
47 percentiles: HashMap::new(),
48 confidence_interval: (0.0, 0.0),
49 }
50}
51
52pub fn statistical_summary_from_slice(values: &[f64]) -> StatisticalSummary {
55 if values.is_empty() {
56 return zero_statistical_summary();
57 }
58 let n = values.len() as f64;
59 let mean = values.iter().sum::<f64>() / n;
60 let variance = values.iter().map(|&x| (x - mean).powi(2)).sum::<f64>() / n;
61 let std_dev = variance.sqrt();
62 let mut sorted = values.to_vec();
63 sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
64 let min = sorted[0];
65 let max = *sorted.last().unwrap_or(&0.0);
66 let median = if sorted.len() % 2 == 0 {
67 (sorted[sorted.len() / 2 - 1] + sorted[sorted.len() / 2]) / 2.0
68 } else {
69 sorted[sorted.len() / 2]
70 };
71 let p95_idx = ((sorted.len() as f64 * 0.95) as usize).min(sorted.len() - 1);
72 let p50_idx = ((sorted.len() as f64 * 0.50) as usize).min(sorted.len() - 1);
73 let mut percentiles = HashMap::new();
74 percentiles.insert(50u8, sorted[p50_idx]);
75 percentiles.insert(95u8, sorted[p95_idx]);
76 let ci_half = 1.96 * std_dev / n.sqrt();
78 StatisticalSummary {
79 mean,
80 std_dev,
81 median,
82 min,
83 max,
84 percentiles,
85 confidence_interval: (mean - ci_half, mean + ci_half),
86 }
87}
88
89pub fn default_gate_level_results() -> GateLevelResults {
94 GateLevelResults {
95 single_qubit_results: HashMap::new(),
96 two_qubit_results: HashMap::new(),
97 multi_qubit_results: HashMap::new(),
98 randomized_benchmarking: RandomizedBenchmarkingResult {
99 clifford_fidelity: 0.99,
100 decay_parameter: 0.001,
101 confidence_interval: (0.985, 0.995),
102 sequence_lengths: vec![1, 2, 4, 8, 16],
103 survival_probabilities: vec![1.0, 0.998, 0.992, 0.984, 0.968],
104 },
105 process_tomography: None,
106 }
107}
108
109pub fn default_circuit_level_results() -> CircuitLevelResults {
111 CircuitLevelResults {
112 depth_scaling: DepthScalingResult {
113 depth_vs_fidelity: vec![(1, 0.99), (10, 0.90), (50, 0.70)],
114 depth_vs_execution_time: vec![
115 (1, Duration::from_micros(50)),
116 (10, Duration::from_micros(500)),
117 (50, Duration::from_millis(3)),
118 ],
119 scaling_exponent: 1.2,
120 coherence_limited_depth: 100,
121 },
122 width_scaling: WidthScalingResult {
123 width_vs_fidelity: vec![(1, 0.99), (5, 0.95), (20, 0.80)],
124 width_vs_execution_time: vec![
125 (1, Duration::from_micros(50)),
126 (5, Duration::from_micros(150)),
127 (20, Duration::from_millis(1)),
128 ],
129 scaling_exponent: 0.8,
130 connectivity_limited_width: 50,
131 },
132 circuit_type_results: HashMap::new(),
133 parametric_results: HashMap::new(),
134 volume_benchmarks: VolumeBenchmarkResult {
135 heavy_output: HeavyOutputResult {
136 heavy_output_probability: 0.66,
137 theoretical_threshold: 0.5,
138 statistical_significance: 0.95,
139 },
140 cross_entropy: CrossEntropyResult {
141 cross_entropy_benchmarking_fidelity: 0.95,
142 linear_xeb_fidelity: 0.94,
143 log_xeb_fidelity: 0.93,
144 },
145 quantum_volume: 32,
146 },
147 }
148}
149
150pub fn default_algorithm_level_results() -> AlgorithmLevelResults {
152 AlgorithmLevelResults {
153 algorithm_results: HashMap::new(),
154 nisq_performance: NISQPerformanceResult {
155 noise_resilience: 0.85,
156 error_mitigation_effectiveness: 0.70,
157 depth_limited_performance: {
158 let mut m = HashMap::new();
159 m.insert(10_usize, 0.95_f64);
160 m.insert(50, 0.80);
161 m.insert(100, 0.60);
162 m
163 },
164 variational_optimization_convergence: ConvergenceAnalysis {
165 convergence_achieved: true,
166 iterations_to_convergence: Some(150),
167 final_cost: -1.0,
168 cost_history: vec![-0.1, -0.5, -0.8, -1.0],
169 gradient_norms: vec![0.5, 0.2, 0.05, 0.001],
170 },
171 },
172 quantum_advantage: QuantumAdvantageResult {
173 advantage_demonstrated: false,
174 speedup_factor: None,
175 confidence_level: 0.0,
176 problem_instances_tested: 0,
177 },
178 classical_comparison: ClassicalComparisonResult {
179 classical_runtime: Duration::from_secs(1),
180 quantum_runtime: Duration::from_millis(100),
181 speedup_ratio: 10.0,
182 accuracy_comparison: AccuracyComparison {
183 classical_accuracy: 1.0,
184 quantum_accuracy: 0.95,
185 relative_error: 0.05,
186 },
187 },
188 variational_algorithm_performance: VariationalAlgorithmResult {
189 optimization_landscapes: HashMap::new(),
190 convergence_analysis: ConvergenceAnalysis {
191 convergence_achieved: true,
192 iterations_to_convergence: Some(200),
193 final_cost: -0.9,
194 cost_history: vec![-0.1, -0.5, -0.8, -0.9],
195 gradient_norms: vec![0.5, 0.2, 0.05, 0.01],
196 },
197 parameter_sensitivity: ParameterSensitivityAnalysis {
198 sensitivity_matrix: Array2::eye(2),
199 most_sensitive_parameters: vec![0],
200 robustness_score: 0.75,
201 },
202 barren_plateau_analysis: BarrenPlateauAnalysis {
203 plateau_detected: false,
204 gradient_variance: 0.1,
205 effective_dimension: 4.0,
206 mitigation_strategies: vec![],
207 },
208 },
209 }
210}
211
212pub fn default_system_level_results(platform: &QuantumPlatform) -> SystemLevelResults {
214 SystemLevelResults {
215 cross_platform_comparison: CrossPlatformComparison {
216 platform_rankings: vec![PlatformRanking {
217 platform: platform.clone(),
218 overall_score: 0.85,
219 category_scores: {
220 let mut m = HashMap::new();
221 m.insert("fidelity".to_string(), 0.90);
222 m.insert("speed".to_string(), 0.80);
223 m
224 },
225 rank: 1,
226 }],
227 relative_performance: {
228 let mut m = HashMap::new();
229 m.insert(format!("{platform:?}"), 1.0);
230 m
231 },
232 statistical_significance: HashMap::new(),
233 },
234 resource_utilization: SystemResourceUtilization {
235 average_queue_time: Duration::from_secs(60),
236 throughput: 10.0,
237 utilization_rate: 0.75,
238 peak_usage_times: vec![],
239 },
240 reliability_analysis: SystemReliabilityAnalysis {
241 uptime: 0.995,
242 error_frequency: 0.001,
243 recovery_time: Duration::from_secs(300),
244 failure_patterns: vec![],
245 },
246 scalability_analysis: SystemScalabilityAnalysis {
247 max_supported_qubits: 127,
248 max_circuit_depth: 1000,
249 performance_scaling: HashMap::new(),
250 },
251 cost_efficiency: SystemCostEfficiency {
252 cost_per_shot: 0.0001,
253 cost_per_gate: 0.000001,
254 cost_efficiency_score: 0.80,
255 roi_analysis: ROIAnalysis {
256 investment_cost: 1000.0,
257 operational_cost: 100.0,
258 performance_benefit: 5000.0,
259 roi_ratio: 4.5,
260 },
261 },
262 }
263}
264
265pub fn compute_performance_metrics(
269 gate: &GateLevelResults,
270 circuit: &CircuitLevelResults,
271 algo: &AlgorithmLevelResults,
272 system: &SystemLevelResults,
273) -> PlatformPerformanceMetrics {
274 let rb_fidelity = gate.randomized_benchmarking.clifford_fidelity;
276
277 let error_rate = (1.0 - rb_fidelity).max(0.0);
279
280 let throughput = system.resource_utilization.throughput;
282
283 let availability = system.reliability_analysis.uptime.clamp(0.0, 1.0);
285
286 let avg_execution_time = circuit
288 .depth_scaling
289 .depth_vs_execution_time
290 .first()
291 .map(|(_, d)| *d)
292 .unwrap_or(Duration::from_millis(100));
293
294 let fidelity = if !algo.nisq_performance.depth_limited_performance.is_empty() {
296 let vals: Vec<f64> = algo
297 .nisq_performance
298 .depth_limited_performance
299 .values()
300 .copied()
301 .collect();
302 let algo_fidelity = vals.iter().sum::<f64>() / vals.len() as f64;
303 (rb_fidelity + algo_fidelity) / 2.0
304 } else {
305 rb_fidelity
306 };
307
308 PlatformPerformanceMetrics {
309 overall_fidelity: fidelity.clamp(0.0, 1.0),
310 average_execution_time: avg_execution_time,
311 throughput,
312 error_rate,
313 availability,
314 }
315}
316
317pub fn compute_reliability_metrics(
319 gate: &GateLevelResults,
320 _circuit: &CircuitLevelResults,
321 _algo: &AlgorithmLevelResults,
322) -> ReliabilityMetrics {
323 let error_rate = (1.0 - gate.randomized_benchmarking.clifford_fidelity).max(0.0);
324 let mtbf_hours = if error_rate > 1e-9 {
326 (1.0 / error_rate).min(876_000.0) } else {
328 876_000.0
329 };
330 let mtbf = Duration::from_secs_f64(mtbf_hours * 3600.0);
331 ReliabilityMetrics {
332 uptime: (1.0 - error_rate).clamp(0.0, 1.0),
333 mtbf,
334 mttr: Duration::from_secs(300), availability: (1.0 - error_rate).clamp(0.0, 1.0),
336 }
337}
338
339pub fn compute_cost_metrics(
341 _gate: &GateLevelResults,
342 circuit: &CircuitLevelResults,
343 _algo: &AlgorithmLevelResults,
344) -> CostMetrics {
345 let qv = circuit.volume_benchmarks.quantum_volume as f64;
348 let cost_per_shot = (0.0001 * qv / 32.0).max(0.00001);
349 let cost_per_hour = cost_per_shot * 3600.0;
350 let total_cost = cost_per_hour; let mut breakdown = HashMap::new();
352 breakdown.insert("gate_operations".to_string(), total_cost * 0.6);
353 breakdown.insert("readout".to_string(), total_cost * 0.2);
354 breakdown.insert("qubit_time".to_string(), total_cost * 0.2);
355 CostMetrics {
356 total_cost,
357 cost_per_shot,
358 cost_per_hour,
359 cost_breakdown: breakdown,
360 }
361}
362
363pub fn compute_cross_platform_analysis(
367 platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
368) -> CrossPlatformAnalysis {
369 if platform_results.is_empty() {
370 return CrossPlatformAnalysis {
371 platform_comparison: HashMap::new(),
372 best_platform_per_metric: HashMap::new(),
373 statistical_significance_tests: HashMap::new(),
374 };
375 }
376
377 let mut platform_comparison: HashMap<String, f64> = HashMap::new();
378 let mut fidelity_scores: Vec<(QuantumPlatform, f64)> = Vec::new();
379 let mut error_scores: Vec<(QuantumPlatform, f64)> = Vec::new();
380 let mut throughput_scores: Vec<(QuantumPlatform, f64)> = Vec::new();
381
382 for (platform, result) in platform_results {
383 let m = &result.performance_metrics;
384 let label = format!("{platform:?}");
385 let composite = m.overall_fidelity * 0.5
387 + (1.0 - m.error_rate).clamp(0.0, 1.0) * 0.3
388 + (m.throughput / 100.0).clamp(0.0, 1.0) * 0.2;
389 platform_comparison.insert(label, composite);
390 fidelity_scores.push((platform.clone(), m.overall_fidelity));
391 error_scores.push((platform.clone(), m.error_rate));
392 throughput_scores.push((platform.clone(), m.throughput));
393 }
394
395 let best_fidelity = fidelity_scores
396 .iter()
397 .max_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(std::cmp::Ordering::Equal))
398 .map(|(p, _)| p.clone());
399
400 let best_error = error_scores
401 .iter()
402 .min_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(std::cmp::Ordering::Equal))
403 .map(|(p, _)| p.clone());
404
405 let best_throughput = throughput_scores
406 .iter()
407 .max_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(std::cmp::Ordering::Equal))
408 .map(|(p, _)| p.clone());
409
410 let mut best_platform_per_metric: HashMap<String, QuantumPlatform> = HashMap::new();
411 if let Some(p) = best_fidelity {
412 best_platform_per_metric.insert("fidelity".to_string(), p);
413 }
414 if let Some(p) = best_error {
415 best_platform_per_metric.insert("error_rate".to_string(), p);
416 }
417 if let Some(p) = best_throughput {
418 best_platform_per_metric.insert("throughput".to_string(), p);
419 }
420
421 let statistical_significance_tests: HashMap<String, f64> = platform_comparison
423 .keys()
424 .map(|k| (k.clone(), 0.05))
425 .collect();
426
427 CrossPlatformAnalysis {
428 platform_comparison,
429 best_platform_per_metric,
430 statistical_significance_tests,
431 }
432}
433
434pub fn default_scirs2_analysis() -> SciRS2AnalysisResult {
440 let hypothesis_test = HypothesisTestResult {
441 test_name: "baseline_t_test".to_string(),
442 p_value: 1.0,
443 statistic: 0.0,
444 critical_value: 1.96,
445 significant: false,
446 effect_size: 0.0,
447 };
448
449 let stationarity_test = HypothesisTestResult {
450 test_name: "adf".to_string(),
451 p_value: 0.5,
452 statistic: -1.0,
453 critical_value: -2.86,
454 significant: false,
455 effect_size: 0.0,
456 };
457
458 SciRS2AnalysisResult {
459 statistical_analysis: StatisticalAnalysisResult {
460 hypothesis_tests: vec![hypothesis_test],
461 correlation_analysis: CorrelationAnalysisResult {
462 correlationmatrix: Array2::eye(1),
463 significant_correlations: vec![],
464 partial_correlations: Array2::eye(1),
465 },
466 regression_analysis: RegressionAnalysisResult {
467 linear_regression: LinearRegressionResult {
468 coefficients: vec![0.0],
469 r_squared: 0.0,
470 adjusted_r_squared: 0.0,
471 p_values: vec![1.0],
472 residuals: vec![],
473 },
474 nonlinear_regression: NonlinearRegressionResult {
475 model_type: "none".to_string(),
476 parameters: vec![],
477 r_squared: 0.0,
478 mse: 0.0,
479 convergence_achieved: false,
480 },
481 model_comparison: ModelComparisonResult {
482 aic_scores: HashMap::new(),
483 bic_scores: HashMap::new(),
484 cross_validation_scores: HashMap::new(),
485 best_model: "none".to_string(),
486 },
487 },
488 time_series_analysis: TimeSeriesAnalysisResult {
489 trend_analysis: TrendAnalysisResult {
490 trend_detected: false,
491 trend_direction: "flat".to_string(),
492 trend_strength: 0.0,
493 trend_coefficients: vec![0.0],
494 change_points: vec![],
495 },
496 seasonality_analysis: SeasonalityAnalysisResult {
497 seasonal_components: vec![],
498 seasonal_period: 0,
499 seasonal_strength: 0.0,
500 },
501 stationarity_tests: StationarityTestResults {
502 adf_test: stationarity_test.clone(),
503 kpss_test: stationarity_test,
504 is_stationary: true,
505 },
506 forecasting: ForecastingResults {
507 forecasts: vec![],
508 confidence_intervals: vec![],
509 forecast_horizon: 0,
510 model_performance: HashMap::new(),
511 },
512 },
513 },
514 ml_analysis: MLAnalysisResult {
515 clustering_results: ClusteringResults {
516 cluster_assignments: vec![],
517 cluster_centers: Array2::zeros((0, 0)),
518 silhouette_score: 0.0,
519 inertia: 0.0,
520 optimal_clusters: 1,
521 },
522 classification_results: ClassificationResults {
523 model_accuracy: 0.0,
524 precision: vec![],
525 recall: vec![],
526 f1_score: vec![],
527 confusion_matrix: Array2::zeros((0, 0)),
528 feature_importance: vec![],
529 },
530 regression_results: MLRegressionResults {
531 models: vec![],
532 ensemble_result: EnsembleResult {
533 ensemble_mse: 0.0,
534 ensemble_mae: 0.0,
535 ensemble_r_squared: 0.0,
536 model_weights: vec![],
537 },
538 cross_validation: CrossValidationResult {
539 cv_scores: vec![],
540 mean_cv_score: 0.0,
541 std_cv_score: 0.0,
542 },
543 },
544 anomaly_detection: AnomalyDetectionResults {
545 anomaly_scores: vec![],
546 anomaly_labels: vec![],
547 anomaly_count: 0,
548 feature_importance: FeatureImportanceResults {
549 importance_scores: vec![],
550 feature_names: vec![],
551 ranked_features: vec![],
552 },
553 },
554 },
555 optimization_analysis: OptimizationAnalysisResult {
556 optimization_results: vec![],
557 pareto_analysis: ParetoAnalysisResult {
558 pareto_front: vec![],
559 pareto_solutions: vec![],
560 hypervolume: 0.0,
561 spread_metric: 0.0,
562 },
563 sensitivity_analysis: SensitivityAnalysisResult {
564 sensitivity_indices: vec![],
565 total_sensitivity_indices: vec![],
566 interaction_effects: Array2::zeros((0, 0)),
567 },
568 robustness_analysis: RobustnessAnalysisResult {
569 robustness_score: 0.0,
570 stability_analysis: StabilityAnalysis {
571 stability_score: 0.0,
572 perturbation_analysis: vec![],
573 },
574 uncertainty_propagation: UncertaintyPropagation {
575 input_uncertainties: vec![],
576 output_uncertainty: 0.0,
577 uncertainty_contributions: vec![],
578 },
579 },
580 },
581 graph_analysis: GraphAnalysisResult {
582 connectivity_analysis: ConnectivityAnalysisResult {
583 connectivity_matrix: Array2::zeros((0, 0)),
584 path_lengths: Array2::zeros((0, 0)),
585 clustering_coefficient: 0.0,
586 graph_density: 0.0,
587 },
588 centrality_analysis: CentralityAnalysisResult {
589 betweenness_centrality: vec![],
590 closeness_centrality: vec![],
591 eigenvector_centrality: vec![],
592 pagerank: vec![],
593 },
594 community_detection: CommunityDetectionResult {
595 community_assignments: vec![],
596 modularity: 0.0,
597 num_communities: 0,
598 community_sizes: vec![],
599 },
600 topology_optimization: TopologyOptimizationResult {
601 optimal_topology: Array2::zeros((0, 0)),
602 optimization_objective: 0.0,
603 improvement_factor: 1.0,
604 },
605 },
606 }
607}
608
609pub fn compute_resource_analysis(
613 platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
614) -> ResourceAnalysisResult {
615 let throughputs: Vec<f64> = platform_results
616 .values()
617 .map(|r| r.performance_metrics.throughput)
618 .collect();
619 let utilizations: Vec<f64> = platform_results
620 .values()
621 .map(|r| r.performance_metrics.availability)
622 .collect();
623
624 let avg_throughput = if throughputs.is_empty() {
625 0.0
626 } else {
627 throughputs.iter().sum::<f64>() / throughputs.len() as f64
628 };
629 let avg_utilization = if utilizations.is_empty() {
630 0.0
631 } else {
632 utilizations.iter().sum::<f64>() / utilizations.len() as f64
633 };
634 let peak_utilization = utilizations.iter().cloned().fold(0.0_f64, f64::max);
635
636 let util_metric = |avg: f64, peak: f64| ResourceUtilizationMetrics {
637 average_utilization: avg,
638 peak_utilization: peak,
639 utilization_distribution: vec![avg],
640 efficiency_score: if peak > 0.0 { avg / peak } else { 1.0 },
641 };
642
643 ResourceAnalysisResult {
644 cpu_utilization: util_metric(avg_utilization * 0.6, peak_utilization * 0.7),
645 memory_utilization: util_metric(avg_utilization * 0.4, peak_utilization * 0.5),
646 network_utilization: util_metric(avg_throughput / 100.0, avg_throughput / 50.0),
647 storage_utilization: util_metric(0.2, 0.4),
648 capacity_planning: CapacityPlanningResult {
649 current_capacity: avg_throughput,
650 projected_demand: vec![avg_throughput * 1.1, avg_throughput * 1.2],
651 capacity_recommendations: vec![CapacityRecommendation {
652 resource_type: "qubit_count".to_string(),
653 recommended_capacity: 256.0,
654 timeline: Duration::from_secs(7_776_000), cost_estimate: 50_000.0,
656 }],
657 scaling_timeline: vec![],
658 },
659 }
660}
661
662pub fn compute_cost_analysis(
664 platform_results: &HashMap<QuantumPlatform, PlatformBenchmarkResult>,
665) -> CostAnalysisResult {
666 let total_cost: f64 = platform_results
667 .values()
668 .map(|r| r.cost_metrics.total_cost)
669 .sum();
670
671 let mut cost_breakdown: HashMap<String, f64> = HashMap::new();
672 let mut cost_per_metric: HashMap<String, f64> = HashMap::new();
673 for (platform, result) in platform_results {
674 let label = format!("{platform:?}");
675 cost_breakdown.insert(label.clone(), result.cost_metrics.total_cost);
676 cost_per_metric.insert(
677 format!("{label}.cost_per_shot"),
678 result.cost_metrics.cost_per_shot,
679 );
680 }
681
682 let potential_savings = total_cost * 0.15; CostAnalysisResult {
684 total_cost,
685 cost_breakdown,
686 cost_per_metric,
687 cost_optimization: CostOptimizationAnalysisResult {
688 potential_savings,
689 optimization_strategies: vec![],
690 implementation_roadmap: vec![],
691 },
692 roi_analysis: ROIAnalysisResult {
693 roi_percentage: 250.0,
694 payback_period: Duration::from_secs(365 * 24 * 3600),
695 net_present_value: total_cost * 2.5,
696 break_even_analysis: BreakEvenAnalysis {
697 break_even_point: Duration::from_secs(180 * 24 * 3600),
698 break_even_volume: total_cost,
699 sensitivity_analysis: vec![],
700 },
701 },
702 }
703}
704
705#[derive(Debug, Clone)]
709pub struct FidelityStats {
710 pub mean: f64,
711 pub median: f64,
712 pub p95: f64,
713 pub std_dev: f64,
714 pub n: usize,
715}
716
717pub fn compute_fidelity_statistics(results: &[f64]) -> Option<FidelityStats> {
721 if results.is_empty() {
722 return None;
723 }
724 let summary = statistical_summary_from_slice(results);
725 let p95 = *summary.percentiles.get(&95u8).unwrap_or(&summary.max);
726 Some(FidelityStats {
727 mean: summary.mean,
728 median: summary.median,
729 p95,
730 std_dev: summary.std_dev,
731 n: results.len(),
732 })
733}
734
735#[cfg(test)]
738mod tests {
739 use super::*;
740
741 #[test]
742 fn test_statistical_summary_from_slice() {
743 let values = vec![1.0, 2.0, 3.0, 4.0, 5.0];
744 let s = statistical_summary_from_slice(&values);
745 assert!((s.mean - 3.0).abs() < 1e-9);
746 assert_eq!(s.min, 1.0);
747 assert_eq!(s.max, 5.0);
748 }
749
750 #[test]
751 fn test_statistical_summary_empty() {
752 let s = statistical_summary_from_slice(&[]);
753 assert_eq!(s.mean, 0.0);
754 }
755
756 #[test]
757 fn test_compute_fidelity_statistics() {
758 let values = vec![0.99, 0.98, 0.97, 0.96, 0.95];
759 let stats = compute_fidelity_statistics(&values).expect("should have stats");
760 assert!(stats.mean > 0.96 && stats.mean < 0.99);
761 assert_eq!(stats.n, 5);
762 }
763
764 #[test]
765 fn test_compute_fidelity_statistics_empty() {
766 assert!(compute_fidelity_statistics(&[]).is_none());
767 }
768
769 #[test]
770 fn test_default_gate_level_results() {
771 let g = default_gate_level_results();
772 assert!(g.randomized_benchmarking.clifford_fidelity > 0.9);
773 }
774
775 #[test]
776 fn test_default_scirs2_analysis_is_valid() {
777 let a = default_scirs2_analysis();
778 assert!(!a.statistical_analysis.hypothesis_tests.is_empty());
779 }
780
781 #[test]
782 fn test_cross_platform_analysis_empty() {
783 let cpa = compute_cross_platform_analysis(&HashMap::new());
784 assert!(cpa.platform_comparison.is_empty());
785 }
786}