예제 #1
0
def qft(eng, circuit, qubits):
    m = len(qubits)
    for i in range(m - 1, -1, -1):
        circuit.apply_single_qubit_gate(Rz(np.pi / 2), qubits[i])
        circuit.apply_single_qubit_gate(Rx(np.pi / 2), qubits[i])
        circuit.apply_single_qubit_gate(Rz(np.pi / 2), qubits[i])
        for j in range(2, i + 2):
            circuit.apply_single_qubit_gate(Rz(-np.pi / 2), qubits[i - j + 1])
            circuit.apply_single_qubit_gate(Rx(np.pi / 2), qubits[i])
            circuit.apply_single_qubit_gate(Rz(np.pi / 2), qubits[i])
            circuit.apply_ld_two_qubit_gate(ISwap, qubits[i - j + 1],
                                            qubits[i])
            circuit.apply_single_qubit_gate(Rx(np.pi / 2), qubits[i - j + 1])
            circuit.apply_ld_two_qubit_gate(ISwap, qubits[i - j + 1],
                                            qubits[i])
            circuit.apply_single_qubit_gate(Rz(np.pi / 2), qubits[i])

            circuit.apply_single_qubit_gate(R(-calculate_phase(i) / 4),
                                            qubits[i])

            circuit.apply_single_qubit_gate(Rz(-np.pi / 2), qubits[i - j + 1])
            circuit.apply_single_qubit_gate(Rx(np.pi / 2), qubits[i])
            circuit.apply_single_qubit_gate(Rz(np.pi / 2), qubits[i])
            circuit.apply_ld_two_qubit_gate(ISwap, qubits[i - j + 1],
                                            qubits[i])
            circuit.apply_single_qubit_gate(Rx(np.pi / 2), qubits[i - j + 1])
            circuit.apply_ld_two_qubit_gate(ISwap, qubits[i - j + 1],
                                            qubits[i])
            circuit.apply_single_qubit_gate(Rz(np.pi / 2), qubits[i])

            circuit.apply_single_qubit_gate(Rz(calculate_phase(i) / 4),
                                            qubits[i - j + 1])
            circuit.apply_single_qubit_gate(Rz(calculate_phase(i) / 4),
                                            qubits[i])
예제 #2
0
def _decompose_time_evolution_individual_terms(cmd):
    """
    Implements a TimeEvolution gate with a hamiltonian having only one term.

    To implement exp(-i * t * hamiltonian), where the hamiltonian is only one
    term, e.g., hamiltonian = X0 x Y1 X Z2, we first perform local
    transformations to in order that all Pauli operators in the hamiltonian
    are Z. We then implement  exp(-i * t * (Z1 x Z2 x Z3) and transform the
    basis back to the original. For more details see, e.g.,

    James D. Whitfield, Jacob Biamonte & Aspuru-Guzik
    Simulation of electronic structure Hamiltonians using quantum computers,
    Molecular Physics, 109:5, 735-750 (2011).

    or

    Nielsen and Chuang, Quantum Computation and Information.
    """
    assert len(cmd.qubits) == 1
    qureg = cmd.qubits[0]
    eng = cmd.engine
    time = cmd.gate.time
    hamiltonian = cmd.gate.hamiltonian
    assert len(hamiltonian.terms) == 1
    term = list(hamiltonian.terms)[0]
    coefficient = hamiltonian.terms[term]
    check_indices = set()

    # Check that hamiltonian is not identity term,
    # Previous or operator should have apply a global phase instead:
    assert not term == ()

    # hamiltonian has only a single local operator
    if len(term) == 1:
        with Control(eng, cmd.control_qubits):
            if term[0][1] == 'X':
                Rx(time * coefficient * 2.) | qureg[term[0][0]]
            elif term[0][1] == 'Y':
                Ry(time * coefficient * 2.) | qureg[term[0][0]]
            else:
                Rz(time * coefficient * 2.) | qureg[term[0][0]]
    # hamiltonian has more than one local operator
    else:
        with Control(eng, cmd.control_qubits):
            with Compute(eng):
                # Apply local basis rotations
                for index, action in term:
                    check_indices.add(index)
                    if action == 'X':
                        H | qureg[index]
                    elif action == 'Y':
                        Rx(math.pi / 2.) | qureg[index]
                # Check that qureg had exactly as many qubits as indices:
                assert check_indices == set((range(len(qureg))))
                # Compute parity
                for i in range(len(qureg) - 1):
                    CNOT | (qureg[i], qureg[i + 1])
            Rz(time * coefficient * 2.) | qureg[-1]
            # Uncompute parity and basis change
            Uncompute(eng)
