Skip to main content

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 Real/Complex
lattice/ (Lattice-based RLS) LRLSPosteriori, LRLSErrorFeedback, LRLSPriori, NormalizedLRLS Complex
fast_rls/ (Fast Transversal RLS) FastRLS, StabFastRLS Real
qr_decomposition/ (QR-RLS) QRRLS Real
iir/ (Adaptive IIR) ErrorEquation, GaussNewton, GaussNewtonGradient, RLSIIR, SteiglitzMcBride Real
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 Complex
base/ (Core API) AdaptiveFilter N/A

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 v4.

Documentation and docstrings were refined using AI assistance to ensure the NumPy/SciPy documentation standards and mathematical clarity.

Metadata

Release files for pydaptivefiltering 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydaptivefiltering 1.0.0
File Size Uploaded
pydaptivefiltering-1.0.0.tar.gz 94.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pydaptivefiltering 1.0.0
File Interpreter ABI Platform
pydaptivefiltering-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 282.1 kB

Release files / pydaptivefiltering-1.0.0.tar.gz

Download URL pydaptivefiltering-1.0.0.tar.gz
Size 94.9 kB
Tags Source
SHA-256 checksum
How to use checksums
074bf426167f7d860a51e373e6cb6ddd0399bf38f6b3f4400dbda3472f2f14bc
BLAKE2b-256 checksum
How to use checksums
d3cf1595a6b7d69a9b84bda35765e87fa90b32877a7799b2beb4dc624682093d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release files / pydaptivefiltering-1.0.0-py3-none-any.whl

Download URL pydaptivefiltering-1.0.0-py3-none-any.whl
Size 187.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
746419fb12eaff4e81986d4d376be025b573c363ed96f51eeb599518f41319d8
BLAKE2b-256 checksum
How to use checksums
9cf01959a514ba00c96ba2a93c50e3554a40996f006fe28c42f61e5671b7bcde
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.9

2 release files

0.7.0

2 release files

0.3

1 release file

0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page