示例#1
0
def oracle(eng):

    ControlledGate(Ph(theta), 2) | (output, des_output, ancilla_qubit2)
    X | output
    X | des_output
    ControlledGate(Ph(theta), 2) | (output, des_output, ancilla_qubit2)
    X | output
    X | des_output
示例#2
0
def _decompose_arb1qubit(cmd):
    """
    Use Z-Y decomposition of Nielsen and Chuang (Theorem 4.1).

    An arbitrary one qubit gate matrix can be writen as
    U = [[exp(j*(a-b/2-d/2))*cos(c/2), -exp(j*(a-b/2+d/2))*sin(c/2)],
         [exp(j*(a+b/2-d/2))*sin(c/2), exp(j*(a+b/2+d/2))*cos(c/2)]]
    where a,b,c,d are real numbers.
    Then U = exp(j*a) Rz(b) Ry(c) Rz(d).
    If the matrix is element of SU(2) (determinant == 1), then
    we can choose a = 0.
    """
    matrix = cmd.gate.matrix.tolist()
    a, b_half, c_half, d_half = _find_parameters(matrix)
    qb = cmd.qubits
    eng = cmd.engine
    with Control(eng, cmd.control_qubits):
        if Rz(2 * d_half) != Rz(0):
            Rz(2 * d_half) | qb
        if Ry(2 * c_half) != Ry(0):
            Ry(2 * c_half) | qb
        if Rz(2 * b_half) != Rz(0):
            Rz(2 * b_half) | qb
        if a != 0:
            Ph(a) | qb
示例#3
0
def lcu_oaa(eng,
            list_of_unitaries,
            coefts,
            ctrl,
            sys,
            ctrl_dim,
            sys_dim,
            rounds=1):
    phi = -1 * math.pi
    for i in range(0, rounds):
        cond_phase(eng, ctrl, sys, phi)
        with Dagger(eng):
            lcu_basic(eng, list_of_unitaries, coefts, ctrl, sys, ctrl_dim,
                      sys_dim)
        size = pow(2, ctrl_dim)
        for l in range(1, size):  # -R flips sign of everything except 00..0
            temp = np.binary_repr(i)
            temp = temp.zfill(ctrl_dim)  # pad with zeros for fixed length bin
        with Compute(eng):
            for j in range(0, ctrl_dim):
                if (int(temp[j]) == 0):
                    X | ctrl[j]
        with Control(eng, ctrl):
            Ph(phi) | sys[0]  # flip sign using any one sys qubit
        Uncompute(eng)
        lcu_basic(eng, list_of_unitaries, coefts, ctrl, sys, ctrl_dim, sys_dim)
        print("Amplitudes of ctrl+sys state after {} rounds of OAA:\n".format(
            int(i) + 1))
        print_amplitudes(eng, ctrl + sys, ctrl_dim + sys_dim)
示例#4
0
def test_openqasm_test_qasm_single_qubit_gates_control():
    backend = OpenQASMEngine()
    eng = MainEngine(backend=backend, engine_list=[])
    qubit = eng.allocate_qubit()
    ctrl = eng.allocate_qubit()

    with Control(eng, ctrl):
        H | qubit
        X | qubit
        Y | qubit
        Z | qubit
        NOT | qubit
        R(0.5) | qubit
        Rz(0.5) | qubit
        Ph(0.5) | qubit
    eng.flush()

    qasm = [l for l in backend.circuit.qasm().split('\n')[2:] if l]
    assert qasm == [
        'qreg q0[1];', 'qreg q1[1];', 'creg c0[1];', 'creg c1[1];',
        'ch q1[0],q0[0];', 'cx q1[0],q0[0];', 'cy q1[0],q0[0];',
        'cz q1[0],q0[0];', 'cx q1[0],q0[0];',
        'cu1(0.500000000000000) q1[0],q0[0];',
        'crz(0.500000000000000) q1[0],q0[0];',
        'cu1(-0.250000000000000) q1[0],q0[0];'
    ]
