def test_to_latex(): """A test to give full coverage of latex_generation and latex_config.""" qubits = range(3) p = Program() p.inst(X(qubits[0]), Y(qubits[0]), CZ(qubits[0], qubits[2]), SWAP(qubits[0], qubits[1]), MEASURE(qubits[0], None), CNOT(qubits[2], qubits[0])) _ = to_latex(p) # Modify settings to access non-standard control paths. settings = get_default_settings() settings['gates']['AllocateQubitGate']['draw_id'] = True settings['gate_shadow'] = None _ = to_latex(p, settings) settings['control']['shadow'] = True _ = to_latex(p, settings)
def phase_estimation(ancillary_start, ancillary_num, time, atomic_distance, state, trails=5, trotter_order=2): """ Measures the phase by using the phase estimation algorithm (PEA) :param ancillary_start: first ancillary qubit :param ancillary_num: how many ancillaries to use corresponds to precision in PEA algorithm :param time: t in exp(-iHt), where H is the Hamiltonian :param atomic_distance: the distance between to H atoms in H2 molecule :param state: ground state (0) or some excited state (1, 2, 3) :param trails: how many measurement to make in order to estimate the most frequent result :return: the phase from exp(-iHt) |psi> = exp(-i2pi phase) |psi> (Schrodinger) """ # initialization of the state init_qubit = Program() if state == 0: init_qubit.inst(X(0)).inst(X(1)) elif state == 1: init_qubit.inst(X(0)).inst(X(2)) elif state == 2: init_qubit.inst(X(0)).inst(X(3)) elif state == 3: init_qubit.inst(X(2)).inst(X(3)) else: print( "Wrong input of state. State should be 0, 1, 2, 3. Your input is " + str(state)) raise ValueError prog = init_qubit + pea_program(ancillary_start, ancillary_num, time, atomic_distance, trotter_order) ro = prog.declare('ro', memory_type='BIT', memory_size=ancillary_num) # measurement of ancillary qubits for cindex, qindex in enumerate( range(ancillary_start, ancillary_start + ancillary_num)): prog += MEASURE(qindex, ro[cindex]) qvm = QVMConnection() cregister = list(range(0, ancillary_num)) m_reg = qvm.run(prog, cregister, trails) # taking most frequent result from the phase elements. The number of the elements are defined by the trails phase, major_index = majority_and_index( [bitstring_to_value(bitst) for bitst in m_reg]) print(str(phase) + " = " + str(m_reg[major_index])) return phase
def test_halt(): prog = Program(Declare('ro', 'BIT'), X(0), MEASURE(0, MemoryReference("ro", 0))) prog.inst(HALT) prog.inst(X(0), MEASURE(0, MemoryReference("ro", 0))) qam = PyQVM(n_qubits=1, quantum_simulator_type=ReferenceWavefunctionSimulator) qam.execute(prog) # HALT should stop execution; measure should give 1 assert qam.ram['ro'][0] == 1 prog = Program(Declare('ro', 'BIT'), X(0)).inst(X(0)).inst(MEASURE(0, MemoryReference("ro", 0))) qam = PyQVM(n_qubits=1, quantum_simulator_type=ReferenceWavefunctionSimulator) qam.execute(prog) assert qam.ram['ro'][0] == 0
def inv_qft_core(qubits): """ Generates a quil programm that performs inverse quantum fourier transform on given qubits without swaping qubits at the end. :param qubits: A list of qubit indexes. :return: A Quil program to compute the invese QFT of the given qubits without swapping. """ qft_quil = Program.inst(qft_core(qubits, coef=-1)) inv_qft_quil = Program() while (len(qft_quil) > 0): inst = qft_quil.pop() inv_qft_quil.inst(inst) return inv_qft_quil
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
class Universe(object): state = None cities = None map = None program = None def __init__(self, cities, map, program): self.state = Program() self.state.inst(X(0), X(5), X(10), X(15)) self.cities = cities self.map = map self.program = program # i u v def h_all(self, side, n): result = 0 if side == 0: # even for n1 in range(0, n, 2): for n2 in range(0, n): for n3 in range(0, n): result += self.h(n1, n2, n3) elif side == 1: # odd for n1 in range(0, n): if n1 % 2 == 1: for n2 in range(0, n): for n3 in range(0, n): result += self.h(n1, n2, n3) else: raise ValueError("Side must be zero (even) or one (odd)") return result def h(self, i, u, v): return self.map.get_distance(u, v) * self.z(u, i) * self.z(v * i + 1) def h2(self, partition, i_list): result = 0 for uv in partition: for i in i_list: result += self.h(uv[0], uv[1], i) return result def z(self, city_index, row_index): self.program.inst(Z(city_index * 4 + row_index))
def test_binary_classicals(): p = Program() p.inst(AND(Addr(0), Addr(1)), OR(Addr(1), Addr(0)), MOVE(Addr(0), Addr(1)), CONVERT(Addr(0), Addr(1)), IOR(Addr(0), Addr(1)), XOR(Addr(0), Addr(1)), ADD(Addr(0), Addr(1)), SUB(Addr(0), Addr(1)), MUL(Addr(0), Addr(1)), DIV(Addr(0), Addr(1)), EXCHANGE(Addr(0), Addr(1))) assert p.out() == 'AND ro[0] ro[1]\n' \ 'IOR ro[0] ro[1]\n' \ 'MOVE ro[0] ro[1]\n' \ 'CONVERT ro[0] ro[1]\n' \ 'IOR ro[0] ro[1]\n' \ 'XOR ro[0] ro[1]\n' \ 'ADD ro[0] ro[1]\n' \ 'SUB ro[0] ro[1]\n'\ 'MUL ro[0] ro[1]\n' \ 'DIV ro[0] ro[1]\n' \ 'EXCHANGE ro[0] ro[1]\n'
def test_to_latex(): """A test to give full coverage of latex_generation.""" p = Program() p.inst(X(0), RX(1.0, 5), Y(0), CZ(0, 2), SWAP(0, 1), MEASURE(0, None), CNOT(2, 0), X(0).controlled(1), Y(0).dagger()) _ = to_latex(p) # Modify settings to access non-standard control paths. settings = DiagramSettings(impute_missing_qubits=True) _ = to_latex(p, settings) settings = DiagramSettings(abbreviate_controlled_rotations=True) _ = to_latex(p, settings) settings = DiagramSettings(label_qubit_lines=False) _ = to_latex(p, settings)
def test_multiqubit_gate(): # A multi-qubit defgate example x_gate_matrix = np.array(([0.0, 1.0], [1.0, 0.0])) x_sqrt_x = np.kron(sqrtm(x_gate_matrix), x_gate_matrix) p = Program().defgate("X-SQRT-X", x_sqrt_x) # Then we can use the new gate p.inst(("X-SQRT-X", 0, 1)) assert p.out() == 'DEFGATE X-SQRT-X:\n 0.0+0.0i, ' \ '0.49999999999999989+0.49999999999999989i, ' \ '0.0+0.0i, 0.49999999999999989-0.49999999999999989i\n ' \ '0.49999999999999989+0.49999999999999989i, 0.0+0.0i, ' \ '0.49999999999999989-0.49999999999999989i, 0.0+0.0i\n 0.0+0.0i,' \ ' 0.49999999999999989-0.49999999999999989i, 0.0+0.0i, ' \ '0.49999999999999989+0.49999999999999989i\n ' \ '0.49999999999999989-0.49999999999999989i, ' \ '0.0+0.0i, 0.49999999999999989+0.49999999999999989i, 0.0+0.0i\n\nX-SQRT-X 0 1\n'
def getMatFromProgram(n_qubits, p): """ Return matrix (in standard ordering) which represents the effect of p on a wavefunction. Note that you must have a quil compiler and a quantum virtual machine running on your computer in order for this function to execute successfully. Parameters ---------- n_qubits: integer Number of qubits in the register which the Program `p` acts on. p: pyQuil Program Program for which you are trying to find a matrix representation Returns ------- A: ndarray, dtype=np.complex_ Complex unitary matrix representing the effect of Program `p` on a state. """ A = np.zeros((2**n_qubits, 2**n_qubits), dtype=np.complex_) # For each basis qubit, see where p sends it for i in range(2**n_qubits): bit_string = [int(j) for j in np.binary_repr(i, width=n_qubits)] bit_string.reverse() # Prep state so it looks like current bit string state_prep_p = Program() for j in range(n_qubits): if bit_string[j] == 1: state_prep_p.inst(Program(X(j))) else: state_prep_p.inst(Program(I(j))) # See what p does to state, record result in matrix A wfn = WavefunctionSimulator().wavefunction(state_prep_p.inst(p)) A[:, i] = wfn.amplitudes[0:2**n_qubits] return A
def test_get_qubits(): pq = Program(X(0), CNOT(0, 4), MEASURE(5, 5)) assert pq.get_qubits() == {0, 4, 5} q = [QubitPlaceholder() for _ in range(6)] pq = Program(X(q[0]), CNOT(q[0], q[4]), MEASURE(q[5], 5)) qq = pq.alloc() pq.inst(Y(q[2]), X(qq)) assert address_qubits(pq).get_qubits() == {0, 1, 2, 3, 4} qubit_index = 1 p = Program(("H", qubit_index)) assert p.get_qubits() == {qubit_index} q1 = p.alloc() q2 = p.alloc() p.inst(("CNOT", q1, q2)) with pytest.raises(ValueError) as e: _ = address_qubits(p).get_qubits() assert e.match('Your program mixes instantiated qubits with placeholders')
def single_q_tomo_fixture(): qubits = [0] qc = get_test_qc(n_qubits=len(qubits)) # Generate random unitary u_rand = haar_rand_unitary(2 ** 1, rs=np.random.RandomState(52)) state_prep = Program().defgate("RandUnitary", u_rand) state_prep.inst([("RandUnitary", qubits[0])]) # True state wfn = NumpyWavefunctionSimulator(n_qubits=1) psi = wfn.do_gate_matrix(u_rand, qubits=[0]).wf.reshape(-1) rho_true = np.outer(psi, psi.T.conj()) # Get data from QVM tomo_expt = generate_state_tomography_experiment(state_prep, qubits) results = list(measure_observables(qc=qc, tomo_experiment=tomo_expt, n_shots=4000)) return results, rho_true
def n_qubits (number) : ''' takes as argument the number of qubits to apply Hadamard Gates to and measure. Outputs a concatenated string of measurements.''' q = Program() [q.inst(H(entry)) for entry in range(number)] [q.measure(entry, entry) for entry in range(number)] wavefunction3 = qvm.wavefunction(q, classical_addresses=range(number)) classical_mem3 = wavefunction3.classical_memory #print (classical_mem3) return("".join([str(x) for x in classical_mem3]))
def test_memory_reference_unpacking(): p = Program() p.inst(AND("ro", ("ro", 1)), MOVE("ro", ("ro", 1)), CONVERT("ro", ("ro", 1)), IOR("ro", ("ro", 1)), XOR("ro", ("ro", 1)), ADD("ro", ("ro", 1)), SUB("ro", ("ro", 1)), MUL("ro", ("ro", 1)), DIV("ro", ("ro", 1)), EXCHANGE("ro", ("ro", 1))) assert p.out() == 'AND ro[0] ro[1]\n' \ 'MOVE ro[0] ro[1]\n' \ 'CONVERT ro[0] ro[1]\n' \ 'IOR ro[0] ro[1]\n' \ 'XOR ro[0] ro[1]\n' \ 'ADD ro[0] ro[1]\n' \ 'SUB ro[0] ro[1]\n'\ 'MUL ro[0] ro[1]\n' \ 'DIV ro[0] ro[1]\n' \ 'EXCHANGE ro[0] ro[1]\n'
def test_kraus(): pq = Program(X(0)) pq.define_noisy_gate("X", (0, ), [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 0.0], [0.0, 0.0]]]) pq.inst(X(1)) pq.define_noisy_gate("X", (1, ), [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 0.0], [0.0, 0.0]]]) ret = pq.out() assert (ret == """X 0 PRAGMA ADD-KRAUS X 0 "(0.0 1.0 1.0 0.0)" PRAGMA ADD-KRAUS X 0 "(0.0 0.0 0.0 0.0)" X 1 PRAGMA ADD-KRAUS X 1 "(0.0 1.0 1.0 0.0)" PRAGMA ADD-KRAUS X 1 "(0.0 0.0 0.0 0.0)" """) # test error due to bad normalization with pytest.raises(ValueError): pq.define_noisy_gate( "X", (0, ), [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 1.0], [1.0, 0.0]]]) # test error due to bad shape of kraus op with pytest.raises(ValueError): pq.define_noisy_gate( "X", (0, ), [[[0.0, 1.0, 0.0], [1.0, 0.0, 0.0]], [[0.0, 1.0], [1.0, 0.0]]]) pq1 = Program(X(0)) pq1.define_noisy_gate("X", (0, ), [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 0.0], [0.0, 0.0]]]) pq2 = Program(X(1)) pq2.define_noisy_gate("X", (1, ), [[[0.0, 1.0], [1.0, 0.0]], [[0.0, 0.0], [0.0, 0.0]]]) assert pq1 + pq2 == pq pq_nn = Program(X(0)) pq_nn.no_noise() pq_nn.inst(X(1)) assert (pq_nn.out() == """X 0 PRAGMA NO-NOISE X 1 """)
def prep_qubits(qubits: list, n: int): """ Generate a quil program which prepares given qubits in a state representing number n. :param n: the number to write :param qubits: qubit indexes to write the number n :return: circuit to write number n on given qubits. """ p = Program() for qubit in qubits: if n % 2 == 1: p.inst(X(qubit)) else: p.inst(I(qubit)) n = int(n/2) return p
def generate_rb_sequence(self, depth, qubits, gateset): """ Construct a randomized benchmarking experiment on the given qubits, decomposing into gateset. The JSON payload that is parsed is a list of lists of indices, or Nones. In the former case, they are the index of the gate in the gateset. :param int depth: The number of Clifford gates to include in the randomized benchmarking experiement. :param int qubits: The number of qubits to generate a randomized benchmarking sequence for. :param list gateset: A list of pyquil gates to decompose the Clifford elements into. """ payload = self._rb_sequence_payload(depth, qubits, gateset) response = post_json(self.session, self.sync_endpoint + "/rb", payload).json() programs = [] for clifford in response: clifford_program = Program() for index in clifford: clifford_program.inst(gateset[index]) programs.append(clifford_program) return programs
def basic_compile(program): new_prog = Program() new_prog.num_shots = program.num_shots new_prog.inst(program.defined_gates) for inst in program: if isinstance(inst, Gate): if inst.name in ['RZ', 'CZ', 'I']: new_prog += inst elif inst.name == 'RX' and is_magic_angle(inst.params[0]): new_prog += inst elif inst.name == 'RY': new_prog += _RY(inst.params[0], inst.qubits[0]) elif inst.name == 'CNOT': new_prog += _CNOT(*inst.qubits) elif inst.name == 'CCNOT': new_prog += _CCNOT(*inst.qubits) elif inst.name == 'SWAP': new_prog += _SWAP(*inst.qubits) elif inst.name == 'T': new_prog += _T(inst.qubits[0]) elif inst.name == "H": new_prog += _H(inst.qubits[0]) elif inst.name == "X": new_prog += _X(inst.qubits[0]) elif inst.name in [gate.name for gate in new_prog.defined_gates]: new_prog += inst else: raise ValueError(f"Unknown gate instruction {inst}") else: new_prog += inst new_prog.native_quil_metadata = { 'final_rewiring': None, 'gate_depth': None, 'gate_volume': None, 'multiqubit_gate_depth': None, 'program_duration': None, 'program_fidelity': None, 'topological_swaps': 0, } return new_prog
def level2(): circuit = Program() initz = Program() circuit.inst(H(1)) circuit.inst(CZ(0,1)) circuit.inst(H(1)) circuit.inst(MEASURE(0,0)) circuit.inst(MEASURE(1,1)) initz.inst(X(0)) qubits = 2 depth = 3 introduction = "The state is initialised as |1,0>. Apply the following gates to construct a CNOT gate:" conclusion = "Applying two H gates on the target qubit, which are sandwiching the CZ gate, results in cancelling of the H gates when the control is zero and a NOT gate when the control is 1." hint = "I like sandwiches" level2 = level(qubits,depth,circuit,initz,introduction,conclusion,hint)
def runAlg(cf): qvm = api.QVMConnection() p = Program() p.defgate('cF', cf) p.inst( # Prepare 0 as a superposition |0> + |1> # Prepare 1 as the Fourier Transform of |0> - |1> H(0), X(1), H(1), # one application of cF gate ('cF', 0, 1), # project and measure H(0), MEASURE(0, 0)) print(p) result = qvm.run(p, [0]) print(result) parseResult(result)
def local_sic_prep(label, qubit): """ :param label: :param qubit: :return: """ theta = 2*np.arccos(1/np.sqrt(3)) zx_plane_rotation = Program(RX(-pi/2, qubit)).inst(RZ(theta - pi, qubit)).inst(RX(-pi/2, qubit)) if label == 'SIC0': gate = I(qubit) elif label == 'SIC1': gate = zx_plane_rotation elif label == 'SIC2': gate = zx_plane_rotation.inst(RZ(-2*pi/3, qubit)) elif label == 'SIC3': gate = zx_plane_rotation.inst(RZ(2*pi/3, qubit)) else: raise ValueError('Unknown gate operation') return gate
def _remove_reset_from_program(program: Program) -> Program: """ Trim the RESET from a program because in measure_observables it is re-added. :param program: Program to remove RESET(s) from. :return: Trimmed Program. """ definitions = [gate for gate in program.defined_gates] p = Program(*[inst for inst in program if not isinstance(inst, Reset)]) for definition in definitions: if isinstance(definition, DefPermutationGate): p.inst( DefPermutationGate(definition.name, list(definition.permutation))) else: p.defgate(definition.name, definition.matrix, definition.parameters) return p
def basis_state_preps(*qubits): """ Generate a sequence of programs that prepares the measurement basis states of some set of qubits in the order such that the qubit with highest index is iterated over the most quickly: E.g., for ``qubits=(0, 1)``, it returns the circuits:: I_0 I_1 I_0 X_1 X_0 I_1 X_0 X_1 :param list qubits: Each qubit to include in the basis state preparation. :return: Yields programs for each basis state preparation. :rtype: Program """ for prep in cartesian_product([I, X], repeat=len(qubits)): basis_prep = Program() for gate, qubit in zip(prep, qubits): basis_prep.inst(gate(qubit)) yield basis_prep
def qft_core(qubits, coef=1): """ Generates a quil programm that performs quantum fourier transform on given qubits without swaping qubits at the end. :param qubits: A list of qubit indexes. :param coeff: A modifier for the angle used in rotations (-1 for inverse QFT, 1 for QFT) :return: A Quil program to compute the QFT of the given qubits without swapping. """ p = Program() # Iterate over qubits starting from the most significant for i, qubit in enumerate(qubits[::-1]): p.inst(H(qubit)) # Add controlled rotations R_i for i in 1 .. n-1 # using all qubits right to current p.inst(crotate(qubit, qubits[:-i - 1], coef=coef, start_index=1)) return p
def state_tomography_programs(state_prep, qubits=None, rotation_generator=tomography.default_rotations): """ Yield tomographic sequences that prepare a state with Quil program `state_prep` and then append tomographic rotations on the specified `qubits`. If `qubits is None`, it assumes all qubits in the program should be tomographically rotated. :param Program state_prep: The program to prepare the state to be tomographed. :param list|NoneType qubits: A list of Qubits or Numbers, to perform the tomography on. If `None`, performs it on all in state_prep. :param generator rotation_generator: A generator that yields tomography rotations to perform. :return: Program for state tomography. :rtype: Program """ if qubits is None: qubits = state_prep.get_qubits() for tomography_program in rotation_generator(*qubits): state_tomography_program = Program() state_tomography_program.inst(state_prep) state_tomography_program.inst(tomography_program) yield state_tomography_program
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)" """)
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")
def get_rotation_program(pauli_term): """ Generate a rotation program so that the pauli term is diagonal :param PauliTerm pauli_term: The Pauli term used to generate diagonalizing one-qubit rotations. :return: The rotation program. :rtype: Program """ meas_basis_change = Program() for index, gate in pauli_term: if gate == 'X': meas_basis_change.inst(RY(-np.pi / 2, index)) elif gate == 'Y': meas_basis_change.inst(RX(np.pi / 2, index)) elif gate == 'Z': pass else: raise ValueError() return meas_basis_change
def test_qaoa_circuit(qvm): wf_true = [ 0.00167784 + 1.00210180e-05 * 1j, 0.50000000 - 4.99997185e-01 * 1j, 0.50000000 - 4.99997185e-01 * 1j, 0.00167784 + 1.00210180e-05 * 1j ] prog = Program() prog.inst([ RYgate(np.pi / 2)(0), RXgate(np.pi)(0), RYgate(np.pi / 2)(1), RXgate(np.pi)(1), CNOTgate(0, 1), RXgate(-np.pi / 2)(1), RYgate(4.71572463191)(1), RXgate(np.pi / 2)(1), CNOTgate(0, 1), RXgate(-2 * 2.74973750579)(0), RXgate(-2 * 2.74973750579)(1) ]) wf_test, _ = qvm.wavefunction(prog) assert np.allclose(wf_test.amplitudes, wf_true)
def run_and_measure(self, program: Program, trials: int) -> Dict[int, np.ndarray]: """ Run the provided state preparation program and measure all qubits. This will measure all the qubits on this QuantumComputer, not just qubits that are used in the program. The returned data is a dictionary keyed by qubit index because qubits for a given QuantumComputer may be non-contiguous and non-zero-indexed. To turn this dictionary into a 2d numpy array of bitstrings, consider:: bitstrings = qc.run_and_measure(...) bitstring_array = np.vstack(bitstrings[q] for q in sorted(qc.qubits())).T bitstring_array.shape # (trials, len(qc.qubits())) .. note:: In contrast to :py:class:`QVMConnection.run_and_measure`, this method simulates noise correctly for noisy QVMs. However, this method is slower for ``trials > 1``. For faster noise-free simulation, consider :py:class:`WavefunctionSimulator.run_and_measure`. :param program: The state preparation program to run and then measure. :param trials: The number of times to run the program. :return: A dictionary keyed by qubit index where the corresponding value is a 1D array of measured bits. """ program = program.copy() program = _validate_run_and_measure_program(program) ro = program.declare('ro', 'BIT', len(self.qubits())) for i, q in enumerate(self.qubits()): program.inst(MEASURE(q, ro[i])) program.wrap_in_numshots_loop(trials) executable = self.compile(program) bitstring_array = self.run(executable=executable) bitstring_dict = {} for i, q in enumerate(self.qubits()): bitstring_dict[q] = bitstring_array[:, i] return bitstring_dict
from pyquil.quil import Program import pyquil.api as api from pyquil.gates import * qvm = api.QVMConnection() p = Program() p.inst(H(0), CNOT(0, 1), MEASURE(1, [1])) wavefunction = qvm.wavefunction(p) print(wavefunction)
# http://pyquil.readthedocs.io/en/latest/intro.html # Imports for pyQuil (ignore for now) import numpy as np from pyquil.quil import Program from pyquil.api import QVMConnection quantum_simulator = QVMConnection() # pyQuil is based around operations (or gates) so we will start with the most # basic one: the identity operation, called I. I takes one argument, the index # of the qubit that it should be applied to. from pyquil.gates import * # Make a quantum program that allocates one qubit (qubit #0) and does nothing to it p = Program(I(0)) print(p.inst(X(0))) # Quantum states are called wavefunctions for historical reasons. # We can run this basic program on our connection to the simulator. # This call will return the state of our qubits after we run program p. # This api call returns a tuple, but we'll ignore the second value for now. wavefunction = quantum_simulator.wavefunction(p) # wavefunction is a Wavefunction object that stores a quantum state as a list of amplitudes alpha, beta = wavefunction print("Our qubit is in the state alpha={} and beta={}".format(alpha, beta)) print("The probability of measuring the qubit in outcome 0 is {}".format(abs(alpha)**2)) print("The probability of measuring the qubit in outcome 1 is {}".format(abs(beta)**2))
from pyquil.quil import Program from pyquil.gates import H, X, CNOT, MEASURE from pyquil.api import SyncConnection # Reference: https://arxiv.org/pdf/1302.4310.pdf p = Program() p.inst("""DEFGATE CH(%theta): 1, 0, 0, 0 0, 1, 0, 0 0, 0, cos(2*%theta), sin(2*%theta) 0, 0, sin(2*%theta), cos(-2*%theta)""") p.inst(H(3)) p.inst(CNOT(3, 2)) p.inst(CNOT(2, 1)) p.inst("CH(pi/8) 1 0") p.inst("CH(pi/16) 2 0") p.inst(H(1)) p.inst(H(2)) p.inst(X(0)) p.inst(MEASURE(0)) p.inst(MEASURE(1)) p.inst(MEASURE(2)) # run the program on a QVM qvm = SyncConnection() wvf, _ = qvm.wavefunction(p) print(wvf)
def get_compiled_prog_1(): return Program([ RX(pi/2, 0), I(0), RZ(-pi/2, 0), RX(-pi/2, 0), I(0), RZ(pi/2, 0), ]) p = Program() p.inst(X(0)) # want increasing number of I-gates p.define_noisy_gate( "II", [0], append_damping_to_gate(np.eye(2), damping_per_I)) p.inst([I(0) for _ in range(num_I)]) # p.inst(H(0)) p.inst(MEASURE(0, [0])) #print("Expected 1 %s" % qvm.run(p, [0])) thetas = np.linspace(-pi, pi, num=20) t1s = np.logspace(-6, -5, num=3) # print(t1s[0]) prog = get_compiled_prog(pi/2) noisy = add_noise_to_program(prog, T1=t1s[0]).inst([
from pyquil.quil import Program from pyquil.gates import * from pyquil.parameters import Parameter, quil_sin, quil_cos from pyquil.quilbase import DefGate #from pyquil.api import QVMConnection from referenceqvm.api import QVMConnection import numpy as np theta = Parameter('theta') cry = np.array([[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, quil_cos( theta / 2), -1 * quil_sin(theta / 2)], [0.0, 0.0, quil_sin(theta / 2), quil_cos(theta / 2)]]) dg = DefGate('CRY', cry, [theta]) CRY = dg.get_constructor() p = Program() p.inst(dg) p.inst(X(0)) p.inst(X(1)) p.inst(CRY(4.304)(0, 2)) qvm = QVMConnection() wf = qvm.wavefunction(p) print(wf)
from pyquil.quil import Program p = Program() """ Gate definitions """ p.inst("""DEFGATE CRX(%theta): 1, 0, 0, 0 0, 1, 0, 0 0, 0, cos(%theta/2), -i*sin(%theta/2) 0, 0, -i*sin(%theta/2), cos(%theta/2)""") p.inst("""DEFGATE CRY(%theta): 1, 0, 0, 0 0, 1, 0, 0 0, 0, cos(%theta/2), -sin(%theta/2) 0, 0, sin(%theta/2), cos(%theta/2)""") p.inst("""DEFGATE CRZ(%theta): 1, 0, 0, 0 0, 1, 0, 0 0, 0, e^(-i*%theta/2), 0 0, 0, 0, e^(i*%theta/2)""")
from pyquil.quil import Program #from pyquil.api import QPUConnection from pyquil.api import QVMConnection from pyquil.gates import * qvm = QVMConnection() ins = Program() ins.inst(H(1), CNOT(1, 2)) # Creating B00 ins.inst(CNOT(0, 1), H(0)) ins.measure(0, 0).measure(1, 1).if_then(1, X(2)).if_then(0, Z(2)) wvf = qvm.wavefunction(ins, [0, 1]) #print( wvf) ins = Program( H(0), H(1), CNOT(1, 2), CNOT(0, 1), H(0), ) ins.measure(0, 0).measure(1, 1).if_then(1, X(2)).if_then(1, Z(2)) wvf = qvm.wavefunction(ins) print(ins) result = qvm.run_and_measure(ins, [2]) print(result)