def test_adjoint_cv_ops(self, op, size, tol): op_d = op.adjoint() op_heis = op._heisenberg_rep(op.parameters) op_d_heis = op_d._heisenberg_rep(op_d.parameters) res1 = np.dot(op_heis, op_d_heis) res2 = np.dot(op_d_heis, op_heis) np_testing.assert_allclose(res1, np.eye(size), atol=tol) np_testing.assert_allclose(res2, np.eye(size), atol=tol) assert op.wires == op_d.wires
def cost(weights, phi, gamma, J, W, epsilon=1e-10): return np.trace( W @ np.linalg.inv( J.T @ CFIM(weights, phi, gamma) @ J + np.eye(2) * epsilon ) )
class TestHelperFunctions: """Tests for additional helper functions.""" one_qubit_vec1 = np.array([1, 1]) one_qubit_vec2 = np.array([1, 1j]) two_qubit_vec = np.array([1, 1, 1, -1]).reshape([2, 2]) single_qubit_obs1 = qml.PauliZ(0) single_qubit_obs2 = qml.PauliY(0) two_qubit_obs = qml.Hermitian(np.eye(4), wires=[0, 1]) @pytest.mark.parametrize( "wires, vec1, obs, vec2, expected", [ (1, one_qubit_vec1, single_qubit_obs1, one_qubit_vec1, 0), (1, one_qubit_vec2, single_qubit_obs1, one_qubit_vec2, 0), (1, one_qubit_vec1, single_qubit_obs1, one_qubit_vec2, 1 - 1j), (1, one_qubit_vec2, single_qubit_obs1, one_qubit_vec1, 1 + 1j), (1, one_qubit_vec1, single_qubit_obs2, one_qubit_vec1, 0), (1, one_qubit_vec2, single_qubit_obs2, one_qubit_vec2, 2), (1, one_qubit_vec1, single_qubit_obs2, one_qubit_vec2, 1 + 1j), (1, one_qubit_vec2, single_qubit_obs2, one_qubit_vec1, 1 - 1j), (2, two_qubit_vec, single_qubit_obs1, two_qubit_vec, 0), (2, two_qubit_vec, single_qubit_obs2, two_qubit_vec, 0), (2, two_qubit_vec, two_qubit_obs, two_qubit_vec, 4), ], ) def test_matrix_elem(self, wires, vec1, obs, vec2, expected): """Tests for the helper function _matrix_elem""" dev = qml.device("default.qubit", wires=wires) tape = ReversibleTape() res = tape._matrix_elem(vec1, obs, vec2, dev) assert res == expected
def diffusion_matrix(): # DO NOT MODIFY anything in this code block psi_piece = (1 / 2**4) * np.ones(2**4) ident_piece = np.eye(2**4) return 2 * psi_piece - ident_piece
def test_get_unitary_matrix_nonparam_1qubit_ops(op, wire): """Check the matrices for different nonparametrized single-qubit gates, which are acting on different qubits in a space of three qubits.""" wires = [0, 1, 2] def testcircuit(wire): op(wires=wire) get_matrix = get_unitary_matrix(testcircuit, wires) matrix = get_matrix(wire) if wire == 0: expected_matrix = np.kron(op(wires=wire).matrix, np.eye(4)) if wire == 1: expected_matrix = np.kron(np.eye(2), np.kron(op(wires=wire).matrix, np.eye(2))) if wire == 2: expected_matrix = np.kron(np.eye(4), op(wires=wire).matrix) assert np.allclose(matrix, expected_matrix)
class TestOperatorMatrices: """Tests that get_operator_matrix returns the correct matrix.""" @pytest.mark.parametrize("name,expected", [ ("PauliX", np.array([[0, 1], [1, 0]])), ("PauliY", np.array([[0, -1j], [1j, 0]])), ("PauliZ", np.array([[1, 0], [0, -1]])), ("Hadamard", np.array([[1, 1], [1, -1]])/np.sqrt(2)), ("CNOT", np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])), ("SWAP", np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])), ("CSWAP",np.array([[1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1]])), ("CZ", np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, -1]])), ]) def test_get_operator_matrix_no_parameters(self, qubit_device_3_wires, tol, name, expected): """Tests that get_operator_matrix returns the correct matrix.""" res = qubit_device_3_wires._get_operator_matrix(name, ()) assert np.allclose(res, expected, atol=tol, rtol=0) @pytest.mark.parametrize("name,expected,par", [ ('PhaseShift', lambda phi: np.array([[1, 0], [0, np.exp(1j*phi)]]), [0.223]), ('RX', lambda phi: np.array([[math.cos(phi/2), -1j*math.sin(phi/2)], [-1j*math.sin(phi/2), math.cos(phi/2)]]), [0.223]), ('RY', lambda phi: np.array([[math.cos(phi/2), -math.sin(phi/2)], [math.sin(phi/2), math.cos(phi/2)]]), [0.223]), ('RZ', lambda phi: np.array([[cmath.exp(-1j*phi/2), 0], [0, cmath.exp(1j*phi/2)]]), [0.223]), ('Rot', lambda phi, theta, omega: np.array([[cmath.exp(-1j*(phi+omega)/2)*math.cos(theta/2), -cmath.exp(1j*(phi-omega)/2)*math.sin(theta/2)], [cmath.exp(-1j*(phi-omega)/2)*math.sin(theta/2), cmath.exp(1j*(phi+omega)/2)*math.cos(theta/2)]]), [0.223, 0.153, 1.212]), ('CRX', lambda phi: np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, math.cos(phi/2), -1j*math.sin(phi/2)], [0, 0, -1j*math.sin(phi/2), math.cos(phi/2)]]), [0.223]), ('CRY', lambda phi: np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, math.cos(phi/2), -math.sin(phi/2)], [0, 0, math.sin(phi/2), math.cos(phi/2)]]), [0.223]), ('CRZ', lambda phi: np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, cmath.exp(-1j*phi/2), 0], [0, 0, 0, cmath.exp(1j*phi/2)]]), [0.223]), ('CRot', lambda phi, theta, omega: np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, cmath.exp(-1j*(phi+omega)/2)*math.cos(theta/2), -cmath.exp(1j*(phi-omega)/2)*math.sin(theta/2)], [0, 0, cmath.exp(-1j*(phi-omega)/2)*math.sin(theta/2), cmath.exp(1j*(phi+omega)/2)*math.cos(theta/2)]]), [0.223, 0.153, 1.212]), ('QubitUnitary', lambda U: np.asarray(U), [np.array([[0.83645892 - 0.40533293j, -0.20215326 + 0.30850569j], [-0.23889780 - 0.28101519j, -0.88031770 - 0.29832709j]])]), ('Hermitian', lambda H: np.asarray(H), [np.array([[1.02789352, 1.61296440 - 0.3498192j], [1.61296440 + 0.3498192j, 1.23920938 + 0j]])]), # Identity will always return a 2x2 Identity, but is still parameterized ('Identity', lambda n: np.eye(2), [2]) ]) def test_get_operator_matrix_with_parameters(self, qubit_device_2_wires, tol, name, expected, par): """Tests that get_operator_matrix returns the correct matrix building functions.""" res = qubit_device_2_wires._get_operator_matrix(name, par) assert np.allclose(res, expected(*par), atol=tol, rtol=0) @pytest.mark.parametrize("name", ["BasisState", "QubitStateVector"]) def test_get_operator_matrix_none(self, qubit_device_2_wires, name): """Tests that get_operator_matrix returns none for direct state manipulations.""" res = qubit_device_2_wires._get_operator_matrix(name, ()) assert res is None
class TestMethods: """Tests the independent methods in the Cirq interface.""" @pytest.mark.parametrize( "U,expected_cirq_operation", [ ( [[1, 0], [0, -1]], cirq.SingleQubitMatrixGate(np.array([[1, 0], [0, -1]])), ), ( [[0, 1j], [-1j, 0]], cirq.SingleQubitMatrixGate(np.array([[0, 1j], [-1j, 0]])), ), ( [[0, 1j, 0, 0], [-1j, 0, 0, 0], [0, 0, 0, 1j], [0, 0, -1j, 0]], cirq.TwoQubitMatrixGate( np.array([[0, 1j, 0, 0], [-1j, 0, 0, 0], [0, 0, 0, 1j], [0, 0, -1j, 0]])), ), ], ) def test_unitary_matrix_gate(self, U, expected_cirq_operation): """Tests that the correct Cirq operation is returned for the unitary matrix gate.""" assert unitary_matrix_gate(np.array(U)) == expected_cirq_operation @pytest.mark.parametrize( "U", [np.eye(6), np.eye(10), np.eye(3), np.eye(3, 5)]) def test_unitary_matrix_gate_error(self, U): """Tests that an error is raised if the given matrix is of wrong format.""" with pytest.raises( qml.DeviceError, match= "Cirq only supports single-qubit and two-qubit unitary matrix gates.", ): unitary_matrix_gate(np.array(U))
def test_supported_fock_expectations(self): """Test that all supported expectations work correctly""" self.logTestName() cutoff_dim = 10 a = 0.312 a_array = np.eye(3) dev = qml.device('strawberryfields.fock', wires=2, cutoff_dim=cutoff_dim) expectations = list(dev._observable_map.items()) for g, sfop in expectations: log.info('\tTesting expectation {}...'.format(g)) self.assertTrue(dev.supports_observable(g)) op = getattr(qml.ops, g) if op.num_wires <= 0: wires = [0] else: wires = list(range(op.num_wires)) @qml.qnode(dev) def circuit(*args): qml.Displacement(0.1, 0, wires=0) qml.TwoModeSqueezing(0.1, 0, wires=[0, 1]) return qml.expval(op(*args, wires=wires)) # compare to reference SF engine def SF_reference(*args): """SF reference circuit""" eng = sf.Engine("fock", backend_options={"cutoff_dim": cutoff_dim}) prog = sf.Program(2) with prog.context as q: sf.ops.Xgate(0.2) | q[0] sf.ops.S2gate(0.1) | q state = eng.run(prog).state return sfop(state, wires, args)[0] if op.num_params == 0: self.assertAllEqual(circuit(), SF_reference()) elif op.num_params == 1: if g == 'FockStateProjector': p = np.array([1]) else: p = a_array if op.par_domain == 'A' else a self.assertAllEqual(circuit(p), SF_reference(p))
def test_supported_gaussian_expectations(self): """Test that all supported expectations work correctly""" self.logTestName() a = 0.312 a_array = np.eye(3) dev = qml.device('strawberryfields.gaussian', wires=2) expectations = list(dev._expectation_map.items()) for g, sfop in expectations: log.info('\tTesting expectation {}...'.format(g)) self.assertTrue(dev.supported(g)) op = getattr(qml.expval, g) if op.num_wires == 0: wires = [0] else: wires = list(range(op.num_wires)) @qml.qnode(dev) def circuit(*x): qml.Displacement(0.1, 0, wires=0) qml.TwoModeSqueezing(0.1, 0, wires=[0, 1]) return op(*x, wires=wires) # compare to reference SF engine def SF_reference(*x): """SF reference circuit""" eng, q = sf.Engine(2) with eng: sf.ops.Xgate(0.2) | q[0] sf.ops.S2gate(0.1) | q state = eng.run('gaussian') return sfop(state, wires, x)[0] if op.num_params == 0: self.assertAllEqual(circuit(), SF_reference()) elif op.num_params == 1: if g == 'NumberState': p = np.array([1]) else: p = a_array if op.par_domain == 'A' else a self.assertAllEqual(circuit(p), SF_reference(p))
def triple_excitation_matrix(gamma): """The matrix representation of a triple-excitation Givens rotation. Args: - gamma (float): The angle of rotation Returns: - (np.ndarray): The matrix representation of a triple-excitation """ # QHACK # i, j = 7, 56 # index for |000111>, |111000> matrix = np.eye(2**6) # make matrix matrix[i, i] = np.cos(gamma / 2) matrix[j, j] = np.cos(gamma / 2) matrix[i, j] = -np.sin(gamma / 2) matrix[j, i] = np.sin(gamma / 2) return matrix
def oracle_matrix(indices): """Return the oracle matrix for a secret combination. Args: - indices (list(int)): A list of bit indices (e.g. [0,3]) representing the elements that are map to 1. Returns: - (np.ndarray): The matrix representation of the oracle """ # QHACK # my_array = np.eye(2**4) for i in indices: my_array[i, i] = -1 # QHACK # return my_array
def displace_matrix(K): r"""Remove negative eigenvalues from the given kernel matrix by adding a multiple of the identity matrix. This method keeps the eigenvectors of the matrix intact. Args: K (array[float]): Kernel matrix, assumed to be symmetric. Returns: array[float]: Kernel matrix with eigenvalues offset by adding the identity. **Example:** Consider a symmetric matrix with both positive and negative eigenvalues: .. code-block :: pycon >>> K = np.array([[0, 1, 0], [1, 0, 0], [0, 0, 2]]) >>> np.linalg.eigvalsh(K) array([-1., 1., 2.]) We then can shift all eigenvalues of the matrix by adding the identity matrix multiplied with the absolute value of the smallest (the most negative, that is) eigenvalue: .. code-block :: pycon >>> K_displaced = qml.kernels.displace_matrix(K) >>> np.linalg.eigvalsh(K_displaced) array([0., 2., 3.]) If the input matrix does not have negative eigenvalues, ``displace_matrix`` does not have any effect. """ wmin = np.linalg.eigvalsh(K)[0] if wmin < 0: return K - np.eye(K.shape[0]) * wmin return K
# # Let's see this method in action. # # Following [#banchi2020]_, we will use the cross-resonance gate as a # working example. This gate is defined as # # .. math:: # # \hat{U}_{CR}(\theta_1, \theta_2, \theta_3) # = \exp\left[ i(\theta_1\hat{X}\otimes\hat{\mathbf{1}} - # \theta_2\hat{Z}\otimes\hat{X} + # \theta_3\hat{\mathbf{1}}\otimes\hat{X} # ) \right]. # First we define some basic Pauli matrices I = np.eye(2) X = np.array([[0, 1], [1, 0]]) Z = np.array([[1, 0], [0, -1]]) def Generator(theta1, theta2, theta3): # the inputs will show up as Pennylane Variable objects, with theta1 being # wrapped in a np.ndarray; we have to extract their numerical values G = theta1.item().val * np.kron(X, I) - \ theta2.val * np.kron(Z, X) + \ theta3.val * np.kron(I, X) return G # A simple example circuit that contains the cross-resonance gate @qml.qnode(dev)
def one_hot(a: np.ndarray, num_classes: int) -> np.ndarray: return np.squeeze(np.eye(num_classes)[a.astype(int).reshape(-1)])
op.heisenberg_tr(Wires(range(op.num_wires))) label_data = [ (cv.Rotation(1.2345, wires=0), "R", "R\n(1.23)", "R⁻¹\n(1)"), (cv.Squeezing(1.234, 2.345, wires=0), "S", "S\n(1.23,\n2.35)", "S⁻¹\n(1,\n2)"), (cv.Displacement(1.234, 2.345, wires=0), "D", "D\n(1.23,\n2.35)", "D⁻¹\n(1,\n2)"), (cv.Beamsplitter(1.234, 2.345, wires=(0, 1)), "BS", "BS\n(1.23,\n2.35)", "BS⁻¹\n(1,\n2)"), (cv.TwoModeSqueezing(1.2345, 2.3456, wires=(0, 1)), "S", "S\n(1.23,\n2.35)", "S⁻¹\n(1,\n2)"), (cv.QuadraticPhase(1.2345, wires=0), "P", "P\n(1.23)", "P⁻¹\n(1)"), (cv.ControlledAddition(1.234, wires=(0, 1)), "X", "X\n(1.23)", "X⁻¹\n(1)"), (cv.ControlledPhase(1.2345, wires=(0, 1)), "Z", "Z\n(1.23)", "Z⁻¹\n(1)"), (cv.Kerr(1.234, wires=0), "Kerr", "Kerr\n(1.23)", "Kerr⁻¹\n(1)"), (cv.CrossKerr(1.234, wires=(0, 1)), "CrossKerr", "CrossKerr\n(1.23)", "CrossKerr⁻¹\n(1)"), (cv.CubicPhase(1.234, wires=0), "V", "V\n(1.23)", "V⁻¹\n(1)"), (cv.InterferometerUnitary(np.eye(2), wires=(0)), "U", "U", "U⁻¹"), (cv.ThermalState(1.234, wires=0), "Thermal", "Thermal\n(1.23)", "Thermal⁻¹\n(1)"), ( cv.GaussianState(np.array([[2, 0], [0, 2]]), np.array([1, 2]), wires=[1]), "Gaussian", "Gaussian", "Gaussian⁻¹", ), (cv.FockState(7, wires=0), "|7⟩", "|7⟩", "|7⟩"), (cv.FockStateVector([1, 2, 3], wires=(0, 1, 2)), "|123⟩", "|123⟩", "|123⟩"), (cv.NumberOperator(wires=0), "n", "n", None), (cv.TensorN(wires=(0, 1, 2)), "n⊗n⊗n", "n⊗n⊗n", None), (cv.QuadOperator(1.234, wires=0), "cos(φ)x\n+sin(φ)p", "cos(1.23)x\n+sin(1.23)p", None), (cv.FockStateProjector([1, 2, 3], wires=(0, 1, 2)), "|123⟩⟨123|", "|123⟩⟨123|", None), ]
# See the License for the specific language governing permissions and # limitations under the License. """ Tests for the ``adjoint_jacobian`` method of LightningQubit. """ import math import pytest import pennylane as qml from pennylane import numpy as np from pennylane import QNode, qnode from scipy.stats import unitary_group from pennylane_lightning import LightningQubit as lq I, X, Y, Z = ( np.eye(2), qml.PauliX.compute_matrix(), qml.PauliY.compute_matrix(), qml.PauliZ.compute_matrix(), ) def Rx(theta): r"""One-qubit rotation about the x axis. Args: theta (float): rotation angle Returns: array: unitary 2x2 rotation matrix :math:`e^{-i \sigma_x \theta/2}` """ return math.cos(theta / 2) * I + 1j * math.sin(-theta / 2) * X
import pennylane as qml from pennylane import numpy as np pytestmark = pytest.mark.skip_unsupported # ========================================================== # Some useful global variables # observables for which device support is tested obs = { "Identity": qml.Identity(wires=[0]), "Hadamard": qml.Hadamard(wires=[0]), "Hermitian": qml.Hermitian(np.eye(2), wires=[0]), "PauliX": qml.PauliX(wires=[0]), "PauliY": qml.PauliY(wires=[0]), "PauliZ": qml.PauliZ(wires=[0]), "Projector": qml.Projector(np.array([1]), wires=[0]), "SparseHamiltonian": qml.SparseHamiltonian(coo_matrix(np.eye(8)), wires=[0, 1, 2]), "Hamiltonian": qml.Hamiltonian([1, 1], [qml.PauliZ(0), qml.PauliX(0)]), } all_obs = obs.keys()
broadcast(unitary=Rotation, pattern="single", wires=wires, parameters=list(phi_rot)) Interferometer(U2, wires=wires) return [expval(X(i)) for i in range(M)] # Test out difference between CV neural network convolution and the theoretical convolution value. # In[5]: F = np.fft.fft(np.eye(M)) / (np.sqrt(M)) F_H = F.conj().T # random values to transform x = np.random.random(M) phi_x = np.zeros(M) phi_r = np.zeros(M) np.random.seed(1) # initialize some random vals for the periodic convolution init = np.random.uniform(low=-1, high=1, size=(2)) c = np.zeros(M) c[0] = init[0] c[1] = init[1]
# In[ ]: from sympy.physics.quantum import TensorProduct as tensor from pennylane import numpy as np import pennylane as qml from sklearn.preprocessing import normalize import sys import time I = np.array([[1., 0.], [0., 1.]]) zero = np.array([[1., 0.], [0., 0.]]) one = np.array([[0., 0.], [0., 1.]]) X = np.array([[0., 1.], [1., 0.]]) I_2 = np.eye(4) I_3 = np.eye(8) I_4 = np.eye(16) I_5 = np.eye(32) I_6 = np.eye(64) # T1 conditional on 1,1 - acts on qubits 1,2 and flips 8 U_T11 = tensor(zero, tensor(zero, I_6)) + tensor(zero, tensor( one, I_6)) + tensor(one, tensor(zero, I_6)) + tensor( one, tensor(one, tensor(I_5, X))) # T2 conditional on 1,0 - acts on qubits 1,2 and flips 8 U_T21 = tensor(zero, tensor(zero, I_6)) + tensor(zero, tensor( one, I_6)) + tensor(one, tensor(zero, tensor(I_5, X))) + tensor( one, tensor(one, I_6)) # T3 conditional on 0,1 - acts on qubits 1,2 and flips 8