def test_error_qubit_statevector(self): """Test that an error is raised for a statevector preparation with invert=True.""" state = np.array([0.4, 1.2 - 0.2j, 9.5, -0.3 + 1.1j]) state = np.array([0.4, 1.2 - 0.2j, 9.5, -0.3 + 1.1j]) state /= np.linalg.norm(state, ord=2) op = qml.QubitStateVector(state, wires=self.device.wires) with pytest.raises(ValueError, match="Can't invert state preparation."): _apply_operations(None, op, self.device, invert=True)
def test_simple_operation_autograd(self, invert): """Test differentiability for a simple operation with Autograd.""" device = qml.device("default.qubit.autograd", wires=2) x = np.array(self.x, requires_grad=True) r_fn = lambda x: qml.math.real( _apply_operations(device._state, qml.RX(x, wires=0), device, invert )) i_fn = lambda x: qml.math.imag( _apply_operations(device._state, qml.RX(x, wires=0), device, invert )) out = qml.jacobian(r_fn)(x) + 1j * qml.jacobian(i_fn)(x) exp = (np.array([[-np.sin(self.x / 2), 0.0], [-1j * (-1)**invert * np.cos(self.x / 2), 0.0]]) / 2) assert np.allclose(out, exp)
def test_simple_operation_jax(self, invert): """Test differentiability for a simple operation with JAX.""" jax = pytest.importorskip("jax") device = qml.device("default.qubit.jax", wires=2) x = jax.numpy.array(self.x) r_fn = lambda x: qml.math.real( _apply_operations(device._state, qml.RX(x, wires=0), device, invert )) i_fn = lambda x: qml.math.imag( _apply_operations(device._state, qml.RX(x, wires=0), device, invert )) out = jax.jacobian(r_fn)(x) + 1j * jax.jacobian(i_fn)(x) exp = (np.array([[-np.sin(self.x / 2), 0.0], [-1j * (-1)**invert * np.cos(self.x / 2), 0.0]]) / 2) assert np.allclose(out, exp)
def test_simple_operation_torch(self, invert): """Test differentiability for a simple operation with Torch.""" torch = pytest.importorskip("torch") jac_fn = torch.autograd.functional.jacobian device = qml.device("default.qubit.torch", wires=2) x = torch.tensor(self.x, requires_grad=True) r_fn = lambda x: qml.math.real( _apply_operations(device._state, qml.RX(x, wires=0), device, invert )) i_fn = lambda x: qml.math.imag( _apply_operations(device._state, qml.RX(x, wires=0), device, invert )) out = jac_fn(r_fn, x) + 1j * jac_fn(i_fn, x) exp = (np.array([[-np.sin(self.x / 2), 0.0], [-1j * (-1)**invert * np.cos(self.x / 2), 0.0]]) / 2) assert np.allclose(out, exp)
def test_basisstate(self): """Test that a basis state preparation is applied correctly.""" op = qml.BasisState(np.array([1, 0]), wires=self.device.wires) out = _apply_operations(None, op, self.device, invert=False) out = qml.math.reshape(out, 4) exp = np.array([0.0, 0.0, 1.0, 0.0]) assert np.allclose(out, exp)
def test_qubit_statevector(self): """Test that a statevector preparation is applied correctly.""" state = np.array([0.4, 1.2 - 0.2j, 9.5, -0.3 + 1.1j]) state /= np.linalg.norm(state, ord=2) op = qml.QubitStateVector(state, wires=self.device.wires) out = _apply_operations(None, op, self.device, invert=False) out = qml.math.reshape(out, 4) assert np.allclose(out, state)
def test_inv_operation(self): """Test that an operation with inverse=True is applied correctly but does not alter the operation (in particular its inverse flag) that is used.""" op = qml.RX(self.x, wires=0).inv() out = _apply_operations(self.device._state, op, self.device) out = qml.math.reshape(out, 4) exp = np.array([np.cos(self.x / 2), 0.0, 1j * np.sin(self.x / 2), 0.0]) assert np.allclose(out, exp) assert op.inverse
def test_simple_operation(self): """Test that an operation is applied correctly.""" op = qml.RX(self.x, wires=0) out = _apply_operations(self.device._state, op, self.device) out = qml.math.reshape(out, 4) exp = np.array( [np.cos(self.x / 2), 0.0, -1j * np.sin(self.x / 2), 0.0]) assert np.allclose(out, exp) assert not op.inverse
def test_simple_operation_tf(self, invert): """Test differentiability for a simple operation with TensorFlow.""" tf = pytest.importorskip("tensorflow") device = qml.device("default.qubit.tf", wires=2) x = tf.Variable(self.x, dtype=tf.float64) r_fn = lambda x: qml.math.real( _apply_operations(device._state, qml.RX(x, wires=0), device, invert )) i_fn = lambda x: qml.math.imag( _apply_operations(device._state, qml.RX(x, wires=0), device, invert )) with tf.GradientTape(persistent=True) as tape: r_state = r_fn(x) i_state = i_fn(x) out = qml.math.complex(tape.jacobian(r_state, x), tape.jacobian(i_state, x)) exp = (np.array([[-np.sin(self.x / 2), 0.0], [-1j * (-1)**invert * np.cos(self.x / 2), 0.0]]) / 2) assert np.allclose(out, exp)
def test_operation_group(self): """Test that a group of operations with is applied correctly but does not alter the operations (in particular their order and inverse flags) that are used.""" op = [ qml.RX(self.x, wires=0).inv(), qml.Hadamard(wires=1), qml.CNOT(wires=[1, 0]) ] out = _apply_operations(self.device._state, op, self.device) out = qml.math.reshape(out, 4) exp = np.array([ np.cos(self.x / 2) / np.sqrt(2), 1j * np.sin(self.x / 2) / np.sqrt(2), 1j * np.sin(self.x / 2) / np.sqrt(2), np.cos(self.x / 2) / np.sqrt(2), ]) assert np.allclose(out, exp) assert isinstance(op[0], qml.RX) and op[0].inverse assert isinstance(op[1], qml.Hadamard) and not op[1].inverse assert isinstance(op[2], qml.CNOT) and not op[2].inverse
def test_error_basisstate(self): """Test that an error is raised for a basis state preparation with invert=True.""" op = qml.BasisState(np.array([1, 0]), wires=self.device.wires) with pytest.raises(ValueError, match="Can't invert state preparation."): _apply_operations(None, op, self.device, invert=True)