//! Report generation and unified interfaces for neural network interpretation
//!
//! This module provides comprehensive reporting capabilities that integrate all
//! interpretation methods and present unified, coherent analysis results.

use crate::error::{NeuralError, Result};
use crate::interpretation::ConceptActivationVector;
use scirs2_core::ndarray::{ArrayD, IxDyn};
use scirs2_core::numeric::Float;
use scirs2_core::ndarray::ArrayStatCompat;
use std::collections::HashMap;
use std::fmt::Debug;
use std::iter::Sum;
use super::analysis::{AttributionStatistics, InterpretationSummary, LayerAnalysisStats};
use super::core::ModelInterpreter;
use statrs::statistics::Statistics;
/// Comprehensive interpretation report for a single input
#[derive(Debug, Clone)]
pub struct InterpretationReport<F: Float + Debug + NumAssign> {
    /// Shape of the input being analyzed
    pub inputshape: IxDyn,
    /// Target class for the analysis (if applicable)
    pub target_class: Option<usize>,
    /// Attribution results from different methods
    pub attributions: HashMap<String, ArrayD<F>>,
    /// Statistical analysis of attributions
    pub attribution_statistics: HashMap<String, AttributionStatistics<F>>,
    /// Layer-wise analysis statistics
    pub layer_statistics: HashMap<String, LayerAnalysisStats<F>>,
    /// Summary of interpretation results
    pub interpretation_summary: InterpretationSummary,
}
/// Comprehensive interpretation report with additional analysis
pub struct ComprehensiveInterpretationReport<F: Float + Debug + NumAssign> {
    /// Basic interpretation report
    pub basic_report: InterpretationReport<F>,
    /// Counterfactual explanations (if available)
    pub counterfactual_explanations: Option<Vec<ArrayD<F>>>,
    /// LIME explanations (if available)
    pub lime_explanations: Option<ArrayD<F>>,
    /// Concept activation scores
    pub concept_activations: HashMap<String, f64>,
    /// Attention visualizations (for transformer models)
    pub attention_visualizations: HashMap<String, ArrayD<F>>,
    /// Feature visualizations
    pub feature_visualizations: HashMap<String, ArrayD<F>>,
    /// Model confidence and uncertainty estimates
    pub confidence_estimates: ConfidenceEstimates,
    /// Adversarial robustness analysis
    pub robustness_analysis: Option<RobustnessAnalysis>,
/// Confidence estimates for interpretation results
pub struct ConfidenceEstimates {
    /// Overall interpretation confidence (0-1)
    pub overall_confidence: f64,
    /// Method-specific confidence scores
    pub method_confidence: HashMap<String, f64>,
    /// Uncertainty estimates for attributions
    pub attribution_uncertainty: HashMap<String, f64>,
    /// Reliability indicators
    pub reliability_indicators: HashMap<String, f64>,
/// Robustness analysis results
pub struct RobustnessAnalysis {
    /// Adversarial vulnerability score (0-1, higher = more vulnerable)
    pub vulnerability_score: f64,
    /// Perturbation sensitivity analysis
    pub perturbation_sensitivity: HashMap<String, f64>,
    /// Attribution stability across noise
    pub attribution_stability: f64,
    /// Recommended confidence adjustments
    pub confidence_adjustments: HashMap<String, f64>,
/// Generate comprehensive interpretation report
#[allow(dead_code)]
pub fn generate_comprehensive_report<F>(
    interpreter: &ModelInterpreter<F>,
    input: &ArrayD<F>,
) -> Result<ComprehensiveInterpretationReport<F>>
where
    F: Float
        + Debug
        + 'static
        + scirs2_core::ndarray::ScalarOperand
        + scirs2_core::numeric::FromPrimitive
        + Sum
        + Clone
        + Copy,
{
    // Generate basic interpretation report
    let basic_report = generate_basic_report(interpreter, input, None)?;
    // Gather additional interpretation data
    let counterfactual_explanations = interpreter
        .counterfactual_generator()
        .map(|_cf_generator| vec![input.clone()]);
    let lime_explanations = interpreter
        .lime_explainer()
        .map(|_lime_explainer| input.clone());
    // Collect concept activations
    let mut concept_activations = HashMap::new();
    
    // Note: concept_vectors are not directly accessible from ModelInterpreter
    // In a real implementation, we would access them through getter methods
    // For now, we'll generate meaningful default concept activations
    // If no concepts are defined, add some meaningful default analyses
    if concept_activations.is_empty() {
        // Add statistical concept activations based on input patterns
        concept_activations.insert("high_activation_regions".to_string(), 
                                 compute_high_activation_score(input));
        concept_activations.insert("low_activation_regions".to_string(), 
                                 compute_low_activation_score(input));
        concept_activations.insert("activation_variance".to_string(), 
                                 compute_activation_variance(input));
    }
    // Collect attention visualizations
    let mut attention_visualizations = HashMap::new();
    if let Some(_attention_viz) = interpreter.attention_visualizer() {
        // Would generate attention visualizations here
        attention_visualizations.insert("layer_1".to_string(), input.clone());
    // Generate feature visualizations
    let feature_visualizations = generate_feature_visualizations(interpreter, input)?;
    // Compute confidence estimates
    let confidence_estimates = compute_confidence_estimates(&basic_report)?;
    // Perform robustness analysis
    let robustness_analysis = Some(perform_robustness_analysis(interpreter, input)?);
    Ok(ComprehensiveInterpretationReport {
        basic_report,
        counterfactual_explanations,
        lime_explanations,
        concept_activations,
        attention_visualizations,
        feature_visualizations,
        confidence_estimates,
        robustness_analysis,
    })
/// Generate basic interpretation report
#[allow(dead_code)]
pub fn generate_basic_report<F>(
    target_class: Option<usize>,
) -> Result<InterpretationReport<F>>
    let mut attributions = HashMap::new();
    // Compute attributions using all available methods
    for method in interpreter.attribution_methods() {
        let attribution = interpreter.compute_attribution(method, input, target_class)?;
        let method_name = format!("{method:?}");
        attributions.insert(method_name, attribution);
    // Compute attribution statistics
    let mut attribution_stats = HashMap::new();
    for (method_name, attribution) in &attributions {
        let stats = super::analysis::compute_attribution_statistics(attribution);
        attribution_stats.insert(method_name.clone(), stats);
    let interpretation_summary = super::analysis::generate_interpretation_summary(&attributions);
    Ok(InterpretationReport {
        inputshape: input.raw_dim(),
        target_class,
        attributions,
        attribution_statistics: attribution_stats,
        layer_statistics: interpreter.layer_statistics().clone(),
        interpretation_summary,
/// Generate feature visualizations for the model
#[allow(dead_code)]
fn generate_feature_visualizations<F>(
    _interpreter: &ModelInterpreter<F>,
) -> Result<HashMap<String, ArrayD<F>>>
    let mut visualizations = HashMap::new();
    // Placeholder feature visualizations
    visualizations.insert("activation_maximization".to_string(), input.clone());
    visualizations.insert(
        "gradient_ascent".to_string(),
        input.mapv(|x| x * F::from(0.5).expect("Failed to convert constant to float")),
    );
    Ok(visualizations)
/// Compute confidence estimates for interpretation results
#[allow(dead_code)]
fn compute_confidence_estimates<F>(report: &InterpretationReport<F>) -> Result<ConfidenceEstimates>, F: Float + Debug,
    let overall_confidence = report.interpretation_summary.interpretation_confidence;
    let mut method_confidence = HashMap::new();
    let mut attribution_uncertainty = HashMap::new();
    let mut reliability_indicators = HashMap::new();
    for (method_name, stats) in &report.attribution_statistics {
        // Compute method-specific confidence based on attribution characteristics
        let confidence =
            if stats.positive_attribution_ratio > 0.1 && stats.positive_attribution_ratio < 0.9 {
                0.8 // Good balance of positive and negative attributions
            } else {
                0.5 // Potentially biased attributions
            };
        method_confidence.insert(method_name.clone(), confidence);
        // Compute uncertainty based on attribution variance
        let uncertainty = 1.0 - confidence;
        attribution_uncertainty.insert(method_name.clone(), uncertainty);
        // Reliability indicator based on magnitude distribution
        let reliability = stats.mean_absolute.to_f64().unwrap_or(0.0).min(1.0);
        reliability_indicators.insert(method_name.clone(), reliability);
    Ok(ConfidenceEstimates {
        overall_confidence,
        method_confidence,
        attribution_uncertainty,
        reliability_indicators,
/// Perform robustness analysis on the interpretation
#[allow(dead_code)]
fn perform_robustness_analysis<F>(
    _input: &ArrayD<F>,
) -> Result<RobustnessAnalysis>
    // Simplified robustness analysis
    let vulnerability_score = 0.3; // Placeholder
    let mut perturbation_sensitivity = HashMap::new();
    perturbation_sensitivity.insert("gaussian_noise".to_string(), 0.2);
    perturbation_sensitivity.insert("adversarial".to_string(), 0.4);
    let attribution_stability = 0.8; // Placeholder
    let mut confidence_adjustments = HashMap::new();
    confidence_adjustments.insert("saliency".to_string(), 0.9);
    confidence_adjustments.insert("integrated_gradients".to_string(), 0.85);
    Ok(RobustnessAnalysis {
        vulnerability_score,
        perturbation_sensitivity,
        attribution_stability,
        confidence_adjustments,
/// Generate summary statistics for a comprehensive report
#[allow(dead_code)]
pub fn generate_report_summary<F>(
    report: &ComprehensiveInterpretationReport<F>,
) -> HashMap<String, String>
    let mut summary = HashMap::new();
    // Basic statistics
    summary.insert(
        "num_attribution_methods".to_string(),
        report.basic_report.attribution_statistics.len().to_string(),
        "overall_confidence".to_string(),
        format!("{:.3}", report.confidence_estimates.overall_confidence),
        "num_layers_analyzed".to_string(),
        report.basic_report.layer_statistics.len().to_string(),
    // Feature analysis
    if let Some(target_class) = report.basic_report.target_class {
        summary.insert("target_class".to_string(), target_class.to_string());
        "top_features_count".to_string(),
        report
            .basic_report
            .interpretation_summary
            .most_important_features
            .len()
            .to_string(),
    // Robustness information
    if let Some(ref robustness) = report.robustness_analysis {
        summary.insert(
            "vulnerability_score".to_string(),
            format!("{:.3}", robustness.vulnerability_score),
        );
            "attribution_stability".to_string(),
            format!("{:.3}", robustness.attribution_stability),
    // Additional capabilities
        "has_counterfactuals".to_string(),
        report.counterfactual_explanations.is_some().to_string(),
        "has_lime_explanations".to_string(),
        report.lime_explanations.is_some().to_string(),
        "num_concept_activations".to_string(),
        report.concept_activations.len().to_string(),
    summary
/// Export report to different formats
#[allow(dead_code)]
pub fn export_report_data<F>(
    format: &str,
) -> Result<String>
    match format.to_lowercase().as_str() {
        "json" => export_to_json(report),
        "summary" => Ok(format_summary_report(report)),
        "csv" => export_to_csv(report),
        "yaml" => export_to_yaml(report),
        "xml" => export_to_xml(report),
        "toml" => export_to_toml(report, _ => Err(NeuralError::NotImplementedError(format!(
            "Export format '{}' not supported. Supported formats: json, summary, csv, yaml, xml, toml",
            format
        ))),
#[allow(dead_code)]
fn export_to_json<F>(report: &ComprehensiveInterpretationReport<F>) -> Result<String>
    use serde_json::{_json, Map};
    // Build JSON object with report data
    let mut json_obj = Map::new();
    // Basic report information
    json_obj.insert("inputshape".to_string(), json!(report.basic_report.inputshape));
    json_obj.insert("target_class".to_string(), json!(report.basic_report.target_class));
    // Attribution methods (convert to string list)
    let attribution_methods: Vec<String> = report.basic_report.attributions
        .keys()
        .cloned()
        .collect();
    json_obj.insert("attribution_methods".to_string(), json!(attribution_methods));
    // Concept activations
    json_obj.insert("concept_activations".to_string(), json!(report.concept_activations));
    // Confidence estimates
    let mut confidence_obj = Map::new();
    confidence_obj.insert("overall_confidence".to_string(), json!(report.confidence_estimates.overall_confidence));
    // Method confidence scores
    let mut method_confidence = Map::new();
    for (method, confidence) in &report.confidence_estimates.method_confidence {
        method_confidence.insert(method.clone(), json!(confidence));
    confidence_obj.insert("method_confidence".to_string(), json!(method_confidence));
    // Attribution uncertainty
    let mut attribution_uncertainty = Map::new();
    for (method, uncertainty) in &report.confidence_estimates.attribution_uncertainty {
        attribution_uncertainty.insert(method.clone(), json!(uncertainty));
    confidence_obj.insert("attribution_uncertainty".to_string(), json!(attribution_uncertainty));
    json_obj.insert("confidence_estimates".to_string(), json!(confidence_obj));
    // Feature visualizations (metadata only, as arrays are too large for JSON)
    let mut viz_metadata = Map::new();
    for (name_) in &report.feature_visualizations {
        viz_metadata.insert(name.clone(), json!("available"));
    json_obj.insert("feature_visualizations".to_string(), json!(viz_metadata));
    // Attention visualizations metadata
    let mut attention_metadata = Map::new();
    for (name_) in &report.attention_visualizations {
        attention_metadata.insert(name.clone(), json!("available"));
    json_obj.insert("attention_visualizations".to_string(), json!(attention_metadata));
    // Robustness analysis
        let mut robustness_obj = Map::new();
        robustness_obj.insert("vulnerability_score".to_string(), json!(robustness.vulnerability_score));
        robustness_obj.insert("attribution_stability".to_string(), json!(robustness.attribution_stability));
        
        // Perturbation sensitivity
        let mut perturbation_sens = Map::new();
        for (method, sensitivity) in &robustness.perturbation_sensitivity {
            perturbation_sens.insert(method.clone(), json!(sensitivity));
        }
        robustness_obj.insert("perturbation_sensitivity".to_string(), json!(perturbation_sens));
        json_obj.insert("robustness_analysis".to_string(), json!(robustness_obj));
    // Serialize to JSON string
    serde_json::to_string_pretty(&json_obj)
        .map_err(|e| NeuralError::ConfigError(format!("JSON serialization error: {e}")))
#[allow(dead_code)]
fn format_summary_report<F>(report: &ComprehensiveInterpretationReport<F>) -> String
    let summary = generate_report_summary(report);
    let mut output = String::new();
    output.push_str("=== Interpretation Report Summary ===\n\n");
    for (key, value) in summary {
        output.push_str(&format!("{key}: {value}\n"));
    output.push_str("\n=== Method Confidence Scores ===\n");
        output.push_str(&format!("{method}: {confidence:.3}\n"));
    output
#[allow(dead_code)]
fn export_to_csv<F>(report: &ComprehensiveInterpretationReport<F>) -> Result<String>
    let mut csv_content = String::new();
    // Header for method confidence data
    csv_content.push_str("section,key,value\n");
    csv_content.push_str(&format!("basic_info,inputshape,\"{:?}\"\n", report.basic_report.inputshape));
        csv_content.push_str(&format!("basic_info,target_class,{target_class}\n"));
    let num_methods = report.basic_report.attributions.len();
    csv_content.push_str(&format!("basic_info,num_attribution_methods,{}\n", num_methods));
    csv_content.push_str(&format!("confidence,overall_confidence,{}\n", report.confidence_estimates.overall_confidence));
        csv_content.push_str(&format!("method_confidence,{},{}\n", method, confidence));
    for (concept, activation) in &report.concept_activations {
        csv_content.push_str(&format!("concept_activation,{},{}\n", concept, activation));
    // Feature visualizations (just names/availability)
        csv_content.push_str(&format!("feature_visualization,{},available\n", name));
    // Attention visualizations (just names/availability) 
        csv_content.push_str(&format!("attention_visualization,{},available\n", name));
        csv_content.push_str(&format!("robustness,vulnerability_score,{}\n", robustness.vulnerability_score));
        csv_content.push_str(&format!("robustness,attribution_stability,{}\n", robustness.attribution_stability));
            csv_content.push_str(&format!("perturbation_sensitivity,{},{}\n", method, sensitivity));
    // Attribution data summary (statistics instead of full array)
    let attribution_stats = compute_attribution_statistics(&report.basic_report.attribution);
    csv_content.push_str(&format!("attribution_stats,min,{}\n", attribution_stats.min));
    csv_content.push_str(&format!("attribution_stats,max,{}\n", attribution_stats.max));
    csv_content.push_str(&format!("attribution_stats,mean,{}\n", attribution_stats.mean));
    csv_content.push_str(&format!("attribution_stats,std,{}\n", attribution_stats.std));
    Ok(csv_content)
/// Helper function to compute attribution statistics
#[allow(dead_code)]
fn compute_attribution_statistics<F>(attribution: &ArrayD<F>) -> AttributionStats
    F: Float + Debug + Copy,
    let data: Vec<f64> = attribution.iter().map(|&x| x.to_f64().unwrap_or(0.0)).collect();
    let min = data.iter().cloned().fold(f64::INFINITY, f64::min);
    let max = data.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
    let mean = data.iter().sum::<f64>() / data.len() as f64;
    let variance = data.iter().map(|&x| (x - mean).powi(2)).sum::<f64>() / data.len() as f64;
    let std = variance.sqrt();
    AttributionStats { min, max, mean, std }
/// Simple statistics for attribution data
struct AttributionStats {
    min: f64,
    max: f64,
    mean: f64,
    std: f64,
/// Export report to YAML format
#[allow(dead_code)]
fn export_to_yaml<F>(report: &ComprehensiveInterpretationReport<F>) -> Result<String>
    use serde_yaml;
    // Reuse the JSON structure but serialize to YAML
    let mut yaml_obj = Map::new();
    yaml_obj.insert("inputshape".to_string(), json!(report.basic_report.inputshape));
    yaml_obj.insert("target_class".to_string(), json!(report.basic_report.target_class));
    yaml_obj.insert("attribution_method".to_string(), json!(format!("{:?}", report.basic_report.attribution_method)));
    yaml_obj.insert("concept_activations".to_string(), json!(report.concept_activations));
    confidence_obj.insert("uncertainty_estimate".to_string(), json!(report.confidence_estimates.uncertainty_estimate));
    yaml_obj.insert("confidence_estimates".to_string(), json!(confidence_obj));
    // Attribution statistics
    let mut stats_obj = Map::new();
    stats_obj.insert("min".to_string(), json!(attribution_stats.min));
    stats_obj.insert("max".to_string(), json!(attribution_stats.max));
    stats_obj.insert("mean".to_string(), json!(attribution_stats.mean));
    stats_obj.insert("std".to_string(), json!(attribution_stats.std));
    yaml_obj.insert("attribution_statistics".to_string(), json!(stats_obj));
    // Serialize to YAML string
    serde_yaml::to_string(&json!(yaml_obj))
        .map_err(|e| NeuralError::ConfigError(format!("YAML serialization error: {}", e)))
/// Export report to XML format
#[allow(dead_code)]
fn export_to_xml<F>(report: &ComprehensiveInterpretationReport<F>) -> Result<String>
    let mut xml_content = String::new();
    xml_content.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    xml_content.push_str("<interpretation_report>\n");
    // Basic information
    xml_content.push_str("  <basic_info>\n");
    xml_content.push_str(&format!("    <inputshape>{:?}</inputshape>\n", report.basic_report.inputshape));
        xml_content.push_str(&format!("    <target_class>{}</target_class>\n", target_class));
    xml_content.push_str(&format!("    <attribution_method>{:?}</attribution_method>\n", report.basic_report.attribution_method));
    xml_content.push_str("  </basic_info>\n");
    xml_content.push_str("  <confidence_estimates>\n");
    xml_content.push_str(&format!("    <overall_confidence>{}</overall_confidence>\n", report.confidence_estimates.overall_confidence));
    xml_content.push_str(&format!("    <uncertainty_estimate>{}</uncertainty_estimate>\n", report.confidence_estimates.uncertainty_estimate));
    xml_content.push_str("    <method_confidence>\n");
        xml_content.push_str(&format!("      <method name=\"{}\">{}</method>\n", method, confidence));
    xml_content.push_str("    </method_confidence>\n");
    xml_content.push_str("  </confidence_estimates>\n");
    xml_content.push_str("  <concept_activations>\n");
        xml_content.push_str(&format!("    <concept name=\"{}\">{}</concept>\n", concept, activation));
    xml_content.push_str("  </concept_activations>\n");
    xml_content.push_str("  <attribution_statistics>\n");
    xml_content.push_str(&format!("    <min>{}</min>\n", attribution_stats.min));
    xml_content.push_str(&format!("    <max>{}</max>\n", attribution_stats.max));
    xml_content.push_str(&format!("    <mean>{}</mean>\n", attribution_stats.mean));
    xml_content.push_str(&format!("    <std>{}</std>\n", attribution_stats.std));
    xml_content.push_str("  </attribution_statistics>\n");
    xml_content.push_str("</interpretation_report>\n");
    Ok(xml_content)
/// Export report to TOML format
#[allow(dead_code)]
fn export_to_toml<F>(report: &ComprehensiveInterpretationReport<F>) -> Result<String>
    let mut toml_content = String::new();
    toml_content.push_str("[basic_info]\n");
    toml_content.push_str(&format!("inputshape = \"{:?}\"\n", report.basic_report.inputshape));
        toml_content.push_str(&format!("target_class = {}\n", target_class));
    toml_content.push_str(&format!("attribution_method = \"{:?}\"\n", report.basic_report.attribution_method));
    toml_content.push_str("\n");
    toml_content.push_str("[confidence_estimates]\n");
    toml_content.push_str(&format!("overall_confidence = {}\n", report.confidence_estimates.overall_confidence));
    toml_content.push_str(&format!("uncertainty_estimate = {}\n", report.confidence_estimates.uncertainty_estimate));
    // Method confidence
    toml_content.push_str("[method_confidence]\n");
        toml_content.push_str(&format!("{} = {}\n", method.replace(" ", "_"), confidence));
    toml_content.push_str("[concept_activations]\n");
        toml_content.push_str(&format!("{} = {}\n", concept.replace(" ", "_"), activation));
    toml_content.push_str("[attribution_statistics]\n");
    toml_content.push_str(&format!("min = {}\n", attribution_stats.min));
    toml_content.push_str(&format!("max = {}\n", attribution_stats.max));
    toml_content.push_str(&format!("mean = {}\n", attribution_stats.mean));
    toml_content.push_str(&format!("std = {}\n", attribution_stats.std));
    Ok(toml_content)
// Display implementation for reports
impl<F: Float + Debug + NumAssign> + std::fmt::Display for InterpretationReport<F> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "Interpretation Report")?;
        writeln!(f, "===================")?;
        writeln!(f, "Input shape: {:?}", self.inputshape)?;
        if let Some(class) = self.target_class {
            writeln!(f, "Target class: {}", class)?;
        writeln!(f, "Attribution methods: {}", self.attributions.len())?;
        writeln!(f, "Layers analyzed: {}", self.layer_statistics.len())?;
        writeln!(
            f,
            "Interpretation confidence: {:.3}",
            self.interpretation_summary.interpretation_confidence
        )?;
        Ok(())
impl<F: Float + Debug + NumAssign> + std::fmt::Display for ComprehensiveInterpretationReport<F> {
        writeln!(f, "Comprehensive Interpretation Report")?;
        writeln!(f, "==================================")?;
        write!(f, "{}", self.basic_report)?;
        writeln!(f, "\nAdditional Analysis:")?;
            "- Counterfactuals: {}",
            self.counterfactual_explanations.is_some()
            "- LIME explanations: {}",
            self.lime_explanations.is_some()
            "- Concept activations: {}",
            self.concept_activations.len()
            "- Attention visualizations: {}",
            self.attention_visualizations.len()
            "- Feature visualizations: {}",
            self.feature_visualizations.len()
        if let Some(ref robustness) = self.robustness_analysis {
            writeln!(f, "\nRobustness Analysis:")?;
            writeln!(
                f,
                "- Vulnerability score: {:.3}",
                robustness.vulnerability_score
            )?;
                "- Attribution stability: {:.3}",
                robustness.attribution_stability
/// Compute concept activation for a given input and concept vector
#[allow(dead_code)]
fn compute_concept_activation<F>(_input: &ArrayD<F>, conceptvector: &ConceptActivationVector<F>) -> f64
    F: Float + Debug + 'static + scirs2_core::ndarray::ScalarOperand + scirs2_core::numeric::FromPrimitive + Sum + Clone + Copy,
    // Simplified concept activation computation
    // In practice, this would be based on the specific concept vector implementation
    let flattened_input: Vec<F> = input.iter().cloned().collect();
    let input_magnitude = flattened_input.iter().map(|&x| x * x).fold(F::zero(), |acc, x| acc + x).sqrt();
    if input_magnitude > F::zero() {
        // Normalize and compute a meaningful activation score
        let normalized_magnitude = input_magnitude.to_f64().unwrap_or(0.0);
        (normalized_magnitude * 0.8 + 0.2).min(1.0)
    } else {
        0.0
/// Compute high activation score based on input statistics
#[allow(dead_code)]
fn compute_high_activation_score<F>(input: &ArrayD<F>) -> f64
    let mean_val = input.mean_or(F::zero()).to_f64().unwrap_or(0.0);
    let max_val = input.iter().fold(F::zero(), |acc, &x| acc.max(x)).to_f64().unwrap_or(0.0);
    // Score based on how much of the input has high activation values
    let threshold = F::from(mean_val + 0.5 * (max_val - mean_val)).expect("Operation failed");
    let high_count = input.iter().filter(|&&x| x > threshold).count();
    let total_count = input.len();
    if total_count > 0 {
        high_count as f64 / total_count as f64
/// Compute low activation score based on _input statistics
#[allow(dead_code)]
fn compute_low_activation_score<F>(input: &ArrayD<F>) -> f64
    let min_val = input.iter().fold(F::zero(), |acc, &x| acc.min(x)).to_f64().unwrap_or(0.0);
    // Score based on how much of the _input has low activation values
    let threshold = F::from(mean_val - 0.5 * (mean_val - min_val)).expect("Operation failed");
    let low_count = input.iter().filter(|&&x| x < threshold).count();
        low_count as f64 / total_count as f64
/// Compute activation variance as a concept score
#[allow(dead_code)]
fn compute_activation_variance<F>(input: &ArrayD<F>) -> f64
    let mean_val = input.mean_or(F::zero());
    let variance = input.iter()
        .map(|&x| {
            let diff = x - mean_val;
            diff * diff
        })
        .fold(F::zero(), |acc, x| acc + x) / F::from(input.len()).expect("Operation failed");
    // Normalize variance to [0, 1] range
    let normalized_variance = variance.to_f64().unwrap_or(0.0);
    normalized_variance.min(1.0)
#[cfg(test)]
mod tests {
    use super::*;
    use scirs2_core::ndarray::Array;
    #[test]
    fn test_confidence_estimates() {
        use super::super::analysis::AttributionStatistics;
        let mut attribution_stats = HashMap::new();
        attribution_stats.insert(
            "saliency".to_string(),
            AttributionStatistics {
                mean: 0.5,
                mean_absolute: 0.7,
                max_absolute: 1.0,
                positive_attribution_ratio: 0.6,
                total_positive_attribution: 10.0,
                total_negative_attribution: -5.0,
            },
        let report = InterpretationReport {
            inputshape: Array::<f64>::ones((3, 32, 32)).into_dyn().raw_dim(),
            target_class: Some(1),
            attributions: HashMap::new(),
            attribution_statistics: attribution_stats,
            layer_statistics: HashMap::new(),
            interpretation_summary: super::super::analysis::InterpretationSummary {
                num_attribution_methods: 1,
                average_method_consistency: 0.8,
                most_important_features: vec![1, 5, 10],
                interpretation_confidence: 0.85,
        };
        let confidence = compute_confidence_estimates(&report);
        assert!(confidence.is_ok());
        let conf_estimates = confidence.expect("Operation failed");
        assert!(conf_estimates.overall_confidence > 0.0);
        assert!(conf_estimates.method_confidence.contains_key("saliency"));
    fn test_report_summary() {
        let basic_report: InterpretationReport<f64> = InterpretationReport {
            target_class: Some(0),
            attribution_statistics: HashMap::new(),
                num_attribution_methods: 2,
                average_method_consistency: 0.7,
                most_important_features: vec![1, 2, 3],
                interpretation_confidence: 0.8,
        let comprehensive_report = ComprehensiveInterpretationReport {
            basic_report,
            counterfactual_explanations: None,
            lime_explanations: None,
            concept_activations: HashMap::new(),
            attention_visualizations: HashMap::new(),
            feature_visualizations: HashMap::new(),
            confidence_estimates: ConfidenceEstimates {
                overall_confidence: 0.8,
                method_confidence: HashMap::new(),
                attribution_uncertainty: HashMap::new(),
                reliability_indicators: HashMap::new(),
            robustness_analysis: None,
        let summary = generate_report_summary(&comprehensive_report);
        assert!(summary.contains_key("overall_confidence"));
        assert!(summary.contains_key("target_class"));
    fn test_export_formats() {
            target_class: None,
                most_important_features: vec![],
        let report = ComprehensiveInterpretationReport {
        let json_export = export_report_data(&report, "json");
        assert!(json_export.is_ok());
        let summary_export = export_report_data(&report, "summary");
        assert!(summary_export.is_ok());
        let csv_export = export_report_data(&report, "csv");
        assert!(csv_export.is_ok());
