hep_classification/
hep_classification.rs1#![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 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 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, 0.05, )?;
46
47 println!("Training completed in {:.2?}", start.elapsed());
48 println!("Final loss: {:.4}", metrics.final_loss);
49
50 println!("Generating test data...");
52 let (test_particles, test_labels) = generate_synthetic_data(100);
53
54 println!("Evaluating classifier...");
56 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 println!("\nClassifying a test collision event...");
81 let event = create_test_collision_event();
82
83 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 println!("\nCreating Higgs detector...");
93 let higgs_detector = quantrs2_ml::hep::HiggsDetector::new(num_qubits)?;
94
95 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
105fn 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, 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 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 let mut additional_features = Vec::with_capacity(3);
136 for _ in 0..3 {
137 additional_features.push(thread_rng().gen::<f64>());
138 }
139
140 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
154fn create_test_collision_event() -> CollisionEvent {
156 let mut particles = Vec::new();
157
158 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 particles.push(ParticleFeatures {
167 particle_type: ParticleType::Electron, four_momentum: [50.2, -9.7, 14.3, -44.1],
169 additional_features: vec![0.7, 0.3, 0.2],
170 });
171
172 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 let global_features = vec![230.0]; CollisionEvent {
189 particles,
190 global_features,
191 event_type: Some("potential_higgs".to_string()),
192 }
193}