예제 #3
0
def test_decomposition(angle):
    for basis_state in ([1, 0], [0, 1]):
        correct_dummy_eng = DummyEngine(save_commands=True)
        correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng])

        rule_set = DecompositionRuleSet(modules=[rx2rz])
        test_dummy_eng = DummyEngine(save_commands=True)
        test_eng = MainEngine(
            backend=Simulator(),
            engine_list=[
                AutoReplacer(rule_set),
                InstructionFilter(rx_decomp_gates),
                test_dummy_eng,
            ],
        )

        correct_qb = correct_eng.allocate_qubit()
        Rx(angle) | correct_qb
        correct_eng.flush()

        test_qb = test_eng.allocate_qubit()
        Rx(angle) | test_qb
        test_eng.flush()

        assert correct_dummy_eng.received_commands[1].gate == Rx(angle)
        assert test_dummy_eng.received_commands[1].gate != Rx(angle)

        for fstate in ['0', '1']:
            test = test_eng.backend.get_amplitude(fstate, test_qb)
            correct = correct_eng.backend.get_amplitude(fstate, correct_qb)
            assert correct == pytest.approx(test, rel=1e-12, abs=1e-12)

        Measure | test_qb
        Measure | correct_qb
예제 #4
0
def test_dagger_with_dirty_qubits():
    backend = DummyEngine(save_commands=True)

    def allow_dirty_qubits(self, meta_tag):
        return meta_tag == DirtyQubitTag

    backend.is_meta_tag_handler = types.MethodType(allow_dirty_qubits, backend)
    eng = MainEngine(backend=backend, engine_list=[DummyEngine()])
    qubit = eng.allocate_qubit()
    with _dagger.Dagger(eng):
        ancilla = eng.allocate_qubit(dirty=True)
        Rx(0.6) | ancilla
        CNOT | (ancilla, qubit)
        H | qubit
        Rx(-0.6) | ancilla
        del ancilla[0]
    eng.flush(deallocate_qubits=True)
    assert len(backend.received_commands) == 9
    assert backend.received_commands[0].gate == Allocate
    assert backend.received_commands[1].gate == Allocate
    assert backend.received_commands[2].gate == Rx(0.6)
    assert backend.received_commands[3].gate == H
    assert backend.received_commands[4].gate == X
    assert backend.received_commands[5].gate == Rx(-0.6)
    assert backend.received_commands[6].gate == Deallocate
    assert backend.received_commands[7].gate == Deallocate
    assert backend.received_commands[1].tags == [DirtyQubitTag()]
    assert backend.received_commands[6].tags == [DirtyQubitTag()]
예제 #5
0
def test_compute_uncompute_no_additional_qubits():
    # No ancilla qubit created in compute section
    backend0 = DummyEngine(save_commands=True)
    compare_engine0 = CompareEngine()
    eng0 = MainEngine(backend=backend0, engine_list=[compare_engine0])
    qubit = eng0.allocate_qubit()
    with _compute.Compute(eng0):
        Rx(0.5) | qubit
    H | qubit
    _compute.Uncompute(eng0)
    eng0.flush(deallocate_qubits=True)
    assert backend0.received_commands[0].gate == Allocate
    assert backend0.received_commands[1].gate == Rx(0.5)
    assert backend0.received_commands[2].gate == H
    assert backend0.received_commands[3].gate == Rx(-0.5)
    assert backend0.received_commands[4].gate == Deallocate
    assert backend0.received_commands[0].tags == []
    assert backend0.received_commands[1].tags == [_compute.ComputeTag()]
    assert backend0.received_commands[2].tags == []
    assert backend0.received_commands[3].tags == [_compute.UncomputeTag()]
    assert backend0.received_commands[4].tags == []
    # Same using CustomUncompute and test using CompareEngine
    backend1 = DummyEngine(save_commands=True)
    compare_engine1 = CompareEngine()
    eng1 = MainEngine(backend=backend1, engine_list=[compare_engine1])
    qubit = eng1.allocate_qubit()
    with _compute.Compute(eng1):
        Rx(0.5) | qubit
    H | qubit
    with _compute.CustomUncompute(eng1):
        Rx(-0.5) | qubit
    eng1.flush(deallocate_qubits=True)
    assert compare_engine0 == compare_engine1
