Esempio n. 1
0
def rus_single(input, theta):
    reg = list()
    reg.append(input)
    reg.append(QubitPlaceholder())
    reg.append(QubitPlaceholder())
    # Gates and classical memory preparation
    prep_pq = Program()
    prep_pq += dg_cry
    prep_pq += dg_cy
    acl_ro = prep_pq.declare('acl_ro', 'BIT', 1)
    # Rotation gates
    rot_pq = Program()
    rot_pq += CRY(2 * theta)(reg[0], reg[1])
    rot_pq += CY(reg[1], reg[2])
    rot_pq += RZ(-np.pi / 2, reg[1])
    rot_pq += CRY(2 * theta)(reg[0], reg[1])
    # Ancilla bit measurement
    pq = Program()
    pq += prep_pq
    pq += rot_pq
    pq += MEASURE(reg[1], acl_ro)
    # Repeated circuit
    rep_pq = Program()
    # rep_pq += RESET(reg[1])
    rep_pq += RY(-np.pi / 2, reg[2])
    rep_pq += rot_pq
    rep_pq += MEASURE(reg[1], acl_ro)

    pq.while_do(acl_ro, rep_pq)
    return pq, reg[2]
Esempio n. 2
0
def period_helper(a, N, size):
    c1 = QubitPlaceholder()
    zero = QubitPlaceholder()
    x = QubitPlaceholder.register(size)
    b = QubitPlaceholder.register(size + 1)
    #takes in x and b as zero, finds
    p = Program()

    n = 2 * size
    def_regs = Program()
    period_regs = def_regs.declare('ro', 'BIT', n)

    #For one reg, we want H, CUA, R_i m_i, X^m_i
    for i in range(n - 1, -1, -1):
        R = Program()
        R += H(c1)
        for j in range(i - 1, -1, -1):
            k = i - j + 1
            doit = Program()
            doit += RK(k)(c1).dagger()
            R = Program().if_then(period_regs[j], doit, I(c1)) + R
        R += MEASURE(c1, period_regs[i])
        R += Program().if_then(period_regs[i], X(c1), I(c1))
        #R = Program(H(c1)) + R
        R = Program(H(c1)) + UA(c1, x, b, a**(2**i), N, zero) + R
        p = R + p
    p = write_in(1, x) + p
    p = def_regs + p
    p = get_defs() + p
    p = address_qubits(p)
    return p
Esempio n. 3
0
def test_alloc_new():
    p = Program()

    q0 = QubitPlaceholder()
    p.inst(H(q0))  # H 0

    q1 = QubitPlaceholder()
    q2 = QubitPlaceholder()

    p.inst(CNOT(q1, q2))  # CNOT 1 3

    qxxx = QubitPlaceholder()
    p.inst(H(qxxx))

    q3 = QubitPlaceholder()

    p.inst(X(q3))  # X 4
    p = address_qubits(p, {
        q1: 1,
        q2: 3,
        q3: 4,
        q0: 0,
        qxxx: 2,
    })

    assert p.out() == "H 0\n" \
                      "CNOT 1 3\n" \
                      "H 2\n" \
                      "X 4\n"
Esempio n. 4
0
def rus(inputs, w, b):
    in_reg = list()
    for i in inputs:
        in_reg.append(i)
    an_reg = list()
    an_reg.append(QubitPlaceholder())
    an_reg.append(QubitPlaceholder())
    # Gates and classical memory preparation
    prep_pq = Program()
    acl_ro = prep_pq.declare('acl_{}_ro'.format(an_reg[0]), 'BIT', 1)
    # Rotation gates
    rot_linear_pq = Program()
    for i in range(len(w)):
        rot_linear_pq += CRY(w[i])(in_reg[i], an_reg[0])
    rot_linear_pq += RY(b, an_reg[0])
    rot_pq = Program()
    rot_pq += rot_linear_pq
    rot_pq += CY(an_reg[0], an_reg[1])
    rot_pq += RZ(-np.pi / 2, an_reg[0])
    rot_pq += rot_linear_pq
    # Ancilla bit measurement
    pq = Program()
    pq += prep_pq
    pq += rot_pq
    pq += MEASURE(an_reg[0], acl_ro)
    # Repeated circuit
    rep_pq = Program()
    # rep_pq += RESET(reg[1])
    rep_pq += RY(-np.pi / 2, an_reg[1])
    rep_pq += rot_pq
    rep_pq += MEASURE(an_reg[0], acl_ro)

    pq.while_do(acl_ro, rep_pq)
    return pq, an_reg[1]
