Пример #1
0
def test_to_latex():
    """A test to give full coverage of latex_generation and latex_config."""
    qubits = range(3)
    p = Program()
    p.inst(X(qubits[0]), Y(qubits[0]), CZ(qubits[0], qubits[2]),
           SWAP(qubits[0], qubits[1]), MEASURE(qubits[0], None),
           CNOT(qubits[2], qubits[0]))
    _ = to_latex(p)

    # Modify settings to access non-standard control paths.
    settings = get_default_settings()
    settings['gates']['AllocateQubitGate']['draw_id'] = True
    settings['gate_shadow'] = None
    _ = to_latex(p, settings)

    settings['control']['shadow'] = True
    _ = to_latex(p, settings)
Пример #2
0
def phase_estimation(ancillary_start,
                     ancillary_num,
                     time,
                     atomic_distance,
                     state,
                     trails=5,
                     trotter_order=2):
    """
    Measures the phase by using the phase estimation algorithm (PEA)

    :param ancillary_start: first ancillary qubit
    :param ancillary_num: how many ancillaries to use corresponds
            to precision in PEA algorithm
    :param time: t in exp(-iHt), where H is the Hamiltonian
    :param atomic_distance:  the distance between to H atoms in H2 molecule
    :param state: ground state (0) or some excited state (1, 2, 3)
    :param trails: how many measurement to make in order to estimate the most
                    frequent result

    :return: the phase from exp(-iHt) |psi> = exp(-i2pi phase) |psi> (Schrodinger)
    """

    # initialization of the state
    init_qubit = Program()
    if state == 0:
        init_qubit.inst(X(0)).inst(X(1))
    elif state == 1:
        init_qubit.inst(X(0)).inst(X(2))
    elif state == 2:
        init_qubit.inst(X(0)).inst(X(3))
    elif state == 3:
        init_qubit.inst(X(2)).inst(X(3))
    else:
        print(
            "Wrong input of state. State should be 0, 1, 2, 3. Your input is "
            + str(state))
        raise ValueError
    prog = init_qubit + pea_program(ancillary_start, ancillary_num, time,
                                    atomic_distance, trotter_order)

    ro = prog.declare('ro', memory_type='BIT', memory_size=ancillary_num)
    # measurement of ancillary qubits
    for cindex, qindex in enumerate(
            range(ancillary_start, ancillary_start + ancillary_num)):
        prog += MEASURE(qindex, ro[cindex])

    qvm = QVMConnection()
    cregister = list(range(0, ancillary_num))
    m_reg = qvm.run(prog, cregister, trails)

    # taking most frequent result from the phase elements. The number of the elements are defined by the trails
    phase, major_index = majority_and_index(
        [bitstring_to_value(bitst) for bitst in m_reg])
    print(str(phase) + "  =  " + str(m_reg[major_index]))

    return phase
Пример #3
0
def test_halt():
    prog = Program(Declare('ro', 'BIT'), X(0),
                   MEASURE(0, MemoryReference("ro", 0)))
    prog.inst(HALT)
    prog.inst(X(0), MEASURE(0, MemoryReference("ro", 0)))
    qam = PyQVM(n_qubits=1,
                quantum_simulator_type=ReferenceWavefunctionSimulator)
    qam.execute(prog)
    # HALT should stop execution; measure should give 1
    assert qam.ram['ro'][0] == 1

    prog = Program(Declare('ro', 'BIT'),
                   X(0)).inst(X(0)).inst(MEASURE(0, MemoryReference("ro", 0)))
    qam = PyQVM(n_qubits=1,
                quantum_simulator_type=ReferenceWavefunctionSimulator)
    qam.execute(prog)
    assert qam.ram['ro'][0] == 0
Пример #4
0
def inv_qft_core(qubits):
    """
    Generates a quil programm that performs 
    inverse quantum fourier transform on given qubits 
    without swaping qubits at the end.
    
    :param qubits: A list of qubit indexes.
    :return: A Quil program to compute the invese QFT of the given qubits without swapping.
    """
    qft_quil = Program.inst(qft_core(qubits, coef=-1))
    inv_qft_quil = Program()

    while (len(qft_quil) > 0):
        inst = qft_quil.pop()
        inv_qft_quil.inst(inst)

    return inv_qft_quil