예제 #6
0
    def run(self, type):
        """
        construct the prob dist according to the parameters trained using born machine.
        :param type: str, forward or backward
        :return:
        """
        if type == 'forward':
            for dep_index in range(self.depth + 1):
                for i in range(self.num_qubits):
                    Rz(self.theta[dep_index, i, 0]) | self.qureg[i]
                    Rx(self.theta[dep_index, i, 1]) | self.qureg[i]
                    Rz(self.theta[dep_index, i, 2]) | self.qureg[i]
                # entanglement
                if dep_index == self.depth:
                    pass
                else:
                    for ctrl_pair in self.ctrl_pairs:
                        CNOT | (self.qureg[ctrl_pair[0]],
                                self.qureg[ctrl_pair[1]])
        elif type == 'backward':
            for dep_index in range(self.depth, -1, -1):
                # entanglement
                if dep_index != self.depth:
                    for ctrl_pair in self.ctrl_pairs[::-1]:
                        CNOT | (self.qureg[ctrl_pair[0]],
                                self.qureg[ctrl_pair[1]])

                for i in range(self.num_qubits):
                    Rz(self.theta[dep_index, i,
                                  2]).get_inverse() | self.qureg[i]
                    Rx(self.theta[dep_index, i,
                                  1]).get_inverse() | self.qureg[i]
                    Rz(self.theta[dep_index, i,
                                  0]).get_inverse() | self.qureg[i]
예제 #7
0
def test_command_get_merged(main_engine):
    qubit = main_engine.allocate_qubit()
    ctrl_qubit = main_engine.allocate_qubit()
    cmd = _command.Command(main_engine, Rx(0.5), (qubit,))
    cmd.tags = ["TestTag"]
    cmd.add_control_qubits(ctrl_qubit)
    # Merge two commands
    cmd2 = _command.Command(main_engine, Rx(0.5), (qubit,))
    cmd2.add_control_qubits(ctrl_qubit)
    cmd2.tags = ["TestTag"]
    merged_cmd = cmd.get_merged(cmd2)
    expected_cmd = _command.Command(main_engine, Rx(1.0), (qubit,))
    expected_cmd.add_control_qubits(ctrl_qubit)
    expected_cmd.tags = ["TestTag"]
    assert merged_cmd == expected_cmd
    # Don't merge commands as different control qubits
    cmd3 = _command.Command(main_engine, Rx(0.5), (qubit,))
    cmd3.tags = ["TestTag"]
    with pytest.raises(NotMergeable):
        cmd.get_merged(cmd3)
    # Don't merge commands as different tags
    cmd4 = _command.Command(main_engine, Rx(0.5), (qubit,))
    cmd4.add_control_qubits(ctrl_qubit)
    with pytest.raises(NotMergeable):
        cmd.get_merged(cmd4)
예제 #8
0
def test_aqt_retrieve(monkeypatch):
    # patch send
    def mock_retrieve(*args, **kwargs):
        return [0, 6, 0, 6, 0, 0, 0, 6, 0, 6]

    monkeypatch.setattr(_aqt, "retrieve", mock_retrieve)
    backend = _aqt.AQTBackend(
        retrieve_execution="a3877d18-314f-46c9-86e7-316bc4dbe968",
        verbose=True)

    eng = MainEngine(backend=backend, engine_list=[])
    unused_qubit = eng.allocate_qubit()
    qureg = eng.allocate_qureg(2)
    # entangle the qureg
    Ry(math.pi / 2) | qureg[0]
    Rx(math.pi / 2) | qureg[0]
    Rx(math.pi / 2) | qureg[0]
    Ry(math.pi / 2) | qureg[0]
    Rxx(math.pi / 2) | (qureg[0], qureg[1])
    Rx(7 * math.pi / 2) | qureg[0]
    Ry(7 * math.pi / 2) | qureg[0]
    Rx(7 * math.pi / 2) | qureg[1]
    del unused_qubit
    # measure; should be all-0 or all-1
    All(Measure) | qureg
    # run the circuit
    eng.flush()
    prob_dict = eng.backend.get_probabilities([qureg[0], qureg[1]])
    assert prob_dict['11'] == pytest.approx(0.4)
    assert prob_dict['00'] == pytest.approx(0.6)

    # Unknown qubit and no mapper
    invalid_qubit = [Qubit(eng, 10)]
    with pytest.raises(RuntimeError):
        eng.backend.get_probabilities(invalid_qubit)
