Skip to content

Commit

Permalink
added call to cmeasure_control finalize method
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesB-1qbit committed Nov 20, 2023
1 parent eabaaa9 commit 2ac99db
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 5 deletions.
7 changes: 6 additions & 1 deletion tangelo/linq/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def __init__(self, gates: List[Gate] = None, n_qubits=None, name="no_name", cmea
self._n_qubit_gate_counts: Dict[int, int] = dict()
self._variational_gates: List[Gate] = []
self._probabilities: Dict[str, float] = dict()
self._cmeasure_control: Callable = cmeasure_control
self._cmeasure_control: Union[Callable, ClassicalControl, None] = cmeasure_control
self._applied_gates: List[Gate] = []

if gates:
Expand Down Expand Up @@ -415,6 +415,11 @@ def controlled_measurement_op(self, measure):
elif isinstance(self._cmeasure_control, ClassicalControl):
return Circuit(self._cmeasure_control.return_circuit(measure), n_qubits=self.width)

def finalize_cmeasure_control(self):
"""Call the finalize method in cmeasure_control"""
if isinstance(self._cmeasure_control, ClassicalControl):
self._cmeasure_control.finalize()


def stack(*circuits):
""" Take list of circuits as input, and stack them (e.g concatenate them along the
Expand Down
4 changes: 4 additions & 0 deletions tangelo/linq/target/target_cirq.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ def simulate_circuit(self, source_circuit: Circuit, return_statevector=False, in
isamples = self.cirq.sample_state_vector(self._current_state, indices, repetitions=1)
bitstr = measurements + "".join([str(int(q)) for q in isamples[0]])
samples[bitstr] = samples.get(bitstr, 0) + 1

# Call the finalize method of ClassicalControl, used to reset variables, perform computation etc.
source_circuit.finalize_cmeasure_control()

if self.n_shots:
self.all_frequencies = {k: v / self.n_shots for k, v in samples.items()}
frequencies = {k[:]: v / self.n_shots for k, v in samples.items()}
Expand Down
4 changes: 4 additions & 0 deletions tangelo/linq/target/target_qulacs.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ def simulate_circuit(self, source_circuit: Circuit, return_statevector=False, in
else:
bitstr = self._int_to_binstr(state.sampling(1)[0], source_circuit.width)
samples[measurements+bitstr] = samples.get(measurements+bitstr, 0) + 1

# Call the finalize method of ClassicalControl, used to reset variables, perform computation etc.
source_circuit.finalize_cmeasure_control()

if self.n_shots:
self.all_frequencies = {k: v / self.n_shots for k, v in samples.items()}
frequencies = {k: v / self.n_shots for k, v in samples.items()}
Expand Down
20 changes: 16 additions & 4 deletions tangelo/linq/tests/test_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,18 +711,24 @@ def test_measurement_controlled_gates_class(self):

for backend in installed_cmeasure_simulators:

sim = get_backend(backend, n_shots=1)
sim = get_backend(backend, n_shots=2)

# Unitary has eigenvalue (1/16+1/8+1/4+1/2)*pi with eigenvector |1> on qubit 1.
ugate = Gate("CPHASE", 1, control=0, parameter=np.pi/16+np.pi/8+np.pi/4+np.pi/2)
# Unitary has eigenvalue (1/16+1/8+1/2)*pi with eigenvector |1> on qubit 1.
# Measurement will be 0011010 = 0/64+0/32+1/16+1/8+0/4+1/2+0
ugate = Gate("CPHASE", 1, control=0, parameter=np.pi/16+np.pi/8+np.pi/2)

class IterativeQPE(ClassicalControl):
def __init__(self, bits):
self.bits = bits
self.bitplace = bits*1
self.phase = 0
self.measurements = [""]
self.energies = [0.]
self.n_runs = 0

def return_circuit(self, measurement) -> List[Gate]:
self.measurements[self.n_runs] += measurement
self.energies[self.n_runs] += int(measurement)/2**self.bitplace
if self.bitplace > 0:
self.bitplace -= 1
self.correction = [Gate("PHASE", 0, parameter=-2*np.pi*self.phase*2**(self.bitplace+1))]
Expand All @@ -739,6 +745,9 @@ def return_circuit(self, measurement) -> List[Gate]:
def finalize(self):
self.bitplace = self.bits*1
self.phase = 0
self.n_runs += 1
self.measurements += [""]
self.energies += [0.]

bits = 6
cfunc = IterativeQPE(bits)
Expand All @@ -747,7 +756,10 @@ def finalize(self):
f, _ = sim.simulate(circuit, save_mid_circuit_meas=True)

assert_freq_dict_almost_equal(f, {"01": 1}, 1.e-7)
assert_freq_dict_almost_equal(circuit.success_probabilities, {"0011110": 1}, 1.e-7)
assert_freq_dict_almost_equal(circuit.success_probabilities, {"0011010": 1}, 1.e-7)
self.assertEqual(cfunc.measurements, ["0011010", "0011010", ""])
energy = 1/16+1/8+1/2
np.testing.assert_array_almost_equal(cfunc.energies, [energy, energy, 0.])


if __name__ == "__main__":
Expand Down

0 comments on commit 2ac99db

Please sign in to comment.