Skip to main content

quantrs2_sim/quantum_chemistry/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use crate::error::{Result, SimulatorError};
6use crate::fermionic_simulation::{FermionicHamiltonian, FermionicOperator, FermionicString};
7use crate::pauli::{PauliOperator, PauliOperatorSum, PauliString};
8use scirs2_core::ndarray::{Array1, Array2, Array4};
9use scirs2_core::random::prelude::*;
10use scirs2_core::Complex64;
11use std::collections::HashMap;
12use std::f64::consts::PI;
13
14/// Molecular Hamiltonian in second quantization
15#[derive(Debug, Clone)]
16pub struct MolecularHamiltonian {
17    /// One-electron integrals (kinetic + nuclear attraction)
18    pub one_electron_integrals: Array2<f64>,
19    /// Two-electron integrals (electron-electron repulsion)
20    pub two_electron_integrals: Array4<f64>,
21    /// Nuclear repulsion energy
22    pub nuclear_repulsion: f64,
23    /// Number of molecular orbitals
24    pub num_orbitals: usize,
25    /// Number of electrons
26    pub num_electrons: usize,
27    /// Fermionic Hamiltonian representation
28    pub fermionic_hamiltonian: FermionicHamiltonian,
29    /// Pauli representation (after fermion-to-spin mapping)
30    pub pauli_hamiltonian: Option<PauliOperatorSum>,
31}
32/// Molecular orbital representation
33#[derive(Debug, Clone)]
34pub struct MolecularOrbitals {
35    /// Orbital coefficients
36    pub coefficients: Array2<f64>,
37    /// Orbital energies
38    pub energies: Array1<f64>,
39    /// Occupation numbers
40    pub occupations: Array1<f64>,
41    /// Number of basis functions
42    pub num_basis: usize,
43    /// Number of molecular orbitals
44    pub num_orbitals: usize,
45}
46/// Fermion-to-spin mapping methods
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum FermionMapping {
49    /// Jordan-Wigner transformation
50    JordanWigner,
51    /// Parity mapping
52    Parity,
53    /// Bravyi-Kitaev transformation
54    BravyiKitaev,
55    /// Symmetry-conserving Bravyi-Kitaev
56    SymmetryConservingBK,
57    /// Fenwick tree mapping
58    FenwickTree,
59}
60/// Statistics for quantum chemistry calculations
61#[derive(Debug, Clone, Default)]
62pub struct ChemistryStats {
63    /// Total computation time
64    pub total_time_ms: f64,
65    /// Hamiltonian construction time
66    pub hamiltonian_time_ms: f64,
67    /// VQE optimization time
68    pub vqe_time_ms: f64,
69    /// Number of quantum circuit evaluations
70    pub circuit_evaluations: usize,
71    /// Number of parameter updates
72    pub parameter_updates: usize,
73    /// Memory usage for matrices
74    pub memory_usage_mb: f64,
75    /// Hamiltonian terms count
76    pub hamiltonian_terms: usize,
77}
78/// Fermion-to-spin mapping utilities
79#[derive(Debug, Clone)]
80pub struct FermionMapper {
81    /// Mapping method
82    pub(super) method: FermionMapping,
83    /// Number of spin orbitals
84    pub(crate) num_spin_orbitals: usize,
85    /// Cached mappings
86    mapping_cache: HashMap<String, PauliString>,
87}
88impl FermionMapper {
89    #[must_use]
90    pub fn new(method: FermionMapping, num_spin_orbitals: usize) -> Self {
91        Self {
92            method,
93            num_spin_orbitals,
94            mapping_cache: HashMap::new(),
95        }
96    }
97    pub(super) fn map_fermionic_string(
98        &self,
99        fermionic_string: &FermionicString,
100    ) -> Result<PauliString> {
101        let mut paulis = HashMap::new();
102        for (i, operator) in fermionic_string.operators.iter().enumerate() {
103            match operator {
104                FermionicOperator::Creation(site) => {
105                    paulis.insert(*site, PauliOperator::X);
106                }
107                FermionicOperator::Annihilation(site) => {
108                    paulis.insert(*site, PauliOperator::X);
109                }
110                _ => {
111                    paulis.insert(i, PauliOperator::Z);
112                }
113            }
114        }
115        let mut operators_vec = vec![PauliOperator::I; self.num_spin_orbitals];
116        for (qubit, op) in paulis {
117            if qubit < operators_vec.len() {
118                operators_vec[qubit] = op;
119            }
120        }
121        let num_qubits = operators_vec.len();
122        Ok(PauliString {
123            operators: operators_vec,
124            coefficient: fermionic_string.coefficient,
125            num_qubits,
126        })
127    }
128    /// Calculate molecular dipole moment from density matrix
129    pub(super) fn calculate_dipole_moment(
130        &self,
131        density_matrix: &Array2<f64>,
132    ) -> Result<Array1<f64>> {
133        let mut dipole = Array1::zeros(3);
134        let num_orbitals = density_matrix.nrows();
135        for i in 0..num_orbitals {
136            for j in 0..num_orbitals {
137                let density_element = density_matrix[[i, j]];
138                if i == j {
139                    let orbital_pos = i as f64 / num_orbitals as f64;
140                    dipole[0] -= density_element * orbital_pos;
141                    dipole[1] -= density_element * orbital_pos * 0.5;
142                    dipole[2] -= density_element * orbital_pos * 0.3;
143                }
144            }
145        }
146        Ok(dipole)
147    }
148    /// Get method reference
149    #[must_use]
150    pub const fn get_method(&self) -> &FermionMapping {
151        &self.method
152    }
153    /// Get number of spin orbitals
154    #[must_use]
155    pub const fn get_num_spin_orbitals(&self) -> usize {
156        self.num_spin_orbitals
157    }
158}
159/// Optimizers for chemistry VQE
160#[derive(Debug, Clone, Copy, PartialEq, Eq)]
161pub enum ChemistryOptimizer {
162    /// Constrained Optimization BY Linear Approximation
163    COBYLA,
164    /// Sequential Least Squares Programming
165    SLSQP,
166    /// Powell's method
167    Powell,
168    /// Gradient descent
169    GradientDescent,
170    /// Adam optimizer
171    Adam,
172    /// Quantum Natural Gradient
173    QuantumNaturalGradient,
174}
175/// VQE optimizer for chemistry problems
176#[derive(Debug, Clone)]
177pub struct VQEOptimizer {
178    /// Optimization method
179    method: ChemistryOptimizer,
180    /// Current parameters
181    pub(super) parameters: Array1<f64>,
182    /// Parameter bounds
183    pub(crate) bounds: Vec<(f64, f64)>,
184    /// Optimization history
185    pub(super) history: Vec<f64>,
186    /// Gradient estimates
187    gradients: Array1<f64>,
188    /// Learning rate (for gradient-based methods)
189    pub(super) learning_rate: f64,
190}
191impl VQEOptimizer {
192    #[must_use]
193    pub fn new(method: ChemistryOptimizer) -> Self {
194        Self {
195            method,
196            parameters: Array1::zeros(0),
197            bounds: Vec::new(),
198            history: Vec::new(),
199            gradients: Array1::zeros(0),
200            learning_rate: 0.01,
201        }
202    }
203    pub(super) fn initialize_parameters(&mut self, num_parameters: usize) {
204        self.parameters = Array1::from_vec(
205            (0..num_parameters)
206                .map(|_| (thread_rng().random::<f64>() - 0.5) * 0.1)
207                .collect(),
208        );
209        self.bounds = vec![(-PI, PI); num_parameters];
210        self.gradients = Array1::zeros(num_parameters);
211    }
212    /// Initialize parameters (public version)
213    pub fn initialize_parameters_public(&mut self, num_parameters: usize) {
214        self.initialize_parameters(num_parameters);
215    }
216    /// Get parameters reference
217    #[must_use]
218    pub const fn get_parameters(&self) -> &Array1<f64> {
219        &self.parameters
220    }
221    /// Get bounds reference
222    #[must_use]
223    pub fn get_bounds(&self) -> &[(f64, f64)] {
224        &self.bounds
225    }
226    /// Get method reference
227    #[must_use]
228    pub const fn get_method(&self) -> &ChemistryOptimizer {
229        &self.method
230    }
231}
232/// Electronic structure methods
233#[derive(Debug, Clone, Copy, PartialEq, Eq)]
234pub enum ElectronicStructureMethod {
235    /// Hartree-Fock method
236    HartreeFock,
237    /// Variational Quantum Eigensolver
238    VQE,
239    /// Quantum Configuration Interaction
240    QuantumCI,
241    /// Quantum Coupled Cluster
242    QuantumCC,
243    /// Quantum Phase Estimation
244    QPE,
245}
246/// Hartree-Fock calculation result
247#[derive(Debug, Clone)]
248pub struct HartreeFockResult {
249    /// SCF energy
250    pub scf_energy: f64,
251    /// Molecular orbitals
252    pub molecular_orbitals: MolecularOrbitals,
253    /// Density matrix
254    pub density_matrix: Array2<f64>,
255    /// Fock matrix
256    pub fock_matrix: Array2<f64>,
257    /// Convergence achieved
258    pub converged: bool,
259    /// SCF iterations
260    pub scf_iterations: usize,
261}
262/// VQE configuration for chemistry calculations
263#[derive(Debug, Clone)]
264pub struct VQEConfig {
265    /// Ansatz type for VQE
266    pub ansatz: ChemistryAnsatz,
267    /// Optimizer for VQE
268    pub optimizer: ChemistryOptimizer,
269    /// Maximum VQE iterations
270    pub max_iterations: usize,
271    /// Convergence threshold for energy
272    pub energy_threshold: f64,
273    /// Gradient threshold for convergence
274    pub gradient_threshold: f64,
275    /// Shot noise for measurements
276    pub shots: usize,
277    /// Enable noise mitigation
278    pub enable_noise_mitigation: bool,
279}
280/// Electronic structure result
281#[derive(Debug, Clone)]
282pub struct ElectronicStructureResult {
283    /// Ground state energy
284    pub ground_state_energy: f64,
285    /// Molecular orbitals
286    pub molecular_orbitals: MolecularOrbitals,
287    /// Electronic density matrix
288    pub density_matrix: Array2<f64>,
289    /// Dipole moment
290    pub dipole_moment: Array1<f64>,
291    /// Convergence achieved
292    pub converged: bool,
293    /// Number of iterations performed
294    pub iterations: usize,
295    /// Final quantum state
296    pub quantum_state: Array1<Complex64>,
297    /// VQE optimization history
298    pub vqe_history: Vec<f64>,
299    /// Computational statistics
300    pub stats: ChemistryStats,
301}
302/// Electronic structure configuration
303#[derive(Debug, Clone)]
304pub struct ElectronicStructureConfig {
305    /// Method for electronic structure calculation
306    pub method: ElectronicStructureMethod,
307    /// Convergence criteria for SCF
308    pub convergence_threshold: f64,
309    /// Maximum SCF iterations
310    pub max_scf_iterations: usize,
311    /// Active space specification
312    pub active_space: Option<ActiveSpace>,
313    /// Enable second quantization optimization
314    pub enable_second_quantization_optimization: bool,
315    /// Fermion-to-spin mapping method
316    pub fermion_mapping: FermionMapping,
317    /// Enable orbital optimization
318    pub enable_orbital_optimization: bool,
319    /// VQE optimizer settings
320    pub vqe_config: VQEConfig,
321}
322/// Active space specification for reduced basis calculations
323#[derive(Debug, Clone)]
324pub struct ActiveSpace {
325    /// Number of active electrons
326    pub num_electrons: usize,
327    /// Number of active orbitals
328    pub num_orbitals: usize,
329    /// Orbital indices to include in active space
330    pub orbital_indices: Vec<usize>,
331    /// Frozen core orbitals
332    pub frozen_core: Vec<usize>,
333    /// Virtual orbitals to exclude
334    pub frozen_virtual: Vec<usize>,
335}
336/// Molecular structure representation
337#[derive(Debug, Clone)]
338pub struct Molecule {
339    /// Atomic numbers
340    pub atomic_numbers: Vec<u32>,
341    /// Atomic positions (x, y, z coordinates)
342    pub positions: Array2<f64>,
343    /// Molecular charge
344    pub charge: i32,
345    /// Spin multiplicity (2S + 1)
346    pub multiplicity: u32,
347    /// Basis set name
348    pub basis_set: String,
349}
350/// Chemistry-specific ansätze for VQE
351#[derive(Debug, Clone, Copy, PartialEq, Eq)]
352pub enum ChemistryAnsatz {
353    /// Unitary Coupled Cluster Singles and Doubles
354    UCCSD,
355    /// Hardware Efficient Ansatz
356    HardwareEfficient,
357    /// Symmetry-Preserving Ansatz
358    SymmetryPreserving,
359    /// Low-Depth Circuit Ansatz
360    LowDepth,
361    /// Adaptive VQE ansatz
362    Adaptive,
363}