Skip to content

Commit

Permalink
Finalize Rust representation for standard gates (#12709)
Browse files Browse the repository at this point in the history
* Add missing gate definitions

* Reorder gates, following number of qubits and a sort of alphabetical order. Make definitions and matrices consistent with new gate order. Remove C4XGate (second mcx) from list.
  • Loading branch information
ElePT authored Jul 12, 2024
1 parent 2a2b806 commit 3e2a6e8
Show file tree
Hide file tree
Showing 4 changed files with 935 additions and 924 deletions.
175 changes: 88 additions & 87 deletions crates/circuit/src/gate_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)],
Expand All @@ -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 = [
[
Expand Down Expand Up @@ -133,13 +126,24 @@ 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],
[C_ZERO, IM, C_ZERO, C_ZERO],
[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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
Loading

0 comments on commit 3e2a6e8

Please sign in to comment.