示例#5
0
def test_Ph_eigenvectors():
    rule_set = DecompositionRuleSet(modules=[pe, dqft])
    eng = MainEngine(backend=Simulator(),
                     engine_list=[
                         AutoReplacer(rule_set),
                     ])
    results = np.array([])
    for i in range(100):
        autovector = eng.allocate_qureg(1)
        theta = cmath.pi * 2. * 0.125
        unit = Ph(theta)
        ancillas = eng.allocate_qureg(3)
        QPE(unit) | (ancillas, autovector)
        All(Measure) | ancillas
        fasebinlist = [int(q) for q in ancillas]
        fasebin = ''.join(str(j) for j in fasebinlist)
        faseint = int(fasebin, 2)
        phase = faseint / (2.**(len(ancillas)))
        results = np.append(results, phase)
        All(Measure) | autovector
        eng.flush()

    num_phase = (results == 0.125).sum()
    assert num_phase / 100. >= 0.35, "Statistics phase calculation are not correct (%f vs. %f)" % (
        num_phase / 100., 0.35)
示例#6
0
def _decompose_h2rx_M(cmd):
    """ Decompose the Ry gate."""
    # Labelled 'M' for 'minus' because decomposition ends with a Ry(-pi/2)
    qubit = cmd.qubits[0]
    Rx(math.pi) | qubit
    Ph(math.pi / 2) | qubit
    Ry(-1 * math.pi / 2) | qubit
示例#7
0
def test_openqasm_test_qasm_single_qubit_gates():
    backend = OpenQASMEngine()
    eng = MainEngine(backend=backend, engine_list=[])
    qubit = eng.allocate_qubit()

    H | qubit
    S | qubit
    T | qubit
    Sdag | qubit
    Tdag | qubit
    X | qubit
    Y | qubit
    Z | qubit
    R(0.5) | qubit
    Rx(0.5) | qubit
    Ry(0.5) | qubit
    Rz(0.5) | qubit
    Ph(0.5) | qubit
    NOT | qubit
    Measure | qubit
    eng.flush()

    qasm = [l for l in backend.circuit.qasm().split('\n')[2:] if l]
    assert qasm == [
        'qreg q0[1];', 'creg c0[1];', 'h q0[0];', 's q0[0];', 't q0[0];',
        'sdg q0[0];', 'tdg q0[0];', 'x q0[0];', 'y q0[0];', 'z q0[0];',
        'u1(0.500000000000000) q0[0];', 'rx(0.500000000000000) q0[0];',
        'ry(0.500000000000000) q0[0];', 'rz(0.500000000000000) q0[0];',
        'u1(-0.250000000000000) q0[0];', 'x q0[0];', 'measure q0[0] -> c0[0];'
    ]
示例#8
0
def _decompose_QAA(cmd):
    """ Decompose the Quantum Amplitude Apmplification algorithm as a gate. """
    eng = cmd.engine

    # System-qubit is the first qubit/qureg. Ancilla qubit is the second qubit
    system_qubits = cmd.qubits[0]
    qaa_ancilla = cmd.qubits[1]

    # The Oracle and the Algorithm
    Oracle = cmd.gate.oracle
    A = cmd.gate.algorithm

    # Apply the oracle to invert the amplitude of the good states, S_Chi
    Oracle(eng, system_qubits, qaa_ancilla)

    # Apply the inversion of the Algorithm,
    # the inversion of the aplitude of |0> and the Algorithm

    with Compute(eng):
        with Dagger(eng):
            A(eng, system_qubits)
        All(X) | system_qubits
    with Control(eng, system_qubits[0:-1]):
        Z | system_qubits[-1]
    with CustomUncompute(eng):
        All(X) | system_qubits
        A(eng, system_qubits)
    Ph(math.pi) | system_qubits[0]
