def test_simulation_cnot():
    """
    Test if the simulation of CNOT is accurate
    :return:
    """
    prog = Program().inst([H(0), CNOT(0, 1)])
    qvmstab = QVM_Stabilizer(num_qubits=2)
    qvmstab._apply_hadamard(prog.instructions[0])
    qvmstab._apply_cnot(prog.instructions[1])

    # assert that ZZ XX stabilizes a bell state
    true_stabilizers = [sX(0) * sX(1), sZ(0) * sZ(1)]
    test_paulis = binary_stabilizer_to_pauli_stabilizer(qvmstab.tableau[2:, :])
    for idx, term in enumerate(test_paulis):
        assert term == true_stabilizers[idx]

    # test that CNOT does nothing to |00> state
    prog = Program().inst([CNOT(0, 1)])
    qvmstab = QVM_Stabilizer(num_qubits=2)
    qvmstab._apply_cnot(prog.instructions[0])
    true_tableau = np.array([
        [1, 1, 0, 0, 0],  # X1 -> X1 X2
        [0, 1, 0, 0, 0],  # X2 -> X2
        [0, 0, 1, 0, 0],  # Z1 -> Z1
        [0, 0, 1, 1, 0]
    ])  # Z2 -> Z1 Z2

    # note that Z1, Z1 Z2 still stabilizees |00>
    assert np.allclose(true_tableau, qvmstab.tableau)

    # test that CNOT produces 11 state after X
    prog = Program().inst([H(0), S(0), S(0), H(0), CNOT(0, 1)])
    qvmstab = QVM_Stabilizer(num_qubits=2)
    qvmstab._apply_hadamard(prog.instructions[0])
    qvmstab._apply_phase(prog.instructions[1])
    qvmstab._apply_phase(prog.instructions[2])
    qvmstab._apply_hadamard(prog.instructions[3])
    qvmstab._apply_cnot(prog.instructions[4])
    true_tableau = np.array([[1, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 1],
                             [0, 0, 1, 1, 0]])

    # note that -Z1, Z1 Z2 still stabilizees |11>
    assert np.allclose(true_tableau, qvmstab.tableau)

    test_paulis = binary_stabilizer_to_pauli_stabilizer(
        qvmstab.stabilizer_tableau())
    state = project_stabilized_state(test_paulis,
                                     qvmstab.num_qubits,
                                     classical_state=[1, 1])
    state_2 = project_stabilized_state(test_paulis, qvmstab.num_qubits)

    assert np.allclose(np.array(state.todense()), np.array(state_2.todense()))
def test_measurement_commuting_result_one():
    """
    Test measuremt of stabilzier state from tableau

    This tests when the measurement operator commutes with the stabilizers

    This time we will generate the stabilizer -Z|1> = |1> so we we need to do
    a bitflip...not just identity.  A Bitflip is HSSH = X
    """
    identity_program = Program().inst([H(0), S(0), S(0), H(0)]).measure(0, 0)
    qvmstab = QVM_Stabilizer()
    results = qvmstab.run(identity_program, trials=1000)
    assert all(np.array(results) == 1)
Esempio n. 3
0
def test_dagger():
    p = Program(X(0), H(0))
    assert p.dagger().out() == "DAGGER H 0\nDAGGER X 0\n"

    p = Program(X(0), MEASURE(0, MemoryReference("ro", 0)))
    with pytest.raises(ValueError):
        p.dagger().out()

    # ensure that modifiers are preserved https://github.com/rigetti/pyquil/pull/914
    p = Program()
    control = 0
    target = 1
    cnot_control = 2
    p += X(target).controlled(control)
    p += Y(target).controlled(control)
    p += Z(target).controlled(control)
    p += H(target).controlled(control)
    p += S(target).controlled(control)
    p += T(target).controlled(control)
    p += PHASE(pi, target).controlled(control)
    p += CNOT(cnot_control, target).controlled(control)

    for instr, instr_dagger in zip(reversed(p._instructions),
                                   p.dagger()._instructions):
        assert "DAGGER " + instr.out() == instr_dagger.out()
