filterpy
Advanced tools
| Metadata-Version: 1.1 | ||
| Name: filterpy | ||
| Version: 1.4.0 | ||
| Version: 1.4.1 | ||
| Summary: Kalman filtering and optimal estimation library | ||
@@ -62,3 +62,3 @@ Home-page: https://github.com/rlabbe/filterpy | ||
| Why 3.5+, and not 3.3+? 3.5 introduced the matrix multiply symbol, | ||
| Why 3.5+, and not 3.4+? 3.5 introduced the matrix multiply symbol, | ||
| and I want my code to take advantage of it. Plus, to be honest, | ||
@@ -65,0 +65,0 @@ I'm being selfish. I don't want to spend my life supporting this |
@@ -17,2 +17,2 @@ # -*- coding: utf-8 -*- | ||
| __version__ = "1.4.0" | ||
| __version__ = "1.4.1" |
@@ -0,2 +1,16 @@ | ||
| Version 1.4.1 | ||
| ============= | ||
| * GitHub 125: used itertools.repeat() instead of [x]*n to get | ||
| iterable list of constant values | ||
| * Fixed bug using [:] to copy data instead of np.copy(), which is | ||
| a deep copy | ||
| * fixed import bug in common.kinematic_kf() | ||
| Version 1.4 | ||
| =========== | ||
@@ -3,0 +17,0 @@ * UKF refactor. This is a (mildly) breaking change. Passing data to |
@@ -23,2 +23,3 @@ # -*- coding: utf-8 -*- | ||
| import copy | ||
| from itertools import repeat | ||
| import numpy as np | ||
@@ -293,1 +294,14 @@ | ||
| return z | ||
| def repeated_array(val, N): | ||
| """ User can specify either a single value, or a list/array of N values. | ||
| If a single value, create an iterable list to return that value | ||
| repeatedly. | ||
| """ | ||
| shape = np.shape(val) | ||
| if len(shape) > 1 and shape[0] == N: | ||
| return val | ||
| return repeat(val, N) |
@@ -140,2 +140,3 @@ # -*- coding: utf-8 -*- | ||
| from filterpy.kalman import KalmanFilter | ||
| if dim < 1: | ||
@@ -150,3 +151,3 @@ raise ValueError("dim must be >= 1") | ||
| kf = filterpy.kalman.KalmanFilter(dim_x=dim * dim_x, dim_z=dim) | ||
| kf = KalmanFilter(dim_x=dim * dim_x, dim_z=dim) | ||
| F = kinematic_state_transition(order, dt) | ||
@@ -153,0 +154,0 @@ if order_by_dim: |
@@ -21,3 +21,4 @@ # -*- coding: utf-8 -*- | ||
| from filterpy.common import linear_ode_discretation, Q_discrete_white_noise | ||
| from filterpy.common import (linear_ode_discretation, Q_discrete_white_noise, | ||
| kinematic_kf) | ||
| from numpy import array | ||
@@ -29,2 +30,6 @@ | ||
| def test_kinematic(): | ||
| kf = kinematic_kf(1,1) | ||
| def test_Q_discrete_white_noise(): | ||
@@ -31,0 +36,0 @@ |
@@ -140,3 +140,3 @@ # -*- coding: utf-8 -*- | ||
| try: | ||
| self.z = z[:] | ||
| self.z = np.copy(z) | ||
| except: | ||
@@ -143,0 +143,0 @@ self.z = copy.deepcopy(z) |
@@ -149,4 +149,4 @@ # -*- coding: utf-8 -*- | ||
| # Priors. Will always be a copy of x, P after predict() is called. | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -211,4 +211,4 @@ | ||
| # save prior | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -340,4 +340,4 @@ # update step | ||
| # save prior | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -344,0 +344,0 @@ |
@@ -197,4 +197,4 @@ # -*- coding: utf-8 -*- | ||
| self.P = P | ||
| self.x_prior = x[:] | ||
| self.P_prior = P[:] | ||
| self.x_prior = np.copy(x) | ||
| self.P_prior = np.copy(P) | ||
@@ -276,4 +276,4 @@ | ||
| # save prior | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -280,0 +280,0 @@ |
@@ -159,4 +159,4 @@ # -*- coding: utf-8 -*- | ||
| # save priors | ||
| self.x_prior = self.x[:] | ||
| self.P_inv_prior = self.P_inv[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_inv_prior = np.copy(self.P_inv) | ||
@@ -215,3 +215,3 @@ | ||
| self.z = reshape_z(z, self.dim_z, np.ndim(self.x))[:] | ||
| self.z = np.copy(reshape_z(z, self.dim_z, np.ndim(self.x))) | ||
@@ -256,6 +256,6 @@ if self.compute_log_likelihood: | ||
| self.P_inv = self.inv(AI + self.Q) | ||
| self.P_inv_prior = self.P_inv[:] | ||
| self.P_inv_prior = np.copy(self.P_inv) | ||
| # save priors | ||
| self.x_prior = self.x[:] | ||
| self.x_prior = np.copy(self.x) | ||
| else: | ||
@@ -269,4 +269,4 @@ I_PF = self._I - dot(self.P_inv, self._F_inv) | ||
| # save priors | ||
| self.x_prior = self.x[:] | ||
| self.P_inv_prior = AQI[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_inv_prior = np.copy(AQI) | ||
@@ -273,0 +273,0 @@ |
@@ -115,2 +115,3 @@ # -*- coding: utf-8 -*- | ||
| from __future__ import absolute_import, division | ||
| import sys | ||
@@ -123,3 +124,3 @@ import warnings | ||
| from filterpy.stats import logpdf | ||
| from filterpy.common import pretty_str, reshape_z | ||
| from filterpy.common import pretty_str, reshape_z, repeated_array | ||
@@ -260,4 +261,4 @@ | ||
| # these will always be a copy of x,P after predict() is called | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -284,12 +285,12 @@ self.compute_log_likelihood = compute_log_likelihood | ||
| B : np.array(dim_x, dim_z), or None | ||
| Optional control transition matrix; a value of None in | ||
| any position will cause the filter to use `self.B`. | ||
| Optional control transition matrix; a value of None | ||
| will cause the filter to use `self.B`. | ||
| F : np.array(dim_x, dim_x), or None | ||
| Optional state transition matrix; a value of None in | ||
| any position will cause the filter to use `self.F`. | ||
| Optional state transition matrix; a value of None | ||
| will cause the filter to use `self.F`. | ||
| Q : np.array(dim_x, dim_x), scalar, or None | ||
| Optional process noise matrix; a value of None in | ||
| any position will cause the filter to use `self.Q`. | ||
| Optional process noise matrix; a value of None will cause the | ||
| filter to use `self.Q`. | ||
| """ | ||
@@ -316,4 +317,4 @@ | ||
| # save prior | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -381,3 +382,3 @@ | ||
| self.z = z[:] # save the measurement | ||
| self.z = np.copy(z) # save the measurement | ||
@@ -406,4 +407,4 @@ if self.compute_log_likelihood: | ||
| B : np.array(dim_x, dim_z), or None | ||
| Optional control transition matrix; a value of None in | ||
| any position will cause the filter to use `self.B`. | ||
| Optional control transition matrix; a value of None | ||
| will cause the filter to use `self.B`. | ||
| """ | ||
@@ -421,4 +422,4 @@ | ||
| # save prior | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -457,4 +458,4 @@ | ||
| >>> cv.update([i, i, i]) | ||
| >>> saved_k = cv.K[:] | ||
| >>> saved_P = cv.P[:] | ||
| >>> saved_k = np.copy(cv.K) | ||
| >>> saved_P = np.copy(cv.P) | ||
@@ -464,4 +465,4 @@ later on: | ||
| >>> cv = kinematic_kf(dim=3, order=2) # 3D const velocity filter | ||
| >>> cv.K = saved_K[:] | ||
| >>> cv.P = saved_P[:] | ||
| >>> cv.K = np.copy(saved_K) | ||
| >>> cv.P = np.copy(saved_P) | ||
| >>> for i in range(100): | ||
@@ -488,3 +489,3 @@ >>> cv.predict_steadystate() | ||
| self.z = z[:] # save the measurement | ||
| self.z = np.copy(z) # save the measurement | ||
@@ -561,3 +562,3 @@ if self.compute_log_likelihood: | ||
| self.z = z[:] # save the measurement | ||
| self.z = np.copy(z) # save the measurement | ||
@@ -584,38 +585,84 @@ if self.compute_log_likelihood: | ||
| Fs : list-like, optional | ||
| optional list of values to use for the state transition matrix matrix; | ||
| a value of None in any position will cause the filter | ||
| to use `self.F` for that time step. If Fs is None then self.F is | ||
| used for all epochs. | ||
| Fs : None, np.array or list-like, default=None | ||
| optional value or list of values to use for the state transition | ||
| matrix F. | ||
| Qs : list-like, optional | ||
| optional list of values to use for the process error | ||
| covariance; a value of None in any position will cause the filter | ||
| to use `self.Q` for that time step. If Qs is None then self.Q is | ||
| used for all epochs. | ||
| If Fs is None then self.F is used for all epochs. | ||
| Hs : list-like, optional | ||
| optional list of values to use for the measurement matrix; | ||
| a value of None in any position will cause the filter | ||
| to use `self.H` for that time step. If Hs is None then self.H is | ||
| used for all epochs. | ||
| If Fs contains a single matrix, then it is used as F for all | ||
| epochs. | ||
| Rs : list-like, optional | ||
| If it is a list of matrices or a 3D array where | ||
| len(Fs) == len(zs), then it is treated as a list of F values, one | ||
| per epoch. This allows you to have varying F per epoch. | ||
| Qs : None, np.array or list-like, default=None | ||
| optional value or list of values to use for the process error | ||
| covariance Q. | ||
| If Qs is None then self.Q is used for all epochs. | ||
| If Qs contains a single matrix, then it is used as Q for all | ||
| epochs. | ||
| If it is a list of matrices or a 3D array where | ||
| len(Qs) == len(zs), then it is treated as a list of Q values, one | ||
| per epoch. This allows you to have varying Q per epoch. | ||
| Hs : None, np.array or list-like, default=None | ||
| optional list of values to use for the measurement matrix H. | ||
| If Hs is None then self.H is used for all epochs. | ||
| If Hs contains a single matrix, then it is used as H for all | ||
| epochs. | ||
| If it is a list of matrices or a 3D array where | ||
| len(Hs) == len(zs), then it is treated as a list of H values, one | ||
| per epoch. This allows you to have varying H per epoch. | ||
| Rs : None, np.array or list-like, default=None | ||
| optional list of values to use for the measurement error | ||
| covariance; a value of None in any position will cause the filter | ||
| to use `self.R` for that time step. If Rs is None then self.R is | ||
| used for all epochs. | ||
| covariance R. | ||
| Bs : list-like, optional | ||
| optional list of values to use for the control transition matrix; | ||
| a value of None in any position will cause the filter | ||
| to use `self.B` for that time step. If Bs is None then self.B is | ||
| used for all epochs. | ||
| If Rs is None then self.R is used for all epochs. | ||
| us : list-like, optional | ||
| If Rs contains a single matrix, then it is used as H for all | ||
| epochs. | ||
| If it is a list of matrices or a 3D array where | ||
| len(Rs) == len(zs), then it is treated as a list of R values, one | ||
| per epoch. This allows you to have varying R per epoch. | ||
| Bs : None, np.array or list-like, default=None | ||
| optional list of values to use for the control transition matrix B. | ||
| If Bs is None then self.B is used for all epochs. | ||
| If Bs contains a single matrix, then it is used as B for all | ||
| epochs. | ||
| If it is a list of matrices or a 3D array where | ||
| len(Bs) == len(zs), then it is treated as a list of B values, one | ||
| per epoch. This allows you to have varying B per epoch. | ||
| us : None, np.array or list-like, default=None | ||
| optional list of values to use for the control input vector; | ||
| a value of None in any position will cause the filter to use | ||
| 0 for that time step. | ||
| update_first : bool, optional, | ||
| If us is None then None is used for all epochs (equivalent to 0, | ||
| or no control input). | ||
| If us contains a single matrix, then it is used as H for all | ||
| epochs. | ||
| If it is a list of matrices or a 3D array where | ||
| len(Rs) == len(zs), then it is treated as a list of R values, one | ||
| per epoch. This allows you to have varying R per epoch. | ||
| update_first : bool, optional, default=False | ||
| controls whether the order of operations is update followed by | ||
@@ -654,9 +701,12 @@ predict, or predict followed by update. Default is predict->update. | ||
| # this example demonstrates tracking a measurement where the time | ||
| # between measurement varies, as stored in dts. This requires | ||
| # that F be recomputed for each epoch. The output is then smoothed | ||
| # with an RTS smoother. | ||
| zs = [t + random.randn()*4 for t in range (40)] | ||
| Fs = [kf.F for t in range (40)] | ||
| Hs = [kf.H for t in range (40)] | ||
| Fs = [np.array([[1., dt], [0, 1]] for dt in dts] | ||
| (mu, cov, _, _) = kf.batch_filter(zs, Rs=R_list, Fs=Fs, Hs=Hs, Qs=None, | ||
| Bs=None, us=None, update_first=False) | ||
| (xs, Ps, Ks) = kf.rts_smoother(mu, cov, Fs=Fs, Qs=None) | ||
| (mu, cov, _, _) = kf.batch_filter(zs, Fs=Fs) | ||
| (xs, Ps, Ks) = kf.rts_smoother(mu, cov, Fs=Fs) | ||
| """ | ||
@@ -667,21 +717,20 @@ | ||
| if Fs is None: | ||
| Fs = [self.F] * n | ||
| Fs = self.F | ||
| if Qs is None: | ||
| Qs = [self.Q] * n | ||
| Qs = self.Q | ||
| if Hs is None: | ||
| Hs = [self.H] * n | ||
| Hs = self.H | ||
| if Rs is None: | ||
| Rs = [self.R] * n | ||
| Rs = self.R | ||
| if Bs is None: | ||
| Bs = [self.B] * n | ||
| Bs = self.B | ||
| if us is None: | ||
| us = [0] * n | ||
| us = 0 | ||
| #pylint: disable=multiple-statements | ||
| if len(Fs) < n: Fs = [Fs] * n | ||
| if len(Qs) < n: Qs = [Qs] * n | ||
| if len(Hs) < n: Hs = [Hs] * n | ||
| if len(Rs) < n: Rs = [Rs] * n | ||
| if len(Bs) < n: Bs = [Bs] * n | ||
| if len(us) < n: us = [us] * n | ||
| Fs = repeated_array(Fs, n) | ||
| Qs = repeated_array(Qs, n) | ||
| Hs = repeated_array(Hs, n) | ||
| Rs = repeated_array(Rs, n) | ||
| Bs = repeated_array(Bs, n) | ||
| us = repeated_array(us, n) | ||
@@ -974,2 +1023,3 @@ | ||
| def test_matrix_dimensions(self, z=None, H=None, R=None, F=None, Q=None): | ||
@@ -1440,8 +1490,8 @@ """ | ||
| #pylint: disable=multiple-statements | ||
| if len(Fs) < n: Fs = [Fs]*n | ||
| if len(Qs) < n: Qs = [Qs]*n | ||
| if len(Hs) < n: Hs = [Hs]*n | ||
| if len(Rs) < n: Rs = [Rs]*n | ||
| if len(Bs) < n: Bs = [Bs]*n | ||
| if len(us) < n: us = [us]*n | ||
| Fs = repeated_array(Fs, n) | ||
| Qs = repeated_array(Qs, n) | ||
| Hs = repeated_array(Hs, n) | ||
| Rs = repeated_array(Rs, n) | ||
| Bs = repeated_array(Bs, n) | ||
| us = repeated_array(us, n) | ||
@@ -1602,8 +1652,8 @@ | ||
| kf = self.kf | ||
| self.xs.append(kf.x[:]) | ||
| self.Ps.append(kf.P[:]) | ||
| self.Ks.append(kf.K[:]) | ||
| self.ys.append(kf.y[:]) | ||
| self.xs_prior.append(kf.x_prior[:]) | ||
| self.Ps_prior.append(kf.P_prior[:]) | ||
| self.xs.append(np.copy(kf.x)) | ||
| self.Ps.append(np.copy(kf.P)) | ||
| self.Ks.append(np.copy(kf.K)) | ||
| self.ys.append(np.copy(kf.y)) | ||
| self.xs_prior.append(np.copy(kf.x_prior)) | ||
| self.Ps_prior.append(np.copy(kf.P_prior)) | ||
@@ -1610,0 +1660,0 @@ |
@@ -84,9 +84,12 @@ # -*- coding: utf-8 -*- | ||
| self.dim_x = dim_x | ||
| self.H = H[:] | ||
| if H is None: | ||
| self.H = None | ||
| else: | ||
| self.H = np.copy(H) | ||
| # try to form a reasonable initial values, but good luck! | ||
| try: | ||
| self.z = filters[0].z[:] | ||
| self.x = filters[0].x[:] | ||
| self.P = filters[0].P[:] | ||
| self.z = np.copy(filters[0].z) | ||
| self.x = np.copy(filters[0].x) | ||
| self.P = np.copy(filters[0].P) | ||
@@ -166,3 +169,3 @@ except AttributeError: | ||
| try: | ||
| self.z = z[:] | ||
| self.z = np.copy(z) | ||
| except IndexError: | ||
@@ -169,0 +172,0 @@ self.z = z |
@@ -155,4 +155,4 @@ # -*- coding: utf-8 -*- | ||
| # copy prior | ||
| self.x_prior = self.x[:] | ||
| self._P1_2_prior = self._P1_2[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self._P1_2_prior = np.copy(self._P1_2) | ||
@@ -228,4 +228,4 @@ | ||
| # copy prior | ||
| self.x_prior = self.x[:] | ||
| self._P1_2_prior = self._P1_2[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self._P1_2_prior = np.copy(self._P1_2) | ||
@@ -232,0 +232,0 @@ |
@@ -273,3 +273,3 @@ # -*- coding: utf-8 -*- | ||
| Ms, Ps = kf.batch_filter(zs) | ||
| smooth_x, _, _ = kf.rts_smoother(Ms, Ps, dt=dt) | ||
| smooth_x, _, _ = kf.rts_smoother(Ms, Ps, dts=dt) | ||
@@ -315,3 +315,3 @@ if DO_PLOT: | ||
| Ms, Ps = kf.batch_filter(zs) | ||
| smooth_x, _, _ = kf.rts_smoother(Ms, Ps, dt=dt) | ||
| smooth_x, _, _ = kf.rts_smoother(Ms, Ps, dts=dt) | ||
@@ -900,4 +900,4 @@ if DO_PLOT: | ||
| ukf.x = np.array([0., 1.]) | ||
| ukf.R = oc[:] | ||
| ukf.Q = tc[:] | ||
| ukf.R = np.copy(oc) | ||
| ukf.Q = np.copy(tc) | ||
| s = Saver(ukf) | ||
@@ -910,6 +910,6 @@ s.save() | ||
| kf.x = np.array([[0., 1]]).T | ||
| kf.R = oc[:] | ||
| kf.Q = tc[:] | ||
| kf.H = H[:] | ||
| kf.F = F[:] | ||
| kf.R = np.copy(oc) | ||
| kf.Q = np.copy(tc) | ||
| kf.H = np.copy(H) | ||
| kf.F = np.copy(F) | ||
@@ -916,0 +916,0 @@ |
+55
-21
@@ -28,3 +28,3 @@ # -*- coding: utf-8 -*- | ||
| from filterpy.stats import logpdf | ||
| from filterpy.common import pretty_str | ||
| from filterpy.common import pretty_str, repeated_array | ||
@@ -286,4 +286,4 @@ | ||
| self.P = eye(dim_x) | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
| self.Q = eye(dim_x) | ||
@@ -335,4 +335,4 @@ self.R = eye(dim_z) | ||
| # save prior | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -367,3 +367,2 @@ | ||
| optional keyword arguments to be passed into f(x). | ||
| variable. | ||
| """ | ||
@@ -385,4 +384,4 @@ | ||
| # save prior | ||
| self.x_prior = self.x[:] | ||
| self.P_prior = self.P[:] | ||
| self.x_prior = np.copy(self.x) | ||
| self.P_prior = np.copy(self.P) | ||
@@ -504,10 +503,27 @@ | ||
| Rs : list-like, optional | ||
| Rs : None, np.array or list-like, default=None | ||
| optional list of values to use for the measurement error | ||
| covariance; a value of None in any position will cause the filter | ||
| to use `self.R` for that time step. | ||
| covariance R. | ||
| dts : list-like, optional | ||
| optional list of delta time to be passed into predict. | ||
| If Rs is None then self.R is used for all epochs. | ||
| If Rs contains a single matrix, then it is used as H for all | ||
| epochs. | ||
| If it is a list of matrices or a 3D array where | ||
| len(Rs) == len(zs), then it is treated as a list of R values, one | ||
| per epoch. This allows you to have varying R per epoch. | ||
| dts : None, scalar or list-like, default=None | ||
| optional value or list of delta time to be passed into predict. | ||
| If dtss is None then self.dt is used for all epochs. | ||
| If dts contains a single matrix, then it is used as dt for all | ||
| epochs. | ||
| If it is a list where len(dts) == len(zs), then it is treated as a | ||
| list of dt values, one per epoch. This allows you to have varying | ||
| epoch durations. | ||
| UT : function(sigmas, Wm, Wc, noise_cov), optional | ||
@@ -534,2 +550,17 @@ Optional function to compute the unscented transform for the sigma | ||
| In other words `covariance[k,:,:]` is the covariance at step `k`. | ||
| Examples | ||
| -------- | ||
| .. code-block:: Python | ||
| # this example demonstrates tracking a measurement where the time | ||
| # between measurement varies, as stored in dts The output is then smoothed | ||
| # with an RTS smoother. | ||
| zs = [t + random.randn()*4 for t in range (40)] | ||
| (mu, cov, _, _) = ukf.batch_filter(zs, dts=dts) | ||
| (xs, Ps, Ks) = ukf.rts_smoother(mu, cov) | ||
| """ | ||
@@ -553,7 +584,10 @@ #pylint: disable=too-many-arguments | ||
| if Rs is None: | ||
| Rs = [None] * z_n | ||
| Rs = self.R | ||
| if dts is None: | ||
| dts = [self._dt] * z_n | ||
| dts = self._dt | ||
| Rs = repeated_array(Rs, z_n) | ||
| dts = repeated_array(dts, z_n) | ||
| # mean estimates from Kalman Filter | ||
@@ -580,3 +614,3 @@ if self.x.ndim == 1: | ||
| def rts_smoother(self, Xs, Ps, Qs=None, dt=None): | ||
| def rts_smoother(self, Xs, Ps, Qs=None, dts=None): | ||
| """ | ||
@@ -636,6 +670,6 @@ Runs the Rauch-Tung-Striebal Kalman smoother on a set of | ||
| if dt is None: | ||
| dt = [self._dt] * n | ||
| elif isscalar(dt): | ||
| dt = [dt] * n | ||
| if dts is None: | ||
| dts = [self._dt] * n | ||
| elif isscalar(dts): | ||
| dts = [dts] * n | ||
@@ -657,3 +691,3 @@ if Qs is None: | ||
| for i in range(num_sigmas): | ||
| sigmas_f[i] = self.fx(sigmas[i], dt[k]) | ||
| sigmas_f[i] = self.fx(sigmas[i], dts[k]) | ||
@@ -660,0 +694,0 @@ xb, Pb = unscented_transform( |
+2
-2
| Metadata-Version: 1.1 | ||
| Name: filterpy | ||
| Version: 1.4.0 | ||
| Version: 1.4.1 | ||
| Summary: Kalman filtering and optimal estimation library | ||
@@ -62,3 +62,3 @@ Home-page: https://github.com/rlabbe/filterpy | ||
| Why 3.5+, and not 3.3+? 3.5 introduced the matrix multiply symbol, | ||
| Why 3.5+, and not 3.4+? 3.5 introduced the matrix multiply symbol, | ||
| and I want my code to take advantage of it. Plus, to be honest, | ||
@@ -65,0 +65,0 @@ I'm being selfish. I don't want to spend my life supporting this |
+1
-1
@@ -53,3 +53,3 @@ FilterPy - Kalman filters and other optimal and non-optimal estimation filters in Python. | ||
| Why 3.5+, and not 3.3+? 3.5 introduced the matrix multiply symbol, | ||
| Why 3.5+, and not 3.4+? 3.5 introduced the matrix multiply symbol, | ||
| and I want my code to take advantage of it. Plus, to be honest, | ||
@@ -56,0 +56,0 @@ I'm being selfish. I don't want to spend my life supporting this |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.