示例#9
0
def _decompose_state_preparation(cmd):  # pylint: disable=too-many-locals
    """Implement state preparation based on arXiv:quant-ph/0407010v1."""
    eng = cmd.engine
    if len(cmd.qubits) != 1:
        raise ValueError(
            'StatePreparation does not support multiple quantum registers!')
    num_qubits = len(cmd.qubits[0])
    qureg = cmd.qubits[0]
    final_state = cmd.gate.final_state
    if len(final_state) != 2**num_qubits:
        raise ValueError("Length of final_state is invalid.")
    norm = 0.0
    for amplitude in final_state:
        norm += abs(amplitude)**2
    if norm < 1 - 1e-10 or norm > 1 + 1e-10:
        raise ValueError("final_state is not normalized.")
    with Control(eng, cmd.control_qubits):
        # As in the paper reference, we implement the inverse:
        with Dagger(eng):
            # Cancel all the relative phases
            phase_of_blocks = []
            for amplitude in final_state:
                phase_of_blocks.append(cmath.phase(amplitude))
            for qubit_idx, qubit in enumerate(qureg):
                angles = []
                phase_of_next_blocks = []
                for block in range(2**(len(qureg) - qubit_idx - 1)):
                    phase0 = phase_of_blocks[2 * block]
                    phase1 = phase_of_blocks[2 * block + 1]
                    angles.append(phase0 - phase1)
                    phase_of_next_blocks.append((phase0 + phase1) / 2.0)
                UniformlyControlledRz(angles) | (
                    qureg[(qubit_idx + 1):],  # noqa: E203
                    qubit,
                )
                phase_of_blocks = phase_of_next_blocks
            # Cancel global phase
            Ph(-phase_of_blocks[0]) | qureg[-1]
            # Remove amplitudes from states which contain a bit value 1:
            abs_of_blocks = []
            for amplitude in final_state:
                abs_of_blocks.append(abs(amplitude))
            for qubit_idx, qubit in enumerate(qureg):
                angles = []
                abs_of_next_blocks = []
                for block in range(2**(len(qureg) - qubit_idx - 1)):
                    a0 = abs_of_blocks[2 * block]  # pylint: disable=invalid-name
                    a1 = abs_of_blocks[2 * block + 1]  # pylint: disable=invalid-name
                    if a0 == 0 and a1 == 0:
                        angles.append(0)
                    else:
                        angles.append(-2.0 *
                                      math.acos(a0 / math.sqrt(a0**2 + a1**2)))
                    abs_of_next_blocks.append(math.sqrt(a0**2 + a1**2))
                UniformlyControlledRy(angles) | (
                    qureg[(qubit_idx + 1):],  # noqa: E203
                    qubit,
                )
                abs_of_blocks = abs_of_next_blocks
示例#10
0
def _decompose_h2rx_N(cmd):
    """ Decompose the Ry gate."""
    # Labelled 'N' for 'neutral' because decomposition doesn't end with
    # Ry(pi/2) or Ry(-pi/2)
    qubit = cmd.qubits[0]
    Ry(math.pi / 2) | qubit
    Ph(3 * math.pi / 2) | qubit
    Rx(-1 * math.pi) | qubit