예제 #9
0
def test_local_optimizer_caching():
    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()
    assert len(backend.received_commands) == 0
    H | qb0
    H | qb1
    CNOT | (qb0, qb1)
    assert len(backend.received_commands) == 0
    Rx(0.5) | qb0
    assert len(backend.received_commands) == 1
    assert backend.received_commands[0].gate == AllocateQubitGate()
    H | qb0
    assert len(backend.received_commands) == 2
    assert backend.received_commands[1].gate == H
    # Another gate on qb0 means it needs to send CNOT but clear pipeline of qb1
    Rx(0.6) | qb0
    for cmd in backend.received_commands:
        print(cmd)
    assert len(backend.received_commands) == 5
    assert backend.received_commands[2].gate == AllocateQubitGate()
    assert backend.received_commands[3].gate == H
    assert backend.received_commands[3].qubits[0][0].id == qb1[0].id
    assert backend.received_commands[4].gate == X
    assert backend.received_commands[4].control_qubits[0].id == qb0[0].id
    assert backend.received_commands[4].qubits[0][0].id == qb1[0].id
예제 #10
0
def CNOT(eng, circuit, b1, b2):
    circuit.apply_single_qubit_gate(Rz(-np.pi / 2), b1)
    circuit.apply_single_qubit_gate(Rx(np.pi / 2), b2)
    circuit.apply_single_qubit_gate(Rz(np.pi / 2), b2)
    circuit.apply_ld_two_qubit_gate(ISwap, b1, b2)
    circuit.apply_single_qubit_gate(Rx(np.pi / 2), b1)
    circuit.apply_ld_two_qubit_gate(ISwap, b1, b2)
    circuit.apply_single_qubit_gate(Rz(np.pi / 2), b2)
예제 #11
0
def Swap(eng, circuit, b1, b2):
    # circuit.apply_ld_two_qubit_gate(ops.Swap, b1, b2)
    circuit.apply_ld_two_qubit_gate(ISwap, b1, b2)
    circuit.apply_single_qubit_gate(Rx(-np.pi / 2), b2)
    circuit.apply_ld_two_qubit_gate(ISwap, b1, b2)
    circuit.apply_single_qubit_gate(Rx(-np.pi / 2), b1)
    circuit.apply_ld_two_qubit_gate(ISwap, b1, b2)
    circuit.apply_single_qubit_gate(Rx(-np.pi / 2), b2)
예제 #12
0
def test_decomposition():
    for basis_state_index in range(0, 16):
        basis_state = [0] * 16
        basis_state[basis_state_index] = 1.0
        correct_dummy_eng = DummyEngine(save_commands=True)
        correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng])
        rule_set = DecompositionRuleSet(modules=[cnu2toffoliandcu])
        test_dummy_eng = DummyEngine(save_commands=True)
        test_eng = MainEngine(
            backend=Simulator(),
            engine_list=[
                AutoReplacer(rule_set),
                InstructionFilter(_decomp_gates),
                test_dummy_eng,
            ],
        )
        test_sim = test_eng.backend
        correct_sim = correct_eng.backend
        correct_qb = correct_eng.allocate_qubit()
        correct_ctrl_qureg = correct_eng.allocate_qureg(3)
        correct_eng.flush()
        test_qb = test_eng.allocate_qubit()
        test_ctrl_qureg = test_eng.allocate_qureg(3)
        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)

        with Control(test_eng, test_ctrl_qureg[:2]):
            Rx(0.4) | test_qb
        with Control(test_eng, test_ctrl_qureg):
            Ry(0.6) | test_qb
        with Control(test_eng, test_ctrl_qureg):
            X | test_qb

        with Control(correct_eng, correct_ctrl_qureg[:2]):
            Rx(0.4) | correct_qb
        with Control(correct_eng, correct_ctrl_qureg):
            Ry(0.6) | correct_qb
        with Control(correct_eng, correct_ctrl_qureg):
            X | correct_qb

        test_eng.flush()
        correct_eng.flush()

        assert len(correct_dummy_eng.received_commands) == 9
        assert len(test_dummy_eng.received_commands) == 25

        for fstate in range(16):
            binary_state = format(fstate, '04b')
            test = test_sim.get_amplitude(binary_state, test_qb + test_ctrl_qureg)
            correct = correct_sim.get_amplitude(binary_state, correct_qb + correct_ctrl_qureg)
            assert correct == pytest.approx(test, rel=1e-12, abs=1e-12)

        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)
