Esempio n. 1
0
def demonstrate_second_order_model_fitting(runs: int = 10000):
    rng = default_rng(1)

    # sensor/measurement system
    S0 = 0.124
    uS0 = 0.001
    delta = 0.01
    udelta = 0.001
    f0 = 36
    uf0 = 0.5

    # Monte Carlo for calculation of unc. assoc. with [real(H),imag(H)]
    MCS0 = rng.normal(loc=S0, scale=uS0, size=runs)
    MCd = rng.normal(loc=delta, scale=udelta, size=runs)
    MCf0 = rng.normal(loc=f0, scale=uf0, size=runs)
    f = np.linspace(0, 1.2 * f0, 30)

    HMC = sos_FreqResp(MCS0, MCd, MCf0, f)

    Hc = np.mean(HMC, dtype=complex, axis=1)
    H = np.r_[np.real(Hc), np.imag(Hc)]
    UH = np.cov(np.r_[np.real(HMC), np.imag(HMC)], rowvar=True)
    UH = make_semiposdef(UH)

    p, Up = fit_som(f, H, UH, scaling=1, MCruns=runs, verbose=True)

    plt.figure(1)
    plt.errorbar(
        range(1, 4),
        [p[0] * 10, p[1] * 10, p[2] / 10],
        np.sqrt(np.diag(Up)) * np.array([10, 10, 0.1]),
        fmt=".",
    )
    plt.errorbar(
        np.arange(1, 4) + 0.2,
        [S0 * 10, delta * 10, f0 / 10],
        [uS0 * 10, udelta * 10, uf0 / 10],
        fmt=".",
    )
    plt.xlim(0, 4)
    plt.xticks([1.1, 2.1, 3.1], [r"$S_0$", r"$\delta$", r"$f_0$"])
    plt.xlabel("scaled model parameters")

    plt.show()
Esempio n. 2
0
Ts = 1 / Fs

# nominal system parameters
fcut = 20e3
L = 100
b = kaiser_lowpass(L, 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):
    B[k, :] = kaiser_lowpass(L, FC[k], Fs)[0]

Ub = make_semiposdef(np.cov(B, rowvar=0))

# simulate input and output signals
time = np.arange(0, 499 * Ts, Ts)
noise = 1e-3
x = rect(time, 100 * Ts, 250 * Ts, 1.0, noise=noise)

y, Uy = FIRuncFilter(x, noise, b, Ub)
yMC, UyMC = MC.MC(x, noise, b, [1.0], Ub, runs=10000)
yMC2, UyMC2 = MC.SMC(x, noise, b, [1.0], Ub, runs=10000)

plt.figure(1)
plt.cla()
plt.plot(time, col_hstack([x, y]))
plt.legend(('input', 'output'))
Esempio n. 3
0
                200)  # frequencies at which to calculate frequency response
HMC = np.zeros((runs, len(f)),
               dtype=complex)  # initialise frequency response with zeros
for k in range(runs):  # actual Monte Carlo
    bc_, ac_ = sos_phys2filter(
        MCS0[k], MCd[k], MCf0[k])  # calculate analogue filter coefficients
    b_, a_ = dsp.bilinear(bc_, ac_,
                          Fs)  # transform to digital filter coefficients
    HMC[k, :] = dsp.freqz(b_, a_, 2 * np.pi * f /
                          Fs)[1]  # calculate DFT frequency response

Hc = np.mean(HMC, dtype=complex, axis=0)  # best estimate (complex-valued)
H = np.r_[np.real(Hc), np.imag(Hc)]  # best estimate in real, imag
UH = np.cov(np.c_[np.real(HMC), np.imag(HMC)],
            rowvar=0)  # covariance of real, imag
UH = make_semiposdef(UH, verbose=True)  # correct for numerical errors

bF, UbF = model_est.invLSFIR_unc(
    H, UH, N, tau, f,
    Fs)  # Calculation of FIR deconvolution filter and its assoc. unc.
