Example #1
0
def test_phase_majority():
    sim = Simulator()
    main_engine = MainEngine(sim)

    qureg = main_engine.allocate_qureg(3)
    All(H) | qureg
    PhaseOracle(0xe8) | qureg

    main_engine.flush()

    assert np.array_equal(np.sign(sim.cheat()[1]),
                          [1., 1., 1., -1., 1., -1., -1., -1.])
    All(Measure) | qureg
def test_local_optimizer_flush_gate():
    local_optimizer = _optimize.LocalOptimizer(m=4)
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend, engine_list=[local_optimizer])
    # Test that it caches for each qubit 3 gates
    qb0 = eng.allocate_qubit()
    qb1 = eng.allocate_qubit()
    H | qb0
    H | qb1
    assert len(backend.received_commands) == 0
    eng.flush()
    # Two allocate gates, two H gates and one flush gate
    assert len(backend.received_commands) == 5
Example #3
0
 def get_state(self, circuit: Circuit, fit_to_constraints=True) -> list:
     c = circuit.copy()
     if fit_to_constraints:
         Transform.RebaseToProjectQ().apply(c)
     fwd = ForwarderEngine(self._backend)
     eng = MainEngine(backend=self._backend, engine_list=[fwd])
     qureg = eng.allocate_qureg(c.n_qubits)
     tk_to_projectq(eng, qureg, c)
     eng.flush()
     state = self._backend.cheat(
     )[1]  #`cheat()` returns tuple:(a dictionary of qubit indices, statevector)
     All(Measure) | qureg
     return state  #list of complex numbers
Example #4
0
def test_high_level_gate_set():
    mod_list = projectq.setups.ibm16.get_engine_list()
    saving_engine = DummyEngine(save_commands=True)
    mod_list = mod_list[:6] + [saving_engine] + mod_list[6:]
    eng = MainEngine(DummyEngine(), engine_list=mod_list)
    qureg = eng.allocate_qureg(3)
    AddConstant(3) | qureg
    QFT | qureg
    eng.flush()
    received_gates = [cmd.gate for cmd in saving_engine.received_commands]
    assert sum([1 for g in received_gates if g == QFT]) == 1
    assert get_inverse(QFT) not in received_gates
    assert AddConstant(3) not in received_gates
Example #5
0
def test_ibmcnotmapper_invalid_circuit():
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend,
                     engine_list=[_ibmcnotmapper.IBMCNOTMapper()])
    qb0 = eng.allocate_qubit()
    qb1 = eng.allocate_qubit()
    qb2 = eng.allocate_qubit()
    qb3 = eng.allocate_qubit()
    CNOT | (qb1, qb2)
    CNOT | (qb0, qb1)
    with pytest.raises(Exception):
        CNOT | (qb3, qb2)
        eng.flush()
Example #6
0
def test_auto_replacer_default_chooser(fixture_gate_filter):
    # Test that default decomposition_chooser takes always first rule.
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(
        backend=backend,
        engine_list=[_replacer.AutoReplacer(rule_set), fixture_gate_filter])
    assert len(rule_set.decompositions[TestGate.__class__.__name__]) == 2
    assert len(backend.received_commands) == 0
    qb = eng.allocate_qubit()
    TestGate | qb
    eng.flush()
    assert len(backend.received_commands) == 3
    assert backend.received_commands[1].gate == X
def test_local_optimizer_mergeable_gates():
    local_optimizer = _optimize.LocalOptimizer(m=4)
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend, engine_list=[local_optimizer])
    # Test that it merges mergeable gates such as Rx
    qb0 = eng.allocate_qubit()
    for _ in range(10):
        Rx(0.5) | qb0
    assert len(backend.received_commands) == 0
    eng.flush()
    # Expect allocate, one Rx gate, and flush gate
    assert len(backend.received_commands) == 3
    assert backend.received_commands[1].gate == Rx(10 * 0.5)
Example #8
0
def test_recognize_correct_gates():
    """Test that recognize_RzNoCtrl recognizes ctrl qubits"""
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend)
    qubit = eng.allocate_qubit()
    ctrl_qubit = eng.allocate_qubit()
    eng.flush()
    Rz(0.3) | qubit
    with Control(eng, ctrl_qubit):
        Rz(0.4) | qubit
    eng.flush(deallocate_qubits=True)
    assert rz2rx._recognize_RzNoCtrl(saving_backend.received_commands[3])
    assert not rz2rx._recognize_RzNoCtrl(saving_backend.received_commands[4])
