diff --git a/qoqo/src/operations/two_qubit_gate_operations.rs b/qoqo/src/operations/two_qubit_gate_operations.rs index 3a2e8b35..b2d33c1b 100644 --- a/qoqo/src/operations/two_qubit_gate_operations.rs +++ b/qoqo/src/operations/two_qubit_gate_operations.rs @@ -493,7 +493,7 @@ pub struct ComplexPMInteraction { } #[allow(clippy::upper_case_acronyms)] -#[wrap(Operate, OperateTwoQubit, OperateGate)] //+ OperateTwoQubitGate (tbd) +#[wrap(Operate, OperateTwoQubit, OperateGate, OperateTwoQubitGate)] /// The phased-shifted controlled-Z gate. /// /// Modified, i.e. phase-shifted ControlledPauliZ two-qubit gate (https://arxiv.org/pdf/1908.06101.pdf eq.(1)). @@ -505,7 +505,7 @@ pub struct ComplexPMInteraction { /// 1 & 0 & 0 & 0 \\\\ /// 0 & e^{i \phi} & 0 & 0 \\\\ /// 0 & 0 & e^{i \phi} & 0 \\\\ -/// 0 & 0 & 0 & e^{i (2\cdot\phi - \pi} +/// 0 & 0 & 0 & e^{i (2\cdot\phi - \pi)} /// \end{pmatrix} /// /// Args: diff --git a/roqoqo/src/operations/_auto_generated_operations.rs b/roqoqo/src/operations/_auto_generated_operations.rs index 18d7dbe8..6b2f62f2 100644 --- a/roqoqo/src/operations/_auto_generated_operations.rs +++ b/roqoqo/src/operations/_auto_generated_operations.rs @@ -708,6 +708,9 @@ pub enum TwoQubitGateOperation { #[allow(clippy::upper_case_acronyms)] #[doc = "Variant for ComplexPMInteraction"] ComplexPMInteraction(ComplexPMInteraction), + #[allow(clippy::upper_case_acronyms)] + #[doc = "Variant for PhaseShiftedControlledZ"] + PhaseShiftedControlledZ(PhaseShiftedControlledZ), } #[doc = r" Enum of all Operations implementing [OperateMultiQubitGate]"] #[derive( diff --git a/roqoqo/src/operations/single_qubit_gate_operations.rs b/roqoqo/src/operations/single_qubit_gate_operations.rs index 01865aa4..8a577081 100644 --- a/roqoqo/src/operations/single_qubit_gate_operations.rs +++ b/roqoqo/src/operations/single_qubit_gate_operations.rs @@ -166,7 +166,7 @@ impl OperateSingleQubitGate for SingleQubitGate { /// 0 & \cos(\frac{\theta}{2}) /// \end{pmatrix} /// + \begin{pmatrix} -/// - i \sin(\frac{\theta}{2}) & 0\\\\ +/// -i \sin(\frac{\theta}{2}) & 0\\\\ /// 0 & i \sin(\frac{\theta}{2}) /// \end{pmatrix} /// $$ @@ -1276,7 +1276,7 @@ impl OperateGate for RotateAroundSphericalAxis { * ((f64::try_from(self.spherical_phi.clone())?).cos()); let vy: f64 = ((f64::try_from(self.spherical_theta.clone())?).sin()) * ((f64::try_from(self.spherical_phi.clone())?).sin()); - let vz: f64 = 0.0; + let vz: f64 = (f64::try_from(self.spherical_theta.clone())?).cos(); Ok(array![ [ Complex64::new(c, -1.0 * s * vz), diff --git a/roqoqo/src/operations/two_qubit_gate_operations.rs b/roqoqo/src/operations/two_qubit_gate_operations.rs index cb73896b..65e09673 100644 --- a/roqoqo/src/operations/two_qubit_gate_operations.rs +++ b/roqoqo/src/operations/two_qubit_gate_operations.rs @@ -2162,7 +2162,7 @@ impl OperateTwoQubitGate for ComplexPMInteraction { /// 1 & 0 & 0 & 0 \\\\ /// 0 & e^{i \phi} & 0 & 0 \\\\ /// 0 & 0 & e^{i \phi} & 0 \\\\ -/// 0 & 0 & 0 & e^{i (2\cdot\phi - \pi} +/// 0 & 0 & 0 & e^{i (2\cdot\phi - \pi)} /// \end{pmatrix} /// $$ /// @@ -2237,3 +2237,33 @@ impl OperateGate for PhaseShiftedControlledZ { ]) } } + +/// Trait for all gate operations acting on exactly two qubits. +impl OperateTwoQubitGate for PhaseShiftedControlledZ { + /// Returns [KakDecomposition] of the gate. + /// + /// # Returns + /// + /// * struct `KakDecomposition { global_phase, k_vector, circuit_before, circuit_after }` + fn kak_decomposition(&self) -> KakDecomposition { + let mut circuit_b = Circuit::new(); + circuit_b += RotateZ::new(self.control, CalculatorFloat::FRAC_PI_2); + circuit_b += RotateZ::new(self.target, CalculatorFloat::FRAC_PI_2); + + let mut circuit_a = Circuit::new(); + circuit_a += RotateZ::new(self.control, self.phi.clone()); + circuit_a += RotateZ::new(self.target, self.phi.clone()); + + let g: CalculatorFloat = CalculatorFloat::FRAC_PI_4 + self.phi.clone(); + KakDecomposition { + global_phase: g, + k_vector: [ + CalculatorFloat::ZERO, + CalculatorFloat::ZERO, + CalculatorFloat::FRAC_PI_4, + ], + circuit_before: Some(circuit_b), + circuit_after: Some(circuit_a), + } + } +} diff --git a/roqoqo/tests/integration/operations/two_qubit_gate_operations.rs b/roqoqo/tests/integration/operations/two_qubit_gate_operations.rs index c44077b6..f52d2a29 100644 --- a/roqoqo/tests/integration/operations/two_qubit_gate_operations.rs +++ b/roqoqo/tests/integration/operations/two_qubit_gate_operations.rs @@ -157,6 +157,9 @@ fn kak_sigma_matrix( #[test_case(TwoQubitGateOperation::from(ComplexPMInteraction::new(0, 1, CalculatorFloat::from(1.0), CalculatorFloat::from(-1.0))); "ComplexPMInteraction")] #[test_case(TwoQubitGateOperation::from(ControlledPauliY::new(0, 1)); "ControlledPauliY")] #[test_case(TwoQubitGateOperation::from(Bogoliubov::new(0, 1, CalculatorFloat::from(1.0), CalculatorFloat::from(-1.0))); "Bogoliubov")] +#[test_case(TwoQubitGateOperation::from(PhaseShiftedControlledZ::new(0, 1, CalculatorFloat::PI)); "PhaseShiftedControlledZ_pi")] +#[test_case(TwoQubitGateOperation::from(PhaseShiftedControlledZ::new(0, 1, CalculatorFloat::ZERO)); "PhaseShiftedControlledZ_zero")] +#[test_case(TwoQubitGateOperation::from(PhaseShiftedControlledZ::new(0, 1, CalculatorFloat::from(PI/(-3.0)))); "PhaseShiftedControlledZ")] fn test_kakdecomposition(gate: TwoQubitGateOperation) { // k vector let k = gate.kak_decomposition().k_vector; @@ -360,6 +363,7 @@ fn test_twoqubitgates_clone(gate1: Operation) { #[test_case(TwoQubitGateOperation::from(Bogoliubov::new(0, 1, CalculatorFloat::from(1.0), CalculatorFloat::from(-1.0))); "Bogoliubov")] #[test_case(TwoQubitGateOperation::from(PMInteraction::new(0, 1, CalculatorFloat::PI)); "PMInteraction")] #[test_case(TwoQubitGateOperation::from(ComplexPMInteraction::new(0, 1, CalculatorFloat::from(1.0), CalculatorFloat::from(-1.0))); "ComplexPMInteraction")] +#[test_case(TwoQubitGateOperation::from(PhaseShiftedControlledZ::new(0, 1, CalculatorFloat::FRAC_PI_4)); "PhaseShiftedControlledZ")] fn test_qubits_twoqubitgates(gate: TwoQubitGateOperation) { let control: &usize = &gate.control(); assert_eq!(control, &0);