|
2 | 2 | from pytest import skip |
3 | 3 |
|
4 | 4 | from ..finite_difference import first_order as iterated_finite_difference |
5 | | -from ..smooth_finite_difference import mediandiff, meandiff, gaussiandiff, friedrichsdiff, butterdiff |
| 5 | +from ..smooth_finite_difference import butterdiff |
6 | 6 | from ..basis_fit import spectraldiff |
7 | 7 | from ..polynomial_fit import polydiff, savgoldiff, splinediff |
8 | 8 | from ..total_variation_regularization import velocity, acceleration, iterative_velocity |
9 | 9 | from ..kalman_smooth import rtsdiff |
10 | 10 | from ..optimize import optimize |
11 | 11 | from ..utils.simulate import pi_cruise_control |
| 12 | +from ..utils.evaluate import rmse |
12 | 13 |
|
13 | 14 |
|
14 | | -# simulation |
15 | 15 | dt = 0.01 |
16 | 16 | x, x_truth, dxdt_truth = pi_cruise_control(duration=2, noise_type='normal', noise_parameters=[0, 0.01], dt=dt) |
17 | | -cutoff_frequency = 10 # in Hz |
18 | | -log_gamma = -1.6 * np.log(cutoff_frequency) - 0.71 * np.log(dt) - 5.1 |
19 | | -tvgamma = np.exp(log_gamma) |
| 17 | +cutoff_frequency = 3 # in Hz |
| 18 | +tvgamma = np.exp(-1.6 * np.log(cutoff_frequency) - 0.71 * np.log(dt) - 5.1) |
20 | 19 |
|
21 | 20 |
|
22 | | -def test_finite_difference(): |
23 | | - params1, val1 = optimize(iterated_finite_difference, x, dt, dxdt_truth=dxdt_truth, padding='auto') |
24 | | - params2, val2 = optimize(iterated_finite_difference, x, dt, tvgamma=tvgamma, dxdt_truth=None, padding='auto') |
25 | | - assert params1['num_iterations'] == 5 |
26 | | - assert params2['num_iterations'] == 1 |
| 21 | +def test_parallel_same_as_serial(): |
| 22 | + """Ensure running optimize across several processes returns the same result as running in a single process""" |
| 23 | + params_parallel, val_parallel = optimize(rtsdiff, x, dt, tvgamma=tvgamma, parallel=True) |
| 24 | + params_serial, val_serial = optimize(rtsdiff, x, dt, tvgamma=tvgamma, parallel=False) |
27 | 25 |
|
28 | | -def test_iterative_velocity(): |
29 | | - params1, val1 = optimize(iterative_velocity, x, dt, dxdt_truth=dxdt_truth, search_space_updates={'num_iterations':1}, padding='auto') |
30 | | - params2, val2 = optimize(iterative_velocity, x, dt, tvgamma=tvgamma, search_space_updates={'num_iterations':1}, padding='auto') |
| 26 | + assert np.allclose(val_serial, val_parallel) |
| 27 | + assert params_serial == params_parallel |
| 28 | + |
| 29 | + |
| 30 | +def test_targeting_rmse_vs_tvgamma_loss(): |
| 31 | + """Ensure optimization properly targets different metrics""" |
| 32 | + params_rmse, val_rmse = optimize(splinediff, x, dt, dxdt_truth=dxdt_truth) |
| 33 | + params_loss, val_loss = optimize(splinediff, x, dt, tvgamma=tvgamma) |
31 | 34 |
|
32 | | - np.testing.assert_almost_equal(params1['gamma'], 0.0001, decimal=4) |
33 | | - np.testing.assert_almost_equal(params2['gamma'], 0.0001, decimal=4) |
34 | | - |
35 | | -def test_savgoldiff(): |
36 | | - params1, val1 = optimize(savgoldiff, x, dt, dxdt_truth=dxdt_truth, padding='auto') |
37 | | - params2, val2 = optimize(savgoldiff, x, dt, tvgamma=tvgamma, padding='auto') |
38 | | - assert (params1['degree'], params1['window_size'], params1['smoothing_win']) == (7, 41, 3) |
39 | | - assert (params2['degree'], params2['window_size'], params2['smoothing_win']) == (3, 3, 5) |
40 | | - |
41 | | -def test_spectraldiff(): |
42 | | - params1, val1 = optimize(spectraldiff, x, dt, dxdt_truth=dxdt_truth, padding='auto') |
43 | | - params2, val2 = optimize(spectraldiff, x, dt, tvgamma=tvgamma, padding='auto') |
44 | | - np.testing.assert_almost_equal(params1['high_freq_cutoff'], 0.18, decimal=2) |
45 | | - np.testing.assert_almost_equal(params2['high_freq_cutoff'], 0.155, decimal=2) |
46 | | - |
47 | | -def test_polydiff(): |
48 | | - params1, val1 = optimize(polydiff, x, dt, dxdt_truth=dxdt_truth, search_space_updates={'step_size':1}, padding='auto') |
49 | | - params2, val2 = optimize(polydiff, x, dt, tvgamma=tvgamma, search_space_updates={'step_size':1}, padding='auto') |
50 | | - assert (params1['degree'], params1['window_size'], params1['kernel']) == (6, 50, 'friedrichs') |
51 | | - assert (params2['degree'], params2['window_size'], params2['kernel']) == (3, 10, 'gaussian') |
52 | | - |
53 | | -# This test runs in a reasonable amount of time locally but for some reason takes forever in CI |
54 | | -# def test_rtsdiff_with_irregular_step(): |
55 | | -# t = np.arange(len(x))*dt; np.random.seed(7) # seed so the test can't randomly fail |
56 | | -# t_irreg = t + np.random.uniform(-dt/10, dt/10, *t.shape) # add jostle |
57 | | -# params1, val1 = optimize(rtsdiff, x, t, dxdt_truth=dxdt_truth) |
58 | | -# params2, val2 = optimize(rtsdiff, x, t_irreg, dxdt_truth=dxdt_truth) |
59 | | -# assert val2 < 1.15*val1 # optimization works and comes out similar, since jostle is small |
60 | | -# assert params1['qr_ratio']*0.85 < params2['qr_ratio'] < params1['qr_ratio']*1.15 |
| 35 | + x_hat, dxdt_hat = splinediff(x, dt, **params_loss) |
| 36 | + loss_rmse = rmse(dxdt_truth, dxdt_hat) |
| 37 | + |
| 38 | + assert val_rmse < loss_rmse < 1.1*val_rmse # This exact bound might break if using a different diff method or data series, but the point is they should be close |
| 39 | + |
| 40 | + |
| 41 | +def test_search_space_updates_applied(): |
| 42 | + """Ensure search space updates are used in optimization""" |
| 43 | + params2, _ = optimize(butterdiff, x, dt, search_space_updates={'filter_order':2}, tvgamma=tvgamma) |
| 44 | + params3, _ = optimize(butterdiff, x, dt, search_space_updates={'filter_order':3}, tvgamma=tvgamma) |
| 45 | + |
| 46 | + assert params2['filter_order'] == 2 |
| 47 | + assert params3['filter_order'] == 3 |
0 commit comments