Esempio n. 4
0
def expectation(pauli, qubit):
    """Returns a pyquil.Program with the correct basis measurement 
    for the given Pauli operator and qubit.
    
    Args:
        pauli : str
            Either "X", "Y", or "Z".

        qubit : int
            Index of qubit in the Hamiltonian.
            Note: This should be an actual physical qubit index
                  on the qubit lattice being considered if running
                  on a quantum chip.
    """
    # Get the index of the classical register for the given qubit index
    if qubit == 10:
        ind = 0
    elif qubit == 11:
        ind = 1
    elif qubit == 17:
        ind = 2
    else:
        raise ValueError(
            "Unsupported qubit index for computer. Rigetti will let you know about this..."
        )

    # Do the appropriate basis measurement
    if pauli == "Z":
        return Program(MEASURE(qubit, creg[ind]))
    elif pauli == "X":
        return Program(H(qubit), MEASURE(qubit, creg[ind]))
    elif pauli == "Y":
        return Program(S(qubit), H(qubit), MEASURE(qubit, creg[ind]))
    else:
        raise ValueError("Unsupported operator. Enter X, Y, or Z.")
Esempio n. 5
0
    def _evaluate_single_term(self, ansatz_circuit: Program,
                              meas_term: PauliTerm) -> np.ndarray:
        """Compute the expectation value of a single PauliTerm , given a quantum circuit to evaluate on.
        
        Args:
            ansatz_circuit: A Program representing the quantum state to evaluate the PauliTerm on.
            
            meas_term: a PauliTerm object to be evaluated.
        
        """
        # First, create the quantum circuit needed for evaluation.

        # concatenate operator (converted to a Program) and ansatz circuit
        expectation_circuit = ansatz_circuit.copy()

        expectation_circuit += meas_term.program

        ro = expectation_circuit.declare('ro', 'BIT',
                                         len(meas_term.get_qubits()))

        # add necessary post-rotations and measurement
        for i, qubit in enumerate(sorted(list(meas_term.get_qubits()))):

            if meas_term.pauli_string([qubit]) == 'X':
                expectation_circuit += H(qubit)
            elif meas_term.pauli_string([qubit]) == 'Y':
                expectation_circuit += H(qubit)
                expectation_circuit += S(qubit)

            expectation_circuit += Program().measure(qubit, ro[i])

        result = self._run(expectation_circuit,
                           num_shots=self._num_shots_evaluation)

        return result
Esempio n. 6
0
def test_dagger():
    # these gates are their own inverses
    p = Program().inst(I(0), X(0), Y(0), Z(0),
                       H(0), CNOT(0, 1), CCNOT(0, 1, 2),
                       SWAP(0, 1), CSWAP(0, 1, 2))
    assert p.dagger().out() == 'CSWAP 0 1 2\nSWAP 0 1\n' \
                               'CCNOT 0 1 2\nCNOT 0 1\nH 0\n' \
                               'Z 0\nY 0\nX 0\nI 0\n'

    # these gates require negating a parameter
    p = Program().inst(PHASE(pi, 0), RX(pi, 0), RY(pi, 0),
                       RZ(pi, 0), CPHASE(pi, 0, 1),
                       CPHASE00(pi, 0, 1), CPHASE01(pi, 0, 1),
                       CPHASE10(pi, 0, 1), PSWAP(pi, 0, 1))
    assert p.dagger().out() == 'PSWAP(-pi) 0 1\n' \
                               'CPHASE10(-pi) 0 1\n' \
                               'CPHASE01(-pi) 0 1\n' \
                               'CPHASE00(-pi) 0 1\n' \
                               'CPHASE(-pi) 0 1\n' \
                               'RZ(-pi) 0\n' \
                               'RY(-pi) 0\n' \
                               'RX(-pi) 0\n' \
                               'PHASE(-pi) 0\n'

    # these gates are special cases
    p = Program().inst(S(0), T(0), ISWAP(0, 1))
    assert p.dagger().out() == 'PSWAP(pi/2) 0 1\n' \
                               'RZ(pi/4) 0\n' \
                               'PHASE(-pi/2) 0\n'

    # must invert defined gates
    G = np.array([[0, 1], [0 + 1j, 0]])
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger().out() == 'DEFGATE G-INV:\n' \
                               '    0.0, -i\n' \
                               '    1.0, 0.0\n\n' \
                               'G-INV 0\n'

    # can also pass in a list of inverses
    inv_dict = {"G": "J"}
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger(inv_dict=inv_dict).out() == 'J 0\n'

    # defined parameterized gates cannot auto generate daggered version https://github.com/rigetticomputing/pyquil/issues/304
    theta = Parameter('theta')
    gparam_matrix = np.array([[quil_cos(theta / 2), -1j * quil_sin(theta / 2)],
                             [-1j * quil_sin(theta / 2), quil_cos(theta / 2)]])
    g_param_def = DefGate('GPARAM', gparam_matrix, [theta])
    p = Program(g_param_def)
    with pytest.raises(TypeError):
        p.dagger()

    # defined parameterized gates should passback parameters https://github.com/rigetticomputing/pyquil/issues/304
    GPARAM = g_param_def.get_constructor()
    p = Program(GPARAM(pi)(1, 2))
    assert p.dagger().out() == 'GPARAM-INV(pi) 1 2\n'