示例#11
0
def ffft_2d(engine, register, system_size):
    """Apply the 2D fermionic fast Fourier transform to a register.

    Args:
        engine (projectq.MainEngine): The simulator engine with the
                                      register.
        register (projectq.QuReg): The register to apply the 2D FFFT to.
        system_size (int): The side length of the system. register must
                           thus have system_size ** 2 qubits.

    Notes:
        This algorithm uses radix-2 decimation-in-time, so system_size
        must be a binary power. This decimation is head recursive (the
        2-mode FFFT is applied as the first part of the 4-mode FFFT,
        which is applied as the first part of the 8-mode FFFT, etc).
    """
    # Apply the FFFT along one axis of the register.
    for i in range(system_size):
        ffft(engine, register[system_size * i:system_size * i + system_size],
             system_size)
        Ph(3 * numpy.pi / 4) | register[0]

    # To apply the FFFT along the second axis, we must fermionically
    # swap qubits into the correct positions. In 2D this is equivalent
    # to flipping all qubits across the "diagonal" of the grid.
    key_2d = (index_of_position_in_1d_array, (0, 1))
    arr = [(i, j) for i in range(system_size) for j in range(system_size)]
    swaps = parallel_bubble_sort(arr, key_2d, system_size)
    all_swaps = [swap for swap_layer in swaps for swap in swap_layer]

    # Fermionically swap into position to FFFT along the second axis.
    for swap in all_swaps:
        Swap | (register[swap[0]], register[swap[1]])
        C(Z) | (register[swap[0]], register[swap[1]])

    # Perform the FFFT along the second axis.
    for i in range(system_size):
        ffft(engine, register[system_size * i:system_size * i + system_size],
             system_size)
        Ph(3 * numpy.pi / 4) | register[0]

    # Undo the fermionic swap network to restore the original ordering.
    for swap in all_swaps[::-1]:
        Swap | (register[swap[0]], register[swap[1]])
        C(Z) | (register[swap[0]], register[swap[1]])
示例#12
0
def _decompose_R(cmd):  # pylint: disable=invalid-name
    """Decompose the (controlled) phase-shift gate, denoted by R(phase)."""
    ctrl = cmd.control_qubits
    eng = cmd.engine
    gate = cmd.gate

    with Control(eng, ctrl):
        Ph(0.5 * gate.angle) | cmd.qubits
        Rz(gate.angle) | cmd.qubits
示例#13
0
def run_circuit(eng):
    qureg = eng.allocate_qureg(4)
    All(H) | qureg
    CRz(3.0) | (qureg[0], qureg[1])
    Toffoli | (qureg[1], qureg[2], qureg[3])

    with Control(eng, qureg[0:2]):
        Ph(1.43) | qureg[2]
    return qureg
示例#14
0
def _decompose_R(cmd):
    """ Decompose the (controlled) phase-shift gate, denoted by R(phase). """
    ctrl = cmd.control_qubits
    eng = cmd.engine
    gate = cmd.gate

    with Control(eng, ctrl):
        Ph(.5 * gate._angle) | cmd.qubits
        Rz(gate._angle) | cmd.qubits
示例#15
0
def test_ionq_invalid_command():
    """Test that this backend raises out with invalid commands."""

    # Ph gate is not a valid gate
    qb = WeakQubitRef(None, 1)
    cmd = Command(None, gate=Ph(math.pi), qubits=[(qb, )])
    backend = _ionq.IonQBackend(verbose=True)
    with pytest.raises(InvalidCommandError):
        backend.receive([cmd])
