Skip to main content

A modern Python implementation of the AdaptiveFiltering toolbox.

Project description

pydaptivefiltering

Adaptive filtering in Python
Implementations based on Adaptive Filtering: Algorithms and Practical Implementation (Paulo S. R. Diniz).

PyPI version Docs License

📌 Table of Contents


Install

pip install pydaptivefiltering

Requirements

  • Python 3.10+ (tested on )
  • NumPy, SciPy

Implementation and Examples

All algorithms follow the same pattern:

  1. Instantiate the filter/model
  2. Run optimize(input_signal, desired_signal)
  3. Inspect outputs, errors, coefficients, and optional extra

Returned dictionary keys:

  • outputs: model output
  • errors: error sequence (see error_type)
  • coefficients: coefficient history (snapshots over time)
  • runtime_s: runtime in seconds
  • error_type: "a_priori", "a_posteriori", or "output_error"
  • extra: optional internal states (when enabled)

System identification (Complex example with RLS):

import numpy as np
import pydaptivefiltering as pdf

rng = np.random.default_rng(0)

# True system (complex FIR)
w_true = np.array([0.5+0.2j, -0.4+0.5j, 0.1-0.1j, 0.2+0j, -0.1+0.1j, 0.0+0.05j])
M = len(w_true) - 1

# Data
N = 5000
x = (rng.standard_normal(N) + 1j*rng.standard_normal(N)) / np.sqrt(2)
noise = 0.05 * (rng.standard_normal(N) + 1j*rng.standard_normal(N)) / np.sqrt(2)

# Desired: d[k] = w^H x_k + noise
x_pad = np.concatenate([np.zeros(M, dtype=complex), x])
d = np.array([np.vdot(w_true, x_pad[k:k+M+1][::-1]) for k in range(N)]) + noise

# RLS
rls = pdf.RLS(filter_order=M, delta=1.0, forgetting_factor=0.995)
res = rls.optimize(x, d)

Coefficients convergence plot


Example: Neural Adaptive Filtering (MLP)

Nonlinear system:

$$d(k) = x(k)^2 + 0.5,x(k-1) + \eta(k) $$

import numpy as np
import matplotlib.pyplot as plt
import pydaptivefiltering as pdf

rng = np.random.default_rng(1)

# Data
N = 3000
x = rng.uniform(-1, 1, N)
d = np.zeros(N)
for k in range(1, N):
    d[k] = (x[k]**2) + 0.5*x[k-1] + 0.01*rng.standard_normal()

# MLP
mlp = pdf.MultilayerPerceptron(
    n_neurons=8,
    input_dim=3,
    step_size=0.01,
    momentum=0.9,
    activation="tanh",
)

res = mlp.optimize(x, d)

plt.plot(10*np.log10(res.errors**2 + 1e-12), alpha=0.8)
plt.title(f"MLP Convergence (Final MSE: {np.mean(res.errors[-500:]**2):.6f})")
plt.xlabel("Iteration")
plt.ylabel("Squared Error (dB)")
plt.show()

RBF learning curve

RBF weights convergence


Example: Kalman Filter Tracking (Constant-Velocity with Maneuvers)

arget-tracking example using a 2-state constant-velocity (CV) Kalman filter (position/velocity). The target performs piecewise acceleration maneuvers, while we measure position only with additive noise; the filter estimates both position and velocity from the noisy measurements.

import numpy as np
import pydaptivefiltering as pdf

rng = np.random.default_rng(7)

# 1) Synthetic target: constant-velocity model with acceleration maneuvers
N, dt = 400, 1.0
x_true = np.zeros((N, 2), dtype=float)   # [pos, vel]

a = np.zeros(N)
a[60:120]  =  0.08
a[180:230] = -0.12
a[300:340] =  0.05

x_true[0] = [0.0, 1.0]
for k in range(1, N):
    pos_prev, vel_prev = x_true[k - 1]
    x_true[k, 1] = vel_prev + a[k] * dt
    x_true[k, 0] = pos_prev + vel_prev * dt + 0.5 * a[k] * dt**2

sigma_meas = 0.8
y = x_true[:, 0] + sigma_meas * rng.standard_normal(N)

# 2) Kalman filter (CV: position/velocity), measuring position only
A = np.array([[1.0, dt],
              [0.0, 1.0]])

C_T = np.array([[1.0, 0.0]])  # shape (p=1, n=2)