Пример #5
0
def test_pragma_with_placeholders():
    q = QubitPlaceholder()
    q2 = QubitPlaceholder()
    p = Program()
    p.inst(Pragma('FENCE', [q, q2]))
    address_map = {q: 0, q2: 1}
    addressed_pragma = address_qubits(p, address_map)[0]
    parse_equals('PRAGMA FENCE 0 1\n', addressed_pragma)

    pq = Program(X(q))
    pq.define_noisy_readout(q, .8, .9)

    pq.inst(X(q2))
    pq.define_noisy_readout(q2, .9, .8)

    ret = address_qubits(pq, address_map).out()
    assert ret == """X 0
Пример #6
0
class Universe(object):
    state = None
    cities = None
    map = None
    program = None

    def __init__(self, cities, map, program):
        self.state = Program()
        self.state.inst(X(0), X(5), X(10), X(15))
        self.cities = cities
        self.map = map
        self.program = program

# i u v

    def h_all(self, side, n):
        result = 0
        if side == 0:  # even
            for n1 in range(0, n, 2):
                for n2 in range(0, n):
                    for n3 in range(0, n):
                        result += self.h(n1, n2, n3)

        elif side == 1:  # odd
            for n1 in range(0, n):
                if n1 % 2 == 1:
                    for n2 in range(0, n):
                        for n3 in range(0, n):
                            result += self.h(n1, n2, n3)
        else:
            raise ValueError("Side must be zero (even) or one (odd)")
        return result

    def h(self, i, u, v):
        return self.map.get_distance(u, v) * self.z(u, i) * self.z(v * i + 1)

    def h2(self, partition, i_list):
        result = 0
        for uv in partition:
            for i in i_list:
                result += self.h(uv[0], uv[1], i)
        return result

    def z(self, city_index, row_index):
        self.program.inst(Z(city_index * 4 + row_index))
Пример #7
0
def test_binary_classicals():
    p = Program()
    p.inst(AND(Addr(0), Addr(1)), OR(Addr(1), Addr(0)), MOVE(Addr(0), Addr(1)),
           CONVERT(Addr(0), Addr(1)), IOR(Addr(0), Addr(1)),
           XOR(Addr(0), Addr(1)), ADD(Addr(0), Addr(1)), SUB(Addr(0), Addr(1)),
           MUL(Addr(0), Addr(1)), DIV(Addr(0), Addr(1)),
           EXCHANGE(Addr(0), Addr(1)))
    assert p.out() == 'AND ro[0] ro[1]\n' \
                      'IOR ro[0] ro[1]\n' \
                      'MOVE ro[0] ro[1]\n' \
                      'CONVERT ro[0] ro[1]\n' \
                      'IOR ro[0] ro[1]\n' \
                      'XOR ro[0] ro[1]\n' \
                      'ADD ro[0] ro[1]\n' \
                      'SUB ro[0] ro[1]\n'\
                      'MUL ro[0] ro[1]\n' \
                      'DIV ro[0] ro[1]\n' \
                      'EXCHANGE ro[0] ro[1]\n'
Пример #8
0
def test_to_latex():
    """A test to give full coverage of latex_generation."""
    p = Program()
    p.inst(X(0), RX(1.0, 5), Y(0), CZ(0, 2), SWAP(0, 1), MEASURE(0, None),
           CNOT(2, 0),
           X(0).controlled(1),
           Y(0).dagger())
    _ = to_latex(p)

    # Modify settings to access non-standard control paths.
    settings = DiagramSettings(impute_missing_qubits=True)
    _ = to_latex(p, settings)

    settings = DiagramSettings(abbreviate_controlled_rotations=True)
    _ = to_latex(p, settings)

    settings = DiagramSettings(label_qubit_lines=False)
    _ = to_latex(p, settings)
Пример #9
0
def test_multiqubit_gate():
    # A multi-qubit defgate example
    x_gate_matrix = np.array(([0.0, 1.0], [1.0, 0.0]))
    x_sqrt_x = np.kron(sqrtm(x_gate_matrix), x_gate_matrix)
    p = Program().defgate("X-SQRT-X", x_sqrt_x)

    # Then we can use the new gate
    p.inst(("X-SQRT-X", 0, 1))

    assert p.out() == 'DEFGATE X-SQRT-X:\n    0.0+0.0i, ' \
                      '0.49999999999999989+0.49999999999999989i, ' \
                      '0.0+0.0i, 0.49999999999999989-0.49999999999999989i\n    ' \
                      '0.49999999999999989+0.49999999999999989i, 0.0+0.0i, ' \
                      '0.49999999999999989-0.49999999999999989i, 0.0+0.0i\n    0.0+0.0i,' \
                      ' 0.49999999999999989-0.49999999999999989i, 0.0+0.0i, ' \
                      '0.49999999999999989+0.49999999999999989i\n    ' \
                      '0.49999999999999989-0.49999999999999989i, ' \
                      '0.0+0.0i, 0.49999999999999989+0.49999999999999989i, 0.0+0.0i\n\nX-SQRT-X 0 1\n'
Пример #10
0
def getMatFromProgram(n_qubits, p):
    """
    Return matrix (in standard ordering) which represents the effect of p on
    a wavefunction.
    
    Note that you must have a quil compiler and a quantum virtual machine
    running on your computer in order for this function to execute 
    successfully.
    
    Parameters
    ----------
    n_qubits: integer
        Number of qubits in the register which the Program `p` acts on.
    p: pyQuil Program
        Program for which you are trying to find a matrix representation
        
    Returns
    -------
    A: ndarray, dtype=np.complex_
        Complex unitary matrix representing the effect of Program `p` on a
        state.
    """

    A = np.zeros((2**n_qubits, 2**n_qubits), dtype=np.complex_)

    # For each basis qubit, see where p sends it
    for i in range(2**n_qubits):
        bit_string = [int(j) for j in np.binary_repr(i, width=n_qubits)]
        bit_string.reverse()

        # Prep state so it looks like current bit string
        state_prep_p = Program()
        for j in range(n_qubits):
            if bit_string[j] == 1:
                state_prep_p.inst(Program(X(j)))
            else:
                state_prep_p.inst(Program(I(j)))

        # See what p does to state, record result in matrix A
        wfn = WavefunctionSimulator().wavefunction(state_prep_p.inst(p))
        A[:, i] = wfn.amplitudes[0:2**n_qubits]

    return A
Пример #11
0
def test_get_qubits():
    pq = Program(X(0), CNOT(0, 4), MEASURE(5, 5))
    assert pq.get_qubits() == {0, 4, 5}

    q = [QubitPlaceholder() for _ in range(6)]
    pq = Program(X(q[0]), CNOT(q[0], q[4]), MEASURE(q[5], 5))
    qq = pq.alloc()
    pq.inst(Y(q[2]), X(qq))
    assert address_qubits(pq).get_qubits() == {0, 1, 2, 3, 4}

    qubit_index = 1
    p = Program(("H", qubit_index))
    assert p.get_qubits() == {qubit_index}
    q1 = p.alloc()
    q2 = p.alloc()
    p.inst(("CNOT", q1, q2))
    with pytest.raises(ValueError) as e:
        _ = address_qubits(p).get_qubits()
    assert e.match('Your program mixes instantiated qubits with placeholders')
Пример #12
0
def single_q_tomo_fixture():
    qubits = [0]
    qc = get_test_qc(n_qubits=len(qubits))

    # Generate random unitary
    u_rand = haar_rand_unitary(2 ** 1, rs=np.random.RandomState(52))
    state_prep = Program().defgate("RandUnitary", u_rand)
    state_prep.inst([("RandUnitary", qubits[0])])

    # True state
    wfn = NumpyWavefunctionSimulator(n_qubits=1)
    psi = wfn.do_gate_matrix(u_rand, qubits=[0]).wf.reshape(-1)
    rho_true = np.outer(psi, psi.T.conj())

    # Get data from QVM
    tomo_expt = generate_state_tomography_experiment(state_prep, qubits)
    results = list(measure_observables(qc=qc, tomo_experiment=tomo_expt, n_shots=4000))

    return results, rho_true
def n_qubits (number) :
    ''' takes as argument the number of qubits to apply Hadamard Gates to
    and measure. Outputs a concatenated string of measurements.'''
    q = Program()
    [q.inst(H(entry)) for entry in range(number)]
    [q.measure(entry, entry) for entry in range(number)]
    wavefunction3 = qvm.wavefunction(q, classical_addresses=range(number))
    classical_mem3 = wavefunction3.classical_memory
    #print (classical_mem3)
    return("".join([str(x) for x in classical_mem3]))
Пример #14
0
def test_memory_reference_unpacking():
    p = Program()

    p.inst(AND("ro", ("ro", 1)), MOVE("ro",
                                      ("ro", 1)), CONVERT("ro", ("ro", 1)),
           IOR("ro", ("ro", 1)), XOR("ro", ("ro", 1)), ADD("ro", ("ro", 1)),
           SUB("ro", ("ro", 1)), MUL("ro", ("ro", 1)), DIV("ro", ("ro", 1)),
           EXCHANGE("ro", ("ro", 1)))

    assert p.out() == 'AND ro[0] ro[1]\n' \
                      'MOVE ro[0] ro[1]\n' \
                      'CONVERT ro[0] ro[1]\n' \
                      'IOR ro[0] ro[1]\n' \
                      'XOR ro[0] ro[1]\n' \
                      'ADD ro[0] ro[1]\n' \
                      'SUB ro[0] ro[1]\n'\
                      'MUL ro[0] ro[1]\n' \
                      'DIV ro[0] ro[1]\n' \
                      'EXCHANGE ro[0] ro[1]\n'
Пример #15
0
def test_kraus():
    pq = Program(X(0))
    pq.define_noisy_gate("X", (0, ),
                         [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 0.0], [0.0, 0.0]]])
    pq.inst(X(1))
    pq.define_noisy_gate("X", (1, ),
                         [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 0.0], [0.0, 0.0]]])

    ret = pq.out()
    assert (ret == """X 0