Esempio n. 5
0
    def run_test(self, description, iterations, buffer):
        """
        Runs the superdense coding algorithm on the given classical buffer.

        Parameters:
            description (str): A description of the test, for logging.
            iterations (int): The number of times to run the program.
            buffer (list[Bool]): The buffer containing the two bits to send.
        """

        # Construct the registers
        print(f"Running test: {description}")
        pair_a = QubitPlaceholder()
        pair_b = QubitPlaceholder()

        # Entangle the qubits together
        self.program += H(pair_a)
        self.program += CNOT(pair_a, pair_b)

        # Encode the buffer into the qubits, then decode them into classical measurements
        self.encode_message(buffer, pair_a)
        (a_measurement_index,
         b_measurement_index) = self.decode_message(pair_a, pair_b)

        # Run the program N times.
        assigned_program = address_qubits(self.program)
        assigned_program.wrap_in_numshots_loop(iterations)
        computer = get_qc(f"2q-qvm", as_qvm=True)
        executable = computer.compile(assigned_program)
        results = computer.run(executable)

        # Check the first qubit to make sure it was always the expected value
        desired_a_state = int(buffer[0])
        for result in results:
            if result[a_measurement_index] != desired_a_state:
                self.fail(
                    f"Test {description} failed. The first bit should have been {desired_a_state} "
                    + f"but it was {result[a_measurement_index]}.")
        else:
            print(
                f"The first qubit was {desired_a_state} all {iterations} times."
            )

        # Check the second qubit to make sure it was always the expected value
        desired_b_state = int(buffer[1])
        for result in results:
            if result[b_measurement_index] != desired_b_state:
                self.fail(
                    f"Test {description} failed. The first bit should have been {desired_b_state} "
                    + f"but it was {result[b_measurement_index]}.")
        else:
            print(
                f"The second qubit was {desired_b_state} all {iterations} times."
            )

        print("Passed!")
        print()
Esempio n. 6
0
def test_reuse_placeholder():
    p = Program()
    q1 = QubitPlaceholder()
    q2 = QubitPlaceholder()
    p.inst(H(q1))
    p.inst(H(q2))
    p.inst(CNOT(q1, q2))
    p = address_qubits(p)
    assert p.out() == "H 0\nH 1\nCNOT 0 1\n"
Esempio n. 7
0
def test_allocating_qubits_on_multiple_programs():
    p = Program()
    qubit0 = QubitPlaceholder()
    p.inst(X(qubit0))

    q = Program()
    qubit1 = QubitPlaceholder()
    q.inst(X(qubit1))

    assert address_qubits(p + q).out() == "X 0\nX 1\n"
Esempio n. 8
0
def test_eq():
    p1 = Program()
    q1 = QubitPlaceholder()
    q2 = QubitPlaceholder()
    p1.inst([H(q1), CNOT(q1, q2)])
    p1 = address_qubits(p1)

    p2 = Program()
    p2.inst([H(0), CNOT(0, 1)])

    assert p1 == p2
    assert not p1 != p2
Esempio n. 9
0
def entangle_test(n=5):
    phi = QubitPlaceholder()
    p = [QubitPlaceholder() for i in range(n)]

    test_pqs = [
        init_p(p) + entangle(phi, p),
        init_p(p) + entangle(phi, p) + disentangle(phi, p),
        init_p(p) + H(phi) + entangle(phi, p),
        init_p(p) + H(phi) + entangle(phi, p) + disentangle(phi, p),
    ]

    wf_sim = WavefunctionSimulator()
    for pq in test_pqs:
        print(wf_sim.wavefunction(address_qubits(pq)))
def run_code(error_code, noise, trials=10):
    """ Takes in an error_code function (e.g. bit_code, phase_code or shor) and runs this code on the QVM"""
    pq, code_register = error_code(QubitPlaceholder(), noise=noise)
    ro = pq.declare('ro', 'BIT', len(code_register))
    pq += [MEASURE(qq, rr) for qq, rr in zip(code_register, ro)]
    
    return qvm.run(address_qubits(pq), trials=trials)
