def test_rect(): width = N // 4 * Ts height = 1 + np.random.rand() * 0.2 x = rect(time, t0, t0 + width, height, noise=0.0) assert_almost_equal(np.max(x), height) assert np.max(x[time < t0]) < 1e-10 assert np.max(x[time > t0 + width]) < 1e-10 # noisy signal nstd = 1e-2 x = rect(time, t0, t0 + width, height, noise=nstd) assert np.round(np.std(x[time < t0]) * 100) / 100 == approx(nstd)
def test_rect(): width = N // 4 * Ts height = 1 + np.random.rand() * 0.2 x = rect(time, t0, t0 + width, height, noise=0.0) assert x.max() == approx(height) assert np.max(x[time < t0]) < 1e-10 assert np.max(x[time > t0 + width]) < 1e-10 # noisy signal nstd = 1e-2 x = rect(time, t0, t0 + width, height, noise=nstd) assert np.round(np.std(x[time < t0]) * 100) / 100 == approx(nstd)
def test_FIRuncFilter_float(): # input signal + run methods x = rect(time,100*Ts,250*Ts,1.0,noise=sigma_noise) # apply uncertain FIR filter (GUM formula) for blow in [None, b2]: y, Uy = FIRuncFilter(x, sigma_noise, b1, Ub, blow=blow, kind="float") assert len(y) == len(x) assert len(Uy) == len(x)
def signal_inputs( draw: Callable, force_number_of_samples_to: int = None, ensure_time_step_to_be_float: bool = False, ensure_uncertainty_array: bool = False, ensure_uncertainty_covariance_matrix: bool = False, ) -> Dict[str, Union[float, np.ndarray]]: minimum_float = 1e-5 maximum_float = 1e-1 number_of_samples = force_number_of_samples_to or draw( hst.integers(min_value=4, max_value=512)) small_positive_float_strategy = hypothesis_bounded_float( min_value=minimum_float, max_value=maximum_float) freq_strategy = hst.one_of( small_positive_float_strategy, hst.just(None), ) intermediate_time_step = draw(small_positive_float_strategy) max_time = number_of_samples * intermediate_time_step time = np.arange(0, max_time, intermediate_time_step)[:number_of_samples] if ensure_time_step_to_be_float: time_step = intermediate_time_step else: time_step = draw(hst.sampled_from((intermediate_time_step, None))) if time_step is None: sampling_frequency = draw(freq_strategy) else: sampling_frequency = draw( hst.sampled_from((np.reciprocal(time_step), None))) values = rect(time, max_time // 4, max_time // 4 * 3) uncertainties_covariance_strategy = (hypothesis_covariance_matrix( number_of_rows=number_of_samples), ) uncertainties_array_strategies = uncertainties_covariance_strategy + ( hypothesis_float_vector(min_value=minimum_float, max_value=maximum_float, length=number_of_samples), ) if ensure_uncertainty_covariance_matrix: uncertainties_strategies = uncertainties_covariance_strategy elif ensure_uncertainty_array: uncertainties_strategies = uncertainties_array_strategies else: uncertainties_strategies = uncertainties_array_strategies + ( small_positive_float_strategy, hst.just(None), ) ux = draw(hst.one_of(uncertainties_strategies)) return { "time": time, "values": values, "Ts": time_step, "Fs": sampling_frequency, "uncertainty": ux, }
def test_FIRuncFilter_diag(): sigma_diag = sigma_noise * ( 1 + np.heaviside(np.arange(len(time)) - len(time)//2,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) # apply uncertain FIR filter (GUM formula) for blow in [None, b2]: y, Uy = FIRuncFilter(x, sigma_diag, b1, Ub, blow=blow, kind="diag") assert len(y) == len(x) assert len(Uy) == len(x)
def input_signal(sigma_noise): # simulate input and output signals Fs = 100e3 # sampling frequency (in Hz) Ts = 1 / Fs # sampling interval length (in s) nx = 500 time = np.arange(nx) * Ts # time values # input signal + run methods x = rect(time, 100 * Ts, 250 * Ts, 1.0, noise=sigma_noise) # generate input signal Ux = sigma_noise * np.ones_like(x) # uncertainty of input signal return {"x": x, "Ux": Ux}
def test_FIRuncFilter_corr(): # get an instance of noise, the covariance and the covariance-matrix with the specified color color = "white" 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) # apply uncertain FIR filter (GUM formula) for blow in [None, b2]: y, Uy = FIRuncFilter(x, Ux, b1, Ub, blow=blow, kind="corr") assert len(y) == len(x) assert len(Uy) == len(x)
ws = 0.3 gpass = 0.1 gstop = 40 # noinspection PyTupleAssignmentBalance b, _ = dsp.iirdesign(wp, ws, gpass, gstop) a = np.ones(1) # simulate input and output signals Fs = 100e3 # sampling frequency (in Hz) Ts = 1 / Fs # sampling interval length (in s) nx = 200 time = np.arange(nx) * Ts # time values # input signal + run methods sigma_noise = 1e-2 x = rect(time, 50 * Ts, 150 * Ts, 1.0, noise=sigma_noise) Ux = sigma_noise * np.ones_like(x) Uab = 0.001 * np.diag(np.arange((len(a) + len(b) - 1))) # calculate result from IIR method y, Uy, _ = pf.IIRuncFilter( x, Ux, b, a, Uab=Uab, kind="diag" ) # state=pf.get_initial_internal_state(b, a) # calculate fir result y_fir, Uy_fir = pf.FIRuncFilter(x, Ux, b, Utheta=Uab, kind="diag") # calculate monte carlo result n_mc = 10000 tmp_y = [] for i in range(n_mc):
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 nTime = 500 time = np.arange(nTime)*Ts # time values # different cases sigma_noise = 1e-5 # input signal + run methods x = rect(time,100*Ts,250*Ts,1.0,noise=sigma_noise) ##### actual tests 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)
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) plt.ylabel('signal amplitude / au', fontsize=22) plt.tick_params(which="both", labelsize=16) plt.figure(2) plt.cla()
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() 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")
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) plt.ylabel('signal amplitude / au',fontsize=22) plt.tick_params(which="both",labelsize=16) plt.figure(2);plt.cla() plt.plot(time*1e3, Uy, label='IIR formula') plt.plot(time*1e3, UyMC, label='Monte Carlo') # plt.title('uncertainty of filter output')
# uncertain knowledge: fcut between 19.8kHz and 20.2kHz runs = 1000 FC = fcut + (2*np.random.rand(runs)-1)*0.2e3 AB = np.zeros((runs,len(b)+len(a)-1)) for k in range(runs): 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)) time = np.arange(0,499*Ts,Ts) t0 = 100*Ts; t1 = 300*Ts height = 0.9 noise = 1e-3 x = rect(time,t0,t1,height,noise=noise) y,Uy = IIRuncFilter(x, noise, b, a, Uab) yMC,UyMC = MC.SMC(x,noise,b,a,Uab,runs=10000) 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) plt.ylabel('signal amplitude / au',fontsize=22) plt.tick_params(which="both",labelsize=16) plt.figure(2);plt.cla() plt.plot(time*1e3, Uy, label='IIR formula') plt.plot(time*1e3, UyMC, label='Monte Carlo') # plt.title('uncertainty of filter output')
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) if __name__=="__main__": N = 1024 Ts = 0.01 time = np.arange(0, N*Ts, Ts) x = rect(time, Ts*N//4, Ts*N//4*3) ux= 0.02 signal = Signal(time, x, Ts = Ts, uncertainty = ux) b = dsp.firls(15, [0, 0.2*signal.Fs/2, 0.25*signal.Fs/2, signal.Fs/2 ], [1, 1, 0, 0], nyq=signal.Fs/2) Ub = np.diag(b*1e-1) signal.apply_filter(b, filter_uncertainty=Ub) signal.plot_uncertainty() bl, al = dsp.bessel(4, 0.2) Ul = np.diag(np.r_[al[1:]*1e-3, bl*1e-2]**2) signal.apply_filter(bl, al, filter_uncertainty = Ul) signal.plot_uncertainty(fignr = 3)
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") plt.xlabel("time / au") plt.ylabel("signal amplitude / au") plt.legend() plt.figure(2)
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')) plt.figure(3) plt.cla() plt.plot(time, col_hstack([Uy, UyMC, UyMC2])) plt.title('Uncertainty of filter output signal') plt.legend(('FIR formula', 'Monte Carlo', 'Sequential Monte Carlo'))
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()