Skip to content

Instantly share code, notes, and snippets.

@WrathfulSpatula
Created January 25, 2019 16:03
Show Gist options
  • Save WrathfulSpatula/6cbde1a428b0fa554f4af6f26e8b97a8 to your computer and use it in GitHub Desktop.
Save WrathfulSpatula/6cbde1a428b0fa554f4af6f26e8b97a8 to your computer and use it in GitHub Desktop.
Demonstration of control bit ordering side effect in ProjectQ
import pytest
import projectq
from projectq import MainEngine
from projectq.backends import Simulator
from projectq.cengines import (AutoReplacer, DecompositionRuleSet, DummyEngine,
InstructionFilter)
from projectq.meta import Compute, Control, Uncompute
from projectq.ops import (All, Measure, Ry, Rz, UniformlyControlledRy,
UniformlyControlledRz, X)
import projectq.setups.decompositions.uniformlycontrolledr2cnot as ucr2cnot
def slow_implementation(angles, control_qubits, target_qubit, eng, gate_class):
"""
Assumption is that control_qubits[0] is lowest order bit
We apply angles[0] to state |0>
"""
assert len(angles) == 2**len(control_qubits)
for index in range(2**len(control_qubits)):
with Compute(eng):
for bit_pos in range(len(control_qubits)):
if not (index >> bit_pos) & 1:
X | control_qubits[bit_pos]
with Control(eng, control_qubits):
gate_class(angles[index]) | target_qubit
Uncompute(eng)
def test_uniformly_controlled_ry():
n = 2
random_angles = [3.0, 0.8, 1.2, 0.7]
basis_state_index = 1
basis_state = [0] * 2**(n+1)
basis_state[basis_state_index] = 1.
correct_dummy_eng = DummyEngine(save_commands=True)
correct_eng = MainEngine(backend=Simulator(),
engine_list=[correct_dummy_eng])
test_dummy_eng = DummyEngine(save_commands=True)
test_eng = MainEngine(backend=Simulator(),
engine_list=[test_dummy_eng])
correct_sim = correct_eng.backend
correct_qb = correct_eng.allocate_qubit()
correct_ctrl_qureg = correct_eng.allocate_qureg(n)
correct_eng.flush()
test_sim = test_eng.backend
test_qb = test_eng.allocate_qubit()
test_ctrl_qureg = test_eng.allocate_qureg(n)
test_eng.flush()
correct_sim.set_wavefunction(basis_state, correct_qb + correct_ctrl_qureg)
test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qureg)
# ****************** THIS IS THE CRUX OF THE WHOLE ISSUE: *************************
# Because of the list reversal in this call, this test should fail, but it doesn't:
# *********************************************************************************
slow_implementation(angles=random_angles,
control_qubits=list(reversed(test_ctrl_qureg)),
target_qubit=test_qb,
eng=test_eng,
gate_class=Ry)
slow_implementation(angles=random_angles,
control_qubits=correct_ctrl_qureg,
target_qubit=correct_qb,
eng=correct_eng,
gate_class=Ry)
test_eng.flush()
correct_eng.flush()
for fstate in range(2**(n+1)):
binary_state = format(fstate, '0' + str(n+1) + 'b')
test = test_sim.get_amplitude(binary_state,
test_qb + test_ctrl_qureg)
correct = correct_sim.get_amplitude(binary_state, correct_qb +
correct_ctrl_qureg)
print(test, "==", correct)
assert correct == pytest.approx(test, rel=1e-10, abs=1e-10)
All(Measure) | test_qb + test_ctrl_qureg
All(Measure) | correct_qb + correct_ctrl_qureg
test_eng.flush(deallocate_qubits=True)
correct_eng.flush(deallocate_qubits=True)
# Passes:
test_uniformly_controlled_ry()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment