Skip to content

Commit bb1dad9

Browse files
committed
Resolve merge conflict in operations.rs
2 parents 97b1fb6 + 62f74c7 commit bb1dad9

14 files changed

Lines changed: 541 additions & 81 deletions

File tree

crates/circuit/src/nlayout.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,18 @@ impl NLayout {
291291
}
292292
}
293293
}
294+
impl ::std::ops::Index<VirtualQubit> for NLayout {
295+
type Output = PhysicalQubit;
296+
fn index(&self, index: VirtualQubit) -> &PhysicalQubit {
297+
&self.virt_to_phys[index.index()]
298+
}
299+
}
300+
impl ::std::ops::Index<PhysicalQubit> for NLayout {
301+
type Output = VirtualQubit;
302+
fn index(&self, index: PhysicalQubit) -> &VirtualQubit {
303+
&self.phys_to_virt[index.index()]
304+
}
305+
}
294306

295307
pub fn nlayout(m: &Bound<PyModule>) -> PyResult<()> {
296308
m.add_class::<NLayout>()?;

crates/circuit/src/operations.rs

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2838,6 +2838,146 @@ impl StandardGate {
28382838
Self::RC3X => None,
28392839
}
28402840
}
2841+
2842+
pub fn matrix_as_static_2q(&self, params: &[Param]) -> Option<[[Complex64; 4]; 4]> {
2843+
match self {
2844+
Self::GlobalPhase => None,
2845+
Self::H => None,
2846+
Self::I => None,
2847+
Self::X => None,
2848+
Self::Y => None,
2849+
Self::Z => None,
2850+
Self::Phase => None,
2851+
Self::R => None,
2852+
Self::RX => None,
2853+
Self::RY => None,
2854+
Self::RZ => None,
2855+
Self::S => None,
2856+
Self::Sdg => None,
2857+
Self::SX => None,
2858+
Self::SXdg => None,
2859+
Self::T => None,
2860+
Self::Tdg => None,
2861+
Self::U => None,
2862+
Self::U1 => None,
2863+
Self::U2 => None,
2864+
Self::U3 => None,
2865+
Self::CH => match params {
2866+
[] => Some(gate_matrix::CH_GATE),
2867+
_ => None,
2868+
},
2869+
Self::CX => match params {
2870+
[] => Some(gate_matrix::CX_GATE),
2871+
_ => None,
2872+
},
2873+
Self::CY => match params {
2874+
[] => Some(gate_matrix::CY_GATE),
2875+
_ => None,
2876+
},
2877+
Self::CZ => match params {
2878+
[] => Some(gate_matrix::CZ_GATE),
2879+
_ => None,
2880+
},
2881+
Self::DCX => match params {
2882+
[] => Some(gate_matrix::DCX_GATE),
2883+
_ => None,
2884+
},
2885+
Self::ECR => match params {
2886+
[] => Some(gate_matrix::ECR_GATE),
2887+
_ => None,
2888+
},
2889+
Self::Swap => match params {
2890+
[] => Some(gate_matrix::SWAP_GATE),
2891+
_ => None,
2892+
},
2893+
Self::ISwap => match params {
2894+
[] => Some(gate_matrix::ISWAP_GATE),
2895+
_ => None,
2896+
},
2897+
Self::CPhase => match params {
2898+
[Param::Float(lam)] => Some(gate_matrix::cp_gate(*lam)),
2899+
_ => None,
2900+
},
2901+
Self::CRX => match params {
2902+
[Param::Float(theta)] => Some(gate_matrix::crx_gate(*theta)),
2903+
_ => None,
2904+
},
2905+
Self::CRY => match params {
2906+
[Param::Float(theta)] => Some(gate_matrix::cry_gate(*theta)),
2907+
_ => None,
2908+
},
2909+
Self::CRZ => match params {
2910+
[Param::Float(theta)] => Some(gate_matrix::crz_gate(*theta)),
2911+
_ => None,
2912+
},
2913+
Self::CS => match params {
2914+
[] => Some(gate_matrix::CS_GATE),
2915+
_ => None,
2916+
},
2917+
Self::CSdg => match params {
2918+
[] => Some(gate_matrix::CSDG_GATE),
2919+
_ => None,
2920+
},
2921+
Self::CSX => match params {
2922+
[] => Some(gate_matrix::CSX_GATE),
2923+
_ => None,
2924+
},
2925+
Self::CU => match params {
2926+
[
2927+
Param::Float(theta),
2928+
Param::Float(phi),
2929+
Param::Float(lam),
2930+
Param::Float(gamma),
2931+
] => Some(gate_matrix::cu_gate(*theta, *phi, *lam, *gamma)),
2932+
_ => None,
2933+
},
2934+
Self::CU1 => match params[0] {
2935+
Param::Float(lam) => Some(gate_matrix::cu1_gate(lam)),
2936+
_ => None,
2937+
},
2938+
Self::CU3 => match params {
2939+
[Param::Float(theta), Param::Float(phi), Param::Float(lam)] => {
2940+
Some(gate_matrix::cu3_gate(*theta, *phi, *lam))
2941+
}
2942+
_ => None,
2943+
},
2944+
Self::RXX => match params[0] {
2945+
Param::Float(theta) => Some(gate_matrix::rxx_gate(theta)),
2946+
_ => None,
2947+
},
2948+
Self::RYY => match params[0] {
2949+
Param::Float(theta) => Some(gate_matrix::ryy_gate(theta)),
2950+
_ => None,
2951+
},
2952+
Self::RZZ => match params[0] {
2953+
Param::Float(theta) => Some(gate_matrix::rzz_gate(theta)),
2954+
_ => None,
2955+
},
2956+
Self::RZX => match params[0] {
2957+
Param::Float(theta) => Some(gate_matrix::rzx_gate(theta)),
2958+
_ => None,
2959+
},
2960+
Self::XXMinusYY => match params {
2961+
[Param::Float(theta), Param::Float(beta)] => {
2962+
Some(gate_matrix::xx_minus_yy_gate(*theta, *beta))
2963+
}
2964+
_ => None,
2965+
},
2966+
Self::XXPlusYY => match params {
2967+
[Param::Float(theta), Param::Float(beta)] => {
2968+
Some(gate_matrix::xx_plus_yy_gate(*theta, *beta))
2969+
}
2970+
_ => None,
2971+
},
2972+
Self::CCX => None,
2973+
Self::CCZ => None,
2974+
Self::CSwap => None,
2975+
Self::RCCX => None,
2976+
Self::C3X => None,
2977+
Self::C3SX => None,
2978+
Self::RC3X => None,
2979+
}
2980+
}
28412981
}
28422982

