quant_iron/components/parametric/
parametric_gate.rs

1use crate::components::gate::Gate;
2use crate::components::parametric::parameter::Parameter;
3use std::fmt::Debug;
4
5/// A trait for gates that can be parametrised.
6///
7/// The trait defines the `to_concrete_gate` method for creating a concrete gate from the parametrised gate.
8/// This is required for applying the parametrised gate in a circuit or compiling it into OpenQASM.
9pub trait ParametricGate: Debug + Send + Sync {
10    /// Creates a concrete `Gate` using the current parameter values.
11    ///
12    /// # Arguments
13    ///
14    /// * `target_indices` - The indices of the target qubits.
15    /// * `control_indices` - The indices of the control qubits.
16    ///
17    /// # Returns
18    ///
19    /// Concrete `Gate::Operator` variants of the parameterised gate instance.
20    fn to_concrete_gates(&self, target_indices: &[usize], control_indices: &[usize]) -> Vec<Gate>;
21
22    /// Clones the trait object.
23    /// This is required by the `Gate` trait.
24    fn box_clone(&self) -> Box<dyn ParametricGate>;
25}
26
27impl Clone for Box<dyn ParametricGate> {
28    fn clone(&self) -> Self {
29        self.box_clone()
30    }
31}
32
33/// A parametrised RY phase gate
34///
35/// This operator can be decomposed into a rotation around the Y axis followed by a phase shift.
36/// The enclosed unitary matrix is guaranteed to be unitary.
37///
38/// # Fields
39/// - `parameter`: A `Parameter<2>` instance that holds the rotation angle (theta) and phase shift (phi).
40#[derive(Debug, Clone)]
41pub struct ParametricRyPhase {
42    pub parameter: Parameter<2>, // theta, phi
43}
44
45impl ParametricGate for ParametricRyPhase {
46    fn to_concrete_gates(&self, target_indices: &[usize], control_indices: &[usize]) -> Vec<Gate> {
47        let params = self.parameter.get();
48        Gate::ry_phase_controlled_gates(
49            target_indices.to_vec(),
50            control_indices.to_vec(),
51            params[0],
52            params[1],
53        )
54    }
55
56    fn box_clone(&self) -> Box<dyn ParametricGate> {
57        Box::new(self.clone())
58    }
59}
60
61/// A parametrised matchgate
62///
63/// A two-qubit operator that applies a matchgate transformation to the adjacent target qubits.
64/// This gate can be decomposed into a two-qubit rotation and phase shifts.
65///
66/// # Fields
67/// - `parameter`: A `Parameter<3>` instance that holds the rotation angle (theta) and phase shifts (phi1, phi2).
68#[derive(Debug, Clone)]
69pub struct ParametricMatchgate {
70    pub parameter: Parameter<3>, // theta, phi1, phi2
71}
72
73impl ParametricGate for ParametricMatchgate {
74    fn to_concrete_gates(&self, target_indices: &[usize], control_indices: &[usize]) -> Vec<Gate> {
75        let params = self.parameter.get();
76        vec![Gate::controlled_matchgate(
77            target_indices[0],
78            control_indices.to_vec(),
79            params[0],
80            params[1],
81            params[2],
82        )]
83    }
84
85    fn box_clone(&self) -> Box<dyn ParametricGate> {
86        Box::new(self.clone())
87    }
88}