def test_simulator_cheat(sim): # cheat function should return a tuple assert isinstance(sim.cheat(), tuple) # first entry is the qubit mapping. # should be empty: assert len(sim.cheat()[0]) == 0 np = MPI.COMM_WORLD.Get_size() # state vector should only have np entries: assert len(sim.cheat()[1]) == np eng = HiQMainEngine(sim, [GreedyScheduler()]) qubit = eng.allocate_qubit() # one qubit has been allocated assert len(sim.cheat()[0]) == 1 assert sim.cheat()[0][0] == 0 assert len(sim.cheat()[1]) == 2 * np assert 1. == pytest.approx(abs(sim.cheat()[1][0])) qubit[0].__del__() eng.flush() # should be empty: assert len(sim.cheat()[0]) == 0 # state vector should only have np entries: assert len(sim.cheat()[1]) == np
def test_simulator_collapse_wavefunction(sim, mapper): engine_list = [LocalOptimizer()] if mapper is not None: engine_list.append(mapper) engine_list.append(GreedyScheduler()) eng = HiQMainEngine(sim, engine_list=engine_list) qubits = eng.allocate_qureg(4) # unknown qubits: raises with pytest.raises(RuntimeError): eng.backend.collapse_wavefunction(qubits, [0] * 4) eng.flush() eng.backend.collapse_wavefunction(qubits, [0] * 4) assert pytest.approx(eng.backend.get_probability([0] * 4, qubits)) == 1. All(H) | qubits[1:] eng.flush() assert pytest.approx(eng.backend.get_probability([0] * 4, qubits)) == .125 # impossible outcome: raises with pytest.raises(RuntimeError): eng.backend.collapse_wavefunction(qubits, [1] + [0] * 3) eng.backend.collapse_wavefunction(qubits[:-1], [0, 1, 0]) probability = eng.backend.get_probability([0, 1, 0, 1], qubits) assert probability == pytest.approx(.5) # reinitialize qubits All(Measure) | qubits del qubits qubits = eng.allocate_qureg(4) H | qubits[0] CNOT | (qubits[0], qubits[1]) eng.flush() eng.backend.collapse_wavefunction([qubits[0]], [1]) probability = eng.backend.get_probability([1, 1], qubits[0:2]) assert probability == pytest.approx(1.)
def test_simulator_probability(sim, mapper): engine_list = [LocalOptimizer()] if mapper is not None: engine_list.append(mapper) engine_list.append(GreedyScheduler()) eng = HiQMainEngine(sim, engine_list=engine_list) qubits = eng.allocate_qureg(6) All(H) | qubits eng.flush() bits = [0, 0, 1, 0, 1, 0] for i in range(6): assert (eng.backend.get_probability( bits[:i], qubits[:i]) == pytest.approx(0.5**i)) extra_qubit = eng.allocate_qubit() with pytest.raises(RuntimeError): eng.backend.get_probability([0], extra_qubit) del extra_qubit All(H) | qubits Ry(2 * math.acos(math.sqrt(0.3))) | qubits[0] eng.flush() assert eng.backend.get_probability([0], [qubits[0]]) == pytest.approx(0.3) Ry(2 * math.acos(math.sqrt(0.4))) | qubits[2] eng.flush() assert eng.backend.get_probability([0], [qubits[2]]) == pytest.approx(0.4) assert (eng.backend.get_probability([0, 0], qubits[:3:2]) == pytest.approx(0.12)) assert (eng.backend.get_probability([0, 1], qubits[:3:2]) == pytest.approx(0.18)) assert (eng.backend.get_probability([1, 0], qubits[:3:2]) == pytest.approx(0.28)) All(Measure) | qubits
def test_simulator_no_uncompute_exception(sim): eng = HiQMainEngine(sim, [GreedyScheduler()]) qubit = eng.allocate_qubit() H | qubit with pytest.raises(RuntimeError): qubit[0].__del__() eng.flush() # If you wanted to keep using the qubit, you shouldn't have deleted it. assert qubit[0].id == -1
def test_simulator_functional_entangle(sim): eng = HiQMainEngine(sim, [GreedyScheduler()]) qubits = eng.allocate_qureg(5) # entangle all qubits: H | qubits[0] for qb in qubits[1:]: CNOT | (qubits[0], qb) eng.flush() id2pos, vec = sim.cheat() # check the state vector: assert .5 == pytest.approx(abs(vec[0])**2) # amplitudes 00000 and 11111 assert .5 == pytest.approx(abs( vec[31])**2) # are never moved even if qubit reordering made for i in range(1, 31): assert 0. == pytest.approx(abs(vec[i])) # unentangle all except the first 2 for qb in qubits[2:]: CNOT | (qubits[0], qb) # entangle using Toffolis for qb in qubits[2:]: Toffoli | (qubits[0], qubits[1], qb) eng.flush() # check the state vector: id2pos, vec = sim.cheat() assert .5 == pytest.approx(abs(vec[0])**2) assert .5 == pytest.approx(abs(vec[31])**2) for i in range(1, 31): assert 0. == pytest.approx(abs(vec[i])) # uncompute using multi-controlled NOTs with Control(eng, qubits[0:-1]): X | qubits[-1] with Control(eng, qubits[0:-2]): X | qubits[-2] with Control(eng, qubits[0:-3]): X | qubits[-3] CNOT | (qubits[0], qubits[1]) H | qubits[0] eng.flush() id2pos, vec = sim.cheat() # check the state vector: assert 1. == pytest.approx(abs(vec[0])**2) for i in range(1, 32): assert 0. == pytest.approx(abs(vec[i])) All(Measure) | qubits
def test_simulator_functional_measurement(sim): eng = HiQMainEngine(sim, [GreedyScheduler()]) qubits = eng.allocate_qureg(5) # entangle all qubits: H | qubits[0] for qb in qubits[1:]: CNOT | (qubits[0], qb) All(Measure) | qubits bit_value_sum = sum([int(qubit) for qubit in qubits]) assert bit_value_sum == 0 or bit_value_sum == 5
def test_simulator_convert_logical_to_mapped_qubits(sim): mapper = BasicMapperEngine() def receive(command_list): pass mapper.receive = receive eng = HiQMainEngine(sim, [mapper, GreedyScheduler()]) qubit0 = eng.allocate_qubit() qubit1 = eng.allocate_qubit() mapper.current_mapping = { qubit0[0].id: qubit1[0].id, qubit1[0].id: qubit0[0].id } assert (sim._convert_logical_to_mapped_qureg(qubit0 + qubit1) == qubit1 + qubit0)
def test_simulator_kqubit_exception(sim): m1 = Rx(0.3).matrix m2 = Rx(0.8).matrix m3 = Ry(0.1).matrix m4 = Rz(0.9).matrix.dot(Ry(-0.1).matrix) m = numpy.kron(m4, numpy.kron(m3, numpy.kron(m2, m1))) class KQubitGate(BasicGate): @property def matrix(self): return m eng = HiQMainEngine(sim, [GreedyScheduler()]) qureg = eng.allocate_qureg(3) with pytest.raises(Exception): KQubitGate() | qureg eng.flush() with pytest.raises(Exception): H | qureg eng.flush()
def test_simulator_measure_mapped_qubit(sim): eng = HiQMainEngine(sim, [GreedyScheduler()]) qb1 = WeakQubitRef(engine=eng, idx=1) qb2 = WeakQubitRef(engine=eng, idx=2) cmd0 = Command(engine=eng, gate=Allocate, qubits=([qb1], )) cmd1 = Command(engine=eng, gate=X, qubits=([qb1], )) cmd2 = Command(engine=eng, gate=Measure, qubits=([qb1], ), controls=[], tags=[LogicalQubitIDTag(2)]) with pytest.raises(NotYetMeasuredError): int(qb1) with pytest.raises(NotYetMeasuredError): int(qb2) eng.send([cmd0, cmd1, cmd2]) eng.flush() with pytest.raises(NotYetMeasuredError): int(qb1) assert int(qb2) == 1
def test_simulator_amplitude(sim, mapper): engine_list = [LocalOptimizer()] if mapper is not None: engine_list.append(mapper) engine_list.append(GreedyScheduler()) eng = HiQMainEngine(sim, engine_list=engine_list) qubits = eng.allocate_qureg(6) All(X) | qubits All(H) | qubits eng.flush() bits = [0, 0, 1, 0, 1, 0] assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(1. / 8.) bits = [0, 0, 0, 0, 1, 0] assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(-1. / 8.) bits = [0, 1, 1, 0, 1, 0] assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(-1. / 8.) All(H) | qubits All(X) | qubits Ry(2 * math.acos(0.3)) | qubits[0] eng.flush() bits = [0] * 6 assert eng.backend.get_amplitude(bits, qubits) == pytest.approx(0.3) bits[0] = 1 assert (eng.backend.get_amplitude(bits, qubits) == pytest.approx( math.sqrt(0.91))) All(Measure) | qubits # raises if not all qubits are in the list: with pytest.raises(RuntimeError): eng.backend.get_amplitude(bits, qubits[:-1]) # doesn't just check for length: with pytest.raises(RuntimeError): eng.backend.get_amplitude(bits, qubits[:-1] + [qubits[0]]) extra_qubit = eng.allocate_qubit() eng.flush() # there is a new qubit now! with pytest.raises(RuntimeError): eng.backend.get_amplitude(bits, qubits)
def test_simulator_kqubit_gate(sim): m1 = Rx(0.3).matrix m2 = Rx(0.8).matrix m3 = Ry(0.1).matrix m4 = Rz(0.9).matrix.dot(Ry(-0.1).matrix) m = numpy.kron(m4, numpy.kron(m3, numpy.kron(m2, m1))) class KQubitGate(BasicGate): @property def matrix(self): return m eng = HiQMainEngine(sim, [GreedyScheduler()]) qureg = eng.allocate_qureg(4) qubit = eng.allocate_qubit() Rx(-0.3) | qureg[0] Rx(-0.8) | qureg[1] Ry(-0.1) | qureg[2] Rz(-0.9) | qureg[3] Ry(0.1) | qureg[3] X | qubit with Control(eng, qubit): KQubitGate() | qureg X | qubit with Control(eng, qubit): with Dagger(eng): KQubitGate() | qureg assert sim.get_amplitude('0' * 5, qubit + qureg) == pytest.approx(1.) class LargerGate(BasicGate): @property def matrix(self): return numpy.eye(2**6) with pytest.raises(Exception): LargerGate() | (qureg + qubit) eng.flush()
# backend = CircuitDrawer() # locations = {} # for i in range(module.nqubits): # locations[i] = i # backend.set_qubit_locations(locations) cache_depth = 10 rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions]) engines = [ TagRemover(), LocalOptimizer(cache_depth), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(cache_depth), #,CommandPrinter(), GreedyScheduler() ] eng = HiQMainEngine(backend, engines) dataset = [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0] if not _is_power2(len(dataset)): raise ValueError("The size of the dataset must be a power of 2!") # choose the first element in Dataset to be the threshold: print( "=======================================================================" ) print("= This is the Unknown Number Gover Search algorithm demo") print("= The algorithm searches for one marked element in a given set") print("= There may be many marked element")
if __name__ == "__main__": # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), InstructionFilter(high_level_gates), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), GreedyScheduler(), resource_counter ] # make the compiler and run the circuit on the simulator backend eng = HiQMainEngine(SimulatorMPI(gate_fusion=True, num_local_qubits=20), compilerengines) N = 0 if MPI.COMM_WORLD.Get_rank() == 0: # print welcome message and ask the user for the number to factor print( "\n\t\033[37mH\033[91mI\033[37mQ\033[91m>\033[0m\n\t--------\n\tImplementation of Shor" "\'s algorithm.", end="") N = int(input('\n\tNumber to factor: ')) print("")