Пример #1
0
def test_MC(visualizeOutput=False):
    # run method
    y, Uy = MC(x, sigma_noise, b1, [1.0], Ub, runs=runs, blow=b2)

    assert len(y) == len(x)
    assert Uy.shape == (x.size, x.size)

    if visualizeOutput:
        # visualize input and mean of system response
        plt.plot(time, x)
        plt.plot(time, y)

        # visualize uncertainty of output
        plt.plot(time,
                 y - np.sqrt(np.diag(Uy)),
                 linestyle="--",
                 linewidth=1,
                 color="red")
        plt.plot(time,
                 y + np.sqrt(np.diag(Uy)),
                 linestyle="--",
                 linewidth=1,
                 color="red")

        plt.show()
Пример #2
0
def test_fir_filter_MC_comparison():
    N_signal = np.random.randint(20, 25)
    x = random_array(N_signal)
    Ux = random_covariance_matrix(N_signal)

    N_theta = np.random.randint(2, 5)  # scipy.linalg.companion requires N >= 2
    theta = random_array(N_theta)  # scipy.signal.firwin(N_theta, 0.1)
    Utheta = random_covariance_matrix(N_theta)

    # run method
    y_fir, Uy_fir = _fir_filter(x, theta, Ux, Utheta, initial_conditions="zero")

    # run FIR with MC and extract diagonal of returned covariance
    y_mc, Uy_mc = MC(x, Ux, theta, np.ones(1), Utheta, blow=None, runs=10000)

    # HACK: for visualization during debugging
    # from PyDynamic.misc.tools import plot_vectors_and_covariances_comparison
    # plot_vectors_and_covariances_comparison(
    #     vector_1=y_fir,
    #     vector_2=y_mc,
    #     covariance_1=Uy_fir,
    #     covariance_2=Uy_mc,
    #     label_1="fir",
    #     label_2="mc",
    #     title=f"filter: {len(theta)}, signal: {len(x)}",
    # )
    # /HACK
    assert_allclose(y_fir, y_mc, atol=1e-1, rtol=1e-1)
    assert_allclose(Uy_fir, Uy_mc, atol=1e-1, rtol=1e-1)
Пример #3
0
def _conduct_FIRuncFilter_and_MonteCarlo(Ub, b1, blow, kind, runs, sigma_noise,
                                         x):
    y, Uy = FIRuncFilter(x, sigma_noise, b1, Ub, blow=blow,
                         kind=kind)  # apply uncertain FIR filter (GUM formula)
    yMC, UyMC = MC(x, sigma_noise, b1, np.ones(1), Ub, runs=runs,
                   blow=blow)  # apply uncertain FIR filter (Monte Carlo)
    return Uy, UyMC, y, yMC
Пример #4
0
def test_FIRuncFilter_MC_uncertainty_comparison(filters, signals, lowpasses):
    # Check output for thinkable permutations of input parameters against a Monte Carlo approach.

    # run method
    y_fir, Uy_fir = FIRuncFilter(**filters,
                                 **signals,
                                 **lowpasses,
                                 return_full_covariance=True)

    # run Monte Carlo simulation of an FIR
    ## adjust input to match conventions of MC
    x = signals["y"]
    ux = signals["sigma_noise"]

    b = filters["theta"]
    a = [1.0]
    if isinstance(filters["Utheta"], np.ndarray):
        Uab = filters["Utheta"]
    else:  # Utheta == None
        Uab = np.zeros(
            (len(b), len(b)))  # MC-method cant deal with Utheta = None

    blow = lowpasses["blow"]
    if isinstance(blow, np.ndarray):
        n_blow = len(blow)
    else:
        n_blow = 0

    ## run FIR with MC and extract diagonal of returned covariance
    y_mc, Uy_mc = MC(x, ux, b, a, Uab, blow=blow, runs=2000)

    # HACK for visualization during debugging
    # import matplotlib.pyplot as plt
    # fig, ax = plt.subplots(nrows=1, ncols=3)
    # ax[0].plot(y_fir, label="fir")
    # ax[0].plot(y_mc, label="mc")
    # ax[0].set_title("filter: {0}, signal: {1}".format(len(b), len(x)))
    # ax[0].legend()
    # ax[1].imshow(Uy_fir)
    # ax[1].set_title("FIR")
    # ax[2].imshow(Uy_mc)
    # ax[2].set_title("MC")
    # plt.show()
    # /HACK

    # check basic properties
    assert np.all(np.diag(Uy_fir) >= 0)
    assert np.all(np.diag(Uy_mc) >= 0)
    assert Uy_fir.shape == Uy_mc.shape

    # approximative comparison after swing-in of MC-result
    # (which is after the combined length of blow and b)
    assert np.allclose(
        Uy_fir[len(b) + n_blow:, len(b) + n_blow:],
        Uy_mc[len(b) + n_blow:, len(b) + n_blow:],
        atol=2e-1 *
        Uy_fir.max(),  # very broad check, increase runs for better fit
        rtol=1e-1,
    )
def test_compare_MC_UMC():

    np.random.seed(12345)

    y_MC, Uy_MC = MC(x,sigma_noise,b1,[1.0],Ub,runs=2*runs,blow=b2)
    y_UMC, Uy_UMC, _, _, _ = UMC(x, b1, [1.0], Ub, blow=b2, sigma=sigma_noise, runs=2*runs, runs_init=10)

    # both methods should yield roughly the same results
    assert np.allclose(y_MC, y_UMC, atol=5e-4)
    assert np.allclose(Uy_MC, Uy_UMC, atol=5e-4)
Пример #6
0
    def apply_filter(self,
                     b,
                     a=1,
                     filter_uncertainty=None,
                     MonteCarloRuns=None):
        """Apply digital filter (b,a) to the signal values and propagate the uncertainty associated with the signal
		Parameters
		----------
			b: np.ndarray
				filter numerator coefficients
			a: np.ndarray
				filter denominator coefficients, use a=1 for FIR-type filter
			filter_uncertainty: np.ndarray
				covariance matrix associated with filter coefficients, Uab=None if no uncertainty associated with filter
			MonteCarloRuns: int
				number of Monte Carlo runs, if `None` then GUM linearization will be used
		Returns
		-------
			no return variables
		"""
        if isinstance(a, list):
            a = np.array(a)
        if not (isinstance(a, np.ndarray)):  # FIR type filter
            if len(self.uncertainty.shape) == 1:
                if not isinstance(MonteCarloRuns, int):
                    self.values, self.uncertainty = \
                     FIRuncFilter(self.values, self.uncertainty, b, Utheta = filter_uncertainty)
                else:
                    self.values, self.uncertainty = \
                     MC(self.values, self.uncertainty, b, a, filter_uncertainty, runs=MonteCarloRuns)
            else:
                if not isinstance(MonteCarloRuns, int):
                    MonteCarloRuns = 10000
                self.values, self.uncertainty = \
                 MC(self.values, self.uncertainty, b, a, filter_uncertainty, runs=MonteCarloRuns)
        else:  # IIR-type filter
            if not isinstance(MonteCarloRuns, int):
                MonteCarloRuns = 10000
                self.values, self.uncertainty = \
                 MC(self.values, self.uncertainty, b, a, filter_uncertainty, runs=MonteCarloRuns)
Пример #7
0
def test_fir_filter_MC_comparison():
    N_signal = np.random.randint(20, 25)
    x = random_array(N_signal)
    Ux = random_covariance_matrix(N_signal)

    N_theta = np.random.randint(2, 5)  # scipy.linalg.companion requires N >= 2
    theta = random_array(N_theta)  # scipy.signal.firwin(N_theta, 0.1)
    Utheta = random_covariance_matrix(N_theta)

    # run method
    y_fir, Uy_fir = _fir_filter(x,
                                theta,
                                Ux,
                                Utheta,
                                initial_conditions="zero")

    ## run FIR with MC and extract diagonal of returned covariance
    y_mc, Uy_mc = MC(x, Ux, theta, [1.0], Utheta, blow=None, runs=10000)

    # HACK: for visualization during debugging
    # import matplotlib.pyplot as plt
    # fig, ax = plt.subplots(nrows=1, ncols=3)
    # ax[0].plot(y_fir, label="fir")
    # ax[0].plot(y_mc, label="mc")
    # ax[0].set_title("filter: {0}, signal: {1}".format(len(theta), len(x)))
    # ax[0].legend()
    # ax[1].imshow(Uy_fir)
    # ax[1].set_title("FIR")
    # ax[2].imshow(Uy_mc)
    # ax[2].set_title("MC")
    # plt.show()
    # /HACK

    # approximate comparison
    assert np.all(np.diag(Uy_fir) >= 0)
    assert np.all(np.diag(Uy_mc) >= 0)
    assert Uy_fir.shape == Uy_mc.shape
    assert np.allclose(Uy_fir, Uy_mc, atol=1e-1, rtol=1e-1)
Пример #8
0
FC = fcut + (2 * np.random.rand(runs) - 1) * 0.5e3

B = np.zeros((runs, L + 1))
for k in range(runs):  # Monte Carlo for filter coefficients of low-pass filter
    B[k, :] = kaiser_lowpass(L, FC[k], Fs)[0]

Ub = make_semiposdef(np.cov(B, rowvar=False))  # covariance matrix of MC result

# simulate input and output signals
time = np.arange(0, 499 * Ts, Ts)  # time values
noise = 1e-5  # std of white noise
x = rect(time, 100 * Ts, 250 * Ts, 1.0, noise=noise)  # input signal

y, Uy = FIRuncFilter(x, noise, b, Ub,
                     blow=b)  # apply uncertain FIR filter (GUM formula)
yMC, UyMC = MC(x, noise, b, np.ones(1), Ub, runs=1000,
               blow=b)  # apply uncertain FIR filter (Monte Carlo)

plt.figure(1)
plt.cla()
plt.plot(time, x, label="input")
plt.plot(time, y, label="output")
plt.xlabel("time / au")
plt.ylabel("signal amplitude / au")
plt.legend()