示例#16
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]
示例#17
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]
def _decompose_state_preparation(cmd):
    """
    Implements state preparation based on arXiv:quant-ph/0407010v1.
    """
    eng = cmd.engine
    assert len(cmd.qubits) == 1
    num_qubits = len(cmd.qubits[0])
    qureg = cmd.qubits[0]
    final_state = cmd.gate.final_state
    if len(final_state) != 2**num_qubits:
        raise ValueError("Length of final_state is invalid.")
    norm = 0.
    for amplitude in final_state:
        norm += abs(amplitude)**2
    if norm < 1 - 1e-10 or norm > 1 + 1e-10:
        raise ValueError("final_state is not normalized.")
    with Control(eng, cmd.control_qubits):
        # As in the paper reference, we implement the inverse:
        with Dagger(eng):
            # Cancel all the relative phases
            phase_of_blocks = []
            for amplitude in final_state:
                phase_of_blocks.append(cmath.phase(amplitude))
            for target_qubit in range(len(qureg)):
                angles = []
                phase_of_next_blocks = []
                for block in range(2**(len(qureg) - target_qubit - 1)):
                    phase0 = phase_of_blocks[2 * block]
                    phase1 = phase_of_blocks[2 * block + 1]
                    angles.append(phase0 - phase1)
                    phase_of_next_blocks.append((phase0 + phase1) / 2.)
                UniformlyControlledRz(angles) | (qureg[(target_qubit + 1):],
                                                 qureg[target_qubit])
                phase_of_blocks = phase_of_next_blocks
            # Cancel global phase
            Ph(-phase_of_blocks[0]) | qureg[-1]
            # Remove amplitudes from states which contain a bit value 1:
            abs_of_blocks = []
            for amplitude in final_state:
                abs_of_blocks.append(abs(amplitude))
            for target_qubit in range(len(qureg)):
                angles = []
                abs_of_next_blocks = []
                for block in range(2**(len(qureg) - target_qubit - 1)):
                    a0 = abs_of_blocks[2 * block]
                    a1 = abs_of_blocks[2 * block + 1]
                    if a0 == 0 and a1 == 0:
                        angles.append(0)
                    else:
                        angles.append(-2. *
                                      math.acos(a0 / math.sqrt(a0**2 + a1**2)))
                    abs_of_next_blocks.append(math.sqrt(a0**2 + a1**2))
                UniformlyControlledRy(angles) | (qureg[(target_qubit + 1):],
                                                 qureg[target_qubit])
                abs_of_blocks = abs_of_next_blocks
示例#19
0
 def test_is_available_correct_result(self):
     self.__is_available_assert_equal(NOT, True, count=1)
     self.__is_available_assert_equal(NOT, False, count=3)
     self.__is_available_assert_equal(CNOT, False, count=0)
     self.__is_available_assert_equal(Z, True, count=1)
     self.__is_available_assert_equal(Z, False, count=3)
     self.__is_available_assert_equal(Ph(0.4), False)
     self.__is_available_assert_equal(Toffoli, False)
     for gate in [Measure, Allocate, Deallocate, Barrier, T, Tdag,
                  S, Sdag, Swap, H, X, Y, Z, Rx(0.1), Ry(0.2), Rz(0.3)]:
         self.__is_available_assert_equal(gate, True)
示例#20
0
def test_recognize_correct_gates():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend)
    qubit = eng.allocate_qubit()
    Ph(0.1) | qubit
    R(0.2) | qubit
    Rx(0.3) | qubit
    X | qubit
    eng.flush(deallocate_qubits=True)
    # Don't test initial allocate and trailing deallocate and flush gate.
    for cmd in saving_backend.received_commands[1:-2]:
        assert arb1q._recognize_arb1qubit(cmd)
示例#21
0
def run_grover(eng, n, oracle):
    """
    Runs Grover's algorithm on n qubit using the provided quantum oracle.

    Args:
        eng (MainEngine): Main compiler engine to run Grover on.
        n (int): Number of bits in the solution.
        oracle (function): Function accepting the engine, an n-qubit register,
            and an output qubit which is flipped by the oracle for the correct
            bit string.

    Returns:
        solution (list<int>): Solution bit-string.
    """
    x = eng.allocate_qureg(n)

    # start in uniform superposition
    All(H) | x

    # number of iterations we have to run:
    num_it = int(math.pi / 4. * math.sqrt(1 << n))
    print("Number of iterations we have to run: {}".format(num_it))

    # prepare the oracle output qubit (the one that is flipped to indicate the
    # solution. start in state 1/sqrt(2) * (|0> - |1>) s.t. a bit-flip turns
    # into a (-1)-phase.
    oracle_out = eng.allocate_qubit()
    X | oracle_out
    H | oracle_out

    # run num_it iterations
    with Loop(eng, num_it):
        # oracle adds a (-1)-phase to the solution
        oracle(eng, x, oracle_out)

        # reflection across uniform superposition
        with Compute(eng):
            All(H) | x
            All(X) | x

        with Control(eng, x[0:-1]):
            Z | x[-1]

        Uncompute(eng)

        All(Ph(math.pi / n)) | x

    All(Measure) | x
    Measure | oracle_out

    eng.flush()
    # return result
    return [int(qubit) for qubit in x]