Example #9
0
def test_simulator_send():
    sim = Simulator()
    backend = DummyEngine(save_commands=True)

    eng = MainEngine(backend, [sim])

    qubit = eng.allocate_qubit()
    H | qubit
    Measure | qubit
    del qubit
    eng.flush()

    assert len(backend.received_commands) == 5
Example #10
0
def test_auto_replacer_priorize_controlstate_rule():
    # Check that when a control state is given and it has negative control,
    # Autoreplacer prioritizes the corresponding decomposition rule before anything else.
    # (Decomposition rule should have name _decompose_controlstate)

    # Create test gate and inverse
    class ControlGate(BasicGate):
        pass

    def _decompose_controlstate(cmd):
        S | cmd.qubits

    def _decompose_random(cmd):
        H | cmd.qubits

    def control_filter(self, cmd):
        if cmd.gate == ControlGate():
            return False
        return True

    rule_set.add_decomposition_rule(
        DecompositionRule(BasicGate, _decompose_random))

    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend,
                     engine_list=[
                         _replacer.AutoReplacer(rule_set),
                         _replacer.InstructionFilter(control_filter)
                     ])
    assert len(backend.received_commands) == 0
    qb = eng.allocate_qubit()
    ControlGate() | qb
    eng.flush()
    assert len(backend.received_commands) == 3
    assert backend.received_commands[1].gate == H

    rule_set.add_decomposition_rule(
        DecompositionRule(BasicGate, _decompose_controlstate))

    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend,
                     engine_list=[
                         _replacer.AutoReplacer(rule_set),
                         _replacer.InstructionFilter(control_filter)
                     ])
    assert len(backend.received_commands) == 0
    qb = eng.allocate_qubit()
    ControlGate() | qb
    eng.flush()
    assert len(backend.received_commands) == 3
    assert backend.received_commands[1].gate == S
Example #11
0
def subproblem4():
    eng = MainEngine()
    qubits = eng.allocate_qureg(3)
    # You should add quantum operations here to change the state of qubits into |101>+|010>
    H | qubits[1]

    CX | (qubits[1], qubits[0])
    CX | (qubits[1], qubits[2])

    eng.flush()
    amplitudes = np.array(eng.backend.cheat()[1])
    All(Measure) | qubits
    print("p4:{}".format(amplitudes))
    return amplitudes
Example #12
0
    def run_test(self, description, iterations, prep_function):
        """
        Runs a unit test of the teleportation protocol with the provided state preparation function.

        Parameters:
            description (str): A description of the test, for logging.
            iterations (int): The number of times to run the program.
            prep_function (function): The function that can prepare (and un-prepare) the desired state
                to be teleported.
        """
        
        print(f"Running test: {description}")
        
        engine = MainEngine()
        original_qubit = engine.allocate_qubit()
        transfer_qubit = engine.allocate_qubit()
        reproduction_qubit = engine.allocate_qubit()

        # Try teleportation using all 4 of the Bell states for the entangled transfer qubit pair
        for entanglement_state in range(0, 4):
            for i in range(0, iterations):

                # Prepare the original qubit in the desired state, and the transfer qubits that will be used to teleport it
                prep_function(original_qubit)
                self.prepare_transfer_qubits(entanglement_state, transfer_qubit, reproduction_qubit)

                # Teleport the original qubit, turning the remote reproduction qubit's state into the original state 
                (original_measurement, transfer_measurement) = self.measure_message_parameters(original_qubit, transfer_qubit)
                self.reproduce_original(entanglement_state, original_measurement, transfer_measurement, reproduction_qubit)

                # Run the adjoint preparation function on the reproduction qubit, and measure it.
                # If it is now in the original state, this should turn it back into |0> every time.
                with Dagger(engine):
                    prep_function(reproduction_qubit)
                    
                # Make sure the result qubit is 0
                Measure | reproduction_qubit

                if int(reproduction_qubit) != 0:
                    self.fail(f"Test {description} failed with entanglement state {entanglement_state}. " +
                            f"Resulting state {result} had a 1 for the result, which means " +
                            "the qubit wasn't teleported properly.")

                reset([original_qubit, transfer_qubit, reproduction_qubit])
                engine.flush()

            print(f"Entanglement state {entanglement_state} passed.");
        
        print("Passed!")
        print()
