def qfunc(a, b, c, angles): qml.RX(a, wires=0) qml.RX(b, wires=1) qml.PauliZ(1) qml.CNOT(wires=[0, 1]).inv() qml.CRY(b, wires=[3, 1]) qml.RX(angles[0], wires=0) qml.RX(4 * angles[1], wires=1) qml.PhaseShift(17 / 9 * c, wires=2) qml.RZ(b, wires=3) qml.RX(angles[2], wires=2).inv() qml.CRY(0.3589, wires=[3, 1]).inv() qml.CSWAP(wires=[4, 2, 1]).inv() qml.QubitUnitary(np.eye(2), wires=[2]) qml.Toffoli(wires=[0, 2, 1]) qml.CNOT(wires=[0, 2]) qml.PauliZ(wires=[1]) qml.PauliZ(wires=[1]).inv() qml.CZ(wires=[0, 1]) qml.CZ(wires=[0, 2]).inv() qml.CNOT(wires=[2, 1]) qml.CNOT(wires=[0, 2]) qml.SWAP(wires=[0, 2]).inv() qml.CNOT(wires=[1, 3]) qml.RZ(b, wires=3) qml.CSWAP(wires=[4, 0, 1]) return [ qml.expval(qml.PauliY(0)), qml.var(qml.Hadamard(wires=1)), qml.sample(qml.PauliX(2)), qml.expval(qml.Hermitian(np.eye(4), wires=[3, 4])), ]
def controlled_ansatz(params): qml.CRY(params[0], wires=[2, 0]) qml.CRY(params[1], wires=[2, 1]) qml.Toffoli(wires=[2, 0, 1]) qml.CRX(params[2], wires=[2, 1]) qml.CRX(params[3], wires=[2, 0]) qml.Toffoli(wires=[2, 1, 0])
def circuit(): """A combination of two and three qubit gates with the one_qubit_block and a simple PauliZ measurement, all acting on a four qubit input basis state""" qml.BasisState(np.array(basis_state), wires=[0, 1, 2, 3]) qml.RX(0.5, wires=0) qml.Hadamard(wires=1) qml.RY(0.9, wires=2) qml.Rot(0.1, -0.2, -0.3, wires=3) qml.CNOT(wires=[0, 1]) qml.CNOT(wires=[3, 1]) one_qubit_block(wires=3) qml.CNOT(wires=[2, 0]) qml.CZ(wires=[1, 0]) one_qubit_block(wires=0) qml.Toffoli(wires=[1, 0, 2]) one_qubit_block(wires=2) qml.SWAP(wires=[0, 1]) qml.SWAP(wires=[0, 2]) qml.Toffoli(wires=[1, 3, 2]) qml.CRX(0.5, wires=[1, 0]) qml.CSWAP(wires=[2, 1, 0]) qml.CRY(0.9, wires=[2, 1]) one_qubit_block(wires=1) qml.CRZ(0.02, wires=[0, 1]) qml.CRY(0.9, wires=[2, 3]) qml.CRot(0.2, 0.3, 0.7, wires=[2, 1]) qml.RZ(0.4, wires=0) qml.Toffoli(wires=[2, 1, 0]) return qml.expval(qml.PauliZ(0))
def Word_Shuffle_circuit(params, wires): """Apply a sequence of controlled-rotation params : 3 angles [0:2pi], 1 per qubit wires : the 3 wires indexing the current word""" for i in range(len(wires)): if i == len(wires) - 1: #the last wire controls the first qubit qml.CRY(params[i], wires=[wires[i], wires[0]]) else: qml.CRY(params[i], wires=[wires[i], wires[i + 1]])
def real(angles, **kwargs): qml.RY(0.27740551, wires=0) qml.PauliX(wires=0) qml.CRY(0.20273270, wires=[0, 1]) qml.PauliX(wires=0) qml.CRY(np.pi / 2, wires=[0, 1]) qml.CRY(np.pi / 2, wires=[0, 2]) qml.PauliX(wires=0) qml.CRY(1.42492, wires=[0, 2]) qml.PauliX(wires=0)
def qfunc(theta): qml.Hadamard(wires=0) qml.RZ(theta[0], wires=0) qml.PauliY(wires=1) qml.RZ(theta[1], wires=0) qml.CNOT(wires=[1, 2]) qml.CRY(theta[2], wires=[1, 2]) qml.PauliZ(wires=0) qml.CRY(theta[3], wires=[1, 2]) qml.Rot(theta[0], theta[1], theta[2], wires=1) qml.Rot(theta[2], theta[3], theta[0], wires=1) return qml.expval(qml.PauliX(0) @ qml.PauliX(2))
def featuremap(x1, x2, y, phi0): # encode y label if y == 1: qml.CNOT(wires=[6, 5]) # flip label qubit # feature map qml.CRX(x1, wires=[6, 3]) qml.CRX(x2, wires=[6, 4]) qml.CNOT(wires=[3, 4]) qml.CNOT(wires=[4, 3]) qml.CRY(phi0[0], wires=[6, 3]) qml.CRY(phi0[0], wires=[6, 4]) qml.CNOT(wires=[3, 4]) qml.CNOT(wires=[4, 3])
def stronglayerCRY(slparam, CRparam, n_wires, r=1): slparam = math.pi * slparam qml.RX(slparam[0, 0], wires=0) qml.RY(slparam[1, 0], wires=0) qml.RZ(slparam[2, 0], wires=0) for i in range(1, n_wires): qml.RX(slparam[0, i], wires=i) qml.RY(slparam[1, i], wires=i) qml.RZ(slparam[2, i], wires=i) qml.CRY(CRparam[i], wires=[i, i - 1]) qml.CRY(CRparam[0], wires=[0, n_wires - 1])
def qfunc(): qml.PauliX(wires=1) qml.S(wires=0) qml.CZ(wires=[0, 1]) qml.CNOT(wires=[1, 0]) qml.PauliY(wires=1) qml.CRY(0.5, wires=[1, 0]) qml.PhaseShift(0.2, wires=0) qml.PauliY(wires=1) qml.T(wires=0) qml.CRZ(-0.3, wires=[0, 1]) qml.RZ(0.2, wires=0) qml.PauliZ(wires=0) qml.PauliX(wires=1) qml.CRY(0.2, wires=[1, 0])
def variational_ansatz(params, wires): """The variational ansatz circuit. Fill in the details of your ansatz between the # QHACK # comment markers. Your ansatz should produce an n-qubit state of the form a_0 |10...0> + a_1 |01..0> + ... + a_{n-2} |00...10> + a_{n-1} |00...01> where {a_i} are real-valued coefficients. Args: params (np.array): The variational parameters. wires (qml.Wires): The device wires that this circuit will run on. """ # These params aren't always mp.arrays , sometimes they're this "ArrayBox" shit from autograd. # And that screwed up my code no matter how hard I tried. :/ # QHACK # num_qubits = len(wires) qml.RY(params[0], wires=0) for i in range(1, num_qubits - 1): qml.CRY(params[i], wires=wires[i - 1:i + 1]) for i in range(num_qubits - 1, 0, -1): qml.CNOT(wires=wires[i - 1:i + 1]) qml.PauliX(wires=0)
def test_get_unitary_matrix_interface_autograd(): """Test with autograd interface""" dev = qml.device("default.qubit", wires=3) def circuit(theta): qml.RZ(theta[0], wires=0) qml.RZ(theta[1], wires=1) qml.CRY(theta[2], wires=[1, 2]) return qml.expval(qml.PauliZ(1)) # set qnode interface qnode = qml.QNode(circuit, dev, interface="autograd") get_matrix = get_unitary_matrix(qnode) # set input parameters theta = np.array([0.1, 0.2, 0.3], requires_grad=True) matrix = get_matrix(theta) # expected matrix matrix1 = np.kron( qml.RZ(theta[0], wires=0).matrix, np.kron(qml.RZ(theta[1], wires=1).matrix, I) ) matrix2 = np.kron(I, qml.CRY(theta[2], wires=[1, 2]).matrix) expected_matrix = matrix2 @ matrix1 assert np.allclose(matrix, expected_matrix)
def test_convert_program_with_controlled_operations(self): """Test that a program with controlled operations is properly converted.""" program = pyquil.Program() program += g.RZ(0.34, 1) program += g.RY(0.2, 3).controlled(2) program += g.RX(0.4, 2).controlled(0) program += g.CNOT(1, 4) program += g.CNOT(1, 6).controlled(3) program += g.X(3).controlled(4).controlled(1) with OperationRecorder() as rec: load_program(program)(wires=range(6)) expected_queue = [ qml.RZ(0.34, wires=[1]), qml.CRY(0.2, wires=[2, 3]), qml.CRX(0.4, wires=[0, 2]), qml.CNOT(wires=[1, 4]), plf.ops.CCNOT(wires=[3, 1, 5]), plf.ops.CCNOT(wires=[1, 4, 3]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params
def test_get_unitary_matrix_interface_tf(): """Test with tensorflow interface""" tf = pytest.importorskip("tensorflow") dev = qml.device("default.qubit", wires=3) def circuit(beta, theta): qml.RZ(beta, wires=0) qml.RZ(theta[0], wires=1) qml.CRY(theta[1], wires=[1, 2]) return qml.expval(qml.PauliZ(1)) # set qnode interface qnode_tensorflow = qml.QNode(circuit, dev, interface="tf") get_matrix = get_unitary_matrix(qnode_tensorflow) beta = 0.1 # input tensorflow parameters theta = tf.Variable([0.2, 0.3]) matrix = get_matrix(beta, theta) # expected matrix theta_np = theta.numpy() matrix1 = np.kron(qml.RZ(beta, wires=0).matrix, np.kron(qml.RZ(theta_np[0], wires=1).matrix, I)) matrix2 = np.kron(I, qml.CRY(theta_np[1], wires=[1, 2]).matrix) expected_matrix = matrix2 @ matrix1 assert np.allclose(matrix, expected_matrix)
def variational_ansatz(params, wires): """The variational ansatz circuit. Fill in the details of your ansatz between the # QHACK # comment markers. Your ansatz should produce an n-qubit state of the form a_0 |10...0> + a_1 |01..0> + ... + a_{n-2} |00...10> + a_{n-1} |00...01> where {a_i} are real-valued coefficients. Args: params (np.array): The variational parameters. wires (qml.Wires): The device wires that this circuit will run on. """ # QHACK # n_qubits = len(wires) qml.RY(params[0], wires=0) for i in range(1, n_qubits - 1): qml.CRY(params[i], wires=[i - 1, i]) for i in range(n_qubits - 1, 0, -1): qml.CNOT(wires=[i - 1, i]) qml.PauliX(wires=0)
def test_decompose_queue_recursive(self, operable_mock_device_2_wires_with_inverses): """Test that decompose queue works correctly when an operation exists that can be decomposed""" queue = [qml.CRY(1, wires=[0, 1]), qml.U3(3, 4, 5, wires=0)] res = decompose_queue(queue, operable_mock_device_2_wires_with_inverses) assert len(res) == 9 assert res[0].name == "RY" assert res[0].parameters == [0.5] assert res[1].name == "CNOT" assert res[2].name == "RY" assert res[2].parameters == [-0.5] assert res[3].name == "CNOT" assert res[4].name == "RZ" assert res[4].parameters == [5] assert res[5].name == "RY" assert res[5].parameters == [3] assert res[6].name == "RZ" assert res[6].parameters == [-5] assert res[7].name == "PhaseShift" assert res[7].parameters == [5] assert res[8].name == "PhaseShift" assert res[8].parameters == [4]
def test_adjoint_of_control(): """Test adjoint(ctrl(fn)) and ctrl(adjoint(fn))""" def my_op(a, b, c): qml.RX(a, wires=2) qml.RY(b, wires=3) qml.RZ(c, wires=0) with QuantumTape() as tape1: cmy_op_dagger = qml.adjoint(ctrl(my_op, 5)) # Execute controlled and adjointed version of my_op. cmy_op_dagger(0.789, 0.123, c=0.456) with QuantumTape() as tape2: cmy_op_dagger = ctrl(qml.adjoint(my_op), 5) # Execute adjointed and controlled version of my_op. cmy_op_dagger(0.789, 0.123, c=0.456) expected = [ qml.CRZ(-0.456, wires=[5, 0]), qml.CRY(-0.123, wires=[5, 3]), qml.CRX(-0.789, wires=[5, 2]), ] for tape in [tape1, tape2]: assert len(tape.operations) == 1 ctrl_op = tape.operations[0] assert isinstance(ctrl_op, ControlledOperation) expanded = ctrl_op.expand() assert_equal_operations(expanded.operations, expected)
def test_control_sanity_check(): """Test that control works on a very standard usecase.""" def make_ops(): qml.RX(0.123, wires=0) qml.RY(0.456, wires=2) qml.RX(0.789, wires=0) qml.Rot(0.111, 0.222, 0.333, wires=2), qml.PauliX(wires=2) qml.PauliY(wires=4) qml.PauliZ(wires=0) with QuantumTape() as tape: cmake_ops = ctrl(make_ops, control=1) #Execute controlled version. cmake_ops() expected = [ qml.CRX(0.123, wires=[1, 0]), qml.CRY(0.456, wires=[1, 2]), qml.CRX(0.789, wires=[1, 0]), qml.CRot(0.111, 0.222, 0.333, wires=[1, 2]), qml.CNOT(wires=[1, 2]), qml.CY(wires=[1, 4]), qml.CZ(wires=[1, 0]), ] assert len(tape.operations) == 1 ctrl_op = tape.operations[0] assert isinstance(ctrl_op, ControlledOperation) expanded = ctrl_op.expand() assert_equal_operations(expanded.operations, expected)
def test_get_unitary_matrix_interface_torch(): """Test with torch interface""" torch = pytest.importorskip("torch", minversion="1.8") dev = qml.device("default.qubit", wires=3) def circuit(theta): qml.RZ(theta[0], wires=0) qml.RZ(theta[1], wires=1) qml.CRY(theta[2], wires=[1, 2]) return qml.expval(qml.PauliZ(1)) # set qnode interface qnode_torch = qml.QNode(circuit, dev, interface="torch") get_matrix = get_unitary_matrix(qnode_torch) # input torch parameters theta = torch.tensor([0.1, 0.2, 0.3]) matrix = get_matrix(theta) # expected matrix matrix1 = np.kron( qml.RZ(theta[0], wires=0).matrix, np.kron(qml.RZ(theta[1], wires=1).matrix, I) ) matrix2 = np.kron(I, qml.CRY(theta[2], wires=[1, 2]).matrix) expected_matrix = matrix2 @ matrix1 assert np.allclose(matrix, expected_matrix)
def decomposition(theta, wires): decomp_ops = [ qml.CNOT(wires=[wires[0], wires[1]]), qml.CRY(theta, wires=[wires[1], wires[0]]), qml.CNOT(wires=[wires[0], wires[1]]), ] return decomp_ops
def circuit(): qml.CRZ(0.0, wires=[0, 1]) qml.CRX(0.0, wires=[0, 1]) qml.PhaseShift(0.0, wires=0) qml.ControlledPhaseShift(0.0, wires=[1, 0]) qml.CRot(1.0, 0.0, 0.0, wires=[0, 1]) qml.CRY(0.0, wires=[0, 1]) return qml.sample(qml.PauliZ(wires=0))
def circuit(x, y, add_RY=True): qml.RX(x[0], wires=0) qml.Toffoli(wires=(0, 1, 2)) qml.CRY(x[1], wires=(0, 1)) qml.Rot(x[2], x[3], y, wires=2) if add_RY: qml.RY(x[4], wires=1) return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(1))
def U_c(): """Unitary matrix rotating the ground state of the ancillary qubits to |sqrt(c)> = U_c |0>.""" # Circuit mapping |00> to sqrt_c[0] |00> + sqrt_c[1] |01> + sqrt_c[2] |10> qml.RY(-2 * np.arccos(sqrt_c[0]), wires=ancilla_idx) qml.CRY(-2 * np.arctan(sqrt_c[2] / sqrt_c[1]), wires=[ancilla_idx, ancilla_idx + 1]) qml.CNOT(wires=[ancilla_idx + 1, ancilla_idx])
def circuit_with_tardigrade(theta): """ Circuit with Tardigrade Prepares cos(theta/2) |010> + sin(theta/2) |001> + |100> """ qml.Hadamard(wires=0) qml.CRY(np.pi + theta, wires=(0, 1)) qml.CNOT(wires=(0, 2)) qml.CNOT(wires=(1, 2)) qml.PauliX(wires=0) return qml.density_matrix(wires=1)
def qfunc(theta): qml.PauliX(wires=2) qml.S(wires=0) qml.CNOT(wires=[0, 1]) qml.PauliY(wires=1) qml.CRY(theta[0], wires=[2, 1]) qml.PhaseShift(theta[1], wires=0) qml.T(wires=0) qml.Toffoli(wires=[0, 1, 2]) return qml.expval(qml.PauliZ(0))
def parameterized_qubit_tape(): """A parametrized qubit ciruit.""" a, b, c = 0.1, 0.2, 0.3 angles = np.array([0.4, 0.5, 0.6]) with qml.tape.QuantumTape() as tape: qml.RX(a, wires=0) qml.RX(b, wires=1) qml.PauliZ(1) qml.CNOT(wires=[0, 1]).inv() qml.CRY(b, wires=[3, 1]) qml.RX(angles[0], wires=0) qml.RX(4 * angles[1], wires=1) qml.PhaseShift(17 / 9 * c, wires=2) qml.RZ(b, wires=3) qml.RX(angles[2], wires=2).inv() qml.CRY(0.3589, wires=[3, 1]).inv() qml.CSWAP(wires=[4, 2, 1]).inv() qml.QubitUnitary(np.eye(2), wires=[2]) qml.ControlledQubitUnitary(np.eye(2), control_wires=[0, 1], wires=[2]) qml.MultiControlledX(control_wires=[0, 1, 2], wires=[3]) qml.Toffoli(wires=[0, 2, 1]) qml.CNOT(wires=[0, 2]) qml.PauliZ(wires=[1]) qml.PauliZ(wires=[1]).inv() qml.CZ(wires=[0, 1]) qml.CZ(wires=[0, 2]).inv() qml.CY(wires=[1, 2]) qml.CY(wires=[2, 0]).inv() qml.CNOT(wires=[2, 1]) qml.CNOT(wires=[0, 2]) qml.SWAP(wires=[0, 2]).inv() qml.CNOT(wires=[1, 3]) qml.RZ(b, wires=3) qml.CSWAP(wires=[4, 0, 1]) qml.expval(qml.PauliY(0)), qml.var(qml.Hadamard(wires=1)), qml.sample(qml.PauliX(2)), qml.expval(qml.Hermitian(np.eye(4), wires=[3, 4])), return tape
def array_qnode(x, y, z): for _x, w in zip(x, dev.wires): qml.RX(_x, wires=w) for i in range(num_wires): qml.CRY(y, wires=[i, (i + 1) % num_wires]) qml.RZ(z[0], wires=0) qml.RZ(z[1], wires=1) qml.RZ(z[1], wires=2) # z[1] is used twice on purpose return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1) @ qml.PauliZ(2))
def op(op_name): ops_list = { "RX": qml.RX(0.123, wires=0), "RY": qml.RY(1.434, wires=0), "RZ": qml.RZ(2.774, wires=0), "S": qml.S(wires=0), "SX": qml.SX(wires=0), "T": qml.T(wires=0), "CNOT": qml.CNOT(wires=[0, 1]), "CZ": qml.CZ(wires=[0, 1]), "CY": qml.CY(wires=[0, 1]), "SWAP": qml.SWAP(wires=[0, 1]), "ISWAP": qml.ISWAP(wires=[0, 1]), "SISWAP": qml.SISWAP(wires=[0, 1]), "SQISW": qml.SQISW(wires=[0, 1]), "CSWAP": qml.CSWAP(wires=[0, 1, 2]), "PauliRot": qml.PauliRot(0.123, "Y", wires=0), "IsingXX": qml.IsingXX(0.123, wires=[0, 1]), "IsingXY": qml.IsingXY(0.123, wires=[0, 1]), "IsingYY": qml.IsingYY(0.123, wires=[0, 1]), "IsingZZ": qml.IsingZZ(0.123, wires=[0, 1]), "Identity": qml.Identity(wires=0), "Rot": qml.Rot(0.123, 0.456, 0.789, wires=0), "Toffoli": qml.Toffoli(wires=[0, 1, 2]), "PhaseShift": qml.PhaseShift(2.133, wires=0), "ControlledPhaseShift": qml.ControlledPhaseShift(1.777, wires=[0, 2]), "CPhase": qml.CPhase(1.777, wires=[0, 2]), "MultiRZ": qml.MultiRZ(0.112, wires=[1, 2, 3]), "CRX": qml.CRX(0.836, wires=[2, 3]), "CRY": qml.CRY(0.721, wires=[2, 3]), "CRZ": qml.CRZ(0.554, wires=[2, 3]), "Hadamard": qml.Hadamard(wires=0), "PauliX": qml.PauliX(wires=0), "PauliY": qml.PauliY(wires=0), "PauliZ": qml.PauliZ(wires=0), "CRot": qml.CRot(0.123, 0.456, 0.789, wires=[0, 1]), "DiagonalQubitUnitary": qml.DiagonalQubitUnitary(np.array([1.0, 1.0j]), wires=1), "ControlledQubitUnitary": qml.ControlledQubitUnitary( np.eye(2) * 1j, wires=[0], control_wires=[2] ), "MultiControlledX": qml.MultiControlledX(wires=(0, 1, 2), control_values="01"), "SingleExcitation": qml.SingleExcitation(0.123, wires=[0, 3]), "SingleExcitationPlus": qml.SingleExcitationPlus(0.123, wires=[0, 3]), "SingleExcitationMinus": qml.SingleExcitationMinus(0.123, wires=[0, 3]), "DoubleExcitation": qml.DoubleExcitation(0.123, wires=[0, 1, 2, 3]), "DoubleExcitationPlus": qml.DoubleExcitationPlus(0.123, wires=[0, 1, 2, 3]), "DoubleExcitationMinus": qml.DoubleExcitationMinus(0.123, wires=[0, 1, 2, 3]), "QFT": qml.QFT(wires=0), "QubitSum": qml.QubitSum(wires=[0, 1, 2]), "QubitCarry": qml.QubitCarry(wires=[0, 1, 2, 3]), "QubitUnitary": qml.QubitUnitary(np.eye(2) * 1j, wires=0), } return ops_list.get(op_name)
def test_four_qubit_random_circuit(self, device, tol): """Compare a four-qubit random circuit with lots of different gates to default.qubit""" n_wires = 4 dev = device(n_wires) dev_def = qml.device("default.qubit", wires=n_wires) if dev.name == dev_def.name: pytest.skip("Device is default.qubit.") if dev.shots is not None: pytest.skip("Device is in non-analytical mode.") gates = [ qml.PauliX(wires=0), qml.PauliY(wires=1), qml.PauliZ(wires=2), qml.S(wires=3), qml.T(wires=0), qml.RX(2.3, wires=1), qml.RY(1.3, wires=2), qml.RZ(3.3, wires=3), qml.Hadamard(wires=0), qml.Rot(0.1, 0.2, 0.3, wires=1), qml.CRot(0.1, 0.2, 0.3, wires=[2, 3]), qml.Toffoli(wires=[0, 1, 2]), qml.SWAP(wires=[1, 2]), qml.CSWAP(wires=[1, 2, 3]), qml.U1(1.0, wires=0), qml.U2(1.0, 2.0, wires=2), qml.U3(1.0, 2.0, 3.0, wires=3), qml.CRX(0.1, wires=[1, 2]), qml.CRY(0.2, wires=[2, 3]), qml.CRZ(0.3, wires=[3, 1]), ] layers = 3 np.random.seed(1967) gates_per_layers = [np.random.permutation(gates).numpy() for _ in range(layers)] def circuit(): """4-qubit circuit with layers of randomly selected gates and random connections for multi-qubit gates.""" np.random.seed(1967) for gates in gates_per_layers: for gate in gates: qml.apply(gate) return qml.expval(qml.PauliZ(0)) qnode_def = qml.QNode(circuit, dev_def) qnode = qml.QNode(circuit, dev) assert np.allclose(qnode(), qnode_def(), atol=tol(dev.shots))
def test_cry(self): """Test if the function correctly returns the derivative of CRY""" p = 0.3 op = qml.CRY(p, wires=[0, 1]) derivative = operation_derivative(op) expected_derivative = 0.5 * np.array([ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, -np.sin(p / 2), -np.cos(p / 2)], [0, 0, np.cos(p / 2), -np.sin(p / 2)], ]) assert np.allclose(derivative, expected_derivative)
def decomposition(theta, wires): decomp_ops = [ qml.PauliX(wires=wires[0]), qml.PauliX(wires=wires[1]), qml.ControlledPhaseShift(theta / 2, wires=[wires[1], wires[0]]), qml.PauliX(wires=wires[0]), qml.PauliX(wires=wires[1]), qml.ControlledPhaseShift(theta / 2, wires=[wires[0], wires[1]]), qml.CNOT(wires=[wires[0], wires[1]]), qml.CRY(theta, wires=[wires[1], wires[0]]), qml.CNOT(wires=[wires[0], wires[1]]), ] return decomp_ops