Skip to content
Open
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
16 changes: 16 additions & 0 deletions crates/circuit/src/gate_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,3 +516,19 @@ pub fn xx_plus_yy_gate(theta: f64, beta: f64) -> GateArray2Q {
[C_ZERO, C_ZERO, C_ZERO, C_ONE],
]
}

pub fn rv_gate(v_x: f64, v_y: f64, v_z: f64) -> GateArray1Q {
let angle = ((v_x * v_x) + (v_y * v_y) + (v_z * v_z)).sqrt();
if angle == 0. {
return ONE_QUBIT_IDENTITY;
}
let n_x = v_x / angle;
let n_y = v_y / angle;
let n_z = v_z / angle;
let sin = (angle / 2.).sin();
let cos = (angle / 2.).cos();
[
[cos - IM * n_z * sin, (-n_y - IM * n_x) * sin],
[(n_y - IM * n_x) * sin, cos + IM * n_z * sin],
]
}
3 changes: 3 additions & 0 deletions crates/circuit/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ static STDGATE_IMPORT_PATHS: [[&str; 2]; STANDARD_GATE_SIZE] = [
["qiskit.circuit.library.standard_gates.x", "C3SXGate"],
// RC3XGate = 51
["qiskit.circuit.library.standard_gates.x", "RC3XGate"],
// RVGate = 52
["qiskit.circuit.library.standard_gates.rv", "RVGate"],
];

/// A mapping from the enum variant in crate::operations::StandardGate to the python object for the
Expand Down Expand Up @@ -326,6 +328,7 @@ static STDGATE_PYTHON_GATES: [PyOnceLock<Py<PyAny>>; STANDARD_GATE_SIZE] = [
PyOnceLock::new(),
PyOnceLock::new(),
PyOnceLock::new(),
PyOnceLock::new(),
];

#[inline]
Expand Down
54 changes: 49 additions & 5 deletions crates/circuit/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{Qubit, gate_matrix, impl_intopyobject_for_copy_pyclass};

use nalgebra::{Matrix2, Matrix4};
use ndarray::{Array2, ArrayView2, Dim, ShapeBuilder, array, aview2};
use num_complex::Complex64;
use num_complex::{Complex64, ComplexFloat};
use smallvec::{SmallVec, smallvec};

use numpy::IntoPyArray;
Expand Down Expand Up @@ -636,6 +636,7 @@ pub enum StandardGate {
C3X = 49,
C3SX = 50,
RC3X = 51,
RV = 52,
// Remember to update StandardGate::is_valid_bit_pattern below
// if you add or remove this enum's variants!
}
Expand All @@ -656,7 +657,7 @@ static STANDARD_GATE_NUM_QUBITS: [u32; STANDARD_GATE_SIZE] = [
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 20-29
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 30-39
2, 2, 2, 2, 2, 3, 3, 3, 3, 4, // 40-49
4, 4, // 50-51
4, 4, 1, // 50-52
];