예제 #13
0
def inversed_full_rotation(wavefunction, qsubset, parameter):
    """
    The inversed operation of full_rotation() of the same parameter
    """
    n_qubit = len(qsubset)
    for i in range(len(qsubset)):
        Rx(-parameter[2 * n_qubit + i]) | wavefunction[qsubset[i]]
        Rz(-parameter[n_qubit + i]) | wavefunction[qsubset[i]]
        Rx(-parameter[i]) | wavefunction[qsubset[i]]
예제 #14
0
def full_rotation(wavefunction, qsubset, parameter):
    """
    Apply Rx(t1)Ry(t2)Rx(t3) rotation to all the qubits with different angle
    """
    n_qubit = len(qsubset)
    for i in range(len(qsubset)):
        Rx(parameter[i]) | wavefunction[qsubset[i]]
        Rz(parameter[n_qubit + i]) | wavefunction[qsubset[i]]
        Rx(parameter[2 * n_qubit + i]) | wavefunction[qsubset[i]]
예제 #15
0
def test_is_identity():
    # Choose gate which is not an identity gate:
    non_identity_gate = Rx(0.5)
    assert not non_identity_gate.is_identity()
    assert not _metagates.is_identity(non_identity_gate)
    # Choose gate which is an identity gate:
    identity_gate = Rx(0.0)
    assert identity_gate.is_identity()
    assert _metagates.is_identity(identity_gate)
예제 #16
0
def initializeState(qreg, theta):
   Rx(np.pi) | qreg[0]
   Ry(np.pi / 2.0) | qreg[1]
   Rx(2.5*np.pi) | qreg[0]
   CNOT | (qreg[1], qreg[0])
   Rz(theta) | qreg[0]
   CNOT | (qreg[1], qreg[0])
   Ry(2.5*np.pi) | qreg[1]
   Rx(np.pi/2) | qreg[0]
예제 #17
0
def test_aqt_backend_functional_test(monkeypatch):
    correct_info = {
        'circuit': '[["Y", 0.5, [1]], ["X", 0.5, [1]], ["X", 0.5, [1]], '
        '["Y", 0.5, [1]], ["MS", 0.5, [1, 2]], ["X", 3.5, [1]], '
        '["Y", 3.5, [1]], ["X", 3.5, [2]]]',
        'nq': 3,
        'shots': 10,
        'backend': {'name': 'simulator'},
    }

    def mock_send(*args, **kwargs):
        assert args[0] == correct_info
        return [0, 6, 0, 6, 0, 0, 0, 6, 0, 6]

    monkeypatch.setattr(_aqt, "send", mock_send)

    backend = _aqt.AQTBackend(verbose=True, num_runs=10)
    # no circuit has been executed -> raises exception
    with pytest.raises(RuntimeError):
        backend.get_probabilities([])

    mapper = BasicMapperEngine()
    res = {}
    for i in range(4):
        res[i] = i
    mapper.current_mapping = res

    eng = MainEngine(backend=backend, engine_list=[mapper])

    unused_qubit = eng.allocate_qubit()
    qureg = eng.allocate_qureg(2)
    # entangle the qureg
    Ry(math.pi / 2) | qureg[0]
    Rx(math.pi / 2) | qureg[0]
    Rx(math.pi / 2) | qureg[0]
    Ry(math.pi / 2) | qureg[0]
    Rxx(math.pi / 2) | (qureg[0], qureg[1])
    Rx(7 * math.pi / 2) | qureg[0]
    Ry(7 * math.pi / 2) | qureg[0]
    Rx(7 * math.pi / 2) | qureg[1]
    All(Barrier) | qureg
    del unused_qubit
    # measure; should be all-0 or all-1
    All(Measure) | qureg
    # run the circuit
    eng.flush()
    prob_dict = eng.backend.get_probabilities([qureg[0], qureg[1]])
    assert prob_dict['11'] == pytest.approx(0.4)
    assert prob_dict['00'] == pytest.approx(0.6)

    # Unknown qubit and no mapper
    invalid_qubit = [WeakQubitRef(eng, 10)]
    with pytest.raises(RuntimeError):
        eng.backend.get_probabilities(invalid_qubit)

    with pytest.raises(RuntimeError):
        eng.backend.get_probabilities(eng.allocate_qubit())
