Example #1
0
 def qft3(q0, q1, q2):
     p = Program()
     p.inst(H(q2),
            CPHASE(pi / 2.0)(q1, q2), H(1),
            CPHASE(pi / 4.0)(q0, q2),
            CPHASE(pi / 2.0)(q0, q1), H(q0), SWAP(q0, q2))
     return p
def test_CPHASE():
    for theta in np.linspace(-2 * np.pi, 2 * np.pi):
        u1 = program_unitary(Program(CPHASE(theta, 0, 1)), n_qubits=2)
        u2 = program_unitary(_CPHASE(theta, 0, 1), n_qubits=2)
        assert equal_up_to_global_phase(u1, u2, atol=1e-12)

        u1 = program_unitary(Program(CPHASE(theta, 1, 0)), n_qubits=2)
        u2 = program_unitary(_CPHASE(theta, 1, 0), n_qubits=2)
        assert equal_up_to_global_phase(u1, u2, atol=1e-12)
def test_gates_in_isa(isa_dict):
    isa = ISA.from_dict(isa_dict)
    gates = gates_in_isa(isa)
    for q in [0, 1, 2]:
        for g in [I, RX(np.pi / 2), RX(-np.pi / 2), RZ(THETA)]:
            assert g(q) in gates

    assert CZ(0, 1) in gates
    assert CZ(1, 0) in gates
    assert ISWAP(1, 2) in gates
    assert ISWAP(2, 1) in gates
    assert CPHASE(THETA)(2, 0) in gates
    assert CPHASE(THETA)(0, 2) in gates
Example #4
0
def test_multi_qubit_qft():
    trial_prog = Program()
    trial_prog.inst(X(0), X(1), X(2))
    trial_prog = trial_prog + inverse_qft([0, 1, 2])
    
    result_prog = Program().inst([X(0), X(1), X(2),
                                     SWAP(0, 2), H(0),
                                     CPHASE(-1.5707963267948966, 0, 1),
                                     CPHASE(-0.7853981633974483, 0, 2),
                                     H(1), CPHASE(-1.5707963267948966, 1, 2),
                                     H(2)])
    
    assert trial_prog == result_prog
Example #5
0
def test_phases():
    p = Program(PHASE(np.pi, 1), CPHASE00(np.pi, 0, 1), CPHASE01(np.pi, 0, 1),
                CPHASE10(np.pi, 0, 1),
                CPHASE(np.pi, 0, 1))
    assert p.out() == 'PHASE(pi) 1\nCPHASE00(pi) 0 1\n' \
                      'CPHASE01(pi) 0 1\nCPHASE10(pi) 0 1\n' \
                      'CPHASE(pi) 0 1\n'
Example #6
0
def test_gradient_program():
    f_h = 0.25
    precision = 2

    trial_prog = gradient_program(f_h, precision)

    result_prog = pq.Program([H(0), H(1)])

    phase_factor = np.exp(-1.0j * 2 * np.pi * abs(f_h))
    U = np.array([[phase_factor, 0], [0, phase_factor]])
    q_out = range(precision, precision + 1)
    for i in range(precision):
        if i > 0:
            U = np.dot(U, U)
        cU = controlled(U)
        name = "CONTROLLED-U{0}".format(2**i)
        result_prog.defgate(name, cU)
        result_prog.inst((name, i) + tuple(q_out))

    result_prog.inst([
        H(1),
        CPHASE(1.5707963267948966, 0, 1),
        H(0),
        SWAP(0, 1),
        MEASURE(0, [0]),
        MEASURE(1, [1])
    ])

    assert (trial_prog == result_prog)
Example #7
0
def test_phases():
    p = Program(PHASE(np.pi)(1), CPHASE00(np.pi)(0, 1), CPHASE01(np.pi)(0, 1),
                CPHASE10(np.pi)(0, 1),
                CPHASE(np.pi)(0, 1))
    assert p.out() == 'PHASE(3.141592653589793) 1\nCPHASE00(3.141592653589793) 0 1\n' \
                      'CPHASE01(3.141592653589793) 0 1\nCPHASE10(3.141592653589793) 0 1\n' \
                      'CPHASE(3.141592653589793) 0 1\n'
Example #8
0
def _core_sycamore_circuit(reg: List[int], depth: int) -> Program:
    """
    Generates the core program to perform an approximation of the Sycamore chip benchmark
    
    :param qubits: A list of qubit indexes.
    :param depth: Benchmark circuit depth
    :return: A Quil program to perform an approximation of the Sycamore chip benchmark
    """

    num_qubits = len(reg)
    gateSequence = [0, 3, 2, 1, 2, 1, 0, 3]
    single_bit_gates = sqrtx, sqrty, H  # H should actually be sqrth
    circ = []

    lastSingleBitGates = []

    colLen = math.floor(math.sqrt(num_qubits))
    while (((num_qubits / colLen) * colLen) != num_qubits):
        colLen = colLen - 1
    rowLen = num_qubits // colLen

    for i in range(depth):
        # Single bit gates
        singleBitGates = []
        for j in range(num_qubits):
            gate = random.choice(single_bit_gates)
            if len(lastSingleBitGates) > 0:
                while gate == lastSingleBitGates[j]:
                    gate = random.choice(single_bit_gates)
            circ.append(gate(reg[j]))
            singleBitGates.append(gate)

        lastSingleBitGates = singleBitGates

        gate = gateSequence[0]
        gateSequence.pop(0)
        gateSequence.append(gate)

        for row in range(1, rowLen, 2):
            for col in range(0, colLen):
                tempRow = row
                tempCol = col

                tempRow = tempRow + (1 if (gate & 2) else -1)
                if colLen != 1:
                    tempCol = tempCol + (1 if (gate & 1) else 0)

                if (tempRow < 0) or (tempCol < 0) or (tempRow >= rowLen) or (
                        tempCol >= colLen):
                    continue

                b1 = row * colLen + col
                b2 = tempRow * colLen + tempCol

                # Two bit gates
                circ.append(CPHASE(math.pi / 6, reg[b1], reg[b2]))
                circ.append(SWAP(reg[b1], reg[b2]))

    return circ
Example #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(-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'
Example #10
0
def test_get_qvm_noise_supported_gates_from_compiler_isa(compiler_isa):
    gates = _get_qvm_noise_supported_gates(compiler_isa)
    for q in [0, 1, 2]:
        for g in [
                I(q),
                RX(np.pi / 2, q),
                RX(-np.pi / 2, q),
                RX(np.pi, q),
                RX(-np.pi, q),
                RZ(THETA, q),
        ]:
            assert g in gates

    assert CZ(0, 1) in gates
    assert CZ(1, 0) in gates
    assert ISWAP(1, 2) in gates
    assert ISWAP(2, 1) in gates
    assert CPHASE(THETA, 2, 0) in gates
    assert CPHASE(THETA, 0, 2) in gates
Example #11
0
def QFT3():  # pylint: disable=invalid-name
    """ Returns the Quantum Fourier Transform of 3 qubits
        pyquil circuit"""
    prog = Program()
    ro = prog.declare("ro", memory_size=3)
    prog += [
        SWAP(0, 2),
        H(0),
        CPHASE(-pi / 2.0, 0, 1),
        H(1),
        CPHASE(-pi / 4.0, 0, 2),
        CPHASE(-pi / 2.0, 1, 2),
        H(2),
    ]

    prog.measure(0, ro[0])
    prog.measure(1, ro[1])
    prog.measure(2, ro[2])
    return prog
Example #12
0
def test_phases():
    p = Program(
        PHASE(np.pi, 1),
        CPHASE00(np.pi, 0, 1),
        CPHASE01(np.pi, 0, 1),
        CPHASE10(np.pi, 0, 1),
        CPHASE(np.pi, 0, 1),
    )
    assert (p.out() == "PHASE(pi) 1\nCPHASE00(pi) 0 1\n"
            "CPHASE01(pi) 0 1\nCPHASE10(pi) 0 1\n"
            "CPHASE(pi) 0 1\n")
Example #13
0
def inverse_qft_2q(qubits):

    prog = Program()

    prog += SWAP(0, 1)
    # QFT is unitary, thus the inverse QFT contains reversed order of gates
    # with complex conjugate in CPHASE
    prog += H(0)
    prog += CPHASE(-math.pi / 2, 0, 1)
    prog += H(1)

    return prog
Example #14
0
def control_gate(target_program, gate, ancillary):
    """
    Adds to the target_program controlled version of the gate

    :param target_program: pyquil Program
    :param gate: pyquil Gate
    :param ancillary: controlling qubit number

    :return: noting. Changes the target_program
    """

    # gate should be pyquil Gate
    if not isinstance(gate, Gate):
        raise NotGateException('Not a Gate!!')

    # target_program should be pyquil Program
    if not isinstance(target_program, Program):
        raise ValueError('Not a program!!')

    qubits = list(gate.get_qubits())
    params = gate.params

    if gate.name == "X":
        target_program.inst(CNOT(ancillary, qubits[0]))
        return

    if gate.name == "CNOT":
        target_program.inst(CCNOT(ancillary, qubits[0], qubits[1]))
        return

    if gate.name == "PHASE":
        target_program.inst(CPHASE(params[0], ancillary, qubits[0]))
        return

    if gate.name == "H":
        def_CH = create_CH()
        CH = def_CH.get_constructor()
        target_program.inst(CH(ancillary, qubits[0]))
        return

    if gate.name == "RX":
        def_CRX = create_CRX()
        CRX = def_CRX.get_constructor()
        target_program.inst(CRX(params[0])(ancillary, qubits[0]))
        return

    if gate.name == "RZ":
        def_CRZ = create_CRZ()
        CRZ = def_CRZ.get_constructor()
        target_program.inst(CRZ(params[0])(ancillary, qubits[0]))
        return

    raise ValueError("wrong Gate or don't have controlled version")
Example #15
0
 def core_qft(qubits):
     q = qubits[0]
     qs = qubits[1:]
     if 1 == len(qubits):
         return [H(q)]
     else:
         n = 1 + len(qs)
         cR = []
         for idx, i in enumerate(xrange(n - 1, 0, -1)):
             q_idx = qs[idx]
             angle = math.pi / 2**(n - i)
             cR.append(CPHASE(angle)(q, q_idx))
         return core_qft(qs) + list(reversed(cR)) + [H(q)]
Example #16
0
def qft_pyquil(n):
    p = Program()

    ro = p.declare('ro', memory_type='BIT', memory_size=n)

    for j in range(n):
        for k in range(j):
            p.inst(CPHASE(math.pi / float(2**(j - k)), j, k))
        p.inst(H(j))

    for i in range(n):
        p.inst(MEASURE(i, ro[i]))

    return p
Example #17
0
def crotate(qubit, controls, coef=1, start_index=0):
    """
    Generates the a circuit to make conditional rotations
    on the `qubit` using `controls` as control qubits.

    :param qubit: the qubit to apply the rotation on.
    :param controls: the control qubits to use for rotation.
    :param coeff: A modifier for the angle used in rotations (-1 for inverse
                 QFT, 1 for QFT)
    :param start_index: index of the controls[0] q indicating from which digit are the control qubits given.
    :return: A Quil program to compute the conditional rotation
           on the `qubit` using `controls` as control qubits
    """
    instructions = []
    for index, cqubit in enumerate(controls[::-1]):
        angle = pi / 2**(index + start_index)
        instructions.append(CPHASE(coef * angle, cqubit, qubit))

    return instructions