CbF = UbF / (np.tile(np.sqrt(np.diag(UbF))[:, np.newaxis], (1, N + 1)) *
             np.tile(np.sqrt(np.diag(UbF))[:, np.newaxis].T,
                     (N + 1, 1)))  # correlation of filter coefficients

# Deconvolution Step1: lowpass filter for noise attenuation
fcut = f0 + 20e3
low_order = 100  # cut-off frequency and filter order
blow, lshift = kaiser_lowpass(low_order, fcut,
                              Fs)  # FIR low pass filter coefficients
shift = tau + lshift  # delay of low-pass plus that of the FIR deconv filter
# Deconvolution Step2: Application of deconvolution filter
Esempio n. 4
0
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
b = kaiser_lowpass(L, 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
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")
Esempio n. 5
0
uf0 = 0.5
f = np.linspace(0, f0 * 1.2, 20)

# Monte Carlo for calculation of unc. assoc. with [real(H),imag(H)]
runs = 10000
MCS0 = S0 + rst.randn(runs) * uS0
MCd = delta + rst.randn(runs) * udelta
MCf0 = f0 + rst.randn(runs) * uf0
f = np.linspace(0, 1.2 * f0, 30)

HMC = sos_FreqResp(MCS0, MCd, MCf0, f)

Hc = np.mean(HMC, dtype=complex, axis=1)
H = np.r_[np.real(Hc), np.imag(Hc)]
UH = np.cov(np.r_[np.real(HMC), np.imag(HMC)], rowvar=True)
UH = make_semiposdef(UH)

p, Up, HMC2 = fit_sos(f, Hc, UH, scaling=1, MCruns=10000)

figure(1)
errorbar(
    range(1, 4),
    [p[0] * 10, p[1] * 10, p[2] / 10],
    np.sqrt(np.diag(Up)) * np.array([10, 10, 0.1]),
    fmt=".",
)
errorbar(
    np.arange(1, 4) + 0.2,
    [S0 * 10, delta * 10, f0 / 10],
    [uS0 * 10, udelta * 10, uf0 / 10],
    fmt=".",
Esempio n. 6
0
# nominal system parameter
fcut = 20e3  # low pass filter cut-off frequency (in Hz)
L = 6  # filter order
b, a = dsp.butter(L, 2 * fcut / Fs,
                  btype='lowpass')  # nominal filter coefficients

# uncertain knowledge: fcut between 19.8kHz and 20.2kHz
runs = 1000  # number of Monte Carlo runs
FC = fcut + (2 * np.random.rand(runs) - 1) * 0.2e3  # cut-off frequency range
AB = np.zeros((runs, len(b) + len(a) - 1))  # filter coefficients

for k in range(runs):  # Monte Carlo for uncertainty of filter coefficients
    bb, aa = dsp.butter(L, 2 * FC[k] / Fs, btype='lowpass')
    AB[k, :] = np.hstack((aa[1:], bb))

Uab = make_semiposdef(np.cov(AB, rowvar=0))  # correct for numerical errors

# Apply filter
time = np.arange(0, 499 * Ts, Ts)  # time values
t0 = 100 * Ts
t1 = 300 * Ts  # left and right boundary of rect signal
height = 0.9  # input signal height
noise = 1e-3  # std of white noise
x = rect(time, t0, t1, height, noise=noise)  # input signal

y, Uy = IIRuncFilter(x, noise, b, a, Uab)  # apply IIR formula (GUM)
yMC, UyMC = MC.SMC(x, noise, b, a, Uab,
                   runs=10000)  # apply sequential Monte Carlo method (GUM S1)

plt.figure(1)
plt.cla()
Esempio n. 7
0
# sensor/measurement system
S0 = 0.124; uS0= 0.001
delta = 0.01; udelta = 0.001
f0 = 36; uf0 = 0.5
f = np.linspace(0, f0*1.2, 20)

# Monte Carlo for calculation of unc. assoc. with [real(H),imag(H)]
runs = 10000
MCS0 = S0 + rst.randn(runs)*uS0
MCd  = delta+ rst.randn(runs)*udelta
MCf0 = f0 + rst.randn(runs)*uf0
f = np.linspace(0, 1.2*f0, 30)

HMC = sos_FreqResp(MCS0, MCd, MCf0, f)

Hc = np.mean(HMC,dtype=complex,axis=1)
H = np.r_[np.real(Hc), np.imag(Hc)]
UH= np.cov(np.r_[np.real(HMC),np.imag(HMC)],rowvar=True)
UH= make_semiposdef(UH)

p, Up, HMC2 = fit_sos(f, Hc, UH, scaling = 1, MCruns = 10000)

figure(1)
errorbar(range(1,4), [p[0]*10,p[1]*10,p[2]/10], np.sqrt(np.diag(Up))*np.array([10,10,0.1]), fmt=".")
errorbar(np.arange(1,4)+0.2, [S0*10, delta*10, f0/10], [uS0*10, udelta*10, uf0/10], fmt=".")
xlim(0,4)
xticks([1.1,2.1,3.1],[r"$S_0$",r"$\delta$",r"$f_0$"])
xlabel("scaled model parameters")

show()
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
b = kaiser_lowpass(L,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=0))	# 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.MC(x,noise,b,[1.0],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()
Esempio n. 9
0
def monte_carlo(
    measurement_system,
    random_number_generator,
    sampling_freq,
    freqs,
    complex_freq_resp,
    reference_array_path,
):
    udelta = 0.1 * measurement_system["delta"]
    uS0 = 0.001 * measurement_system["S0"]
    uf0 = 0.01 * measurement_system["f0"]

    runs = 10000
    MCS0 = random_number_generator.normal(
        loc=measurement_system["S0"], scale=uS0, size=runs
    )
    MCd = random_number_generator.normal(
        loc=measurement_system["delta"], scale=udelta, size=runs
    )
    MCf0 = random_number_generator.normal(
        loc=measurement_system["f0"], scale=uf0, size=runs
    )
    HMC = np.empty((runs, len(freqs)), dtype=complex)
    for index, mcs0_mcd_mcf0 in enumerate(zip(MCS0, MCd, MCf0)):
        bc_, ac_ = sos_phys2filter(mcs0_mcd_mcf0[0], mcs0_mcd_mcf0[1], mcs0_mcd_mcf0[2])
        b_, a_ = dsp.bilinear(bc_, ac_, sampling_freq)
        HMC[index, :] = dsp.freqz(b_, a_, 2 * np.pi * freqs / sampling_freq)[1]

    H = complex_2_real_imag(complex_freq_resp)
    assert_allclose(
        H,
        np.load(
            os.path.join(reference_array_path, "test_LSFIR_H.npz"),
        )["H"],
    )
    uAbs = np.std(np.abs(HMC), axis=0)
    assert_allclose(
        uAbs,
        np.load(
            os.path.join(reference_array_path, "test_LSFIR_uAbs.npz"),
        )["uAbs"],
        rtol=3.5e-2,
    )
    uPhas = np.std(np.angle(HMC), axis=0)
    assert_allclose(
        uPhas,
        np.load(
            os.path.join(reference_array_path, "test_LSFIR_uPhas.npz"),
        )["uPhas"],
        rtol=4.3e-2,
    )
    UH = np.cov(np.hstack((np.real(HMC), np.imag(HMC))), rowvar=False)
    UH = make_semiposdef(UH)
    assert_allclose(
        UH,
        np.load(
            os.path.join(reference_array_path, "test_LSFIR_UH.npz"),
        )["UH"],
        atol=1,
    )
    return {"H": H, "uAbs": uAbs, "uPhas": uPhas, "UH": UH}
# nominal system parameter
fcut = 20e3		# low pass filter cut-off frequency (in Hz)
L = 6			# filter order
b,a = dsp.butter(L,2*fcut/Fs,btype='lowpass')	# nominal filter coefficients

# uncertain knowledge: fcut between 19.8kHz and 20.2kHz
runs = 1000		# number of Monte Carlo runs
FC = fcut + (2*np.random.rand(runs)-1)*0.2e3	# cut-off frequency range
AB = np.zeros((runs,len(b)+len(a)-1))			# filter coefficients

for k in range(runs):		# Monte Carlo for uncertainty of filter coefficients
	bb,aa = dsp.butter(L,2*FC[k]/Fs,btype='lowpass')
	AB[k,:] = np.hstack((aa[1:],bb))

Uab = make_semiposdef(np.cov(AB,rowvar=0))	# correct for numerical errors

# Apply filter
time = np.arange(0,499*Ts,Ts)				# time values
t0 = 100*Ts; t1 = 300*Ts					# left and right boundary of rect signal
height = 0.9								# input signal height
noise = 1e-3								# std of white noise
x = rect(time,t0,t1,height,noise=noise)		# input signal

y,Uy = IIRuncFilter(x, noise, b, a, Uab)		# apply IIR formula (GUM)
yMC,UyMC = MC.SMC(x,noise,b,a,Uab,runs=10000)	# apply sequential Monte Carlo method (GUM S1)

plt.figure(1);plt.cla()
plt.plot(time*1e3, x, label="input signal")
plt.plot(time*1e3, y, label="output signal")
plt.xlabel('time / ms',fontsize=22)
Esempio n. 11
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()
Esempio n. 12
0
# Monte Carlo for calculation of unc. assoc. with [real(H),imag(H)]
runs = 10000
MCf0 = f0 + rst.randn(runs)*uf0                 # MC draws of resonance frequency
MCS0 = S0 + rst.randn(runs)*uS0                 # MC draws of static gain
MCd  = delta+ rst.randn(runs)*udelta            # MC draws of damping
f = np.linspace(0, 120e3, 200)                  # frequencies at which to calculate frequency response
HMC = np.zeros((runs, len(f)),dtype=complex)    # initialise frequency response with zeros
for k in range(runs):       # actual Monte Carlo
    bc_,ac_ = sos_phys2filter(MCS0[k], MCd[k], MCf0[k])     # calculate analogue filter coefficients
    b_,a_ = dsp.bilinear(bc_,ac_,Fs)                        # transform to digital filter coefficients
    HMC[k,:] = dsp.freqz(b_,a_,2*np.pi*f/Fs)[1]             # calculate DFT frequency response

Hc = np.mean(HMC,dtype=complex,axis=0)                      # best estimate (complex-valued)
H = np.r_[np.real(Hc), np.imag(Hc)]                         # best estimate in real, imag
UH= np.cov(np.c_[np.real(HMC),np.imag(HMC)],rowvar=0)       # covariance of real, imag
UH= make_semiposdef(UH, verbose=True)                       # correct for numerical errors

bF, UbF = deconv.LSFIR_unc(H,UH,N,tau,f,Fs)                             # Calculation of FIR deconvolution filter and its assoc. unc.
CbF = UbF/(np.tile(np.sqrt(np.diag(UbF))[:,np.newaxis],(1,N+1))*
		   np.tile(np.sqrt(np.diag(UbF))[:,np.newaxis].T,(N+1,1)))      # correlation of filter coefficients


# Deconvolution Step1: lowpass filter for noise attenuation
fcut = f0+20e3; low_order = 100                             # cut-off frequency and filter order
blow, lshift = kaiser_lowpass(low_order, fcut, Fs)          # FIR low pass filter coefficients
shift = tau + lshift                                        # delay of low-pass plus that of the FIR deconv filter
# Deconvolution Step2: Application of deconvolution filter
xhat,Uxhat = FIRuncFilter(yn,noise,bF,UbF,shift,blow)       # apply low-pass and FIR deconv filter


# Plot of results