Esempio n. 7
0
def prepare_measurement(qubit, direction, program):
    if direction == 'x':
        program += H(qubit)
    else:
        program += H(qubit)
        program_S_dagger = Program()
        program_S_dagger += S(qubit)
        program += program_S_dagger.dagger()

    return program
def test_simulation_phase():
    """
    Test if the Phase gate is applied correctly to the tableau

    S|0> = |0>

    S|+> = |R>
    """
    prog = Program().inst(S(0))
    qvmstab = QVM_Stabilizer(num_qubits=1)
    qvmstab._apply_phase(prog.instructions[0])
    true_stab = np.array([[1, 1, 0], [0, 1, 0]])
    assert np.allclose(true_stab, qvmstab.tableau)

    prog = Program().inst([H(0), S(0)])
    qvmstab = QVM_Stabilizer(num_qubits=1)
    qvmstab._apply_hadamard(prog.instructions[0])
    qvmstab._apply_phase(prog.instructions[1])
    true_stab = np.array([[0, 1, 0], [1, 1, 0]])
    assert np.allclose(true_stab, qvmstab.tableau)
Esempio n. 9
0
def test_dagger():
    # these gates are their own inverses
    p = Program().inst(I(0), X(0), Y(0), Z(0),
                       H(0), CNOT(0,1), CCNOT(0,1,2),
                       SWAP(0,1), CSWAP(0,1,2))
    assert p.dagger().out() == 'CSWAP 0 1 2\nSWAP 0 1\n' \
                      'CCNOT 0 1 2\nCNOT 0 1\nH 0\n' \
                      'Z 0\nY 0\nX 0\nI 0\n'

    # these gates require negating a parameter
    p = Program().inst(PHASE(pi, 0), RX(pi, 0), RY(pi, 0),
                       RZ(pi, 0), CPHASE(pi, 0, 1),
                       CPHASE00(pi, 0, 1), CPHASE01(pi, 0, 1),
                       CPHASE10(pi, 0, 1), PSWAP(pi, 0, 1))
    assert p.dagger().out() == 'PSWAP(-3.141592653589793) 0 1\n' \
                               'CPHASE10(-3.141592653589793) 0 1\n' \
                               'CPHASE01(-3.141592653589793) 0 1\n' \
                               'CPHASE00(-3.141592653589793) 0 1\n' \
                               'CPHASE(-3.141592653589793) 0 1\n' \
                               'RZ(-3.141592653589793) 0\n' \
                               'RY(-3.141592653589793) 0\n' \
                               'RX(-3.141592653589793) 0\n' \
                               'PHASE(-3.141592653589793) 0\n'

    # these gates are special cases
    p = Program().inst(S(0), T(0), ISWAP(0, 1))
    assert p.dagger().out() == 'PSWAP(1.5707963267948966) 0 1\n' \
                               'RZ(0.7853981633974483) 0\n' \
                               'PHASE(-1.5707963267948966) 0\n'

    # must invert defined gates
    G = np.array([[0, 1], [0+1j, 0]])
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger().out() == 'DEFGATE G-INV:\n' \
                               '    0.0+-0.0i, 0.0-1.0i\n' \
                               '    1.0+-0.0i, 0.0+-0.0i\n\n' \
                               'G-INV 0\n'

    # can also pass in a list of inverses
    inv_dict = {"G":"J"}
    p = Program().defgate("G", G).inst(("G", 0))
    assert p.dagger(inv_dict=inv_dict).out() == 'J 0\n'
