def test_compare_returnc_interp1d_unc(interp_inputs):
    # Compare the uncertainties computed from the sensitivities inside the
    # interpolation range and directly.
    uy_new_with_sensitivities = interp1d_unc(**interp_inputs)[2]
    interp_inputs["returnC"] = False
    uy_new_without_sensitivities = interp1d_unc(**interp_inputs)[2]
    # Check that extrapolation results match up to machine epsilon.
    assert_allclose(uy_new_with_sensitivities,
                    uy_new_without_sensitivities,
                    rtol=9e-15)
def interpolate_hyd(hyd_data, f):
    # Interpolation and extrapolation of calibration data
    hyd_interpolated = {"frequency": f}
    N = len(f) // 2
    # interpolate real part in selected frequency range
    (
        hyd_interpolated["frequency"],
        hyd_interpolated["real"],
        hyd_interpolated["varreal"],
        Creal,
    ) = interp1d_unc(
        f[:N],
        hyd_data["frequency"],
        hyd_data["real"],
        hyd_data["varreal"],
        bounds_error=False,
        fill_value="extrapolate",
        fill_unc="extrapolate",
        returnC=True,
    )

    # interpolate imag part in selected frequency range
    hyd_interpolated["imag"] = np.zeros((N, ))
    hyd_interpolated["varimag"] = np.zeros((N, ))
    (
        hyd_interpolated["frequency"],
        hyd_interpolated["imag"],
        hyd_interpolated["varimag"],
        Cimag,
    ) = interp1d_unc(
        f[:N],
        hyd_data["frequency"],
        hyd_data["imag"],
        hyd_data["varimag"],
        bounds_error=False,
        fill_value="extrapolate",
        fill_unc="extrapolate",
        returnC=True,
    )
    # adjustment of end points
    hyd_interpolated["imag"][0] = 0  # Must be 0 by definition
    hyd_interpolated["imag"][-1] = 0
    hyd_interpolated["varimag"][0] = 0  # Must be 0 by definition
    hyd_interpolated["varimag"][-1] = 0

    ## Use pseudo-interpolation for the covariances between real and imaginary parts
    hyd_interpolated["cov"] = (Creal.dot(np.diag(hyd_data["cov"]))).dot(
        Cimag.T)
    return hyd_interpolated
def test_extrapolate_above_with_fill_value_interp1d_unc(interp_inputs):
    # Deal with those cases where at least one of t_new is above the maximum of t and
    # fill_value is a float, which means constant extrapolation with this value.
    y_new = interp1d_unc(**interp_inputs)[1]
    # Check that extrapolation works.
    assert np.all(y_new[interp_inputs["t_new"] > np.max(interp_inputs["t"])] ==
                  interp_inputs["fill_value"])
def test_extrapolate_below_with_fill_uncs_interp1d_unc(interp_inputs):
    # Deal with those cases where at least one of t_new is below the minimum of t and
    # fill_unc is a tuple, which means constant extrapolation with its first element.
    uy_new = interp1d_unc(**interp_inputs)[2]
    # Check that extrapolation works.
    assert np.all(uy_new[interp_inputs["t_new"] < np.min(interp_inputs["t"])]
                  == interp_inputs["fill_unc"][0])
def test_returnc_with_extrapolation_check_c_interp1d_unc(interp_inputs, ):
    # Check if sensitivity computation parallel to linear interpolation and
    # extrapolation with constant values works as expected regarding the shape and
    # content of the sensitivity matrix.
    C = interp1d_unc(**interp_inputs)[3]

    # Check that C has the right shape.
    assert C.shape == (len(interp_inputs["t_new"]), len(interp_inputs["t"]))

    # Find interpolation range because we reuse it.
    interp_range = (interp_inputs["t_new"] >= np.min(interp_inputs["t"])) | (
        interp_inputs["t_new"] <= np.max(interp_inputs["t"]))

    # Check if each row corresponding to an extrapolated value contains exactly one
    # non-zero sensitivity.
    assert np.all(np.count_nonzero(C[np.where(~interp_range)], 1) == 1)

    # Check if each row corresponding to an interpolated value contains either exactly
    # one or exactly two non-zero sensitivities, which are the two possible cases
    # when performing Lagrangian linear interpolation.
    assert np.all(
        np.any(
            (
                np.count_nonzero(C[np.where(interp_range)], 1) == 2,
                np.count_nonzero(C[np.where(interp_range)], 1) == 1,
            ),
            0,
        ))

    # Check if each row of sensitivities sum to one, which should hold for the
    # Lagrangians and proves equality with one for extrapolation sensitivities.
    assert_allclose(np.sum(C, 1), np.ones_like(interp_inputs["t_new"]))
