diff --git a/crates/circuit/src/gate_matrix.rs b/crates/circuit/src/gate_matrix.rs index 6f527af2e30f..a38783ef7e7f 100644 --- a/crates/circuit/src/gate_matrix.rs +++ b/crates/circuit/src/gate_matrix.rs @@ -46,28 +46,21 @@ macro_rules! make_n_controlled_gate { }}; } +pub static H_GATE: GateArray1Q = [ + [c64(FRAC_1_SQRT_2, 0.), c64(FRAC_1_SQRT_2, 0.)], + [c64(FRAC_1_SQRT_2, 0.), c64(-FRAC_1_SQRT_2, 0.)], +]; + pub static X_GATE: GateArray1Q = [[C_ZERO, C_ONE], [C_ONE, C_ZERO]]; pub static Z_GATE: GateArray1Q = [[C_ONE, C_ZERO], [C_ZERO, C_M_ONE]]; pub static Y_GATE: GateArray1Q = [[C_ZERO, M_IM], [IM, C_ZERO]]; -pub static H_GATE: GateArray1Q = [ - [c64(FRAC_1_SQRT_2, 0.), c64(FRAC_1_SQRT_2, 0.)], - [c64(FRAC_1_SQRT_2, 0.), c64(-FRAC_1_SQRT_2, 0.)], -]; - pub static S_GATE: GateArray1Q = [[C_ONE, C_ZERO], [C_ZERO, IM]]; pub static SDG_GATE: GateArray1Q = [[C_ONE, C_ZERO], [C_ZERO, M_IM]]; -pub static T_GATE: GateArray1Q = [[C_ONE, C_ZERO], [C_ZERO, c64(FRAC_1_SQRT_2, FRAC_1_SQRT_2)]]; - -pub static TDG_GATE: GateArray1Q = [ - [C_ONE, C_ZERO], - [C_ZERO, c64(FRAC_1_SQRT_2, -FRAC_1_SQRT_2)], -]; - pub static SX_GATE: GateArray1Q = [ [c64(0.5, 0.5), c64(0.5, -0.5)], [c64(0.5, -0.5), c64(0.5, 0.5)], @@ -78,27 +71,27 @@ pub static SXDG_GATE: GateArray1Q = [ [c64(0.5, 0.5), c64(0.5, -0.5)], ]; -pub static CX_GATE: GateArray2Q = make_n_controlled_gate!(X_GATE, 1); - -pub static CZ_GATE: GateArray2Q = make_n_controlled_gate!(Z_GATE, 1); - -pub static CY_GATE: GateArray2Q = make_n_controlled_gate!(Y_GATE, 1); - -pub static CCX_GATE: GateArray3Q = make_n_controlled_gate!(X_GATE, 2); - -pub static CCZ_GATE: GateArray3Q = make_n_controlled_gate!(Z_GATE, 2); - -pub static C3X_GATE: GateArray4Q = make_n_controlled_gate!(X_GATE, 3); +pub static T_GATE: GateArray1Q = [[C_ONE, C_ZERO], [C_ZERO, c64(FRAC_1_SQRT_2, FRAC_1_SQRT_2)]]; -pub static C3SX_GATE: GateArray4Q = make_n_controlled_gate!(SX_GATE, 3); +pub static TDG_GATE: GateArray1Q = [ + [C_ONE, C_ZERO], + [C_ZERO, c64(FRAC_1_SQRT_2, -FRAC_1_SQRT_2)], +]; pub static CH_GATE: GateArray2Q = make_n_controlled_gate!(H_GATE, 1); -pub static CS_GATE: GateArray2Q = make_n_controlled_gate!(S_GATE, 1); +pub static CX_GATE: GateArray2Q = make_n_controlled_gate!(X_GATE, 1); -pub static CSDG_GATE: GateArray2Q = make_n_controlled_gate!(SDG_GATE, 1); +pub static CY_GATE: GateArray2Q = make_n_controlled_gate!(Y_GATE, 1); -pub static CSX_GATE: GateArray2Q = make_n_controlled_gate!(SX_GATE, 1); +pub static CZ_GATE: GateArray2Q = make_n_controlled_gate!(Z_GATE, 1); + +pub static DCX_GATE: GateArray2Q = [ + [C_ONE, C_ZERO, C_ZERO, C_ZERO], + [C_ZERO, C_ZERO, C_ZERO, C_ONE], + [C_ZERO, C_ONE, C_ZERO, C_ZERO], + [C_ZERO, C_ZERO, C_ONE, C_ZERO], +]; pub static ECR_GATE: GateArray2Q = [ [ @@ -133,6 +126,7 @@ pub static SWAP_GATE: GateArray2Q = [ [C_ZERO, C_ONE, C_ZERO, C_ZERO], [C_ZERO, C_ZERO, C_ZERO, C_ONE], ]; + pub static ISWAP_GATE: GateArray2Q = [ [C_ONE, C_ZERO, C_ZERO, C_ZERO], [C_ZERO, C_ZERO, IM, C_ZERO], @@ -140,6 +134,16 @@ pub static ISWAP_GATE: GateArray2Q = [ [C_ZERO, C_ZERO, C_ZERO, C_ONE], ]; +pub static CS_GATE: GateArray2Q = make_n_controlled_gate!(S_GATE, 1); + +pub static CSDG_GATE: GateArray2Q = make_n_controlled_gate!(SDG_GATE, 1); + +pub static CSX_GATE: GateArray2Q = make_n_controlled_gate!(SX_GATE, 1); + +pub static CCX_GATE: GateArray3Q = make_n_controlled_gate!(X_GATE, 2); + +pub static CCZ_GATE: GateArray3Q = make_n_controlled_gate!(Z_GATE, 2); + pub static CSWAP_GATE: GateArray3Q = [ [ C_ONE, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, @@ -167,13 +171,6 @@ pub static CSWAP_GATE: GateArray3Q = [ ], ]; -pub static DCX_GATE: GateArray2Q = [ - [C_ONE, C_ZERO, C_ZERO, C_ZERO], - [C_ZERO, C_ZERO, C_ZERO, C_ONE], - [C_ZERO, C_ONE, C_ZERO, C_ZERO], - [C_ZERO, C_ZERO, C_ONE, C_ZERO], -]; - pub static RCCX_GATE: GateArray3Q = [ [ C_ONE, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, @@ -197,6 +194,10 @@ pub static RCCX_GATE: GateArray3Q = [ [C_ZERO, C_ZERO, C_ZERO, IM, C_ZERO, C_ZERO, C_ZERO, C_ZERO], ]; +pub static C3X_GATE: GateArray4Q = make_n_controlled_gate!(X_GATE, 3); + +pub static C3SX_GATE: GateArray4Q = make_n_controlled_gate!(SX_GATE, 3); + pub static RC3X_GATE: GateArray4Q = [ [ C_ONE, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, @@ -274,6 +275,41 @@ pub fn phase_gate(lam: f64) -> GateArray1Q { [[C_ONE, C_ZERO], [C_ZERO, c64(0., lam).exp()]] } +#[inline] +pub fn r_gate(theta: f64, phi: f64) -> GateArray1Q { + let half_theta = theta / 2.; + let cost = c64(half_theta.cos(), 0.); + let sint = half_theta.sin(); + let cosphi = phi.cos(); + let sinphi = phi.sin(); + [ + [cost, c64(-sint * sinphi, -sint * cosphi)], + [c64(sint * sinphi, -sint * cosphi), cost], + ] +} + +#[inline] +pub fn rx_gate(theta: f64) -> GateArray1Q { + let half_theta = theta / 2.; + let cos = c64(half_theta.cos(), 0.); + let isin = c64(0., -half_theta.sin()); + [[cos, isin], [isin, cos]] +} + +#[inline] +pub fn ry_gate(theta: f64) -> GateArray1Q { + let half_theta = theta / 2.; + let cos = c64(half_theta.cos(), 0.); + let sin = c64(half_theta.sin(), 0.); + [[cos, -sin], [sin, cos]] +} + +#[inline] +pub fn rz_gate(theta: f64) -> GateArray1Q { + let ilam2 = c64(0., 0.5 * theta); + [[(-ilam2).exp(), C_ZERO], [C_ZERO, ilam2.exp()]] +} + #[inline] pub fn u_gate(theta: f64, phi: f64, lam: f64) -> GateArray1Q { let cos = (theta / 2.).cos(); @@ -323,6 +359,24 @@ pub fn cp_gate(lam: f64) -> GateArray2Q { ] } +#[inline] +pub fn crx_gate(theta: f64) -> GateArray2Q { + let gate_matrix = rx_gate(theta); + make_n_controlled_gate!(gate_matrix, 1) +} + +#[inline] +pub fn cry_gate(theta: f64) -> GateArray2Q { + let gate_matrix = ry_gate(theta); + make_n_controlled_gate!(gate_matrix, 1) +} + +#[inline] +pub fn crz_gate(theta: f64) -> GateArray2Q { + let gate_matrix = rz_gate(theta); + make_n_controlled_gate!(gate_matrix, 1) +} + #[inline] pub fn cu_gate(theta: f64, phi: f64, lam: f64, gamma: f64) -> GateArray2Q { let cos_theta = (theta / 2.).cos(); @@ -357,59 +411,6 @@ pub fn cu3_gate(theta: f64, phi: f64, lam: f64) -> GateArray2Q { make_n_controlled_gate!(gate_matrix, 1) } -#[inline] -pub fn r_gate(theta: f64, phi: f64) -> GateArray1Q { - let half_theta = theta / 2.; - let cost = c64(half_theta.cos(), 0.); - let sint = half_theta.sin(); - let cosphi = phi.cos(); - let sinphi = phi.sin(); - [ - [cost, c64(-sint * sinphi, -sint * cosphi)], - [c64(sint * sinphi, -sint * cosphi), cost], - ] -} - -#[inline] -pub fn rx_gate(theta: f64) -> GateArray1Q { - let half_theta = theta / 2.; - let cos = c64(half_theta.cos(), 0.); - let isin = c64(0., -half_theta.sin()); - [[cos, isin], [isin, cos]] -} - -#[inline] -pub fn ry_gate(theta: f64) -> GateArray1Q { - let half_theta = theta / 2.; - let cos = c64(half_theta.cos(), 0.); - let sin = c64(half_theta.sin(), 0.); - [[cos, -sin], [sin, cos]] -} - -#[inline] -pub fn rz_gate(theta: f64) -> GateArray1Q { - let ilam2 = c64(0., 0.5 * theta); - [[(-ilam2).exp(), C_ZERO], [C_ZERO, ilam2.exp()]] -} - -#[inline] -pub fn crx_gate(theta: f64) -> GateArray2Q { - let gate_matrix = rx_gate(theta); - make_n_controlled_gate!(gate_matrix, 1) -} - -#[inline] -pub fn cry_gate(theta: f64) -> GateArray2Q { - let gate_matrix = ry_gate(theta); - make_n_controlled_gate!(gate_matrix, 1) -} - -#[inline] -pub fn crz_gate(theta: f64) -> GateArray2Q { - let gate_matrix = rz_gate(theta); - make_n_controlled_gate!(gate_matrix, 1) -} - #[inline] pub fn rxx_gate(theta: f64) -> GateArray2Q { let (sint, cost) = (theta / 2.0).sin_cos(); diff --git a/crates/circuit/src/imports.rs b/crates/circuit/src/imports.rs index d277dea9f89c..153b66392083 100644 --- a/crates/circuit/src/imports.rs +++ b/crates/circuit/src/imports.rs @@ -86,121 +86,119 @@ pub static WARNINGS_WARN: ImportOnceCell = ImportOnceCell::new("warnings", "warn /// index of it's entry in this table. This is all done statically for performance // TODO: replace placeholders with actual implementation static STDGATE_IMPORT_PATHS: [[&str; 2]; STANDARD_GATE_SIZE] = [ - // ZGate = 0 - ["qiskit.circuit.library.standard_gates.z", "ZGate"], - // YGate = 1 - ["qiskit.circuit.library.standard_gates.y", "YGate"], - // XGate = 2 - ["qiskit.circuit.library.standard_gates.x", "XGate"], - // CZGate = 3 - ["qiskit.circuit.library.standard_gates.z", "CZGate"], - // CYGate = 4 - ["qiskit.circuit.library.standard_gates.y", "CYGate"], - // CXGate = 5 - ["qiskit.circuit.library.standard_gates.x", "CXGate"], - // CCXGate = 6 - ["qiskit.circuit.library.standard_gates.x", "CCXGate"], - // RXGate = 7 - ["qiskit.circuit.library.standard_gates.rx", "RXGate"], - // RYGate = 8 - ["qiskit.circuit.library.standard_gates.ry", "RYGate"], - // RZGate = 9 - ["qiskit.circuit.library.standard_gates.rz", "RZGate"], - // ECRGate = 10 - ["qiskit.circuit.library.standard_gates.ecr", "ECRGate"], - // SwapGate = 11 - ["qiskit.circuit.library.standard_gates.swap", "SwapGate"], - // SXGate = 12 - ["qiskit.circuit.library.standard_gates.sx", "SXGate"], - // GlobalPhaseGate = 13 + // GlobalPhaseGate = 0 [ "qiskit.circuit.library.standard_gates.global_phase", "GlobalPhaseGate", ], - // IGate = 14 - ["qiskit.circuit.library.standard_gates.i", "IGate"], - // HGate = 15 + // HGate = 1 ["qiskit.circuit.library.standard_gates.h", "HGate"], - // PhaseGate = 16 + // IGate = 2 + ["qiskit.circuit.library.standard_gates.i", "IGate"], + // XGate = 3 + ["qiskit.circuit.library.standard_gates.x", "XGate"], + // YGate = 4 + ["qiskit.circuit.library.standard_gates.y", "YGate"], + // ZGate = 5 + ["qiskit.circuit.library.standard_gates.z", "ZGate"], + // PhaseGate = 6 ["qiskit.circuit.library.standard_gates.p", "PhaseGate"], - // UGate = 17 - ["qiskit.circuit.library.standard_gates.u", "UGate"], - // SGate = 18 + // RGate 7 + ["qiskit.circuit.library.standard_gates.r", "RGate"], + // RXGate = 8 + ["qiskit.circuit.library.standard_gates.rx", "RXGate"], + // RYGate = 9 + ["qiskit.circuit.library.standard_gates.ry", "RYGate"], + // RZGate = 10 + ["qiskit.circuit.library.standard_gates.rz", "RZGate"], + // SGate = 11 ["qiskit.circuit.library.standard_gates.s", "SGate"], - // SdgGate = 19 + // SdgGate = 12 ["qiskit.circuit.library.standard_gates.s", "SdgGate"], - // TGate = 20 + // SXGate = 13 + ["qiskit.circuit.library.standard_gates.sx", "SXGate"], + // SXdgGate = 14 + ["qiskit.circuit.library.standard_gates.sx", "SXdgGate"], + // TGate = 15 ["qiskit.circuit.library.standard_gates.t", "TGate"], - // TdgGate = 21 + // TdgGate = 16 ["qiskit.circuit.library.standard_gates.t", "TdgGate"], - // SXdgGate = 22 - ["qiskit.circuit.library.standard_gates.sx", "SXdgGate"], - // iSWAPGate = 23 - ["qiskit.circuit.library.standard_gates.iswap", "iSwapGate"], - // XXMinusYYGate = 24 - [ - "qiskit.circuit.library.standard_gates.xx_minus_yy", - "XXMinusYYGate", - ], - // XXPlusYYGate = 25 - [ - "qiskit.circuit.library.standard_gates.xx_plus_yy", - "XXPlusYYGate", - ], - // U1Gate = 26 + // UGate = 17 + ["qiskit.circuit.library.standard_gates.u", "UGate"], + // U1Gate = 18 ["qiskit.circuit.library.standard_gates.u1", "U1Gate"], - // U2Gate = 27 + // U2Gate = 19 ["qiskit.circuit.library.standard_gates.u2", "U2Gate"], - // U3Gate = 28 + // U3Gate = 20 ["qiskit.circuit.library.standard_gates.u3", "U3Gate"], - // CRXGate = 29 + // CHGate = 21 + ["qiskit.circuit.library.standard_gates.h", "CHGate"], + // CXGate = 22 + ["qiskit.circuit.library.standard_gates.x", "CXGate"], + // CYGate = 23 + ["qiskit.circuit.library.standard_gates.y", "CYGate"], + // CZGate = 24 + ["qiskit.circuit.library.standard_gates.z", "CZGate"], + // DCXGate = 25 + ["qiskit.circuit.library.standard_gates.dcx", "DCXGate"], + // ECRGate = 26 + ["qiskit.circuit.library.standard_gates.ecr", "ECRGate"], + // SwapGate = 27 + ["qiskit.circuit.library.standard_gates.swap", "SwapGate"], + // iSWAPGate = 28 + ["qiskit.circuit.library.standard_gates.iswap", "iSwapGate"], + // CPhaseGate = 29 + ["qiskit.circuit.library.standard_gates.p", "CPhaseGate"], + // CRXGate = 30 ["qiskit.circuit.library.standard_gates.rx", "CRXGate"], - // CRYGate = 30 + // CRYGate = 31 ["qiskit.circuit.library.standard_gates.ry", "CRYGate"], - // CRZGate = 31 + // CRZGate = 32 ["qiskit.circuit.library.standard_gates.rz", "CRZGate"], - // RGate 32 - ["qiskit.circuit.library.standard_gates.r", "RGate"], - // CHGate = 33 - ["qiskit.circuit.library.standard_gates.h", "CHGate"], - // CPhaseGate = 34 - ["qiskit.circuit.library.standard_gates.p", "CPhaseGate"], - // CSGate = 35 + // CSGate = 33 ["qiskit.circuit.library.standard_gates.s", "CSGate"], - // CSdgGate = 36 + // CSdgGate = 34 ["qiskit.circuit.library.standard_gates.s", "CSdgGate"], - // CSXGate = 37 + // CSXGate = 35 ["qiskit.circuit.library.standard_gates.sx", "CSXGate"], - // CSwapGate = 38 - ["qiskit.circuit.library.standard_gates.swap", "CSwapGate"], - // CUGate = 39 + // CUGate = 36 ["qiskit.circuit.library.standard_gates.u", "CUGate"], - // CU1Gate = 40 + // CU1Gate = 37 ["qiskit.circuit.library.standard_gates.u1", "CU1Gate"], - // CU3Gate = 41 + // CU3Gate = 38 ["qiskit.circuit.library.standard_gates.u3", "CU3Gate"], - // C3XGate = 42 - ["qiskit.circuit.library.standard_gates.x", "C3XGate"], - // C3SXGate = 43 - ["qiskit.circuit.library.standard_gates.x", "C3SXGate"], - // C4XGate = 44 - ["qiskit.circuit.library.standard_gates.x", "C4XGate"], - // DCXGate = 45 - ["qiskit.circuit.library.standard_gates.dcx", "DCXGate"], - // CCZGate = 46 - ["qiskit.circuit.library.standard_gates.z", "CCZGate"], - // RCCXGate = 47 - ["qiskit.circuit.library.standard_gates.x", "RCCXGate"], - // RC3XGate = 48 - ["qiskit.circuit.library.standard_gates.x", "RC3XGate"], - // RXXGate = 49 + // RXXGate = 39 ["qiskit.circuit.library.standard_gates.rxx", "RXXGate"], - // RYYGate = 50 + // RYYGate = 40 ["qiskit.circuit.library.standard_gates.ryy", "RYYGate"], - // RZZGate = 51 + // RZZGate = 41 ["qiskit.circuit.library.standard_gates.rzz", "RZZGate"], - // RZXGate = 52 + // RZXGate = 42 ["qiskit.circuit.library.standard_gates.rzx", "RZXGate"], + // XXMinusYYGate = 43 + [ + "qiskit.circuit.library.standard_gates.xx_minus_yy", + "XXMinusYYGate", + ], + // XXPlusYYGate = 44 + [ + "qiskit.circuit.library.standard_gates.xx_plus_yy", + "XXPlusYYGate", + ], + // CCXGate = 45 + ["qiskit.circuit.library.standard_gates.x", "CCXGate"], + // CCZGate = 46 + ["qiskit.circuit.library.standard_gates.z", "CCZGate"], + // CSwapGate = 47 + ["qiskit.circuit.library.standard_gates.swap", "CSwapGate"], + // RCCXGate = 48 + ["qiskit.circuit.library.standard_gates.x", "RCCXGate"], + // C3XGate = 49 + ["qiskit.circuit.library.standard_gates.x", "C3XGate"], + // C3SXGate = 50 + ["qiskit.circuit.library.standard_gates.x", "C3SXGate"], + // RC3XGate = 51 + ["qiskit.circuit.library.standard_gates.x", "RC3XGate"], ]; /// A mapping from the enum variant in crate::operations::StandardGate to the python object for the diff --git a/crates/circuit/src/operations.rs b/crates/circuit/src/operations.rs index fcbfddb72181..1eed72347da6 100644 --- a/crates/circuit/src/operations.rs +++ b/crates/circuit/src/operations.rs @@ -187,59 +187,58 @@ impl ToPyObject for Param { #[derive(Clone, Debug, Copy, Eq, PartialEq, Hash)] #[pyclass(module = "qiskit._accelerate.circuit")] pub enum StandardGate { - ZGate = 0, - YGate = 1, - XGate = 2, - CZGate = 3, - CYGate = 4, - CXGate = 5, - CCXGate = 6, - RXGate = 7, - RYGate = 8, - RZGate = 9, - ECRGate = 10, - SwapGate = 11, - SXGate = 12, - GlobalPhaseGate = 13, - IGate = 14, - HGate = 15, - PhaseGate = 16, + GlobalPhaseGate = 0, + HGate = 1, + IGate = 2, + XGate = 3, + YGate = 4, + ZGate = 5, + PhaseGate = 6, + RGate = 7, + RXGate = 8, + RYGate = 9, + RZGate = 10, + SGate = 11, + SdgGate = 12, + SXGate = 13, + SXdgGate = 14, + TGate = 15, + TdgGate = 16, UGate = 17, - SGate = 18, - SdgGate = 19, - TGate = 20, - TdgGate = 21, - SXdgGate = 22, - ISwapGate = 23, - XXMinusYYGate = 24, - XXPlusYYGate = 25, - U1Gate = 26, - U2Gate = 27, - U3Gate = 28, - CRXGate = 29, - CRYGate = 30, - CRZGate = 31, - RGate = 32, - CHGate = 33, - CPhaseGate = 34, - CSGate = 35, - CSdgGate = 36, - CSXGate = 37, - CSwapGate = 38, - CUGate = 39, - CU1Gate = 40, - CU3Gate = 41, - C3XGate = 42, - C3SXGate = 43, - C4XGate = 44, - DCXGate = 45, + U1Gate = 18, + U2Gate = 19, + U3Gate = 20, + CHGate = 21, + CXGate = 22, + CYGate = 23, + CZGate = 24, + DCXGate = 25, + ECRGate = 26, + SwapGate = 27, + ISwapGate = 28, + CPhaseGate = 29, + CRXGate = 30, + CRYGate = 31, + CRZGate = 32, + CSGate = 33, + CSdgGate = 34, + CSXGate = 35, + CUGate = 36, + CU1Gate = 37, + CU3Gate = 38, + RXXGate = 39, + RYYGate = 40, + RZZGate = 41, + RZXGate = 42, + XXMinusYYGate = 43, + XXPlusYYGate = 44, + CCXGate = 45, CCZGate = 46, - RCCXGate = 47, - RC3XGate = 48, - RXXGate = 49, - RYYGate = 50, - RZZGate = 51, - RZXGate = 52, + CSwapGate = 47, + RCCXGate = 48, + C3XGate = 49, + C3SXGate = 50, + RC3XGate = 51, } impl ToPyObject for StandardGate { @@ -249,77 +248,76 @@ impl ToPyObject for StandardGate { } static STANDARD_GATE_NUM_QUBITS: [u32; STANDARD_GATE_SIZE] = [ - 1, 1, 1, 2, 2, 2, 3, 1, 1, 1, // 0-9 - 2, 2, 1, 0, 1, 1, 1, 1, 1, 1, // 10-19 - 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, // 20-29 - 2, 2, 1, 2, 2, 2, 2, 2, 3, 2, // 30-39 - 2, 2, 4, 4, 5, 2, 3, 3, 4, 2, // 40-49 - 2, 2, 2, // 50-52 + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0-9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10-19 + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 20-29 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 30-39 + 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, // 40-49 + 4, 4, // 50-51 ]; static STANDARD_GATE_NUM_PARAMS: [u32; STANDARD_GATE_SIZE] = [ - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, // 0-9 - 0, 0, 0, 1, 0, 0, 1, 3, 0, 0, // 10-19 - 0, 0, 0, 0, 2, 2, 1, 2, 3, 1, // 20-29 - 1, 1, 2, 0, 1, 0, 0, 0, 0, 4, // 30-39 - 1, 3, 0, 0, 0, 0, 0, 0, 0, 1, // 40-49 - 1, 1, 1, // 50-52 + 1, 0, 0, 0, 0, 0, 1, 2, 1, 1, // 0-9 + 1, 0, 0, 0, 0, 0, 0, 3, 1, 2, // 10-19 + 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 20-29 + 1, 1, 1, 0, 0, 0, 4, 1, 3, 1, // 30-39 + 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, // 40-49 + 0, 0, // 50-51 ]; static STANDARD_GATE_NAME: [&str; STANDARD_GATE_SIZE] = [ - "z", // 0 - "y", // 1 - "x", // 2 - "cz", // 3 - "cy", // 4 - "cx", // 5 - "ccx", // 6 - "rx", // 7 - "ry", // 8 - "rz", // 9 - "ecr", // 10 - "swap", // 11 - "sx", // 12 - "global_phase", // 13 - "id", // 14 - "h", // 15 - "p", // 16 + "global_phase", // 0 + "h", // 1 + "id", // 2 + "x", // 3 + "y", // 4 + "z", // 5 + "p", // 6 + "r", // 7 + "rx", // 8 + "ry", // 9 + "rz", // 10 + "s", // 11 + "sdg", // 12 + "sx", // 13 + "sxdg", // 14 + "t", // 15 + "tdg", // 16 "u", // 17 - "s", // 18 - "sdg", // 19 - "t", // 20 - "tdg", // 21 - "sxdg", // 22 - "iswap", // 23 - "xx_minus_yy", // 24 - "xx_plus_yy", // 25 - "u1", // 26 - "u2", // 27 - "u3", // 28 - "crx", // 29 - "cry", // 30 - "crz", // 31 - "r", // 32 - "ch", // 33 - "cp", // 34 - "cs", // 35 - "csdg", // 36 - "csx", // 37 - "cswap", // 38 - "cu", // 39 - "cu1", // 40 - "cu3", // 41 - "mcx", // 42 ("c3x") - "c3sx", // 43 - "mcx", // 44 ("c4x") - "dcx", // 45 + "u1", // 18 + "u2", // 19 + "u3", // 20 + "ch", // 21 + "cx", // 22 + "cy", // 23 + "cz", // 24 + "dcx", // 25 + "ecr", // 26 + "swap", // 27 + "iswap", // 28 + "cp", // 29 + "crx", // 30 + "cry", // 31 + "crz", // 32 + "cs", // 33 + "csdg", // 34 + "csx", // 35 + "cu", // 36 + "cu1", // 37 + "cu3", // 38 + "rxx", // 39 + "ryy", // 40 + "rzz", // 41 + "rzx", // 42 + "xx_minus_yy", // 43 + "xx_plus_yy", // 44 + "ccx", // 45 "ccz", // 46 - "rccx", // 47 - "rcccx", // 48 ("rc3x") - "rxx", // 49 - "ryy", // 50 - "rzz", // 51 - "rzx", // 52 + "cswap", // 47 + "rccx", // 48 + "mcx", // 49 ("c3x") + "c3sx", // 50 + "rcccx", // 51 ("rc3x") ]; #[pymethods] @@ -368,7 +366,7 @@ impl StandardGate { // // Remove this when std::mem::variant_count() is stabilized (see // https://github.com/rust-lang/rust/issues/73662 ) -pub const STANDARD_GATE_SIZE: usize = 53; +pub const STANDARD_GATE_SIZE: usize = 52; impl Operation for StandardGate { fn name(&self) -> &str { @@ -397,32 +395,40 @@ impl Operation for StandardGate { fn matrix(&self, params: &[Param]) -> Option> { match self { - Self::ZGate => match params { - [] => Some(aview2(&gate_matrix::Z_GATE).to_owned()), + Self::GlobalPhaseGate => match params { + [Param::Float(theta)] => { + Some(aview2(&gate_matrix::global_phase_gate(*theta)).to_owned()) + } _ => None, }, - Self::YGate => match params { - [] => Some(aview2(&gate_matrix::Y_GATE).to_owned()), + Self::HGate => match params { + [] => Some(aview2(&gate_matrix::H_GATE).to_owned()), + _ => None, + }, + Self::IGate => match params { + [] => Some(aview2(&gate_matrix::ONE_QUBIT_IDENTITY).to_owned()), _ => None, }, Self::XGate => match params { [] => Some(aview2(&gate_matrix::X_GATE).to_owned()), _ => None, }, - Self::CZGate => match params { - [] => Some(aview2(&gate_matrix::CZ_GATE).to_owned()), + Self::YGate => match params { + [] => Some(aview2(&gate_matrix::Y_GATE).to_owned()), _ => None, }, - Self::CYGate => match params { - [] => Some(aview2(&gate_matrix::CY_GATE).to_owned()), + Self::ZGate => match params { + [] => Some(aview2(&gate_matrix::Z_GATE).to_owned()), _ => None, }, - Self::CXGate => match params { - [] => Some(aview2(&gate_matrix::CX_GATE).to_owned()), + Self::PhaseGate => match params { + [Param::Float(theta)] => Some(aview2(&gate_matrix::phase_gate(*theta)).to_owned()), _ => None, }, - Self::CCXGate => match params { - [] => Some(aview2(&gate_matrix::CCX_GATE).to_owned()), + Self::RGate => match params { + [Param::Float(theta), Param::Float(phi)] => { + Some(aview2(&gate_matrix::r_gate(*theta, *phi)).to_owned()) + } _ => None, }, Self::RXGate => match params { @@ -437,24 +443,12 @@ impl Operation for StandardGate { [Param::Float(theta)] => Some(aview2(&gate_matrix::rz_gate(*theta)).to_owned()), _ => None, }, - Self::CRXGate => match params { - [Param::Float(theta)] => Some(aview2(&gate_matrix::crx_gate(*theta)).to_owned()), - _ => None, - }, - Self::CRYGate => match params { - [Param::Float(theta)] => Some(aview2(&gate_matrix::cry_gate(*theta)).to_owned()), - _ => None, - }, - Self::CRZGate => match params { - [Param::Float(theta)] => Some(aview2(&gate_matrix::crz_gate(*theta)).to_owned()), - _ => None, - }, - Self::ECRGate => match params { - [] => Some(aview2(&gate_matrix::ECR_GATE).to_owned()), + Self::SGate => match params { + [] => Some(aview2(&gate_matrix::S_GATE).to_owned()), _ => None, }, - Self::SwapGate => match params { - [] => Some(aview2(&gate_matrix::SWAP_GATE).to_owned()), + Self::SdgGate => match params { + [] => Some(aview2(&gate_matrix::SDG_GATE).to_owned()), _ => None, }, Self::SXGate => match params { @@ -465,38 +459,6 @@ impl Operation for StandardGate { [] => Some(aview2(&gate_matrix::SXDG_GATE).to_owned()), _ => None, }, - Self::GlobalPhaseGate => match params { - [Param::Float(theta)] => { - Some(aview2(&gate_matrix::global_phase_gate(*theta)).to_owned()) - } - _ => None, - }, - Self::IGate => match params { - [] => Some(aview2(&gate_matrix::ONE_QUBIT_IDENTITY).to_owned()), - _ => None, - }, - Self::HGate => match params { - [] => Some(aview2(&gate_matrix::H_GATE).to_owned()), - _ => None, - }, - Self::PhaseGate => match params { - [Param::Float(theta)] => Some(aview2(&gate_matrix::phase_gate(*theta)).to_owned()), - _ => None, - }, - Self::UGate => match params { - [Param::Float(theta), Param::Float(phi), Param::Float(lam)] => { - Some(aview2(&gate_matrix::u_gate(*theta, *phi, *lam)).to_owned()) - } - _ => None, - }, - Self::SGate => match params { - [] => Some(aview2(&gate_matrix::S_GATE).to_owned()), - _ => None, - }, - Self::SdgGate => match params { - [] => Some(aview2(&gate_matrix::SDG_GATE).to_owned()), - _ => None, - }, Self::TGate => match params { [] => Some(aview2(&gate_matrix::T_GATE).to_owned()), _ => None, @@ -505,19 +467,9 @@ impl Operation for StandardGate { [] => Some(aview2(&gate_matrix::TDG_GATE).to_owned()), _ => None, }, - Self::ISwapGate => match params { - [] => Some(aview2(&gate_matrix::ISWAP_GATE).to_owned()), - _ => None, - }, - Self::XXMinusYYGate => match params { - [Param::Float(theta), Param::Float(beta)] => { - Some(aview2(&gate_matrix::xx_minus_yy_gate(*theta, *beta)).to_owned()) - } - _ => None, - }, - Self::XXPlusYYGate => match params { - [Param::Float(theta), Param::Float(beta)] => { - Some(aview2(&gate_matrix::xx_plus_yy_gate(*theta, *beta)).to_owned()) + Self::UGate => match params { + [Param::Float(theta), Param::Float(phi), Param::Float(lam)] => { + Some(aview2(&gate_matrix::u_gate(*theta, *phi, *lam)).to_owned()) } _ => None, }, @@ -537,42 +489,54 @@ impl Operation for StandardGate { } _ => None, }, - Self::CUGate => match params { - [Param::Float(theta), Param::Float(phi), Param::Float(lam), Param::Float(gamma)] => { - Some(aview2(&gate_matrix::cu_gate(*theta, *phi, *lam, *gamma)).to_owned()) - } + Self::CHGate => match params { + [] => Some(aview2(&gate_matrix::CH_GATE).to_owned()), _ => None, }, - Self::CU1Gate => match params[0] { - Param::Float(lam) => Some(aview2(&gate_matrix::cu1_gate(lam)).to_owned()), + Self::CXGate => match params { + [] => Some(aview2(&gate_matrix::CX_GATE).to_owned()), _ => None, }, - Self::CU3Gate => match params { - [Param::Float(theta), Param::Float(phi), Param::Float(lam)] => { - Some(aview2(&gate_matrix::cu3_gate(*theta, *phi, *lam)).to_owned()) - } + Self::CYGate => match params { + [] => Some(aview2(&gate_matrix::CY_GATE).to_owned()), _ => None, }, - Self::C3XGate => match params { - [] => Some(aview2(&gate_matrix::C3X_GATE).to_owned()), + Self::CZGate => match params { + [] => Some(aview2(&gate_matrix::CZ_GATE).to_owned()), _ => None, }, - Self::C3SXGate => match params { - [] => Some(aview2(&gate_matrix::C3SX_GATE).to_owned()), + Self::DCXGate => match params { + [] => Some(aview2(&gate_matrix::DCX_GATE).to_owned()), _ => None, }, - Self::CCZGate => match params { - [] => Some(aview2(&gate_matrix::CCZ_GATE).to_owned()), + Self::ECRGate => match params { + [] => Some(aview2(&gate_matrix::ECR_GATE).to_owned()), _ => None, }, - Self::CHGate => match params { - [] => Some(aview2(&gate_matrix::CH_GATE).to_owned()), + Self::SwapGate => match params { + [] => Some(aview2(&gate_matrix::SWAP_GATE).to_owned()), + _ => None, + }, + Self::ISwapGate => match params { + [] => Some(aview2(&gate_matrix::ISWAP_GATE).to_owned()), _ => None, }, Self::CPhaseGate => match params { [Param::Float(lam)] => Some(aview2(&gate_matrix::cp_gate(*lam)).to_owned()), _ => None, }, + Self::CRXGate => match params { + [Param::Float(theta)] => Some(aview2(&gate_matrix::crx_gate(*theta)).to_owned()), + _ => None, + }, + Self::CRYGate => match params { + [Param::Float(theta)] => Some(aview2(&gate_matrix::cry_gate(*theta)).to_owned()), + _ => None, + }, + Self::CRZGate => match params { + [Param::Float(theta)] => Some(aview2(&gate_matrix::crz_gate(*theta)).to_owned()), + _ => None, + }, Self::CSGate => match params { [] => Some(aview2(&gate_matrix::CS_GATE).to_owned()), _ => None, @@ -585,21 +549,22 @@ impl Operation for StandardGate { [] => Some(aview2(&gate_matrix::CSX_GATE).to_owned()), _ => None, }, - Self::CSwapGate => match params { - [] => Some(aview2(&gate_matrix::CSWAP_GATE).to_owned()), + Self::CUGate => match params { + [Param::Float(theta), Param::Float(phi), Param::Float(lam), Param::Float(gamma)] => { + Some(aview2(&gate_matrix::cu_gate(*theta, *phi, *lam, *gamma)).to_owned()) + } _ => None, }, - Self::RGate => match params { - [Param::Float(theta), Param::Float(phi)] => { - Some(aview2(&gate_matrix::r_gate(*theta, *phi)).to_owned()) - } + Self::CU1Gate => match params[0] { + Param::Float(lam) => Some(aview2(&gate_matrix::cu1_gate(lam)).to_owned()), _ => None, }, - Self::DCXGate => match params { - [] => Some(aview2(&gate_matrix::DCX_GATE).to_owned()), + Self::CU3Gate => match params { + [Param::Float(theta), Param::Float(phi), Param::Float(lam)] => { + Some(aview2(&gate_matrix::cu3_gate(*theta, *phi, *lam)).to_owned()) + } _ => None, }, - Self::C4XGate => todo!(), Self::RXXGate => match params[0] { Param::Float(theta) => Some(aview2(&gate_matrix::rxx_gate(theta)).to_owned()), _ => None, @@ -616,10 +581,42 @@ impl Operation for StandardGate { Param::Float(theta) => Some(aview2(&gate_matrix::rzx_gate(theta)).to_owned()), _ => None, }, + Self::XXMinusYYGate => match params { + [Param::Float(theta), Param::Float(beta)] => { + Some(aview2(&gate_matrix::xx_minus_yy_gate(*theta, *beta)).to_owned()) + } + _ => None, + }, + Self::XXPlusYYGate => match params { + [Param::Float(theta), Param::Float(beta)] => { + Some(aview2(&gate_matrix::xx_plus_yy_gate(*theta, *beta)).to_owned()) + } + _ => None, + }, + Self::CCXGate => match params { + [] => Some(aview2(&gate_matrix::CCX_GATE).to_owned()), + _ => None, + }, + Self::CCZGate => match params { + [] => Some(aview2(&gate_matrix::CCZ_GATE).to_owned()), + _ => None, + }, + Self::CSwapGate => match params { + [] => Some(aview2(&gate_matrix::CSWAP_GATE).to_owned()), + _ => None, + }, Self::RCCXGate => match params { [] => Some(aview2(&gate_matrix::RCCX_GATE).to_owned()), _ => None, }, + Self::C3XGate => match params { + [] => Some(aview2(&gate_matrix::C3X_GATE).to_owned()), + _ => None, + }, + Self::C3SXGate => match params { + [] => Some(aview2(&gate_matrix::C3SX_GATE).to_owned()), + _ => None, + }, Self::RC3XGate => match params { [] => Some(aview2(&gate_matrix::RC3X_GATE).to_owned()), _ => None, @@ -629,14 +626,20 @@ impl Operation for StandardGate { fn definition(&self, params: &[Param]) -> Option { match self { - Self::ZGate => Python::with_gil(|py| -> Option { + Self::GlobalPhaseGate => Python::with_gil(|py| -> Option { + Some( + CircuitData::from_standard_gates(py, 0, [], params[0].clone()) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::HGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, 1, [( - Self::PhaseGate, - smallvec![Param::Float(PI)], + Self::UGate, + smallvec![Param::Float(PI / 2.), FLOAT_ZERO, Param::Float(PI)], smallvec![Qubit(0)], )], FLOAT_ZERO, @@ -644,18 +647,15 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::YGate => Python::with_gil(|py| -> Option { + Self::IGate => None, + Self::XGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, 1, [( Self::UGate, - smallvec![ - Param::Float(PI), - Param::Float(PI / 2.), - Param::Float(PI / 2.), - ], + smallvec![Param::Float(PI), FLOAT_ZERO, Param::Float(PI)], smallvec![Qubit(0)], )], FLOAT_ZERO, @@ -663,14 +663,18 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::XGate => Python::with_gil(|py| -> Option { + Self::YGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, 1, [( Self::UGate, - smallvec![Param::Float(PI), Param::Float(0.), Param::Float(PI)], + smallvec![ + Param::Float(PI), + Param::Float(PI / 2.), + Param::Float(PI / 2.), + ], smallvec![Qubit(0)], )], FLOAT_ZERO, @@ -678,69 +682,47 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::CZGate => Python::with_gil(|py| -> Option { - let q1 = smallvec![Qubit(1)]; - let q0_1 = smallvec![Qubit(0), Qubit(1)]; + + Self::ZGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, - 2, - [ - (Self::HGate, smallvec![], q1.clone()), - (Self::CXGate, smallvec![], q0_1), - (Self::HGate, smallvec![], q1), - ], + 1, + [( + Self::PhaseGate, + smallvec![Param::Float(PI)], + smallvec![Qubit(0)], + )], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), ) }), - Self::CYGate => Python::with_gil(|py| -> Option { - let q1 = smallvec![Qubit(1)]; - let q0_1 = smallvec![Qubit(0), Qubit(1)]; + Self::PhaseGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, - 2, - [ - (Self::SdgGate, smallvec![], q1.clone()), - (Self::CXGate, smallvec![], q0_1), - (Self::SGate, smallvec![], q1), - ], + 1, + [( + Self::UGate, + smallvec![FLOAT_ZERO, FLOAT_ZERO, params[0].clone()], + smallvec![Qubit(0)], + )], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), ) }), - Self::CXGate => None, - Self::CCXGate => Python::with_gil(|py| -> Option { - let q0 = smallvec![Qubit(0)]; - let q1 = smallvec![Qubit(1)]; - let q2 = smallvec![Qubit(2)]; - let q0_1 = smallvec![Qubit(0), Qubit(1)]; - let q0_2 = smallvec![Qubit(0), Qubit(2)]; - let q1_2 = smallvec![Qubit(1), Qubit(2)]; + Self::RGate => Python::with_gil(|py| -> Option { + let theta_expr = clone_param(¶ms[0], py); + let phi_expr1 = add_param(¶ms[1], -PI / 2., py); + let phi_expr2 = multiply_param(&phi_expr1, -1.0, py); + let defparams = smallvec![theta_expr, phi_expr1, phi_expr2]; Some( CircuitData::from_standard_gates( py, - 3, - [ - (Self::HGate, smallvec![], q2.clone()), - (Self::CXGate, smallvec![], q1_2.clone()), - (Self::TdgGate, smallvec![], q2.clone()), - (Self::CXGate, smallvec![], q0_2.clone()), - (Self::TGate, smallvec![], q2.clone()), - (Self::CXGate, smallvec![], q1_2), - (Self::TdgGate, smallvec![], q2.clone()), - (Self::CXGate, smallvec![], q0_2), - (Self::TGate, smallvec![], q1.clone()), - (Self::TGate, smallvec![], q2.clone()), - (Self::HGate, smallvec![], q2), - (Self::CXGate, smallvec![], q0_1.clone()), - (Self::TGate, smallvec![], q0), - (Self::TdgGate, smallvec![], q1), - (Self::CXGate, smallvec![], q0_1), - ], + 1, + [(Self::UGate, defparams, smallvec![Qubit(0)])], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), @@ -770,7 +752,7 @@ impl Operation for StandardGate { 1, [( Self::RGate, - smallvec![theta.clone(), Param::Float(PI / 2.0)], + smallvec![theta.clone(), Param::Float(PI / 2.)], smallvec![Qubit(0)], )], FLOAT_ZERO, @@ -794,105 +776,31 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::CRXGate => Python::with_gil(|py| -> Option { - let theta = ¶ms[0]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - ( - Self::PhaseGate, - smallvec![Param::Float(PI / 2.)], - smallvec![Qubit(1)], - ), - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - ( - Self::UGate, - smallvec![ - multiply_param(theta, -0.5, py), - Param::Float(0.0), - Param::Float(0.0) - ], - smallvec![Qubit(1)], - ), - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - ( - Self::UGate, - smallvec![ - multiply_param(theta, 0.5, py), - Param::Float(-PI / 2.), - Param::Float(0.0) - ], - smallvec![Qubit(1)], - ), - ], - Param::Float(0.0), - ) - .expect("Unexpected Qiskit Python bug!"), - ) - }), - Self::CRYGate => Python::with_gil(|py| -> Option { - let theta = ¶ms[0]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - ( - Self::RYGate, - smallvec![multiply_param(theta, 0.5, py)], - smallvec![Qubit(1)], - ), - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - ( - Self::RYGate, - smallvec![multiply_param(theta, -0.5, py)], - smallvec![Qubit(1)], - ), - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - ], - Param::Float(0.0), - ) - .expect("Unexpected Qiskit Python bug!"), - ) - }), - Self::CRZGate => Python::with_gil(|py| -> Option { - let theta = ¶ms[0]; + Self::SGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, - 2, - [ - ( - Self::RZGate, - smallvec![multiply_param(theta, 0.5, py)], - smallvec![Qubit(1)], - ), - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - ( - Self::RZGate, - smallvec![multiply_param(theta, -0.5, py)], - smallvec![Qubit(1)], - ), - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - ], - Param::Float(0.0), + 1, + [( + Self::PhaseGate, + smallvec![Param::Float(PI / 2.)], + smallvec![Qubit(0)], + )], + FLOAT_ZERO, ) - .expect("Unexpected Qiskit Python bug!"), + .expect("Unexpected Qiskit python bug"), ) }), - Self::ECRGate => todo!("Add when we have RZX"), - Self::SwapGate => Python::with_gil(|py| -> Option { + Self::SdgGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, - 2, - [ - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - (Self::CXGate, smallvec![], smallvec![Qubit(1), Qubit(0)]), - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - ], + 1, + [( + Self::PhaseGate, + smallvec![Param::Float(-PI / 2.)], + smallvec![Qubit(0)], + )], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), @@ -928,21 +836,14 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::GlobalPhaseGate => Python::with_gil(|py| -> Option { - Some( - CircuitData::from_standard_gates(py, 0, [], params[0].clone()) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::IGate => None, - Self::HGate => Python::with_gil(|py| -> Option { + Self::TGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, 1, [( - Self::UGate, - smallvec![Param::Float(PI / 2.), Param::Float(0.), Param::Float(PI)], + Self::PhaseGate, + smallvec![Param::Float(PI / 4.)], smallvec![Qubit(0)], )], FLOAT_ZERO, @@ -950,14 +851,14 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::PhaseGate => Python::with_gil(|py| -> Option { + Self::TdgGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, 1, [( - Self::UGate, - smallvec![Param::Float(0.), Param::Float(0.), params[0].clone()], + Self::PhaseGate, + smallvec![Param::Float(-PI / 4.)], smallvec![Qubit(0)], )], FLOAT_ZERO, @@ -1011,61 +912,110 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::SGate => Python::with_gil(|py| -> Option { + Self::CHGate => Python::with_gil(|py| -> Option { + let q1 = smallvec![Qubit(1)]; + let q0_1 = smallvec![Qubit(0), Qubit(1)]; Some( CircuitData::from_standard_gates( py, - 1, - [( - Self::PhaseGate, - smallvec![Param::Float(PI / 2.)], - smallvec![Qubit(0)], - )], + 2, + [ + (Self::SGate, smallvec![], q1.clone()), + (Self::HGate, smallvec![], q1.clone()), + (Self::TGate, smallvec![], q1.clone()), + (Self::CXGate, smallvec![], q0_1), + (Self::TdgGate, smallvec![], q1.clone()), + (Self::HGate, smallvec![], q1.clone()), + (Self::SdgGate, smallvec![], q1), + ], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), ) }), - Self::SdgGate => Python::with_gil(|py| -> Option { + + Self::CXGate => None, + Self::CYGate => Python::with_gil(|py| -> Option { + let q1 = smallvec![Qubit(1)]; + let q0_1 = smallvec![Qubit(0), Qubit(1)]; Some( CircuitData::from_standard_gates( py, - 1, - [( - Self::PhaseGate, - smallvec![Param::Float(-PI / 2.)], - smallvec![Qubit(0)], - )], + 2, + [ + (Self::SdgGate, smallvec![], q1.clone()), + (Self::CXGate, smallvec![], q0_1), + (Self::SGate, smallvec![], q1), + ], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), ) }), - Self::TGate => Python::with_gil(|py| -> Option { + Self::CZGate => Python::with_gil(|py| -> Option { + let q1 = smallvec![Qubit(1)]; + let q0_1 = smallvec![Qubit(0), Qubit(1)]; Some( CircuitData::from_standard_gates( py, - 1, - [( - Self::PhaseGate, - smallvec![Param::Float(PI / 4.)], - smallvec![Qubit(0)], - )], + 2, + [ + (Self::HGate, smallvec![], q1.clone()), + (Self::CXGate, smallvec![], q0_1), + (Self::HGate, smallvec![], q1), + ], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), ) }), - Self::TdgGate => Python::with_gil(|py| -> Option { + Self::DCXGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( py, - 1, - [( - Self::PhaseGate, - smallvec![Param::Float(-PI / 4.)], - smallvec![Qubit(0)], - )], + 2, + [ + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), + (Self::CXGate, smallvec![], smallvec![Qubit(1), Qubit(0)]), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::ECRGate => Python::with_gil(|py| -> Option { + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + ( + Self::RZXGate, + smallvec![Param::Float(PI / 4.)], + smallvec![Qubit(0), Qubit(1)], + ), + (Self::XGate, smallvec![], smallvec![Qubit(0)]), + ( + Self::RZXGate, + smallvec![Param::Float(-PI / 4.)], + smallvec![Qubit(0), Qubit(1)], + ), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::SwapGate => Python::with_gil(|py| -> Option { + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), + (Self::CXGate, smallvec![], smallvec![Qubit(1), Qubit(0)]), + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), + ], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), @@ -1089,82 +1039,185 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::XXMinusYYGate => Python::with_gil(|py| -> Option { + Self::CPhaseGate => Python::with_gil(|py| -> Option { let q0 = smallvec![Qubit(0)]; let q1 = smallvec![Qubit(1)]; let q0_1 = smallvec![Qubit(0), Qubit(1)]; - let theta = ¶ms[0]; - let beta = ¶ms[1]; Some( CircuitData::from_standard_gates( py, 2, [ ( - Self::RZGate, - smallvec![multiply_param(beta, -1.0, py)], - q1.clone(), + Self::PhaseGate, + smallvec![multiply_param(¶ms[0], 0.5, py)], + q0, ), - (Self::RZGate, smallvec![Param::Float(-PI / 2.)], q0.clone()), - (Self::SXGate, smallvec![], q0.clone()), - (Self::RZGate, smallvec![Param::Float(PI / 2.)], q0.clone()), - (Self::SGate, smallvec![], q1.clone()), (Self::CXGate, smallvec![], q0_1.clone()), + ( + Self::PhaseGate, + smallvec![multiply_param(¶ms[0], -0.5, py)], + q1.clone(), + ), + (Self::CXGate, smallvec![], q0_1), + ( + Self::PhaseGate, + smallvec![multiply_param(¶ms[0], 0.5, py)], + q1, + ), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::CRXGate => Python::with_gil(|py| -> Option { + let theta = ¶ms[0]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + ( + Self::PhaseGate, + smallvec![Param::Float(PI / 2.)], + smallvec![Qubit(1)], + ), + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), + ( + Self::UGate, + smallvec![ + multiply_param(theta, -0.5, py), + Param::Float(0.0), + Param::Float(0.0) + ], + smallvec![Qubit(1)], + ), + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), + ( + Self::UGate, + smallvec![ + multiply_param(theta, 0.5, py), + Param::Float(-PI / 2.), + Param::Float(0.0) + ], + smallvec![Qubit(1)], + ), + ], + Param::Float(0.0), + ) + .expect("Unexpected Qiskit Python bug!"), + ) + }), + Self::CRYGate => Python::with_gil(|py| -> Option { + let theta = ¶ms[0]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ ( Self::RYGate, smallvec![multiply_param(theta, 0.5, py)], - q0.clone(), + smallvec![Qubit(1)], ), + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), ( Self::RYGate, smallvec![multiply_param(theta, -0.5, py)], + smallvec![Qubit(1)], + ), + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), + ], + Param::Float(0.0), + ) + .expect("Unexpected Qiskit Python bug!"), + ) + }), + Self::CRZGate => Python::with_gil(|py| -> Option { + let theta = ¶ms[0]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + ( + Self::RZGate, + smallvec![multiply_param(theta, 0.5, py)], + smallvec![Qubit(1)], + ), + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), + ( + Self::RZGate, + smallvec![multiply_param(theta, -0.5, py)], + smallvec![Qubit(1)], + ), + (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), + ], + Param::Float(0.0), + ) + .expect("Unexpected Qiskit Python bug!"), + ) + }), + Self::CSGate => Python::with_gil(|py| -> Option { + let q0 = smallvec![Qubit(0)]; + let q1 = smallvec![Qubit(1)]; + let q0_1 = smallvec![Qubit(0), Qubit(1)]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + (Self::PhaseGate, smallvec![Param::Float(PI / 4.)], q0), + (Self::CXGate, smallvec![], q0_1.clone()), + ( + Self::PhaseGate, + smallvec![Param::Float(-PI / 4.)], q1.clone(), ), (Self::CXGate, smallvec![], q0_1), - (Self::SdgGate, smallvec![], q1.clone()), - (Self::RZGate, smallvec![Param::Float(-PI / 2.)], q0.clone()), - (Self::SXdgGate, smallvec![], q0.clone()), - (Self::RZGate, smallvec![Param::Float(PI / 2.)], q0), - (Self::RZGate, smallvec![beta.clone()], q1), + (Self::PhaseGate, smallvec![Param::Float(PI / 4.)], q1), ], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), ) }), - Self::XXPlusYYGate => Python::with_gil(|py| -> Option { + Self::CSdgGate => Python::with_gil(|py| -> Option { let q0 = smallvec![Qubit(0)]; let q1 = smallvec![Qubit(1)]; - let q1_0 = smallvec![Qubit(1), Qubit(0)]; - let theta = ¶ms[0]; - let beta = ¶ms[1]; + let q0_1 = smallvec![Qubit(0), Qubit(1)]; Some( CircuitData::from_standard_gates( py, 2, [ - (Self::RZGate, smallvec![beta.clone()], q0.clone()), - (Self::RZGate, smallvec![Param::Float(-PI / 2.)], q1.clone()), - (Self::SXGate, smallvec![], q1.clone()), - (Self::RZGate, smallvec![Param::Float(PI / 2.)], q1.clone()), - (Self::SGate, smallvec![], q0.clone()), - (Self::CXGate, smallvec![], q1_0.clone()), + (Self::PhaseGate, smallvec![Param::Float(-PI / 4.)], q0), + (Self::CXGate, smallvec![], q0_1.clone()), ( - Self::RYGate, - smallvec![multiply_param(theta, -0.5, py)], + Self::PhaseGate, + smallvec![Param::Float(PI / 4.)], q1.clone(), ), - ( - Self::RYGate, - smallvec![multiply_param(theta, -0.5, py)], - q0.clone(), - ), - (Self::CXGate, smallvec![], q1_0), - (Self::SdgGate, smallvec![], q0.clone()), - (Self::RZGate, smallvec![Param::Float(-PI / 2.)], q1.clone()), - (Self::SXdgGate, smallvec![], q1.clone()), - (Self::RZGate, smallvec![Param::Float(PI / 2.)], q1), - (Self::RZGate, smallvec![multiply_param(beta, -1.0, py)], q0), + (Self::CXGate, smallvec![], q0_1), + (Self::PhaseGate, smallvec![Param::Float(-PI / 4.)], q1), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::CSXGate => Python::with_gil(|py| -> Option { + let q1 = smallvec![Qubit(1)]; + let q0_1 = smallvec![Qubit(0), Qubit(1)]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + (Self::HGate, smallvec![], q1.clone()), + (Self::CPhaseGate, smallvec![Param::Float(PI / 2.)], q0_1), + (Self::HGate, smallvec![], q1), ], FLOAT_ZERO, ) @@ -1212,7 +1265,7 @@ impl Operation for StandardGate { Self::UGate, smallvec![ multiply_param(¶ms[0], -0.5, py), - Param::Float(0.), + FLOAT_ZERO, param_first_u ], smallvec![Qubit(1)], @@ -1223,7 +1276,7 @@ impl Operation for StandardGate { smallvec![ multiply_param(¶ms[0], 0.5, py), params[1].clone(), - Param::Float(0.) + FLOAT_ZERO ], smallvec![Qubit(1)], ), @@ -1233,27 +1286,6 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::CHGate => Python::with_gil(|py| -> Option { - let q1 = smallvec![Qubit(1)]; - let q0_1 = smallvec![Qubit(0), Qubit(1)]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - (Self::SGate, smallvec![], q1.clone()), - (Self::HGate, smallvec![], q1.clone()), - (Self::TGate, smallvec![], q1.clone()), - (Self::CXGate, smallvec![], q0_1), - (Self::TdgGate, smallvec![], q1.clone()), - (Self::HGate, smallvec![], q1.clone()), - (Self::SdgGate, smallvec![], q1), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), Self::CU1Gate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( @@ -1283,38 +1315,6 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::CPhaseGate => Python::with_gil(|py| -> Option { - let q0 = smallvec![Qubit(0)]; - let q1 = smallvec![Qubit(1)]; - let q0_1 = smallvec![Qubit(0), Qubit(1)]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - ( - Self::PhaseGate, - smallvec![multiply_param(¶ms[0], 0.5, py)], - q0, - ), - (Self::CXGate, smallvec![], q0_1.clone()), - ( - Self::PhaseGate, - smallvec![multiply_param(¶ms[0], -0.5, py)], - q1.clone(), - ), - (Self::CXGate, smallvec![], q0_1), - ( - Self::PhaseGate, - smallvec![multiply_param(¶ms[0], 0.5, py)], - q1, - ), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), Self::CU3Gate => Python::with_gil(|py| -> Option { let param_first_u1 = radd_param( multiply_param(¶ms[2], 0.5, py), @@ -1347,7 +1347,7 @@ impl Operation for StandardGate { Self::U3Gate, smallvec![ multiply_param(¶ms[0], -0.5, py), - Param::Float(0.), + FLOAT_ZERO, param_first_u3 ], smallvec![Qubit(1)], @@ -1358,7 +1358,7 @@ impl Operation for StandardGate { smallvec![ multiply_param(¶ms[0], 0.5, py), params[1].clone(), - Param::Float(0.) + FLOAT_ZERO ], smallvec![Qubit(1)], ), @@ -1368,33 +1368,276 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::CSGate => Python::with_gil(|py| -> Option { + Self::RXXGate => Python::with_gil(|py| -> Option { let q0 = smallvec![Qubit(0)]; let q1 = smallvec![Qubit(1)]; - let q0_1 = smallvec![Qubit(0), Qubit(1)]; + let q0_q1 = smallvec![Qubit(0), Qubit(1)]; + let theta = ¶ms[0]; Some( CircuitData::from_standard_gates( py, 2, [ - (Self::PhaseGate, smallvec![Param::Float(PI / 4.)], q0), - (Self::CXGate, smallvec![], q0_1.clone()), - ( - Self::PhaseGate, - smallvec![Param::Float(-PI / 4.)], - q1.clone(), - ), - (Self::CXGate, smallvec![], q0_1), - (Self::PhaseGate, smallvec![Param::Float(PI / 4.)], q1), + (Self::HGate, smallvec![], q0.clone()), + (Self::HGate, smallvec![], q1.clone()), + (Self::CXGate, smallvec![], q0_q1.clone()), + (Self::RZGate, smallvec![theta.clone()], q1.clone()), + (Self::CXGate, smallvec![], q0_q1), + (Self::HGate, smallvec![], q1), + (Self::HGate, smallvec![], q0), ], FLOAT_ZERO, ) .expect("Unexpected Qiskit python bug"), ) }), - Self::C3XGate => Python::with_gil(|py| -> Option { - Some( - CircuitData::from_standard_gates( + Self::RYYGate => Python::with_gil(|py| -> Option { + let q0 = smallvec![Qubit(0)]; + let q1 = smallvec![Qubit(1)]; + let q0_q1 = smallvec![Qubit(0), Qubit(1)]; + let theta = ¶ms[0]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + (Self::RXGate, smallvec![Param::Float(PI / 2.)], q0.clone()), + (Self::RXGate, smallvec![Param::Float(PI / 2.)], q1.clone()), + (Self::CXGate, smallvec![], q0_q1.clone()), + (Self::RZGate, smallvec![theta.clone()], q1.clone()), + (Self::CXGate, smallvec![], q0_q1), + (Self::RXGate, smallvec![Param::Float(-PI / 2.)], q0), + (Self::RXGate, smallvec![Param::Float(-PI / 2.)], q1), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::RZZGate => Python::with_gil(|py| -> Option { + let q1 = smallvec![Qubit(1)]; + let q0_q1 = smallvec![Qubit(0), Qubit(1)]; + let theta = ¶ms[0]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + (Self::CXGate, smallvec![], q0_q1.clone()), + (Self::RZGate, smallvec![theta.clone()], q1), + (Self::CXGate, smallvec![], q0_q1), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::RZXGate => Python::with_gil(|py| -> Option { + let q1 = smallvec![Qubit(1)]; + let q0_q1 = smallvec![Qubit(0), Qubit(1)]; + let theta = ¶ms[0]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + (Self::HGate, smallvec![], q1.clone()), + (Self::CXGate, smallvec![], q0_q1.clone()), + (Self::RZGate, smallvec![theta.clone()], q1.clone()), + (Self::CXGate, smallvec![], q0_q1), + (Self::HGate, smallvec![], q1), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::XXMinusYYGate => Python::with_gil(|py| -> Option { + let q0 = smallvec![Qubit(0)]; + let q1 = smallvec![Qubit(1)]; + let q0_1 = smallvec![Qubit(0), Qubit(1)]; + let theta = ¶ms[0]; + let beta = ¶ms[1]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + ( + Self::RZGate, + smallvec![multiply_param(beta, -1.0, py)], + q1.clone(), + ), + (Self::RZGate, smallvec![Param::Float(-PI / 2.)], q0.clone()), + (Self::SXGate, smallvec![], q0.clone()), + (Self::RZGate, smallvec![Param::Float(PI / 2.)], q0.clone()), + (Self::SGate, smallvec![], q1.clone()), + (Self::CXGate, smallvec![], q0_1.clone()), + ( + Self::RYGate, + smallvec![multiply_param(theta, 0.5, py)], + q0.clone(), + ), + ( + Self::RYGate, + smallvec![multiply_param(theta, -0.5, py)], + q1.clone(), + ), + (Self::CXGate, smallvec![], q0_1), + (Self::SdgGate, smallvec![], q1.clone()), + (Self::RZGate, smallvec![Param::Float(-PI / 2.)], q0.clone()), + (Self::SXdgGate, smallvec![], q0.clone()), + (Self::RZGate, smallvec![Param::Float(PI / 2.)], q0), + (Self::RZGate, smallvec![beta.clone()], q1), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::XXPlusYYGate => Python::with_gil(|py| -> Option { + let q0 = smallvec![Qubit(0)]; + let q1 = smallvec![Qubit(1)]; + let q1_0 = smallvec![Qubit(1), Qubit(0)]; + let theta = ¶ms[0]; + let beta = ¶ms[1]; + Some( + CircuitData::from_standard_gates( + py, + 2, + [ + (Self::RZGate, smallvec![beta.clone()], q0.clone()), + (Self::RZGate, smallvec![Param::Float(-PI / 2.)], q1.clone()), + (Self::SXGate, smallvec![], q1.clone()), + (Self::RZGate, smallvec![Param::Float(PI / 2.)], q1.clone()), + (Self::SGate, smallvec![], q0.clone()), + (Self::CXGate, smallvec![], q1_0.clone()), + ( + Self::RYGate, + smallvec![multiply_param(theta, -0.5, py)], + q1.clone(), + ), + ( + Self::RYGate, + smallvec![multiply_param(theta, -0.5, py)], + q0.clone(), + ), + (Self::CXGate, smallvec![], q1_0), + (Self::SdgGate, smallvec![], q0.clone()), + (Self::RZGate, smallvec![Param::Float(-PI / 2.)], q1.clone()), + (Self::SXdgGate, smallvec![], q1.clone()), + (Self::RZGate, smallvec![Param::Float(PI / 2.)], q1), + (Self::RZGate, smallvec![multiply_param(beta, -1.0, py)], q0), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::CCXGate => Python::with_gil(|py| -> Option { + let q0 = smallvec![Qubit(0)]; + let q1 = smallvec![Qubit(1)]; + let q2 = smallvec![Qubit(2)]; + let q0_1 = smallvec![Qubit(0), Qubit(1)]; + let q0_2 = smallvec![Qubit(0), Qubit(2)]; + let q1_2 = smallvec![Qubit(1), Qubit(2)]; + Some( + CircuitData::from_standard_gates( + py, + 3, + [ + (Self::HGate, smallvec![], q2.clone()), + (Self::CXGate, smallvec![], q1_2.clone()), + (Self::TdgGate, smallvec![], q2.clone()), + (Self::CXGate, smallvec![], q0_2.clone()), + (Self::TGate, smallvec![], q2.clone()), + (Self::CXGate, smallvec![], q1_2), + (Self::TdgGate, smallvec![], q2.clone()), + (Self::CXGate, smallvec![], q0_2), + (Self::TGate, smallvec![], q1.clone()), + (Self::TGate, smallvec![], q2.clone()), + (Self::HGate, smallvec![], q2), + (Self::CXGate, smallvec![], q0_1.clone()), + (Self::TGate, smallvec![], q0), + (Self::TdgGate, smallvec![], q1), + (Self::CXGate, smallvec![], q0_1), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + + Self::CCZGate => Python::with_gil(|py| -> Option { + Some( + CircuitData::from_standard_gates( + py, + 3, + [ + (Self::HGate, smallvec![], smallvec![Qubit(2)]), + ( + Self::CCXGate, + smallvec![], + smallvec![Qubit(0), Qubit(1), Qubit(2)], + ), + (Self::HGate, smallvec![], smallvec![Qubit(2)]), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::CSwapGate => Python::with_gil(|py| -> Option { + Some( + CircuitData::from_standard_gates( + py, + 3, + [ + (Self::CXGate, smallvec![], smallvec![Qubit(2), Qubit(1)]), + ( + Self::CCXGate, + smallvec![], + smallvec![Qubit(0), Qubit(1), Qubit(2)], + ), + (Self::CXGate, smallvec![], smallvec![Qubit(2), Qubit(1)]), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + + Self::RCCXGate => Python::with_gil(|py| -> Option { + let q2 = smallvec![Qubit(2)]; + let q0_2 = smallvec![Qubit(0), Qubit(2)]; + let q1_2 = smallvec![Qubit(1), Qubit(2)]; + Some( + CircuitData::from_standard_gates( + py, + 3, + [ + ( + Self::U2Gate, + smallvec![FLOAT_ZERO, Param::Float(PI)], + q2.clone(), + ), + (Self::U1Gate, smallvec![Param::Float(PI / 4.)], q2.clone()), + (Self::CXGate, smallvec![], q1_2.clone()), + (Self::U1Gate, smallvec![Param::Float(-PI / 4.)], q2.clone()), + (Self::CXGate, smallvec![], q0_2), + (Self::U1Gate, smallvec![Param::Float(PI / 4.)], q2.clone()), + (Self::CXGate, smallvec![], q1_2), + (Self::U1Gate, smallvec![Param::Float(-PI / 4.)], q2.clone()), + (Self::U2Gate, smallvec![FLOAT_ZERO, Param::Float(PI)], q2), + ], + FLOAT_ZERO, + ) + .expect("Unexpected Qiskit python bug"), + ) + }), + Self::C3XGate => Python::with_gil(|py| -> Option { + Some( + CircuitData::from_standard_gates( py, 4, [ @@ -1495,30 +1738,7 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::CSdgGate => Python::with_gil(|py| -> Option { - let q0 = smallvec![Qubit(0)]; - let q1 = smallvec![Qubit(1)]; - let q0_1 = smallvec![Qubit(0), Qubit(1)]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - (Self::PhaseGate, smallvec![Param::Float(-PI / 4.)], q0), - (Self::CXGate, smallvec![], q0_1.clone()), - ( - Self::PhaseGate, - smallvec![Param::Float(PI / 4.)], - q1.clone(), - ), - (Self::CXGate, smallvec![], q0_1), - (Self::PhaseGate, smallvec![Param::Float(-PI / 4.)], q1), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), + Self::C3SXGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( @@ -1586,207 +1806,6 @@ impl Operation for StandardGate { .expect("Unexpected Qiskit python bug"), ) }), - Self::CSXGate => Python::with_gil(|py| -> Option { - let q1 = smallvec![Qubit(1)]; - let q0_1 = smallvec![Qubit(0), Qubit(1)]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - (Self::HGate, smallvec![], q1.clone()), - (Self::CPhaseGate, smallvec![Param::Float(PI / 2.)], q0_1), - (Self::HGate, smallvec![], q1), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::CCZGate => Python::with_gil(|py| -> Option { - Some( - CircuitData::from_standard_gates( - py, - 3, - [ - (Self::HGate, smallvec![], smallvec![Qubit(2)]), - ( - Self::CCXGate, - smallvec![], - smallvec![Qubit(0), Qubit(1), Qubit(2)], - ), - (Self::HGate, smallvec![], smallvec![Qubit(2)]), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::CSwapGate => Python::with_gil(|py| -> Option { - Some( - CircuitData::from_standard_gates( - py, - 3, - [ - (Self::CXGate, smallvec![], smallvec![Qubit(2), Qubit(1)]), - ( - Self::CCXGate, - smallvec![], - smallvec![Qubit(0), Qubit(1), Qubit(2)], - ), - (Self::CXGate, smallvec![], smallvec![Qubit(2), Qubit(1)]), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::RGate => Python::with_gil(|py| -> Option { - let theta_expr = clone_param(¶ms[0], py); - let phi_expr1 = add_param(¶ms[1], -PI / 2., py); - let phi_expr2 = multiply_param(&phi_expr1, -1.0, py); - let defparams = smallvec![theta_expr, phi_expr1, phi_expr2]; - Some( - CircuitData::from_standard_gates( - py, - 1, - [(Self::UGate, defparams, smallvec![Qubit(0)])], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::C4XGate => todo!(), - Self::DCXGate => Python::with_gil(|py| -> Option { - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(1)]), - (Self::CXGate, smallvec![], smallvec![Qubit(1), Qubit(0)]), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::RXXGate => Python::with_gil(|py| -> Option { - let q0 = smallvec![Qubit(0)]; - let q1 = smallvec![Qubit(1)]; - let q0_q1 = smallvec![Qubit(0), Qubit(1)]; - let theta = ¶ms[0]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - (Self::HGate, smallvec![], q0.clone()), - (Self::HGate, smallvec![], q1.clone()), - (Self::CXGate, smallvec![], q0_q1.clone()), - (Self::RZGate, smallvec![theta.clone()], q1.clone()), - (Self::CXGate, smallvec![], q0_q1), - (Self::HGate, smallvec![], q1), - (Self::HGate, smallvec![], q0), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::RYYGate => Python::with_gil(|py| -> Option { - let q0 = smallvec![Qubit(0)]; - let q1 = smallvec![Qubit(1)]; - let q0_q1 = smallvec![Qubit(0), Qubit(1)]; - let theta = ¶ms[0]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - (Self::RXGate, smallvec![Param::Float(PI / 2.)], q0.clone()), - (Self::RXGate, smallvec![Param::Float(PI / 2.)], q1.clone()), - (Self::CXGate, smallvec![], q0_q1.clone()), - (Self::RZGate, smallvec![theta.clone()], q1.clone()), - (Self::CXGate, smallvec![], q0_q1), - (Self::RXGate, smallvec![Param::Float(-PI / 2.)], q0), - (Self::RXGate, smallvec![Param::Float(-PI / 2.)], q1), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::RZZGate => Python::with_gil(|py| -> Option { - let q1 = smallvec![Qubit(1)]; - let q0_q1 = smallvec![Qubit(0), Qubit(1)]; - let theta = ¶ms[0]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - (Self::CXGate, smallvec![], q0_q1.clone()), - (Self::RZGate, smallvec![theta.clone()], q1), - (Self::CXGate, smallvec![], q0_q1), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::RZXGate => Python::with_gil(|py| -> Option { - let q1 = smallvec![Qubit(1)]; - let q0_q1 = smallvec![Qubit(0), Qubit(1)]; - let theta = ¶ms[0]; - Some( - CircuitData::from_standard_gates( - py, - 2, - [ - (Self::HGate, smallvec![], q1.clone()), - (Self::CXGate, smallvec![], q0_q1.clone()), - (Self::RZGate, smallvec![theta.clone()], q1.clone()), - (Self::CXGate, smallvec![], q0_q1), - (Self::HGate, smallvec![], q1), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), - Self::RCCXGate => Python::with_gil(|py| -> Option { - let q2 = smallvec![Qubit(2)]; - let q0_2 = smallvec![Qubit(0), Qubit(2)]; - let q1_2 = smallvec![Qubit(1), Qubit(2)]; - Some( - CircuitData::from_standard_gates( - py, - 3, - [ - ( - Self::U2Gate, - smallvec![Param::Float(0.), Param::Float(PI)], - q2.clone(), - ), - (Self::U1Gate, smallvec![Param::Float(PI / 4.)], q2.clone()), - (Self::CXGate, smallvec![], q1_2.clone()), - (Self::U1Gate, smallvec![Param::Float(-PI / 4.)], q2.clone()), - (Self::CXGate, smallvec![], q0_2), - (Self::U1Gate, smallvec![Param::Float(PI / 4.)], q2.clone()), - (Self::CXGate, smallvec![], q1_2), - (Self::U1Gate, smallvec![Param::Float(-PI / 4.)], q2.clone()), - ( - Self::U2Gate, - smallvec![Param::Float(0.), Param::Float(PI)], - q2, - ), - ], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), - ) - }), Self::RC3XGate => Python::with_gil(|py| -> Option { Some( CircuitData::from_standard_gates( @@ -1795,7 +1814,7 @@ impl Operation for StandardGate { [ ( Self::U2Gate, - smallvec![Param::Float(0.), Param::Float(PI)], + smallvec![FLOAT_ZERO, Param::Float(PI)], smallvec![Qubit(3)], ), ( @@ -1811,7 +1830,7 @@ impl Operation for StandardGate { ), ( Self::U2Gate, - smallvec![Param::Float(0.), Param::Float(PI)], + smallvec![FLOAT_ZERO, Param::Float(PI)], smallvec![Qubit(3)], ), (Self::CXGate, smallvec![], smallvec![Qubit(0), Qubit(3)]), @@ -1840,7 +1859,7 @@ impl Operation for StandardGate { ), ( Self::U2Gate, - smallvec![Param::Float(0.), Param::Float(PI)], + smallvec![FLOAT_ZERO, Param::Float(PI)], smallvec![Qubit(3)], ), ( @@ -1856,7 +1875,7 @@ impl Operation for StandardGate { ), ( Self::U2Gate, - smallvec![Param::Float(0.), Param::Float(PI)], + smallvec![FLOAT_ZERO, Param::Float(PI)], smallvec![Qubit(3)], ), ], diff --git a/test/python/circuit/test_rust_equivalence.py b/test/python/circuit/test_rust_equivalence.py index 29cc0723bb60..c226ae004896 100644 --- a/test/python/circuit/test_rust_equivalence.py +++ b/test/python/circuit/test_rust_equivalence.py @@ -24,7 +24,6 @@ from qiskit.circuit.library.standard_gates import get_standard_gate_name_mapping from qiskit.quantum_info import Operator -SKIP_LIST = {"rx", "ry", "ecr"} CUSTOM_NAME_MAPPING = {"mcx": C3XGate()} @@ -62,9 +61,6 @@ def test_definitions(self): """Test definitions are the same in rust space.""" for name, gate_class in self.standard_gates.items(): standard_gate = getattr(gate_class, "_standard_gate", None) - if name in SKIP_LIST: - # gate does not have a rust definition yet - continue if standard_gate is None: # gate is not in rust yet continue @@ -157,9 +153,6 @@ def test_name(self): if standard_gate is None: # gate is not in rust yet continue - if gate_class.name == "mcx": - # ambiguous gate name - continue with self.subTest(name=name): self.assertEqual(gate_class.name, standard_gate.name)