From ba1ea9a9199bc958e9803a1dfe25ee218adf6bf7 Mon Sep 17 00:00:00 2001 From: Anurudh Peduri Date: Fri, 26 Apr 2024 01:23:25 +0200 Subject: [PATCH 1/2] Fix coefficient type `GlobalPhase`, and convert from cirq correctly --- qualtran/bloqs/basic_gates/global_phase.py | 14 +++++++++++--- qualtran/cirq_interop/_cirq_to_bloq.py | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/qualtran/bloqs/basic_gates/global_phase.py b/qualtran/bloqs/basic_gates/global_phase.py index aa1d0b1fb..00d11ab78 100644 --- a/qualtran/bloqs/basic_gates/global_phase.py +++ b/qualtran/bloqs/basic_gates/global_phase.py @@ -12,10 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Union import attrs import cirq +import sympy from attrs import frozen from qualtran import bloq_example, BloqDocSpec, DecomposeTypeError @@ -35,7 +36,7 @@ class GlobalPhase(CirqGateAsBloqBase): eps: precision """ - coefficient: complex + coefficient: Union[complex, sympy.Expr] eps: float = 1e-11 @property @@ -46,7 +47,14 @@ def decompose_bloq(self) -> 'CompositeBloq': raise DecomposeTypeError(f"{self} is atomic") def adjoint(self) -> 'GlobalPhase': - return attrs.evolve(self, coefficient=complex(self.coefficient).conjugate()) + from qualtran.resource_counting.symbolic_counting_utils import is_symbolic + + coefficient = ( + sympy.conjugate(self.coefficient) + if is_symbolic(self.coefficient) + else complex(self.coefficient).conjugate() + ) + return attrs.evolve(self, coefficient=coefficient) def pretty_name(self) -> str: return 'GPhase' diff --git a/qualtran/cirq_interop/_cirq_to_bloq.py b/qualtran/cirq_interop/_cirq_to_bloq.py index 6823eb070..b199ce123 100644 --- a/qualtran/cirq_interop/_cirq_to_bloq.py +++ b/qualtran/cirq_interop/_cirq_to_bloq.py @@ -399,7 +399,7 @@ def _cirq_gate_to_bloq(gate: cirq.Gate) -> Bloq: exponent=gate.exponent, global_shift=gate.global_shift ) - if isinstance(gate, cirq.GlobalPhaseGate) and isinstance(gate.coefficient, (float, complex)): + if isinstance(gate, cirq.GlobalPhaseGate): return GlobalPhase(coefficient=gate.coefficient) # No known basic gate, wrap the cirq gate in a CirqGateAsBloq wrapper. From 5f3bf9ccc7bcc49876319bee074992a71427e510 Mon Sep 17 00:00:00 2001 From: Anurudh Peduri Date: Fri, 26 Apr 2024 19:37:10 +0200 Subject: [PATCH 2/2] add `sconj` to symbolic utils --- qualtran/bloqs/basic_gates/global_phase.py | 17 ++++++----------- .../symbolic_counting_utils.py | 8 ++++++++ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/qualtran/bloqs/basic_gates/global_phase.py b/qualtran/bloqs/basic_gates/global_phase.py index 00d11ab78..45c602b2a 100644 --- a/qualtran/bloqs/basic_gates/global_phase.py +++ b/qualtran/bloqs/basic_gates/global_phase.py @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING import attrs import cirq -import sympy from attrs import frozen from qualtran import bloq_example, BloqDocSpec, DecomposeTypeError @@ -25,6 +24,7 @@ if TYPE_CHECKING: from qualtran import CompositeBloq + from qualtran.resource_counting.symbolic_counting_utils import SymbolicComplex @frozen @@ -36,7 +36,7 @@ class GlobalPhase(CirqGateAsBloqBase): eps: precision """ - coefficient: Union[complex, sympy.Expr] + coefficient: 'SymbolicComplex' eps: float = 1e-11 @property @@ -47,14 +47,9 @@ def decompose_bloq(self) -> 'CompositeBloq': raise DecomposeTypeError(f"{self} is atomic") def adjoint(self) -> 'GlobalPhase': - from qualtran.resource_counting.symbolic_counting_utils import is_symbolic - - coefficient = ( - sympy.conjugate(self.coefficient) - if is_symbolic(self.coefficient) - else complex(self.coefficient).conjugate() - ) - return attrs.evolve(self, coefficient=coefficient) + from qualtran.resource_counting.symbolic_counting_utils import sconj + + return attrs.evolve(self, coefficient=sconj(self.coefficient)) def pretty_name(self) -> str: return 'GPhase' diff --git a/qualtran/resource_counting/symbolic_counting_utils.py b/qualtran/resource_counting/symbolic_counting_utils.py index 0ddc7d54e..f30811719 100644 --- a/qualtran/resource_counting/symbolic_counting_utils.py +++ b/qualtran/resource_counting/symbolic_counting_utils.py @@ -24,6 +24,9 @@ SymbolicInt = Union[int, sympy.Expr] document(SymbolicFloat, """A floating point value or a sympy expression.""") +SymbolicComplex = Union[complex, sympy.Expr] +document(SymbolicComplex, """A complex value or a sympy expression.""") + @frozen class Shaped: @@ -118,6 +121,11 @@ def acos(x: SymbolicFloat) -> SymbolicFloat: return sympy.acos(x) +def sconj(x: SymbolicComplex) -> SymbolicComplex: + """Compute the complex conjugate.""" + return sympy.conjugate(x) if is_symbolic(x) else np.conjugate(x) + + def slen(x: Union[Sized, Shaped]) -> SymbolicInt: if isinstance(x, Shaped): return x.shape[0]