예제 #1
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"
예제 #2
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]
예제 #3
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]
예제 #4
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
예제 #5
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)
예제 #6
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]
예제 #7
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()
예제 #8
0
파일: test_quil.py 프로젝트: tocheng/pyquil
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"
예제 #9
0
파일: test_quil.py 프로젝트: tocheng/pyquil
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"
예제 #10
0
파일: test_quil.py 프로젝트: tocheng/pyquil
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
예제 #11
0
파일: test_quil.py 프로젝트: tocheng/pyquil
def test_placeholders_preserves_modifiers():
    cs = QubitPlaceholder.register(3)
    ts = QubitPlaceholder.register(1)

    g = X(ts[0])
    for c in cs:
        g = g.controlled(c).dagger()

    p = Program(g)
    a = address_qubits(p)

    assert a[0].modifiers == g.modifiers
예제 #12
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)))
예제 #13
0
def controlled_modular_multiply(ancilla_cache, program, control, constant,
                                modulus, multiplier):
    """
    This function implements the operation (A*B mod C), where A and C are constants,
    and B is a qubit register representing a little-endian integer.

    Remarks:
        See the Q# source for the "ModularMultiplyByConstantLE" function at
        https://github.com/Microsoft/QuantumLibraries/blob/master/Canon/src/Arithmetic/Arithmetic.qs
    """

    summand = None
    if not "summand" in ancilla_cache:
        summand = QubitPlaceholder.register(len(multiplier))
        ancilla_cache["summand"] = summand
    else:
        summand = ancilla_cache["summand"]

    program += controlled_modular_add_product(ancilla_cache, control, constant,
                                              modulus, multiplier, summand)

    for i in range(0, len(multiplier)):
        program += CSWAP(control, summand[i], multiplier[i])

    inverse_mod_value = inverse_mod(constant, modulus)

    program += controlled_modular_add_product(ancilla_cache, control,
                                              inverse_mod_value, modulus,
                                              multiplier, summand).dagger()
예제 #14
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)
예제 #15
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)
예제 #16
0
def test_exponentiate_3ns():
    # testing circuit for 3-terms non-sequential
    q = QubitPlaceholder.register(8)
    generator = (
        PauliTerm("Y", q[0], 1.0)
        * PauliTerm("I", q[1], 1.0)
        * PauliTerm("Y", q[2], 1.0)
        * PauliTerm("Y", q[3], 1.0)
    )
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst(
        [
            RX(math.pi / 2.0, q[0]),
            RX(math.pi / 2.0, q[2]),
            RX(math.pi / 2.0, q[3]),
            CNOT(q[0], q[2]),
            CNOT(q[2], q[3]),
            RZ(2.0, q[3]),
            CNOT(q[2], q[3]),
            CNOT(q[0], q[2]),
            RX(-math.pi / 2.0, q[0]),
            RX(-math.pi / 2.0, q[2]),
            RX(-math.pi / 2.0, q[3]),
        ]
    )
    assert address_qubits(prog) == address_qubits(result_prog)
def get_rb_gateset(rb_type: str) -> Tuple[List[Gate], Tuple[QubitPlaceholder]]:
    """
    A wrapper around the gateset generation functions.

    :param rb_type: "1q" or "2q".
    :returns: list of gates, tuple of qubits
    """
    if rb_type == '1q':
        q = QubitPlaceholder()
        return list(oneq_rb_gateset(q)), (q,)

    if rb_type == '2q':
        q1, q2 = QubitPlaceholder.register(n=2)
        return list(twoq_rb_gateset(q1, q2)), (q1, q2)

    raise ValueError(f"No RB gateset for {rb_type}")
예제 #18
0
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)
예제 #19
0
def test_simplify_term_single():
    q0, q1, q2 = QubitPlaceholder.register(3)
    term = (
        PauliTerm("Z", q0) * PauliTerm("I", q1) * PauliTerm("X", q2, 0.5j) * PauliTerm("Z", q0, 1.0)
    )
    assert term.id() == "X{}".format(q2)
    assert term.coefficient == 0.5j