Example #18
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'
Example #19
0
def _qaoa_cost_ham_rotation(zz_rotation_angles_reg: MemoryReference,
                            qubit_pairs: List,
                            z_rotation_angles_reg: MemoryReference,
                            qubit_singles: List) -> Program:
    """Produce the Quil-Code for the cost-hamiltonian rotation.

    Parameters
    ----------
    zz_rotation_angles_reg:
        Classic register to read the zz_rotation_angles from.
    qubit_pairs:
        List of the Qubit pairs to apply rotations on.
    z_rotation_angles_reg:
        Classic register to read the z_rotation_angles from.
    qubit_singles:
        List of the single qubits to apply rotations on.

    Returns
    -------
    Program
        Parametric Quil code containing the Z-Rotations.

    """
    p = Program()

    if len(qubit_pairs) != zz_rotation_angles_reg.declared_size:
        raise ValueError("zz_rotation_angles_reg must have the same length"
                         " as qubits_pairs")

    for zz_angle, qubit_pair in zip(zz_rotation_angles_reg, qubit_pairs):
        p.inst(RZ(2 * zz_angle, qubit_pair[0]))
        p.inst(RZ(2 * zz_angle, qubit_pair[1]))
        p.inst(CPHASE(-4 * zz_angle, qubit_pair[0], qubit_pair[1]))

    if z_rotation_angles_reg.declared_size != len(qubit_singles):
        raise ValueError("z_rotation_angles_reg must have the same length as"
                         " qubit_singles")

    for z_angle, qubit in zip(z_rotation_angles_reg, qubit_singles):
        p.inst(RZ(2 * z_angle, qubit))

    return p
Example #20
0
def _core_qft(qubits: List[int], coeff: int) -> Program:
    """
    Generates the core program to perform the quantum Fourier transform
    
    :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 core (inverse) QFT of the qubits.
    """

    q = qubits[0]
    qs = qubits[1:]
    if 1 == len(qubits):
        return [H(q)]
    else:
        n = 1 + len(qs)
        cR = []
        for idx, i in enumerate(range(n - 1, 0, -1)):
            q_idx = qs[idx]
            angle = math.pi / 2**(n - i)
            cR.append(CPHASE(coeff * angle, q, q_idx))
        return _core_qft(qs, coeff) + list(reversed(cR)) + [H(q)]
Example #21
0
def controlled_phase(phi, q, *wires):
    r"""Maps the two-qubit controlled phase gate to the equivalent pyQuil command.

    Args:
        phi (float): the controlled phase angle
        q (int): an integer between 0 and 3 that corresponds to a state
            :math:`\{00, 01, 10, 11\}` on which the conditional phase
            gets applied
        wires (list): list of wires the CPHASE gate acts on

    Returns:
        pyquil.operation: the corresponding pyQuil operation
    """
    # pylint: disable=no-value-for-parameter
    if q == 0:
        return CPHASE00(phi, *wires)
    if q == 1:
        return CPHASE01(phi, *wires)
    if q == 2:
        return CPHASE10(phi, *wires)

    return CPHASE(phi, *wires)