Beispiel #6
0
def test_extrapolate_below_with_fill_unc_interp1d_unc(interp_inputs):
    # Deal with those cases where at least one of x_new is below the minimum of x and
    # fill_unc is a float, which means constant extrapolation with this value.
    uy_new = interp1d_unc(**interp_inputs)[2]
    # Check that extrapolation works.
    assert np.all(uy_new[interp_inputs["x_new"] < np.min(interp_inputs["x"])]
                  == interp_inputs["fill_unc"])
def test_extrapolate_above_with_fill_uncs_interp1d_unc(interp_inputs):
    # Deal with those cases where at least one of t_new is above the maximum of t and
    # fill_unc is a tuple, which means constant extrapolation with its second element.
    uy_new = interp1d_unc(**interp_inputs)[2]
    # Check that extrapolation works.
    assert np.all(uy_new[interp_inputs["t_new"] > np.max(interp_inputs["t"])]
                  == interp_inputs["fill_unc"][1])
def test_extrapolate_below_without_fill_value_interp1d_unc(interp_inputs):
    # Deal with those cases where at least one of t_new is below the minimum of t and
    # fill_value=="extrapolate", which means constant extrapolation from the boundaries.
    y_new = interp1d_unc(**interp_inputs)[1]
    # Check that extrapolation works, meaning in the present case, that the boundary
    # value of y is taken for all t_new below the original bound.
    assert np.all(y_new[interp_inputs["t_new"] < np.min(interp_inputs["t"])] ==
                  interp_inputs["y"][0])
def test_extrapolate_above_without_fill_unc_interp1d_unc(interp_inputs):
    # Deal with those cases where at least one of t_new is above the maximum of t and
    # fill_unc=="extrapolate", which means constant extrapolation from the boundaries.
    uy_new = interp1d_unc(**interp_inputs)[2]
    # Check that extrapolation works, meaning in the present case, that the boundary
    # value of y is taken for all t_new above the original bound.
    assert np.all(uy_new[interp_inputs["t_new"] > np.max(interp_inputs["t"])]
                  == interp_inputs["uy"][-1])
def test_returnc_with_extrapolation_check_below_bound_interp1d_unc(
        interp_inputs):
    # Check if extrapolation with constant values outside interpolation range and
    # returning sensitivities work as expected regarding extrapolation values
    # below original bound.
    uy_new, C = interp1d_unc(**interp_inputs)[2:]
    assert np.all(uy_new[interp_inputs["t_new"] < np.min(interp_inputs["t"])]
                  == interp_inputs["uy"][0])
def test_returnc_with_extrapolation_check_uy_new_above_bound_interp1d_unc(
    interp_inputs, ):
    # Check if extrapolation with constant values outside interpolation range and
    # returning sensitivities work as expected regarding extrapolation values
    # above original bound.
    uy_new = interp1d_unc(**interp_inputs)[2]
    assert np.all(uy_new[interp_inputs["t_new"] > np.max(interp_inputs["t"])]
                  == interp_inputs["uy"][-1])
Beispiel #12
0
def test_extrapolate_below_with_fill_values_interp1d_unc(interp_inputs):
    # Deal with those cases where at least one of x_new is below the minimum of x and
    # fill_value is a tuple, which means constant extrapolation with its first
    # element.
    y_new = interp1d_unc(**interp_inputs)[1]
    # Check that extrapolation works.
    assert np.all(y_new[interp_inputs["x_new"] < np.min(interp_inputs["x"])] ==
                  interp_inputs["fill_value"][0])
