1pub mod advanced_algorithms;
8pub mod encoding;
9pub mod generative_adversarial;
10pub mod layers;
11pub mod nlp;
12pub mod reinforcement_learning;
13pub mod training;
14
15pub mod quantum_contrastive;
17pub mod quantum_memory_networks;
18pub mod quantum_meta_learning;
19pub mod quantum_reservoir;
20pub mod quantum_transformer;
21
22pub mod quantum_boltzmann;
24pub mod quantum_federated;
25
26pub use advanced_algorithms::{
28 FeatureMapType, QMLMetrics, QuantumEnsemble, QuantumKernel, QuantumKernelConfig, QuantumSVM,
29 QuantumTransferLearning, TransferLearningConfig, VotingStrategy,
30};
31
32pub use quantum_contrastive::{
34 QuantumAugmentation, QuantumContrastiveConfig, QuantumContrastiveLearner,
35};
36pub use quantum_memory_networks::{MemoryInitStrategy, QuantumMemoryConfig, QuantumMemoryNetwork};
37pub use quantum_meta_learning::{
38 QuantumMAML, QuantumMetaLearningConfig, QuantumReptile, QuantumTask,
39};
40pub use quantum_reservoir::{QuantumReservoirComputer, QuantumReservoirConfig};
41pub use quantum_transformer::{QuantumAttention, QuantumTransformer, QuantumTransformerConfig};
42
43pub use quantum_boltzmann::{DeepQuantumBoltzmannMachine, QRBMConfig, QuantumRBM};
45pub use quantum_federated::{AggregationStrategy, QuantumFederatedConfig, QuantumFederatedServer};
46
47use crate::{
48 error::{QuantRS2Error, QuantRS2Result},
49 gate::GateOp,
50 qubit::QubitId,
51};
52use scirs2_core::ndarray::{Array1, Array2};
53use scirs2_core::Complex64;
54
55pub use layers::Parameter;
57
58pub trait QMLLayer: Send + Sync {
60 fn num_qubits(&self) -> usize;
62
63 fn parameters(&self) -> &[Parameter];
65
66 fn parameters_mut(&mut self) -> &mut [Parameter];
68
69 fn set_parameters(&mut self, values: &[f64]) -> QuantRS2Result<()> {
71 if values.len() != self.parameters().len() {
72 return Err(QuantRS2Error::InvalidInput(format!(
73 "Expected {} parameters, got {}",
74 self.parameters().len(),
75 values.len()
76 )));
77 }
78
79 for (param, &value) in self.parameters_mut().iter_mut().zip(values.iter()) {
80 param.value = value;
81 }
82
83 Ok(())
84 }
85
86 fn gates(&self) -> Vec<Box<dyn GateOp>>;
88
89 fn compute_gradients(
91 &self,
92 state: &Array1<Complex64>,
93 loss_gradient: &Array1<Complex64>,
94 ) -> QuantRS2Result<Vec<f64>>;
95
96 fn name(&self) -> &str;
98}
99
100#[derive(Debug, Clone, Copy, PartialEq)]
102pub enum EncodingStrategy {
103 Amplitude,
105 Angle,
107 IQP,
109 Basis,
111}
112
113#[derive(Debug, Clone)]
115pub struct QMLConfig {
116 pub num_qubits: usize,
118 pub num_layers: usize,
120 pub encoding: EncodingStrategy,
122 pub entanglement: EntanglementPattern,
124 pub data_reuploading: bool,
126}
127
128impl Default for QMLConfig {
129 fn default() -> Self {
130 Self {
131 num_qubits: 4,
132 num_layers: 2,
133 encoding: EncodingStrategy::Angle,
134 entanglement: EntanglementPattern::Full,
135 data_reuploading: false,
136 }
137 }
138}
139
140#[derive(Debug, Clone, Copy, PartialEq)]
142pub enum EntanglementPattern {
143 None,
145 Linear,
147 Circular,
149 Full,
151 Alternating,
153}
154
155pub struct QMLCircuit {
157 config: QMLConfig,
159 layers: Vec<Box<dyn QMLLayer>>,
161 num_parameters: usize,
163}
164
165impl QMLCircuit {
166 pub fn new(config: QMLConfig) -> Self {
168 Self {
169 config,
170 layers: Vec::new(),
171 num_parameters: 0,
172 }
173 }
174
175 pub fn add_layer(&mut self, layer: Box<dyn QMLLayer>) -> QuantRS2Result<()> {
177 if layer.num_qubits() != self.config.num_qubits {
178 return Err(QuantRS2Error::InvalidInput(format!(
179 "Layer has {} qubits, circuit has {}",
180 layer.num_qubits(),
181 self.config.num_qubits
182 )));
183 }
184
185 self.num_parameters += layer.parameters().len();
186 self.layers.push(layer);
187 Ok(())
188 }
189
190 pub fn parameters(&self) -> Vec<&Parameter> {
192 self.layers
193 .iter()
194 .flat_map(|layer| layer.parameters().iter())
195 .collect()
196 }
197
198 pub fn set_parameters(&mut self, values: &[f64]) -> QuantRS2Result<()> {
200 if values.len() != self.num_parameters {
201 return Err(QuantRS2Error::InvalidInput(format!(
202 "Expected {} parameters, got {}",
203 self.num_parameters,
204 values.len()
205 )));
206 }
207
208 let mut offset = 0;
209 for layer in &mut self.layers {
210 let layer_params = layer.parameters().len();
211 layer.set_parameters(&values[offset..offset + layer_params])?;
212 offset += layer_params;
213 }
214
215 Ok(())
216 }
217
218 pub fn gates(&self) -> Vec<Box<dyn GateOp>> {
220 self.layers.iter().flat_map(|layer| layer.gates()).collect()
221 }
222
223 pub fn compute_gradients(
225 &self,
226 state: &Array1<Complex64>,
227 loss_gradient: &Array1<Complex64>,
228 ) -> QuantRS2Result<Vec<f64>> {
229 let mut all_gradients = Vec::new();
230
231 for layer in &self.layers {
232 let layer_grads = layer.compute_gradients(state, loss_gradient)?;
233 all_gradients.extend(layer_grads);
234 }
235
236 Ok(all_gradients)
237 }
238}
239
240pub fn create_entangling_gates(
242 num_qubits: usize,
243 pattern: EntanglementPattern,
244) -> Vec<(QubitId, QubitId)> {
245 match pattern {
246 EntanglementPattern::None => vec![],
247
248 EntanglementPattern::Linear => (0..num_qubits - 1)
249 .map(|i| (QubitId(i as u32), QubitId((i + 1) as u32)))
250 .collect(),
251
252 EntanglementPattern::Circular => {
253 let mut gates = vec![];
254 for i in 0..num_qubits {
255 gates.push((QubitId(i as u32), QubitId(((i + 1) % num_qubits) as u32)));
256 }
257 gates
258 }
259
260 EntanglementPattern::Full => {
261 let mut gates = vec![];
262 for i in 0..num_qubits {
263 for j in i + 1..num_qubits {
264 gates.push((QubitId(i as u32), QubitId(j as u32)));
265 }
266 }
267 gates
268 }
269
270 EntanglementPattern::Alternating => {
271 let mut gates = vec![];
272 for i in (0..num_qubits - 1).step_by(2) {
274 gates.push((QubitId(i as u32), QubitId((i + 1) as u32)));
275 }
276 for i in (1..num_qubits - 1).step_by(2) {
278 gates.push((QubitId(i as u32), QubitId((i + 1) as u32)));
279 }
280 gates
281 }
282 }
283}
284
285pub fn quantum_fisher_information(
287 circuit: &QMLCircuit,
288 _state: &Array1<Complex64>,
289) -> QuantRS2Result<Array2<f64>> {
290 let num_params = circuit.num_parameters;
291 let fisher = Array2::zeros((num_params, num_params));
292
293 Ok(fisher)
300}
301
302pub fn natural_gradient(
304 gradients: &[f64],
305 fisher: &Array2<f64>,
306 regularization: f64,
307) -> QuantRS2Result<Vec<f64>> {
308 let mut regularized_fisher = fisher.clone();
310 for i in 0..fisher.nrows() {
311 regularized_fisher[(i, i)] += regularization;
312 }
313
314 let _grad_array = Array1::from_vec(gradients.to_vec());
317
318 Ok(gradients.to_vec())
321}
322
323#[cfg(test)]
324mod tests {
325 use super::*;
326
327 #[test]
328 fn test_entanglement_patterns() {
329 let linear = create_entangling_gates(4, EntanglementPattern::Linear);
330 assert_eq!(linear.len(), 3);
331 assert_eq!(linear[0], (QubitId(0), QubitId(1)));
332
333 let circular = create_entangling_gates(4, EntanglementPattern::Circular);
334 assert_eq!(circular.len(), 4);
335 assert_eq!(circular[3], (QubitId(3), QubitId(0)));
336
337 let full = create_entangling_gates(3, EntanglementPattern::Full);
338 assert_eq!(full.len(), 3); let none = create_entangling_gates(4, EntanglementPattern::None);
341 assert_eq!(none.len(), 0);
342 }
343
344 #[test]
345 fn test_qml_circuit() {
346 let config = QMLConfig {
347 num_qubits: 2,
348 num_layers: 1,
349 ..Default::default()
350 };
351
352 let circuit = QMLCircuit::new(config);
353 assert_eq!(circuit.num_parameters, 0);
354 }
355}