Example #13
0
def test_ibm_backend_functional_test(monkeypatch):
    correct_info = ('{"qasms": [{"qasm": "\\ninclude \\"'
                    'qelib1.inc\\";\\nqreg q[3];\\ncreg c[3];\\nh q[0];\\ncx'
                    ' q[0], q[2];\\ncx q[0], q[1];\\ntdg q[0];\\nsdg q[0];\\'
                    'nbarrier q[0], q[2], q[1];\\nu3(0.2, -pi/2, pi/2) q[0];'
                    '\\nmeasure q[0] -> c[0];\\nmeasure q[2] -> c[2];\\nmeas'
                    'ure q[1] -> c[1];"}], "shots": 1024, "maxCredits": 5,'
                    ' "backend": {"name": "simulator"}}')

    # patch send
    def mock_send(*args, **kwargs):
        assert json.loads(args[0]) == json.loads(correct_info)
        return {'date': '2017-01-19T14:28:47.622Z',
                'data': {'time': 14.429004907608032, 'counts': {'00111': 396,
                                                                '00101': 27,
                                                                '00000': 601},
                         'qasm': ('...')}}
    monkeypatch.setattr(_ibm, "send", mock_send)

    backend = _ibm.IBMBackend(verbose=True)
    # no circuit has been executed -> raises exception
    with pytest.raises(RuntimeError):
        backend.get_probabilities([])
    rule_set = DecompositionRuleSet(modules=[projectq.setups.decompositions])
    engine_list = [TagRemover(),
                   LocalOptimizer(10),
                   AutoReplacer(rule_set),
                   TagRemover(),
                   IBMCNOTMapper(),
                   LocalOptimizer(10)]
    eng = MainEngine(backend=backend, engine_list=engine_list)
    unused_qubit = eng.allocate_qubit()
    qureg = eng.allocate_qureg(3)
    # entangle the qureg
    Entangle | qureg
    Tdag | qureg[0]
    Sdag | qureg[0]
    Barrier | qureg
    Rx(0.2) | qureg[0]
    del unused_qubit
    # measure; should be all-0 or all-1
    Measure | qureg
    # run the circuit
    eng.flush()
    prob_dict = eng.backend.get_probabilities([qureg[0], qureg[2], qureg[1]])
    assert prob_dict['111'] == pytest.approx(0.38671875)
    assert prob_dict['101'] == pytest.approx(0.0263671875)

    with pytest.raises(RuntimeError):
        eng.backend.get_probabilities(eng.allocate_qubit())
Example #14
0
def MUL_resources(number_of_bits = 16):
    print('getting costs of ' + str(number_of_bits) + ' unsigned multiplication...')
    #___________________initial__________________
    resource_counter = ResourceCounter()
    eng = MainEngine(resource_counter)
    a = [0 for i in range(number_of_bits)]
    b = [0 for i in range(number_of_bits)]
    n = len(a)
    z = list_to_reg([0 for _ in range(2*n)],eng)
    a = list_to_reg( a, eng) #one extra bit (in most significant) needed for addition
    b = list_to_reg(b, eng)
    fixed_MUL(a,b,z, eng = eng)
    eng.flush()
    print(resource_counter)
Example #15
0
def CRightShift_resources(k):
    #___________________initial__________________
    resource_counter = ResourceCounter()
    eng = MainEngine(resource_counter)
    control = list_to_reg([0],eng)
    m = k #case when mantissa is 13 bits
    x = list_to_reg([0 for i in range(m)],eng)
    x = x[::-1]#for right swap
    print('Getting resources for ' + str(len(x)) + ' controlled shift by 1 circuit.')
    for i in range(0,m-1): C(Swap,1)|(control,x[i],x[i+1] )
    Measure | control
    Measure | x #for tex purposes
    eng.flush()
    print(resource_counter)
Example #16
0
def test_simulator_functional_measurement():
    sim = StabilizerSimulator(5)
    eng = MainEngine(sim, [])
    qubits = eng.allocate_qureg(5)
    # entangle all qubits:
    H | qubits[0]
    for qb in qubits[1:]:
        CNOT | (qubits[0], qb)

    All(Measure) | qubits
    eng.flush()

    bit_value_sum = sum([int(qubit) for qubit in qubits])
    assert bit_value_sum == 0 or bit_value_sum == 5
