quantumlib / Cirq

A Python framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
Apache License 2.0
4.24k stars 1.01k forks source link

Replace (int, float, complex) and permutations with numbers.Number #2375

Open kevinsung opened 4 years ago

kevinsung commented 4 years ago

Instances of np.int64 are not instances of int, leading to unhandled cases. For instance,

import cirq
import numpy as np

a = np.arange(1)
print(isinstance(a[0], int))

q = cirq.LineQubit(0)
p = cirq.X(q)

print(0 * p)
print(a[0] * p)

gives

False
0j*X(0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-72d730548027> in <module>
      9 
     10 print(0 * p)
---> 11 print(a[0] * p)

TypeError: operand type(s) all returned NotImplemented from __array_ufunc__(<ufunc 'multiply'>, '__call__', 0, cirq.X.on(cirq.LineQubit(0))): 'int64', 'SingleQubitPauliStringGateOperation'
Strilanc commented 4 years ago

Urgh, this is probably all over the code base. Could you check if it's a numbers.Number? Checking for that might be the fix.

kevinsung commented 4 years ago

Indeed, it is a numbers.Number. That is the way to go then.

c-poole commented 4 years ago

In many instances it may be more appropriate to check against numbers.Integral, numbers.Real, and numbers.Complex to verify that the code will behave as expected w.r.t. integer vs. floating point arithmetic or other similar concerns.

c-poole commented 4 years ago

For the specific problem given by the example test, replacing our number checks with these other checks won't fix the problem. We also need to add cases for multiplication and for each other operation we want to support to the referenced method. Otherwise, numpy will have no idea what to do with our Cirq objects and the same error message will result. For these other operations, we will need to cast the numpy numbers into python numbers to avoid an infinite recursive loop. Adding support for numpy data types in dunder methods will have similar complexity anywhere else in the code base we want to include them. Similar complications also exists for sympy symbols that are numbers.

https://github.com/quantumlib/Cirq/blob/c572eb7fd98be8390858c0edf9a865a89e33940b/cirq/ops/pauli_string.py#L527-L531

mpharrigan commented 3 years ago

Unfortunately numpy 1.20 type hints doesn't seem to like numbers.Complex as coercible to numpy array.