mirror of https://github.com/Qiskit/qiskit.git
Add Rust representation for CHGate, CPhaseGate, CSGate, CSdgGate, CSXGate, CSwapGate (#12639)
* Add CHGate, CPhaseGate, CSGate, CSdgGate, CSXGate, CSwapGate * Fix tests, add labels * Fix oversights in gate definitions * Fix test * Add ctrl_state 1 to rust building path.
This commit is contained in:
parent
c452694d70
commit
a7fc2daf4c
|
@ -53,43 +53,6 @@ pub fn rz_gate(theta: f64) -> GateArray1Q {
|
|||
[[(-ilam2).exp(), C_ZERO], [C_ZERO, ilam2.exp()]]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn crx_gate(theta: f64) -> GateArray2Q {
|
||||
let half_theta = theta / 2.;
|
||||
let cos = c64(half_theta.cos(), 0.);
|
||||
let isin = c64(0., half_theta.sin());
|
||||
[
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, cos, C_ZERO, -isin],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, -isin, C_ZERO, cos],
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cry_gate(theta: f64) -> GateArray2Q {
|
||||
let half_theta = theta / 2.;
|
||||
let cos = c64(half_theta.cos(), 0.);
|
||||
let sin = c64(half_theta.sin(), 0.);
|
||||
[
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, cos, C_ZERO, -sin],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, sin, C_ZERO, cos],
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn crz_gate(theta: f64) -> GateArray2Q {
|
||||
let i_half_theta = c64(0., theta / 2.);
|
||||
[
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, (-i_half_theta).exp(), C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ZERO, i_half_theta.exp()],
|
||||
]
|
||||
}
|
||||
|
||||
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.)],
|
||||
|
@ -210,6 +173,71 @@ pub static TDG_GATE: GateArray1Q = [
|
|||
[C_ZERO, c64(FRAC_1_SQRT_2, -FRAC_1_SQRT_2)],
|
||||
];
|
||||
|
||||
pub static CH_GATE: GateArray2Q = [
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[
|
||||
C_ZERO,
|
||||
c64(FRAC_1_SQRT_2, 0.),
|
||||
C_ZERO,
|
||||
c64(FRAC_1_SQRT_2, 0.),
|
||||
],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[
|
||||
C_ZERO,
|
||||
c64(FRAC_1_SQRT_2, 0.),
|
||||
C_ZERO,
|
||||
c64(-FRAC_1_SQRT_2, 0.),
|
||||
],
|
||||
];
|
||||
|
||||
pub static CS_GATE: GateArray2Q = [
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ONE, C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ZERO, IM],
|
||||
];
|
||||
|
||||
pub static CSDG_GATE: GateArray2Q = [
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ONE, C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ZERO, M_IM],
|
||||
];
|
||||
|
||||
pub static CSX_GATE: GateArray2Q = [
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, c64(0.5, 0.5), C_ZERO, c64(0.5, -0.5)],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, c64(0.5, -0.5), C_ZERO, c64(0.5, 0.5)],
|
||||
];
|
||||
|
||||
pub static CSWAP_GATE: GateArray3Q = [
|
||||
[
|
||||
C_ONE, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO,
|
||||
],
|
||||
[
|
||||
C_ZERO, C_ONE, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO,
|
||||
],
|
||||
[
|
||||
C_ZERO, C_ZERO, C_ONE, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO,
|
||||
],
|
||||
[
|
||||
C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ONE, C_ZERO, C_ZERO,
|
||||
],
|
||||
[
|
||||
C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ONE, C_ZERO, C_ZERO, C_ZERO,
|
||||
],
|
||||
[
|
||||
C_ZERO, C_ZERO, C_ZERO, C_ONE, C_ZERO, C_ZERO, C_ZERO, C_ZERO,
|
||||
],
|
||||
[
|
||||
C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ONE, C_ZERO,
|
||||
],
|
||||
[
|
||||
C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ZERO, C_ONE,
|
||||
],
|
||||
];
|
||||
|
||||
pub static DCX_GATE: GateArray2Q = [
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ZERO, C_ONE],
|
||||
|
@ -217,6 +245,43 @@ pub static DCX_GATE: GateArray2Q = [
|
|||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
];
|
||||
|
||||
#[inline]
|
||||
pub fn crx_gate(theta: f64) -> GateArray2Q {
|
||||
let half_theta = theta / 2.;
|
||||
let cos = c64(half_theta.cos(), 0.);
|
||||
let isin = c64(0., half_theta.sin());
|
||||
[
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, cos, C_ZERO, -isin],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, -isin, C_ZERO, cos],
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cry_gate(theta: f64) -> GateArray2Q {
|
||||
let half_theta = theta / 2.;
|
||||
let cos = c64(half_theta.cos(), 0.);
|
||||
let sin = c64(half_theta.sin(), 0.);
|
||||
[
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, cos, C_ZERO, -sin],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, sin, C_ZERO, cos],
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn crz_gate(theta: f64) -> GateArray2Q {
|
||||
let i_half_theta = c64(0., theta / 2.);
|
||||
[
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, (-i_half_theta).exp(), C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ZERO, i_half_theta.exp()],
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn global_phase_gate(theta: f64) -> GateArray0Q {
|
||||
[[c64(0., theta).exp()]]
|
||||
|
@ -310,18 +375,27 @@ pub fn xx_plus_yy_gate(theta: f64, beta: f64) -> GateArray2Q {
|
|||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cp_gate(lam: f64) -> GateArray2Q {
|
||||
[
|
||||
[C_ONE, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ONE, C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ONE, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ZERO, c64(0., lam).exp()],
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn rxx_gate(theta: f64) -> GateArray2Q {
|
||||
let (sint, cost) = (theta / 2.0).sin_cos();
|
||||
let ccos = c64(cost, 0.);
|
||||
let csinm = c64(0., -sint);
|
||||
let c0 = c64(0., 0.);
|
||||
|
||||
[
|
||||
[ccos, c0, c0, csinm],
|
||||
[c0, ccos, csinm, c0],
|
||||
[c0, csinm, ccos, c0],
|
||||
[csinm, c0, c0, ccos],
|
||||
[ccos, C_ZERO, C_ZERO, csinm],
|
||||
[C_ZERO, ccos, csinm, C_ZERO],
|
||||
[C_ZERO, csinm, ccos, C_ZERO],
|
||||
[csinm, C_ZERO, C_ZERO, ccos],
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -330,28 +404,26 @@ pub fn ryy_gate(theta: f64) -> GateArray2Q {
|
|||
let (sint, cost) = (theta / 2.0).sin_cos();
|
||||
let ccos = c64(cost, 0.);
|
||||
let csin = c64(0., sint);
|
||||
let c0 = c64(0., 0.);
|
||||
|
||||
[
|
||||
[ccos, c0, c0, csin],
|
||||
[c0, ccos, -csin, c0],
|
||||
[c0, -csin, ccos, c0],
|
||||
[csin, c0, c0, ccos],
|
||||
[ccos, C_ZERO, C_ZERO, csin],
|
||||
[C_ZERO, ccos, -csin, C_ZERO],
|
||||
[C_ZERO, -csin, ccos, C_ZERO],
|
||||
[csin, C_ZERO, C_ZERO, ccos],
|
||||
]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn rzz_gate(theta: f64) -> GateArray2Q {
|
||||
let (sint, cost) = (theta / 2.0).sin_cos();
|
||||
let c0 = c64(0., 0.);
|
||||
let exp_it2 = c64(cost, sint);
|
||||
let exp_mit2 = c64(cost, -sint);
|
||||
|
||||
[
|
||||
[exp_mit2, c0, c0, c0],
|
||||
[c0, exp_it2, c0, c0],
|
||||
[c0, c0, exp_it2, c0],
|
||||
[c0, c0, c0, exp_mit2],
|
||||
[exp_mit2, C_ZERO, C_ZERO, C_ZERO],
|
||||
[C_ZERO, exp_it2, C_ZERO, C_ZERO],
|
||||
[C_ZERO, C_ZERO, exp_it2, C_ZERO],
|
||||
[C_ZERO, C_ZERO, C_ZERO, exp_mit2],
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -360,12 +432,11 @@ pub fn rzx_gate(theta: f64) -> GateArray2Q {
|
|||
let (sint, cost) = (theta / 2.0).sin_cos();
|
||||
let ccos = c64(cost, 0.);
|
||||
let csin = c64(0., sint);
|
||||
let c0 = c64(0., 0.);
|
||||
|
||||
[
|
||||
[ccos, c0, -csin, c0],
|
||||
[c0, ccos, c0, csin],
|
||||
[-csin, c0, ccos, c0],
|
||||
[c0, csin, c0, ccos],
|
||||
[ccos, C_ZERO, -csin, C_ZERO],
|
||||
[C_ZERO, ccos, C_ZERO, csin],
|
||||
[-csin, C_ZERO, ccos, C_ZERO],
|
||||
[C_ZERO, csin, C_ZERO, ccos],
|
||||
]
|
||||
}
|
||||
|
|
|
@ -522,20 +522,38 @@ impl Operation for StandardGate {
|
|||
}
|
||||
_ => None,
|
||||
},
|
||||
Self::CHGate => match params {
|
||||
[] => Some(aview2(&gate_matrix::CH_GATE).to_owned()),
|
||||
_ => None,
|
||||
},
|
||||
Self::CPhaseGate => match params {
|
||||
[Param::Float(lam)] => Some(aview2(&gate_matrix::cp_gate(*lam)).to_owned()),
|
||||
_ => None,
|
||||
},
|
||||
Self::CSGate => match params {
|
||||
[] => Some(aview2(&gate_matrix::CS_GATE).to_owned()),
|
||||
_ => None,
|
||||
},
|
||||
Self::CSdgGate => match params {
|
||||
[] => Some(aview2(&gate_matrix::CSDG_GATE).to_owned()),
|
||||
_ => None,
|
||||
},
|
||||
Self::CSXGate => match params {
|
||||
[] => Some(aview2(&gate_matrix::CSX_GATE).to_owned()),
|
||||
_ => None,
|
||||
},
|
||||
Self::CSwapGate => match params {
|
||||
[] => Some(aview2(&gate_matrix::CSWAP_GATE).to_owned()),
|
||||
_ => None,
|
||||
},
|
||||
Self::CUGate | Self::CU1Gate | Self::CU3Gate => todo!(),
|
||||
Self::C3XGate | Self::C3SXGate | Self::C4XGate => todo!(),
|
||||
Self::RGate => match params {
|
||||
[Param::Float(theta), Param::Float(phi)] => {
|
||||
Some(aview2(&gate_matrix::r_gate(*theta, *phi)).to_owned())
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
Self::CHGate => todo!(),
|
||||
Self::CPhaseGate => todo!(),
|
||||
Self::CSGate => todo!(),
|
||||
Self::CSdgGate => todo!(),
|
||||
Self::CSXGate => todo!(),
|
||||
Self::CSwapGate => todo!(),
|
||||
Self::CUGate | Self::CU1Gate | Self::CU3Gate => todo!(),
|
||||
Self::C3XGate | Self::C3SXGate | Self::C4XGate => todo!(),
|
||||
Self::DCXGate => match params {
|
||||
[] => Some(aview2(&gate_matrix::DCX_GATE).to_owned()),
|
||||
_ => None,
|
||||
|
@ -870,21 +888,6 @@ impl Operation for StandardGate {
|
|||
)
|
||||
}),
|
||||
Self::UGate => None,
|
||||
Self::SGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
py,
|
||||
1,
|
||||
[(
|
||||
Self::PhaseGate,
|
||||
smallvec![Param::Float(PI / 2.)],
|
||||
smallvec![Qubit(0)],
|
||||
)],
|
||||
FLOAT_ZERO,
|
||||
)
|
||||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::U1Gate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
|
@ -900,21 +903,6 @@ impl Operation for StandardGate {
|
|||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::SdgGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
py,
|
||||
1,
|
||||
[(
|
||||
Self::PhaseGate,
|
||||
smallvec![Param::Float(-PI / 2.)],
|
||||
smallvec![Qubit(0)],
|
||||
)],
|
||||
FLOAT_ZERO,
|
||||
)
|
||||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::U2Gate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
|
@ -930,21 +918,6 @@ impl Operation for StandardGate {
|
|||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::TGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
py,
|
||||
1,
|
||||
[(
|
||||
Self::PhaseGate,
|
||||
smallvec![Param::Float(PI / 4.)],
|
||||
smallvec![Qubit(0)],
|
||||
)],
|
||||
FLOAT_ZERO,
|
||||
)
|
||||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::U3Gate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
|
@ -960,6 +933,51 @@ impl Operation for StandardGate {
|
|||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::SGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
py,
|
||||
1,
|
||||
[(
|
||||
Self::PhaseGate,
|
||||
smallvec![Param::Float(PI / 2.)],
|
||||
smallvec![Qubit(0)],
|
||||
)],
|
||||
FLOAT_ZERO,
|
||||
)
|
||||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::SdgGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
py,
|
||||
1,
|
||||
[(
|
||||
Self::PhaseGate,
|
||||
smallvec![Param::Float(-PI / 2.)],
|
||||
smallvec![Qubit(0)],
|
||||
)],
|
||||
FLOAT_ZERO,
|
||||
)
|
||||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::TGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
py,
|
||||
1,
|
||||
[(
|
||||
Self::PhaseGate,
|
||||
smallvec![Param::Float(PI / 4.)],
|
||||
smallvec![Qubit(0)],
|
||||
)],
|
||||
FLOAT_ZERO,
|
||||
)
|
||||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::TdgGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
Some(
|
||||
CircuitData::from_standard_gates(
|
||||
|
@ -1075,6 +1093,143 @@ impl Operation for StandardGate {
|
|||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::CHGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
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::CPhaseGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
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::CSGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
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::CSdgGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
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::CSXGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
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::CSwapGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
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<CircuitData> {
|
||||
let theta_expr = clone_param(¶ms[0], py);
|
||||
let phi_expr1 = add_param(¶ms[1], -PI / 2., py);
|
||||
|
@ -1090,12 +1245,6 @@ impl Operation for StandardGate {
|
|||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
Self::CHGate => todo!(),
|
||||
Self::CPhaseGate => todo!(),
|
||||
Self::CSGate => todo!(),
|
||||
Self::CSdgGate => todo!(),
|
||||
Self::CSXGate => todo!(),
|
||||
Self::CSwapGate => todo!(),
|
||||
Self::CUGate => todo!(),
|
||||
Self::CU1Gate => todo!(),
|
||||
Self::CU3Gate => todo!(),
|
||||
|
@ -1114,7 +1263,6 @@ impl Operation for StandardGate {
|
|||
.expect("Unexpected Qiskit python bug"),
|
||||
)
|
||||
}),
|
||||
|
||||
Self::CCZGate => todo!(),
|
||||
Self::RCCXGate | Self::RC3XGate => todo!(),
|
||||
Self::RXXGate => Python::with_gil(|py| -> Option<CircuitData> {
|
||||
|
|
|
@ -185,6 +185,8 @@ class CHGate(SingletonControlledGate):
|
|||
\end{pmatrix}
|
||||
"""
|
||||
|
||||
_standard_gate = StandardGate.CHGate
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
label: Optional[str] = None,
|
||||
|
|
|
@ -200,6 +200,8 @@ class CPhaseGate(ControlledGate):
|
|||
phase difference.
|
||||
"""
|
||||
|
||||
_standard_gate = StandardGate.CPhaseGate
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
theta: ParameterValueType,
|
||||
|
|
|
@ -215,6 +215,8 @@ class CSGate(SingletonControlledGate):
|
|||
\end{pmatrix}
|
||||
"""
|
||||
|
||||
_standard_gate = StandardGate.CSGate
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
label: Optional[str] = None,
|
||||
|
@ -301,6 +303,8 @@ class CSdgGate(SingletonControlledGate):
|
|||
\end{pmatrix}
|
||||
"""
|
||||
|
||||
_standard_gate = StandardGate.CSdgGate
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
label: Optional[str] = None,
|
||||
|
|
|
@ -216,6 +216,8 @@ class CSwapGate(SingletonControlledGate):
|
|||
|1, b, c\rangle \rightarrow |1, c, b\rangle
|
||||
"""
|
||||
|
||||
_standard_gate = StandardGate.CSwapGate
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
label: Optional[str] = None,
|
||||
|
|
|
@ -266,6 +266,8 @@ class CSXGate(SingletonControlledGate):
|
|||
|
||||
"""
|
||||
|
||||
_standard_gate = StandardGate.CSXGate
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
label: Optional[str] = None,
|
||||
|
|
|
@ -4516,6 +4516,12 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CHGate, [], qargs=[control_qubit, target_qubit], label=label
|
||||
)
|
||||
|
||||
from .library.standard_gates.h import CHGate
|
||||
|
||||
return self.append(
|
||||
|
@ -4593,6 +4599,12 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CPhaseGate, [theta], qargs=[control_qubit, target_qubit], label=label
|
||||
)
|
||||
|
||||
from .library.standard_gates.p import CPhaseGate
|
||||
|
||||
return self.append(
|
||||
|
@ -4772,14 +4784,14 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
from .library.standard_gates.rx import CRXGate
|
||||
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CRXGate, [theta], [control_qubit, target_qubit], None, label=label
|
||||
)
|
||||
|
||||
from .library.standard_gates.rx import CRXGate
|
||||
|
||||
return self.append(
|
||||
CRXGate(theta, label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
|
@ -4845,14 +4857,14 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
from .library.standard_gates.ry import CRYGate
|
||||
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CRYGate, [theta], [control_qubit, target_qubit], None, label=label
|
||||
)
|
||||
|
||||
from .library.standard_gates.ry import CRYGate
|
||||
|
||||
return self.append(
|
||||
CRYGate(theta, label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
|
@ -4915,14 +4927,14 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
from .library.standard_gates.rz import CRZGate
|
||||
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CRZGate, [theta], [control_qubit, target_qubit], None, label=label
|
||||
)
|
||||
|
||||
from .library.standard_gates.rz import CRZGate
|
||||
|
||||
return self.append(
|
||||
CRZGate(theta, label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
|
@ -4975,9 +4987,7 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
return self._append_standard_gate(
|
||||
StandardGate.ECRGate, [], qargs=[qubit1, qubit2], cargs=None
|
||||
)
|
||||
return self._append_standard_gate(StandardGate.ECRGate, [], qargs=[qubit1, qubit2])
|
||||
|
||||
def s(self, qubit: QubitSpecifier) -> InstructionSet:
|
||||
"""Apply :class:`~qiskit.circuit.library.SGate`.
|
||||
|
@ -4990,7 +5000,7 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
return self._append_standard_gate(StandardGate.SGate, [], [qubit], cargs=None)
|
||||
return self._append_standard_gate(StandardGate.SGate, [], qargs=[qubit])
|
||||
|
||||
def sdg(self, qubit: QubitSpecifier) -> InstructionSet:
|
||||
"""Apply :class:`~qiskit.circuit.library.SdgGate`.
|
||||
|
@ -5003,7 +5013,7 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
return self._append_standard_gate(StandardGate.SdgGate, [], [qubit], cargs=None)
|
||||
return self._append_standard_gate(StandardGate.SdgGate, [], qargs=[qubit])
|
||||
|
||||
def cs(
|
||||
self,
|
||||
|
@ -5027,6 +5037,12 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CSGate, [], qargs=[control_qubit, target_qubit], label=label
|
||||
)
|
||||
|
||||
from .library.standard_gates.s import CSGate
|
||||
|
||||
return self.append(
|
||||
|
@ -5058,6 +5074,12 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CSdgGate, [], qargs=[control_qubit, target_qubit], label=label
|
||||
)
|
||||
|
||||
from .library.standard_gates.s import CSdgGate
|
||||
|
||||
return self.append(
|
||||
|
@ -5082,7 +5104,6 @@ class QuantumCircuit:
|
|||
StandardGate.SwapGate,
|
||||
[],
|
||||
qargs=[qubit1, qubit2],
|
||||
cargs=None,
|
||||
)
|
||||
|
||||
def iswap(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet:
|
||||
|
@ -5096,7 +5117,7 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
return self._append_standard_gate(StandardGate.ISwapGate, [], [qubit1, qubit2], cargs=None)
|
||||
return self._append_standard_gate(StandardGate.ISwapGate, [], qargs=[qubit1, qubit2])
|
||||
|
||||
def cswap(
|
||||
self,
|
||||
|
@ -5122,6 +5143,15 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CSwapGate,
|
||||
[],
|
||||
qargs=[control_qubit, target_qubit1, target_qubit2],
|
||||
label=label,
|
||||
)
|
||||
|
||||
from .library.standard_gates.swap import CSwapGate
|
||||
|
||||
return self.append(
|
||||
|
@ -5142,7 +5172,7 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
return self._append_standard_gate(StandardGate.SXGate, None, qargs=[qubit])
|
||||
return self._append_standard_gate(StandardGate.SXGate, [], qargs=[qubit])
|
||||
|
||||
def sxdg(self, qubit: QubitSpecifier) -> InstructionSet:
|
||||
"""Apply :class:`~qiskit.circuit.library.SXdgGate`.
|
||||
|
@ -5155,7 +5185,7 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
return self._append_standard_gate(StandardGate.SXdgGate, None, qargs=[qubit])
|
||||
return self._append_standard_gate(StandardGate.SXdgGate, [], qargs=[qubit])
|
||||
|
||||
def csx(
|
||||
self,
|
||||
|
@ -5179,6 +5209,12 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CSXGate, [], qargs=[control_qubit, target_qubit], label=label
|
||||
)
|
||||
|
||||
from .library.standard_gates.sx import CSXGate
|
||||
|
||||
return self.append(
|
||||
|
@ -5199,7 +5235,7 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
return self._append_standard_gate(StandardGate.TGate, [], [qubit], cargs=None)
|
||||
return self._append_standard_gate(StandardGate.TGate, [], qargs=[qubit])
|
||||
|
||||
def tdg(self, qubit: QubitSpecifier) -> InstructionSet:
|
||||
"""Apply :class:`~qiskit.circuit.library.TdgGate`.
|
||||
|
@ -5212,7 +5248,7 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
return self._append_standard_gate(StandardGate.TdgGate, [], [qubit], cargs=None)
|
||||
return self._append_standard_gate(StandardGate.TdgGate, [], qargs=[qubit])
|
||||
|
||||
def u(
|
||||
self,
|
||||
|
@ -5311,17 +5347,23 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
if ctrl_state is not None:
|
||||
from .library.standard_gates.x import CXGate
|
||||
|
||||
return self.append(
|
||||
CXGate(label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CXGate,
|
||||
[],
|
||||
copy=False,
|
||||
qargs=[control_qubit, target_qubit],
|
||||
cargs=None,
|
||||
label=label,
|
||||
)
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CXGate, [], qargs=[control_qubit, target_qubit], cargs=None, label=label
|
||||
|
||||
from .library.standard_gates.x import CXGate
|
||||
|
||||
return self.append(
|
||||
CXGate(label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
[],
|
||||
copy=False,
|
||||
)
|
||||
|
||||
def dcx(self, qubit1: QubitSpecifier, qubit2: QubitSpecifier) -> InstructionSet:
|
||||
|
@ -5360,20 +5402,22 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
if ctrl_state is not None:
|
||||
from .library.standard_gates.x import CCXGate
|
||||
|
||||
return self.append(
|
||||
CCXGate(ctrl_state=ctrl_state),
|
||||
[control_qubit1, control_qubit2, target_qubit],
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CCXGate,
|
||||
[],
|
||||
copy=False,
|
||||
qargs=[control_qubit1, control_qubit2, target_qubit],
|
||||
cargs=None,
|
||||
)
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CCXGate,
|
||||
|
||||
from .library.standard_gates.x import CCXGate
|
||||
|
||||
return self.append(
|
||||
CCXGate(ctrl_state=ctrl_state),
|
||||
[control_qubit1, control_qubit2, target_qubit],
|
||||
[],
|
||||
qargs=[control_qubit1, control_qubit2, target_qubit],
|
||||
cargs=None,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
def mcx(
|
||||
|
@ -5495,18 +5539,23 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
if ctrl_state is not None:
|
||||
from .library.standard_gates.y import CYGate
|
||||
|
||||
return self.append(
|
||||
CYGate(label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CYGate,
|
||||
[],
|
||||
copy=False,
|
||||
qargs=[control_qubit, target_qubit],
|
||||
cargs=None,
|
||||
label=label,
|
||||
)
|
||||
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CYGate, [], qargs=[control_qubit, target_qubit], cargs=None, label=label
|
||||
from .library.standard_gates.y import CYGate
|
||||
|
||||
return self.append(
|
||||
CYGate(label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
[],
|
||||
copy=False,
|
||||
)
|
||||
|
||||
def z(self, qubit: QubitSpecifier) -> InstructionSet:
|
||||
|
@ -5544,18 +5593,19 @@ class QuantumCircuit:
|
|||
Returns:
|
||||
A handle to the instructions created.
|
||||
"""
|
||||
if ctrl_state is not None:
|
||||
from .library.standard_gates.z import CZGate
|
||||
|
||||
return self.append(
|
||||
CZGate(label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
[],
|
||||
copy=False,
|
||||
# if the control state is |1> use the fast Rust version of the gate
|
||||
if ctrl_state is None or ctrl_state in ["1", 1]:
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CZGate, [], qargs=[control_qubit, target_qubit], label=label
|
||||
)
|
||||
|
||||
return self._append_standard_gate(
|
||||
StandardGate.CZGate, [], qargs=[control_qubit, target_qubit], cargs=None, label=label
|
||||
from .library.standard_gates.z import CZGate
|
||||
|
||||
return self.append(
|
||||
CZGate(label=label, ctrl_state=ctrl_state),
|
||||
[control_qubit, target_qubit],
|
||||
[],
|
||||
copy=False,
|
||||
)
|
||||
|
||||
def ccz(
|
||||
|
|
|
@ -73,6 +73,7 @@ class TestRustGateEquivalence(QiskitTestCase):
|
|||
self.assertIsNone(rs_def)
|
||||
else:
|
||||
rs_def = QuantumCircuit._from_circuit_data(rs_def)
|
||||
|
||||
for rs_inst, py_inst in zip(rs_def._data, py_def._data):
|
||||
# Rust uses U but python still uses U3 and u2
|
||||
if rs_inst.operation.name == "u":
|
||||
|
@ -92,8 +93,8 @@ class TestRustGateEquivalence(QiskitTestCase):
|
|||
[py_def.find_bit(x).index for x in py_inst.qubits],
|
||||
[rs_def.find_bit(x).index for x in rs_inst.qubits],
|
||||
)
|
||||
# Rust uses P but python still uses u1
|
||||
elif rs_inst.operation.name == "p":
|
||||
# Rust uses p but python still uses u1/u3 in some cases
|
||||
elif rs_inst.operation.name == "p" and not name in ["cp", "cs", "csdg"]:
|
||||
if py_inst.operation.name == "u1":
|
||||
self.assertEqual(py_inst.operation.name, "u1")
|
||||
self.assertEqual(rs_inst.operation.params, py_inst.operation.params)
|
||||
|
@ -110,7 +111,14 @@ class TestRustGateEquivalence(QiskitTestCase):
|
|||
[py_def.find_bit(x).index for x in py_inst.qubits],
|
||||
[rs_def.find_bit(x).index for x in rs_inst.qubits],
|
||||
)
|
||||
|
||||
# Rust uses cp but python still uses cu1 in some cases
|
||||
elif rs_inst.operation.name == "cp":
|
||||
self.assertEqual(py_inst.operation.name, "cu1")
|
||||
self.assertEqual(rs_inst.operation.params, py_inst.operation.params)
|
||||
self.assertEqual(
|
||||
[py_def.find_bit(x).index for x in py_inst.qubits],
|
||||
[rs_def.find_bit(x).index for x in rs_inst.qubits],
|
||||
)
|
||||
else:
|
||||
self.assertEqual(py_inst.operation.name, rs_inst.operation.name)
|
||||
self.assertEqual(rs_inst.operation.params, py_inst.operation.params)
|
||||
|
|
Loading…
Reference in New Issue