rigetti / pyquil

A Python library for quantum programming using Quil.
http://docs.rigetti.com
Apache License 2.0
1.4k stars 341 forks source link

`pyquil.paulis.PauliSum.__mul__` doesn't work with `numpy.float64` #813

Open jlbosse opened 5 years ago

jlbosse commented 5 years ago

When multiplying a PauliSum with a numpy.float64 it returns a list of terms instead of the PauliTerm.

>>> from pyquil.paulis import PauliTerm
>>> import numpy as np
>>> ham  = PauliSum([PauliTerm("I",0), PauliTerm("Z",0)])
>>> print(0.5*ham)
    (0.5+0j)*I + (0.5+0j)*Z0
>>> print(np.float64(0.5)*ham)
    [<pyquil.paulis.PauliTerm object at 0x7fa33497ce48>
     <pyquil.paulis.PauliTerm object at 0x7fa33497c208>]
notmgsk commented 5 years ago

This is an interesting issue with how python interprets multiplication (and other operations).

What is happening above is something like: Python calls np.float64(0.5).__mul__(ham), and that numpy-defined __mul__ somehow interprets ham as being a list of n Numbers, returning [np.float64(0.5) * ham[0], np.float64(0.5) * ham[1], ..., np.float64(0.5) * ham[n-1].

If you instead do ham * np.float64(0.5) you get the value you expect -- something of type PauliSum.

It's not clear to me how we should go about taking precedence over np.float64(0.5).__mul__. Maybe some python gurus can chip in -- summoning @ecp-rigetti @stevenheidel

notmgsk commented 5 years ago

Seems like class.__array_priority__ might be useful.

jlbosse commented 5 years ago

https://stackoverflow.com/questions/38229953/array-and-rmul-operator-in-python-numpy/43823885#43823885 seems to be relevant as well

notmgsk commented 5 years ago

I'm going to be that guy and say this is a wont-fix. Seems verbose and tedious to jump through numpy's hoops.

notmgsk commented 5 years ago

@stevenheidel what are your thoughts on this?