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
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
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'
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)
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'
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
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'
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
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
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")
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
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")
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)]
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
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
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'
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
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)]
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)
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
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
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),
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))
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])