예제 #18
0
def test_command_str():
    qubit = Qureg([Qubit(main_engine, 0)])
    ctrl_qubit = Qureg([Qubit(main_engine, 1)])
    cmd = _command.Command(main_engine, Rx(0.5), (qubit, ))
    cmd.tags = ["TestTag"]
    cmd.add_control_qubits(ctrl_qubit)
    assert str(cmd) == "CRx(0.5) | ( Qureg[1], Qureg[0] )"
    cmd2 = _command.Command(main_engine, Rx(0.5), (qubit, ))
    assert str(cmd2) == "Rx(0.5) | Qureg[0]"
예제 #19
0
 def swap(self, node1, node2):
     self.gates_applied += 6
     self.single_applied += 3
     self.two_applied += 3
     ISwap | (node1.qubit.qubit, node2.qubit.qubit)
     Rx(-np.pi / 2) | node2.qubit.qubit
     ISwap | (node1.qubit.qubit, node2.qubit.qubit)
     Rx(-np.pi / 2) | node1.qubit.qubit
     ISwap | (node1.qubit.qubit, node2.qubit.qubit)
     Rx(-np.pi / 2) | node2.qubit.qubit
예제 #20
0
def _decompose_cnot2rxx_P(cmd):
    """ Decompose CNOT gate into Rxx gate. """
    # Labelled 'P' for 'plus' because decomposition ends with a Ry(+pi/2)
    ctrl = cmd.control_qubits
    Ry(-math.pi / 2) | ctrl[0]
    Ph(math.pi / 4) | ctrl[0]
    Rx(-math.pi / 2) | ctrl[0]
    Rx(math.pi / 2) | cmd.qubits[0][0]
    Rxx(math.pi / 2) | (ctrl[0], cmd.qubits[0][0])
    Ry(math.pi / 2) | ctrl[0]
예제 #21
0
def _decompose_cnot2rxx_M(cmd):  # pylint: disable=invalid-name
    """Decompose CNOT gate into Rxx gate."""
    # Labelled 'M' for 'minus' because decomposition ends with a Ry(-pi/2)
    ctrl = cmd.control_qubits
    Ry(math.pi / 2) | ctrl[0]
    Ph(7 * math.pi / 4) | ctrl[0]
    Rx(-math.pi / 2) | ctrl[0]
    Rx(-math.pi / 2) | cmd.qubits[0][0]
    Rxx(math.pi / 2) | (ctrl[0], cmd.qubits[0][0])
    Ry(-1 * math.pi / 2) | ctrl[0]
예제 #22
0
def test_command_is_identity(main_engine):
    qubit = main_engine.allocate_qubit()
    qubit2 = main_engine.allocate_qubit()
    cmd = _command.Command(main_engine, Rx(0.0), (qubit,))
    cmd2 = _command.Command(main_engine, Rx(0.5), (qubit2,))
    inverse_cmd = cmd.get_inverse()
    inverse_cmd2 = cmd2.get_inverse()
    assert inverse_cmd.gate.is_identity()
    assert cmd.gate.is_identity()
    assert not inverse_cmd2.gate.is_identity()
    assert not cmd2.gate.is_identity()
예제 #23
0
def test_recognize_correct_gates():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend)
    qubit = eng.allocate_qubit()
    ctrl_qubit = eng.allocate_qubit()
    eng.flush()
    Rx(0.3) | qubit
    with Control(eng, ctrl_qubit):
        Rx(0.4) | qubit
    eng.flush(deallocate_qubits=True)
    assert rx2rz._recognize_RxNoCtrl(saving_backend.received_commands[3])
    assert not rx2rz._recognize_RxNoCtrl(saving_backend.received_commands[4])
예제 #24
0
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)
예제 #25
0
def test_command_str(main_engine):
    qubit = Qureg([Qubit(main_engine, 0)])
    ctrl_qubit = Qureg([Qubit(main_engine, 1)])
    cmd = _command.Command(main_engine, Rx(0.5 * math.pi), (qubit,))
    cmd.tags = ["TestTag"]
    cmd.add_control_qubits(ctrl_qubit)
    cmd2 = _command.Command(main_engine, Rx(0.5 * math.pi), (qubit,))
    if sys.version_info.major == 3:
        assert cmd.to_string(symbols=False) == "CRx(1.570796326795) | ( Qureg[1], Qureg[0] )"
        assert str(cmd2) == "Rx(1.570796326795) | Qureg[0]"
    else:
        assert cmd.to_string(symbols=False) == "CRx(1.5707963268) | ( Qureg[1], Qureg[0] )"
        assert str(cmd2) == "Rx(1.5707963268) | Qureg[0]"