def test_linear_uy_in_interp1d_unc(n, ):
    # Check for given input, if interpolated uncertainties equal 1 and
    # :math:`sqrt(2) / 2`.
    dt_unit = 2
    dt_half = dt_unit / 2
    t_new = np.arange(0, n, dt_half)
    t_unit = np.arange(0, n + dt_half, dt_unit)
    y = uy_unit = np.ones_like(t_unit)
    uy_new = interp1d_unc(t_new, t_unit, y, uy_unit, "linear")[2]
    assert np.all(uy_new[0:n:dt_unit] == 1) and np.all(
        uy_new[1:n:dt_unit] == np.sqrt(2) / 2)
def test_wrong_input_lengths_call_interp1d(interp_inputs):
    # Check erroneous calls with unequally long inputs.
    with raises(ValueError):
        interp_inputs["uy"] = np.tile(interp_inputs["uy"], 2)
        interp1d_unc(**interp_inputs)
def test_value_error_for_returnc_interp1d_unc(interp_inputs):
    # Check erroneous calls with returnC and wrong kind.
    with raises(NotImplementedError):
        interp1d_unc(**interp_inputs)
def test_usual_call_interp1d_unc(interp_inputs):
    t_new, y_new, uy_new = interp1d_unc(**interp_inputs)[:]
    # Check the equal dimensions of the minimum calls output.
    assert len(t_new) == len(y_new) == len(uy_new)
def test_returnc_with_extrapolation_interp1d_unc(interp_inputs):
    # Check if extrapolation with constant values outside interpolation range and
    # returning of sensitivities is callable.
    assert interp1d_unc(**interp_inputs)
def test_failing_returnc_with_extrapolation_interp1d_unc(interp_inputs):
    # Since we have not implemented these cases, for now we
    # check for exception being thrown.
    assume(not isinstance(interp_inputs["fill_unc"], str))
    with raises(NotImplementedError):
        interp1d_unc(**interp_inputs)
def test_trivial_in_interp1d_unc(interp_inputs):
    y_new, uy_new = interp1d_unc(**interp_inputs)[1:3]
    # Check if all 'interpolated' values are present in the actual values.
    assert np.all(np.isin(y_new, interp_inputs["y"]))
    assert np.all(np.isin(uy_new, interp_inputs["uy"]))
def test_raise_not_implemented_yet_interp1d(interp_inputs):
    # Check that not implemented versions raise exceptions.
    with raises(NotImplementedError):
        interp1d_unc(**interp_inputs)
def test_linear_in_interp1d_unc(interp_inputs):
    y_new, uy_new = interp1d_unc(**interp_inputs)[1:3]
    # Check if all interpolated values lie in the range of the original values.
    assert np.all(np.min(interp_inputs["y"]) <= y_new)
    assert np.all(np.max(interp_inputs["y"]) >= y_new)
def test_extrapolate_interp1d_unc(interp_inputs):
    # Check that extrapolation is executable in general.
    assert interp1d_unc(**interp_inputs)
def test_raise_value_error_interp1d_unc(interp_inputs):
    # Check that interpolation with points outside the original domain raises
    # exception if requested.
    interp_inputs["bounds_error"] = True
    with raises(ValueError):
        interp1d_unc(**interp_inputs)
import matplotlib.pyplot as plt
import numpy as np
from PyDynamic.uncertainty.interpolate import interp1d_unc
from scipy.interpolate import interp1d

# base signal
N = 10
t = np.cumsum(0.5 * (1 + np.random.random(N)))
x = np.sin(t)  # + 0.01*np.random.randn(N)
# ut = np.full_like(t, 0.05)
ux = np.full_like(x, 0.2)

# interpolate with PyDynamic
ti = np.linspace(np.min(t), np.max(t), 60)
# uti = np.full_like(ti, 0.05)
ti, xi, uxi = interp1d_unc(ti, t, x, ux, kind="cubic")

# interpolate with Monte Carlo
X_mc = []
for i in range(2000):
    interp_x = interp1d(t, x + ux * np.random.randn(len(x)), kind="cubic")
    xm = interp_x(ti)
    X_mc.append(xm)
x_mc = np.mean(X_mc, axis=0)
ux_mc = np.std(X_mc, axis=0)

# visualize
# interpolated signal
plt.plot(ti, xi, "-or", label="interpolation PyDynamic")
plt.fill_between(ti, xi + uxi, xi - uxi, color="r", alpha=0.3)
# interpolated signal