def test_sync_expectation_mock(qvm: QVMConnection): mock_qvm = qvm mock_endpoint = mock_qvm.sync_endpoint def mock_response(request, context): assert json.loads(request.text) == { "type": "expectation", "state-preparation": BELL_STATE.out(), "operators": ["Z 0\n", "Z 1\n", "Z 0\nZ 1\n"], "rng-seed": 52, } return b"[0.0, 0.0, 1.0]" with requests_mock.Mocker() as m: m.post(mock_endpoint + "/qvm", content=mock_response) result = mock_qvm.expectation( BELL_STATE, [Program(Z(0)), Program(Z(1)), Program(Z(0), Z(1))]) exp_expected = [0.0, 0.0, 1.0] np.testing.assert_allclose(exp_expected, result) with requests_mock.Mocker() as m: m.post(mock_endpoint + "/qvm", content=mock_response) z0 = PauliTerm("Z", 0) z1 = PauliTerm("Z", 1) z01 = z0 * z1 result = mock_qvm.pauli_expectation(BELL_STATE, [z0, z1, z01]) exp_expected = [0.0, 0.0, 1.0] np.testing.assert_allclose(exp_expected, result)
def orig_decode(qubits, indices=None, measure=True): ## indices are qubits you recover secret from, need 3 ## measure asks whether or not to measure result at end if indices is None: indices = np.random.choice(len(qubits), 3, replace=False) new_qubits = [qubits[index] for index in indices] pq = Program() ro = pq.declare('ro', 'BIT', 3) # first hadamard qubit 0 pq += H(new_qubits[0]) # bell state measurement on 1,2 pq += X(new_qubits[2]) pq += CNOT(new_qubits[2], new_qubits[1]) pq += H(new_qubits[2]) pq += MEASURE(new_qubits[1], ro[0]) pq += MEASURE(new_qubits[2], ro[1]) case1 = Program() case2 = Program() case1.if_then(ro[1], Program(Z(new_qubits[0]), X(new_qubits[0])), Z(new_qubits[0])) case2.if_then(ro[1], X(new_qubits[0]), I(new_qubits[0])) pq.if_then(ro[0], case1, case2) if measure: pq += MEASURE(new_qubits[0], ro[2]) return pq, new_qubits
def test_sync_expectation(qvm): result = qvm.expectation( BELL_STATE, [Program(Z(0)), Program(Z(1)), Program(Z(0), Z(1))]) exp_expected = [0.0, 0.0, 1.0] np.testing.assert_allclose(exp_expected, result)
def test_sync_expectation(): def mock_response(request, context): assert json.loads(request.text) == { "type": "expectation", "state-preparation": BELL_STATE.out(), "operators": ["Z 0\n", "Z 1\n", "Z 0\nZ 1\n"] } return b'[0.0, 0.0, 1.0]' with requests_mock.Mocker() as m: m.post('https://api.rigetti.com/qvm', content=mock_response) result = qvm.expectation( BELL_STATE, [Program(Z(0)), Program(Z(1)), Program(Z(0), Z(1))]) exp_expected = [0.0, 0.0, 1.0] assert np.allclose(result, exp_expected) with requests_mock.Mocker() as m: m.post('https://api.rigetti.com/qvm', content=mock_response) z0 = PauliTerm("Z", 0) z1 = PauliTerm("Z", 1) z01 = z0 * z1 result = qvm.pauli_expectation(BELL_STATE, [z0, z1, z01]) exp_expected = [0.0, 0.0, 1.0] assert np.allclose(result, exp_expected)
def test_ref_program_pass(): ref_prog = Program().inst([X(0), Y(1), Z(2)]) fakeQVM = Mock(spec=qvm_module.SyncConnection()) inst = QAOA(fakeQVM, 2, driver_ref=ref_prog) param_prog = inst.get_parameterized_program() test_prog = param_prog([0, 0]) compare_progs(ref_prog, test_prog)
def decomposed_diffusion_program(qubits): """ Constructs the diffusion operator used in Grover's Algorithm, acted on both sides by an a Hadamard gate on each qubit. Note that this means that the matrix representation of this operator is diag(1, -1, ..., -1). In particular, this decomposes the diffusion operator, which is a :math:`2**{len(qubits)}\times2**{len(qubits)}` sparse matrix, into :math:`\mathcal{O}(len(qubits)**2) single and two qubit gates. See C. Lavor, L.R.U. Manssur, and R. Portugal (2003) `Grover's Algorithm: Quantum Database Search`_ for more information. .. _`Grover's Algorithm: Quantum Database Search`: https://arxiv.org/abs/quant-ph/0301079 :param qubits: A list of ints corresponding to the qubits to operate on. The operator operates on bistrings of the form ``|qubits[0], ..., qubits[-1]>``. """ program = pq.Program() if len(qubits) == 1: program.inst(Z(qubits[0])) else: program.inst([X(q) for q in qubits]) program.inst(H(qubits[-1])) program.inst(RZ(-np.pi, qubits[0])) program += (ControlledProgramBuilder().with_controls( qubits[:-1]).with_target(qubits[-1]).with_operation( X_GATE).with_gate_name(X_GATE_LABEL).build()) program.inst(RZ(-np.pi, qubits[0])) program.inst(H(qubits[-1])) program.inst([X(q) for q in qubits]) return program
def test_dagger(): p = Program(X(0), H(0)) assert p.dagger().out() == "DAGGER H 0\nDAGGER X 0\n" p = Program(X(0), MEASURE(0, MemoryReference("ro", 0))) with pytest.raises(ValueError): p.dagger().out() # ensure that modifiers are preserved https://github.com/rigetti/pyquil/pull/914 p = Program() control = 0 target = 1 cnot_control = 2 p += X(target).controlled(control) p += Y(target).controlled(control) p += Z(target).controlled(control) p += H(target).controlled(control) p += S(target).controlled(control) p += T(target).controlled(control) p += PHASE(pi, target).controlled(control) p += CNOT(cnot_control, target).controlled(control) for instr, instr_dagger in zip(reversed(p._instructions), p.dagger()._instructions): assert "DAGGER " + instr.out() == instr_dagger.out()
def test_construction_syntax(): p = Program().inst(X(0), Y(1), Z(0)).measure(0, 1) assert p.out() == 'X 0\nY 1\nZ 0\nMEASURE 0 [1]\n' p = Program().inst(X(0)).inst(Y(1)).measure(0, 1).inst(MEASURE(1, 2)) assert p.out() == 'X 0\nY 1\nMEASURE 0 [1]\nMEASURE 1 [2]\n' p = Program().inst(X(0)).measure(0, 1).inst(Y(1), X(0)).measure(0, 0) assert p.out() == 'X 0\nMEASURE 0 [1]\nY 1\nX 0\nMEASURE 0 [0]\n'
def diffusion_program(qubits): """Constructs the diffusion operator used in Grover's Algorithm, acted on both sides by an a Hadamard gate on each qubit. Note that this means that the matrix representation of this operator is diag(1, -1, ..., -1). See C. Lavor, L.R.U. Manssur, and R. Portugal (2003) `Grover's Algorithm: Quantum Database Search`_ for more information. .. _`Grover's Algorithm: Quantum Database Search`: https://arxiv.org/abs/quant-ph/0301079 :param qubits: A list of ints corresponding to the qubits to operate on. The operator operates on bistrings of the form |qubits[0], ..., qubits[-1]>. """ diffusion_program = pq.Program() if len(qubits) == 1: diffusion_program.inst(Z(qubits[0])) else: diffusion_program.inst([X(q) for q in qubits]) diffusion_program.inst(H(qubits[-1])) diffusion_program.inst(RZ(-np.pi)(qubits[0])) diffusion_program += (ControlledProgramBuilder() .with_controls(qubits[:-1]) .with_target(qubits[-1]) .with_operation(X_GATE) .with_gate_name("NOT").build()) diffusion_program.inst(RZ(-np.pi)(qubits[0])) diffusion_program.inst(H(qubits[-1])) diffusion_program.inst([X(q) for q in qubits]) return diffusion_program
def diffusion_operator(qubits): """Constructs the (Grover) diffusion operator on qubits, assuming they are ordered from most significant qubit to least significant qubit. The diffusion operator is the diagonal operator given by(1, -1, -1, ..., -1). :param qubits: A list of ints corresponding to the qubits to operate on. The operator operates on bistrings of the form |qubits[0], ..., qubits[-1]>. """ p = pq.Program() if len(qubits) == 1: p.inst(H(qubits[0])) p.inst(Z(qubits[0])) p.inst(H(qubits[0])) else: p.inst(map(X, qubits)) p.inst(H(qubits[-1])) p.inst(RZ(-np.pi)(qubits[0])) p += n_qubit_control(qubits[:-1], qubits[-1], np.array([[0, 1], [1, 0]]), "NOT") p.inst(RZ(-np.pi)(qubits[0])) p.inst(H(qubits[-1])) p.inst(map(X, qubits)) return p
def transformcionDeAlice(mensajeDeAlice): #Entrelazamiento de los qubits program = estadoDeBell() #Alice aplica la compuerta apropiada if (mensajeDeAlice == "11"): program += Program(X(0), Z(0)) elif (mensajeDeAlice == "01"): program += Program(X(0)) elif (mensajeDeAlice == "10"): program += Program(Z(0)) return program
def test_to_pyquil_from_pyquil_simple(): p = Program() p += X(0) p += Y(1) p += Z(2) p += CNOT(0, 1) p += CZ(1, 2) assert p.out() == to_pyquil(from_pyquil(p)).out()
def test_ref_program_pass(): ref_prog = Program().inst([X(0), Y(1), Z(2)]) fakeQVM = Mock(QuantumComputer) inst = QAOA(fakeQVM, list(range(2)), driver_ref=ref_prog) param_prog = inst.get_parameterized_program() test_prog = param_prog([0, 0]) assert ref_prog == test_prog
def test_ref_program_pass(): ref_prog = Program().inst([X(0), Y(1), Z(2)]) fakeQVM = Mock(spec=qvm_module.QVMConnection()) inst = QAOA(fakeQVM, range(2), driver_ref=ref_prog) param_prog = inst.get_parameterized_program() test_prog = param_prog([0, 0]) assert ref_prog == test_prog
def test_to_pyquil_from_pyquil_not_starting_at_zero(): p = Program() p += X(10) p += Y(11) p += Z(12) p += CNOT(10, 11) p += CZ(11, 12) assert p.out() == to_pyquil(from_pyquil(p)).out()
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 random_identity_circuit(depth=None): """Returns a single-qubit identity circuit based on Pauli gates.""" # initialize a quantum circuit prog = Program() # index of the (inverting) final gate: 0=I, 1=X, 2=Y, 3=Z k_inv = 0 # apply a random sequence of Pauli gates for _ in range(depth): # random index for the next gate: 1=X, 2=Y, 3=Z k = np.random.choice([1, 2, 3]) # apply the Pauli gate "k" if k == 1: prog += X(0) elif k == 2: prog += Y(0) elif k == 3: prog += Z(0) # update the inverse index according to # the product rules of Pauli matrices k and k_inv if k_inv == 0: k_inv = k elif k_inv == k: k_inv = 0 else: _ = [1, 2, 3] _.remove(k_inv) _.remove(k) k_inv = _[0] # apply the final inverse gate if k_inv == 1: prog += X(0) elif k_inv == 2: prog += Y(0) elif k_inv == 3: prog += Z(0) return prog
def test_merge_disjoint_experiments(): sett1 = ExperimentSetting(TensorProductState(), sX(0) * sY(1)) sett2 = ExperimentSetting(plusZ(1), sY(1)) sett3 = ExperimentSetting(plusZ(0), sX(0)) sett4 = ExperimentSetting(minusX(1), sY(1)) sett5 = ExperimentSetting(TensorProductState(), sZ(2)) expt1 = Experiment(settings=[sett1, sett2], program=Program(X(1))) expt2 = Experiment(settings=[sett3, sett4], program=Program(Z(0))) expt3 = Experiment(settings=[sett5], program=Program()) merged_expt = merge_disjoint_experiments([expt1, expt2, expt3]) assert len(merged_expt) == 2
def test_construction_syntax(): p = (Program().inst(Declare("ro", "BIT", 2), X(0), Y(1), Z(0)).measure(0, MemoryReference("ro", 1))) assert p.out() == ("DECLARE ro BIT[2]\nX 0\nY 1\nZ 0\nMEASURE 0 ro[1]\n") p = (Program().inst(Declare("ro", "BIT", 3), X(0)).inst(Y(1)).measure( 0, MemoryReference("ro", 1)).inst(MEASURE(1, MemoryReference("ro", 2)))) assert p.out() == ( "DECLARE ro BIT[3]\nX 0\nY 1\nMEASURE 0 ro[1]\nMEASURE 1 ro[2]\n") p = (Program().inst(Declare("ro", "BIT", 2), X(0)).measure(0, MemoryReference("ro", 1)).inst( Y(1), X(0)).measure(0, MemoryReference("ro", 0))) assert p.out() == ( "DECLARE ro BIT[2]\nX 0\nMEASURE 0 ro[1]\nY 1\nX 0\nMEASURE 0 ro[0]\n")
def test_trivial_grover(): """Testing that we construct the correct circuit for Grover's Algorithm with one step, and the identity_oracle on one qubit. """ trivial_grover = Program() qubit0 = trivial_grover.alloc() # First we put the input into uniform superposition. trivial_grover.inst(H(qubit0)) # No oracle is applied, so we just apply the diffusion operator. trivial_grover.inst(H(qubit0)) trivial_grover.inst(Z(qubit0)) trivial_grover.inst(H(qubit0)) qubits = [qubit0] generated_trivial_grover = Grover().oracle_grover(identity_oracle, qubits, 1) assert generated_trivial_grover.out() == trivial_grover.out()
def test_fuse(): @parametric def rx(alpha): p = Program() p += RX(alpha)(0) return p @parametric def ry(beta): p = Program() p += RY(beta)(1) return p z = Program().inst(Z(2)) fused = rx.fuse(ry).fuse(z) assert fused(1.0, 2.0).out() == "RX(1.0) 0\nRY(2.0) 1\nZ 2\n"
def simulate_error(primal: nx.Graph, dual: nx.Graph, p=None, phase_flips=None, bit_flips=None): '''Given a code defined by a primal and dual graph, applies noise under the independent noise model. :param primal: Primal graph of the code :param dual: Dual graph of the code :param p: Probability with which to apply bit and phase flips :param phase_flips, bit_flips: Lists of edges to apply bit/phase flips to, if working in a deterministic setting (in this case, set p=None) :returns: Program for primal and dual graphs representing the applied errors, and lists of edges for each graph where phase and bit flips were applied for debugging ''' if p is None: assert phase_flips is not None assert bit_flips is not None else: # Randomly choose which qubits will have bit/phase flip errors # Working under the independent noise model; since the toric code is a # CSS code, we can analyze bit and phase flip errors seperately assert phase_flips is None assert bit_flips is None phase_flips = set() for edge in primal.edges: if weighted_flip(p): phase_flips.add(edge) bit_flips = set() for edge in dual.edges: if weighted_flip(p): bit_flips.add(edge) primal_pq = Program() dual_pq = Program() # Apply the errors we selected above to the necessary qubits for p_edge in primal.edges: if p_edge in phase_flips: primal_pq += Z(primal.edges[p_edge]['data_qubit']) for d_edge in dual.edges: if d_edge in bit_flips: dual_pq += X(dual.edges[d_edge]['data_qubit']) return primal_pq, phase_flips, dual_pq, bit_flips
def test_merge_with_pauli_noise(): p = Program(X(0)).inst(Z(0)) probs = [0.0, 1.0, 0.0, 0.0] merged = merge_with_pauli_noise(p, probs, [0]) assert (merged.out() == """DEFGATE pauli_noise: 1.0, 0 0, 1.0 PRAGMA ADD-KRAUS pauli_noise 0 "(0.0 0.0 0.0 0.0)" PRAGMA ADD-KRAUS pauli_noise 0 "(0.0 1.0 1.0 0.0)" PRAGMA ADD-KRAUS pauli_noise 0 "(0.0 0.0 0.0 0.0)" PRAGMA ADD-KRAUS pauli_noise 0 "(0.0 0.0 0.0 -0.0)" X 0 pauli_noise 0 Z 0 pauli_noise 0 """)
def test_x_oracle_one_grover(x_oracle): """Testing that Grover's algorithm with an oracle that applies an X gate to the query bit works, with one iteration.""" x_oracle_grover = Program() qubit0 = x_oracle_grover.alloc() qubits = [qubit0] oracle, query_qubit = x_oracle with patch("pyquil.quil.Program.alloc") as mock_alloc: mock_alloc.return_value = qubit0 generated_x_oracle_grover = Grover().oracle_grover(oracle, qubits, 1) # First we put the input into uniform superposition. x_oracle_grover.inst(H(qubit0)) # Now an oracle is applied. x_oracle_grover.inst(X(query_qubit)) # We now apply the diffusion operator. x_oracle_grover.inst(H(qubit0)) x_oracle_grover.inst(Z(qubit0)) x_oracle_grover.inst(H(qubit0)) assert generated_x_oracle_grover == x_oracle_grover
def teleport(start_index, end_index, ancilla_index): """Teleport a qubit from start to end using an ancilla qubit """ p = make_bell_pair(end_index, ancilla_index) # do the teleportation p.inst(CNOT(start_index, ancilla_index)) p.inst(H(start_index)) # measure the results and store them in classical registers [0] and [1] p.measure(start_index, 0) p.measure(ancilla_index, 1) p.if_then(1, X(2)) p.if_then(0, Z(2)) p.measure(end_index, 2) return p
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 test_construction_syntax(): p = Program().inst(Declare('ro', 'BIT', 2), X(0), Y(1), Z(0)).measure(0, MemoryReference('ro', 1)) assert p.out() == ('DECLARE ro BIT[2]\n' 'X 0\n' 'Y 1\n' 'Z 0\n' 'MEASURE 0 ro[1]\n') p = Program().inst(Declare('ro', 'BIT', 3), X(0)).inst(Y(1)).measure(0, MemoryReference('ro', 1)).inst(MEASURE(1, MemoryReference('ro', 2))) assert p.out() == ('DECLARE ro BIT[3]\n' 'X 0\n' 'Y 1\n' 'MEASURE 0 ro[1]\n' 'MEASURE 1 ro[2]\n') p = Program().inst(Declare('ro', 'BIT', 2), X(0)).measure(0, MemoryReference('ro', 1)).inst(Y(1), X(0)).measure(0, MemoryReference('ro', 0)) assert p.out() == ('DECLARE ro BIT[2]\n' 'X 0\n' 'MEASURE 0 ro[1]\n' 'Y 1\n' 'X 0\n' 'MEASURE 0 ro[0]\n')
def test_construction_syntax(): p = Program().inst(X(0), Y(1), Z(0)).measure(0, 1) assert p.out() == ('DECLARE ro BIT[2]\n' 'X 0\n' 'Y 1\n' 'Z 0\n' 'MEASURE 0 ro[1]\n') p = Program().inst(X(0)).inst(Y(1)).measure(0, 1).inst(MEASURE(1, 2)) assert p.out() == ('DECLARE ro BIT[3]\n' 'X 0\n' 'Y 1\n' 'MEASURE 0 ro[1]\n' 'MEASURE 1 ro[2]\n') p = Program().inst(X(0)).measure(0, 1).inst(Y(1), X(0)).measure(0, 0) assert p.out() == ('DECLARE ro BIT[2]\n' 'X 0\n' 'MEASURE 0 ro[1]\n' 'Y 1\n' 'X 0\n' 'MEASURE 0 ro[0]\n')
def create_singlet_state(): """ Returns quantum program that constructs a Singlet state of two spins """ p = Program() # Start by constructing a Triplet state of two spins (Bell state) # 10|> + 01|> # https://en.wikipedia.org/wiki/Triplet_state # p.inst(X(0)) p.inst(H(1)) p.inst(CNOT(1, 0)) # Convert to Singlet # 01|> - 10|> # https://en.wikipedia.org/wiki/Singlet_state # p.inst(Z(1)) return p
def test_x_oracle_two_grover(x_oracle): """Testing that Grover's algorithm with an oracle that applies an X gate to the query bit works, with two iterations.""" x_oracle_grover = Program() qubit0 = x_oracle_grover.alloc() qubits = [qubit0] oracle, query_qubit = x_oracle with patch("pyquil.quilbase.InstructionGroup.alloc") as mock_alloc: mock_alloc.return_value = qubit0 generated_x_oracle_grover = Grover().oracle_grover(oracle, qubits, 2) # First we put the input into uniform superposition. x_oracle_grover.inst(H(qubit0)) # Two iterations. for _ in range(2): # Now an oracle is applied. x_oracle_grover.inst(X(query_qubit)) # We apply the diffusion operator. x_oracle_grover.inst(H(qubit0)) x_oracle_grover.inst(Z(qubit0)) x_oracle_grover.inst(H(qubit0)) synthesize_programs(generated_x_oracle_grover, x_oracle_grover) assert prog_equality(generated_x_oracle_grover, x_oracle_grover)