hep_classification/
hep_classification.rs

1#![allow(
2    clippy::pedantic,
3    clippy::unnecessary_wraps,
4    clippy::needless_range_loop,
5    clippy::useless_vec,
6    clippy::needless_collect,
7    clippy::too_many_arguments,
8    clippy::vec_init_then_push
9)]
10use quantrs2_ml::hep::{CollisionEvent, HEPQuantumClassifier, ParticleFeatures, ParticleType};
11use quantrs2_ml::prelude::*;
12use scirs2_core::ndarray::{Array1, Array2};
13use scirs2_core::random::prelude::*;
14use std::time::Instant;
15
16fn main() -> Result<()> {
17    println!("Quantum High-Energy Physics Classification Example");
18    println!("=================================================");
19
20    // Create a quantum classifier for high-energy physics data
21    let num_qubits = 8;
22    let feature_dim = 8;
23    let num_classes = 2;
24
25    println!("Creating HEP quantum classifier with {num_qubits} qubits...");
26    let mut classifier = HEPQuantumClassifier::new(
27        num_qubits,
28        feature_dim,
29        num_classes,
30        quantrs2_ml::hep::HEPEncodingMethod::HybridEncoding,
31        vec!["background".to_string(), "higgs".to_string()],
32    )?;
33
34    // Generate synthetic training data
35    println!("Generating synthetic training data...");
36    let (training_particles, training_labels) = generate_synthetic_data(500);
37
38    println!("Training quantum classifier...");
39    let start = Instant::now();
40    let metrics = classifier.train_on_particles(
41        &training_particles,
42        &training_labels,
43        20,   // epochs
44        0.05, // learning rate
45    )?;
46
47    println!("Training completed in {:.2?}", start.elapsed());
48    println!("Final loss: {:.4}", metrics.final_loss);
49
50    // Generate test data
51    println!("Generating test data...");
52    let (test_particles, test_labels) = generate_synthetic_data(100);
53
54    // Evaluate classifier
55    println!("Evaluating classifier...");
56    // Convert test data to ndarray format
57    let num_samples = test_particles.len();
58    let mut test_features = Array2::zeros((num_samples, classifier.feature_dimension));
59    let mut test_labels_array = Array1::zeros(num_samples);
60
61    for (i, particle) in test_particles.iter().enumerate() {
62        let features = classifier.extract_features(particle)?;
63        for j in 0..features.len() {
64            test_features[[i, j]] = features[j];
65        }
66        test_labels_array[i] = test_labels[i] as f64;
67    }
68
69    let evaluation = classifier.evaluate(&test_features, &test_labels_array)?;
70
71    println!("Evaluation results:");
72    println!("  Overall accuracy: {:.2}%", evaluation.accuracy * 100.0);
73
74    println!("Class accuracies:");
75    for (i, &acc) in evaluation.class_accuracies.iter().enumerate() {
76        println!("  {}: {:.2}%", evaluation.class_labels[i], acc * 100.0);
77    }
78
79    // Create a test collision event
80    println!("\nClassifying a test collision event...");
81    let event = create_test_collision_event();
82
83    // Run classification
84    let classifications = classifier.classify_event(&event)?;
85
86    println!("Event classification results:");
87    for (i, (class, confidence)) in classifications.iter().enumerate() {
88        println!("  Particle {i}: {class} (confidence: {confidence:.2})");
89    }
90
91    // Create a Higgs detector
92    println!("\nCreating Higgs detector...");
93    let higgs_detector = quantrs2_ml::hep::HiggsDetector::new(num_qubits)?;
94
95    // Detect Higgs
96    let higgs_detections = higgs_detector.detect_higgs(&event)?;
97
98    println!("Higgs detection results:");
99    let higgs_count = higgs_detections.iter().filter(|&&x| x).count();
100    println!("  Found {higgs_count} potential Higgs particles");
101
102    Ok(())
103}
104
105// Generate synthetic particle data for training/testing
106fn generate_synthetic_data(num_samples: usize) -> (Vec<ParticleFeatures>, Vec<usize>) {
107    let mut particles = Vec::with_capacity(num_samples);
108    let mut labels = Vec::with_capacity(num_samples);
109
110    let particle_types = [
111        ParticleType::Electron,
112        ParticleType::Muon,
113        ParticleType::Photon,
114        ParticleType::Quark, // Changed from Proton which doesn't exist
115        ParticleType::Higgs,
116    ];
117
118    for i in 0..num_samples {
119        let is_higgs = i % 5 == 0;
120        let particle_type = if is_higgs {
121            ParticleType::Higgs
122        } else {
123            particle_types[i % 4]
124        };
125
126        // Generate synthetic four-momentum
127        // Higgs particles have higher energy
128        let energy_base = if is_higgs { 125.0 } else { 50.0 };
129        let energy = thread_rng().gen::<f64>().mul_add(10.0, energy_base);
130        let px = (thread_rng().gen::<f64>() - 0.5) * 20.0;
131        let py = (thread_rng().gen::<f64>() - 0.5) * 20.0;
132        let pz = (thread_rng().gen::<f64>() - 0.5) * 50.0;
133
134        // Create additional features
135        let mut additional_features = Vec::with_capacity(3);
136        for _ in 0..3 {
137            additional_features.push(thread_rng().gen::<f64>());
138        }
139
140        // Create particle features
141        let particle = ParticleFeatures {
142            particle_type,
143            four_momentum: [energy, px, py, pz],
144            additional_features,
145        };
146
147        particles.push(particle);
148        labels.push(usize::from(is_higgs));
149    }
150
151    (particles, labels)
152}
153
154// Create a test collision event
155fn create_test_collision_event() -> CollisionEvent {
156    let mut particles = Vec::new();
157
158    // Add an electron
159    particles.push(ParticleFeatures {
160        particle_type: ParticleType::Electron,
161        four_momentum: [50.5, 10.2, -15.7, 45.9],
162        additional_features: vec![0.8, 0.2, 0.3],
163    });
164
165    // Add a positron
166    particles.push(ParticleFeatures {
167        particle_type: ParticleType::Electron, // Type is electron, but with opposite charge
168        four_momentum: [50.2, -9.7, 14.3, -44.1],
169        additional_features: vec![0.7, 0.3, 0.2],
170    });
171
172    // Add photons (potential Higgs decay products)
173    particles.push(ParticleFeatures {
174        particle_type: ParticleType::Photon,
175        four_momentum: [62.8, 25.4, 30.1, 41.2],
176        additional_features: vec![0.9, 0.1, 0.4],
177    });
178
179    particles.push(ParticleFeatures {
180        particle_type: ParticleType::Photon,
181        four_momentum: [63.2, -24.1, -29.5, -40.8],
182        additional_features: vec![0.9, 0.1, 0.5],
183    });
184
185    // Create global event features
186    let global_features = vec![230.0]; // Total energy
187
188    CollisionEvent {
189        particles,
190        global_features,
191        event_type: Some("potential_higgs".to_string()),
192    }
193}