예제 #20
0
파일: test_quil.py 프로젝트: tocheng/pyquil
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"
예제 #21
0
    def correct_errors(self, program, qubits):
        """
        Corrects any errors that have occurred within the logical qubit register.

        Parameters:
            program (Program): The program to add the error correction to
            qubits (list[QubitPlaceholder]): The logical qubit register to check and correct
        """

        parity_qubits = QubitPlaceholder.register(3)
        parity_measurement = program.declare("parity_measurement", "BIT", 3)

        # Correct bit flips
        self.detect_bit_flip_error(program, qubits, parity_qubits,
                                   parity_measurement)
        self.generate_classical_control_corrector(program, qubits,
                                                  parity_measurement, X)
        for qubit in parity_qubits:
            program += RESET(qubit)

        # Correct phase flips
        self.detect_phase_flip_error(program, qubits, parity_qubits,
                                     parity_measurement)
        self.generate_classical_control_corrector(program, qubits,
                                                  parity_measurement, Z)
def test_commuting_sets():
    q = QubitPlaceholder.register(8)
    term1 = PauliTerm("X", q[0]) * PauliTerm("X", q[1])
    term2 = PauliTerm("Y", q[0]) * PauliTerm("Y", q[1])
    term3 = PauliTerm("Y", q[0]) * PauliTerm("Z", q[2])
    pauli_sum = term1 + term2 + term3
    commuting_sets(pauli_sum)
예제 #23
0
    def detect_error(self, program, qubits):
        """
        Detects a bit-flip error on one of the three qubits in a logical qubit register.

        Parameters:
            program (Program): The program to add the error detection to
            qubits (list[QubitPlaceholder]): The logical qubit register to check for errors

        Returns:
            A MemoryReference list representing the parity measurements. The first one
            contains the parity of qubits 0 and 1, and the second contains the parity
            of qubits 0 and 2.
        """

        # The plan here is to check if q0 and q1 have the same parity (00 or 11), and if q0 and q2
        # have the same parity. If both checks come out true, then there isn't an error. Otherwise,
        # if one of the checks reveals a parity discrepancy, we can use the other check to tell us
        # which qubit is broken.
        
        parity_qubits = QubitPlaceholder.register(2)
        parity_measurement = program.declare("parity_measurement", "BIT", 2)

        # Check if q0 and q1 have the same value
        program += CNOT(qubits[0], parity_qubits[0])
        program += CNOT(qubits[1], parity_qubits[0])
        
        # Check if q0 and q2 have the same value
        program += CNOT(qubits[0], parity_qubits[1])
        program += CNOT(qubits[2], parity_qubits[1])

        # Measure the parity values and return the measurement register
        program += MEASURE(parity_qubits[0], parity_measurement[0])
        program += MEASURE(parity_qubits[1], parity_measurement[1])

        return parity_measurement
def test_enumerate():
    q0, q1, q5 = QubitPlaceholder.register(3)
    term = PauliTerm("Z", q0, 1.0) * PauliTerm("Z", q1, 1.0) * PauliTerm(
        "X", q5, 5)
    position_op_pairs = [(q0, "Z"), (q1, "Z"), (q5, "X")]
    for key, val in term:
        assert (key, val) in position_op_pairs
def test_pauli_sum():
    q = QubitPlaceholder.register(8)
    q_plus = 0.5 * PauliTerm('X', q[0]) + 0.5j * PauliTerm('Y', q[0])
    the_sum = q_plus * PauliSum([PauliTerm('X', q[0])])
    term_strings = [str(x) for x in the_sum.terms]
    assert '(0.5+0j)*I' in term_strings
    assert len(term_strings) == 2
    assert len(the_sum.terms) == 2

    the_sum = q_plus * PauliTerm('X', q[0])
    term_strings = [str(x) for x in the_sum.terms]
    assert '(0.5+0j)*I' in term_strings
    assert len(term_strings) == 2
    assert len(the_sum.terms) == 2

    the_sum = PauliTerm('X', q[0]) * q_plus
    term_strings = [str(x) for x in the_sum.terms]
    assert '(0.5+0j)*I' in term_strings
    assert len(term_strings) == 2
    assert len(the_sum.terms) == 2

    with pytest.raises(ValueError):
        _ = PauliSum(sI(q[0]))
    with pytest.raises(ValueError):
        _ = PauliSum([1, 1, 1, 1])
    with pytest.raises(ValueError):
        _ = the_sum * []