PRAGMA ADD-KRAUS X 0 "(0.0 1.0 1.0 0.0)"
PRAGMA ADD-KRAUS X 0 "(0.0 0.0 0.0 0.0)"
X 1
PRAGMA ADD-KRAUS X 1 "(0.0 1.0 1.0 0.0)"
PRAGMA ADD-KRAUS X 1 "(0.0 0.0 0.0 0.0)"
""")
    # test error due to bad normalization
    with pytest.raises(ValueError):
        pq.define_noisy_gate(
            "X", (0, ), [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 1.0], [1.0, 0.0]]])
    # test error due to bad shape of kraus op
    with pytest.raises(ValueError):
        pq.define_noisy_gate(
            "X", (0, ),
            [[[0.0, 1.0, 0.0], [1.0, 0.0, 0.0]], [[0.0, 1.0], [1.0, 0.0]]])

    pq1 = Program(X(0))
    pq1.define_noisy_gate("X", (0, ),
                          [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 0.0], [0.0, 0.0]]])
    pq2 = Program(X(1))
    pq2.define_noisy_gate("X", (1, ),
                          [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 0.0], [0.0, 0.0]]])

    assert pq1 + pq2 == pq

    pq_nn = Program(X(0))
    pq_nn.no_noise()
    pq_nn.inst(X(1))

    assert (pq_nn.out() == """X 0