Esempio n. 10
0
def get_test_program(measure: bool = False) -> Program:
    PI = float(pi.evalf())
    p = Program()
    p += X(0)
    p += Y(1)
    p += Z(2)
    p += H(3)
    p += S(0)
    p += T(1)
    p += RX(PI / 2, 2)
    p += RY(PI / 2, 3)
    p += RZ(PI / 2, 0)
    p += CZ(0, 1)
    p += CNOT(2, 3)
    p += CCNOT(0, 1, 2)
    p += CPHASE(PI / 4, 2, 1)
    p += SWAP(0, 3)
    if measure:
        ro = p.declare("ro", "BIT", 4)
        p += MEASURE(0, ro[0])
        p += MEASURE(3, ro[1])
        p += MEASURE(2, ro[2])
        p += MEASURE(1, ro[3])
    return p
Esempio n. 11
0
def test_singles():
    p = Program(I(0), X(0), Y(1), Z(1), H(2), T(2), S(1))
    assert p.out() == "I 0\nX 0\nY 1\nZ 1\nH 2\nT 2\nS 1\n"
Esempio n. 12
0
#
# job = execute(circ, backend, shots=10)
# result = job.result()
# counts = result.get_counts(circ)
#
# print(counts)

## personal testing

# theoretical_probs =  {'00000': 0.10139983459411607, '00001': 0.01735805702132643, '00010': 0.017358057021326437, '00011': 0.043801529890753046, '00100': 0.017358057021326423, '00101': 0.043801529890753046, '00110': 0.043801529890753046, '00111': 0.0017330570213264689, '01000': 0.017358057021326437, '01001': 0.04380152989075303, '01010': 0.043801529890753046, '01011': 0.0017330570213264678, '01100': 0.04380152989075303, '01101': 0.0017330570213264689, '01110': 0.0017330570213264678, '01111': 0.05942652989075301, '10000': 0.017358057021326437, '10001': 0.04380152989075307, '10010': 0.04380152989075308, '10011': 0.0017330570213264678, '10100': 0.04380152989075307, '10101': 0.0017330570213264689, '10110': 0.0017330570213264678, '10111': 0.05942652989075301, '11000': 0.04380152989075308, '11001': 0.0017330570213264695, '11010': 0.0017330570213264695, '11011': 0.05942652989075301, '11100': 0.0017330570213264654, '11101': 0.05942652989075301, '11110': 0.05942652989075301, '11111': 0.05933136172468943}
# experimental_probs = {'00000': 0.0997, '00001': 0.0175, '00010': 0.015, '00011': 0.0418, '00100': 0.017, '00101': 0.0459, '00110': 0.0443, '00111': 0.0018, '01000': 0.0155, '01001': 0.0471, '01010': 0.0451, '01011': 0.0015, '01100': 0.039, '01101': 0.0018, '01110': 0.0014, '01111': 0.0611, '10000': 0.0201, '10001': 0.0449, '10010': 0.043, '10011': 0.0021, '10100': 0.0446, '10101': 0.0023, '10110': 0.0022, '10111': 0.0582, '11000': 0.0435, '11001': 0.0018, '11010': 0.0016, '11011': 0.0595, '11100': 0.0024, '11101': 0.0631, '11110': 0.0612, '11111': 0.054}
#
#
# for key in theoretical_probs.keys():
#     if key in experimental_probs.keys():
#         print("present")
#     else:
#         print("not present")

from pyquil.quil import Gate
from pyquil.gates import H, CNOT, S
from pyquil import Program, get_qc
from pyquil.latex import to_latex
from pyquil.api import local_qvm

qvm = get_qc('3q-qvm')
program = Program(H(2))
program += S(2)
program += Gate.dagger(S(2))

print(to_latex(program))
Esempio n. 13
0
def test_S():
    u1 = program_unitary(Program(S(0)), n_qubits=1)
    u2 = program_unitary(_S(0), n_qubits=1)
    assert equal_up_to_global_phase(u1, u2, atol=1e-12)