Repository: rigetti/pyquil (python)

Issue:
DEFGATEs are not correct
There is a problem with DEFGATEs that has manifested itself in the `phase_estimation` module of Grove (brought to our attention here: https://github.com/rigetticomputing/grove/issues/145). 

I have traced the problem to commit d309ac11dabd9ea9c7ffa57dd26e68b5e7129aa9 

Each of the below test cases should deterministically return the input phase, for both `phase_estimation` and `estimate_gradient`. With this commit, result is not correct and nondeterministic for phase=3/4.

```
import numpy as np
import scipy.linalg
import pyquil.api as api
from grove.alpha.phaseestimation.phase_estimation import phase_estimation
from grove.alpha.jordan_gradient.gradient_utils import *
from grove.alpha.jordan_gradient.jordan_gradient import estimate_gradient

qvm = api.QVMConnection()
trials = 1
precision = 8
for phase in [1/2, 1/4, 3/4, 1/8, 1/16, 1/32]:

    Z = np.asarray([[1.0, 0.0], [0.0, -1.0]])
    Rz = scipy.linalg.expm(-1j*Z*np.pi*phase)

    p = phase_estimation(Rz, precision)
    out = qvm.run(p, list(range(precision)), trials)
    wf = qvm.wavefunction(p)

    bf_estimate = measurements_to_bf(out)
    bf_explicit = '{0:.16f}'.format(bf_estimate)
    deci_estimate = binary_to_real(bf_explicit)

    print('phase: ', phase)
    print('pe', deci_estimate)
    print('jg', estimate_gradient(phase, precision, n_measurements=trials, cxn=qvm))
    print('\n')
```

DEFGATEs are not correct
There is a problem with DEFGATEs that has manifested itself in the `phase_estimation` module of Grove (brought to our attention here: https://github.com/rigetticomputing/grove/issues/145). 

I have traced the problem to commit d309ac11dabd9ea9c7ffa57dd26e68b5e7129aa9 

Each of the below test cases should deterministically return the input phase, for both `phase_estimation` and `estimate_gradient`. With this commit, result is not correct and nondeterministic for phase=3/4.

```
import numpy as np
import scipy.linalg
import pyquil.api as api
from grove.alpha.phaseestimation.phase_estimation import phase_estimation
from grove.alpha.jordan_gradient.gradient_utils import *
from grove.alpha.jordan_gradient.jordan_gradient import estimate_gradient

qvm = api.QVMConnection()
trials = 1
precision = 8
for phase in [1/2, 1/4, 3/4, 1/8, 1/16, 1/32]:

    Z = np.asarray([[1.0, 0.0], [0.0, -1.0]])
    Rz = scipy.linalg.expm(-1j*Z*np.pi*phase)

    p = phase_estimation(Rz, precision)
    out = qvm.run(p, list(range(precision)), trials)
    wf = qvm.wavefunction(p)

    bf_estimate = measurements_to_bf(out)
    bf_explicit = '{0:.16f}'.format(bf_estimate)
    deci_estimate = binary_to_real(bf_explicit)

    print('phase: ', phase)
    print('pe', deci_estimate)
    print('jg', estimate_gradient(phase, precision, n_measurements=trials, cxn=qvm))
    print('\n')
```



Discussion:

Patch:
diff --git a/pyquil/parameters.py b/pyquil/parameters.py
--- a/pyquil/parameters.py
+++ b/pyquil/parameters.py
@@ -31,9 +31,11 @@ def format_parameter(element):
             out += repr(r)
 
         if i == 1:
-            out += 'i'
+            assert np.isclose(r, 0, atol=1e-14)
+            out = 'i'
         elif i == -1:
-            out += '-i'
+            assert np.isclose(r, 0, atol=1e-14)
+            out = '-i'
         elif i < 0:
             out += repr(i) + 'i'
         else:


Test patch:
diff --git a/pyquil/tests/test_parameters.py b/pyquil/tests/test_parameters.py
--- a/pyquil/tests/test_parameters.py
+++ b/pyquil/tests/test_parameters.py
@@ -14,6 +14,8 @@ def test_format_parameter():
         (1j, 'i'),
         (0 + 1j, 'i'),
         (-1j, '-i'),
+        (1e-15 + 1j, 'i'),
+        (1e-15 - 1j, '-i')
     ]
 
     for test_case in test_cases: