Skip to content

Commit 9404d2b

Browse files
committed
Merge remote-tracking branch 'origin/dev' into docs
2 parents 1f77172 + 7a8c258 commit 9404d2b

16 files changed

Lines changed: 2786 additions & 445 deletions

File tree

crates/pecos-core/src/gate_type.rs

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ pub enum GateType {
1717
X = 0b01,
1818
Z = 0b10,
1919
Y = 0b11,
20-
// SX = 4,
21-
// SXdg = 5,
22-
// SY = 6
23-
// SYdg = 7
20+
/// sqrt(X) gate
21+
SX = 4,
22+
/// sqrt(X)-dagger gate
23+
SXdg = 5,
24+
/// sqrt(Y) gate
25+
SY = 6,
26+
/// sqrt(Y)-dagger gate
27+
SYdg = 7,
2428
SZ = 8,
2529
SZdg = 9,
2630
H = 10,
@@ -60,19 +64,15 @@ pub enum GateType {
6064
// G = 61
6165
/// Controlled-RZ gate (2 qubits, 1 angle parameter)
6266
CRZ = 70,
63-
64-
// RXX = 80
65-
// RYY = 81
67+
/// RXX rotation gate
68+
RXX = 80,
69+
/// RYY rotation gate
70+
RYY = 81,
6671
RZZ = 82,
6772
// RXXYYZZ
6873
/// Toffoli gate (CCX, 3 qubits)
6974
CCX = 90,
7075

71-
/// Square root of X gate (also known as V gate)
72-
SX = 24,
73-
/// Inverse of square root of X gate (also known as Vdg gate)
74-
SXdg = 25,
75-
7676
// MX = 100
7777
// MnX = 101
7878
// MY = 102
@@ -108,6 +108,10 @@ impl From<u8> for GateType {
108108
1 => GateType::X,
109109
2 => GateType::Z,
110110
3 => GateType::Y,
111+
4 => GateType::SX,
112+
5 => GateType::SXdg,
113+
6 => GateType::SY,
114+
7 => GateType::SYdg,
111115
8 => GateType::SZ,
112116
9 => GateType::SZdg,
113117
10 => GateType::H,
@@ -118,15 +122,15 @@ impl From<u8> for GateType {
118122
34 => GateType::Tdg,
119123
35 => GateType::U,
120124
36 => GateType::R1XY,
121-
24 => GateType::SX,
122-
25 => GateType::SXdg,
123125
50 => GateType::CX,
124126
51 => GateType::CY,
125127
52 => GateType::CZ,
126128
57 => GateType::SZZ,
127129
58 => GateType::SZZdg,
128130
59 => GateType::SWAP,
129131
70 => GateType::CRZ,
132+
80 => GateType::RXX,
133+
81 => GateType::RYY,
130134
82 => GateType::RZZ,
131135
90 => GateType::CCX,
132136
104 => GateType::Measure,
@@ -157,13 +161,15 @@ impl GateType {
157161
| GateType::X
158162
| GateType::Y
159163
| GateType::Z
164+
| GateType::SX
165+
| GateType::SXdg
166+
| GateType::SY
167+
| GateType::SYdg
160168
| GateType::SZ
161169
| GateType::SZdg
162170
| GateType::H
163171
| GateType::T
164172
| GateType::Tdg
165-
| GateType::SX
166-
| GateType::SXdg
167173
| GateType::CX
168174
| GateType::CY
169175
| GateType::CZ
@@ -184,6 +190,8 @@ impl GateType {
184190
GateType::RX
185191
| GateType::RY
186192
| GateType::RZ
193+
| GateType::RXX
194+
| GateType::RYY
187195
| GateType::RZZ
188196
| GateType::CRZ
189197
| GateType::Idle => 1,
@@ -210,6 +218,10 @@ impl GateType {
210218
| GateType::X
211219
| GateType::Y
212220
| GateType::Z
221+
| GateType::SX
222+
| GateType::SXdg
223+
| GateType::SY
224+
| GateType::SYdg
213225
| GateType::SZ
214226
| GateType::SZdg
215227
| GateType::H
@@ -218,8 +230,6 @@ impl GateType {
218230
| GateType::RZ
219231
| GateType::T
220232
| GateType::Tdg
221-
| GateType::SX
222-
| GateType::SXdg
223233
| GateType::R1XY
224234
| GateType::U
225235
| GateType::Measure
@@ -240,6 +250,8 @@ impl GateType {
240250
| GateType::SZZdg
241251
| GateType::SWAP
242252
| GateType::CRZ
253+
| GateType::RXX
254+
| GateType::RYY
243255
| GateType::RZZ => 2,
244256

245257
// Three-qubit gates
@@ -255,7 +267,13 @@ impl GateType {
255267
pub const fn angle_arity(self) -> usize {
256268
match self {
257269
// Rotation gates with angle parameters
258-
GateType::RX | GateType::RY | GateType::RZ | GateType::RZZ | GateType::CRZ => 1,
270+
GateType::RX
271+
| GateType::RY
272+
| GateType::RZ
273+
| GateType::RXX
274+
| GateType::RYY
275+
| GateType::RZZ
276+
| GateType::CRZ => 1,
259277
GateType::R1XY => 2,
260278
GateType::U => 3,
261279
// All other gates have no angle parameters
@@ -298,6 +316,10 @@ impl fmt::Display for GateType {
298316
GateType::X => write!(f, "X"),
299317
GateType::Y => write!(f, "Y"),
300318
GateType::Z => write!(f, "Z"),
319+
GateType::SX => write!(f, "SX"),
320+
GateType::SXdg => write!(f, "SXdg"),
321+
GateType::SY => write!(f, "SY"),
322+
GateType::SYdg => write!(f, "SYdg"),
301323
GateType::SZ => write!(f, "SZ"),
302324
GateType::SZdg => write!(f, "SZdg"),
303325
GateType::H => write!(f, "H"),
@@ -308,13 +330,13 @@ impl fmt::Display for GateType {
308330
GateType::Tdg => write!(f, "Tdg"),
309331
GateType::U => write!(f, "U"),
310332
GateType::R1XY => write!(f, "R1XY"),
311-
GateType::SX => write!(f, "SX"),
312-
GateType::SXdg => write!(f, "SXdg"),
313333
GateType::CX => write!(f, "CX"),
314334
GateType::CY => write!(f, "CY"),
315335
GateType::CZ => write!(f, "CZ"),
316336
GateType::SZZ => write!(f, "SZZ"),
317337
GateType::SZZdg => write!(f, "SZZdg"),
338+
GateType::RXX => write!(f, "RXX"),
339+
GateType::RYY => write!(f, "RYY"),
318340
GateType::SWAP => write!(f, "SWAP"),
319341
GateType::CRZ => write!(f, "CRZ"),
320342
GateType::RZZ => write!(f, "RZZ"),

crates/pecos-core/src/gates.rs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ impl Gate {
9494
.collect()
9595
}
9696

97+
/// Create Identity gate on multiple qubits
98+
#[must_use]
99+
pub fn i(qubits: &[impl Into<QubitId> + Copy]) -> Self {
100+
Self::simple(GateType::I, qubits.iter().map(|&q| q.into()).collect())
101+
}
102+
97103
/// Create X gate on multiple qubits
98104
#[must_use]
99105
pub fn x(qubits: &[impl Into<QubitId> + Copy]) -> Self {
@@ -118,6 +124,54 @@ impl Gate {
118124
Self::simple(GateType::H, qubits.iter().map(|&q| q.into()).collect())
119125
}
120126

127+
/// Create SX gate (sqrt-X) on multiple qubits
128+
#[must_use]
129+
pub fn sx(qubits: &[impl Into<QubitId> + Copy]) -> Self {
130+
Self::simple(GateType::SX, qubits.iter().map(|&q| q.into()).collect())
131+
}
132+
133+
/// Create `SXdg` gate (sqrt-X dagger) on multiple qubits
134+
#[must_use]
135+
pub fn sxdg(qubits: &[impl Into<QubitId> + Copy]) -> Self {
136+
Self::simple(GateType::SXdg, qubits.iter().map(|&q| q.into()).collect())
137+
}
138+
139+
/// Create SY gate (sqrt-Y) on multiple qubits
140+
#[must_use]
141+
pub fn sy(qubits: &[impl Into<QubitId> + Copy]) -> Self {
142+
Self::simple(GateType::SY, qubits.iter().map(|&q| q.into()).collect())
143+
}
144+
145+
/// Create `SYdg` gate (sqrt-Y dagger) on multiple qubits
146+
#[must_use]
147+
pub fn sydg(qubits: &[impl Into<QubitId> + Copy]) -> Self {
148+
Self::simple(GateType::SYdg, qubits.iter().map(|&q| q.into()).collect())
149+
}
150+
151+
/// Create SZ gate (sqrt-Z) on multiple qubits
152+
#[must_use]
153+
pub fn sz(qubits: &[impl Into<QubitId> + Copy]) -> Self {
154+
Self::simple(GateType::SZ, qubits.iter().map(|&q| q.into()).collect())
155+
}
156+
157+
/// Create `SZdg` gate (sqrt-Z dagger) on multiple qubits
158+
#[must_use]
159+
pub fn szdg(qubits: &[impl Into<QubitId> + Copy]) -> Self {
160+
Self::simple(GateType::SZdg, qubits.iter().map(|&q| q.into()).collect())
161+
}
162+
163+
/// Create T gate on multiple qubits
164+
#[must_use]
165+
pub fn t(qubits: &[impl Into<QubitId> + Copy]) -> Self {
166+
Self::simple(GateType::T, qubits.iter().map(|&q| q.into()).collect())
167+
}
168+
169+
/// Create Tdg gate on multiple qubits
170+
#[must_use]
171+
pub fn tdg(qubits: &[impl Into<QubitId> + Copy]) -> Self {
172+
Self::simple(GateType::Tdg, qubits.iter().map(|&q| q.into()).collect())
173+
}
174+
121175
/// Create CX gate from flat qubit list (control1, target1, control2, target2, ...)
122176
///
123177
/// # Panics
@@ -139,6 +193,48 @@ impl Gate {
139193
Self::cx_vec(&flat_qubits)
140194
}
141195

196+
/// Create CY gate from flat qubit list (control1, target1, control2, target2, ...)
197+
///
198+
/// # Panics
199+
///
200+
/// Panics if the number of qubits is not even, as `CY` gates require pairs of qubits.
201+
#[must_use]
202+
pub fn cy_vec(qubits: &[impl Into<QubitId> + Copy]) -> Self {
203+
assert!(
204+
qubits.len().is_multiple_of(2),
205+
"CY gate requires an even number of qubits"
206+
);
207+
Self::simple(GateType::CY, qubits.iter().map(|&q| q.into()).collect())
208+
}
209+
210+
/// Create CY gate on multiple qubit pairs
211+
#[must_use]
212+
pub fn cy(qubit_pairs: &[(impl Into<QubitId> + Copy, impl Into<QubitId> + Copy)]) -> Self {
213+
let flat_qubits = Self::flatten_qubit_pairs(qubit_pairs);
214+
Self::cy_vec(&flat_qubits)
215+
}
216+
217+
/// Create CZ gate from flat qubit list (control1, target1, control2, target2, ...)
218+
///
219+
/// # Panics
220+
///
221+
/// Panics if the number of qubits is not even, as `CZ` gates require pairs of qubits.
222+
#[must_use]
223+
pub fn cz_vec(qubits: &[impl Into<QubitId> + Copy]) -> Self {
224+
assert!(
225+
qubits.len().is_multiple_of(2),
226+
"CZ gate requires an even number of qubits"
227+
);
228+
Self::simple(GateType::CZ, qubits.iter().map(|&q| q.into()).collect())
229+
}
230+
231+
/// Create CZ gate on multiple qubit pairs
232+
#[must_use]
233+
pub fn cz(qubit_pairs: &[(impl Into<QubitId> + Copy, impl Into<QubitId> + Copy)]) -> Self {
234+
let flat_qubits = Self::flatten_qubit_pairs(qubit_pairs);
235+
Self::cz_vec(&flat_qubits)
236+
}
237+
142238
/// Create SZZ gate from flat qubit list (`qubit1_1`, `qubit2_1`, `qubit1_2`, `qubit2_2`, ...)
143239
///
144240
/// # Panics
@@ -181,6 +277,62 @@ impl Gate {
181277
Self::szzdg_vec(&flat_qubits)
182278
}
183279

280+
/// Create RXX gate from flat qubit list (`qubit1_1`, `qubit2_1`, `qubit1_2`, `qubit2_2`, ...)
281+
///
282+
/// # Panics
283+
///
284+
/// Panics if the number of qubits is not even, as `RXX` gates require pairs of qubits.
285+
#[must_use]
286+
pub fn rxx_vec(theta: Angle64, qubits: &[impl Into<QubitId> + Copy]) -> Self {
287+
assert!(
288+
qubits.len().is_multiple_of(2),
289+
"RXX gate requires an even number of qubits"
290+
);
291+
Self::with_angles(
292+
GateType::RXX,
293+
vec![theta],
294+
qubits.iter().map(|&q| q.into()).collect(),
295+
)
296+
}
297+
298+
/// Create RXX gate on multiple qubit pairs
299+
#[must_use]
300+
pub fn rxx(
301+
theta: Angle64,
302+
qubit_pairs: &[(impl Into<QubitId> + Copy, impl Into<QubitId> + Copy)],
303+
) -> Self {
304+
let flat_qubits = Self::flatten_qubit_pairs(qubit_pairs);
305+
Self::rxx_vec(theta, &flat_qubits)
306+
}
307+
308+
/// Create RYY gate from flat qubit list (`qubit1_1`, `qubit2_1`, `qubit1_2`, `qubit2_2`, ...)
309+
///
310+
/// # Panics
311+
///
312+
/// Panics if the number of qubits is not even, as `RYY` gates require pairs of qubits.
313+
#[must_use]
314+
pub fn ryy_vec(theta: Angle64, qubits: &[impl Into<QubitId> + Copy]) -> Self {
315+
assert!(
316+
qubits.len().is_multiple_of(2),
317+
"RYY gate requires an even number of qubits"
318+
);
319+
Self::with_angles(
320+
GateType::RYY,
321+
vec![theta],
322+
qubits.iter().map(|&q| q.into()).collect(),
323+
)
324+
}
325+
326+
/// Create RYY gate on multiple qubit pairs
327+
#[must_use]
328+
pub fn ryy(
329+
theta: Angle64,
330+
qubit_pairs: &[(impl Into<QubitId> + Copy, impl Into<QubitId> + Copy)],
331+
) -> Self {
332+
let flat_qubits = Self::flatten_qubit_pairs(qubit_pairs);
333+
Self::ryy_vec(theta, &flat_qubits)
334+
}
335+
184336
/// Create RZZ gate from flat qubit list (`qubit1_1`, `qubit2_1`, `qubit1_2`, `qubit2_2`, ...)
185337
///
186338
/// # Panics

crates/pecos-engines/src/noise/biased_depolarizing.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,32 +157,36 @@ impl BiasedDepolarizingNoiseModel {
157157
for gate in gates {
158158
match gate.gate_type {
159159
GateType::X
160-
| GateType::Y
161160
| GateType::Z
162-
| GateType::SZ
163-
| GateType::SZdg
161+
| GateType::Y
164162
| GateType::SX
165163
| GateType::SXdg
164+
| GateType::SY
165+
| GateType::SYdg
166+
| GateType::SZ
167+
| GateType::SZdg
166168
| GateType::H
167-
| GateType::T
168-
| GateType::Tdg
169169
| GateType::RX
170170
| GateType::RY
171-
| GateType::R1XY
172171
| GateType::RZ
173-
| GateType::U => {
172+
| GateType::T
173+
| GateType::Tdg
174+
| GateType::U
175+
| GateType::R1XY => {
174176
NoiseUtils::add_gate_to_builder(&mut builder, gate);
175177
trace!("Applying single-qubit gate with possible fault");
176178
self.apply_sq_faults(&mut builder, gate);
177179
}
178180
GateType::CX
179181
| GateType::CY
180182
| GateType::CZ
181-
| GateType::RZZ
182183
| GateType::SZZ
183184
| GateType::SZZdg
184185
| GateType::SWAP
185-
| GateType::CRZ => {
186+
| GateType::CRZ
187+
| GateType::RXX
188+
| GateType::RYY
189+
| GateType::RZZ => {
186190
NoiseUtils::add_gate_to_builder(&mut builder, gate);
187191
trace!("Applying two-qubit gate with possible fault");
188192
self.apply_tq_faults(&mut builder, gate);

0 commit comments

Comments
 (0)