Repository: rigetticomputing/pyquil
Pull request #32 (2017-04-14 21:47:23)

Removes parametric programs from Paulis
  * This cleanly separates experimental from prod code
  * Decouples grove from experimental code
	(see https://github.com/rigetticomputing/grove/issues/20)




Patch:
diff --git a/pyquil/parametric.py b/pyquil/parametric.py
index 3000abe..9218df1 100644
--- a/pyquil/parametric.py
+++ b/pyquil/parametric.py
@@ -45,6 +45,8 @@ def argument_count(thing):
 
 class ParametricProgram(object):
     """
+    .. note:: Experimental
+
     A class representing Programs with changeable gate parameters.
     """
 
@@ -57,6 +59,8 @@ class ParametricProgram(object):
 
     def fuse(self, other):
         """
+        .. note:: Experimental
+
         Fuse another program to this one.
 
         :param other: A Program or ParametricProgram.
@@ -88,6 +92,8 @@ class ParametricProgram(object):
 
 def parametric(decorated_function):
     """
+    .. note:: Experimental
+
     A decorator to change a function into a ParametricProgram.
 
     :param decorated_function: The function taking parameters producing a Program object.
diff --git a/pyquil/paulis.py b/pyquil/paulis.py
index 44ef37b..8bd17cc 100644
--- a/pyquil/paulis.py
+++ b/pyquil/paulis.py
@@ -21,9 +21,8 @@ Module for working with Pauli algebras.
 from itertools import product
 import numpy as np
 import copy
+from pyquil.quil import Program
 from pyquil.gates import H, RZ, RX, CNOT, X, PHASE
-from pyquil.parametric import parametric, ParametricProgram
-import pyquil.quil as pq
 import pyquil.quilbase as pqb
 from numbers import Number
 
@@ -398,20 +397,19 @@ def exponentiate(term):
 
 def exponential_map(term):
     """
-    Creates map alpha -> exp(-1j*alpha*term) represented as a ParametricProgram.
+    Creates map alpha -> exp(-1j*alpha*term) represented as a Program.
 
     :param PauliTerm term: Tests is a PauliTerm is the identity operator
-    :returns: A ParametricProgram
-    :rtype: ParametricProgram
+    :returns: Program
+    :rtype: Program
     """
     if not np.isclose(np.imag(term.coefficient), 0.0):
         raise TypeError("PauliTerm coefficient must be real")
 
     coeff = term.coefficient
 
-    @parametric
     def exp_wrap(param):
-        prog = pq.Program()
+        prog = Program()
         if is_identity(term):
             prog.inst(X(0))
             prog.inst(PHASE(-param*coeff)(0))
@@ -444,14 +442,14 @@ def _exponentiate_general_case(pauli_term, param):
                 return (pqb.ACTION_RELEASE_QUBIT, obj)
             else:
                 return tup
-        revp = pq.Program()
+        revp = Program()
         revp.actions = map(translate, reversed(p.actions))
         return revp
 
-    quil_prog = pq.Program()
-    change_to_z_basis = pq.Program()
-    change_to_original_basis = pq.Program()
-    cnot_seq = pq.Program()
+    quil_prog = Program()
+    change_to_z_basis = Program()
+    change_to_original_basis = Program()
+    cnot_seq = Program()
     prev_index = None
     highest_target_index = None
 
@@ -565,8 +563,7 @@ def trotterize(first_pauli_term, second_pauli_term, trotter_order=1,
     commutator = (first_pauli_term * second_pauli_term) +\
                  (-1 * second_pauli_term * first_pauli_term)
 
-    prog = pq.Program()
-    fused_param_prog = ParametricProgram(lambda: pq.Program())
+    prog = Program()
     if is_zero(commutator):
         param_exp_prog_one = exponential_map(first_pauli_term)
         exp_prog = param_exp_prog_one(1)
@@ -574,19 +571,16 @@ def trotterize(first_pauli_term, second_pauli_term, trotter_order=1,
         param_exp_prog_two = exponential_map(second_pauli_term)
         exp_prog = param_exp_prog_two(1)
         prog += exp_prog
-        fused_param_prog = param_exp_prog_one.fuse(param_exp_prog_two)
-        return prog, fused_param_prog
+        return prog
 
     order_slices = suzuki_trotter(trotter_order, trotter_steps)
     for coeff, operator in order_slices:
         if operator == 0:
             param_prog = exponential_map(coeff * first_pauli_term)
             exp_prog = param_prog(1)
-            fused_param_prog = fused_param_prog.fuse(param_prog)
             prog += exp_prog
         else:
             param_prog = exponential_map(coeff * second_pauli_term)
             exp_prog = param_prog(1)
-            fused_param_prog = fused_param_prog.fuse(param_prog)
             prog += exp_prog
-    return prog, fused_param_prog
+    return prog


Test patch:
diff --git a/pyquil/tests/test_paulis.py b/pyquil/tests/test_paulis.py
index 663f35f..b04b3b7 100644
--- a/pyquil/tests/test_paulis.py
+++ b/pyquil/tests/test_paulis.py
@@ -324,30 +324,30 @@ def test_trotterize():
     with pytest.raises(ValueError):
         trotterize(term_one, term_two, trotter_order=5)
 
-    prog, _ = trotterize(term_one, term_one)
+    prog = trotterize(term_one, term_one)
     result_prog = Program().inst([H(0), RZ(2.0)(0), H(0), H(0),
                                   RZ(2.0)(0), H(0)])
     compare_progs(prog, result_prog)
 
     # trotter_order 1 steps 1
-    prog, _ = trotterize(term_one, term_two, trotter_steps=1)
+    prog = trotterize(term_one, term_two, trotter_steps=1)
     result_prog = Program().inst([H(0), RZ(2.0)(0), H(0), RZ(2.0)(0)])
     compare_progs(prog, result_prog)
 
     # trotter_order 1 steps 2
-    prog, _ = trotterize(term_one, term_two, trotter_steps=2)
+    prog  = trotterize(term_one, term_two, trotter_steps=2)
     result_prog = Program().inst([H(0), RZ(1.0)(0), H(0), RZ(1.0)(0),
                                   H(0), RZ(1.0)(0), H(0), RZ(1.0)(0)])
     compare_progs(prog, result_prog)
 
     # trotter_order 2 steps 1
-    prog, _ = trotterize(term_one, term_two, trotter_order=2)
+    prog  = trotterize(term_one, term_two, trotter_order=2)
     result_prog = Program().inst([H(0), RZ(1.0)(0), H(0), RZ(2.0)(0),
                                   H(0), RZ(1.0)(0), H(0)])
     compare_progs(prog, result_prog)
 
     # trotter_order 2 steps 2
-    prog, _ = trotterize(term_one, term_two, trotter_order=2, trotter_steps=2)
+    prog = trotterize(term_one, term_two, trotter_order=2, trotter_steps=2)
     result_prog = Program().inst([H(0), RZ(0.5)(0), H(0), RZ(1.0)(0),
                                   H(0), RZ(0.5)(0), H(0),
                                   H(0), RZ(0.5)(0), H(0), RZ(1.0)(0),
@@ -355,7 +355,7 @@ def test_trotterize():
     compare_progs(prog, result_prog)
 
     # trotter_order 3 steps 1
-    prog, _ = trotterize(term_one, term_two, trotter_order=3, trotter_steps=1)
+    prog = trotterize(term_one, term_two, trotter_order=3, trotter_steps=1)
     result_prog = Program().inst([H(0), RZ(14.0 / 24)(0), H(0), RZ(4.0 / 3.0)(0),
                                   H(0), RZ(1.5)(0), H(0), RZ(-4.0 / 3.0)(0),
                                   H(0), RZ(-2.0 / 24)(0), H(0), RZ(2.0)(0)])