plt.figure(2)
plt.cla()
plt.plot(time, Uy, label="FIR formula")
plt.plot(time, np.sqrt(np.diag(UyMC)), label="Monte Carlo")
plt.xlabel("time / au")
plt.ylabel("signal uncertainty/ au")
Пример #9
0
for kind in ["float", "corr", "diag"]:

    for blow in [None, b2]:

        print(kind, type(blow))

        if kind == "float":
            # input signal + run methods
            x = rect(time, 100 * Ts, 250 * Ts, 1.0, noise=sigma_noise)

            y, Uy = FIRuncFilter(
                x, sigma_noise, b1, Ub, blow=blow,
                kind=kind)  # apply uncertain FIR filter (GUM formula)
            yMC, UyMC = MC(
                x, sigma_noise, b1, [1.0], Ub, runs=runs,
                blow=blow)  # apply uncertain FIR filter (Monte Carlo)

        elif kind == "corr":

            # get an instance of noise, the covariance and the covariance-matrix with the specified color
            color = "red"
            noise = power_law_noise(N=nTime,
                                    color_value=color,
                                    std=sigma_noise)

            Ux = power_law_acf(nTime, color_value=color, std=sigma_noise)

            # input signal
            x = rect(time, 100 * Ts, 250 * Ts, 1.0, noise=noise)
Пример #10
0
def conduct_validation_of_FIRuncFilter():
    # parameters of simulated measurement
    Fs = 100e3  # sampling frequency (in Hz)
    Ts = 1 / Fs  # sampling interval length (in s)
    # nominal system parameters
    fcut = 20e3  # low-pass filter cut-off frequency (6 dB)
    L = 100  # filter order
    b1 = kaiser_lowpass(L, fcut, Fs)[0]
    b2 = kaiser_lowpass(L - 20, fcut, Fs)[0]
    # uncertain knowledge: cutoff between 19.5kHz and 20.5kHz
    runs = 1000
    FC = fcut + (2 * np.random.rand(runs) - 1) * 0.5e3
    B = np.zeros((runs, L + 1))
    for k in range(
            runs):  # Monte Carlo for filter coefficients of low-pass filter
        B[k, :] = kaiser_lowpass(L, FC[k], Fs)[0]
    Ub = make_semiposdef(np.cov(
        B, rowvar=False))  # covariance matrix of MC result
    # simulate input and output signals
    nTime = 500
    time = np.arange(nTime) * Ts  # time values
    # different cases
    sigma_noise = 1e-2  # 1e-5
    for kind in ["float", "corr", "diag"]:

        for blow in [None, b2]:

            print(kind, type(blow))

            if kind == "float":
                # input signal + run methods
                x = rect(time, 100 * Ts, 250 * Ts, 1.0, noise=sigma_noise)

                Uy, UyMC, y, yMC = _conduct_FIRuncFilter_and_MonteCarlo(
                    Ub, b1, blow, kind, runs, sigma_noise, x)

            elif kind == "corr":

                # get an instance of noise, the covariance and the covariance-matrix
                # with
                # the specified color
                color = "red"
                noise = power_law_noise(N=nTime,
                                        color_value=color,
                                        std=sigma_noise)

                Ux = power_law_acf(nTime, color_value=color, std=sigma_noise)

                # input signal
                x = rect(time, 100 * Ts, 250 * Ts, 1.0, noise=noise)

                # build Ux_matrix from autocorrelation Ux
                Ux_matrix = toeplitz(trimOrPad(Ux, nTime))

                # run methods
                y, Uy = FIRuncFilter(
                    x, Ux, b1, Ub, blow=blow,
                    kind=kind)  # apply uncertain FIR filter (GUM formula)
                yMC, UyMC = MC(
                    x, Ux_matrix, b1, np.ones(1), Ub, runs=runs,
                    blow=blow)  # apply uncertain FIR filter (Monte Carlo)

            elif kind == "diag":
                sigma_diag = sigma_noise * (
                    1 +
                    np.heaviside(np.arange(len(time)) - len(time) // 2.5, 0)
                )  # std doubles after half of the time
                noise = sigma_diag * white_gaussian(len(time))

                # input signal + run methods
                x = rect(time, 100 * Ts, 250 * Ts, 1.0, noise=noise)

                Uy, UyMC, y, yMC = _conduct_FIRuncFilter_and_MonteCarlo(
                    Ub, b1, blow, kind, runs, sigma_diag, x)

            # compare FIR and MC results
            plt.figure(1)
            plt.cla()
            plt.plot(time, x, label="input")
            plt.plot(time, y, label="output FIR direct")
            plt.plot(time, yMC, label="output FIR MC")
            plt.xlabel("time [s]")
            plt.ylabel("signal amplitude [1]")
            plt.legend()

            plt.figure(2)
            plt.cla()
            plt.plot(time, Uy, label="FIR formula")
            plt.plot(time, np.sqrt(np.diag(UyMC)), label="Monte Carlo")
            plt.xlabel("time [s]")
            plt.ylabel("signal uncertainty [1]")
            plt.legend()
            plt.show()