示例#22
0
def test_qubitop2singlequbit():
    num_qubits = 4
    random_initial_state = [
        0.2 + 0.1 * x * cmath.exp(0.1j + 0.2j * x)
        for x in range(2**(num_qubits + 1))
    ]
    rule_set = DecompositionRuleSet(modules=[qubitop2onequbit])
    test_eng = MainEngine(
        backend=Simulator(),
        engine_list=[AutoReplacer(rule_set),
                     InstructionFilter(_decomp_gates)],
    )
    test_qureg = test_eng.allocate_qureg(num_qubits)
    test_ctrl_qb = test_eng.allocate_qubit()
    test_eng.flush()
    test_eng.backend.set_wavefunction(random_initial_state,
                                      test_qureg + test_ctrl_qb)
    correct_eng = MainEngine()
    correct_qureg = correct_eng.allocate_qureg(num_qubits)
    correct_ctrl_qb = correct_eng.allocate_qubit()
    correct_eng.flush()
    correct_eng.backend.set_wavefunction(random_initial_state,
                                         correct_qureg + correct_ctrl_qb)

    qubit_op_0 = QubitOperator("X0 Y1 Z3", -1.0j)
    qubit_op_1 = QubitOperator("Z0 Y1 X3", cmath.exp(0.6j))

    qubit_op_0 | test_qureg
    with Control(test_eng, test_ctrl_qb):
        qubit_op_1 | test_qureg
    test_eng.flush()

    correct_eng.backend.apply_qubit_operator(qubit_op_0, correct_qureg)
    with Control(correct_eng, correct_ctrl_qb):
        Ph(0.6) | correct_qureg[0]
        Z | correct_qureg[0]
        Y | correct_qureg[1]
        X | correct_qureg[3]
    correct_eng.flush()

    for fstate in range(2**(num_qubits + 1)):
        binary_state = format(fstate, '0' + str(num_qubits + 1) + 'b')
        test = test_eng.backend.get_amplitude(binary_state,
                                              test_qureg + test_ctrl_qb)
        correct = correct_eng.backend.get_amplitude(
            binary_state, correct_qureg + correct_ctrl_qb)
        assert correct == pytest.approx(test, rel=1e-10, abs=1e-10)

    All(Measure) | correct_qureg + correct_ctrl_qb
    All(Measure) | test_qureg + test_ctrl_qb
    correct_eng.flush()
    test_eng.flush()