def test_recognize():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend, engine_list=[])
    ctrl_qureg = eng.allocate_qureg(2)
    qureg = eng.allocate_qureg(2)
    with Control(eng, ctrl_qureg):
        QubitOperator("X0 Y1") | qureg
    with Control(eng, ctrl_qureg[0]):
        QubitOperator("X0 Y1") | qureg
    eng.flush()
    cmd0 = saving_backend.received_commands[4]
    cmd1 = saving_backend.received_commands[5]
    assert not qubitop2onequbit._recognize_qubitop(cmd0)
    assert qubitop2onequbit._recognize_qubitop(cmd1)
Example #18
0
def test_simulator_time_evolution(sim):
    N = 9  # number of qubits
    time_to_evolve = 1.1  # time to evolve for
    eng = MainEngine(sim, [])
    qureg = eng.allocate_qureg(N)
    # initialize in random wavefunction by applying some gates:
    for qb in qureg:
        Rx(random.random()) | qb
        Ry(random.random()) | qb
    eng.flush()
    # Use cheat to get initial start wavefunction:
    qubit_to_bit_map, init_wavefunction = copy.deepcopy(eng.backend.cheat())
    Qop = QubitOperator
    op = 0.3 * Qop("X0 Y1 Z2 Y3 X4")
    op += 1.1 * Qop(())
    op += -1.4 * Qop("Y0 Z1 X3 Y5")
    op += -1.1 * Qop("Y1 X2 X3 Y4")
    TimeEvolution(time_to_evolve, op) | qureg
    eng.flush()
    qbit_to_bit_map, final_wavefunction = copy.deepcopy(eng.backend.cheat())
    Measure | qureg

    # Check manually:

    def build_matrix(list_single_matrices):
        res = list_single_matrices[0]
        for i in range(1, len(list_single_matrices)):
            res = scipy.sparse.kron(res, list_single_matrices[i])
        return res

    id_sp = scipy.sparse.identity(2, format="csr", dtype=complex)
    x_sp = scipy.sparse.csr_matrix([[0., 1.], [1., 0.]], dtype=complex)
    y_sp = scipy.sparse.csr_matrix([[0., -1.j], [1.j, 0.]], dtype=complex)
    z_sp = scipy.sparse.csr_matrix([[1., 0.], [0., -1.]], dtype=complex)
    gates = [x_sp, y_sp, z_sp]

    res_matrix = 0
    for t, c in op.terms.items():
        matrix = [id_sp] * N
        for idx, gate in t:
            matrix[qbit_to_bit_map[qureg[idx].id]] = gates[ord(gate) -
                                                           ord('X')]
        matrix.reverse()
        res_matrix += build_matrix(matrix) * c
    res_matrix *= -1j * time_to_evolve

    init_wavefunction = numpy.array(init_wavefunction, copy=False)
    final_wavefunction = numpy.array(final_wavefunction, copy=False)
    res = scipy.sparse.linalg.expm_multiply(res_matrix, init_wavefunction)
    assert numpy.allclose(res, final_wavefunction)
Example #19
0
def circuit_no_ancilla(param=0, sigma=0, M=1):

    Engine = MainEngine()

    q1 = Engine.allocate_qureg(1)
    q2 = Engine.allocate_qureg(1)

    Rx(param) | q1
    Rx(param) | q2

    # [R * c-Pi * R^\dag * P * R * c-Pi * R^\dag * P]
    for _ in range(M):
        Z | q1
        Z | q2

        DaggeredGate(Rx(param)) | q1
        DaggeredGate(Rx(param)) | q2

        Rzz(pi / 2) | (q1, q2)

        Rz(pi / 2) | q1
        Rz(pi / 2) | q2

        Rx(param) | q1
        Rx(param) | q2

        Z | q1
        Z | q2

        DaggeredGate(Rx(param)) | q1
        DaggeredGate(Rx(param)) | q2

        Rzz(pi / 2) | (q1, q2)

        Rz(pi / 2) | q1
        Rz(pi / 2) | q2

        Rx(param) | q1
        Rx(param) | q2

    DaggeredGate(Rx(param)) | q1
    DaggeredGate(Rx(param)) | q2

    Measure | q1
    Measure | q2

    Engine.flush()

    return (int(q1), int(q2))
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        """
        See :py:meth:`pytket.backends.Backend.process_circuits`.
        Supported kwargs: `seed`.
        """
        circuit_list = list(circuits)
        if valid_check:
            self._check_all_circuits(circuit_list)

        handle_list = []
        for circuit in circuit_list:
            sim = Simulator(rnd_seed=kwargs.get("seed"))
            fwd = ForwarderEngine(sim)
            eng = MainEngine(backend=sim, engine_list=[fwd])
            qureg = eng.allocate_qureg(circuit.n_qubits)
            tk_to_projectq(eng, qureg, circuit, True)
            eng.flush()
            state = np.array(
                eng.backend.cheat()[1], dtype=complex
            )  # `cheat()` returns tuple:(a dictionary of qubit indices, statevector)
            handle = ResultHandle(str(uuid4()))
            try:
                phase = float(circuit.phase)
                coeff = np.exp(phase * np.pi * 1j)
                state *= coeff
            except ValueError:
                warning(
                    "Global phase is dependent on a symbolic parameter, so cannot "
                    "adjust for phase")
            implicit_perm = circuit.implicit_qubit_permutation()
            # reverse qubits as projectq state is dlo
            res_qubits = [
                implicit_perm[qb]
                for qb in sorted(circuit.qubits, reverse=True)
            ]
            measures = circuit.n_gates_of_type(OpType.Measure)
            if measures == 0 and n_shots is not None:
                backres = self.empty_result(circuit, n_shots=n_shots)
            else:
                backres = BackendResult(q_bits=res_qubits, state=state)
            self._cache[handle] = {"result": backres}
            handle_list.append(handle)
        return handle_list