def test_operations_as_set():
    q = QubitPlaceholder.register(6)
    term_1 = PauliTerm("Z", q[0], 1.0) * PauliTerm("Z", q[1], 1.0) * PauliTerm(
        "X", q[5], 5)
    term_2 = PauliTerm("X", q[5], 5) * PauliTerm("Z", q[0], 1.0) * PauliTerm(
        "Z", q[1], 1.0)
    assert term_1.operations_as_set() == term_2.operations_as_set()
def test_exponentiate_identity():
    q = QubitPlaceholder.register(11)
    mapping = {qp: Qubit(i) for i, qp in enumerate(q)}
    generator = PauliTerm("I", q[1], 0.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst()
    assert address_qubits(prog,
                          mapping) == address_qubits(result_prog, mapping)

    generator = PauliTerm("I", q[1], 1.0)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst(
        [X(q[0]), PHASE(-1.0, q[0]),
         X(q[0]), PHASE(-1.0, q[0])])
    assert address_qubits(prog,
                          mapping) == address_qubits(result_prog, mapping)

    generator = PauliTerm("I", q[10], 0.08)
    para_prog = exponential_map(generator)
    prog = para_prog(1)
    result_prog = Program().inst(
        [X(q[0]), PHASE(-0.08, q[0]),
         X(q[0]), PHASE(-0.08, q[0])])
    assert address_qubits(prog,
                          mapping) == address_qubits(result_prog, mapping)
예제 #28
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:])
def test_check_commutation_rigorous():
    # more rigorous test.  Get all operators in Pauli group
    p_n_group = ("I", "X", "Y", "Z")
    pauli_list = list(product(p_n_group, repeat=3))
    pauli_ops = [
        list(zip(x, QubitPlaceholder.register(3))) for x in pauli_list
    ]
    pauli_ops_pq = [
        reduce(mul, (PauliTerm(*x) for x in op)) for op in pauli_ops
    ]

    non_commuting_pairs = []
    commuting_pairs = []
    for x in range(len(pauli_ops_pq)):
        for y in range(x, len(pauli_ops_pq)):

            tmp_op = _commutator(pauli_ops_pq[x], pauli_ops_pq[y])
            assert len(tmp_op.terms) == 1
            if is_zero(tmp_op.terms[0]):
                commuting_pairs.append((pauli_ops_pq[x], pauli_ops_pq[y]))
            else:
                non_commuting_pairs.append((pauli_ops_pq[x], pauli_ops_pq[y]))

    # now that we have our sets let's check against our code.
    for t1, t2 in non_commuting_pairs:
        assert not check_commutation([t1], t2)

    for t1, t2 in commuting_pairs:
        assert check_commutation([t1], t2)
예제 #30
0
def NN_encode(qubit: QubitPlaceholder,
              N: int) -> (Program, List[QubitPlaceholder]):

    ### qubit: qubit you want to encode (main qubit)
    ### N: number of qubits you want to encode the main qubit in.
    ### For N=1, there is no encoding

    code_register = QubitPlaceholder.register(
        N)  # the List[QubitPlaceholder] of the qubits you have encoded into
    code_register[0] = qubit

    pq = Program()

    ### creation of GHZ state:
    for ii in range(N - 1):
        pq += CNOT(code_register[ii], code_register[ii + 1])

    for jj in range(N - 1):
        pq += H(code_register[jj])
        pq += CZ(code_register[jj + 1], code_register[jj])

    for kk in range(N - 1):
        pq += CNOT(code_register[kk], code_register[-1])

    return pq, code_register