Skip to content

Commit 1d54ee4

Browse files
committed
adjusted an error bound and moved come lines around to make it less redundant
1 parent 12a341a commit 1d54ee4

2 files changed

Lines changed: 13 additions & 19 deletions

File tree

pynumdiff/kalman_smooth.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -296,39 +296,33 @@ def robustdiff(x, dt_or_t, order, log_q, log_r, proc_huberM=6, meas_huberM=0):
296296
- **dxdt_hat** (np.array) -- estimated derivative of x
297297
"""
298298
equispaced = np.isscalar(dt_or_t)
299+
if not equispaced and len(x) != len(dt_or_t):
300+
raise ValueError("If `dt_or_t` is given as array-like, must have same length as `x`.")
299301

300302
A_c = np.diag(np.ones(order), 1) # continuous-time A just has 1s on the first diagonal (where 0th is main diagonal)
301303
Q_c = np.zeros(A_c.shape); Q_c[-1,-1] = 10**log_q # continuous-time uncertainty around the last derivative
302304
C = np.zeros((1, order+1)); C[0,0] = 1 # we measure only y = noisy x
303305
R = np.array([[10**log_r]]) # 1 observed state, so this is 1x1
304-
305306
M = np.block([[A_c, Q_c], [np.zeros(A_c.shape), -A_c.T]]) # exponentiate per step
306307

307308
if equispaced:
308309
# convert to discrete time using matrix exponential
309310
eM = expm(M * dt_or_t) # Note this could handle variable dt, similar to rtsdiff
310311
A_d = eM[:order+1, :order+1]
311-
Q_d = eM[:order+1, order+1:] @ A_d.T #
312-
if np.linalg.cond(Q_d) > 1e12:
313-
Q_d += np.eye(order + 1)*1e-12 # for numerical stability with convex solver. Doesn't change answers appreciably (or at all).
312+
Q_d = eM[:order+1, order+1:] @ A_d.T
313+
if np.linalg.cond(Q_d) > 1e12: Q_d += np.eye(order + 1)*1e-12 # for numerical stability with convex solver. Doesn't change answers appreciably (or at all).
314+
else: # support variable step size for this function
315+
A_d = np.empty((len(x)-1, order+1, order+1)) # stack all the evolution matrices
316+
Q_d = np.empty((len(x)-1, order+1, order+1))
314317

315-
x_states = convex_smooth(x, A_d, Q_d, C, R, proc_huberM=proc_huberM, meas_huberM=meas_huberM) # outsource solution of the convex optimization problem
316-
else: # support variable step size for this function
317-
N = len(x)
318-
if N != len(dt_or_t): raise ValueError("If `dt_or_t` is given as array-like, must have same length as `x`.")
319-
320-
A_ds = np.empty((N-1, order+1, order+1))
321-
Q_ds = np.empty((N-1, order+1, order+1))
322318
for i, dt in enumerate(np.diff(dt_or_t)): # for each variable time step
323319
eM = expm(M * dt)
324-
A_ds[i] = eM[:order+1, :order+1] # extract discrete time A matrix
325-
Q_ds[i] = eM[:order+1, order+1:] @ A_ds[i].T # extract discrete time Q matrix
326-
if dt < 0: Q_ds[i] = np.abs(Q_ds[i]) # eigenvalues go negative if reverse time, but noise shouldn't shrink
327-
if np.linalg.cond(Q_ds[i]) > 1e12:
328-
Q_ds[i] += np.eye(order + 1)*1e-12
329-
330-
x_states = convex_smooth(x, A_ds, Q_ds, C, R, proc_huberM=proc_huberM, meas_huberM=meas_huberM) # outsource solution of the convex optimization problem
320+
A_d[i] = eM[:order+1, :order+1] # extract discrete time A matrix
321+
Q_d[i] = eM[:order+1, order+1:] @ A_d[i].T # extract discrete time Q matrix
322+
if dt < 0: Q_d[i] = np.abs(Q_d[i]) # eigenvalues go negative if reverse time, but noise shouldn't shrink
323+
if np.linalg.cond(Q_d[i]) > 1e12: Q_d[i] += np.eye(order + 1)*1e-12
331324

325+
x_states = convex_smooth(x, A_d, Q_d, C, R, proc_huberM=proc_huberM, meas_huberM=meas_huberM) # outsource solution of the convex optimization problem
332326
return x_states[:,0], x_states[:,1]
333327

334328

pynumdiff/tests/test_diff_methods.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def polydiff_irreg_step(*args, **kwargs): return polydiff(*args, **kwargs)
235235
[(1, 1), (3, 3), (1, 1), (3, 3)]],
236236
robust_irreg_step: [[(-15, -15), (-13, -14), (0, -1), (1, 1)],
237237
[(-14, -14), (-13, -13), (0, -1), (1, 1)],
238-
[(-14, -15), (-13, -13), (0, -1), (1, 1)],
238+
[(-14, -14), (-13, -13), (0, -1), (1, 1)],
239239
[(-8, -8), (-2, -2), (0, -1), (1, 1)],
240240
[(0, 0), (2, 2), (0, 0), (2, 2)],
241241
[(1, 1), (3, 3), (1, 1), (3, 3)]],

0 commit comments

Comments
 (0)