Example #22
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
Example #23
0
def StateInit(qc, circuit_params, p, q, r, s, circuit_choice, control, sign):
    '''This function computes the state produced after the given circuit, either QAOA, IQP, or IQPy,
		depending on the value of circuit_choice.'''

    #sign = 'POSITIVE' for the positive probability version, sign = 'NEGATIVE' for the negative version of the probability (only used to compute the gradients)
    #final_layer is either 'IQP', 'QAOA', 'IQPy' for IQP (Final Hadamard), QAOA (Final X rotation) or IQPy (Final Y rotation)
    #control = 'BIAS' for updating biases, = 'WEIGHTS' for updating weights, = 'NEITHER' for neither

    #Initialise empty quantum program, with QuantumComputer Object, and Wavefunction Simulator
    '''With Active qubit reset'''
    # prog = Program(RESET())
    '''Without Active qubit reset'''
    prog = Program()

    qubits = qc.qubits()
    N_qubits = len(qubits)
    #Unpack circuit parameters from dictionary
    J = circuit_params['J']
    b = circuit_params['b']
    gamma = circuit_params['gamma']
    delta = circuit_params['delta']

    #Apply hadarmard to all qubits in computation
    prog = HadamardToAll(prog, qubits)

    # print(qc.name)

    #Apply Control-Phase(4J) gates to each qubit, the factor of 4 comes from the decomposition of the Ising gate
    #with local Z corrections to neighbouring qubits, coming from the decomposition of the Ising gate
    #If weight J_{p,q} is updated, add a +/- pi/2 rotation
    if qc.name.lower() == 'aspen-3-3q-b-qvm':
        ''''Specific entanglement structure for Rigetti Aspen-3-2Q-C'''
        if (control.lower() == 'weights' and p == 0 and q == 1):
            #first weight parameter between qubit[1] and qubit[2]

            prog.inst(
                CPHASE(4 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[0],
                       qubits[1]))
            prog.inst(PHASE(-2 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[0]))
            prog.inst(PHASE(-2 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[1]))

        elif (control.lower() == 'weights' and p == 1 and q == 2):
            #Second weight parameter between qubit[1] and qubit[2]
            prog.inst(
                CPHASE(4 * J[1, 2] + (-1)**(sign) * pi / 2, qubits[1],
                       qubits[2]))
            prog.inst(PHASE(-2 * J[1, 2] + (-1)**(sign) * pi / 2, qubits[1]))
            prog.inst(PHASE(-2 * J[1, 2] + (-1)**(sign) * pi / 2, qubits[2]))

        elif (control.lower() == 'neither' or 'bias'
              or 'gamma' and sign.lower() == 'neither'):
            prog.inst(CPHASE(4 * J[0, 1], qubits[0], qubits[1]))
            prog.inst(PHASE(-2 * J[0, 1], qubits[0]))
            prog.inst(PHASE(-2 * J[0, 1], qubits[1]))

            prog.inst(CPHASE(4 * J[1, 2], qubits[1], qubits[2]))
            prog.inst(PHASE(-2 * J[1, 2], qubits[1]))
            prog.inst(PHASE(-2 * J[1, 2], qubits[2]))

    elif qc.name.lower() == 'aspen-4-3q-a' or qc.name.lower(
    ) == 'aspen-4-3q-a-qvm':
        ''''Specific entanglement structure for Rigetti Aspen-4-3Q-A
			17 - 10 - 11
			'''
        if (control.lower() == 'weights' and p == 0 and q == 1):
            #first weight parameter between qubit[1] and qubit[2]

            prog.inst(
                CPHASE(4 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[0],
                       qubits[1]))
            prog.inst(PHASE(-2 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[0]))
            prog.inst(PHASE(-2 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[1]))

        elif (control.lower() == 'weights' and p == 1 and q == 2):
            #Second weight parameter between qubit[1] and qubit[2]
            prog.inst(
                CPHASE(4 * J[0, 2] + (-1)**(sign) * pi / 2, qubits[0],
                       qubits[2]))
            prog.inst(PHASE(-2 * J[0, 2] + (-1)**(sign) * pi / 2, qubits[0]))
            prog.inst(PHASE(-2 * J[0, 2] + (-1)**(sign) * pi / 2, qubits[2]))

        elif (control.lower() == 'neither' or 'bias'
              or 'gamma' and sign.lower() == 'neither'):
            prog.inst(CPHASE(4 * J[0, 1], qubits[0], qubits[1]))
            prog.inst(PHASE(-2 * J[0, 1], qubits[0]))
            prog.inst(PHASE(-2 * J[0, 1], qubits[1]))

            prog.inst(CPHASE(4 * J[0, 2], qubits[0], qubits[2]))
            prog.inst(PHASE(-2 * J[0, 2], qubits[0]))
            prog.inst(PHASE(-2 * J[0, 2], qubits[2]))

    elif qc.name.lower() == 'aspen-4-4q-a' or qc.name.lower(
    ) == 'aspen-4-4q-a-qvm':
        ''''
			Specific entanglement structure for Rigetti Aspen-4-4Q-A 
			7 - 0 - 1 - 2
			'''
        if (control.lower() == 'weights' and p == 0 and q == 1):
            #first weight parameter between qubit[1] and qubit[2]

            prog.inst(
                CPHASE(4 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[0],
                       qubits[1]))
            prog.inst(PHASE(-2 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[0]))
            prog.inst(PHASE(-2 * J[0, 1] + (-1)**(sign) * pi / 2, qubits[1]))

        elif (control.lower() == 'weights' and p == 1 and q == 2):
            #Second weight parameter between qubit[1] and qubit[2]
            prog.inst(
                CPHASE(4 * J[1, 2] + (-1)**(sign) * pi / 2, qubits[1],
                       qubits[2]))
            prog.inst(PHASE(-2 * J[1, 2] + (-1)**(sign) * pi / 2, qubits[1]))
            prog.inst(PHASE(-2 * J[1, 2] + (-1)**(sign) * pi / 2, qubits[2]))

        elif (control.lower() == 'weights' and p == 0 and q == 3):
            #Second weight parameter between qubit[1] and qubit[2]
            prog.inst(
                CPHASE(4 * J[0, 3] + (-1)**(sign) * pi / 2, qubits[0],
                       qubits[3]))
            prog.inst(PHASE(-2 * J[0, 3] + (-1)**(sign) * pi / 2, qubits[0]))
            prog.inst(PHASE(-2 * J[0, 3] + (-1)**(sign) * pi / 2, qubits[3]))

        elif (control.lower() == 'neither' or 'bias'
              or 'gamma' and sign.lower() == 'neither'):
            prog.inst(CPHASE(4 * J[0, 1], qubits[0], qubits[1]))
            prog.inst(PHASE(-2 * J[0, 1], qubits[0]))
            prog.inst(PHASE(-2 * J[0, 1], qubits[1]))

            prog.inst(CPHASE(4 * J[1, 2], qubits[1], qubits[2]))
            prog.inst(PHASE(-2 * J[1, 2], qubits[1]))
            prog.inst(PHASE(-2 * J[1, 2], qubits[2]))

            prog.inst(CPHASE(4 * J[0, 3], qubits[0], qubits[3]))
            prog.inst(PHASE(-2 * J[0, 3], qubits[0]))
            prog.inst(PHASE(-2 * J[0, 3], qubits[3]))
    else:
        for j in range(0, N_qubits):
            for i in range(0, N_qubits):
                if (
                        i < j
                ):  #connection is symmetric, so don't overcount entangling gates
                    if (control.lower() == 'weights' and i == p and j == q):
                        prog.inst(
                            CPHASE(4 * J[i, j] + (-1)**(sign) * pi / 2,
                                   qubits[i], qubits[j]))
                        prog.inst(
                            PHASE(-2 * J[i, j] + (-1)**(sign) * pi / 2,
                                  qubits[i]))
                        prog.inst(
                            PHASE(-2 * J[i, j] + (-1)**(sign) * pi / 2,
                                  qubits[j]))

                    elif (control.lower() == 'neither' or 'bias'
                          or 'gamma' and sign.lower() == 'neither'):
                        prog.inst(CPHASE(4 * J[i, j], qubits[i], qubits[j]))
                        prog.inst(PHASE(-2 * J[i, j], qubits[i]))
                        prog.inst(PHASE(-2 * J[i, j], qubits[j]))

    #Apply local Z rotations (b) to each qubit (with one phase changed by pi/2 if the corresponding parameter {r} is being updated
    for j in range(0, N_qubits):
        if (control == 'BIAS' and j == r):
            prog.inst(PHASE(-2 * b[j] + (-1)**(sign) * pi / 2, qubits[j]))
        elif (control == 'NEITHER' or 'WEIGHTS'
              or 'GAMMA' and sign == 'NEITHER'):
            prog.inst(PHASE(-2 * b[j], qubits[j]))

    #Apply final 'measurement' layer to all qubits, either all Hadamard, or X or Y rotations
    if (circuit_choice == 'IQP'):
        prog = HadamardToAll(
            prog, qubits
        )  #If the final 'measurement' layer is to be an IQP measurement (i.e. Hadamard on all qubits)

    elif (circuit_choice == 'QAOA'):
        #If the final 'measurement' layer is to be a QAOA measurement (i.e. e^(-i(pi/4)X_i)on all qubits)
        for k in range(0, N_qubits):
            # if (control == 'GAMMA' and k == s):
            # 	prog.inst(pl.exponential_map(sX(k))(-float(gamma[k])+ (-1)**(sign)*pi/2))

            # elif (control == 'NEITHER' or 'WEIGHTS' or 'BIAS' and sign == 'NEITHER'):
            H_temp = (-float(gamma[k])) * pl.sX(qubits[k])
            prog.inst(pl.exponential_map(H_temp)(1.0))
            # print('GAMMA IS:',-float(gamma[k]))
    elif (circuit_choice == 'IQPy'):
        #If the final 'measurement' layer is to be a IQPy measurement (i.e. e^(-i(pi/4)Y_i) on all qubits)
        for k in qubits:
            H_temp = (-float(delta[k])) * pl.sY(qubits[k])
            prog.inst(pl.exponential_map(H_temp)(1.0))

    else:
        raise ValueError("circuit_choice must be either  \
							\'IQP\' for IQP (Final Hadamard), \
							\'QAOA\' for QAOA (Final X rotation) or \
							\'IQPy\' IQPy (Final Y rotation)")
    # print(prog)
    '''Insert explicit measure instruction if required'''
    # ro = prog.declare('ro', 'BIT', len(qubits))
    # prog.inst([MEASURE(qubit, ro[idx]) for idx, qubit in enumerate(qubits)])

    return prog
