use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum HardwareArchitecture {
NISQ,
FaultTolerant,
Superconducting,
TrappedIon,
Photonic,
NeutralAtom,
ClassicalSimulation,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum QMLAlgorithmType {
VQE,
QAOA,
QCNN,
QSVM,
QRL,
QGAN,
QBM,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum GradientMethod {
ParameterShift,
FiniteDifferences,
AutomaticDifferentiation,
NaturalGradients,
StochasticParameterShift,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum OptimizerType {
Adam,
SGD,
RMSprop,
LBFGS,
QuantumNaturalGradient,
SPSA,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QMLConfig {
pub hardware_architecture: HardwareArchitecture,
pub algorithm_type: QMLAlgorithmType,
pub num_qubits: usize,
pub circuit_depth: usize,
pub num_parameters: usize,
pub gradient_method: GradientMethod,
pub optimizer_type: OptimizerType,
pub learning_rate: f64,
pub batch_size: usize,
pub max_epochs: usize,
pub convergence_tolerance: f64,
pub hardware_aware_optimization: bool,
pub noise_adaptive_training: bool,
pub shot_budget: usize,
}
impl Default for QMLConfig {
fn default() -> Self {
Self {
hardware_architecture: HardwareArchitecture::NISQ,
algorithm_type: QMLAlgorithmType::VQE,
num_qubits: 4,
circuit_depth: 3,
num_parameters: 12,
gradient_method: GradientMethod::ParameterShift,
optimizer_type: OptimizerType::Adam,
learning_rate: 0.01,
batch_size: 32,
max_epochs: 100,
convergence_tolerance: 1e-6,
hardware_aware_optimization: true,
noise_adaptive_training: true,
shot_budget: 8192,
}
}
}
impl QMLConfig {
#[must_use]
pub fn for_algorithm(algorithm_type: QMLAlgorithmType) -> Self {
let mut config = Self {
algorithm_type,
..Self::default()
};
match algorithm_type {
QMLAlgorithmType::VQE => {
config.num_qubits = 4;
config.circuit_depth = 3;
config.num_parameters = 12;
config.gradient_method = GradientMethod::ParameterShift;
}
QMLAlgorithmType::QAOA => {
config.num_qubits = 6;
config.circuit_depth = 2;
config.num_parameters = 4;
config.gradient_method = GradientMethod::ParameterShift;
}
QMLAlgorithmType::QCNN => {
config.num_qubits = 8;
config.circuit_depth = 4;
config.num_parameters = 24;
config.gradient_method = GradientMethod::AutomaticDifferentiation;
}
QMLAlgorithmType::QSVM => {
config.num_qubits = 6;
config.circuit_depth = 2;
config.num_parameters = 8;
config.gradient_method = GradientMethod::FiniteDifferences;
}
QMLAlgorithmType::QRL => {
config.num_qubits = 4;
config.circuit_depth = 5;
config.num_parameters = 20;
config.gradient_method = GradientMethod::NaturalGradients;
}
QMLAlgorithmType::QGAN => {
config.num_qubits = 8;
config.circuit_depth = 6;
config.num_parameters = 32;
config.gradient_method = GradientMethod::AutomaticDifferentiation;
}
QMLAlgorithmType::QBM => {
config.num_qubits = 10;
config.circuit_depth = 3;
config.num_parameters = 15;
config.gradient_method = GradientMethod::StochasticParameterShift;
}
}
config
}
#[must_use]
pub fn for_hardware(hardware: HardwareArchitecture) -> Self {
let mut config = Self {
hardware_architecture: hardware,
..Self::default()
};
match hardware {
HardwareArchitecture::NISQ => {
config.circuit_depth = 3;
config.shot_budget = 8192;
config.noise_adaptive_training = true;
}
HardwareArchitecture::FaultTolerant => {
config.circuit_depth = 10;
config.shot_budget = 1_000_000;
config.noise_adaptive_training = false;
}
HardwareArchitecture::Superconducting => {
config.circuit_depth = 5;
config.shot_budget = 16_384;
config.noise_adaptive_training = true;
}
HardwareArchitecture::TrappedIon => {
config.circuit_depth = 8;
config.shot_budget = 32_768;
config.noise_adaptive_training = true;
}
HardwareArchitecture::Photonic => {
config.circuit_depth = 4;
config.shot_budget = 4096;
config.noise_adaptive_training = true;
}
HardwareArchitecture::NeutralAtom => {
config.circuit_depth = 6;
config.shot_budget = 16_384;
config.noise_adaptive_training = true;
}
HardwareArchitecture::ClassicalSimulation => {
config.circuit_depth = 15;
config.shot_budget = 1_000_000;
config.noise_adaptive_training = false;
}
}
config
}
pub fn validate(&self) -> Result<(), String> {
if self.num_qubits == 0 {
return Err("Number of qubits must be positive".to_string());
}
if self.circuit_depth == 0 {
return Err("Circuit depth must be positive".to_string());
}
if self.num_parameters == 0 {
return Err("Number of parameters must be positive".to_string());
}
if self.learning_rate <= 0.0 {
return Err("Learning rate must be positive".to_string());
}
if self.batch_size == 0 {
return Err("Batch size must be positive".to_string());
}
if self.max_epochs == 0 {
return Err("Maximum epochs must be positive".to_string());
}
if self.convergence_tolerance <= 0.0 {
return Err("Convergence tolerance must be positive".to_string());
}
if self.shot_budget == 0 {
return Err("Shot budget must be positive".to_string());
}
Ok(())
}
}