PRAGMA NO-NOISE
X 1
""")
Пример #16
0
def prep_qubits(qubits: list, n: int):
    """
    Generate a quil program which prepares given qubits in a state representing number n.

    :param n: the number to write
    :param qubits: qubit indexes to write the number n

    :return: circuit to write number n on given qubits.
    """
    p = Program()

    for qubit in qubits:
        if n % 2 == 1:
            p.inst(X(qubit))
        else:
            p.inst(I(qubit))
        n = int(n/2)
    
    return p
Пример #17
0
    def generate_rb_sequence(self, depth, qubits, gateset):
        """
        Construct a randomized benchmarking experiment on the given qubits, decomposing into gateset.

        The JSON payload that is parsed is a list of lists of indices, or Nones. In the former case, they are the index
         of the gate in the gateset.
        :param int depth: The number of Clifford gates to include in the randomized benchmarking experiement.
        :param int qubits: The number of qubits to generate a randomized benchmarking sequence for.
        :param list gateset: A list of pyquil gates to decompose the Clifford elements into.
        """
        payload = self._rb_sequence_payload(depth, qubits, gateset)
        response = post_json(self.session, self.sync_endpoint + "/rb", payload).json()
        programs = []
        for clifford in response:
            clifford_program = Program()
            for index in clifford:
                clifford_program.inst(gateset[index])
            programs.append(clifford_program)
        return programs
Пример #18
0
def basic_compile(program):
    new_prog = Program()
    new_prog.num_shots = program.num_shots
    new_prog.inst(program.defined_gates)
    for inst in program:
        if isinstance(inst, Gate):
            if inst.name in ['RZ', 'CZ', 'I']:
                new_prog += inst
            elif inst.name == 'RX' and is_magic_angle(inst.params[0]):
                new_prog += inst
            elif inst.name == 'RY':
                new_prog += _RY(inst.params[0], inst.qubits[0])
            elif inst.name == 'CNOT':
                new_prog += _CNOT(*inst.qubits)
            elif inst.name == 'CCNOT':
                new_prog += _CCNOT(*inst.qubits)
            elif inst.name == 'SWAP':
                new_prog += _SWAP(*inst.qubits)
            elif inst.name == 'T':
                new_prog += _T(inst.qubits[0])
            elif inst.name == "H":
                new_prog += _H(inst.qubits[0])
            elif inst.name == "X":
                new_prog += _X(inst.qubits[0])
            elif inst.name in [gate.name for gate in new_prog.defined_gates]:
                new_prog += inst
            else:
                raise ValueError(f"Unknown gate instruction {inst}")

        else:
            new_prog += inst

    new_prog.native_quil_metadata = {
        'final_rewiring': None,
        'gate_depth': None,
        'gate_volume': None,
        'multiqubit_gate_depth': None,
        'program_duration': None,
        'program_fidelity': None,
        'topological_swaps': 0,
    }
    return new_prog
Пример #19
0
def level2():
    circuit = Program()
    initz = Program()

    circuit.inst(H(1))
    circuit.inst(CZ(0,1))
    circuit.inst(H(1))
    circuit.inst(MEASURE(0,0))
    circuit.inst(MEASURE(1,1))

    initz.inst(X(0))


    qubits = 2
    depth = 3

    introduction = "The state is initialised as |1,0>. Apply the following gates to construct a CNOT gate:"
    conclusion = "Applying two H gates on the target qubit, which are sandwiching the CZ gate, results in cancelling of the H gates when the control is zero and a NOT gate when the control is 1."
    hint = "I like sandwiches"
    level2 = level(qubits,depth,circuit,initz,introduction,conclusion,hint)
Пример #20
0
def runAlg(cf):
    qvm = api.QVMConnection()
    p = Program()
    p.defgate('cF', cf)

    p.inst(
        # Prepare 0 as a superposition |0> + |1>
        # Prepare 1 as the Fourier Transform of |0> - |1>
        H(0),
        X(1),
        H(1),
        # one application of cF gate
        ('cF', 0, 1),
        # project and measure
        H(0),
        MEASURE(0, 0))
    print(p)
    result = qvm.run(p, [0])
    print(result)
    parseResult(result)
Пример #21
0
def local_sic_prep(label, qubit):
    """

    :param label:
    :param qubit:
    :return:
    """
    theta = 2*np.arccos(1/np.sqrt(3))
    zx_plane_rotation = Program(RX(-pi/2, qubit)).inst(RZ(theta - pi, qubit)).inst(RX(-pi/2, qubit))
    if label == 'SIC0':
        gate = I(qubit)
    elif label == 'SIC1':
        gate = zx_plane_rotation
    elif label == 'SIC2':
        gate = zx_plane_rotation.inst(RZ(-2*pi/3, qubit))
    elif label == 'SIC3':
        gate = zx_plane_rotation.inst(RZ(2*pi/3, qubit))
    else:
        raise ValueError('Unknown gate operation')
    return gate
Пример #22
0
def _remove_reset_from_program(program: Program) -> Program:
    """
    Trim the RESET from a program because in measure_observables it is re-added.

    :param program: Program to remove RESET(s) from.
    :return: Trimmed Program.
    """
    definitions = [gate for gate in program.defined_gates]

    p = Program(*[inst for inst in program if not isinstance(inst, Reset)])

    for definition in definitions:
        if isinstance(definition, DefPermutationGate):
            p.inst(
                DefPermutationGate(definition.name,
                                   list(definition.permutation)))
        else:
            p.defgate(definition.name, definition.matrix,
                      definition.parameters)
    return p
Пример #23
0
def basis_state_preps(*qubits):
    """
    Generate a sequence of programs that prepares the measurement
    basis states of some set of qubits in the order such that the qubit
    with highest index is iterated over the most quickly:
    E.g., for ``qubits=(0, 1)``, it returns the circuits::

        I_0 I_1
        I_0 X_1
        X_0 I_1
        X_0 X_1

    :param list qubits: Each qubit to include in the basis state preparation.
    :return: Yields programs for each basis state preparation.
    :rtype: Program
    """
    for prep in cartesian_product([I, X], repeat=len(qubits)):
        basis_prep = Program()
        for gate, qubit in zip(prep, qubits):
            basis_prep.inst(gate(qubit))
        yield basis_prep
Пример #24
0
def qft_core(qubits, coef=1):
    """
    Generates a quil programm that performs 
    quantum fourier transform on given qubits 
    without swaping qubits at the end.
    
    :param qubits: A list of qubit indexes.
    :param coeff: A modifier for the angle used in rotations (-1 for inverse
                 QFT, 1 for QFT)
    :return: A Quil program to compute the QFT of the given qubits without swapping.
    """
    p = Program()

    # Iterate over qubits starting from the most significant
    for i, qubit in enumerate(qubits[::-1]):
        p.inst(H(qubit))

        # Add controlled rotations R_i for i in 1 .. n-1
        # using all qubits right to current
        p.inst(crotate(qubit, qubits[:-i - 1], coef=coef, start_index=1))
    return p
Пример #25
0
def state_tomography_programs(state_prep, qubits=None,
                              rotation_generator=tomography.default_rotations):
    """
    Yield tomographic sequences that prepare a state with Quil program `state_prep` and then append
    tomographic rotations on the specified `qubits`. If `qubits is None`, it assumes all qubits in
    the program should be tomographically rotated.

    :param Program state_prep: The program to prepare the state to be tomographed.
    :param list|NoneType qubits: A list of Qubits or Numbers, to perform the tomography on. If
    `None`, performs it on all in state_prep.
    :param generator rotation_generator: A generator that yields tomography rotations to perform.
    :return: Program for state tomography.
    :rtype: Program
    """
    if qubits is None:
        qubits = state_prep.get_qubits()
    for tomography_program in rotation_generator(*qubits):
        state_tomography_program = Program()
        state_tomography_program.inst(state_prep)
        state_tomography_program.inst(tomography_program)
        yield state_tomography_program
Пример #26
0
def test_pragma_with_placeholders():
    q = QubitPlaceholder()
    q2 = QubitPlaceholder()
    p = Program()
    p.inst(Pragma("FENCE", [q, q2]))
    address_map = {q: 0, q2: 1}
    addressed_pragma = address_qubits(p, address_map)[0]
    parse_equals("PRAGMA FENCE 0 1\n", addressed_pragma)

    pq = Program(X(q))
    pq.define_noisy_readout(q, 0.8, 0.9)

    pq.inst(X(q2))
    pq.define_noisy_readout(q2, 0.9, 0.8)

    ret = address_qubits(pq, address_map).out()
    assert (ret == """X 0