Example #24
0
    RY,
    RZ,
    SWAP,
    X,
    QUANTUM_GATES,
)
from pyquil.paulis import PauliTerm, exponentiate, sZ, sX, sI, sY
from pyquil.pyqvm import PyQVM
from pyquil.quil import Program
from pyquil.quilatom import MemoryReference
from pyquil.quilbase import Declare
from pyquil.simulation._reference import ReferenceWavefunctionSimulator

QFT_8_INSTRUCTIONS = [
    H(7),
    CPHASE(1.5707963267948966, 6, 7),
    H(6),
    CPHASE(0.7853981633974483, 5, 7),
    CPHASE(1.5707963267948966, 5, 6),
    H(5),
    CPHASE(0.39269908169872414, 4, 7),
    CPHASE(0.7853981633974483, 4, 6),
    CPHASE(1.5707963267948966, 4, 5),
    H(4),
    CPHASE(0.19634954084936207, 3, 7),
    CPHASE(0.39269908169872414, 3, 6),
    CPHASE(0.7853981633974483, 3, 5),
    CPHASE(1.5707963267948966, 3, 4),
    H(3),
    CPHASE(0.09817477042468103, 2, 7),
    CPHASE(0.19634954084936207, 2, 6),
Example #25
0
x = np.fft.ifft(y, norm='ortho')
print(x)

#==============================================================================
# QFT
#==============================================================================
import math
from pyquil import Program
from pyquil.gates import SWAP, H, CPHASE
from pyquil.api import WavefunctionSimulator

# Initilize program
prog = Program()

# Prepare state
prog = prog.inst(H(0),H(1))
print('Amplitudes a of input state psi: {}'.format(WavefunctionSimulator().wavefunction(prog).amplitudes))

# Perfrom QFT
prog += SWAP(0, 1)
prog += H(1)
prog += CPHASE(math.pi / 2, 0, 1)
prog += H(0)

print('Amplitudes b of output state phi: {}'.format(WavefunctionSimulator().wavefunction(prog).amplitudes))





Example #26
0
def QFT(q0, q1, q2):
    for i in range(0, len(states)):
        states[i] = states[i] + Program().inst(
            H(q2), CPHASE(pi / 2.0, q1, q2), H(q1), CPHASE(pi / 4.0, q0, q2),
            CPHASE(pi / 2.0, q0, q1), H(q0), SWAP(q0, q2))
for i in range(1, n):
    if sumando_1[i - 1] == "1":
        p += X(a[n - (i + 1)])
for i in range(1, n):
    if sumando_2[i - 1] == "1":
        p += X(b[n - (i + 1)])

# Take the QFT.
# Iterate through the target.
for i in range(n, 0, -1):
    # Apply the Hadamard gate to the target.
    p += H(b[i - 1])

    # Iterate through the control.
    for j in range(i - 1, 0, -1):
        p += CPHASE(2 * pi / 2**(i - j + 1), b[j - 1], b[i - 1])

# Compute controlled-phases.
# Iterate through the targets.
for i in range(n, 0, -1):
    # Iterate through the controls.
    for j in range(i, 0, -1):
        p += CPHASE(2 * pi / 2**(i - j + 1), a[j - 1], b[i - 1])

# Take the inverse QFT.
# Iterate through the target.
for i in range(1, n + 1):
    # Iterate through the control.
    for j in range(1, i):
        # The inverse Fourier transform just uses a negative phase.
        p += CPHASE(-2 * pi / 2**(i - j + 1), b[j - 1], b[i - 1])