28432983
#[pymethods]
@@ -3172,6 +3312,26 @@ impl PyInstruction {
31723312
})
31733313
}
31743314

3315+
pub fn matrix_as_static_2q(&self) -> Option<[[Complex64; 4]; 4]> {
3316+
if self.num_qubits() != 2 {
3317+
return None;
3318+
}
3319+
Python::attach(|py| -> Option<[[Complex64; 4]; 4]> {
3320+
let array = self
3321+
.instruction
3322+
.call_method0(py, intern!(py, "to_matrix"))
3323+
.ok()?
3324+
.extract::<PyReadonlyArray2<Complex64>>(py)
3325+
.ok()?;
3326+
let arr = array.as_array();
3327+
Some([
3328+
[arr[[0, 0]], arr[[0, 1]], arr[[0, 2]], arr[[0, 3]]],
3329+
[arr[[1, 0]], arr[[1, 1]], arr[[1, 2]], arr[[1, 3]]],
3330+
[arr[[2, 0]], arr[[2, 1]], arr[[2, 2]], arr[[2, 3]]],
3331+
[arr[[3, 0]], arr[[3, 1]], arr[[3, 2]], arr[[3, 3]]],
3332+
])
3333+
})
3334+
}
31753335
}
31763336

31773337
#[derive(Clone, Debug)]
@@ -3254,6 +3414,30 @@ impl UnitaryGate {
32543414
}
32553415
}
32563416

