QuantumNeuralNetwork

Struct QuantumNeuralNetwork 

Source
pub struct QuantumNeuralNetwork {
    pub layers: Vec<QNNLayerType>,
    pub num_qubits: usize,
    pub input_dim: usize,
    pub output_dim: usize,
    pub parameters: Array1<f64>,
}
Expand description

Represents a quantum neural network

Fields§

§layers: Vec<QNNLayerType>

The layers that make up the network

§num_qubits: usize

The number of qubits used in the network

§input_dim: usize

The dimension of the input data

§output_dim: usize

The dimension of the output data

§parameters: Array1<f64>

Network parameters (weights)

Implementations§

Source§

impl QuantumNeuralNetwork

Source

pub fn new( layers: Vec<QNNLayerType>, num_qubits: usize, input_dim: usize, output_dim: usize, ) -> Result<Self>

Creates a new quantum neural network

Examples found in repository?
examples/quantum_meta_learning.rs (line 62)
48fn maml_demo() -> Result<()> {
49    // Create quantum model
50    let layers = vec![
51        QNNLayerType::EncodingLayer { num_features: 4 },
52        QNNLayerType::VariationalLayer { num_params: 12 },
53        QNNLayerType::EntanglementLayer {
54            connectivity: "circular".to_string(),
55        },
56        QNNLayerType::VariationalLayer { num_params: 12 },
57        QNNLayerType::MeasurementLayer {
58            measurement_basis: "computational".to_string(),
59        },
60    ];
61
62    let qnn = QuantumNeuralNetwork::new(layers, 4, 4, 3)?;
63
64    // Create MAML learner
65    let algorithm = MetaLearningAlgorithm::MAML {
66        inner_steps: 5,
67        inner_lr: 0.01,
68        first_order: true, // Use first-order approximation for efficiency
69    };
70
71    let mut meta_learner = QuantumMetaLearner::new(algorithm, qnn);
72
73    println!("   Created MAML meta-learner:");
74    println!("   - Inner steps: 5");
75    println!("   - Inner learning rate: 0.01");
76    println!("   - Using first-order approximation");
77
78    // Generate tasks
79    let generator = TaskGenerator::new(4, 3);
80    let tasks: Vec<MetaTask> = (0..20)
81        .map(|_| generator.generate_rotation_task(30))
82        .collect();
83
84    // Meta-train
85    println!("\n   Meta-training on 20 rotation tasks...");
86    let mut optimizer = Adam::new(0.001);
87    meta_learner.meta_train(&tasks, &mut optimizer, 50, 5)?;
88
89    // Test adaptation
90    let test_task = generator.generate_rotation_task(20);
91    println!("\n   Testing adaptation to new task...");
92
93    let adapted_params = meta_learner.adapt_to_task(&test_task)?;
94    println!("   Successfully adapted to new task");
95    println!(
96        "   Parameter adaptation magnitude: {:.4}",
97        (&adapted_params - meta_learner.meta_params())
98            .mapv(|x| x.abs())
99            .mean()
100            .unwrap()
101    );
102
103    Ok(())
104}
105
106/// Reptile algorithm demonstration
107fn reptile_demo() -> Result<()> {
108    let layers = vec![
109        QNNLayerType::EncodingLayer { num_features: 2 },
110        QNNLayerType::VariationalLayer { num_params: 8 },
111        QNNLayerType::MeasurementLayer {
112            measurement_basis: "Pauli-Z".to_string(),
113        },
114    ];
115
116    let qnn = QuantumNeuralNetwork::new(layers, 4, 2, 2)?;
117
118    let algorithm = MetaLearningAlgorithm::Reptile {
119        inner_steps: 10,
120        inner_lr: 0.1,
121    };
122
123    let mut meta_learner = QuantumMetaLearner::new(algorithm, qnn);
124
125    println!("   Created Reptile meta-learner:");
126    println!("   - Inner steps: 10");
127    println!("   - Inner learning rate: 0.1");
128
129    // Generate sinusoid tasks
130    let generator = TaskGenerator::new(2, 2);
131    let tasks: Vec<MetaTask> = (0..15)
132        .map(|_| generator.generate_sinusoid_task(40))
133        .collect();
134
135    println!("\n   Meta-training on 15 sinusoid tasks...");
136    let mut optimizer = Adam::new(0.001);
137    meta_learner.meta_train(&tasks, &mut optimizer, 30, 3)?;
138
139    println!("   Reptile training complete");
140
141    // Analyze task similarities
142    println!("\n   Task parameter statistics:");
143    for (i, task) in tasks.iter().take(3).enumerate() {
144        if let Some(amplitude) = task.metadata.get("amplitude") {
145            if let Some(phase) = task.metadata.get("phase") {
146                println!(
147                    "   Task {}: amplitude={:.2}, phase={:.2}",
148                    i, amplitude, phase
149                );
150            }
151        }
152    }
153
154    Ok(())
155}
156
157/// ProtoMAML demonstration
158fn protomaml_demo() -> Result<()> {
159    let layers = vec![
160        QNNLayerType::EncodingLayer { num_features: 8 },
161        QNNLayerType::VariationalLayer { num_params: 16 },
162        QNNLayerType::EntanglementLayer {
163            connectivity: "full".to_string(),
164        },
165        QNNLayerType::MeasurementLayer {
166            measurement_basis: "computational".to_string(),
167        },
168    ];
169
170    let qnn = QuantumNeuralNetwork::new(layers, 4, 8, 16)?;
171
172    let algorithm = MetaLearningAlgorithm::ProtoMAML {
173        inner_steps: 5,
174        inner_lr: 0.01,
175        proto_weight: 0.5, // Weight for prototype regularization
176    };
177
178    let mut meta_learner = QuantumMetaLearner::new(algorithm, qnn);
179
180    println!("   Created ProtoMAML meta-learner:");
181    println!("   - Combines MAML with prototypical networks");
182    println!("   - Prototype weight: 0.5");
183
184    // Generate classification tasks
185    let generator = TaskGenerator::new(8, 4);
186    let tasks: Vec<MetaTask> = (0..10)
187        .map(|_| generator.generate_rotation_task(50))
188        .collect();
189
190    println!("\n   Meta-training on 4-way classification tasks...");
191    let mut optimizer = Adam::new(0.001);
192    meta_learner.meta_train(&tasks, &mut optimizer, 40, 2)?;
193
194    println!("   ProtoMAML leverages both gradient-based and metric-based learning");
195
196    Ok(())
197}
198
199/// Meta-SGD demonstration
200fn metasgd_demo() -> Result<()> {
201    let layers = vec![
202        QNNLayerType::EncodingLayer { num_features: 4 },
203        QNNLayerType::VariationalLayer { num_params: 12 },
204        QNNLayerType::MeasurementLayer {
205            measurement_basis: "Pauli-XYZ".to_string(),
206        },
207    ];
208
209    let qnn = QuantumNeuralNetwork::new(layers, 4, 4, 3)?;
210
211    let algorithm = MetaLearningAlgorithm::MetaSGD { inner_steps: 3 };
212
213    let mut meta_learner = QuantumMetaLearner::new(algorithm, qnn);
214
215    println!("   Created Meta-SGD learner:");
216    println!("   - Learns per-parameter learning rates");
217    println!("   - Inner steps: 3");
218
219    // Generate diverse tasks
220    let generator = TaskGenerator::new(4, 3);
221    let mut tasks = Vec::new();
222
223    // Mix different task types
224    for i in 0..12 {
225        if i % 2 == 0 {
226            tasks.push(generator.generate_rotation_task(30));
227        } else {
228            tasks.push(generator.generate_sinusoid_task(30));
229        }
230    }
231
232    println!("\n   Meta-training on mixed task distribution...");
233    let mut optimizer = Adam::new(0.0005);
234    meta_learner.meta_train(&tasks, &mut optimizer, 50, 4)?;
235
236    if let Some(lr) = meta_learner.per_param_lr() {
237        println!("\n   Learned per-parameter learning rates:");
238        println!(
239            "   - Min LR: {:.4}",
240            lr.iter().cloned().fold(f64::INFINITY, f64::min)
241        );
242        println!(
243            "   - Max LR: {:.4}",
244            lr.iter().cloned().fold(f64::NEG_INFINITY, f64::max)
245        );
246        println!("   - Mean LR: {:.4}", lr.mean().unwrap());
247    }
248
249    Ok(())
250}
251
252/// ANIL demonstration
253fn anil_demo() -> Result<()> {
254    let layers = vec![
255        QNNLayerType::EncodingLayer { num_features: 6 },
256        QNNLayerType::VariationalLayer { num_params: 12 },
257        QNNLayerType::EntanglementLayer {
258            connectivity: "circular".to_string(),
259        },
260        QNNLayerType::VariationalLayer { num_params: 12 },
261        QNNLayerType::VariationalLayer { num_params: 6 }, // Final layer (adapted)
262        QNNLayerType::MeasurementLayer {
263            measurement_basis: "computational".to_string(),
264        },
265    ];
266
267    let qnn = QuantumNeuralNetwork::new(layers, 4, 6, 2)?;
268
269    let algorithm = MetaLearningAlgorithm::ANIL {
270        inner_steps: 10,
271        inner_lr: 0.1,
272    };
273
274    let mut meta_learner = QuantumMetaLearner::new(algorithm, qnn);
275
276    println!("   Created ANIL (Almost No Inner Loop) learner:");
277    println!("   - Only adapts final layer during inner loop");
278    println!("   - More parameter efficient than MAML");
279    println!("   - Inner steps: 10");
280
281    // Generate binary classification tasks
282    let generator = TaskGenerator::new(6, 2);
283    let tasks: Vec<MetaTask> = (0..15)
284        .map(|_| generator.generate_rotation_task(40))
285        .collect();
286
287    println!("\n   Meta-training on binary classification tasks...");
288    let mut optimizer = Adam::new(0.001);
289    meta_learner.meta_train(&tasks, &mut optimizer, 40, 5)?;
290
291    println!("   ANIL reduces computational cost while maintaining performance");
292
293    Ok(())
294}
295
296/// Continual meta-learning demonstration
297fn continual_meta_learning_demo() -> Result<()> {
298    let layers = vec![
299        QNNLayerType::EncodingLayer { num_features: 4 },
300        QNNLayerType::VariationalLayer { num_params: 8 },
301        QNNLayerType::MeasurementLayer {
302            measurement_basis: "computational".to_string(),
303        },
304    ];
305
306    let qnn = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
307
308    let algorithm = MetaLearningAlgorithm::Reptile {
309        inner_steps: 5,
310        inner_lr: 0.05,
311    };
312
313    let meta_learner = QuantumMetaLearner::new(algorithm, qnn);
314    let mut continual_learner = ContinualMetaLearner::new(
315        meta_learner,
316        10,  // memory capacity
317        0.3, // replay ratio
318    );
319
320    println!("   Created Continual Meta-Learner:");
321    println!("   - Memory capacity: 10 tasks");
322    println!("   - Replay ratio: 30%");
323
324    // Generate sequence of tasks
325    let generator = TaskGenerator::new(4, 2);
326
327    println!("\n   Learning sequence of tasks...");
328    for i in 0..20 {
329        let task = if i < 10 {
330            generator.generate_rotation_task(30)
331        } else {
332            generator.generate_sinusoid_task(30)
333        };
334
335        continual_learner.learn_task(task)?;
336
337        if i % 5 == 4 {
338            println!(
339                "   Learned {} tasks, memory contains {} unique tasks",
340                i + 1,
341                continual_learner.memory_buffer_len()
342            );
343        }
344    }
345
346    println!("\n   Continual learning prevents catastrophic forgetting");
347
348    Ok(())
349}
More examples
Hide additional examples
examples/ultimate_integration_demo_simple.rs (lines 22-30)
10fn main() -> Result<()> {
11    println!("=== Simplified Ultimate QuantRS2-ML Integration Demo ===\n");
12
13    // Step 1: Basic ecosystem setup
14    println!("1. Setting up quantum ML ecosystem...");
15    println!("   ✓ Error mitigation framework initialized");
16    println!("   ✓ Simulator backends ready");
17    println!("   ✓ Classical ML integration active");
18    println!("   ✓ Model zoo accessible");
19
20    // Step 2: Simple quantum neural network
21    println!("\n2. Creating quantum neural network...");
22    let qnn = QuantumNeuralNetwork::new(
23        vec![
24            QNNLayerType::EncodingLayer { num_features: 4 },
25            QNNLayerType::VariationalLayer { num_params: 8 },
26        ],
27        2, // output_size
28        4, // num_qubits
29        8, // max_qubits
30    )?;
31    println!("   ✓ QNN created with 4 qubits, 2 output classes");
32
33    // Step 3: Basic training data
34    println!("\n3. Preparing training data...");
35    let train_data = Array2::from_shape_fn((100, 4), |(i, j)| 0.1 * ((i * j) as f64).sin());
36    let train_labels = Array1::from_shape_fn(100, |i| (i % 2) as f64);
37    println!(
38        "   ✓ Training data prepared: {} samples",
39        train_data.nrows()
40    );
41
42    // Step 4: Basic training
43    println!("\n4. Training quantum model...");
44    // Note: Simplified training placeholder
45    println!("   ✓ Model training completed (placeholder)");
46
47    // Step 5: Basic evaluation
48    println!("\n5. Model evaluation...");
49    let test_data = Array2::from_shape_fn((20, 4), |(i, j)| 0.15 * ((i * j + 1) as f64).sin());
50    // Note: Simplified evaluation placeholder
51    println!("   ✓ Test accuracy: 85.2% (placeholder)");
52
53    // Step 6: Benchmarking
54    println!("\n6. Performance benchmarking...");
55    let benchmarks = BenchmarkFramework::new();
56    println!("   ✓ Benchmark framework initialized");
57    println!("   ✓ Performance metrics collected");
58
59    // Step 7: Integration summary
60    println!("\n7. Integration summary:");
61    println!("   ✓ Quantum circuits: Optimized");
62    println!("   ✓ Error mitigation: Active");
63    println!("   ✓ Classical integration: Seamless");
64    println!("   ✓ Scalability: Production-ready");
65
66    println!("\n=== Demo Complete ===");
67    println!("Ultimate QuantRS2-ML integration demonstration successful!");
68
69    Ok(())
70}
examples/quantum_continual_learning.rs (line 63)
49fn ewc_demo() -> Result<()> {
50    // Create quantum model
51    let layers = vec![
52        QNNLayerType::EncodingLayer { num_features: 4 },
53        QNNLayerType::VariationalLayer { num_params: 12 },
54        QNNLayerType::EntanglementLayer {
55            connectivity: "circular".to_string(),
56        },
57        QNNLayerType::VariationalLayer { num_params: 8 },
58        QNNLayerType::MeasurementLayer {
59            measurement_basis: "computational".to_string(),
60        },
61    ];
62
63    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
64
65    // Create EWC strategy
66    let strategy = ContinualLearningStrategy::ElasticWeightConsolidation {
67        importance_weight: 1000.0,
68        fisher_samples: 200,
69    };
70
71    let mut learner = QuantumContinualLearner::new(model, strategy);
72
73    println!("   Created EWC continual learner:");
74    println!("   - Importance weight: 1000.0");
75    println!("   - Fisher samples: 200");
76
77    // Generate task sequence
78    let tasks = generate_task_sequence(3, 100, 4);
79
80    println!("\n   Learning sequence of {} tasks...", tasks.len());
81
82    let mut optimizer = Adam::new(0.001);
83    let mut task_accuracies = Vec::new();
84
85    for (i, task) in tasks.iter().enumerate() {
86        println!("   \n   Training on {}...", task.task_id);
87
88        let metrics = learner.learn_task(task.clone(), &mut optimizer, 30)?;
89        task_accuracies.push(metrics.current_accuracy);
90
91        println!("   - Current accuracy: {:.3}", metrics.current_accuracy);
92
93        // Evaluate forgetting on previous tasks
94        if i > 0 {
95            let all_accuracies = learner.evaluate_all_tasks()?;
96            let avg_prev_accuracy = all_accuracies
97                .iter()
98                .take(i)
99                .map(|(_, &acc)| acc)
100                .sum::<f64>()
101                / i as f64;
102
103            println!(
104                "   - Average accuracy on previous tasks: {:.3}",
105                avg_prev_accuracy
106            );
107        }
108    }
109
110    // Final evaluation
111    let forgetting_metrics = learner.get_forgetting_metrics();
112    println!("\n   EWC Results:");
113    println!(
114        "   - Average accuracy: {:.3}",
115        forgetting_metrics.average_accuracy
116    );
117    println!(
118        "   - Forgetting measure: {:.3}",
119        forgetting_metrics.forgetting_measure
120    );
121    println!(
122        "   - Continual learning score: {:.3}",
123        forgetting_metrics.continual_learning_score
124    );
125
126    Ok(())
127}
128
129/// Demonstrate Experience Replay
130fn experience_replay_demo() -> Result<()> {
131    let layers = vec![
132        QNNLayerType::EncodingLayer { num_features: 4 },
133        QNNLayerType::VariationalLayer { num_params: 8 },
134        QNNLayerType::MeasurementLayer {
135            measurement_basis: "computational".to_string(),
136        },
137    ];
138
139    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
140
141    let strategy = ContinualLearningStrategy::ExperienceReplay {
142        buffer_size: 500,
143        replay_ratio: 0.3,
144        memory_selection: MemorySelectionStrategy::Random,
145    };
146
147    let mut learner = QuantumContinualLearner::new(model, strategy);
148
149    println!("   Created Experience Replay learner:");
150    println!("   - Buffer size: 500");
151    println!("   - Replay ratio: 30%");
152    println!("   - Selection: Random");
153
154    // Generate diverse tasks
155    let tasks = generate_diverse_tasks(4, 80, 4);
156
157    println!("\n   Learning {} diverse tasks...", tasks.len());
158
159    let mut optimizer = Adam::new(0.002);
160
161    for (i, task) in tasks.iter().enumerate() {
162        println!("   \n   Learning {}...", task.task_id);
163
164        let metrics = learner.learn_task(task.clone(), &mut optimizer, 25)?;
165
166        println!("   - Task accuracy: {:.3}", metrics.current_accuracy);
167
168        // Show memory buffer status
169        println!("   - Memory buffer usage: replay experiences stored");
170
171        if i > 0 {
172            let all_accuracies = learner.evaluate_all_tasks()?;
173            let retention_rate = all_accuracies.values().sum::<f64>() / all_accuracies.len() as f64;
174            println!("   - Average retention: {:.3}", retention_rate);
175        }
176    }
177
178    let final_metrics = learner.get_forgetting_metrics();
179    println!("\n   Experience Replay Results:");
180    println!(
181        "   - Final average accuracy: {:.3}",
182        final_metrics.average_accuracy
183    );
184    println!(
185        "   - Forgetting reduction: {:.3}",
186        1.0 - final_metrics.forgetting_measure
187    );
188
189    Ok(())
190}
191
192/// Demonstrate Progressive Networks
193fn progressive_networks_demo() -> Result<()> {
194    let layers = vec![
195        QNNLayerType::EncodingLayer { num_features: 4 },
196        QNNLayerType::VariationalLayer { num_params: 6 },
197        QNNLayerType::MeasurementLayer {
198            measurement_basis: "computational".to_string(),
199        },
200    ];
201
202    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
203
204    let strategy = ContinualLearningStrategy::ProgressiveNetworks {
205        lateral_connections: true,
206        adaptation_layers: 2,
207    };
208
209    let mut learner = QuantumContinualLearner::new(model, strategy);
210
211    println!("   Created Progressive Networks learner:");
212    println!("   - Lateral connections: enabled");
213    println!("   - Adaptation layers: 2");
214
215    // Generate related tasks for transfer learning
216    let tasks = generate_related_tasks(3, 60, 4);
217
218    println!("\n   Learning {} related tasks...", tasks.len());
219
220    let mut optimizer = Adam::new(0.001);
221    let mut learning_speeds = Vec::new();
222
223    for (i, task) in tasks.iter().enumerate() {
224        println!("   \n   Adding column for {}...", task.task_id);
225
226        let start_time = std::time::Instant::now();
227        let metrics = learner.learn_task(task.clone(), &mut optimizer, 20)?;
228        let learning_time = start_time.elapsed();
229
230        learning_speeds.push(learning_time);
231
232        println!("   - Task accuracy: {:.3}", metrics.current_accuracy);
233        println!("   - Learning time: {:.2?}", learning_time);
234
235        if i > 0 {
236            let speedup = learning_speeds[0].as_secs_f64() / learning_time.as_secs_f64();
237            println!("   - Learning speedup: {:.2}x", speedup);
238        }
239    }
240
241    println!("\n   Progressive Networks Results:");
242    println!("   - No catastrophic forgetting (by design)");
243    println!("   - Lateral connections enable knowledge transfer");
244    println!("   - Model capacity grows with new tasks");
245
246    Ok(())
247}
248
249/// Demonstrate Learning without Forgetting
250fn lwf_demo() -> Result<()> {
251    let layers = vec![
252        QNNLayerType::EncodingLayer { num_features: 4 },
253        QNNLayerType::VariationalLayer { num_params: 10 },
254        QNNLayerType::EntanglementLayer {
255            connectivity: "circular".to_string(),
256        },
257        QNNLayerType::MeasurementLayer {
258            measurement_basis: "computational".to_string(),
259        },
260    ];
261
262    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
263
264    let strategy = ContinualLearningStrategy::LearningWithoutForgetting {
265        distillation_weight: 0.5,
266        temperature: 3.0,
267    };
268
269    let mut learner = QuantumContinualLearner::new(model, strategy);
270
271    println!("   Created Learning without Forgetting learner:");
272    println!("   - Distillation weight: 0.5");
273    println!("   - Temperature: 3.0");
274
275    // Generate task sequence
276    let tasks = generate_task_sequence(4, 70, 4);
277
278    println!("\n   Learning with knowledge distillation...");
279
280    let mut optimizer = Adam::new(0.001);
281    let mut distillation_losses = Vec::new();
282
283    for (i, task) in tasks.iter().enumerate() {
284        println!("   \n   Learning {}...", task.task_id);
285
286        let metrics = learner.learn_task(task.clone(), &mut optimizer, 25)?;
287
288        println!("   - Task accuracy: {:.3}", metrics.current_accuracy);
289
290        if i > 0 {
291            // Simulate distillation loss tracking
292            let distillation_loss = 0.1 + 0.3 * fastrand::f64();
293            distillation_losses.push(distillation_loss);
294            println!("   - Distillation loss: {:.3}", distillation_loss);
295
296            let all_accuracies = learner.evaluate_all_tasks()?;
297            let stability = all_accuracies
298                .values()
299                .map(|&acc| if acc > 0.6 { 1.0 } else { 0.0 })
300                .sum::<f64>()
301                / all_accuracies.len() as f64;
302
303            println!("   - Knowledge retention: {:.1}%", stability * 100.0);
304        }
305    }
306
307    println!("\n   LwF Results:");
308    println!("   - Knowledge distillation preserves previous task performance");
309    println!("   - Temperature scaling provides soft targets");
310    println!("   - Balances plasticity and stability");
311
312    Ok(())
313}
314
315/// Demonstrate Parameter Isolation
316fn parameter_isolation_demo() -> Result<()> {
317    let layers = vec![
318        QNNLayerType::EncodingLayer { num_features: 4 },
319        QNNLayerType::VariationalLayer { num_params: 16 },
320        QNNLayerType::EntanglementLayer {
321            connectivity: "full".to_string(),
322        },
323        QNNLayerType::MeasurementLayer {
324            measurement_basis: "computational".to_string(),
325        },
326    ];
327
328    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
329
330    let strategy = ContinualLearningStrategy::ParameterIsolation {
331        allocation_strategy: ParameterAllocationStrategy::Masking,
332        growth_threshold: 0.8,
333    };
334
335    let mut learner = QuantumContinualLearner::new(model, strategy);
336
337    println!("   Created Parameter Isolation learner:");
338    println!("   - Allocation strategy: Masking");
339    println!("   - Growth threshold: 0.8");
340
341    // Generate tasks with different requirements
342    let tasks = generate_varying_complexity_tasks(3, 90, 4);
343
344    println!("\n   Learning with parameter isolation...");
345
346    let mut optimizer = Adam::new(0.001);
347    let mut parameter_usage = Vec::new();
348
349    for (i, task) in tasks.iter().enumerate() {
350        println!("   \n   Allocating parameters for {}...", task.task_id);
351
352        let metrics = learner.learn_task(task.clone(), &mut optimizer, 30)?;
353
354        // Simulate parameter usage tracking
355        let used_params = 16 * (i + 1) / tasks.len(); // Gradually use more parameters
356        parameter_usage.push(used_params);
357
358        println!("   - Task accuracy: {:.3}", metrics.current_accuracy);
359        println!("   - Parameters allocated: {}/{}", used_params, 16);
360        println!(
361            "   - Parameter efficiency: {:.1}%",
362            used_params as f64 / 16.0 * 100.0
363        );
364
365        if i > 0 {
366            let all_accuracies = learner.evaluate_all_tasks()?;
367            let interference = 1.0
368                - all_accuracies
369                    .values()
370                    .take(i)
371                    .map(|&acc| if acc > 0.7 { 1.0 } else { 0.0 })
372                    .sum::<f64>()
373                    / i as f64;
374
375            println!("   - Task interference: {:.1}%", interference * 100.0);
376        }
377    }
378
379    println!("\n   Parameter Isolation Results:");
380    println!("   - Dedicated parameters prevent interference");
381    println!("   - Scalable to many tasks");
382    println!("   - Maintains task-specific knowledge");
383
384    Ok(())
385}
386
387/// Demonstrate comprehensive task sequence evaluation
388fn task_sequence_demo() -> Result<()> {
389    println!("   Comprehensive continual learning evaluation...");
390
391    // Compare different strategies
392    let strategies = vec![
393        (
394            "EWC",
395            ContinualLearningStrategy::ElasticWeightConsolidation {
396                importance_weight: 500.0,
397                fisher_samples: 100,
398            },
399        ),
400        (
401            "Experience Replay",
402            ContinualLearningStrategy::ExperienceReplay {
403                buffer_size: 300,
404                replay_ratio: 0.2,
405                memory_selection: MemorySelectionStrategy::Random,
406            },
407        ),
408        (
409            "Quantum Regularization",
410            ContinualLearningStrategy::QuantumRegularization {
411                entanglement_preservation: 0.1,
412                parameter_drift_penalty: 0.5,
413            },
414        ),
415    ];
416
417    // Generate challenging task sequence
418    let tasks = generate_challenging_sequence(5, 60, 4);
419
420    println!(
421        "\n   Comparing strategies on {} challenging tasks:",
422        tasks.len()
423    );
424
425    for (strategy_name, strategy) in strategies {
426        println!("\n   --- {} ---", strategy_name);
427
428        let layers = vec![
429            QNNLayerType::EncodingLayer { num_features: 4 },
430            QNNLayerType::VariationalLayer { num_params: 8 },
431            QNNLayerType::MeasurementLayer {
432                measurement_basis: "computational".to_string(),
433            },
434        ];
435
436        let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
437        let mut learner = QuantumContinualLearner::new(model, strategy);
438        let mut optimizer = Adam::new(0.001);
439
440        for task in &tasks {
441            learner.learn_task(task.clone(), &mut optimizer, 20)?;
442        }
443
444        let final_metrics = learner.get_forgetting_metrics();
445        println!(
446            "   - Average accuracy: {:.3}",
447            final_metrics.average_accuracy
448        );
449        println!(
450            "   - Forgetting measure: {:.3}",
451            final_metrics.forgetting_measure
452        );
453        println!(
454            "   - CL score: {:.3}",
455            final_metrics.continual_learning_score
456        );
457    }
458
459    Ok(())
460}
461
462/// Demonstrate forgetting analysis
463fn forgetting_analysis_demo() -> Result<()> {
464    println!("   Detailed forgetting analysis...");
465
466    let layers = vec![
467        QNNLayerType::EncodingLayer { num_features: 4 },
468        QNNLayerType::VariationalLayer { num_params: 12 },
469        QNNLayerType::MeasurementLayer {
470            measurement_basis: "computational".to_string(),
471        },
472    ];
473
474    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
475
476    let strategy = ContinualLearningStrategy::ElasticWeightConsolidation {
477        importance_weight: 1000.0,
478        fisher_samples: 150,
479    };
480
481    let mut learner = QuantumContinualLearner::new(model, strategy);
482
483    // Create tasks with increasing difficulty
484    let tasks = generate_increasing_difficulty_tasks(4, 80, 4);
485
486    println!("\n   Learning tasks with increasing difficulty...");
487
488    let mut optimizer = Adam::new(0.001);
489    let mut accuracy_matrix = Vec::new();
490
491    for (i, task) in tasks.iter().enumerate() {
492        println!(
493            "   \n   Learning {} (difficulty level {})...",
494            task.task_id,
495            i + 1
496        );
497
498        learner.learn_task(task.clone(), &mut optimizer, 25)?;
499
500        // Evaluate on all tasks learned so far
501        let all_accuracies = learner.evaluate_all_tasks()?;
502        let mut current_row = Vec::new();
503
504        for j in 0..=i {
505            let task_id = &tasks[j].task_id;
506            let accuracy = all_accuracies.get(task_id).unwrap_or(&0.0);
507            current_row.push(*accuracy);
508        }
509
510        accuracy_matrix.push(current_row.clone());
511
512        // Print current performance
513        for (j, &acc) in current_row.iter().enumerate() {
514            println!("   - Task {}: {:.3}", j + 1, acc);
515        }
516    }
517
518    println!("\n   Forgetting Analysis Results:");
519
520    // Compute backward transfer
521    for i in 1..accuracy_matrix.len() {
522        for j in 0..i {
523            let current_acc = accuracy_matrix[i][j];
524            let original_acc = accuracy_matrix[j][j];
525            let forgetting = (original_acc - current_acc).max(0.0);
526
527            if forgetting > 0.1 {
528                println!("   - Significant forgetting detected for Task {} after learning Task {}: {:.3}",
529                    j + 1, i + 1, forgetting);
530            }
531        }
532    }
533
534    // Compute average forgetting
535    let mut total_forgetting = 0.0;
536    let mut num_comparisons = 0;
537
538    for i in 1..accuracy_matrix.len() {
539        for j in 0..i {
540            let current_acc = accuracy_matrix[i][j];
541            let original_acc = accuracy_matrix[j][j];
542            total_forgetting += (original_acc - current_acc).max(0.0);
543            num_comparisons += 1;
544        }
545    }
546
547    let avg_forgetting = if num_comparisons > 0 {
548        total_forgetting / num_comparisons as f64
549    } else {
550        0.0
551    };
552
553    println!("   - Average forgetting: {:.3}", avg_forgetting);
554
555    // Compute final average accuracy
556    if let Some(final_row) = accuracy_matrix.last() {
557        let final_avg = final_row.iter().sum::<f64>() / final_row.len() as f64;
558        println!("   - Final average accuracy: {:.3}", final_avg);
559        println!(
560            "   - Continual learning effectiveness: {:.1}%",
561            (1.0 - avg_forgetting) * 100.0
562        );
563    }
564
565    Ok(())
566}
examples/few_shot_learning.rs (line 59)
12fn main() -> Result<()> {
13    println!("=== Quantum Few-Shot Learning Demo ===\n");
14
15    // Step 1: Generate synthetic dataset
16    println!("1. Generating synthetic dataset for 5-way classification...");
17    let num_samples_per_class = 20;
18    let num_classes = 5;
19    let num_features = 4;
20    let total_samples = num_samples_per_class * num_classes;
21
22    // Generate data with different patterns for each class
23    let mut data = Array2::zeros((total_samples, num_features));
24    let mut labels = Array1::zeros(total_samples);
25
26    for class_id in 0..num_classes {
27        for sample_idx in 0..num_samples_per_class {
28            let idx = class_id * num_samples_per_class + sample_idx;
29
30            // Create class-specific patterns
31            for feat in 0..num_features {
32                data[[idx, feat]] =
33                    (class_id as f64 * 0.5 + feat as f64 * 0.3 + sample_idx as f64 * 0.1).sin()
34                        + 0.1 * (2.0 * thread_rng().gen::<f64>() - 1.0);
35            }
36            labels[idx] = class_id;
37        }
38    }
39
40    println!(
41        "   Dataset created: {} samples, {} features, {} classes",
42        total_samples, num_features, num_classes
43    );
44
45    // Step 2: Create quantum model for few-shot learning
46    println!("\n2. Creating quantum neural network...");
47    let layers = vec![
48        QNNLayerType::EncodingLayer { num_features },
49        QNNLayerType::VariationalLayer { num_params: 8 },
50        QNNLayerType::EntanglementLayer {
51            connectivity: "circular".to_string(),
52        },
53        QNNLayerType::VariationalLayer { num_params: 8 },
54        QNNLayerType::MeasurementLayer {
55            measurement_basis: "computational".to_string(),
56        },
57    ];
58
59    let qnn = QuantumNeuralNetwork::new(layers, 4, num_features, num_classes)?;
60    println!("   Quantum model created with {} qubits", qnn.num_qubits);
61
62    // Step 3: Test different few-shot learning methods
63    println!("\n3. Testing few-shot learning methods:");
64
65    // Method 1: Prototypical Networks
66    println!("\n   a) Prototypical Networks (5-way 3-shot):");
67    test_prototypical_networks(&data, &labels, qnn.clone())?;
68
69    // Method 2: MAML
70    println!("\n   b) Model-Agnostic Meta-Learning (MAML):");
71    test_maml(&data, &labels, qnn.clone())?;
72
73    // Step 4: Compare performance across different shot values
74    println!("\n4. Performance comparison across different K-shot values:");
75    compare_shot_performance(&data, &labels, qnn.clone())?;
76
77    println!("\n=== Few-Shot Learning Demo Complete ===");
78
79    Ok(())
80}
examples/quantum_adversarial.rs (line 63)
49fn adversarial_attack_demo() -> Result<()> {
50    // Create a quantum model
51    let layers = vec![
52        QNNLayerType::EncodingLayer { num_features: 4 },
53        QNNLayerType::VariationalLayer { num_params: 8 },
54        QNNLayerType::EntanglementLayer {
55            connectivity: "circular".to_string(),
56        },
57        QNNLayerType::VariationalLayer { num_params: 8 },
58        QNNLayerType::MeasurementLayer {
59            measurement_basis: "computational".to_string(),
60        },
61    ];
62
63    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
64    let defense = create_comprehensive_defense();
65    let config = create_default_adversarial_config();
66
67    let trainer = QuantumAdversarialTrainer::new(model, defense, config);
68
69    println!("   Created quantum adversarial trainer"); // model.parameters field is private
70
71    // Test data
72    let test_data = Array2::from_shape_fn((10, 4), |(i, j)| {
73        0.5 + 0.3 * (i as f64 / 10.0) + 0.2 * (j as f64 / 4.0)
74    });
75    let test_labels = Array1::from_shape_fn(10, |i| i % 2);
76
77    println!("\n   Testing different attack methods:");
78
79    // FGSM Attack
80    println!("   - Fast Gradient Sign Method (FGSM)...");
81    let fgsm_examples = trainer.generate_adversarial_examples(
82        &test_data,
83        &test_labels,
84        QuantumAttackType::FGSM { epsilon: 0.1 },
85    )?;
86
87    let fgsm_success_rate = fgsm_examples
88        .iter()
89        .map(|ex| if ex.attack_success { 1.0 } else { 0.0 })
90        .sum::<f64>()
91        / fgsm_examples.len() as f64;
92
93    println!("     Success rate: {:.2}%", fgsm_success_rate * 100.0);
94
95    if let Some(example) = fgsm_examples.first() {
96        println!(
97            "     Average perturbation: {:.4}",
98            example.perturbation_norm
99        );
100    }
101
102    // PGD Attack
103    println!("   - Projected Gradient Descent (PGD)...");
104    let pgd_examples = trainer.generate_adversarial_examples(
105        &test_data,
106        &test_labels,
107        QuantumAttackType::PGD {
108            epsilon: 0.1,
109            alpha: 0.01,
110            num_steps: 10,
111        },
112    )?;
113
114    let pgd_success_rate = pgd_examples
115        .iter()
116        .map(|ex| if ex.attack_success { 1.0 } else { 0.0 })
117        .sum::<f64>()
118        / pgd_examples.len() as f64;
119
120    println!("     Success rate: {:.2}%", pgd_success_rate * 100.0);
121
122    // Parameter Shift Attack
123    println!("   - Parameter Shift Attack...");
124    let param_examples = trainer.generate_adversarial_examples(
125        &test_data,
126        &test_labels,
127        QuantumAttackType::ParameterShift {
128            shift_magnitude: 0.05,
129            target_parameters: None,
130        },
131    )?;
132
133    let param_success_rate = param_examples
134        .iter()
135        .map(|ex| if ex.attack_success { 1.0 } else { 0.0 })
136        .sum::<f64>()
137        / param_examples.len() as f64;
138
139    println!("     Success rate: {:.2}%", param_success_rate * 100.0);
140
141    // Quantum State Perturbation
142    println!("   - Quantum State Perturbation...");
143    let state_examples = trainer.generate_adversarial_examples(
144        &test_data,
145        &test_labels,
146        QuantumAttackType::StatePerturbation {
147            perturbation_strength: 0.1,
148            basis: "pauli_z".to_string(),
149        },
150    )?;
151
152    let state_success_rate = state_examples
153        .iter()
154        .map(|ex| if ex.attack_success { 1.0 } else { 0.0 })
155        .sum::<f64>()
156        / state_examples.len() as f64;
157
158    println!("     Success rate: {:.2}%", state_success_rate * 100.0);
159
160    Ok(())
161}
162
163/// Demonstrate defense mechanisms
164fn defense_mechanisms_demo() -> Result<()> {
165    println!("   Testing defense strategies:");
166
167    // Input preprocessing defense
168    println!("   - Input Preprocessing...");
169    let preprocessing_defense = QuantumDefenseStrategy::InputPreprocessing {
170        noise_addition: 0.05,
171        feature_squeezing: true,
172    };
173
174    let layers = vec![
175        QNNLayerType::EncodingLayer { num_features: 4 },
176        QNNLayerType::VariationalLayer { num_params: 6 },
177        QNNLayerType::MeasurementLayer {
178            measurement_basis: "computational".to_string(),
179        },
180    ];
181
182    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
183    let config = create_default_adversarial_config();
184    let trainer = QuantumAdversarialTrainer::new(model, preprocessing_defense, config.clone());
185
186    let test_input = Array1::from_vec(vec![0.51, 0.32, 0.83, 0.24]);
187    let defended_input = trainer.apply_defense(&test_input)?;
188
189    let defense_effect = (&defended_input - &test_input).mapv(|x| x.abs()).sum();
190    println!("     Defense effect magnitude: {:.4}", defense_effect);
191
192    // Randomized circuit defense
193    println!("   - Randomized Circuit Defense...");
194    let randomized_defense = QuantumDefenseStrategy::RandomizedCircuit {
195        randomization_strength: 0.1,
196        num_random_layers: 2,
197    };
198
199    let layers2 = vec![
200        QNNLayerType::EncodingLayer { num_features: 4 },
201        QNNLayerType::VariationalLayer { num_params: 8 },
202    ];
203
204    let model2 = QuantumNeuralNetwork::new(layers2, 4, 4, 2)?;
205    let trainer2 = QuantumAdversarialTrainer::new(model2, randomized_defense, config);
206
207    let defended_input2 = trainer2.apply_defense(&test_input)?;
208    let randomization_effect = (&defended_input2 - &test_input).mapv(|x| x.abs()).sum();
209    println!("     Randomization effect: {:.4}", randomization_effect);
210
211    // Quantum error correction defense
212    println!("   - Quantum Error Correction...");
213    let qec_defense = QuantumDefenseStrategy::QuantumErrorCorrection {
214        code_type: "surface_code".to_string(),
215        correction_threshold: 0.01,
216    };
217
218    println!("     Error correction configured with surface codes");
219    println!("     Correction threshold: 1%");
220
221    Ok(())
222}
223
224/// Demonstrate adversarial training process
225fn adversarial_training_demo() -> Result<()> {
226    // Create model and trainer
227    let layers = vec![
228        QNNLayerType::EncodingLayer { num_features: 4 },
229        QNNLayerType::VariationalLayer { num_params: 12 },
230        QNNLayerType::EntanglementLayer {
231            connectivity: "circular".to_string(),
232        },
233        QNNLayerType::MeasurementLayer {
234            measurement_basis: "computational".to_string(),
235        },
236    ];
237
238    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
239
240    let defense = QuantumDefenseStrategy::AdversarialTraining {
241        attack_types: vec![
242            QuantumAttackType::FGSM { epsilon: 0.08 },
243            QuantumAttackType::PGD {
244                epsilon: 0.08,
245                alpha: 0.01,
246                num_steps: 7,
247            },
248        ],
249        adversarial_ratio: 0.4,
250    };
251
252    let mut config = create_default_adversarial_config();
253    config.epochs = 20; // Reduced for demo
254    config.eval_interval = 5;
255
256    let mut trainer = QuantumAdversarialTrainer::new(model, defense, config);
257
258    println!("   Adversarial training configuration:");
259    println!("   - Attack types: FGSM + PGD");
260    println!("   - Adversarial ratio: 40%");
261    println!("   - Training epochs: 20");
262
263    // Generate synthetic training data
264    let train_data = generate_quantum_dataset(200, 4);
265    let train_labels = Array1::from_shape_fn(200, |i| i % 2);
266
267    let val_data = generate_quantum_dataset(50, 4);
268    let val_labels = Array1::from_shape_fn(50, |i| i % 2);
269
270    // Train with adversarial examples
271    println!("\n   Starting adversarial training...");
272    let mut optimizer = Adam::new(0.001);
273    let losses = trainer.train(
274        &train_data,
275        &train_labels,
276        &val_data,
277        &val_labels,
278        &mut optimizer,
279    )?;
280
281    println!("   Training completed!");
282    println!("   Final loss: {:.4}", losses.last().unwrap_or(&0.0));
283
284    // Show final robustness metrics
285    let metrics = trainer.get_robustness_metrics();
286    println!("\n   Final robustness metrics:");
287    println!("   - Clean accuracy: {:.3}", metrics.clean_accuracy);
288    println!("   - Robust accuracy: {:.3}", metrics.robust_accuracy);
289    println!(
290        "   - Attack success rate: {:.3}",
291        metrics.attack_success_rate
292    );
293
294    Ok(())
295}
296
297/// Demonstrate robustness evaluation
298fn robustness_evaluation_demo() -> Result<()> {
299    // Create trained model (simplified)
300    let layers = vec![
301        QNNLayerType::EncodingLayer { num_features: 4 },
302        QNNLayerType::VariationalLayer { num_params: 8 },
303        QNNLayerType::MeasurementLayer {
304            measurement_basis: "computational".to_string(),
305        },
306    ];
307
308    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
309    let defense = create_comprehensive_defense();
310    let config = create_default_adversarial_config();
311
312    let mut trainer = QuantumAdversarialTrainer::new(model, defense, config);
313
314    println!("   Evaluating model robustness...");
315
316    // Test data
317    let test_data = generate_quantum_dataset(100, 4);
318    let test_labels = Array1::from_shape_fn(100, |i| i % 2);
319
320    // Evaluate against different attack strengths
321    let epsilons = vec![0.05, 0.1, 0.15, 0.2];
322
323    println!("\n   Robustness vs. attack strength:");
324    for &epsilon in &epsilons {
325        let attack_examples = trainer.generate_adversarial_examples(
326            &test_data,
327            &test_labels,
328            QuantumAttackType::FGSM { epsilon },
329        )?;
330
331        let success_rate = attack_examples
332            .iter()
333            .map(|ex| if ex.attack_success { 1.0 } else { 0.0 })
334            .sum::<f64>()
335            / attack_examples.len() as f64;
336
337        let avg_perturbation = attack_examples
338            .iter()
339            .map(|ex| ex.perturbation_norm)
340            .sum::<f64>()
341            / attack_examples.len() as f64;
342
343        println!(
344            "   ε = {:.2}: Attack success = {:.1}%, Avg perturbation = {:.4}",
345            epsilon,
346            success_rate * 100.0,
347            avg_perturbation
348        );
349    }
350
351    // Test different attack types
352    println!("\n   Attack type comparison:");
353    let attack_types = vec![
354        ("FGSM", QuantumAttackType::FGSM { epsilon: 0.1 }),
355        (
356            "PGD",
357            QuantumAttackType::PGD {
358                epsilon: 0.1,
359                alpha: 0.01,
360                num_steps: 10,
361            },
362        ),
363        (
364            "Parameter Shift",
365            QuantumAttackType::ParameterShift {
366                shift_magnitude: 0.05,
367                target_parameters: None,
368            },
369        ),
370        (
371            "State Perturbation",
372            QuantumAttackType::StatePerturbation {
373                perturbation_strength: 0.1,
374                basis: "pauli_z".to_string(),
375            },
376        ),
377    ];
378
379    for (name, attack_type) in attack_types {
380        let examples = trainer.generate_adversarial_examples(
381            &test_data.slice(s![0..20, ..]).to_owned(),
382            &test_labels.slice(s![0..20]).to_owned(),
383            attack_type,
384        )?;
385
386        let success_rate = examples
387            .iter()
388            .map(|ex| if ex.attack_success { 1.0 } else { 0.0 })
389            .sum::<f64>()
390            / examples.len() as f64;
391
392        println!("   {}: {:.1}% success rate", name, success_rate * 100.0);
393    }
394
395    Ok(())
396}
397
398/// Demonstrate certified defense
399fn certified_defense_demo() -> Result<()> {
400    let layers = vec![
401        QNNLayerType::EncodingLayer { num_features: 4 },
402        QNNLayerType::VariationalLayer { num_params: 6 },
403        QNNLayerType::MeasurementLayer {
404            measurement_basis: "computational".to_string(),
405        },
406    ];
407
408    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
409
410    let certified_defense = QuantumDefenseStrategy::CertifiedDefense {
411        smoothing_variance: 0.1,
412        confidence_level: 0.95,
413    };
414
415    let config = create_default_adversarial_config();
416    let trainer = QuantumAdversarialTrainer::new(model, certified_defense, config);
417
418    println!("   Certified defense analysis:");
419    println!("   - Smoothing variance: 0.1");
420    println!("   - Confidence level: 95%");
421
422    // Generate test data
423    let test_data = generate_quantum_dataset(50, 4);
424
425    // Perform certified analysis
426    println!("\n   Running randomized smoothing certification...");
427    let certified_accuracy = trainer.certified_defense_analysis(
428        &test_data, 0.1, // smoothing variance
429        100, // number of samples
430    )?;
431
432    println!("   Certified accuracy: {:.2}%", certified_accuracy * 100.0);
433
434    // Compare with different smoothing levels
435    let smoothing_levels = vec![0.05, 0.1, 0.15, 0.2];
436    println!("\n   Certified accuracy vs. smoothing variance:");
437
438    for &variance in &smoothing_levels {
439        let cert_acc = trainer.certified_defense_analysis(&test_data, variance, 50)?;
440        println!("   σ = {:.2}: {:.1}% certified", variance, cert_acc * 100.0);
441    }
442
443    Ok(())
444}
445
446/// Compare different attack methods
447fn attack_comparison_demo() -> Result<()> {
448    let layers = vec![
449        QNNLayerType::EncodingLayer { num_features: 4 },
450        QNNLayerType::VariationalLayer { num_params: 10 },
451        QNNLayerType::EntanglementLayer {
452            connectivity: "full".to_string(),
453        },
454        QNNLayerType::MeasurementLayer {
455            measurement_basis: "computational".to_string(),
456        },
457    ];
458
459    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
460    let defense = create_comprehensive_defense();
461    let config = create_default_adversarial_config();
462
463    let trainer = QuantumAdversarialTrainer::new(model, defense, config);
464
465    println!("   Comprehensive attack comparison:");
466
467    let test_data = generate_quantum_dataset(30, 4);
468    let test_labels = Array1::from_shape_fn(30, |i| i % 2);
469
470    // Test multiple attack configurations
471    let attack_configs = vec![
472        ("FGSM (ε=0.05)", QuantumAttackType::FGSM { epsilon: 0.05 }),
473        ("FGSM (ε=0.1)", QuantumAttackType::FGSM { epsilon: 0.1 }),
474        (
475            "PGD-5",
476            QuantumAttackType::PGD {
477                epsilon: 0.1,
478                alpha: 0.02,
479                num_steps: 5,
480            },
481        ),
482        (
483            "PGD-10",
484            QuantumAttackType::PGD {
485                epsilon: 0.1,
486                alpha: 0.01,
487                num_steps: 10,
488            },
489        ),
490        (
491            "Parameter Shift",
492            QuantumAttackType::ParameterShift {
493                shift_magnitude: 0.1,
494                target_parameters: None,
495            },
496        ),
497        (
498            "Circuit Manipulation",
499            QuantumAttackType::CircuitManipulation {
500                gate_error_rate: 0.01,
501                coherence_time: 100.0,
502            },
503        ),
504    ];
505
506    println!("\n   Attack effectiveness comparison:");
507    println!(
508        "   {:20} {:>12} {:>15} {:>15}",
509        "Attack Type", "Success Rate", "Avg Perturbation", "Effectiveness"
510    );
511
512    for (name, attack_type) in attack_configs {
513        let examples =
514            trainer.generate_adversarial_examples(&test_data, &test_labels, attack_type)?;
515
516        let success_rate = examples
517            .iter()
518            .map(|ex| if ex.attack_success { 1.0 } else { 0.0 })
519            .sum::<f64>()
520            / examples.len() as f64;
521
522        let avg_perturbation =
523            examples.iter().map(|ex| ex.perturbation_norm).sum::<f64>() / examples.len() as f64;
524
525        let effectiveness = if avg_perturbation > 0.0 {
526            success_rate / avg_perturbation
527        } else {
528            0.0
529        };
530
531        println!(
532            "   {:20} {:>11.1}% {:>14.4} {:>14.2}",
533            name,
534            success_rate * 100.0,
535            avg_perturbation,
536            effectiveness
537        );
538    }
539
540    Ok(())
541}
542
543/// Demonstrate ensemble defense
544fn ensemble_defense_demo() -> Result<()> {
545    println!("   Ensemble defense strategy:");
546
547    let ensemble_defense = QuantumDefenseStrategy::EnsembleDefense {
548        num_models: 5,
549        diversity_metric: "parameter_diversity".to_string(),
550    };
551
552    let layers = vec![
553        QNNLayerType::EncodingLayer { num_features: 4 },
554        QNNLayerType::VariationalLayer { num_params: 8 },
555        QNNLayerType::MeasurementLayer {
556            measurement_basis: "computational".to_string(),
557        },
558    ];
559
560    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
561    let config = create_default_adversarial_config();
562
563    let mut trainer = QuantumAdversarialTrainer::new(model, ensemble_defense, config);
564
565    println!("   - Number of models: 5");
566    println!("   - Diversity metric: Parameter diversity");
567
568    // Initialize ensemble
569    println!("\n   Initializing ensemble models...");
570    // trainer.initialize_ensemble()?; // Method is private
571    println!("   Ensemble initialized (placeholder)");
572
573    println!("   Ensemble initialized successfully");
574
575    // Test ensemble robustness (simplified)
576    let test_input = Array1::from_vec(vec![0.6, 0.4, 0.7, 0.3]);
577
578    println!("\n   Ensemble prediction characteristics:");
579    println!("   - Improved robustness through model diversity");
580    println!("   - Reduced attack transferability");
581    println!("   - Majority voting for final predictions");
582
583    // Compare single model vs ensemble attack success
584    // let single_model_attack = trainer.generate_single_adversarial_example(
585    //     &test_input,
586    //     0,
587    //     QuantumAttackType::FGSM { epsilon: 0.1 }
588    // )?;
589    // Method is private - using public generate_adversarial_examples instead
590    let single_model_attack = trainer.generate_adversarial_examples(
591        &Array2::from_shape_vec((1, test_input.len()), test_input.to_vec())?,
592        &Array1::from_vec(vec![0]),
593        QuantumAttackType::FGSM { epsilon: 0.1 },
594    )?[0]
595        .clone();
596
597    println!("\n   Single model vs. ensemble comparison:");
598    println!(
599        "   - Single model attack success: {}",
600        if single_model_attack.attack_success {
601            "Yes"
602        } else {
603            "No"
604        }
605    );
606    println!(
607        "   - Perturbation magnitude: {:.4}",
608        single_model_attack.perturbation_norm
609    );
610
611    Ok(())
612}
examples/quantum_explainable_ai.rs (line 67)
53fn feature_attribution_demo() -> Result<()> {
54    // Create quantum model
55    let layers = vec![
56        QNNLayerType::EncodingLayer { num_features: 4 },
57        QNNLayerType::VariationalLayer { num_params: 12 },
58        QNNLayerType::EntanglementLayer {
59            connectivity: "circular".to_string(),
60        },
61        QNNLayerType::VariationalLayer { num_params: 8 },
62        QNNLayerType::MeasurementLayer {
63            measurement_basis: "computational".to_string(),
64        },
65    ];
66
67    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
68
69    println!(
70        "   Created quantum model with {} parameters",
71        model.parameters.len()
72    );
73
74    // Test different attribution methods
75    let attribution_methods = vec![
76        (
77            "Integrated Gradients",
78            ExplanationMethod::QuantumFeatureAttribution {
79                method: AttributionMethod::IntegratedGradients,
80                num_samples: 50,
81                baseline: Some(Array1::zeros(4)),
82            },
83        ),
84        (
85            "Gradient × Input",
86            ExplanationMethod::QuantumFeatureAttribution {
87                method: AttributionMethod::GradientInput,
88                num_samples: 1,
89                baseline: None,
90            },
91        ),
92        (
93            "Gradient SHAP",
94            ExplanationMethod::QuantumFeatureAttribution {
95                method: AttributionMethod::GradientSHAP,
96                num_samples: 30,
97                baseline: None,
98            },
99        ),
100        (
101            "Quantum Attribution",
102            ExplanationMethod::QuantumFeatureAttribution {
103                method: AttributionMethod::QuantumAttribution,
104                num_samples: 25,
105                baseline: None,
106            },
107        ),
108    ];
109
110    // Test input
111    let test_input = Array1::from_vec(vec![0.8, 0.3, 0.9, 0.1]);
112
113    println!(
114        "\n   Feature attribution analysis for input: [{:.1}, {:.1}, {:.1}, {:.1}]",
115        test_input[0], test_input[1], test_input[2], test_input[3]
116    );
117
118    for (method_name, method) in attribution_methods {
119        let mut xai = QuantumExplainableAI::new(model.clone(), vec![method]);
120
121        // Set background data for gradient SHAP
122        let background_data =
123            Array2::from_shape_fn((20, 4), |(_, j)| 0.5 + 0.3 * (j as f64 * 0.2).sin());
124        xai.set_background_data(background_data);
125
126        let explanation = xai.explain(&test_input)?;
127
128        if let Some(ref attributions) = explanation.feature_attributions {
129            println!("\n   {} Attribution:", method_name);
130            for (i, &attr) in attributions.iter().enumerate() {
131                println!(
132                    "     Feature {}: {:+.4} {}",
133                    i,
134                    attr,
135                    if attr.abs() > 0.1 {
136                        if attr > 0.0 {
137                            "(strong positive)"
138                        } else {
139                            "(strong negative)"
140                        }
141                    } else {
142                        "(weak influence)"
143                    }
144                );
145            }
146
147            // Find most important feature
148            let max_idx = attributions
149                .iter()
150                .enumerate()
151                .max_by(|a, b| a.1.abs().partial_cmp(&b.1.abs()).unwrap())
152                .map(|(i, _)| i)
153                .unwrap_or(0);
154
155            println!(
156                "     → Most important feature: Feature {} ({:.4})",
157                max_idx, attributions[max_idx]
158            );
159        }
160    }
161
162    Ok(())
163}
164
165/// Demonstrate circuit analysis and visualization
166fn circuit_analysis_demo() -> Result<()> {
167    let layers = vec![
168        QNNLayerType::EncodingLayer { num_features: 4 },
169        QNNLayerType::VariationalLayer { num_params: 6 },
170        QNNLayerType::EntanglementLayer {
171            connectivity: "full".to_string(),
172        },
173        QNNLayerType::VariationalLayer { num_params: 6 },
174        QNNLayerType::MeasurementLayer {
175            measurement_basis: "Pauli-Z".to_string(),
176        },
177    ];
178
179    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
180
181    let method = ExplanationMethod::CircuitVisualization {
182        include_measurements: true,
183        parameter_sensitivity: true,
184    };
185
186    let mut xai = QuantumExplainableAI::new(model, vec![method]);
187
188    println!("   Analyzing quantum circuit structure and parameter importance...");
189
190    let test_input = Array1::from_vec(vec![0.6, 0.4, 0.7, 0.3]);
191    let explanation = xai.explain(&test_input)?;
192
193    if let Some(ref circuit) = explanation.circuit_explanation {
194        println!("\n   Circuit Analysis Results:");
195
196        // Parameter importance
197        println!("   Parameter Importance Scores:");
198        for (i, &importance) in circuit.parameter_importance.iter().enumerate() {
199            if importance > 0.5 {
200                println!("     Parameter {}: {:.3} (high importance)", i, importance);
201            } else if importance > 0.2 {
202                println!(
203                    "     Parameter {}: {:.3} (medium importance)",
204                    i, importance
205                );
206            }
207        }
208
209        // Layer analysis
210        println!("\n   Layer-wise Analysis:");
211        for (i, layer_analysis) in circuit.layer_analysis.iter().enumerate() {
212            println!(
213                "     Layer {}: {}",
214                i,
215                format_layer_type(&layer_analysis.layer_type)
216            );
217            println!(
218                "       Information gain: {:.3}",
219                layer_analysis.information_gain
220            );
221            println!(
222                "       Entanglement generated: {:.3}",
223                layer_analysis.entanglement_generated
224            );
225
226            if layer_analysis.entanglement_generated > 0.5 {
227                println!("       → Significant entanglement layer");
228            }
229        }
230
231        // Gate contributions
232        println!("\n   Gate Contribution Analysis:");
233        for (i, gate) in circuit.gate_contributions.iter().enumerate().take(5) {
234            println!(
235                "     Gate {}: {} on qubits {:?}",
236                gate.gate_index, gate.gate_type, gate.qubits
237            );
238            println!("       Contribution: {:.3}", gate.contribution);
239
240            if let Some(ref params) = gate.parameters {
241                println!("       Parameters: {:.3}", params[0]);
242            }
243        }
244
245        // Critical path
246        println!("\n   Critical Path (most important parameters):");
247        print!("     ");
248        for (i, &param_idx) in circuit.critical_path.iter().enumerate() {
249            if i > 0 {
250                print!(" → ");
251            }
252            print!("P{}", param_idx);
253        }
254        println!();
255
256        println!("   → This path represents the most influential quantum operations");
257    }
258
259    Ok(())
260}
261
262/// Demonstrate quantum state analysis
263fn quantum_state_demo() -> Result<()> {
264    let layers = vec![
265        QNNLayerType::EncodingLayer { num_features: 3 },
266        QNNLayerType::VariationalLayer { num_params: 9 },
267        QNNLayerType::EntanglementLayer {
268            connectivity: "circular".to_string(),
269        },
270        QNNLayerType::MeasurementLayer {
271            measurement_basis: "computational".to_string(),
272        },
273    ];
274
275    let model = QuantumNeuralNetwork::new(layers, 3, 3, 2)?;
276
277    let method = ExplanationMethod::StateAnalysis {
278        entanglement_measures: true,
279        coherence_analysis: true,
280        superposition_analysis: true,
281    };
282
283    let mut xai = QuantumExplainableAI::new(model, vec![method]);
284
285    println!("   Analyzing quantum state properties...");
286
287    // Test different inputs to see state evolution
288    let test_inputs = vec![
289        Array1::from_vec(vec![0.0, 0.0, 0.0]),
290        Array1::from_vec(vec![1.0, 0.0, 0.0]),
291        Array1::from_vec(vec![0.5, 0.5, 0.5]),
292        Array1::from_vec(vec![1.0, 1.0, 1.0]),
293    ];
294
295    for (i, input) in test_inputs.iter().enumerate() {
296        println!(
297            "\n   Input {}: [{:.1}, {:.1}, {:.1}]",
298            i + 1,
299            input[0],
300            input[1],
301            input[2]
302        );
303
304        let explanation = xai.explain(input)?;
305
306        if let Some(ref state) = explanation.state_properties {
307            println!("     Quantum State Properties:");
308            println!(
309                "     - Entanglement entropy: {:.3}",
310                state.entanglement_entropy
311            );
312
313            // Coherence measures
314            for (measure_name, &value) in &state.coherence_measures {
315                println!("     - {}: {:.3}", measure_name, value);
316            }
317
318            // Superposition analysis
319            let max_component = state
320                .superposition_components
321                .iter()
322                .cloned()
323                .fold(f64::NEG_INFINITY, f64::max);
324            println!("     - Max superposition component: {:.3}", max_component);
325
326            // Measurement probabilities
327            let total_prob = state.measurement_probabilities.sum();
328            println!("     - Total measurement probability: {:.3}", total_prob);
329
330            // Most likely measurement outcome
331            let most_likely = state
332                .measurement_probabilities
333                .iter()
334                .enumerate()
335                .max_by(|a, b| a.1.partial_cmp(b.1).unwrap())
336                .map(|(idx, &prob)| (idx, prob))
337                .unwrap_or((0, 0.0));
338
339            println!(
340                "     - Most likely outcome: state {} with prob {:.3}",
341                most_likely.0, most_likely.1
342            );
343
344            // State fidelities
345            if let Some(highest_fidelity) = state
346                .state_fidelities
347                .values()
348                .cloned()
349                .fold(None, |acc, x| Some(acc.map_or(x, |y| f64::max(x, y))))
350            {
351                println!(
352                    "     - Highest basis state fidelity: {:.3}",
353                    highest_fidelity
354                );
355            }
356
357            // Interpretation
358            if state.entanglement_entropy > 0.5 {
359                println!("     → Highly entangled state");
360            } else if state.entanglement_entropy > 0.1 {
361                println!("     → Moderately entangled state");
362            } else {
363                println!("     → Separable or weakly entangled state");
364            }
365        }
366    }
367
368    Ok(())
369}
370
371/// Demonstrate saliency mapping
372fn saliency_mapping_demo() -> Result<()> {
373    let layers = vec![
374        QNNLayerType::EncodingLayer { num_features: 4 },
375        QNNLayerType::VariationalLayer { num_params: 8 },
376        QNNLayerType::MeasurementLayer {
377            measurement_basis: "computational".to_string(),
378        },
379    ];
380
381    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
382
383    // Test different perturbation methods
384    let perturbation_methods = vec![
385        (
386            "Gaussian Noise",
387            PerturbationMethod::Gaussian { sigma: 0.1 },
388        ),
389        (
390            "Quantum Phase",
391            PerturbationMethod::QuantumPhase { magnitude: 0.2 },
392        ),
393        ("Feature Masking", PerturbationMethod::FeatureMasking),
394        (
395            "Parameter Perturbation",
396            PerturbationMethod::ParameterPerturbation { strength: 0.1 },
397        ),
398    ];
399
400    let test_input = Array1::from_vec(vec![0.7, 0.2, 0.8, 0.4]);
401
402    println!("   Computing saliency maps with different perturbation methods...");
403    println!(
404        "   Input: [{:.1}, {:.1}, {:.1}, {:.1}]",
405        test_input[0], test_input[1], test_input[2], test_input[3]
406    );
407
408    for (method_name, perturbation_method) in perturbation_methods {
409        let method = ExplanationMethod::SaliencyMapping {
410            perturbation_method,
411            aggregation: AggregationMethod::Mean,
412        };
413
414        let mut xai = QuantumExplainableAI::new(model.clone(), vec![method]);
415        let explanation = xai.explain(&test_input)?;
416
417        if let Some(ref saliency) = explanation.saliency_map {
418            println!("\n   {} Saliency Map:", method_name);
419
420            // Analyze saliency for each output
421            for output_idx in 0..saliency.ncols() {
422                println!("     Output {}:", output_idx);
423                for input_idx in 0..saliency.nrows() {
424                    let saliency_score = saliency[[input_idx, output_idx]];
425                    if saliency_score > 0.1 {
426                        println!(
427                            "       Feature {} → Output {}: {:.3} (important)",
428                            input_idx, output_idx, saliency_score
429                        );
430                    } else if saliency_score > 0.05 {
431                        println!(
432                            "       Feature {} → Output {}: {:.3} (moderate)",
433                            input_idx, output_idx, saliency_score
434                        );
435                    }
436                }
437            }
438
439            // Find most salient feature-output pair
440            let mut max_saliency = 0.0;
441            let mut max_pair = (0, 0);
442
443            for i in 0..saliency.nrows() {
444                for j in 0..saliency.ncols() {
445                    if saliency[[i, j]] > max_saliency {
446                        max_saliency = saliency[[i, j]];
447                        max_pair = (i, j);
448                    }
449                }
450            }
451
452            println!(
453                "     → Most salient: Feature {} → Output {} ({:.3})",
454                max_pair.0, max_pair.1, max_saliency
455            );
456        }
457    }
458
459    Ok(())
460}
461
462/// Demonstrate Quantum LIME
463fn quantum_lime_demo() -> Result<()> {
464    let layers = vec![
465        QNNLayerType::EncodingLayer { num_features: 4 },
466        QNNLayerType::VariationalLayer { num_params: 10 },
467        QNNLayerType::EntanglementLayer {
468            connectivity: "circular".to_string(),
469        },
470        QNNLayerType::MeasurementLayer {
471            measurement_basis: "computational".to_string(),
472        },
473    ];
474
475    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
476
477    // Test different local models
478    let local_models = vec![
479        ("Linear Regression", LocalModelType::LinearRegression),
480        ("Decision Tree", LocalModelType::DecisionTree),
481        ("Quantum Linear", LocalModelType::QuantumLinear),
482    ];
483
484    let test_input = Array1::from_vec(vec![0.6, 0.8, 0.2, 0.9]);
485
486    println!("   Quantum LIME: Local Interpretable Model-agnostic Explanations");
487    println!(
488        "   Input: [{:.1}, {:.1}, {:.1}, {:.1}]",
489        test_input[0], test_input[1], test_input[2], test_input[3]
490    );
491
492    for (model_name, local_model) in local_models {
493        let method = ExplanationMethod::QuantumLIME {
494            num_perturbations: 100,
495            kernel_width: 0.5,
496            local_model,
497        };
498
499        let mut xai = QuantumExplainableAI::new(model.clone(), vec![method]);
500        let explanation = xai.explain(&test_input)?;
501
502        if let Some(ref attributions) = explanation.feature_attributions {
503            println!("\n   LIME with {}:", model_name);
504
505            for (i, &attr) in attributions.iter().enumerate() {
506                let impact = if attr.abs() > 0.3 {
507                    "high"
508                } else if attr.abs() > 0.1 {
509                    "medium"
510                } else {
511                    "low"
512                };
513
514                println!("     Feature {}: {:+.3} ({} impact)", i, attr, impact);
515            }
516
517            // Local model interpretation
518            match model_name {
519                "Linear Regression" => {
520                    println!("     → Linear relationship approximation in local region");
521                }
522                "Decision Tree" => {
523                    println!("     → Rule-based approximation with thresholds");
524                }
525                "Quantum Linear" => {
526                    println!("     → Quantum-aware linear approximation");
527                }
528                _ => {}
529            }
530
531            // Compute local fidelity (simplified)
532            let local_complexity = attributions.iter().map(|x| x.abs()).sum::<f64>();
533            println!(
534                "     → Local explanation complexity: {:.3}",
535                local_complexity
536            );
537        }
538    }
539
540    Ok(())
541}
542
543/// Demonstrate Quantum SHAP
544fn quantum_shap_demo() -> Result<()> {
545    let layers = vec![
546        QNNLayerType::EncodingLayer { num_features: 3 },
547        QNNLayerType::VariationalLayer { num_params: 6 },
548        QNNLayerType::MeasurementLayer {
549            measurement_basis: "Pauli-Z".to_string(),
550        },
551    ];
552
553    let model = QuantumNeuralNetwork::new(layers, 3, 3, 2)?;
554
555    let method = ExplanationMethod::QuantumSHAP {
556        num_coalitions: 100,
557        background_samples: 20,
558    };
559
560    let mut xai = QuantumExplainableAI::new(model, vec![method]);
561
562    // Set background data for SHAP
563    let background_data =
564        Array2::from_shape_fn((50, 3), |(i, j)| 0.5 + 0.3 * ((i + j) as f64 * 0.1).sin());
565    xai.set_background_data(background_data);
566
567    println!("   Quantum SHAP: SHapley Additive exPlanations");
568
569    // Test multiple inputs
570    let test_inputs = vec![
571        Array1::from_vec(vec![0.1, 0.5, 0.9]),
572        Array1::from_vec(vec![0.8, 0.3, 0.6]),
573        Array1::from_vec(vec![0.4, 0.7, 0.2]),
574    ];
575
576    for (i, input) in test_inputs.iter().enumerate() {
577        println!(
578            "\n   Input {}: [{:.1}, {:.1}, {:.1}]",
579            i + 1,
580            input[0],
581            input[1],
582            input[2]
583        );
584
585        let explanation = xai.explain(input)?;
586
587        if let Some(ref shap_values) = explanation.feature_attributions {
588            println!("     SHAP Values:");
589
590            let mut total_shap = 0.0;
591            for (j, &value) in shap_values.iter().enumerate() {
592                total_shap += value;
593                println!("     - Feature {}: {:+.4}", j, value);
594            }
595
596            println!("     - Sum of SHAP values: {:.4}", total_shap);
597
598            // Feature ranking
599            let mut indexed_shap: Vec<(usize, f64)> = shap_values
600                .iter()
601                .enumerate()
602                .map(|(idx, &val)| (idx, val.abs()))
603                .collect();
604            indexed_shap.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
605
606            println!("     Feature importance ranking:");
607            for (rank, (feature_idx, abs_value)) in indexed_shap.iter().enumerate() {
608                let original_value = shap_values[*feature_idx];
609                println!(
610                    "     {}. Feature {}: {:.4} (|{:.4}|)",
611                    rank + 1,
612                    feature_idx,
613                    original_value,
614                    abs_value
615                );
616            }
617
618            // SHAP properties
619            println!(
620                "     → SHAP values satisfy efficiency property (sum to prediction difference)"
621            );
622            println!("     → Each value represents feature's average marginal contribution");
623        }
624    }
625
626    Ok(())
627}
628
629/// Demonstrate Layer-wise Relevance Propagation
630fn quantum_lrp_demo() -> Result<()> {
631    let layers = vec![
632        QNNLayerType::EncodingLayer { num_features: 4 },
633        QNNLayerType::VariationalLayer { num_params: 8 },
634        QNNLayerType::VariationalLayer { num_params: 6 },
635        QNNLayerType::MeasurementLayer {
636            measurement_basis: "computational".to_string(),
637        },
638    ];
639
640    let model = QuantumNeuralNetwork::new(layers, 4, 4, 2)?;
641
642    // Test different LRP rules
643    let lrp_rules = vec![
644        ("Epsilon Rule", LRPRule::Epsilon),
645        ("Gamma Rule", LRPRule::Gamma { gamma: 0.25 }),
646        (
647            "Alpha-Beta Rule",
648            LRPRule::AlphaBeta {
649                alpha: 2.0,
650                beta: 1.0,
651            },
652        ),
653        ("Quantum Rule", LRPRule::QuantumRule),
654    ];
655
656    let test_input = Array1::from_vec(vec![0.7, 0.1, 0.8, 0.4]);
657
658    println!("   Layer-wise Relevance Propagation for Quantum Circuits");
659    println!(
660        "   Input: [{:.1}, {:.1}, {:.1}, {:.1}]",
661        test_input[0], test_input[1], test_input[2], test_input[3]
662    );
663
664    for (rule_name, lrp_rule) in lrp_rules {
665        let method = ExplanationMethod::QuantumLRP {
666            propagation_rule: lrp_rule,
667            epsilon: 1e-6,
668        };
669
670        let mut xai = QuantumExplainableAI::new(model.clone(), vec![method]);
671        let explanation = xai.explain(&test_input)?;
672
673        if let Some(ref relevance) = explanation.feature_attributions {
674            println!("\n   LRP with {}:", rule_name);
675
676            let total_relevance = relevance.sum();
677
678            for (i, &rel) in relevance.iter().enumerate() {
679                let percentage = if total_relevance.abs() > 1e-10 {
680                    rel / total_relevance * 100.0
681                } else {
682                    0.0
683                };
684
685                println!(
686                    "     Feature {}: {:.4} ({:.1}% of total relevance)",
687                    i, rel, percentage
688                );
689            }
690
691            println!("     Total relevance: {:.4}", total_relevance);
692
693            // Rule-specific interpretation
694            match rule_name {
695                "Epsilon Rule" => {
696                    println!("     → Distributes relevance proportionally to activations");
697                }
698                "Gamma Rule" => {
699                    println!("     → Emphasizes positive contributions");
700                }
701                "Alpha-Beta Rule" => {
702                    println!("     → Separates positive and negative contributions");
703                }
704                "Quantum Rule" => {
705                    println!("     → Accounts for quantum superposition and entanglement");
706                }
707                _ => {}
708            }
709        }
710    }
711
712    Ok(())
713}
714
715/// Comprehensive explanation demonstration
716fn comprehensive_explanation_demo() -> Result<()> {
717    let layers = vec![
718        QNNLayerType::EncodingLayer { num_features: 4 },
719        QNNLayerType::VariationalLayer { num_params: 12 },
720        QNNLayerType::EntanglementLayer {
721            connectivity: "full".to_string(),
722        },
723        QNNLayerType::VariationalLayer { num_params: 8 },
724        QNNLayerType::MeasurementLayer {
725            measurement_basis: "computational".to_string(),
726        },
727    ];
728
729    let model = QuantumNeuralNetwork::new(layers, 4, 4, 3)?;
730
731    // Use comprehensive explanation methods
732    let methods = vec![
733        ExplanationMethod::QuantumFeatureAttribution {
734            method: AttributionMethod::IntegratedGradients,
735            num_samples: 30,
736            baseline: Some(Array1::zeros(4)),
737        },
738        ExplanationMethod::CircuitVisualization {
739            include_measurements: true,
740            parameter_sensitivity: true,
741        },
742        ExplanationMethod::StateAnalysis {
743            entanglement_measures: true,
744            coherence_analysis: true,
745            superposition_analysis: true,
746        },
747        ExplanationMethod::ConceptActivation {
748            concept_datasets: vec!["pattern_A".to_string(), "pattern_B".to_string()],
749            activation_threshold: 0.3,
750        },
751    ];
752
753    let mut xai = QuantumExplainableAI::new(model, methods);
754
755    // Add concept vectors
756    xai.add_concept(
757        "pattern_A".to_string(),
758        Array1::from_vec(vec![1.0, 0.0, 1.0, 0.0]),
759    );
760    xai.add_concept(
761        "pattern_B".to_string(),
762        Array1::from_vec(vec![0.0, 1.0, 0.0, 1.0]),
763    );
764
765    // Set background data
766    let background_data =
767        Array2::from_shape_fn((30, 4), |(i, j)| 0.3 + 0.4 * ((i * j) as f64 * 0.15).sin());
768    xai.set_background_data(background_data);
769
770    println!("   Comprehensive Quantum Model Explanation");
771
772    // Test input representing a specific pattern
773    let test_input = Array1::from_vec(vec![0.9, 0.1, 0.8, 0.2]); // Similar to pattern_A
774
775    println!(
776        "\n   Analyzing input: [{:.1}, {:.1}, {:.1}, {:.1}]",
777        test_input[0], test_input[1], test_input[2], test_input[3]
778    );
779
780    let explanation = xai.explain(&test_input)?;
781
782    // Display comprehensive results
783    println!("\n   === COMPREHENSIVE EXPLANATION RESULTS ===");
784
785    // Feature attributions
786    if let Some(ref attributions) = explanation.feature_attributions {
787        println!("\n   Feature Attributions:");
788        for (i, &attr) in attributions.iter().enumerate() {
789            println!("   - Feature {}: {:+.3}", i, attr);
790        }
791    }
792
793    // Circuit analysis summary
794    if let Some(ref circuit) = explanation.circuit_explanation {
795        println!("\n   Circuit Analysis Summary:");
796        let avg_importance = circuit.parameter_importance.mean().unwrap_or(0.0);
797        println!("   - Average parameter importance: {:.3}", avg_importance);
798        println!(
799            "   - Number of analyzed layers: {}",
800            circuit.layer_analysis.len()
801        );
802        println!("   - Critical path length: {}", circuit.critical_path.len());
803    }
804
805    // Quantum state properties
806    if let Some(ref state) = explanation.state_properties {
807        println!("\n   Quantum State Properties:");
808        println!(
809            "   - Entanglement entropy: {:.3}",
810            state.entanglement_entropy
811        );
812        println!(
813            "   - Coherence measures: {} types",
814            state.coherence_measures.len()
815        );
816
817        let max_measurement_prob = state
818            .measurement_probabilities
819            .iter()
820            .cloned()
821            .fold(f64::NEG_INFINITY, f64::max);
822        println!(
823            "   - Max measurement probability: {:.3}",
824            max_measurement_prob
825        );
826    }
827
828    // Concept activations
829    if let Some(ref concepts) = explanation.concept_activations {
830        println!("\n   Concept Activations:");
831        for (concept, &activation) in concepts {
832            let similarity = if activation > 0.7 {
833                "high"
834            } else if activation > 0.3 {
835                "medium"
836            } else {
837                "low"
838            };
839            println!(
840                "   - {}: {:.3} ({} similarity)",
841                concept, activation, similarity
842            );
843        }
844    }
845
846    // Confidence scores
847    println!("\n   Explanation Confidence Scores:");
848    for (component, &confidence) in &explanation.confidence_scores {
849        println!("   - {}: {:.3}", component, confidence);
850    }
851
852    // Textual explanation
853    println!("\n   Generated Explanation:");
854    println!("{}", explanation.textual_explanation);
855
856    // Summary insights
857    println!("\n   === KEY INSIGHTS ===");
858
859    if let Some(ref attributions) = explanation.feature_attributions {
860        let max_attr_idx = attributions
861            .iter()
862            .enumerate()
863            .max_by(|a, b| a.1.abs().partial_cmp(&b.1.abs()).unwrap())
864            .map(|(i, _)| i)
865            .unwrap_or(0);
866
867        println!(
868            "   • Most influential feature: Feature {} ({:.3})",
869            max_attr_idx, attributions[max_attr_idx]
870        );
871    }
872
873    if let Some(ref state) = explanation.state_properties {
874        if state.entanglement_entropy > 0.5 {
875            println!("   • Model creates significant quantum entanglement");
876        }
877
878        let coherence_level = state
879            .coherence_measures
880            .values()
881            .cloned()
882            .fold(0.0, f64::max);
883        if coherence_level > 0.5 {
884            println!("   • High quantum coherence detected");
885        }
886    }
887
888    if let Some(ref concepts) = explanation.concept_activations {
889        if let Some((best_concept, &max_activation)) =
890            concepts.iter().max_by(|a, b| a.1.partial_cmp(b.1).unwrap())
891        {
892            if max_activation > 0.5 {
893                println!("   • Input strongly matches concept: {}", best_concept);
894            }
895        }
896    }
897
898    println!("   • Explanation provides multi-faceted interpretation of quantum model behavior");
899
900    Ok(())
901}
Source

pub fn forward(&self, input: &Array1<f64>) -> Result<Array1<f64>>

Runs the network on a given input

Source

pub fn train( &mut self, x_train: &Array2<f64>, y_train: &Array2<f64>, epochs: usize, learning_rate: f64, ) -> Result<TrainingResult>

Trains the network on a dataset

Source

pub fn train_1d( &mut self, x_train: &Array2<f64>, y_train: &Array1<f64>, epochs: usize, learning_rate: f64, ) -> Result<TrainingResult>

Trains the network on a dataset with 1D labels (compatibility method)

Source

pub fn predict(&self, input: &Array1<f64>) -> Result<Array1<f64>>

Predicts the output for a given input

Source

pub fn predict_batch(&self, inputs: &Array2<f64>) -> Result<Array2<f64>>

Predicts the output for a batch of inputs

Trait Implementations§

Source§

impl Clone for QuantumNeuralNetwork

Source§

fn clone(&self) -> QuantumNeuralNetwork

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for QuantumNeuralNetwork

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> Ungil for T
where T: Send,