Example #21
0
def deutsch_jozsa(f): 
    # Determine number of qubits needed
    N = len(f)
    n = int(np.log2(N))
    
    # Check we can simulate on our local simulator
    if n > 28:   # 28 qubits = 4GB of RAM
        print('Number of qubits required =', n, 'which is too large to simulate.')
        return 0

    # Initialise qubits
    engine = MainEngine()
    qubits = engine.allocate_qureg(n)
    ancilla = engine.allocate_qubit()
    
    # Start with qubits in equal superposition and ancilla in |->
    All(H) | qubits
    X | ancilla
    H | ancilla
    
    # Apply oracle U_f which flips the phase of every state |x> with f(x) = 1
    for i in range(N):
        if f[i] == '1':   # Then we need to flip the phase
            state = bin(i)[2:].zfill(n)
            for j in range(n):
                if state[j] == '0':
                    X | qubits[j]
            with Control(engine, qubits):
                X | ancilla
            for j in range(n):
                if state[j] == '0':
                    X | qubits[j] 
    
    # Apply Hadamards to working qubits
    All(H) | qubits

    # Measure all the qubits and output result
    All(Measure) | qubits
    Measure | ancilla
    engine.flush()
    
    y = 0
    for i in range(n):
        y = y + 2**i*int(qubits[i])
      
    if y == 0:
        print('Function is constant.')
    else:
        print('Function is balanced.')
Example #22
0
def ADD_resources(number_of_bits = 16):
    print('getting costs of ' + str(number_of_bits) + ' bit addition...')
    #___________________initial__________________
    resource_counter = ResourceCounter()
    eng = MainEngine(resource_counter)
    a = [0 for i in range(number_of_bits)]
    b = [0 for i in range(number_of_bits)]
    a = list_to_reg( a, eng) #one extra bit (in most significant) needed for addition
    z = list_to_reg([0],eng)
    b = list_to_reg(b, eng)
    #___________________circuit___________________
    ADD(a,b,z)
    #___________________measure___________________
    eng.flush()
    print(resource_counter)
Example #23
0
def ADD_test(x = [0,1,0,1,1,1,1,1], y = [1,0,1,1,0,0,1,1], z = [0]):
	print('Addition of two 8 bit numbers' )
	eng = MainEngine()
	#<least ---significance---most>
	print('x: ',x)
	print('y: ',y,' (205 in binary)')
	x = list_to_reg(x, eng) #one extra bit needed for addition
	y = list_to_reg(y,eng)
	z = list_to_reg(z, eng)
	ADD(x,y,z)
	All(Measure) | x+z+y
	eng.flush()
	print('x value: ',get_int(x))
	print('(sum) value: ',get_int(y+z))
	print('')
def test_ibm5qubitmapper_toomanyqubits():
    backend = DummyEngine(save_commands=True)
    connectivity = {(2, 1), (4, 2), (2, 0), (3, 2), (3, 4), (1, 0)}
    eng = MainEngine(
        backend=backend,
        engine_list=[
            _ibm5qubitmapper.IBM5QubitMapper(),
            SwapAndCNOTFlipper(connectivity),
        ],
    )
    qubits = eng.allocate_qureg(6)
    All(H) | qubits
    CNOT | (qubits[0], qubits[1])
    with pytest.raises(RuntimeError):
        eng.flush()