sigma_a = 0.15
Q = (sigma_a**2) * np.array([[dt**4/4, dt**3/2],
                             [dt**3/2, dt**2]])

Rn  = Q
Rn1 = np.array([[sigma_meas**2]])

kf = pdf.Kalman(
    A=A,
    C_T=C_T,
    Rn=Rn,
    Rn1=Rn1,
    x_init=np.array([y[0], 0.0]),
    Re_init=np.eye(2) * 50.0,
)

res = kf.optimize(y)

x_hat = res.outputs
innov = res.errors

rmse_pos = np.sqrt(np.mean((x_hat[:, 0] - x_true[:, 0])**2))
rmse_vel = np.sqrt(np.mean((x_hat[:, 1] - x_true[:, 1])**2))

print(f"RMSE position: {rmse_pos:.3f}")
print(f"RMSE velocity: {rmse_vel:.3f}")
print(f"Innovation std: {innov.std():.3f}")

Kalman tracking

Kalman innovation


Algorithms (overview)

This is an overview. For the full list, check the documentation: Docs

Algorithms categories are based on the chapters of the book Adaptive Filtering: Algorithms and Practical Implementation (Paulo S. R. Diniz).

Module / Category Exported classes (examples) Data type
lms/ (LMS family) LMS, NLMS, AffineProjection, SignData, SignError, DualSign, LMSNewton, Power2ErrorLMS, TDomainLMS, TDomainDCT, TDomainDFT Real/Complex
rls/ (RLS family) RLS, RLSAlt Complex
set_membership/ (Set-membership) SMNLMS, SMBNLMS, SMAffineProjection, SimplifiedSMAP, SimplifiedSMPUAP Complex
lattice/ (Lattice-based RLS) LRLSPosteriori, LRLSErrorFeedback, LRLSPriori, NormalizedLRLS Real/Complex
fast_rls/ (Fast Transversal RLS) FastRLS, StabFastRLS Complex
qr_decomposition/ (QR-RLS) QRRLS Real
iir/ (Adaptive IIR) ErrorEquation, GaussNewton, GaussNewtonGradient, RLSIIR, SteiglitzMcBride Real/Complex
nonlinear/ (Nonlinear models) VolterraLMS, VolterraRLS, BilinearRLS, RBF, ComplexRBF, MultilayerPerceptron Real/Complex
subband/ (Subband) OLSBLMS, DLCLLMS, CFDLMS Real
blind/ (Blind equalization) CMA, Godard, Sato, AffineProjectionCM Complex
kalman/ (Kalman) Kalman Real
base/ (Core API) AdaptiveFilter N/A

Known limitations (this release)

  • ⚠️ set_membership.simplified_puap.py: under technical review (convergence may differ from reference).
  • ⚠️ nonlinear.complex_rbf.py: under technical review (convergence may differ from reference).

Notebooks


📝 License

This project is under the license found at LICENSE.

GitHub repo size GitHub language count GitHub forks

References

  • Diniz, P. S. R. (2020). Adaptive Filtering: Algorithms and Practical Implementation. Springer.
  • MATLAB Adaptive Filtering Toolbox (for comparison).

Footer image

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydaptivefiltering-0.9.tar.gz (107.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydaptivefiltering-0.9-py3-none-any.whl (166.1 kB view details)

Uploaded Python 3

File details

Details for the file pydaptivefiltering-0.9.tar.gz.

File metadata

  • Download URL: pydaptivefiltering-0.9.tar.gz
  • Upload date:
  • Size: 107.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for pydaptivefiltering-0.9.tar.gz
Algorithm Hash digest
SHA256 565c4b7c6270f6c756b96b25bf734fd1124b45b57152f3f7c672150806fc527a
MD5 5228cefe3b9f25d932ef57ddcec456c8
BLAKE2b-256 96a5bb19311eee279d42e91d161ff05ece6f9464e381026096e31b07d1b8c5e8

See more details on using hashes here.

File details

Details for the file pydaptivefiltering-0.9-py3-none-any.whl.

File metadata

File hashes

Hashes for pydaptivefiltering-0.9-py3-none-any.whl
Algorithm Hash digest
SHA256 885d4f5b36bbc46e58fb5086d0c7a2240cdf8615a08d77d27d0d9e7f857a18ca
MD5 996a9c14fc633b14d90e58503a7077d8
BLAKE2b-256 23cdd8469fe3d4432e91fbe2c94e878a63d1bdd9a0d0bec82ee5346b2c155e09

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page