Esempio n. 11
0
def simulate_code(kraus_operators, trials, error_code) -> int:
    """
        :param kraus_operators: The set of Kraus operators to apply as the noise model on the identity gate
        :param trials: The number of times to simulate the program
        :param error_code: The error code {bit_code, phase_code or shor} to use
        :return: The number of times the code did not correct back to the logical zero state for "trials" attempts
        """
    # Apply the error_code to some qubits and return back a Program pq
    pq, code_register = error_code(QubitPlaceholder())
    ro = pq.declare('ro', 'BIT', len(code_register))
    pq += [MEASURE(qq, rr) for qq, rr in zip(code_register, ro)]

    # THIS CODE APPLIES THE NOISE FOR YOU
    kraus_ops = kraus_operators
    noise_data = Program()
    for qq in range(3):
        noise_data.define_noisy_gate("I", [qq], kraus_ops)
    pq = noise_data + pq

    # Run the simulation trials times using the QVM and check how many times it did not work
    results = qvm.run(address_qubits(pq), trials=trials)
    score = 0
    for i in results:
        count = np.sum(i)
        #if count >= len(code_register)/2
        if count == len(code_register):
            score += 1
    return int(score)
Esempio n. 12
0
def run_flip_marker_as_phase_marker(program, ancilla_cache, oracle, qubits,
                                    oracle_args):
    """
    Runs an oracle, flipping the phase of the input array if the result was |1>
    instead of flipping the target qubit.

    Parameters:
        program (Program): The program being constructed
        ancilla_cache (dict[string, QubitPlaceholder]): A collection of ancilla qubits
            that have been allocated in the program for use, paired with a name to help
            determine when they're free for use.
        oracle (function): The oracle to run
        qubits (list[QubitPlaceholder]): The register to run the oracle on
        oracle_args (anything): An oracle-specific argument object to pass to
            the oracle during execution
    """

    # Add the phase-flip ancilla qubit to the program if it doesn't already
    # exist, and set it up in the |-> state
    phase_marker_target = None
    if not "phase_marker_target" in ancilla_cache:
        phase_marker_target = QubitPlaceholder()
        ancilla_cache["phase_marker_target"] = phase_marker_target
        program += X(phase_marker_target)
        program += H(phase_marker_target)
    else:
        phase_marker_target = ancilla_cache["phase_marker_target"]

    # Run the oracle with the phase-flip ancilla as the target - when the
    # oracle flips this target, it will actually flip the phase of the input
    # instead of entangling it with the target.
    if oracle_args is None:
        oracle(program, qubits, phase_marker_target)
    else:
        oracle(program, qubits, phase_marker_target, oracle_args)
Esempio n. 13
0
def test_multiple_instantiate():
    p = Program()
    q = QubitPlaceholder()
    p.inst(H(q))
    p = address_qubits(p)
    assert p.out() == "H 0\n"
    assert p.out() == "H 0\n"
Esempio n. 14
0
def new_logical_qubit(prog: Program, qecc: QECC, name: str) -> CodeBlock:
    n = qecc.n
    raw_mem = prog.declare(name, 'BIT', 2 * n)
    mem = MemoryChunk(raw_mem, 0, raw_mem.declared_size)
    qubits = [QubitPlaceholder() for _ in range(n)]
    _initialize_memory(prog, raw_mem, qubits)
    return CodeBlock(qubits, mem[:n], mem[n:])
Esempio n. 15
0
    def test_multi_control(self):
        """
        Tests entanglement with more than one control qubit.

        NOTE: This will currently fail because pyQuil has a bug with controlled gates
        and QubitPlaceholder: https://github.com/rigetti/pyquil/issues/905
        Once that gets fixed, I'll revisit this function.
        """

        # Construct the program and the qubits - we're going to use 2 separate registers,
        # where one will be a bunch of control qubits and the other will be a single target
        # qubit.
        valid_states = [
            "0000", "0010", "0100", "0110", "1000", "1010", "1100", "1111"
        ]
        controls = QubitPlaceholder.register(len(valid_states[0]) - 1)
        target = QubitPlaceholder()
        program = Program()

        # Hadamard the first three qubits - these will be the controls
        for control in controls:
            program += H(control)

        # pyQuil supports gates that are controlled by arbitrary many qubits, so
        # we don't need to mess with Toffoli gates or custom multi-control implementations.
        # We just have to chain a bunch of controlled() calls for each control qubit.
        gate = X(target)
        for control in controls:
            gate = gate.controlled(control)
        program += gate

        # Run the test
        self.run_test("multi-controlled operation", program,
                      controls + [target], 1000, valid_states)