def test_simulator_set_wavefunction(sim, mapper):
    engine_list = [LocalOptimizer()]
    if mapper is not None:
        engine_list.append(mapper)
    eng = MainEngine(sim, engine_list=engine_list)
    qubits = eng.allocate_qureg(2)
    wf = [0., 0., math.sqrt(0.2), math.sqrt(0.8)]
    with pytest.raises(RuntimeError):
        eng.backend.set_wavefunction(wf, qubits)
    eng.flush()
    eng.backend.set_wavefunction(wf, qubits)
    assert pytest.approx(eng.backend.get_probability('1', [qubits[0]])) == .8
    assert pytest.approx(eng.backend.get_probability('01', qubits)) == .2
    assert pytest.approx(eng.backend.get_probability('1', [qubits[1]])) == 1.
    All(Measure) | qubits
Example #26
0
    def run(self, circuit:Circuit, shots:int, fit_to_constraints=True) -> np.ndarray:
        state = self.get_state(circuit, fit_to_constraints)
        fwd = ForwarderEngine(self._backend)
        eng = MainEngine(backend=self._backend,engine_list=[fwd])
        qb_results = []
        qureg = eng.allocate_qureg(circuit.n_qubits)

        for _ in range(shots):
            self._backend.set_wavefunction(state,qureg)
            All(Measure) | qureg
            eng.flush()
            results = (list(map(int,qureg)))
            qb_results.append(results)
        
        return np.asarray(qb_results)
Example #27
0
def subproblem1():
    eng = MainEngine()
    # Allocate qubits
    qubits = eng.allocate_qureg(2)
    # You should add quantum operations here to change the state of qubits into |01>
    # X|qubits[1]
    X | qubits[0]
    # Submit all your operations
    eng.flush()
    # Get the amplitudes list
    amplitudes = np.array(eng.backend.cheat()[1])
    print("p1:{}".format(amplitudes))
    # Here we return the amplitudes without measures and you do not need to care about the warnings
    All(Measure) | qubits
    return amplitudes
Example #28
0
def test_body():
    drawer = _drawer.CircuitDrawer()
    eng = MainEngine(drawer, [])
    old_tolatex = _drawer.to_latex
    _drawer.to_latex = lambda x: x

    qubit1 = eng.allocate_qubit()
    qubit2 = eng.allocate_qubit()
    qubit3 = eng.allocate_qubit()
    H | qubit1
    H | qubit2
    CNOT | (qubit1, qubit2)
    X | qubit2
    Measure | qubit2
    CNOT | (qubit2, qubit1)
    Z | qubit2
    C(Z) | (qubit1, qubit2)
    C(Swap) | (qubit1, qubit2, qubit3)
    SqrtX | qubit1
    SqrtSwap | (qubit1, qubit2)
    get_inverse(SqrtX) | qubit1
    C(SqrtSwap) | (qubit1, qubit2, qubit3)
    get_inverse(SqrtSwap) | (qubit1, qubit2)
    C(Swap) | (qubit3, qubit1, qubit2)
    C(SqrtSwap) | (qubit3, qubit1, qubit2)

    del qubit1
    eng.flush()

    circuit_lines = drawer.get_latex()
    _drawer.to_latex = old_tolatex

    settings = _to_latex.get_default_settings()
    settings['gates']['AllocateQubitGate']['draw_id'] = True
    code = _to_latex._body(circuit_lines, settings)

    # swap draws 2 nodes + 2 lines each, so is sqrtswap gate, csqrtswap,
    # inv(sqrt_swap), and cswap.
    assert code.count("swapstyle") == 36
    # CZ is two phases plus 2 from CNOTs + 2 from cswap + 2 from csqrtswap
    assert code.count("phase") == 8
    assert code.count("{{{}}}".format(str(H))) == 2  # 2 hadamard gates
    assert code.count("{$\Ket{0}") == 3  # 3 qubits allocated
    # 1 cnot, 1 not gate, 3 SqrtSwap, 1 inv(SqrtSwap)
    assert code.count("xstyle") == 7
    assert code.count("measure") == 1  # 1 measurement
    assert code.count("{{{}}}".format(str(Z))) == 1  # 1 Z gate
    assert code.count("{red}") == 3
