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

Source§

fn __clone_box(&self, _: Private) -> *mut ()

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