From aea4f5d0f08d5f5bc2ebe20bda378a91107d9e66 Mon Sep 17 00:00:00 2001 From: mlodi-hqs Date: Thu, 17 Oct 2024 15:47:55 +0200 Subject: [PATCH] missed from last PR --- .../operations/three_qubit_gate_operations.rs | 8 +- .../operations/four_qubit_gate_operations.rs | 8 +- roqoqo-derive/src/operate_n_qubit.rs | 8 +- roqoqo-derive/src/operate_unitary.rs | 2 +- .../operations/four_qubit_gate_operations.rs | 3 - .../operations/four_qubit_gate_operations.rs | 722 +++++++++--------- 6 files changed, 371 insertions(+), 380 deletions(-) diff --git a/qoqo/src/operations/three_qubit_gate_operations.rs b/qoqo/src/operations/three_qubit_gate_operations.rs index dc90c11af..7c765c25a 100644 --- a/qoqo/src/operations/three_qubit_gate_operations.rs +++ b/qoqo/src/operations/three_qubit_gate_operations.rs @@ -219,10 +219,10 @@ impl ControlledSWAPWrapper { })?, }) } - /// Remap qubits + /// Remap qubits in the ControlledSWAP operation /// /// Args: - /// mapping (Dict[int, int]): The mapping + /// mapping (Dict[int, int]): The mapping to be used in the remapping. /// /// Returns: /// Operation: The operation with the remapped qubits @@ -238,7 +238,7 @@ impl ControlledSWAPWrapper { internal: new_internal, }) } - /// List all involved Qubits + /// List all involved qubits in the ControlledSWAP operation. /// /// Returns: /// Union[Set[int], str]: The involved qubits as a set or 'ALL' if all qubits are involved @@ -302,7 +302,6 @@ impl ControlledSWAPWrapper { )] /// The phased-shifted double-controlled-Z gate. /// -/// /// The unitary matrix representation is: /// /// .. math:: @@ -341,7 +340,6 @@ pub struct PhaseShiftedControlledControlledZ { )] /// The phased-shifted double-controlled-Z gate. /// -/// /// The unitary matrix representation is: /// /// .. math:: diff --git a/qoqo/tests/integration/operations/four_qubit_gate_operations.rs b/qoqo/tests/integration/operations/four_qubit_gate_operations.rs index 9cb8f9142..3b970133c 100644 --- a/qoqo/tests/integration/operations/four_qubit_gate_operations.rs +++ b/qoqo/tests/integration/operations/four_qubit_gate_operations.rs @@ -13,22 +13,18 @@ use ndarray::Array2; use num_complex::Complex64; use numpy::PyArray2; - -use qoqo_calculator::CalculatorFloat; - use pyo3::prelude::*; -use std::collections::HashMap; - use qoqo::operations::{ convert_operation_to_pyobject, TripleControlledPauliXWrapper, TripleControlledPauliZWrapper, TripleControlledPhaseShiftWrapper, }; use qoqo::CircuitWrapper; +use qoqo_calculator::CalculatorFloat; use roqoqo::operations::*; #[cfg(feature = "json_schema")] use roqoqo::ROQOQO_VERSION; use roqoqo::{Circuit, RoqoqoError}; - +use std::collections::HashMap; use test_case::test_case; #[test_case(Operation::from(TripleControlledPauliX::new(0, 1, 2, 3)); "TripleControlledPauliX")] diff --git a/roqoqo-derive/src/operate_n_qubit.rs b/roqoqo-derive/src/operate_n_qubit.rs index ba9f77f79..2c5648ed7 100644 --- a/roqoqo-derive/src/operate_n_qubit.rs +++ b/roqoqo-derive/src/operate_n_qubit.rs @@ -435,19 +435,19 @@ fn operate_four_qubit_struct(ident: Ident) -> TokenStream { /// Trait for Operations acting on exactly four qubits. impl OperateFourQubit for #ident{ /// Returns `control_0` qubit of the four qubit Operation. - fn control_0(&self ) -> &usize { + fn control_0(&self) -> &usize { &self.control_0 } /// Returns `control_1` qubit of the four qubit Operation. - fn control_1(&self ) -> &usize { + fn control_1(&self) -> &usize { &self.control_1 } /// Returns `control_2` qubit of the four qubit Operation. - fn control_2(&self ) -> &usize { + fn control_2(&self) -> &usize { &self.control_2 } /// Returns `target` qubit of the four qubit Operation. - fn target(&self ) -> &usize { + fn target(&self) -> &usize { &self.target } } diff --git a/roqoqo-derive/src/operate_unitary.rs b/roqoqo-derive/src/operate_unitary.rs index 7078a32fa..fce6fd51f 100644 --- a/roqoqo-derive/src/operate_unitary.rs +++ b/roqoqo-derive/src/operate_unitary.rs @@ -300,7 +300,7 @@ fn four_qubit_gate_struct(ident: Ident) -> TokenStream { quote! { #[automatically_derived] impl OperateFourQubitGate for #ident{ - fn circuit(&self ) -> crate::Circuit { + fn circuit(&self) -> crate::Circuit { self.circuit } } diff --git a/roqoqo/src/operations/four_qubit_gate_operations.rs b/roqoqo/src/operations/four_qubit_gate_operations.rs index 55ad89056..49d2d940f 100644 --- a/roqoqo/src/operations/four_qubit_gate_operations.rs +++ b/roqoqo/src/operations/four_qubit_gate_operations.rs @@ -17,7 +17,6 @@ use num_complex::Complex64; /// The triple-controlled PauliX gate. /// -/// #[allow(clippy::upper_case_acronyms)] #[derive( Debug, @@ -92,7 +91,6 @@ impl OperateFourQubitGate for TripleControlledPauliX { /// The triple-controlled PauliZ gate. /// -/// #[allow(clippy::upper_case_acronyms)] #[derive( Debug, @@ -166,7 +164,6 @@ impl OperateFourQubitGate for TripleControlledPauliZ { /// The triple-controlled PhaseShift gate. /// -/// #[allow(clippy::upper_case_acronyms)] #[derive( Debug, diff --git a/roqoqo/tests/integration/operations/four_qubit_gate_operations.rs b/roqoqo/tests/integration/operations/four_qubit_gate_operations.rs index ac24e1818..2a8c71fa9 100644 --- a/roqoqo/tests/integration/operations/four_qubit_gate_operations.rs +++ b/roqoqo/tests/integration/operations/four_qubit_gate_operations.rs @@ -49,6 +49,344 @@ fn test_circuit_triple_controlled_x() { assert!(c == comparison_circuit); } +#[test] +fn test_clone_partial_eq_triple_controlled_x() { + let gate = TripleControlledPauliX::new(0, 1, 2, 3); + let gate1 = TripleControlledPauliX::new(1, 2, 3, 4); + let helper = gate != gate1; + assert!(helper); + #[allow(clippy::redundant_clone)] + let gate2 = gate1.clone(); + assert_eq!(gate2, gate1); +} + +#[test] +fn test_operate_triple_controlled_x() { + let gate = TripleControlledPauliX::new(0, 1, 2, 3); + assert_eq!(gate.hqslang(), "TripleControlledPauliX"); + assert_eq!( + gate.tags(), + &[ + "Operation", + "GateOperation", + "FourQubitGateOperation", + "TripleControlledPauliX", + ] + ); + assert!(!gate.is_parametrized()); +} + +#[test] +fn test_substitute_triple_controlled_x() { + let gate = TripleControlledPauliX::new(0, 1, 2, 3); + let gate1 = TripleControlledPauliX::new(1, 2, 3, 0); + let mut substitution_dict: Calculator = Calculator::new(); + substitution_dict.set_variable("theta", 0.0); + let result = gate.substitute_parameters(&substitution_dict).unwrap(); + assert_eq!(result, gate); + + let mut mapping: HashMap = std::collections::HashMap::new(); + let _ = mapping.insert(0, 1); + let _ = mapping.insert(1, 2); + let _ = mapping.insert(2, 3); + let _ = mapping.insert(3, 0); + let remapped = gate1.remap_qubits(&mapping).unwrap(); + let qubits = remapped.involved_qubits(); + assert_eq!(qubits, InvolvedQubits::Set(HashSet::from([1, 2, 3, 0]))); +} + +#[test] +fn test_substitute_error_triple_controlled_x() { + let gate = TripleControlledPauliX::new(0, 1, 2, 3); + let mut mapping: HashMap = std::collections::HashMap::new(); + let _ = mapping.insert(1, 2); + let _ = mapping.insert(2, 3); + let _ = mapping.insert(3, 4); + let _ = mapping.insert(4, 0); + let remapped = gate.remap_qubits(&mapping); + assert!(remapped.is_err()); +} + +#[test] +fn test_format_triple_controlled_x() { + let gate = TripleControlledPauliX::new(0, 1, 2, 3); + let string = format!("{:?}", gate); + assert!(string.contains("TripleControlledPauliX")); + assert!(string.contains("control_0")); + assert!(string.contains("control_1")); + assert!(string.contains("control_2")); + assert!(string.contains("target")); + println!("{:?}", string); +} + +#[test] +fn test_involved_qubits_triple_controlled_x() { + let gate = TripleControlledPauliX::new(0, 1, 2, 3); + let involved_qubits = gate.involved_qubits(); + let mut comp_set: HashSet = HashSet::new(); + let _ = comp_set.insert(0); + let _ = comp_set.insert(1); + let _ = comp_set.insert(2); + let _ = comp_set.insert(3); + assert_eq!(involved_qubits, InvolvedQubits::Set(comp_set)); +} + +#[test] +fn test_circuit_triple_controlled_z() { + let gate = TripleControlledPauliZ::new(0, 1, 2, 3); + let c = gate.circuit(); + + let mut comparison_circuit = Circuit::new(); + comparison_circuit += ControlledPauliZ::new(0, 3); + comparison_circuit += CNOT::new(0, 1); + comparison_circuit += ControlledPauliZ::new(1, 3); + comparison_circuit += CNOT::new(0, 1); + comparison_circuit += ControlledPauliZ::new(1, 3); + comparison_circuit += CNOT::new(1, 2); + comparison_circuit += ControlledPauliZ::new(2, 3); + comparison_circuit += CNOT::new(0, 2); + comparison_circuit += ControlledPauliZ::new(2, 3); + comparison_circuit += CNOT::new(1, 2); + comparison_circuit += ControlledPauliZ::new(2, 3); + comparison_circuit += CNOT::new(0, 2); + comparison_circuit += ControlledPauliZ::new(2, 3); + + assert!(c == comparison_circuit); +} + +#[test] +fn test_clone_partial_eq_triple_controlled_z() { + let gate = TripleControlledPauliZ::new(0, 1, 2, 3); + let gate1 = TripleControlledPauliZ::new(1, 2, 3, 4); + let helper = gate != gate1; + assert!(helper); + #[allow(clippy::redundant_clone)] + let gate2 = gate1.clone(); + assert_eq!(gate2, gate1); +} + +#[test] +fn test_operate_triple_controlled_z() { + let gate = TripleControlledPauliZ::new(0, 1, 2, 3); + assert_eq!(gate.hqslang(), "TripleControlledPauliZ"); + assert_eq!( + gate.tags(), + &[ + "Operation", + "GateOperation", + "FourQubitGateOperation", + "TripleControlledPauliZ", + ] + ); + assert!(!gate.is_parametrized()); +} + +#[test] +fn test_substitute_triple_controlled_z() { + let gate = TripleControlledPauliZ::new(0, 1, 2, 3); + let gate1 = TripleControlledPauliZ::new(1, 2, 3, 0); + let mut substitution_dict: Calculator = Calculator::new(); + substitution_dict.set_variable("theta", 0.0); + let result = gate.substitute_parameters(&substitution_dict).unwrap(); + assert_eq!(result, gate); + + let mut mapping: HashMap = std::collections::HashMap::new(); + let _ = mapping.insert(0, 1); + let _ = mapping.insert(1, 2); + let _ = mapping.insert(2, 3); + let _ = mapping.insert(3, 0); + let remapped = gate1.remap_qubits(&mapping).unwrap(); + let qubits = remapped.involved_qubits(); + assert_eq!(qubits, InvolvedQubits::Set(HashSet::from([1, 2, 3, 0]))); +} + +#[test] +fn test_substitute_error_triple_controlled_z() { + let gate = TripleControlledPauliX::new(0, 1, 2, 3); + let mut mapping: HashMap = std::collections::HashMap::new(); + let _ = mapping.insert(1, 2); + let _ = mapping.insert(2, 3); + let _ = mapping.insert(3, 4); + let _ = mapping.insert(4, 0); + let remapped = gate.remap_qubits(&mapping); + assert!(remapped.is_err()); +} + +#[test] +fn test_format_triple_controlled_z() { + let gate = TripleControlledPauliZ::new(0, 1, 2, 3); + let string = format!("{:?}", gate); + assert!(string.contains("TripleControlledPauliZ")); + assert!(string.contains("control_0")); + assert!(string.contains("control_1")); + assert!(string.contains("control_2")); + assert!(string.contains("target")); + println!("{:?}", string); +} + +#[test] +fn test_involved_qubits_triple_controlled_z() { + let gate = TripleControlledPauliZ::new(0, 1, 2, 3); + let involved_qubits = gate.involved_qubits(); + let mut comp_set: HashSet = HashSet::new(); + let _ = comp_set.insert(0); + let _ = comp_set.insert(1); + let _ = comp_set.insert(2); + let _ = comp_set.insert(3); + assert_eq!(involved_qubits, InvolvedQubits::Set(comp_set)); +} + +#[test] +fn test_circuit_triple_controlled_phaseshift() { + let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::FRAC_PI_2); + let c = gate.circuit(); + + let mut comparison_circuit = Circuit::new(); + comparison_circuit += ControlledPhaseShift::new(0, 3, CalculatorFloat::FRAC_PI_4); + comparison_circuit += CNOT::new(0, 1); + comparison_circuit += ControlledPhaseShift::new(1, 3, -CalculatorFloat::FRAC_PI_4); + comparison_circuit += CNOT::new(0, 1); + comparison_circuit += ControlledPhaseShift::new(1, 3, CalculatorFloat::FRAC_PI_4); + comparison_circuit += CNOT::new(1, 2); + comparison_circuit += ControlledPhaseShift::new(2, 3, -CalculatorFloat::FRAC_PI_4); + comparison_circuit += CNOT::new(0, 2); + comparison_circuit += ControlledPhaseShift::new(2, 3, CalculatorFloat::FRAC_PI_4); + comparison_circuit += CNOT::new(1, 2); + comparison_circuit += ControlledPhaseShift::new(2, 3, -CalculatorFloat::FRAC_PI_4); + comparison_circuit += CNOT::new(0, 2); + comparison_circuit += ControlledPhaseShift::new(2, 3, CalculatorFloat::FRAC_PI_4); + + assert!(c == comparison_circuit); +} + +#[test] +fn test_clone_partial_eq_triple_controlled_phaseshift() { + let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); + let gate1 = TripleControlledPhaseShift::new(1, 2, 3, 4, CalculatorFloat::from(1.0)); + let helper = gate != gate1; + assert!(helper); + #[allow(clippy::redundant_clone)] + let gate2 = gate1.clone(); + assert_eq!(gate2, gate1); +} + +#[test] +fn test_operate_triple_controlled_phaseshift() { + let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); + let gate_p = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from("theta")); + assert_eq!(gate.hqslang(), "TripleControlledPhaseShift"); + assert_eq!( + gate.tags(), + &[ + "Operation", + "GateOperation", + "FourQubitGateOperation", + "TripleControlledPhaseShift", + ] + ); + assert!(!gate.is_parametrized()); + assert!(gate_p.is_parametrized()); +} + +#[test] +fn test_substitute_triple_controlled_phaseshift() { + let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); + let gate1 = TripleControlledPhaseShift::new(1, 2, 3, 0, CalculatorFloat::from(1.0)); + let mut substitution_dict: Calculator = Calculator::new(); + substitution_dict.set_variable("theta", 0.0); + let result = gate.substitute_parameters(&substitution_dict).unwrap(); + assert_eq!(result, gate); + + let mut mapping: HashMap = std::collections::HashMap::new(); + let _ = mapping.insert(0, 1); + let _ = mapping.insert(1, 2); + let _ = mapping.insert(2, 3); + let _ = mapping.insert(3, 0); + let remapped = gate1.remap_qubits(&mapping).unwrap(); + let qubits = remapped.involved_qubits(); + assert_eq!(qubits, InvolvedQubits::Set(HashSet::from([1, 2, 3, 0]))); +} + +#[test] +fn test_substitute_error_triple_controlled_phaseshift() { + let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); + let mut mapping: HashMap = std::collections::HashMap::new(); + let _ = mapping.insert(1, 2); + let _ = mapping.insert(2, 3); + let _ = mapping.insert(3, 4); + let _ = mapping.insert(4, 0); + let remapped = gate.remap_qubits(&mapping); + assert!(remapped.is_err()); +} + +#[test] +fn test_format_triple_controlled_phaseshift() { + let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); + let string = format!("{:?}", gate); + assert!(string.contains("TripleControlledPhaseShift")); + assert!(string.contains("control_0")); + assert!(string.contains("control_1")); + assert!(string.contains("control_2")); + assert!(string.contains("target")); + println!("{:?}", string); +} + +#[test] +fn test_involved_qubits_triple_controlled_phaseshift() { + let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); + let involved_qubits = gate.involved_qubits(); + let mut comp_set: HashSet = HashSet::new(); + let _ = comp_set.insert(0); + let _ = comp_set.insert(1); + let _ = comp_set.insert(2); + let _ = comp_set.insert(3); + assert_eq!(involved_qubits, InvolvedQubits::Set(comp_set)); +} + +/// Test JsonSchema trait +#[cfg(feature = "json_schema")] +#[test_case(FourQubitGateOperation::from(TripleControlledPauliX::new(0, 1, 2, 3)); "TripleControlledPauliX")] +#[test_case(FourQubitGateOperation::from(TripleControlledPauliZ::new(0, 1, 2, 3)); "TripleControlledPauliZ")] +#[test_case( + FourQubitGateOperation::from(TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(0.0))); + "TripleControlledPhaseShift" +)] +pub fn test_json_schema_three_qubit_gate_operations(gate: FourQubitGateOperation) { + // Serialize + let test_json = match gate.clone() { + FourQubitGateOperation::TripleControlledPauliX(op) => serde_json::to_string(&op).unwrap(), + FourQubitGateOperation::TripleControlledPauliZ(op) => serde_json::to_string(&op).unwrap(), + FourQubitGateOperation::TripleControlledPhaseShift(op) => { + serde_json::to_string(&op).unwrap() + } + _ => unreachable!(), + }; + let test_value: serde_json::Value = serde_json::from_str(&test_json).unwrap(); + + // Create JSONSchema + let test_schema = match gate { + FourQubitGateOperation::TripleControlledPauliX(_) => { + schema_for!(TripleControlledPauliX) + } + FourQubitGateOperation::TripleControlledPauliZ(_) => { + schema_for!(TripleControlledPauliZ) + } + FourQubitGateOperation::TripleControlledPhaseShift(_) => { + schema_for!(TripleControlledPhaseShift) + } + _ => unreachable!(), + }; + let schema = serde_json::to_string(&test_schema).unwrap(); + let schema_value: serde_json::Value = serde_json::from_str(&schema).unwrap(); + let compiled_schema = Validator::options() + .with_draft(Draft::Draft7) + .build(&schema_value) + .unwrap(); + + let validation_result = compiled_schema.validate(&test_value); + assert!(validation_result.is_ok()); +} + #[test] fn test_matrix_output_triple_controlled_x() { let gate = TripleControlledPauliX::new(0, 1, 2, 3); @@ -322,134 +660,29 @@ fn test_matrix_output_triple_controlled_x() { Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0), - ], - [ - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(0.0, 0.0), - Complex64::new(1.0, 0.0), - Complex64::new(0.0, 0.0), - ], - ]; - let unit = gate.unitary_matrix().unwrap(); - let should_be_zero = unit - test_array; - assert!(should_be_zero.iter().all(|x| x.norm() < f64::EPSILON)); -} - -#[test] -fn test_clone_partial_eq_triple_controlled_x() { - let gate = TripleControlledPauliX::new(0, 1, 2, 3); - let gate1 = TripleControlledPauliX::new(1, 2, 3, 4); - let helper = gate != gate1; - assert!(helper); - #[allow(clippy::redundant_clone)] - let gate2 = gate1.clone(); - assert_eq!(gate2, gate1); -} - -#[test] -fn test_operate_triple_controlled_x() { - let gate = TripleControlledPauliX::new(0, 1, 2, 3); - assert_eq!(gate.hqslang(), "TripleControlledPauliX"); - assert_eq!( - gate.tags(), - &[ - "Operation", - "GateOperation", - "FourQubitGateOperation", - "TripleControlledPauliX", - ] - ); - assert!(!gate.is_parametrized()); -} - -#[test] -fn test_substitute_triple_controlled_x() { - let gate = TripleControlledPauliX::new(0, 1, 2, 3); - let gate1 = TripleControlledPauliX::new(1, 2, 3, 0); - let mut substitution_dict: Calculator = Calculator::new(); - substitution_dict.set_variable("theta", 0.0); - let result = gate.substitute_parameters(&substitution_dict).unwrap(); - assert_eq!(result, gate); - - let mut mapping: HashMap = std::collections::HashMap::new(); - let _ = mapping.insert(0, 1); - let _ = mapping.insert(1, 2); - let _ = mapping.insert(2, 3); - let _ = mapping.insert(3, 0); - let remapped = gate1.remap_qubits(&mapping).unwrap(); - let qubits = remapped.involved_qubits(); - assert_eq!(qubits, InvolvedQubits::Set(HashSet::from([1, 2, 3, 0]))); -} - -#[test] -fn test_substitute_error_triple_controlled_x() { - let gate = TripleControlledPauliX::new(0, 1, 2, 3); - let mut mapping: HashMap = std::collections::HashMap::new(); - let _ = mapping.insert(1, 2); - let _ = mapping.insert(2, 3); - let _ = mapping.insert(3, 4); - let _ = mapping.insert(4, 0); - let remapped = gate.remap_qubits(&mapping); - assert!(remapped.is_err()); -} - -#[test] -fn test_format_triple_controlled_x() { - let gate = TripleControlledPauliX::new(0, 1, 2, 3); - let string = format!("{:?}", gate); - assert!(string.contains("TripleControlledPauliX")); - assert!(string.contains("control_0")); - assert!(string.contains("control_1")); - assert!(string.contains("control_2")); - assert!(string.contains("target")); - println!("{:?}", string); -} - -#[test] -fn test_involved_qubits_triple_controlled_x() { - let gate = TripleControlledPauliX::new(0, 1, 2, 3); - let involved_qubits = gate.involved_qubits(); - let mut comp_set: HashSet = HashSet::new(); - let _ = comp_set.insert(0); - let _ = comp_set.insert(1); - let _ = comp_set.insert(2); - let _ = comp_set.insert(3); - assert_eq!(involved_qubits, InvolvedQubits::Set(comp_set)); -} - -#[test] -fn test_circuit_triple_controlled_z() { - let gate = TripleControlledPauliZ::new(0, 1, 2, 3); - let c = gate.circuit(); - - let mut comparison_circuit = Circuit::new(); - comparison_circuit += ControlledPauliZ::new(0, 3); - comparison_circuit += CNOT::new(0, 1); - comparison_circuit += ControlledPauliZ::new(1, 3); - comparison_circuit += CNOT::new(0, 1); - comparison_circuit += ControlledPauliZ::new(1, 3); - comparison_circuit += CNOT::new(1, 2); - comparison_circuit += ControlledPauliZ::new(2, 3); - comparison_circuit += CNOT::new(0, 2); - comparison_circuit += ControlledPauliZ::new(2, 3); - comparison_circuit += CNOT::new(1, 2); - comparison_circuit += ControlledPauliZ::new(2, 3); - comparison_circuit += CNOT::new(0, 2); - comparison_circuit += ControlledPauliZ::new(2, 3); - - assert!(c == comparison_circuit); + ], + [ + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(0.0, 0.0), + Complex64::new(1.0, 0.0), + Complex64::new(0.0, 0.0), + ], + ]; + let unit = gate.unitary_matrix().unwrap(); + let should_be_zero = unit - test_array; + assert!(should_be_zero.iter().all(|x| x.norm() < f64::EPSILON)); } #[test] @@ -750,111 +983,6 @@ fn test_matrix_output_triple_controlled_z() { assert!(should_be_zero.iter().all(|x| x.norm() < f64::EPSILON)); } -#[test] -fn test_clone_partial_eq_triple_controlled_z() { - let gate = TripleControlledPauliZ::new(0, 1, 2, 3); - let gate1 = TripleControlledPauliZ::new(1, 2, 3, 4); - let helper = gate != gate1; - assert!(helper); - #[allow(clippy::redundant_clone)] - let gate2 = gate1.clone(); - assert_eq!(gate2, gate1); -} - -#[test] -fn test_operate_triple_controlled_z() { - let gate = TripleControlledPauliZ::new(0, 1, 2, 3); - assert_eq!(gate.hqslang(), "TripleControlledPauliZ"); - assert_eq!( - gate.tags(), - &[ - "Operation", - "GateOperation", - "FourQubitGateOperation", - "TripleControlledPauliZ", - ] - ); - assert!(!gate.is_parametrized()); -} - -#[test] -fn test_substitute_triple_controlled_z() { - let gate = TripleControlledPauliZ::new(0, 1, 2, 3); - let gate1 = TripleControlledPauliZ::new(1, 2, 3, 0); - let mut substitution_dict: Calculator = Calculator::new(); - substitution_dict.set_variable("theta", 0.0); - let result = gate.substitute_parameters(&substitution_dict).unwrap(); - assert_eq!(result, gate); - - let mut mapping: HashMap = std::collections::HashMap::new(); - let _ = mapping.insert(0, 1); - let _ = mapping.insert(1, 2); - let _ = mapping.insert(2, 3); - let _ = mapping.insert(3, 0); - let remapped = gate1.remap_qubits(&mapping).unwrap(); - let qubits = remapped.involved_qubits(); - assert_eq!(qubits, InvolvedQubits::Set(HashSet::from([1, 2, 3, 0]))); -} - -#[test] -fn test_substitute_error_triple_controlled_z() { - let gate = TripleControlledPauliX::new(0, 1, 2, 3); - let mut mapping: HashMap = std::collections::HashMap::new(); - let _ = mapping.insert(1, 2); - let _ = mapping.insert(2, 3); - let _ = mapping.insert(3, 4); - let _ = mapping.insert(4, 0); - let remapped = gate.remap_qubits(&mapping); - assert!(remapped.is_err()); -} - -#[test] -fn test_format_triple_controlled_z() { - let gate = TripleControlledPauliZ::new(0, 1, 2, 3); - let string = format!("{:?}", gate); - assert!(string.contains("TripleControlledPauliZ")); - assert!(string.contains("control_0")); - assert!(string.contains("control_1")); - assert!(string.contains("control_2")); - assert!(string.contains("target")); - println!("{:?}", string); -} - -#[test] -fn test_involved_qubits_triple_controlled_z() { - let gate = TripleControlledPauliZ::new(0, 1, 2, 3); - let involved_qubits = gate.involved_qubits(); - let mut comp_set: HashSet = HashSet::new(); - let _ = comp_set.insert(0); - let _ = comp_set.insert(1); - let _ = comp_set.insert(2); - let _ = comp_set.insert(3); - assert_eq!(involved_qubits, InvolvedQubits::Set(comp_set)); -} - -#[test] -fn test_circuit_triple_controlled_phaseshift() { - let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::FRAC_PI_2); - let c = gate.circuit(); - - let mut comparison_circuit = Circuit::new(); - comparison_circuit += ControlledPhaseShift::new(0, 3, CalculatorFloat::FRAC_PI_4); - comparison_circuit += CNOT::new(0, 1); - comparison_circuit += ControlledPhaseShift::new(1, 3, -CalculatorFloat::FRAC_PI_4); - comparison_circuit += CNOT::new(0, 1); - comparison_circuit += ControlledPhaseShift::new(1, 3, CalculatorFloat::FRAC_PI_4); - comparison_circuit += CNOT::new(1, 2); - comparison_circuit += ControlledPhaseShift::new(2, 3, -CalculatorFloat::FRAC_PI_4); - comparison_circuit += CNOT::new(0, 2); - comparison_circuit += ControlledPhaseShift::new(2, 3, CalculatorFloat::FRAC_PI_4); - comparison_circuit += CNOT::new(1, 2); - comparison_circuit += ControlledPhaseShift::new(2, 3, -CalculatorFloat::FRAC_PI_4); - comparison_circuit += CNOT::new(0, 2); - comparison_circuit += ControlledPhaseShift::new(2, 3, CalculatorFloat::FRAC_PI_4); - - assert!(c == comparison_circuit); -} - #[test] fn test_matrix_output_triple_controlled_phaseshift() { let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::FRAC_PI_2); @@ -1152,131 +1280,3 @@ fn test_matrix_output_triple_controlled_phaseshift() { let should_be_zero = unit - test_array; assert!(should_be_zero.iter().all(|x| x.norm() < f64::EPSILON)); } - -#[test] -fn test_clone_partial_eq_triple_controlled_phaseshift() { - let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); - let gate1 = TripleControlledPhaseShift::new(1, 2, 3, 4, CalculatorFloat::from(1.0)); - let helper = gate != gate1; - assert!(helper); - #[allow(clippy::redundant_clone)] - let gate2 = gate1.clone(); - assert_eq!(gate2, gate1); -} - -#[test] -fn test_operate_triple_controlled_phaseshift() { - let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); - let gate_p = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from("theta")); - assert_eq!(gate.hqslang(), "TripleControlledPhaseShift"); - assert_eq!( - gate.tags(), - &[ - "Operation", - "GateOperation", - "FourQubitGateOperation", - "TripleControlledPhaseShift", - ] - ); - assert!(!gate.is_parametrized()); - assert!(gate_p.is_parametrized()); -} - -#[test] -fn test_substitute_triple_controlled_phaseshift() { - let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); - let gate1 = TripleControlledPhaseShift::new(1, 2, 3, 0, CalculatorFloat::from(1.0)); - let mut substitution_dict: Calculator = Calculator::new(); - substitution_dict.set_variable("theta", 0.0); - let result = gate.substitute_parameters(&substitution_dict).unwrap(); - assert_eq!(result, gate); - - let mut mapping: HashMap = std::collections::HashMap::new(); - let _ = mapping.insert(0, 1); - let _ = mapping.insert(1, 2); - let _ = mapping.insert(2, 3); - let _ = mapping.insert(3, 0); - let remapped = gate1.remap_qubits(&mapping).unwrap(); - let qubits = remapped.involved_qubits(); - assert_eq!(qubits, InvolvedQubits::Set(HashSet::from([1, 2, 3, 0]))); -} - -#[test] -fn test_substitute_error_triple_controlled_phaseshift() { - let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); - let mut mapping: HashMap = std::collections::HashMap::new(); - let _ = mapping.insert(1, 2); - let _ = mapping.insert(2, 3); - let _ = mapping.insert(3, 4); - let _ = mapping.insert(4, 0); - let remapped = gate.remap_qubits(&mapping); - assert!(remapped.is_err()); -} - -#[test] -fn test_format_triple_controlled_phaseshift() { - let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); - let string = format!("{:?}", gate); - assert!(string.contains("TripleControlledPhaseShift")); - assert!(string.contains("control_0")); - assert!(string.contains("control_1")); - assert!(string.contains("control_2")); - assert!(string.contains("target")); - println!("{:?}", string); -} - -#[test] -fn test_involved_qubits_triple_controlled_phaseshift() { - let gate = TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(1.0)); - let involved_qubits = gate.involved_qubits(); - let mut comp_set: HashSet = HashSet::new(); - let _ = comp_set.insert(0); - let _ = comp_set.insert(1); - let _ = comp_set.insert(2); - let _ = comp_set.insert(3); - assert_eq!(involved_qubits, InvolvedQubits::Set(comp_set)); -} - -/// Test JsonSchema trait -#[cfg(feature = "json_schema")] -#[test_case(FourQubitGateOperation::from(TripleControlledPauliX::new(0, 1, 2, 3)); "TripleControlledPauliX")] -#[test_case(FourQubitGateOperation::from(TripleControlledPauliZ::new(0, 1, 2, 3)); "TripleControlledPauliZ")] -#[test_case( - FourQubitGateOperation::from(TripleControlledPhaseShift::new(0, 1, 2, 3, CalculatorFloat::from(0.0))); - "TripleControlledPhaseShift" -)] -pub fn test_json_schema_three_qubit_gate_operations(gate: FourQubitGateOperation) { - // Serialize - let test_json = match gate.clone() { - FourQubitGateOperation::TripleControlledPauliX(op) => serde_json::to_string(&op).unwrap(), - FourQubitGateOperation::TripleControlledPauliZ(op) => serde_json::to_string(&op).unwrap(), - FourQubitGateOperation::TripleControlledPhaseShift(op) => { - serde_json::to_string(&op).unwrap() - } - _ => unreachable!(), - }; - let test_value: serde_json::Value = serde_json::from_str(&test_json).unwrap(); - - // Create JSONSchema - let test_schema = match gate { - FourQubitGateOperation::TripleControlledPauliX(_) => { - schema_for!(TripleControlledPauliX) - } - FourQubitGateOperation::TripleControlledPauliZ(_) => { - schema_for!(TripleControlledPauliZ) - } - FourQubitGateOperation::TripleControlledPhaseShift(_) => { - schema_for!(TripleControlledPhaseShift) - } - _ => unreachable!(), - }; - let schema = serde_json::to_string(&test_schema).unwrap(); - let schema_value: serde_json::Value = serde_json::from_str(&schema).unwrap(); - let compiled_schema = Validator::options() - .with_draft(Draft::Draft7) - .build(&schema_value) - .unwrap(); - - let validation_result = compiled_schema.validate(&test_value); - assert!(validation_result.is_ok()); -}