PRAGMA READOUT-POVM 0 "(0.8 0.09999999999999998 0.19999999999999996 0.9)"
X 1
PRAGMA READOUT-POVM 1 "(0.9 0.19999999999999996 0.09999999999999998 0.8)"
""")
Пример #27
0
def test_get_qubits():
    pq = Program(Declare("ro", "BIT"), X(0), CNOT(0, 4),
                 MEASURE(5, MemoryReference("ro", 0)))
    assert pq.get_qubits() == {0, 4, 5}

    q = [QubitPlaceholder() for _ in range(6)]
    pq = Program(Declare("ro", "BIT"), X(q[0]), CNOT(q[0], q[4]),
                 MEASURE(q[5], MemoryReference("ro", 0)))
    qq = QubitPlaceholder()
    pq.inst(Y(q[2]), X(qq))
    assert address_qubits(pq).get_qubits() == {0, 1, 2, 3, 4}

    qubit_index = 1
    p = Program(("H", qubit_index))
    assert p.get_qubits() == {qubit_index}
    q1 = QubitPlaceholder()
    q2 = QubitPlaceholder()
    p.inst(("CNOT", q1, q2))
    with pytest.raises(ValueError) as e:
        _ = address_qubits(p).get_qubits()
    assert e.match("Your program mixes instantiated qubits with placeholders")
Пример #28
0
def get_rotation_program(pauli_term):
    """
    Generate a rotation program so that the pauli term is diagonal

    :param PauliTerm pauli_term: The Pauli term used to generate diagonalizing
                                 one-qubit rotations.
    :return: The rotation program.
    :rtype: Program
    """
    meas_basis_change = Program()
    for index, gate in pauli_term:
        if gate == 'X':
            meas_basis_change.inst(RY(-np.pi / 2, index))
        elif gate == 'Y':
            meas_basis_change.inst(RX(np.pi / 2, index))
        elif gate == 'Z':
            pass
        else:
            raise ValueError()

    return meas_basis_change
Пример #29
0
def test_qaoa_circuit(qvm):
    wf_true = [
        0.00167784 + 1.00210180e-05 * 1j, 0.50000000 - 4.99997185e-01 * 1j,
        0.50000000 - 4.99997185e-01 * 1j, 0.00167784 + 1.00210180e-05 * 1j
    ]
    prog = Program()
    prog.inst([
        RYgate(np.pi / 2)(0),
        RXgate(np.pi)(0),
        RYgate(np.pi / 2)(1),
        RXgate(np.pi)(1),
        CNOTgate(0, 1),
        RXgate(-np.pi / 2)(1),
        RYgate(4.71572463191)(1),
        RXgate(np.pi / 2)(1),
        CNOTgate(0, 1),
        RXgate(-2 * 2.74973750579)(0),
        RXgate(-2 * 2.74973750579)(1)
    ])
    wf_test, _ = qvm.wavefunction(prog)
    assert np.allclose(wf_test.amplitudes, wf_true)
Пример #30
0
    def run_and_measure(self, program: Program,
                        trials: int) -> Dict[int, np.ndarray]:
        """
        Run the provided state preparation program and measure all qubits.

        This will measure all the qubits on this QuantumComputer, not just qubits
        that are used in the program.

        The returned data is a dictionary keyed by qubit index because qubits for a given
        QuantumComputer may be non-contiguous and non-zero-indexed. To turn this dictionary
        into a 2d numpy array of bitstrings, consider::

            bitstrings = qc.run_and_measure(...)
            bitstring_array = np.vstack(bitstrings[q] for q in sorted(qc.qubits())).T
            bitstring_array.shape  # (trials, len(qc.qubits()))

        .. note::

            In contrast to :py:class:`QVMConnection.run_and_measure`, this method simulates
            noise correctly for noisy QVMs. However, this method is slower for ``trials > 1``.
            For faster noise-free simulation, consider
            :py:class:`WavefunctionSimulator.run_and_measure`.

        :param program: The state preparation program to run and then measure.
        :param trials: The number of times to run the program.
        :return: A dictionary keyed by qubit index where the corresponding value is a 1D array of
            measured bits.
        """
        program = program.copy()
        program = _validate_run_and_measure_program(program)
        ro = program.declare('ro', 'BIT', len(self.qubits()))
        for i, q in enumerate(self.qubits()):
            program.inst(MEASURE(q, ro[i]))
        program.wrap_in_numshots_loop(trials)
        executable = self.compile(program)
        bitstring_array = self.run(executable=executable)
        bitstring_dict = {}
        for i, q in enumerate(self.qubits()):
            bitstring_dict[q] = bitstring_array[:, i]
        return bitstring_dict
Пример #31
0
from pyquil.quil import Program
import pyquil.api as api
from pyquil.gates import *
qvm = api.QVMConnection()
p = Program()
p.inst(H(0), CNOT(0, 1), MEASURE(1, [1]))
wavefunction = qvm.wavefunction(p)
print(wavefunction)
Пример #32
0
# http://pyquil.readthedocs.io/en/latest/intro.html

# Imports for pyQuil (ignore for now)
import numpy as np
from pyquil.quil import Program
from pyquil.api import QVMConnection
quantum_simulator = QVMConnection()

# pyQuil is based around operations (or gates) so we will start with the most
# basic one: the identity operation, called I. I takes one argument, the index
# of the qubit that it should be applied to.
from pyquil.gates import *

# Make a quantum program that allocates one qubit (qubit #0) and does nothing to it
p = Program(I(0))

print(p.inst(X(0)))

# Quantum states are called wavefunctions for historical reasons.
# We can run this basic program on our connection to the simulator.
# This call will return the state of our qubits after we run program p.
# This api call returns a tuple, but we'll ignore the second value for now.
wavefunction = quantum_simulator.wavefunction(p)

# wavefunction is a Wavefunction object that stores a quantum state as a list of amplitudes
alpha, beta = wavefunction

print("Our qubit is in the state alpha={} and beta={}".format(alpha, beta))
print("The probability of measuring the qubit in outcome 0 is {}".format(abs(alpha)**2))
print("The probability of measuring the qubit in outcome 1 is {}".format(abs(beta)**2))
Пример #33
0
from pyquil.quil import Program
from pyquil.gates import H, X, CNOT, MEASURE
from pyquil.api import SyncConnection

# Reference: https://arxiv.org/pdf/1302.4310.pdf

p = Program()
p.inst("""DEFGATE CH(%theta):
    1, 0, 0, 0
    0, 1, 0, 0
    0, 0, cos(2*%theta), sin(2*%theta)
    0, 0, sin(2*%theta), cos(-2*%theta)""")
p.inst(H(3))
p.inst(CNOT(3, 2))
p.inst(CNOT(2, 1))
p.inst("CH(pi/8) 1 0")
p.inst("CH(pi/16) 2 0")
p.inst(H(1))
p.inst(H(2))
p.inst(X(0))
p.inst(MEASURE(0))
p.inst(MEASURE(1))
p.inst(MEASURE(2))

# run the program on a QVM
qvm = SyncConnection()

wvf, _ = qvm.wavefunction(p)
print(wvf)
Пример #34
0

def get_compiled_prog_1():
    return Program([
        RX(pi/2, 0),
        I(0),
        RZ(-pi/2, 0),

        RX(-pi/2, 0),
        I(0),
        RZ(pi/2, 0),
    ])


p = Program()
p.inst(X(0))
# want increasing number of I-gates
p.define_noisy_gate(
    "II", [0], append_damping_to_gate(np.eye(2), damping_per_I))
p.inst([I(0) for _ in range(num_I)])
# p.inst(H(0))
p.inst(MEASURE(0, [0]))
#print("Expected 1 %s" % qvm.run(p, [0]))

thetas = np.linspace(-pi, pi, num=20)
t1s = np.logspace(-6, -5, num=3)

# print(t1s[0])

prog = get_compiled_prog(pi/2)
noisy = add_noise_to_program(prog, T1=t1s[0]).inst([
Пример #35
0
from pyquil.quil import Program
from pyquil.gates import *
from pyquil.parameters import Parameter, quil_sin, quil_cos
from pyquil.quilbase import DefGate
#from pyquil.api import QVMConnection
from referenceqvm.api import QVMConnection
import numpy as np
theta = Parameter('theta')
cry = np.array([[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, quil_cos(
    theta / 2), -1 * quil_sin(theta / 2)], [0.0, 0.0, quil_sin(theta / 2), quil_cos(theta / 2)]])
dg = DefGate('CRY', cry, [theta])
CRY = dg.get_constructor()
p = Program()
p.inst(dg)
p.inst(X(0))
p.inst(X(1))
p.inst(CRY(4.304)(0, 2))
qvm = QVMConnection()
wf = qvm.wavefunction(p)
print(wf)
Пример #36
0
from pyquil.quil import Program

p = Program()

"""
Gate definitions
"""
p.inst("""DEFGATE CRX(%theta):
    1, 0, 0, 0
    0, 1, 0, 0
    0, 0, cos(%theta/2), -i*sin(%theta/2)
    0, 0, -i*sin(%theta/2), cos(%theta/2)""")

p.inst("""DEFGATE CRY(%theta):
    1, 0, 0, 0
    0, 1, 0, 0
    0, 0, cos(%theta/2), -sin(%theta/2)
    0, 0, sin(%theta/2), cos(%theta/2)""")

p.inst("""DEFGATE CRZ(%theta):
    1, 0, 0, 0
    0, 1, 0, 0
    0, 0, e^(-i*%theta/2), 0
    0, 0, 0, e^(i*%theta/2)""")
Пример #37
0
from pyquil.quil import Program
#from pyquil.api import QPUConnection
from pyquil.api import QVMConnection
from pyquil.gates import *

qvm = QVMConnection()

ins = Program()

ins.inst(H(1), CNOT(1, 2))  # Creating B00
ins.inst(CNOT(0, 1), H(0))
ins.measure(0, 0).measure(1, 1).if_then(1, X(2)).if_then(0, Z(2))
wvf = qvm.wavefunction(ins, [0, 1])
#print( wvf)


ins = Program(
    H(0),
    H(1),
    CNOT(1, 2),
    CNOT(0, 1),
    H(0),
)


ins.measure(0, 0).measure(1, 1).if_then(1, X(2)).if_then(1, Z(2))
wvf = qvm.wavefunction(ins)

print(ins)
result = qvm.run_and_measure(ins, [2])
print(result)