Python源码示例:pyquil.quil.Program()
示例1
def _defgate(self, program, gate_name, gate_matrix):
"""Defines a gate named gate_name with matrix gate_matrix in program. In addition, updates
self.defined_gates to track what has been defined.
:param Program program: Pyquil Program to add the defgate and gate to.
:param str gate_name: The name of the gate to add to program.
:param numpy.ndarray gate_matrix: The array corresponding to the gate to define.
:return: the modified Program.
:retype: Program
"""
new_program = pq.Program()
new_program += program
if gate_name not in self.defined_gates:
new_program.defgate(gate_name, gate_matrix)
self.defined_gates.add(gate_name)
return new_program
示例2
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(Pragma("PRESERVE_BLOCK"))
state_tomography_program.inst(state_prep)
state_tomography_program.inst(tomography_program)
state_tomography_program.inst(Pragma("END_PRESERVE_BLOCK"))
yield state_tomography_program
示例3
def do_state_tomography(preparation_program, nsamples, cxn, qubits=None, use_run=False):
"""
Method to perform both a QPU and QVM state tomography, and use the latter as
as reference to calculate the fidelity of the former.
:param Program preparation_program: Program to execute.
:param int nsamples: Number of samples to take for the program.
:param QVMConnection|QPUConnection cxn: Connection on which to run the program.
:param list qubits: List of qubits for the program.
to use in the tomography analysis.
:param bool use_run: If ``True``, use append measurements on all qubits and use ``cxn.run``
instead of ``cxn.run_and_measure``.
:return: The state tomogram.
:rtype: StateTomography
"""
return tomography._do_tomography(preparation_program, nsamples, cxn, qubits,
tomography.MAX_QUBITS_STATE_TOMO,
StateTomography, state_tomography_programs,
DEFAULT_STATE_TOMO_SETTINGS, use_run=use_run)
示例4
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(Pragma("PRESERVE_BLOCK"))
for gate, qubit in zip(prep, qubits):
basis_prep.inst(gate(qubit))
basis_prep.inst(Pragma("END_PRESERVE_BLOCK"))
yield basis_prep
示例5
def density(self, pyquil_program):
"""
Run program and compute the density matrix
Loads and checks program if all gates are within the stabilizer set.
Then executes program and returns the final density matrix for the
stabilizer
:param Program pyquil_program: a pyquil Program containing only
CNOT-H-S-MEASUREMENT operations
:return:
"""
self.load_program(pyquil_program)
self.tableau = self._n_qubit_tableau(self.num_qubits)
self.kernel()
stabilizers = binary_stabilizer_to_pauli_stabilizer(self.stabilizer_tableau())
pauli_ops = reduce(lambda x, y: x * y, [0.5 * (sI(0) + b) for b in stabilizers])
return tensor_up(pauli_ops, self.num_qubits)
示例6
def get_compiled_prog(theta):
return Program([
RZgate(-pi/2, 0),
RXgate(-pi/2, 0),
RZgate(-pi/2, 1),
RXgate( pi/2, 1),
CZgate(1, 0),
RZgate(-pi/2, 1),
RXgate(-pi/2, 1),
RZgate(theta, 1),
RXgate( pi/2, 1),
CZgate(1, 0),
RXgate( pi/2, 0),
RZgate( pi/2, 0),
RZgate(-pi/2, 1),
RXgate( pi/2, 1),
RZgate(-pi/2, 1),
])
示例7
def test_exp_circuit(qvm):
true_wf = np.array([0.54030231-0.84147098j,
0.00000000+0.j,
0.00000000+0.j,
0.00000000+0.j,
0.00000000+0.j,
0.00000000+0.j,
0.00000000+0.j,
0.00000000+0.j])
create2kill1 = PauliTerm("X", 1, -0.25)*PauliTerm("Y", 2)
create2kill1 += PauliTerm("Y", 1, 0.25)*PauliTerm("Y", 2)
create2kill1 += PauliTerm("Y", 1, 0.25)*PauliTerm("X", 2)
create2kill1 += PauliTerm("X", 1, 0.25)*PauliTerm("X", 2)
create2kill1 += PauliTerm("I", 0, 1.0)
prog = Program()
for term in create2kill1.terms:
single_exp_prog = exponentiate(term)
prog += single_exp_prog
wf, _ = qvm.wavefunction(prog)
wf = np.reshape(wf.amplitudes, -1)
assert np.allclose(wf.dot(np.conj(wf).T), true_wf.dot(np.conj(true_wf).T))
示例8
def test_errors(qvm):
# NOP unsupported
prog = Program(NOP)
with pytest.raises(TypeError):
qvm.wavefunction(prog)
with pytest.raises(TypeError):
qvm.run(prog)
with pytest.raises(TypeError):
qvm.run_and_measure(prog)
# WAIT unsupported
prog = Program(WAIT)
with pytest.raises(TypeError):
qvm.wavefunction(prog)
with pytest.raises(TypeError):
qvm.run(prog)
with pytest.raises(TypeError):
qvm.run_and_measure(prog)
示例9
def tests_against_cloud(qvm):
# simple program
p = Program(H(0))
cloud_results = [[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
local_results = qvm.run(p, classical_addresses=[0], trials=10)
assert len(cloud_results) == len(local_results)
cloud_wf = dc.HADAMARD_WF
local_wf, _ = qvm.wavefunction(p)
assert np.allclose(cloud_wf, local_wf.amplitudes)
# complex program
p = Program(dc.QFT_8_INSTRUCTIONS)
cloud_wf = dc.QFT_8_WF_PROBS
local_wf, _ = qvm.wavefunction(p)
assert np.allclose(cloud_wf, local_wf.amplitudes)
示例10
def test_random_gates(qvm_unitary):
p = Program().inst([H(0), H(1), H(0)])
test_unitary = qvm_unitary.unitary(p)
actual_unitary = np.kron(gate_matrix['H'], np.eye(2 ** 1))
assert np.allclose(test_unitary, actual_unitary)
p = Program().inst([H(0), X(1), Y(2), Z(3)])
test_unitary = qvm_unitary.unitary(p)
actual_unitary = np.kron(gate_matrix['Z'],
np.kron(gate_matrix['Y'],
np.kron(gate_matrix['X'],
gate_matrix['H'])))
assert np.allclose(test_unitary, actual_unitary)
p = Program().inst([X(2), CNOT(2, 1), CNOT(1, 0)])
test_unitary = qvm_unitary.unitary(p)
# gates are multiplied in 'backwards' order
actual_unitary = np.kron(np.eye(2 ** 1), gate_matrix['CNOT']).dot(
np.kron(gate_matrix['CNOT'], np.eye(2 ** 1))).dot(
np.kron(gate_matrix['X'], np.eye(2 ** 2)))
assert np.allclose(test_unitary, actual_unitary)
示例11
def test_qaoa_unitary(qvm_unitary):
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([RY(np.pi/2, 0), RX(np.pi, 0),
RY(np.pi/2, 1), RX(np.pi, 1),
CNOT(0, 1), RX(-np.pi/2, 1), RY(4.71572463191, 1),
RX(np.pi/2, 1), CNOT(0, 1),
RX(-2*2.74973750579, 0), RX(-2*2.74973750579, 1)])
test_unitary = qvm_unitary.unitary(prog)
wf_test = np.zeros(4)
wf_test[0] = 1.0
wf_test = test_unitary.dot(wf_test)
assert np.allclose(wf_test, wf_true)
示例12
def test_tensor_gates_single_qubit():
prog = Program().inst([Hgate(0)])
test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 1).toarray()
true_unitary = gate_matrix['H']
assert np.allclose(test_unitary, true_unitary)
prog = Program().inst([Hgate(0)])
test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 5).toarray()
true_unitary = np.kron(np.eye(2**4), gate_matrix['H'])
assert np.allclose(test_unitary, true_unitary)
prog = Program().inst([RXgate(0.2, 3)])
test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 5).toarray()
true_unitary = np.kron(np.eye(2**1), np.kron(gate_matrix['RX'](0.2), np.eye(2**3)))
assert np.allclose(test_unitary, true_unitary)
prog = Program().inst([RXgate(0.5, 4)])
test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 5).toarray()
true_unitary = np.kron(np.eye(2**0), np.kron(gate_matrix['RX'](0.5), np.eye(2**4)))
assert np.allclose(test_unitary, true_unitary)
示例13
def test_simulation_phase():
"""
Test if the Phase gate is applied correctly to the tableau
S|0> = |0>
S|+> = |R>
"""
prog = Program().inst(S(0))
qvmstab = QVM_Stabilizer(num_qubits=1)
qvmstab._apply_phase(prog.instructions[0])
true_stab = np.array([[1, 1, 0],
[0, 1, 0]])
assert np.allclose(true_stab, qvmstab.tableau)
prog = Program().inst([H(0), S(0)])
qvmstab = QVM_Stabilizer(num_qubits=1)
qvmstab._apply_hadamard(prog.instructions[0])
qvmstab._apply_phase(prog.instructions[1])
true_stab = np.array([[0, 1, 0],
[1, 1, 0]])
assert np.allclose(true_stab, qvmstab.tableau)
示例14
def run(self, pyquil_program, classical_addresses=None, trials=1):
"""
Run a pyQuil program multiple times, accumulating the values deposited
in a list of classical addresses.
This uses numpy's inverse sampling method to calculate bit string
outcomes
:param Program pyquil_program: A pyQuil program.
:param list classical_addresses: A list of classical addresses.
This is ignored but kept to have
similar input as Forest QVM.
:param int trials: Number of shots to collect.
:return: A list of lists of bits. Each sublist corresponds to the
values in `classical_addresses`.
:rtype: list
"""
results = []
for trial in range(trials):
_ = self.density(pyquil_program)
results.append(self.classical_memory[classical_addresses])
return list(results)
示例15
def run(self, pyquil_program, classical_addresses=None, trials=1):
"""
Run a pyQuil program multiple times, accumulating the values deposited
in a list of classical addresses.
:param Program pyquil_program: A pyQuil program.
:param list classical_addresses: A list of classical addresses.
:param int trials: Number of shots to collect.
:return: A list of lists of bits. Each sublist corresponds to the
values in `classical_addresses`.
:rtype: list
"""
results = []
for trial in range(trials):
_, classical_vals = self.wavefunction(pyquil_program,
classical_addresses=classical_addresses)
results.append(classical_vals)
return results
示例16
def apply(self, operations, **kwargs):
"""Run the QVM"""
# pylint: disable=attribute-defined-outside-init
if self.parametric_compilation and "pyqvm" not in self.qc.name:
self.apply_parametric_program(operations, **kwargs)
else:
super().apply(operations, **kwargs)
prag = Program(Pragma("INITIAL_REWIRING", ['"PARTIAL"']))
if self.active_reset:
prag += RESET()
self.prog = prag + self.prog
qubits = sorted(self.wiring.values())
ro = self.prog.declare("ro", "BIT", len(qubits))
for i, q in enumerate(qubits):
self.prog.inst(MEASURE(q, ro[i]))
self.prog.wrap_in_numshots_loop(self.shots)
示例17
def build(self):
"""Builds this controlled gate.
:return: The controlled gate, defined by this object.
:rtype: Program
"""
self.defined_gates = set(STANDARD_GATE_NAMES)
prog = self._recursive_builder(self.operation,
self.gate_name,
self.control_qubits,
self.target_qubit)
return prog
示例18
def sample_bad_readout(program, num_samples, assignment_probs, cxn):
"""
Generate `n` samples of measuring all outcomes of a Quil `program`
assuming the assignment probabilities `assignment_probs` by simulating the
wave function on a qvm QVMConnection `cxn`
:param pyquil.quil.Program program: The program.
:param int num_samples: The number of samples
:param numpy.ndarray assignment_probs: A matrix of assignment probabilities
:param QVMConnection cxn: the QVM connection.
:return: The resulting sampled outcomes from assignment_probs applied to cxn, one dimensional.
:rtype: numpy.ndarray
"""
wf = cxn.wavefunction(program)
return sample_outcomes(assignment_probs.dot(abs(wf.amplitudes.ravel())**2), num_samples)
示例19
def process_tomography_programs(process, qubits=None,
pre_rotation_generator=tomography.default_rotations,
post_rotation_generator=tomography.default_rotations):
"""
Generator that yields tomographic sequences that wrap a process encoded by a QUIL program `proc`
in tomographic rotations on the specified `qubits`.
If `qubits is None`, it assumes all qubits in the program should be
tomographically rotated.
:param Program process: A Quil program
:param list|NoneType qubits: The specific qubits for which to generate the tomographic sequences
:param pre_rotation_generator: A generator that yields tomographic pre-rotations to perform.
:param post_rotation_generator: A generator that yields tomographic post-rotations to perform.
:return: Program for process tomography.
:rtype: Program
"""
if qubits is None:
qubits = process.get_qubits()
for tomographic_pre_rotation in pre_rotation_generator(*qubits):
for tomography_post_rotation in post_rotation_generator(*qubits):
process_tomography_program = Program(Pragma("PRESERVE_BLOCK"))
process_tomography_program.inst(tomographic_pre_rotation)
process_tomography_program.inst(process)
process_tomography_program.inst(tomography_post_rotation)
process_tomography_program.inst(Pragma("END_PRESERVE_BLOCK"))
yield process_tomography_program
示例20
def test_1_qubit_control():
prog = Program()
qubit = Qubit(0)
control_qubit = Qubit(1)
prog += (ControlledProgramBuilder()
.with_controls([control_qubit])
.with_target(qubit)
.with_operation(SIGMA_Z)
.with_gate_name(SIGMA_Z_NAME).build())
# This should be one "CZ" instruction, from control_qubit to qubit.
assert len(prog) == 1
instruction = prog.instructions[0]
assert instruction.name == (ControlledProgramBuilder()
.format_gate_name("C", SIGMA_Z_NAME))
assert instruction.qubits == [control_qubit, qubit]
示例21
def test_2_qubit_control():
"""Test that ControlledProgramBuilder builds the program correctly all the way through."""
prog = Program()
qubit = Qubit(0)
control_qubit_one = Qubit(1)
control_qubit_two = Qubit(2)
prog += (ControlledProgramBuilder()
.with_controls([control_qubit_one, control_qubit_two])
.with_target(qubit)
.with_operation(SIGMA_Z)
.with_gate_name(SIGMA_Z_NAME).build())
# This should be one "CZ" instruction, from control_qubit to qubit.
assert len(prog) == 5
# Run tests
double_control_test(prog.instructions, qubit, control_qubit_one, control_qubit_two)
示例22
def test_sample_bad_readout():
np.random.seed(234)
assignment_probs = .3*np.random.rand(4, 4) + np.eye(4)
assignment_probs /= assignment_probs.sum(axis=0)[np.newaxis, :]
cxn = Mock()
cxn.wavefunction.return_value.amplitudes = 0.5j * np.ones(4)
with patch("grove.tomography.utils.sample_outcomes") as so:
ut.sample_bad_readout(Program(X(0), X(1), X(0), X(1)), 10000, assignment_probs, cxn)
assert np.allclose(so.call_args[0][0], 0.25 * assignment_probs.sum(axis=1))
示例23
def test_append_measure_register():
q0 = QubitPlaceholder()
p = Program(H(q0), RX(np.pi/2, 0))
p = append_measure_register(p)
assert str(p[-1]) == "MEASURE 0 ro[1]"
示例24
def run(self, pyquil_program, classical_addresses=None, trials=1):
"""
Run pyquil program and return the results
Loads and checks program if all gates are within the stabilizer set.
Then executes program. If measurements are requested then the measured
results are returned
:param Program pyquil_program: a pyquil Program containing only
CNOT-H-S-MEASUREMENT operations
:param classical_addresses: classical addresses to return
:param trials: number of times to repeat the execution of the program
:return: list of lists of classical memory after each run
"""
self.load_program(pyquil_program)
if classical_addresses is None:
classical_addresses = get_classical_addresses_from_program(pyquil_program)
results = []
for _ in range(trials):
# set up stabilizers
self.tableau = self._n_qubit_tableau(self.num_qubits)
self.kernel()
results.append(list(map(int, self.classical_memory[classical_addresses])))
# results.append([int(b) for b in self.classical_memory[classical_addresses]])
assert results[-1] == [int(b) for b in self.classical_memory[classical_addresses]]
# reset qvm
self.memory_reset()
self.program_counter = 0
return results
示例25
def memory_reset(self):
if self.program is None:
raise TypeError("Program must be loaded to call reset")
# setup quantum and classical memory
q_max, c_max = self.identify_bits()
if c_max <= 512: # allocate at least 512 cbits (as floor)
c_max = 512
self.num_qubits = q_max
self.classical_memory = np.zeros(c_max).astype(bool)
示例26
def expectation(self, pyquil_program, operator_programs=[Program()]):
"""
Calculate the expectation value given a state prepared.
:param pyquil_program: (pyquil.Program) object containing only protoQuil
instructions.
:param operator_programs: (optional, list) of PauliTerms. Default is
Identity operator.
:return: expectation value of the operators.
:rtype: float
"""
# TODO
raise NotImplementedError()
示例27
def test_generate_arbitrary_states(qvm):
for k in list(dc.ARBITRARY_STATE_GEN_INSTRUCTIONS.keys()):
v = np.asarray(dc.ARBITRARY_STATE_GEN_WF[k])
norm = np.sqrt(np.sum(np.multiply(np.conj(v), v)))
p = Program(dc.ARBITRARY_STATE_GEN_INSTRUCTIONS[k])
wf, _ = qvm.wavefunction(p)
# check actual part of wavefunction
assert np.allclose(v.reshape(-1), wf.amplitudes[:len(v)] * norm)
# check remaining zeros part of wavefunction
assert np.allclose(np.zeros((wf.amplitudes.shape[0] - len(v), 1)),
wf.amplitudes[len(v):] * norm)
示例28
def test_qaoa_density():
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]
wf_true = np.reshape(np.array(wf_true), (4, 1))
rho_true = np.dot(wf_true, np.conj(wf_true).T)
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)])
qvm = QVMConnection(type_trans='density')
wf_rho = qvm.density(prog)
assert np.isclose(rho_true, wf_rho.todense()).all()
示例29
def test_kraus_through_qvm_t2():
noise = NoiseModel(T1=INFINITY, ro_fidelity=1.0)
qvm = QVMConnection(type_trans='density', noise_model=noise)
rho = random_1q_density()
identity_program = Program().inst(Igate(0))
qvm._density = sps.csc_matrix(rho)
qvm.num_qubits = 1
qvm.load_program(identity_program)
qvm.kernel()
p = 1 - np.exp(-noise.gate_time_1q/noise.T2)
final_density = np.array([[rho[0, 0], (1 - p) * rho[0, 1]],
[(1 - p) * rho[1, 0], rho[1, 1]]])
assert np.allclose(final_density, qvm._density.todense())
示例30
def test_kraus_through_qvm_t1t2():
noise = NoiseModel(ro_fidelity=1.0)
qvm = QVMConnection(type_trans='density', noise_model=noise)
rho = random_1q_density()
identity_program = Program().inst(Igate(0))
qvm._density = sps.csc_matrix(rho)
qvm.num_qubits = 1
qvm.load_program(identity_program)
qvm.kernel()
p = 1 - np.exp(-noise.gate_time_1q/noise.T2)
p1 = 1 - np.exp(-noise.gate_time_1q/noise.T1)
final_density = np.array([[rho[0, 0] + p1 * rho[1, 1], np.sqrt(1 - p1) * (1 - p) * rho[0, 1]],
[np.sqrt(1 - p1) * (1 - p) * rho[1, 0], (1 - p1) * rho[1, 1]]])
assert np.allclose(final_density, qvm._density.todense())