def test_decompose_commuting_terms():
    saving_backend = DummyEngine(save_commands=True)

    def my_filter(self, cmd):
        if len(cmd.qubits[0]) <= 2 or isinstance(cmd.gate,
                                                 ClassicalInstructionGate):
            return True
        return False

    rules = DecompositionRuleSet([te.rule_commuting_terms])
    replacer = AutoReplacer(rules)
    filter_eng = InstructionFilter(my_filter)
    eng = MainEngine(backend=saving_backend,
                     engine_list=[replacer, filter_eng])
    qureg = eng.allocate_qureg(5)
    with Control(eng, qureg[3]):
        op1 = QubitOperator("X1 Y2", 0.7)
        op2 = QubitOperator("Y2 X4", -0.8)
        op3 = QubitOperator((), 0.6)
        TimeEvolution(1.5, op1 + op2 + op3) | qureg

    cmd1 = saving_backend.received_commands[5]
    cmd2 = saving_backend.received_commands[6]
    cmd3 = saving_backend.received_commands[7]

    found = [False, False, False]
    scaled_op1 = QubitOperator("X0 Y1", 0.7)
    scaled_op2 = QubitOperator("Y0 X1", -0.8)
    for cmd in [cmd1, cmd2, cmd3]:
        if (cmd.gate == Ph(-1.5 * 0.6) and cmd.qubits[0][0].id == qureg[1].id
                and cmd.control_qubits[0].id
                == qureg[3].id  # 1st qubit of [1,2,4]
            ):
            found[0] = True
        elif (isinstance(cmd.gate, TimeEvolution)
              and cmd.gate.hamiltonian.isclose(scaled_op1)
              and cmd.gate.time == pytest.approx(1.5)
              and cmd.qubits[0][0].id == qureg[1].id
              and cmd.qubits[0][1].id == qureg[2].id
              and cmd.control_qubits[0].id == qureg[3].id):
            found[1] = True
        elif (isinstance(cmd.gate, TimeEvolution)
              and cmd.gate.hamiltonian.isclose(scaled_op2)
              and cmd.gate.time == pytest.approx(1.5)
              and cmd.qubits[0][0].id == qureg[2].id
              and cmd.qubits[0][1].id == qureg[4].id
              and cmd.control_qubits[0].id == qureg[3].id):
            found[2] = True
    assert all(found)
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()
    with Control(eng, ctrl_qubit):
        Ph(0.1) | qubit
        R(0.2) | qubit
        Rx(0.3) | qubit
        X | qubit
    eng.flush(deallocate_qubits=True)
    # Don't test initial two allocate and flush and trailing deallocate
    # and flush gate.
    for cmd in saving_backend.received_commands[3:-3]:
        assert carb1q._recognize_carb1qubit(cmd)
示例#25
0
def _decompose_qubitop(cmd):
    assert len(cmd.qubits) == 1
    qureg = cmd.qubits[0]
    eng = cmd.engine
    qubit_op = cmd.gate
    with Control(eng, cmd.control_qubits):
        (term, coefficient), = qubit_op.terms.items()
        phase = cmath.phase(coefficient)
        Ph(phase) | qureg[0]
        for index, action in term:
            if action == "X":
                X | qureg[index]
            elif action == "Y":
                Y | qureg[index]
            elif action == "Z":
                Z | qureg[index]
def test_or_gate_identity():
    saving_backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=saving_backend, engine_list=[])
    qureg = eng.allocate_qureg(4)
    hamiltonian = QubitOperator((), 3.4)
    correct_h = copy.deepcopy(hamiltonian)
    gate = te.TimeEvolution(2.1, hamiltonian)
    gate | qureg
    eng.flush()
    cmd = saving_backend.received_commands[4]
    assert isinstance(cmd.gate, Ph)
    assert cmd.gate == Ph(-3.4 * 2.1)
    correct = numpy.array([[cmath.exp(-1j * 3.4 * 2.1), 0],
                           [0, cmath.exp(-1j * 3.4 * 2.1)]])
    print(correct)
    print(cmd.gate.matrix)
    assert numpy.allclose(cmd.gate.matrix, correct)
示例#27
0
def _decompose_qubitop(cmd):
    if len(cmd.qubits) != 1:
        raise ValueError('QubitOperator decomposition can only accept a single quantum register')
    qureg = cmd.qubits[0]
    eng = cmd.engine
    qubit_op = cmd.gate
    with Control(eng, cmd.control_qubits):
        ((term, coefficient),) = qubit_op.terms.items()
        phase = cmath.phase(coefficient)
        Ph(phase) | qureg[0]
        for index, action in term:
            if action == "X":
                X | qureg[index]
            elif action == "Y":
                Y | qureg[index]
            elif action == "Z":
                Z | qureg[index]