Esempio n. 16
0
    def alloc(self):
        """
        Get a new qubit.

        :return: A qubit.
        :rtype: Qubit
        """
        return QubitPlaceholder()
Esempio n. 17
0
def test_get_qubits():
    q = QubitPlaceholder.register(2)
    term = PauliTerm("Z", q[0]) * PauliTerm("X", q[1])
    assert term.get_qubits() == q

    q10 = QubitPlaceholder()
    sum_term = PauliTerm("X", q[0], 0.5) + 0.5j * PauliTerm("Y", q10) * PauliTerm("Y", q[0], 0.5j)
    assert sum_term.get_qubits() == [q[0], q10]
def test_simplify_term_xz():
    q0 = QubitPlaceholder()
    term1 = (-0.5 * PauliTerm('X', q0)) * (-1.0 * PauliTerm('Z', q0))
    term2 = -0.5 * PauliTerm('X', q0) * (-1.0) * PauliTerm('Z', q0)
    term3 = 0.5 * PauliTerm('X', q0) * PauliTerm('Z', q0)
    for term in [term1, term2, term3]:
        assert term.id() == 'Y{}'.format(q0)
        assert term.coefficient == -0.5j
Esempio n. 19
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
Esempio n. 20
0
def qft_tests(n=4):
    phi = [QubitPlaceholder() for i in range(n)]
    tests = [
        init_pure(phi) + H(phi[0]) + qft(phi, n) +
        iqft(phi, n),  # Should be H(0)
        init_pure(phi) + iqft(phi, n) + qft(phi, n),  # Should be pure |1>'s
    ]
    wf_sim = WavefunctionSimulator()
    for test in tests:
        print(wf_sim.wavefunction(address_qubits(test)))
Esempio n. 21
0
def test_qubit_placeholder():
    p = Program()

    p.inst(H(0))  # H 0

    q1 = QubitPlaceholder()  # q1 = 1
    q2 = QubitPlaceholder()  # q2 = 3

    p.inst(CNOT(q1, q2))  # CNOT 1 3

    p.inst(H(2))

    q3 = QubitPlaceholder()  # q3 = 4

    p.inst(X(q3))  # X 4

    with pytest.raises(RuntimeError) as e:
        _ = p.out()
    assert e.match(r"Qubit q\d+ has not been assigned an index")
Esempio n. 22
0
def test_qubit_placeholder_2():
    p = Program()

    p.inst(H(0))  # H 0

    q1 = QubitPlaceholder()  # q1 = 1
    q2 = QubitPlaceholder()  # q2 = 3

    p.inst(CNOT(q1, q2))  # CNOT 1 3

    p.inst(H(2))

    q3 = QubitPlaceholder()  # q3 = 4

    p.inst(X(q3))  # X 4
    with pytest.raises(ValueError) as e:
        _ = address_qubits(p, {q1: 1, q2: 3, q3: 4})

    assert e.match("Your program mixes instantiated qubits with placeholders")
def test_zero_term():
    qubit_id = QubitPlaceholder()
    coefficient = 10
    ps = sI(qubit_id) + sX(qubit_id)
    assert coefficient * ZERO() == ZERO()
    assert ZERO() * coefficient == ZERO()
    assert ZERO() * ID() == ZERO()
    assert ZERO() + ID() == ID()
    assert ZERO() + ps == ps
    assert ps + ZERO() == ps
Esempio n. 24
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')
Esempio n. 25
0
    def alloc(self):
        """
        Get a new qubit.

        :return: A qubit.
        :rtype: Qubit
        """
        warnings.warn("`alloc` is deprecated and will be removed in a future version of pyQuil. "
                      "Please create a `QubitPlaceholder` directly", DeprecationWarning)
        return QubitPlaceholder()
def test_ps_sub():
    q0 = QubitPlaceholder()
    term = 3 * ID()
    b = term - 1.0
    assert str(b) == "(2+0j)*I"
    assert str(b - 1.0) == "(1+0j)*I"
    assert str(1.0 - b) == "(-1+0j)*I"
    b = 1.0 - sX(q0)
    assert re.match(r"\(1\+0j\)\*I \+ \(-1\+0j\)\*Xq\d+", str(b))
    b = sX(q0) - 1.0
    assert re.match(r"\(1\+0j\)\*Xq\d+ \+ \(-1\+0j\)\*I", str(b))
