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}