From b373e4d0f59544d21b663d8f5a222a850315ae80 Mon Sep 17 00:00:00 2001 From: John Lapeyre Date: Wed, 5 Jun 2024 15:08:49 -0400 Subject: [PATCH] Add more cases to rust definition of RGate We have done all float parameters. This commit adds all expression (variable) parameters. It remains to implement heterogeneous parameters. * Run formatting tools on source --- crates/circuit/src/imports.rs | 7 ++-- crates/circuit/src/operations.rs | 44 +++++++++++++--------- qiskit/circuit/library/standard_gates/r.py | 11 +++++- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/crates/circuit/src/imports.rs b/crates/circuit/src/imports.rs index 9182530f4a74..d61acee183b3 100644 --- a/crates/circuit/src/imports.rs +++ b/crates/circuit/src/imports.rs @@ -106,7 +106,8 @@ static mut STDGATE_PYTHON_GATES: GILOnceCell<[Option; STANDARD_GATE_SI fn _array_of_option_pyobject() -> [Option; STANDARD_GATE_SIZE] { use std::mem::{self, MaybeUninit}; let array = unsafe { - let mut data: [MaybeUninit>; STANDARD_GATE_SIZE] = MaybeUninit::uninit().assume_init(); + let mut data: [MaybeUninit>; STANDARD_GATE_SIZE] = + MaybeUninit::uninit().assume_init(); for elem in &mut data[..] { *elem = MaybeUninit::new(None); } @@ -135,9 +136,7 @@ pub fn populate_std_gate_map(py: Python, rs_gate: StandardGate, py_gate: PyObjec #[inline] pub fn get_std_gate_class(py: Python, rs_gate: StandardGate) -> PyResult { - let gate_map = unsafe { - STDGATE_PYTHON_GATES.get_or_init(py, _array_of_option_pyobject) - }; + let gate_map = unsafe { STDGATE_PYTHON_GATES.get_or_init(py, _array_of_option_pyobject) }; let gate = &gate_map[rs_gate as usize]; let populate = gate.is_none(); let out_gate = match gate { diff --git a/crates/circuit/src/operations.rs b/crates/circuit/src/operations.rs index d7b9fc8d1542..eef6ad38d212 100644 --- a/crates/circuit/src/operations.rs +++ b/crates/circuit/src/operations.rs @@ -627,28 +627,38 @@ impl Operation for StandardGate { Self::RGate => Python::with_gil(|py| -> Option { let params = params.unwrap(); let defparams = match (¶ms[0], ¶ms[1]) { - (Param::Float(theta), Param::Float(phi)) => + (Param::Float(theta), Param::Float(phi)) => [ + Param::Float(*theta), + Param::Float(*phi - 1.0), + Param::Float(-*phi + 1.0), + ], + (Param::ParameterExpression(theta), Param::ParameterExpression(phi)) => { + let thetaexpr = Param::ParameterExpression(theta.clone_ref(py)); + let phiexpr1 = phi + .call_method1(py, intern!(py, "__add__"), ((-PI / 2.0),)) + .expect("Unexpected Qiskit python bug"); + let phiexpr2 = phiexpr1 + .clone() + .call_method1(py, intern!(py, "__rmul__"), (-1.0,)) + .expect("Unexpected Qiskit python bug"); [ - Param::Float(*theta), - Param::Float(*phi - PI / 2.), - Param::Float(-*phi + PI / 2.), - ], + thetaexpr, + Param::ParameterExpression(phiexpr1), + Param::ParameterExpression(phiexpr2), + ] + } _ => todo!(), }; Some( - CircuitData::build_new_from( - py, - 1, - 0, - &[( - OperationType::Standard(Self::UGate), - &defparams, - &[0], - )], - FLOAT_ZERO, - ) - .expect("Unexpected Qiskit python bug"), + CircuitData::build_new_from( + py, + 1, + 0, + &[(OperationType::Standard(Self::UGate), &defparams, &[0])], + FLOAT_ZERO, ) + .expect("Unexpected Qiskit python bug"), + ) }), } } diff --git a/qiskit/circuit/library/standard_gates/r.py b/qiskit/circuit/library/standard_gates/r.py index 00d979480a78..98ae89d7a9bf 100644 --- a/qiskit/circuit/library/standard_gates/r.py +++ b/qiskit/circuit/library/standard_gates/r.py @@ -22,6 +22,7 @@ from qiskit.circuit.parameterexpression import ParameterValueType from qiskit._accelerate.circuit import StandardGate + class RGate(Gate): r"""Rotation θ around the cos(φ)x + sin(φ)y axis. @@ -61,8 +62,14 @@ def __init__( unit="dt", ): """Create new r single-qubit gate.""" - super().__init__("r", 1, [theta, phi], label=label, duration=duration, unit=unit, - ) + super().__init__( + "r", + 1, + [theta, phi], + label=label, + duration=duration, + unit=unit, + ) def _define(self): """