def phase_code(qubit: QubitPlaceholder, noise=None) -> (Program, List[QubitPlaceholder]):
    ### Do your encoding step here
    q0 = QubitPlaceholder()
    q1 = QubitPlaceholder()
    a0 = QubitPlaceholder()
    a1 = QubitPlaceholder()
    code_register = [qubit, q0, q1, a0, a1]  # the List[QubitPlaceholder] of the qubits you have encoded into
    pq = Program(CNOT(code_register[0], code_register[1]), CNOT(code_register[0], code_register[2]))
    pq += (H(q) for q in code_register[:3])
    # DON'T CHANGE THIS CODE BLOCK. It applies the errors for simulations
    if noise is None:
        pq += [I(qq) for qq in code_register]
    else:
        pq += noise(code_register)

    ### Do your decoding and correction steps here
    pq += (H(q) for q in code_register[:3])
    ro = pq.declare('ro', 'BIT', 2)
    pq += Program(CNOT(code_register[0], code_register[3]), CNOT(code_register[1], code_register[3]))
    pq = pq + MEASURE(code_register[3], ro[0])
Esempio n. 28
0
def main():

    A_SIZE = 4
    a = QubitPlaceholder.register(A_SIZE)
    n = QubitPlaceholder.register(A_SIZE)
    b = QubitPlaceholder.register(A_SIZE)
    c = QubitPlaceholder.register(A_SIZE)
    exp = QubitPlaceholder.register(A_SIZE)
    t = QubitPlaceholder()

    nila = QubitPlaceholder.register(A_SIZE)

    master = QubitPlaceholder()

    N = 3
    base = 2

    p = Program()

    p += write_in(1, exp)
    p += write_in(1, a)
    p += write_in(0, b)
    p += write_in(N, n)
    p += write_in(0, c)

    p += EXP_MOD(c, a, b, n, N, t, nila, base, exp)
    #p += MUL_MOD(c, a, b, n, N, t, nila, multiplier, master)
    #p += ADDER_MOD(c, a, b, n, N, t)
    #p += REVERSE(ADDER(c, a, b))
    #p += ADDER(c, a, b)

    res, code = read_out(p, a)
    print(res)

    #qbit_lookup = {}
    #lookup_append(qbit_lookup, a, "a")
    #lookup_append(qbit_lookup, b, "b")
    #lookup_append(qbit_lookup, c, "c")
    #pretty_print(qbit_lookup)

    embed(colors="Neutral")
Esempio n. 29
0
def construct_toric_code(L: int) -> Tuple[nx.Graph]:
    '''Constructs a toric code as a NetworkX graph structure.

    Args
    - L: int, # of physical qubits on one side of the square lattice

    Returns
    - primal_graph: nx.Graph, L x L lattice
    - dual_graph: nx.Graph, L x L lattice
    - distance_graph: nx.Graph, nodes are primal_graph edges (qubits), edges
        indicate adjacency between those qubits, needed for MWPM algorithm
    '''
    # Generate a L x L lattice with periodic boundary conditions
    primal_graph = nx.generators.lattice.grid_2d_graph(L, L, periodic=True)
    for edge in primal_graph.edges:
        # Add data qubits to edges
        primal_graph.edges[edge]['data_qubit'] = QubitPlaceholder()
    for node in primal_graph.nodes:
        # Add ancilla qubits to nodes
        primal_graph.nodes[node]['ancilla_qubit'] = QubitPlaceholder()

    dual_graph = nx.generators.lattice.grid_2d_graph(L, L, periodic=True)
    for edge in dual_graph.edges:
        dual_graph.edges[edge]['data_qubit'] = primal_graph.edges[dual_edge_to_primal_edge(edge, L)]['data_qubit']
    for node in dual_graph.nodes:
        dual_graph.nodes[node]['ancilla_qubit'] = QubitPlaceholder()

    distance_graph = nx.Graph()
    for edge in primal_graph.edges:
        edge = sort_edge(edge, L)
        distance_graph.add_node(edge)
        distance_graph.nodes[edge]['data_qubit'] = primal_graph.edges[edge]['data_qubit']
    for n1 in distance_graph.nodes:
        for n2 in distance_graph.nodes:
            if n1 == n2:
                continue

            if (n1[0] == n2[0]) or (n1[0] == n2[1]) or (n1[1] == n2[0]) or (n1[1] == n2[1]):
                distance_graph.add_edge(n1, n2)

    return primal_graph, dual_graph, distance_graph
Esempio n. 30
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)"
""")