예제 #26
0
def generalized_rotation(wavefunction, qsubset, pauliword, evolution_time):
    """Apply e^{iPt} on the wavefunction
    Args:
        qsubset: The subset of qubits in the wavefunction that the operation applies on
        pauliword: The Pauli word P in e^{iPt} 1:X,2:Y,3:Z
        evolution_time: t in e^{iPt}
    """
    HALF_PI = math.pi / 2
    n_qubit = len(qsubset)

    # Exponentiating each Pauli string requires five parts

    # 1. Perform basis rotations
    for p in range(0, n_qubit):
        pop = pauliword[p]  # Pauli op
        if pop == 1:
            H | wavefunction[qsubset[p]]  # Hadamard
        elif pop == 2:
            Rx(HALF_PI) | wavefunction[qsubset[p]]

    # 2. First set CNOTs
    prev_index = None

    for p in range(0, n_qubit):
        pop = pauliword[p]  # Pauli op
        if pop == 0:
            continue
        if prev_index is not None:
            CNOT | (wavefunction[prev_index], wavefunction[qsubset[p]])
        prev_index = qsubset[p]

    # 3. Rotation (Note kexp & Ntrot)
    Rz(evolution_time * 2) | wavefunction[prev_index]

    # 4. Second set of CNOTs
    prev_index = None
    for p in reversed(range(0, n_qubit)):
        pop = pauliword[p]  # Pauli op
        if pop == 0:
            continue
        if prev_index is not None:
            CNOT | (wavefunction[qsubset[p]], wavefunction[prev_index])
        prev_index = qsubset[p]

    # 5. Rotate back to Z basis
    for p in range(0, len(pauliword)):
        pop = pauliword[p]  # Pauli op
        if pop == 1:
            H | wavefunction[qsubset[p]]  # Hadamard
        elif pop == 2:
            Rx(-HALF_PI) | wavefunction[qsubset[p]]
예제 #27
0
def test_unitary_is_available():
    sim = UnitarySimulator()
    qb0 = WeakQubitRef(engine=None, idx=0)
    qb1 = WeakQubitRef(engine=None, idx=1)
    qb2 = WeakQubitRef(engine=None, idx=2)
    qb3 = WeakQubitRef(engine=None, idx=2)
    qb4 = WeakQubitRef(engine=None, idx=2)
    qb5 = WeakQubitRef(engine=None, idx=2)
    qb6 = WeakQubitRef(engine=None, idx=2)

    assert sim.is_available(Command(None, Allocate, qubits=([qb0], )))
    assert sim.is_available(Command(None, Deallocate, qubits=([qb0], )))
    assert sim.is_available(Command(None, Measure, qubits=([qb0], )))
    assert sim.is_available(Command(None, X, qubits=([qb0], )))
    assert sim.is_available(Command(None, Rx(1.2), qubits=([qb0], )))
    assert sim.is_available(Command(None, Rxx(1.2), qubits=([qb0, qb1], )))
    assert sim.is_available(Command(None, X, qubits=([qb0], ), controls=[qb1]))
    assert sim.is_available(
        Command(None, X, qubits=([qb0], ), controls=[qb1], control_state='1'))

    assert not sim.is_available(Command(None, BasicGate(), qubits=([qb0], )))
    assert not sim.is_available(
        Command(None, X, qubits=([qb0], ), controls=[qb1], control_state='0'))

    with pytest.warns(UserWarning):
        assert sim.is_available(
            Command(
                None,
                MatrixGate(np.identity(2**7)),
                qubits=([qb0, qb1, qb2, qb3, qb4, qb5, qb6], ),
            ))