Example #29
0
def test_simulator_arithmetic(mapper):
    class Offset(BasicMathGate):
        def __init__(self, amount):
            BasicMathGate.__init__(self, lambda x: (x + amount, ))

    class Sub(BasicMathGate):
        def __init__(self):
            BasicMathGate.__init__(self, lambda x, y: (x, y - x))

    engine_list = []
    if mapper is not None:
        engine_list.append(mapper)
    sim = ClassicalSimulator()
    eng = MainEngine(sim, engine_list)
    a = eng.allocate_qureg(4)
    b = eng.allocate_qureg(5)
    sim.write_register(a, 9)
    sim.write_register(b, 17)

    Offset(2) | a
    assert sim.read_register(a) == 11
    assert sim.read_register(b) == 17

    Offset(3) | b
    assert sim.read_register(a) == 11
    assert sim.read_register(b) == 20

    Offset(32 + 5) | b
    assert sim.read_register(a) == 11
    assert sim.read_register(b) == 25

    Sub() | (a, b)
    assert sim.read_register(a) == 11
    assert sim.read_register(b) == 14

    Sub() | (a, b)
    Sub() | (a, b)
    assert sim.read_register(a) == 11
    assert sim.read_register(b) == 24

    # also test via measurement:
    All(Measure) | a + b
    eng.flush()

    for i in range(len(a)):
        assert int(a[i]) == ((11 >> i) & 1)
    for i in range(len(b)):
        assert int(b[i]) == ((24 >> i) & 1)
Example #30
0
def test_auto_replacer_no_rule_found():
    # Check that exception is thrown if no rule is found
    # For both the cmd and it's inverse (which exists)
    def h_filter(self, cmd):
        if cmd.gate == H:
            return False
        return True

    h_filter = _replacer.InstructionFilter(h_filter)
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend,
                     engine_list=[_replacer.AutoReplacer(rule_set), h_filter])
    qubit = eng.allocate_qubit()
    with pytest.raises(_replacer.NoGateDecompositionError):
        H | qubit
    eng.flush()
    def run_circuit(self, circuit):
        """Run a circuit and return a single Result.

        Args:
            circuit (dict): JSON circuit from qobj circuits list

        Returns:
            dict: A dictionary of results which looks something like::

                {
                "data":
                    {  #### DATA CAN BE A DIFFERENT DICTIONARY FOR EACH BACKEND ####
                    "counts": {'00000': XXXX, '00001': XXXXX},
                    "time"  : xx.xxxxxxxx
                    },
                "status": --status (string)--
                }
        Raises:
            SimulatorError: if an error occurred.
        """
        # pylint: disable=expression-not-assigned,pointless-statement
        ccircuit = circuit['compiled_circuit']
        self._number_of_qubits = ccircuit['header']['number_of_qubits']
        self._number_of_clbits = ccircuit['header']['number_of_clbits']
        self._statevector = 0
        self._classical_state = 0
        cl_reg_index = []  # starting bit index of classical register
        cl_reg_nbits = []  # number of bits in classical register
        clbit_index = 0
        qobj_quregs = OrderedDict(_get_register_specs(
            ccircuit['header']['qubit_labels']))
        eng = MainEngine(backend=self._sim)
        for cl_reg in ccircuit['header']['clbit_labels']:
            cl_reg_nbits.append(cl_reg[1])
            cl_reg_index.append(clbit_index)
            clbit_index += cl_reg[1]
        # let circuit seed override qobj default
        if 'config' in circuit:
            if 'seed' in circuit['config']:
                if circuit['config']['seed'] is not None:
                    self._sim._simulator = CppSim(circuit['config']['seed'])
        outcomes = []
        start = time.time()
        for _ in range(self._shots):
            self._statevector = np.zeros(1 << self._number_of_qubits,
                                         dtype=complex)
            self._statevector[0] = 1
            # initialize starting state
            self._classical_state = 0
            unmeasured_qubits = list(range(self._number_of_qubits))
            projq_qureg_dict = OrderedDict(((key, eng.allocate_qureg(size))
                                            for key, size in
                                            qobj_quregs.items()))
            qureg = [qubit for sublist in projq_qureg_dict.values()
                     for qubit in sublist]
            # Do each operation in this shot
            for operation in ccircuit['operations']:
                if 'conditional' in operation:
                    mask = int(operation['conditional']['mask'], 16)
                    if mask > 0:
                        value = self._classical_state & mask
                        while (mask & 0x1) == 0:
                            mask >>= 1
                            value >>= 1
                        if value != int(operation['conditional']['val'], 16):
                            continue
                # Check if single  gate
                if operation['name'] in ['U', 'u3']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[2]) | qubit
                    Ry(params[0]) | qubit
                    Rz(params[1]) | qubit
                elif operation['name'] in ['u1']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[0]) | qubit
                elif operation['name'] in ['u2']:
                    params = operation['params']
                    qubit = qureg[operation['qubits'][0]]
                    Rz(params[1] - np.pi/2) | qubit
                    Rx(np.pi/2) | qubit
                    Rz(params[0] + np.pi/2) | qubit
                elif operation['name'] == 't':
                    qubit = qureg[operation['qubits'][0]]
                    T | qubit
                elif operation['name'] == 'h':
                    qubit = qureg[operation['qubits'][0]]
                    H | qubit
                elif operation['name'] == 's':
                    qubit = qureg[operation['qubits'][0]]
                    S | qubit
                elif operation['name'] in ['CX', 'cx']:
                    qubit0 = qureg[operation['qubits'][0]]
                    qubit1 = qureg[operation['qubits'][1]]
                    CX | (qubit0, qubit1)
                elif operation['name'] in ['id', 'u0']:
                    pass
                # Check if measure
                elif operation['name'] == 'measure':
                    qubit_index = operation['qubits'][0]
                    qubit = qureg[qubit_index]
                    clbit = operation['clbits'][0]
                    Measure | qubit
                    bit = 1 << clbit
                    self._classical_state = (
                        self._classical_state & (~bit)) | (int(qubit)
                                                           << clbit)
                    # check whether we already measured this qubit
                    if operation['qubits'][0] in unmeasured_qubits:
                        unmeasured_qubits.remove(operation['qubits'][0])
                # Check if reset
                elif operation['name'] == 'reset':
                    qubit = operation['qubits'][0]
                    raise SimulatorError('Reset operation not yet implemented '
                                         'for ProjectQ C++ backend')
                elif operation['name'] == 'barrier':
                    pass
                else:
                    backend = self._configuration['name']
                    err_msg = '{0} encountered unrecognized operation "{1}"'
                    raise SimulatorError(err_msg.format(backend,
                                                        operation['name']))
            for ind in unmeasured_qubits:
                qubit = qureg[ind]
                Measure | qubit
            eng.flush()
            # Turn classical_state (int) into bit string
            state = format(self._classical_state, 'b')
            outcomes.append(state.zfill(self._number_of_clbits))
        # Return the results
        counts = dict(Counter(outcomes))
        data = {'counts': _format_result(
            counts, cl_reg_index, cl_reg_nbits)}
        if self._shots == 1:
            # TODO: deprecated -- remove in v0.6
            data['statevector'] = self._statevector
            data['quantum_state'] = self._statevector
            data['classical_state'] = self._classical_state
        end = time.time()
        return {'name': circuit['name'],
                'seed': self._seed,
                'shots': self._shots,
                'data': data,
                'status': 'DONE',
                'success': True,
                'time_taken': (end-start)}