示例#28
0
def alternating_bits_oracle_modified(eng, qubits, output, phi):
    """
    Marks the solution string 0,1,0,... by applying phase gate to the output bits,
    conditioned on qubits being equal to the alternating bit-string.

    Args:
        eng (MainEngine): Main compiler engine the algorithm is being run on.
        qubits (Qureg): n-qubit quantum register Grover search is run on.
        output (Qubit): Output qubit to mark the solution by a phase gate with parameter phi.
    """
    with Compute(eng):
        All(X) | qubits[1::2]
    with Control(eng, qubits):
        Rz(phi) | output
        Ph(phi/2) | output

    Uncompute(eng)
    def test_8mode_ffft_with_external_swaps_on_single_logical_state(self):
        n_qubits = 8
        grid = Grid(dimensions=1, length=n_qubits, scale=1.0)

        eng = MainEngine()
        register = eng.allocate_qureg(n_qubits)

        state_index = 157

        prepare_logical_state(register, state_index)

        ffft(eng, register, n_qubits)
        Ph(3 * numpy.pi / 4) | register[0]
        eng.flush()
        wvfn = ordered_wavefunction(eng)

        fermion_operator = prepare_integer_fermion_operator(state_index)

        # Swap 01234567 to 45670123 for fourier_transform. Additionally,
        # the FFFT's ordering is 04261537, so swap 04261537 to 01234567,
        # and then 01234567 to 45670123.
        swap_mode_list = ([1, 3, 5, 2, 4, 1, 3, 5] +
                          [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3])
        for mode in swap_mode_list:
            fermion_operator = normal_ordered(fermion_operator)
            fermion_operator = swap_adjacent_fermionic_modes(
                fermion_operator, mode)

        ffft_result = fourier_transform(fermion_operator,
                                        grid, spinless=True)
        ffft_result = normal_ordered(ffft_result)

        # After the FFFT, swap 45670123 -> 01234567.
        swap_mode_list = [3, 2, 4, 1, 3, 5, 0, 2, 4, 6, 1, 3, 5, 2, 4, 3]
        for mode in swap_mode_list:
            ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode)

        converted_wvfn = numpy.zeros(2 ** n_qubits, dtype=complex)
        for term in ffft_result.terms:
            index = sum(2 ** site[0] for site in term)
            converted_wvfn[index] = ffft_result.terms[term]

        All(Measure) | register

        self.assertTrue(numpy.allclose(wvfn, converted_wvfn))
示例#30
0
    def test_4mode_ffft_with_external_swaps_all_logical_states(self):
        n_qubits = 4

        grid = Grid(dimensions=1, length=n_qubits, scale=1.0)

        for i in range(2**n_qubits):
            eng = MainEngine()
            register = eng.allocate_qureg(n_qubits)
            prepare_logical_state(register, i)

            ffft(eng, register, n_qubits)
            Ph(3 * numpy.pi / 4) | register[0]
            eng.flush()
            wvfn = ordered_wavefunction(eng)

            fermion_operator = prepare_integer_fermion_operator(i)

            # Reorder the modes for correct input to the FFFT.
            # Swap 0123 to 2301 for fourier_transform. Additionally, the
            # FFFT's ordering is 0213, so connect 0213 -> 0123 -> 2301.
            swap_mode_list = [1] + [1, 0, 2, 1]
            for mode in swap_mode_list:
                fermion_operator = normal_ordered(fermion_operator)
                fermion_operator = swap_adjacent_fermionic_modes(
                    fermion_operator, mode)

            ffft_result = fourier_transform(fermion_operator,
                                            grid,
                                            spinless=True)
            ffft_result = normal_ordered(ffft_result)

            swap_mode_list = [1, 0, 2, 1]  # After FFFT, swap 2301 -> 0123
            for mode in swap_mode_list:
                ffft_result = swap_adjacent_fermionic_modes(ffft_result, mode)

            converted_wvfn = numpy.zeros(2**n_qubits, dtype=complex)
            for term in ffft_result.terms:
                index = sum(2**site[0] for site in term)
                converted_wvfn[index] = ffft_result.terms[term]

            All(Measure) | register

            self.assertTrue(numpy.allclose(wvfn, converted_wvfn))