Skip to content

Commit

Permalink
Force NumPy 2 legacy formatting mode for numbers
Browse files Browse the repository at this point in the history
As a consequence of [NEP
51](https://numpy.org/neps/nep-0051-scalar-representation.html#nep51),
the string representation of scalar numbers changed in NumPy 2 to
include type information. This affected printing Cirq circuit
diagrams: instead seeing numbers like 1.5, you would see
`np.float64(1.5)` and similar.

The simplest solution turned out to wrap relevant parts of the Cirq
code with the context manager form of
[`np.printoptions()`](https://numpy.org/doc/stable/reference/generated/numpy.set_printoptions.html#numpy-set-printoptions),
and use that to set legacy mode '1.25' to get the same string formats
as in NumPy 1.x.
  • Loading branch information
mhucka committed Sep 11, 2024
1 parent a5c557a commit 312b0c2
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 20 deletions.
3 changes: 2 additions & 1 deletion cirq-core/cirq/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ def _print(self, expr, **kwargs):
if hasattr(value, "__qualname__"):
return f"{value.__module__}.{value.__qualname__}"

return repr(value)
with np.printoptions(legacy='1.25'):
return repr(value)


def dataclass_repr(value: Any, namespace: str = 'cirq') -> str:
Expand Down
26 changes: 14 additions & 12 deletions cirq-core/cirq/ops/fsim_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,10 @@ def _decompose_(self, qubits) -> Iterator['cirq.OP_TREE']:
yield cirq.CZ(a, b) ** (-self.phi / np.pi)

def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs') -> Tuple[str, ...]:
t = args.format_radians(self.theta)
p = args.format_radians(self.phi)
return f'FSim({t}, {p})', f'FSim({t}, {p})'
with np.printoptions(legacy='1.25'):
t = args.format_radians(self.theta)
p = args.format_radians(self.phi)
return f'FSim({t}, {p})', f'FSim({t}, {p})'

def __pow__(self, power) -> 'FSimGate':
return FSimGate(cirq.mul(self.theta, power), cirq.mul(self.phi, power))
Expand Down Expand Up @@ -476,15 +477,16 @@ def to_exponent(angle_rads: 'cirq.TParamVal') -> 'cirq.TParamVal':
yield cirq.Z(q1) ** to_exponent(after[1])

def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs') -> Tuple[str, ...]:
theta = args.format_radians(self.theta)
zeta = args.format_radians(self.zeta)
chi = args.format_radians(self.chi)
gamma = args.format_radians(self.gamma)
phi = args.format_radians(self.phi)
return (
f'PhFSim({theta}, {zeta}, {chi}, {gamma}, {phi})',
f'PhFSim({theta}, {zeta}, {chi}, {gamma}, {phi})',
)
with np.printoptions(legacy='1.25'):
theta = args.format_radians(self.theta)
zeta = args.format_radians(self.zeta)
chi = args.format_radians(self.chi)
gamma = args.format_radians(self.gamma)
phi = args.format_radians(self.phi)
return (
f'PhFSim({theta}, {zeta}, {chi}, {gamma}, {phi})',
f'PhFSim({theta}, {zeta}, {chi}, {gamma}, {phi})',
)

def __repr__(self) -> str:
theta = proper_repr(self.theta)
Expand Down
15 changes: 8 additions & 7 deletions cirq-core/cirq/protocols/circuit_diagram_info_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,14 @@ def __repr__(self) -> str:
)

def format_real(self, val: Union[sympy.Basic, int, float]) -> str:
if isinstance(val, sympy.Basic):
return str(val)
if val == int(val):
return str(int(val))
if self.precision is None:
return str(val)
return f'{float(val):.{self.precision}}'
with np.printoptions(legacy='1.25'):
if isinstance(val, sympy.Basic):
return str(val)
if val == int(val):
return str(int(val))
if self.precision is None:
return str(val)
return f'{float(val):.{self.precision}}'

def format_complex(self, val: Union[sympy.Basic, int, float, 'cirq.TParamValComplex']) -> str:
if isinstance(val, sympy.Basic):
Expand Down

0 comments on commit 312b0c2

Please sign in to comment.