Example #32
0
# From http://dataespresso.com/en/2018/07/22/Tutorial-Generating-random-numbers-with-a-quantum-computer-Python/

from projectq.ops import H, Measure
from projectq import MainEngine

"""
This Function creates a new qubit,
applies a Hadamard gate to put it in superposition,
and then measures the qubit to get a random
1 or 0.

"""
def get_random_number(quantum_engine):
    qubit = quantum_engine.allocate_qubit()
    H | qubit
    Measure | qubit
    random_number = int(qubit)
    return random_number

# This list is used to store our random numbers
random_numbers_list = []
# initialises a new quantum backend
quantum_engine = MainEngine()
# for loop to generate 10 random numbers
for i in range(10):
    # calling the random number function and append the return to the list
    random_numbers_list.append(get_random_number(quantum_engine))
# Flushes the quantum engine from memory
quantum_engine.flush()
print('Random numbers', random_numbers_list)
Example #33
0
from projectq import MainEngine  # import the main compiler engine
# import the operations we want to perform (Hadamard and measurement)
from projectq.ops import H, Measure

eng = MainEngine()  # create a default compiler (the back-end is a simulator)
qubit = eng.allocate_qubit()  # allocate 1 qubit

H | qubit  # apply a Hadamard gate
Measure | qubit  # measure the qubit

eng.flush()  # flush all gates (and execute measurements)
print("Measured {}".format(int(qubit)))  # output measurement result