static STANDARD_GATE_NUM_PARAMS: [u32; STANDARD_GATE_SIZE] = [
Expand All @@ -665,7 +666,7 @@ static STANDARD_GATE_NUM_PARAMS: [u32; STANDARD_GATE_SIZE] = [
3, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 20-29
1, 1, 1, 0, 0, 0, 4, 1, 3, 1, // 30-39
1, 1, 1, 2, 2, 0, 0, 0, 0, 0, // 40-49
0, 0, // 50-51
0, 0, 3, // 50-52
];

static STANDARD_GATE_NUM_CTRL_QUBITS: [u32; STANDARD_GATE_SIZE] = [
Expand All @@ -674,7 +675,7 @@ static STANDARD_GATE_NUM_CTRL_QUBITS: [u32; STANDARD_GATE_SIZE] = [
0, 1, 1, 1, 1, 0, 0, 0, 0, 1, // 20-29
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 30-39
0, 0, 0, 0, 0, 2, 2, 1, 0, 3, // 40-49
3, 0, // 50-51
3, 0, 0, // 50-52
];

static STANDARD_GATE_NAME: [&str; STANDARD_GATE_SIZE] = [
Expand Down Expand Up @@ -730,6 +731,7 @@ static STANDARD_GATE_NAME: [&str; STANDARD_GATE_SIZE] = [
"mcx", // 49 ("c3x")
"c3sx", // 50
"rcccx", // 51 ("rc3x")
"rv", // 52
];

/// Get a slice of all standard gate names.
Expand Down Expand Up @@ -862,6 +864,14 @@ impl StandardGate {
Self::C3X => Some((Self::C3X, smallvec![])),
Self::C3SX => None, // the inverse in not a StandardGate
Self::RC3X => None, // the inverse in not a StandardGate
Self::RV => Some((
Self::RV,
smallvec![
multiply_param(&params[0], -1.0),
multiply_param(&params[1], -1.0),
multiply_param(&params[2], -1.0)
],
)),
}
}
}
Expand Down Expand Up @@ -946,7 +956,7 @@ impl StandardGate {
//
// Remove this when std::mem::variant_count() is stabilized (see
// https://github.com/rust-lang/rust/issues/73662 )
pub const STANDARD_GATE_SIZE: usize = 52;
pub const STANDARD_GATE_SIZE: usize = 53;

impl Operation for StandardGate {
fn name(&self) -> &str {
Expand Down Expand Up @@ -1204,6 +1214,12 @@ impl Operation for StandardGate {
[] => Some(aview2(&gate_matrix::RC3X_GATE).to_owned()),
_ => None,
},
Self::RV => match params {
[Param::Float(v_x), Param::Float(v_y), Param::Float(v_z)] => {
Some(aview2(&gate_matrix::rv_gate(*v_x, *v_y, *v_z)).to_owned())
}
_ => None,
},
}
}

Expand Down Expand Up @@ -2241,6 +2257,28 @@ impl Operation for StandardGate {
)
.expect("Unexpected Qiskit python bug"),
),
Self::RV => {
let mat = self.matrix_as_static_1q(params).unwrap();
let det_arg = (mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]).arg();
let theta = 2. * mat[1][0].abs().atan2(mat[0][0].abs());
let ang1 = mat[1][1].arg();
let ang2 = mat[1][0].arg();
let phi = ang1 + ang2 - det_arg;
let lam = ang1 - ang2;
let phase = (0.5 * det_arg) - 0.5 * (phi + lam);
Some(
CircuitData::from_standard_gates(
1,
[(
Self::U,
smallvec![Param::Float(theta), Param::Float(phi), Param::Float(lam)],
smallvec![Qubit(0)],
)],
Param::Float(phase),
)
.expect("unexpected Qiskit python bug"),
)
}
}
}

Expand Down Expand Up @@ -2335,6 +2373,12 @@ impl Operation for StandardGate {
}
_ => None,
},
Self::RV => match params {
[Param::Float(v_x), Param::Float(v_y), Param::Float(v_z)] => {
Some(gate_matrix::rv_gate(*v_x, *v_y, *v_z))
}
_ => None,
},
Self::CH => None,
Self::CX => None,
Self::CY => None,
Expand Down
1 change: 0 additions & 1 deletion qiskit/circuit/library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,6 @@
GRX,
GRY,
GRZ,
RVGate,
PauliGate,
LinearFunction,
Isometry,
Expand Down
1 change: 0 additions & 1 deletion qiskit/circuit/library/generalized_gates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from .gms import GMS, MSGate
from .gr import GR, GRX, GRY, GRZ
from .pauli import PauliGate
from .rv import RVGate
from .linear_function import LinearFunction
from .isometry import Isometry
from .uc import UCGate
Expand Down
96 changes: 0 additions & 96 deletions qiskit/circuit/library/generalized_gates/rv.py

This file was deleted.

2 changes: 2 additions & 0 deletions qiskit/circuit/library/standard_gates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .i import IGate
from .p import PhaseGate, CPhaseGate, MCPhaseGate
from .r import RGate
from .rv import RVGate
from .rx import RXGate, CRXGate
from .rxx import RXXGate
from .ry import RYGate, CRYGate
Expand Down Expand Up @@ -109,6 +110,7 @@ def get_standard_gate_name_mapping():
PhaseGate(theta),
RCCXGate(),
RC3XGate(),
RVGate(theta, phi, lambda_),
RXGate(theta),
RXXGate(theta),
RYGate(theta),
Expand Down
Loading
Loading