quantrs2_anneal/quantum_machine_learning/
functions.rs1use scirs2_core::random::prelude::*;
6use std::time::{Duration, Instant};
7
8use super::types::{
9 FeatureMapType, KernelMethodType, QAutoencoderConfig, QmlError, QmlMetrics, QnnConfig,
10 QuantumAutoencoder, QuantumCircuit, QuantumFeatureMap, QuantumKernelMethod,
11 QuantumNeuralNetwork, VariationalQuantumClassifier, VqcConfig,
12};
13
14pub type QmlResult<T> = Result<T, QmlError>;
16pub fn create_binary_classifier(
19 num_features: usize,
20 num_qubits: usize,
21 ansatz_layers: usize,
22) -> QmlResult<VariationalQuantumClassifier> {
23 let config = VqcConfig {
24 max_iterations: 500,
25 learning_rate: 0.01,
26 num_shots: 1024,
27 ..Default::default()
28 };
29 VariationalQuantumClassifier::new(num_features, num_qubits, 2, ansatz_layers, config)
30}
31pub fn create_zz_feature_map(
33 num_features: usize,
34 repetitions: usize,
35) -> QmlResult<QuantumFeatureMap> {
36 QuantumFeatureMap::new(
37 num_features,
38 num_features,
39 FeatureMapType::ZZFeatureMap { repetitions },
40 )
41}
42#[must_use]
44pub const fn create_quantum_svm(
45 feature_map: QuantumFeatureMap,
46 c_parameter: f64,
47) -> QuantumKernelMethod {
48 QuantumKernelMethod::new(
49 feature_map,
50 KernelMethodType::SupportVectorMachine { c_parameter },
51 )
52}
53pub fn evaluate_qml_model<F>(model: F, test_data: &[(Vec<f64>, usize)]) -> QmlResult<QmlMetrics>
55where
56 F: Fn(&[f64]) -> QmlResult<usize>,
57{
58 let start = Instant::now();
59 let mut correct = 0;
60 let mut total = 0;
61 for (features, true_label) in test_data {
62 let predicted_label = model(features)?;
63 if predicted_label == *true_label {
64 correct += 1;
65 }
66 total += 1;
67 }
68 let accuracy = f64::from(correct) / f64::from(total);
69 let training_time = start.elapsed();
70 Ok(QmlMetrics {
71 training_accuracy: accuracy,
72 validation_accuracy: accuracy,
73 training_loss: 0.0,
74 validation_loss: 0.0,
75 training_time,
76 num_parameters: 0,
77 quantum_advantage: 1.2,
78 complexity_score: 0.5,
79 })
80}
81#[cfg(test)]
82mod tests {
83 use super::*;
84 #[test]
85 fn test_quantum_circuit_creation() {
86 let circuit = QuantumCircuit::hardware_efficient_ansatz(4, 2);
87 assert_eq!(circuit.num_qubits, 4);
88 assert_eq!(circuit.depth, 2);
89 assert!(circuit.num_parameters > 0);
90 }
91 #[test]
92 fn test_quantum_feature_map() {
93 let feature_map = QuantumFeatureMap::new(3, 4, FeatureMapType::AngleEncoding)
94 .expect("should create quantum feature map");
95 assert_eq!(feature_map.num_features, 3);
96 assert_eq!(feature_map.num_qubits, 4);
97 let data = vec![1.0, 0.5, -0.5];
98 let encoded = feature_map.encode(&data).expect("should encode data");
99 assert_eq!(encoded.len(), 4);
100 }
101 #[test]
102 fn test_vqc_creation() {
103 let vqc = VariationalQuantumClassifier::new(4, 4, 2, 2, VqcConfig::default())
104 .expect("should create variational quantum classifier");
105 assert_eq!(vqc.num_classes, 2);
106 assert_eq!(vqc.feature_map.num_features, 4);
107 }
108 #[test]
109 fn test_quantum_neural_network() {
110 let qnn = QuantumNeuralNetwork::new(&[3, 4, 2], QnnConfig::default())
111 .expect("should create quantum neural network");
112 assert_eq!(qnn.layers.len(), 2);
113 let input = vec![0.5, -0.3, 0.8];
114 let output = qnn.forward(&input).expect("should perform forward pass");
115 assert_eq!(output.len(), 2);
116 }
117 #[test]
118 fn test_quantum_kernel_method() {
119 let feature_map = QuantumFeatureMap::new(2, 2, FeatureMapType::AngleEncoding)
120 .expect("should create quantum feature map");
121 let kernel_method = QuantumKernelMethod::new(
122 feature_map,
123 KernelMethodType::SupportVectorMachine { c_parameter: 1.0 },
124 );
125 let x1 = vec![0.5, 0.3];
126 let x2 = vec![0.7, 0.1];
127 let kernel_val = kernel_method
128 .quantum_kernel(&x1, &x2)
129 .expect("should compute kernel value");
130 assert!(kernel_val >= 0.0);
131 assert!(kernel_val <= 1.0);
132 }
133 #[test]
134 fn test_quantum_autoencoder() {
135 let config = QAutoencoderConfig {
136 input_dim: 8,
137 latent_dim: 3,
138 learning_rate: 0.01,
139 epochs: 5,
140 batch_size: 16,
141 seed: Some(42),
142 };
143 let autoencoder =
144 QuantumAutoencoder::new(config).expect("should create quantum autoencoder");
145 let input = vec![1.0, 0.5, -0.5, 0.3, 0.8, -0.2, 0.6, -0.8];
146 let latent = autoencoder
147 .encode(&input)
148 .expect("should encode input to latent space");
149 assert_eq!(latent.len(), 3);
150 let reconstructed = autoencoder
151 .decode(&latent)
152 .expect("should decode latent to output");
153 assert_eq!(reconstructed.len(), 8);
154 }
155 #[test]
156 fn test_helper_functions() {
157 let vqc = create_binary_classifier(4, 4, 2).expect("should create binary classifier");
158 assert_eq!(vqc.num_classes, 2);
159 let feature_map = create_zz_feature_map(3, 2).expect("should create ZZ feature map");
160 assert_eq!(feature_map.num_features, 3);
161 let kernel_svm = create_quantum_svm(feature_map, 1.0);
162 assert!(matches!(
163 kernel_svm.method_type,
164 KernelMethodType::SupportVectorMachine { .. }
165 ));
166 }
167}