Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 43 additions & 21 deletions crates/pecos-core/src/gate_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ pub enum GateType {
X = 0b01,
Z = 0b10,
Y = 0b11,
// SX = 4,
// SXdg = 5,
// SY = 6
// SYdg = 7
/// sqrt(X) gate
SX = 4,
/// sqrt(X)-dagger gate
SXdg = 5,
/// sqrt(Y) gate
SY = 6,
/// sqrt(Y)-dagger gate
SYdg = 7,
SZ = 8,
SZdg = 9,
H = 10,
Expand Down Expand Up @@ -60,19 +64,15 @@ pub enum GateType {
// G = 61
/// Controlled-RZ gate (2 qubits, 1 angle parameter)
CRZ = 70,

// RXX = 80
// RYY = 81
/// RXX rotation gate
RXX = 80,
/// RYY rotation gate
RYY = 81,
RZZ = 82,
// RXXYYZZ
/// Toffoli gate (CCX, 3 qubits)
CCX = 90,

/// Square root of X gate (also known as V gate)
SX = 24,
/// Inverse of square root of X gate (also known as Vdg gate)
SXdg = 25,

// MX = 100
// MnX = 101
// MY = 102
Expand Down Expand Up @@ -108,6 +108,10 @@ impl From<u8> for GateType {
1 => GateType::X,
2 => GateType::Z,
3 => GateType::Y,
4 => GateType::SX,
5 => GateType::SXdg,
6 => GateType::SY,
7 => GateType::SYdg,
8 => GateType::SZ,
9 => GateType::SZdg,
10 => GateType::H,
Expand All @@ -118,15 +122,15 @@ impl From<u8> for GateType {
34 => GateType::Tdg,
35 => GateType::U,
36 => GateType::R1XY,
24 => GateType::SX,
25 => GateType::SXdg,
50 => GateType::CX,
51 => GateType::CY,
52 => GateType::CZ,
57 => GateType::SZZ,
58 => GateType::SZZdg,
59 => GateType::SWAP,
70 => GateType::CRZ,
80 => GateType::RXX,
81 => GateType::RYY,
82 => GateType::RZZ,
90 => GateType::CCX,
104 => GateType::Measure,
Expand Down Expand Up @@ -157,13 +161,15 @@ impl GateType {
| GateType::X
| GateType::Y
| GateType::Z
| GateType::SX
| GateType::SXdg
| GateType::SY
| GateType::SYdg
| GateType::SZ
| GateType::SZdg
| GateType::H
| GateType::T
| GateType::Tdg
| GateType::SX
| GateType::SXdg
| GateType::CX
| GateType::CY
| GateType::CZ
Expand All @@ -184,6 +190,8 @@ impl GateType {
GateType::RX
| GateType::RY
| GateType::RZ
| GateType::RXX
| GateType::RYY
| GateType::RZZ
| GateType::CRZ
| GateType::Idle => 1,
Expand All @@ -210,6 +218,10 @@ impl GateType {
| GateType::X
| GateType::Y
| GateType::Z
| GateType::SX
| GateType::SXdg
| GateType::SY
| GateType::SYdg
| GateType::SZ
| GateType::SZdg
| GateType::H
Expand All @@ -218,8 +230,6 @@ impl GateType {
| GateType::RZ
| GateType::T
| GateType::Tdg
| GateType::SX
| GateType::SXdg
| GateType::R1XY
| GateType::U
| GateType::Measure
Expand All @@ -240,6 +250,8 @@ impl GateType {
| GateType::SZZdg
| GateType::SWAP
| GateType::CRZ
| GateType::RXX
| GateType::RYY
| GateType::RZZ => 2,

// Three-qubit gates
Expand All @@ -255,7 +267,13 @@ impl GateType {
pub const fn angle_arity(self) -> usize {
match self {
// Rotation gates with angle parameters
GateType::RX | GateType::RY | GateType::RZ | GateType::RZZ | GateType::CRZ => 1,
GateType::RX
| GateType::RY
| GateType::RZ
| GateType::RXX
| GateType::RYY
| GateType::RZZ
| GateType::CRZ => 1,
GateType::R1XY => 2,
GateType::U => 3,
// All other gates have no angle parameters
Expand Down Expand Up @@ -298,6 +316,10 @@ impl fmt::Display for GateType {
GateType::X => write!(f, "X"),
GateType::Y => write!(f, "Y"),
GateType::Z => write!(f, "Z"),
GateType::SX => write!(f, "SX"),
GateType::SXdg => write!(f, "SXdg"),
GateType::SY => write!(f, "SY"),
GateType::SYdg => write!(f, "SYdg"),
GateType::SZ => write!(f, "SZ"),
GateType::SZdg => write!(f, "SZdg"),
GateType::H => write!(f, "H"),
Expand All @@ -308,13 +330,13 @@ impl fmt::Display for GateType {
GateType::Tdg => write!(f, "Tdg"),
GateType::U => write!(f, "U"),
GateType::R1XY => write!(f, "R1XY"),
GateType::SX => write!(f, "SX"),
GateType::SXdg => write!(f, "SXdg"),
GateType::CX => write!(f, "CX"),
GateType::CY => write!(f, "CY"),
GateType::CZ => write!(f, "CZ"),
GateType::SZZ => write!(f, "SZZ"),
GateType::SZZdg => write!(f, "SZZdg"),
GateType::RXX => write!(f, "RXX"),
GateType::RYY => write!(f, "RYY"),
GateType::SWAP => write!(f, "SWAP"),
GateType::CRZ => write!(f, "CRZ"),
GateType::RZZ => write!(f, "RZZ"),
Expand Down
152 changes: 152 additions & 0 deletions crates/pecos-core/src/gates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ impl Gate {
.collect()
}

/// Create Identity gate on multiple qubits
#[must_use]
pub fn i(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::I, qubits.iter().map(|&q| q.into()).collect())
}

/// Create X gate on multiple qubits
#[must_use]
pub fn x(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Expand All @@ -118,6 +124,54 @@ impl Gate {
Self::simple(GateType::H, qubits.iter().map(|&q| q.into()).collect())
}

/// Create SX gate (sqrt-X) on multiple qubits
#[must_use]
pub fn sx(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::SX, qubits.iter().map(|&q| q.into()).collect())
}

/// Create `SXdg` gate (sqrt-X dagger) on multiple qubits
#[must_use]
pub fn sxdg(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::SXdg, qubits.iter().map(|&q| q.into()).collect())
}

/// Create SY gate (sqrt-Y) on multiple qubits
#[must_use]
pub fn sy(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::SY, qubits.iter().map(|&q| q.into()).collect())
}

/// Create `SYdg` gate (sqrt-Y dagger) on multiple qubits
#[must_use]
pub fn sydg(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::SYdg, qubits.iter().map(|&q| q.into()).collect())
}

/// Create SZ gate (sqrt-Z) on multiple qubits
#[must_use]
pub fn sz(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::SZ, qubits.iter().map(|&q| q.into()).collect())
}

/// Create `SZdg` gate (sqrt-Z dagger) on multiple qubits
#[must_use]
pub fn szdg(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::SZdg, qubits.iter().map(|&q| q.into()).collect())
}

/// Create T gate on multiple qubits
#[must_use]
pub fn t(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::T, qubits.iter().map(|&q| q.into()).collect())
}

/// Create Tdg gate on multiple qubits
#[must_use]
pub fn tdg(qubits: &[impl Into<QubitId> + Copy]) -> Self {
Self::simple(GateType::Tdg, qubits.iter().map(|&q| q.into()).collect())
}

/// Create CX gate from flat qubit list (control1, target1, control2, target2, ...)
///
/// # Panics
Expand All @@ -139,6 +193,48 @@ impl Gate {
Self::cx_vec(&flat_qubits)
}

/// Create CY gate from flat qubit list (control1, target1, control2, target2, ...)
///
/// # Panics
///
/// Panics if the number of qubits is not even, as `CY` gates require pairs of qubits.
#[must_use]
pub fn cy_vec(qubits: &[impl Into<QubitId> + Copy]) -> Self {
assert!(
qubits.len().is_multiple_of(2),
"CY gate requires an even number of qubits"
);
Self::simple(GateType::CY, qubits.iter().map(|&q| q.into()).collect())
}

/// Create CY gate on multiple qubit pairs
#[must_use]
pub fn cy(qubit_pairs: &[(impl Into<QubitId> + Copy, impl Into<QubitId> + Copy)]) -> Self {
let flat_qubits = Self::flatten_qubit_pairs(qubit_pairs);
Self::cy_vec(&flat_qubits)
}

/// Create CZ gate from flat qubit list (control1, target1, control2, target2, ...)
///
/// # Panics
///
/// Panics if the number of qubits is not even, as `CZ` gates require pairs of qubits.
#[must_use]
pub fn cz_vec(qubits: &[impl Into<QubitId> + Copy]) -> Self {
assert!(
qubits.len().is_multiple_of(2),
"CZ gate requires an even number of qubits"
);
Self::simple(GateType::CZ, qubits.iter().map(|&q| q.into()).collect())
}

/// Create CZ gate on multiple qubit pairs
#[must_use]
pub fn cz(qubit_pairs: &[(impl Into<QubitId> + Copy, impl Into<QubitId> + Copy)]) -> Self {
let flat_qubits = Self::flatten_qubit_pairs(qubit_pairs);
Self::cz_vec(&flat_qubits)
}

/// Create SZZ gate from flat qubit list (`qubit1_1`, `qubit2_1`, `qubit1_2`, `qubit2_2`, ...)
///
/// # Panics
Expand Down Expand Up @@ -181,6 +277,62 @@ impl Gate {
Self::szzdg_vec(&flat_qubits)
}

/// Create RXX gate from flat qubit list (`qubit1_1`, `qubit2_1`, `qubit1_2`, `qubit2_2`, ...)
///
/// # Panics
///
/// Panics if the number of qubits is not even, as `RXX` gates require pairs of qubits.
#[must_use]
pub fn rxx_vec(theta: Angle64, qubits: &[impl Into<QubitId> + Copy]) -> Self {
assert!(
qubits.len().is_multiple_of(2),
"RXX gate requires an even number of qubits"
);
Self::with_angles(
GateType::RXX,
vec![theta],
qubits.iter().map(|&q| q.into()).collect(),
)
}

/// Create RXX gate on multiple qubit pairs
#[must_use]
pub fn rxx(
theta: Angle64,
qubit_pairs: &[(impl Into<QubitId> + Copy, impl Into<QubitId> + Copy)],
) -> Self {
let flat_qubits = Self::flatten_qubit_pairs(qubit_pairs);
Self::rxx_vec(theta, &flat_qubits)
}

/// Create RYY gate from flat qubit list (`qubit1_1`, `qubit2_1`, `qubit1_2`, `qubit2_2`, ...)
///
/// # Panics
///
/// Panics if the number of qubits is not even, as `RYY` gates require pairs of qubits.
#[must_use]
pub fn ryy_vec(theta: Angle64, qubits: &[impl Into<QubitId> + Copy]) -> Self {
assert!(
qubits.len().is_multiple_of(2),
"RYY gate requires an even number of qubits"
);
Self::with_angles(
GateType::RYY,
vec![theta],
qubits.iter().map(|&q| q.into()).collect(),
)
}

/// Create RYY gate on multiple qubit pairs
#[must_use]
pub fn ryy(
theta: Angle64,
qubit_pairs: &[(impl Into<QubitId> + Copy, impl Into<QubitId> + Copy)],
) -> Self {
let flat_qubits = Self::flatten_qubit_pairs(qubit_pairs);
Self::ryy_vec(theta, &flat_qubits)
}

/// Create RZZ gate from flat qubit list (`qubit1_1`, `qubit2_1`, `qubit1_2`, `qubit2_2`, ...)
///
/// # Panics
Expand Down
22 changes: 13 additions & 9 deletions crates/pecos-engines/src/noise/biased_depolarizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,32 +157,36 @@ impl BiasedDepolarizingNoiseModel {
for gate in gates {
match gate.gate_type {
GateType::X
| GateType::Y
| GateType::Z
| GateType::SZ
| GateType::SZdg
| GateType::Y
| GateType::SX
| GateType::SXdg
| GateType::SY
| GateType::SYdg
| GateType::SZ
| GateType::SZdg
| GateType::H
| GateType::T
| GateType::Tdg
| GateType::RX
| GateType::RY
| GateType::R1XY
| GateType::RZ
| GateType::U => {
| GateType::T
| GateType::Tdg
| GateType::U
| GateType::R1XY => {
NoiseUtils::add_gate_to_builder(&mut builder, gate);
trace!("Applying single-qubit gate with possible fault");
self.apply_sq_faults(&mut builder, gate);
}
GateType::CX
| GateType::CY
| GateType::CZ
| GateType::RZZ
| GateType::SZZ
| GateType::SZZdg
| GateType::SWAP
| GateType::CRZ => {
| GateType::CRZ
| GateType::RXX
| GateType::RYY
| GateType::RZZ => {
NoiseUtils::add_gate_to_builder(&mut builder, gate);
trace!("Applying two-qubit gate with possible fault");
self.apply_tq_faults(&mut builder, gate);
Expand Down
Loading
Loading