from random import uniform import numpy as np from pytestpavement.analysis.regression import fit_cos, fit_cos_eval def fit(freq: float = 10, ampl: float = 100.0, offset: float = 20.0, slope: float = 0.1, phase: float = 0.05, error: float = 0.001) -> None: N: int = 5 num_samples_per_cycle: int = 50 t = np.linspace(0, N / freq, N * num_samples_per_cycle) y = ampl * np.cos(2 * np.pi * freq * t + phase) + slope * t + offset r = fit_cos(t, y) error_min = (1 - error) error_max = (1 + error) # ampltude rel_error = (r['amp'] / ampl) assert error_min <= rel_error <= error_max # offset rel_error = (r['offset'] / offset) assert error_min <= rel_error <= error_max # slope rel_error = (r['slope'] / slope) assert error_min <= rel_error <= error_max # phase rel_error = (r['phase'] / phase) assert error_min <= rel_error <= error_max # freq rel_error = (r['freq'] / freq) assert error_min <= rel_error <= error_max def test_fit_simple_sine(ntest: int = 50) -> None: """ fit a simple sine signal and evaluate amplitude error: percentage error of ampl, Error max 0.1 % """ fit() #run multiple tests with random parameters for i in range(ntest): fit( ampl=uniform(1e-3, 1000), offset=uniform(1e-3, 1), slope=uniform(1e-5, 1), phase=uniform(1e-5, 1), ) def fit_noise(freq: float = 10, ampl: float = 100.0, offset: float = 20.0, slope: float = 0.1, phase: float = 0.05, noise_level: float = 0.01, error: float = 0.01) -> None: N: int = 5 num_samples_per_cycle: int = 50 t = np.linspace(0, N / freq, N * num_samples_per_cycle) y = ampl * np.cos(2 * np.pi * freq * t + phase) + slope * t + offset y_noise = np.random.normal(0, noise_level * ampl, len(t)) y = y + y_noise r = fit_cos(t, y) error_min = (1 - error) error_max = (1 + error) # ampltude rel_error = (r['amp'] / ampl) assert error_min <= rel_error <= error_max # freq rel_error = (r['freq'] / freq) assert error_min <= rel_error <= error_max def test_fit_simple_sine_with_noise(ntest: int = 50) -> None: """ fit a simple sine signal and evaluate amplitude error: percentage error of ampl, Error max 0.1 % """ fit_noise() #run multiple tests with random parameters for i in range(ntest): fit_noise( ampl=uniform(1e-3, 1000), offset=uniform(1e-3, 1), slope=uniform(1e-5, 1), phase=uniform(1e-5, 1), noise_level=uniform(0.01, 0.1), error=0.02, )