예제 #28
0
 def test_store_returns_correct_qasm(self):
     angle = 0.1
     self.__store_function_assert_equal(0, NOT, "\nx q[0]")
     self.__store_function_assert_equal(1,
                                        NOT,
                                        "\ncnot q[0], q[1]",
                                        count=1)
     self.__store_function_assert_equal(0, Swap, "\nswap q[0], q[1]")
     self.__store_function_assert_equal(1,
                                        X,
                                        "\ntoffoli q[0], q[1], q[1]",
                                        count=2)
     self.__store_function_assert_equal(1, Z, "\ncz q[0], q[1]", count=1)
     self.__store_function_assert_equal(0, Barrier,
                                        "\n# barrier gate q[0], q[1];")
     self.__store_function_assert_equal(
         1, Rz(angle), "\ncr q[0],q[1],{0:.12f}".format(angle), count=1)
     self.__store_function_assert_equal(
         1, R(angle), "\ncr q[0],q[1],{0:.12f}".format(angle), count=1)
     self.__store_function_assert_equal(1, Rx(angle),
                                        "\nrx q[1],{0}".format(angle))
     self.__store_function_assert_equal(1, Ry(angle),
                                        "\nry q[1],{0}".format(angle))
     self.__store_function_assert_equal(1, Rz(angle),
                                        "\nrz q[1],{0}".format(angle))
     self.__store_function_assert_equal(0, X, "\nx q[0]")
     self.__store_function_assert_equal(0, Y, "\ny q[0]")
     self.__store_function_assert_equal(0, Z, "\nz q[0]")
     self.__store_function_assert_equal(0, H, "\nh q[0]")
     self.__store_function_assert_equal(0, S, "\ns q[0]")
     self.__store_function_assert_equal(0, Sdag, "\nsdag q[0]")
     self.__store_function_assert_equal(0, T, "\nt q[0]")
     self.__store_function_assert_equal(0, Tdag, "\ntdag q[0]")
예제 #29
0
def test_tensor_or():
    saving_backend = DummyEngine(save_commands=True)
    main_engine = MainEngine(backend=saving_backend,
                             engine_list=[DummyEngine()])
    gate = Rx(0.6)
    qubit0 = Qubit(main_engine, 0)
    qubit1 = Qubit(main_engine, 1)
    qubit2 = Qubit(main_engine, 2)
    # Option 1:
    _metagates.Tensor(gate) | ([qubit0, qubit1, qubit2], )
    # Option 2:
    _metagates.Tensor(gate) | [qubit0, qubit1, qubit2]
    received_commands = []
    # Remove Allocate and Deallocate gates
    for cmd in saving_backend.received_commands:
        if not (isinstance(cmd.gate, FastForwardingGate)
                or isinstance(cmd.gate, ClassicalInstructionGate)):
            received_commands.append(cmd)
    # Check results
    assert len(received_commands) == 6
    qubit_ids = []
    for cmd in received_commands:
        assert len(cmd.qubits) == 1
        assert cmd.gate == gate
        qubit_ids.append(cmd.qubits[0][0].id)
    assert sorted(qubit_ids) == [0, 0, 1, 1, 2, 2]
예제 #30
0
def test_controlled_gate_or():
    saving_backend = DummyEngine(save_commands=True)
    main_engine = MainEngine(backend=saving_backend,
                             engine_list=[DummyEngine()])
    gate = Rx(0.6)
    qubit0 = Qubit(main_engine, 0)
    qubit1 = Qubit(main_engine, 1)
    qubit2 = Qubit(main_engine, 2)
    qubit3 = Qubit(main_engine, 3)
    expected_cmd = Command(main_engine, gate, ([qubit3], ))
    expected_cmd.add_control_qubits([qubit0, qubit1, qubit2])
    received_commands = []
    # Option 1:
    _metagates.ControlledGate(gate, 3) | ([qubit1], [qubit0], [qubit2
                                                               ], [qubit3])
    # Option 2:
    _metagates.ControlledGate(gate, 3) | (qubit1, qubit0, qubit2, qubit3)
    # Option 3:
    _metagates.ControlledGate(gate, 3) | ([qubit1, qubit0], qubit2, qubit3)
    # Option 4:
    _metagates.ControlledGate(gate, 3) | (qubit1, [qubit0, qubit2], qubit3)
    # Wrong option 5:
    with pytest.raises(_metagates.ControlQubitError):
        _metagates.ControlledGate(gate, 3) | (qubit1, [qubit0, qubit2, qubit3])
    # Remove Allocate and Deallocate gates
    for cmd in saving_backend.received_commands:
        if not (isinstance(cmd.gate, FastForwardingGate)
                or isinstance(cmd.gate, ClassicalInstructionGate)):
            received_commands.append(cmd)
    assert len(received_commands) == 4
    for cmd in received_commands:
        assert cmd == expected_cmd