def test_ill_conditioned(self): """Test that a warning is raised for an ill-conditioned matrix in the Fourier trafo.""" shifts = [ -np.pi / 2 - 1e-9, -np.pi / 2, 0, np.pi / 2, np.pi / 2 + 1e-9 ] with pytest.warns(UserWarning, match="condition number of the Fourier"): _reconstruct_gen(dummy_qnode, spectrum=[1.0, 2.0], shifts=shifts)
def test_with_classical_fun(self, fun, spectrum, mocker): """Test that arbitrary-frequency classical functions are reconstructed correctly.""" Fun = Lambda(fun) spy = mocker.spy(Fun, "fun") rec = _reconstruct_gen(Fun, spectrum) assert spy.call_count == len([f for f in spectrum if f > 0.0]) * 2 + 1 assert fun_close(fun, rec) # Repeat, using precomputed f0 f0 = fun(0.0) Fun = Lambda(fun) spy = mocker.spy(Fun, "fun") rec = _reconstruct_gen(Fun, spectrum, f0=f0) assert spy.call_count == len([f for f in spectrum if f > 0.0]) * 2 assert fun_close(fun, rec)
def test_differentiability_autograd(self, fun, spectrum, expected_grad): """Test that the reconstruction of equidistant-frequency classical functions are differentiable for Autograd input variables.""" # Convert fun to have integer frequencies rec = _reconstruct_gen(fun, spectrum, interface="autograd") grad = qml.grad(rec) assert fun_close(fun, rec, zero=pnp.array(0.0, requires_grad=True)) assert fun_close(expected_grad, grad, zero=pnp.array(0.0, requires_grad=True))
def test_with_classical_fun_spectrum_overcomplete(self, fun, spectrum, mocker): """Test that arbitrary-frequency classical functions are reconstructed correctly if spectrum contains additional frequencies.""" spectrum = spectrum + [0.4812759, 1.2281] Fun = Lambda(fun) spy = mocker.spy(Fun, "fun") # Convert fun to have integer frequencies rec = _reconstruct_gen(Fun, spectrum) assert spy.call_count == len([f for f in spectrum if f > 0.0]) * 2 + 1 assert fun_close(fun, rec)
def test_differentiability_jax(self, fun, spectrum, expected_grad): """Test that the reconstruction of equidistant-frequency classical functions are differentiable for JAX input variables.""" jax = pytest.importorskip("jax") from jax.config import config config.update("jax_enable_x64", True) # Convert fun to have integer frequencies rec = _reconstruct_gen(fun, spectrum, interface="jax") grad = jax.grad(rec) assert fun_close(fun, rec, zero=jax.numpy.array(0.0)) assert fun_close(expected_grad, grad, zero=jax.numpy.array(0.0))
def test_with_classical_fun_spectrum_incomplete(self, fun, spectrum, mocker): """Test that arbitrary-frequency classical functions are reconstructed wrongly if spectrum does not contain all frequencies.""" if len(spectrum) <= 1: pytest.skip("Can't skip a frequency if len(spectrum)<=1.") spectrum = spectrum[:-1] Fun = Lambda(fun) spy = mocker.spy(Fun, "fun") rec = _reconstruct_gen(Fun, spectrum) assert spy.call_count == len([f for f in spectrum if f > 0.0]) * 2 + 1 assert not fun_close(fun, rec)
def test_differentiability_torch(self, fun, spectrum, expected_grad): """Test that the reconstruction of equidistant-frequency classical functions are differentiable for Torch input variables.""" torch = pytest.importorskip("torch") spectrum = torch.tensor(spectrum, dtype=torch.float64) # Convert fun to have integer frequencies rec = _reconstruct_gen(fun, spectrum, interface="torch") grad = lambda x: torch.autograd.functional.jacobian(rec, x) assert fun_close(fun, rec, zero=torch.tensor(np.float64(0.0), requires_grad=True)) assert fun_close( expected_grad, grad, zero=torch.tensor(np.float64(0.0), requires_grad=True) )
def test_with_classical_fun_with_shifts(self, fun, spectrum, shifts, mocker, recwarn): """Test that arbitrary-frequency classical functions are reconstructed correctly.""" Fun = Lambda(fun) spy = mocker.spy(Fun, "fun") rec = _reconstruct_gen(Fun, spectrum, shifts=shifts) assert spy.call_count == len([f for f in spectrum if f > 0.0]) * 2 + 1 assert fun_close(fun, rec) # Repeat, using precomputed f0 f0 = fun(0.0) Fun = Lambda(fun) spy = mocker.spy(Fun, "fun") rec = _reconstruct_gen(Fun, spectrum, shifts=shifts, f0=f0) if 0.0 in shifts: assert spy.call_count == len([f for f in spectrum if f > 0.0]) * 2 else: assert len(recwarn) == 1 assert recwarn[0].category == UserWarning assert recwarn[0].message.args[0].startswith("The provided value") assert fun_close(fun, rec)
def test_with_qnode(self, scales, mocker): """Test that arbitrary-frequency qnodes are reconstructed correctly.""" circuit = get_RX_circuit(scales) Fun = Lambda(circuit) spy = mocker.spy(Fun, "fun") if len(scales) == 1: spectrum = sorted({0.0, scales[0]}) else: _spectra = [{0.0, s} for s in scales] spectrum = sorted(reduce(join_spectra, _spectra, {0.0})) rec = _reconstruct_gen(Fun, spectrum) assert spy.call_count == len([f for f in spectrum if f > 0.0]) * 2 + 1 assert fun_close(circuit, rec) # Repeat, using precomputed f0 f0 = circuit(0.0) Fun = Lambda(circuit) spy = mocker.spy(Fun, "fun") rec = _reconstruct_gen(Fun, spectrum, f0=f0) assert spy.call_count == len([f for f in spectrum if f > 0.0]) * 2 assert fun_close(circuit, rec)
def test_differentiability_tensorflow(self, fun, spectrum, expected_grad): """Test that the reconstruction of equidistant-frequency classical functions are differentiable for TensorFlow input variables.""" tf = pytest.importorskip("tensorflow") spectrum = tf.constant(spectrum, dtype=tf.float64) # Convert fun to have integer frequencies rec = _reconstruct_gen(fun, spectrum, interface="tensorflow") def grad(arg): arg = tf.Variable(arg) with tf.GradientTape() as tape: out = rec(arg) return tape.gradient(out, arg) assert fun_close(fun, rec, zero=tf.Variable(0.0)) assert fun_close(expected_grad, grad, zero=tf.Variable(0.0))