3417+
pub fn matrix_as_static_2q(&self) -> Option<[[Complex64; 4]; 4]> {
3418+
match &self.array {
3419+
ArrayType::OneQ(_mat) => None,
3420+
ArrayType::NDArray(arr) => {
3421+
if self.num_qubits() == 2 {
3422+
Some([
3423+
[arr[[0, 0]], arr[[0, 1]], arr[[0, 2]], arr[[0, 3]]],
3424+
[arr[[1, 0]], arr[[1, 1]], arr[[1, 2]], arr[[1, 3]]],
3425+
[arr[[2, 0]], arr[[2, 1]], arr[[2, 2]], arr[[2, 3]]],
3426+
[arr[[3, 0]], arr[[3, 1]], arr[[3, 2]], arr[[3, 3]]],
3427+
])
3428+
} else {
3429+
None
3430+
}
3431+
}
3432+
ArrayType::TwoQ(mat) => Some([
3433+
[mat[(0, 0)], mat[(0, 1)], mat[(0, 2)], mat[(0, 3)]],
3434+
[mat[(1, 0)], mat[(1, 1)], mat[(1, 2)], mat[(1, 3)]],
3435+
[mat[(2, 0)], mat[(2, 1)], mat[(2, 2)], mat[(2, 3)]],
3436+
[mat[(3, 0)], mat[(3, 1)], mat[(3, 2)], mat[(3, 3)]],
3437+
]),
3438+
}
3439+
}
3440+
32573441
pub fn matrix_as_nalgebra_1q(&self) -> Option<Matrix2<Complex64>> {
32583442
match &self.array {
32593443
ArrayType::OneQ(mat) => Some(*mat),
@@ -3272,6 +3456,36 @@ impl UnitaryGate {
32723456
ArrayType::TwoQ(_) => None,
32733457
}
32743458
}
3459+
pub fn matrix_as_nalgebra_2q(&self) -> Option<Matrix4<Complex64>> {
3460+
match &self.array {
3461+
ArrayType::OneQ(_mat) => None,
3462+
ArrayType::NDArray(arr) => {
3463+
if self.num_qubits() == 2 {
3464+
Some(Matrix4::new(
3465+
arr[[0, 0]],
3466+
arr[[0, 1]],
3467+
arr[[0, 2]],
3468+
arr[[0, 3]],
3469+
arr[[1, 0]],
3470+
arr[[1, 1]],
3471+
arr[[1, 2]],
3472+
arr[[1, 3]],
3473+
arr[[2, 0]],
3474+
arr[[2, 1]],
3475+
arr[[2, 2]],
3476+
arr[[2, 3]],
3477+
arr[[3, 0]],
3478+
arr[[3, 1]],
3479+
arr[[3, 2]],
3480+
arr[[3, 3]],
3481+
))
3482+
} else {
3483+
None
3484+
}
3485+
}
3486+
ArrayType::TwoQ(mat) => Some(*mat),
3487+
}
3488+
}
32753489
}
32763490

32773491
impl UnitaryGate {

crates/circuit/src/packed_instruction.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::operations::{
2525
use crate::{Block, Clbit, Qubit};
2626

2727
use hashbrown::HashMap;
28-
use nalgebra::Matrix2;
28+
use nalgebra::{Matrix2, Matrix4};
2929
use ndarray::{Array2, CowArray, Ix2};
3030
use num_complex::Complex64;
3131
use pyo3::prelude::*;
@@ -985,6 +985,7 @@ impl PackedInstruction {
985985
}
986986
}
987987

988+
#[inline]
988989
pub fn try_matrix_as_nalgebra_1q(&self) -> Option<Matrix2<Complex64>> {
989990
match self.op.view() {
990991
OperationRef::Unitary(u) => u.matrix_as_nalgebra_1q(),
@@ -995,6 +996,34 @@ impl PackedInstruction {
995996
}
996997
}
997998

999+
/// Returns a static matrix for 1-qubit gates. Will return `None` when the gate is not 1-qubit.
1000+
#[inline]
1001+
pub fn try_matrix_as_static_2q(&self) -> Option<[[Complex64; 4]; 4]> {
1002+
match self.op.view() {
1003+
OperationRef::StandardGate(standard) => {
1004+
standard.matrix_as_static_2q(self.params_view())
1005+
}
1006+
OperationRef::Gate(gate) => gate.matrix_as_static_2q(),
1007+
OperationRef::Unitary(unitary) => unitary.matrix_as_static_2q(),
1008+
_ => None,
1009+
}
1010+
}
1011+
1012+
#[inline]
1013+
pub fn try_matrix_as_nalgebra_2q(&self) -> Option<Matrix4<Complex64>> {
1014+
match self.op.view() {
1015+
OperationRef::Unitary(u) => u.matrix_as_nalgebra_2q(),
1016+
// default implementation
1017+
_ => self.try_matrix_as_static_2q().map(|arr| {
1018+
Matrix4::new(
1019+
arr[0][0], arr[0][1], arr[0][2], arr[0][3], arr[1][0], arr[1][1], arr[1][2],
1020+
arr[1][3], arr[2][0], arr[2][1], arr[2][2], arr[2][3], arr[3][0], arr[3][1],
1021+
arr[3][2], arr[3][3],
1022+
)
1023+
}),
1024+
}
1025+
}
1026+
9981027
pub fn try_definition(&self) -> Option<CircuitData> {
9991028
match self.op.view() {
10001029
OperationRef::StandardGate(g) => g.definition(self.params_view()),

0 commit comments

Comments
 (0)