# Adaptif
[](https://github.com/bglid/adaptif/actions)
[](https://github.com/astral-sh/ruff)
[](https://github.com/bglid/adaptif/blob/main/LICENSE)
#### Rust crate for DSP Adaptive Filters with Python bindings.
---
## Overview
This project contains Rust implementations of [adaptive filtering](https://en.wikipedia.org/wiki/Adaptive_filter) algorithms, with bindings for Python.
Currently, the following algorithms are supported:
| Least Mean Squares (LMS) | ✔ |
| Normalized Least Mean Squares (NLMS) | ✔ |
| Recursive Least Squares (RLS) | ✔ |
| Affine Projection Algorithm (APA) | _in progress_ |
We're also working on real-time processing and `no_std` functionality for use in embedded systems, which are planned for the next major release.
---
## Installation
The projects currently supports Rust stable (no MSRV) and Python 3.11 - 3.15.
#### Rust crate
Via crates.io:
```bash
cargo add adaptif
```
#### Python bindings
Via PyPI:
```bash
# With uv (preferred).
uv add adaptif
```
```bash
# With pip.
pip install adaptif
```
- - -
## Usage
This section shows basic examples for a least mean squares (LMS) filter in Rust and Python.
Here:
- `input_signal` is the desired/noisy signal. Commonly referred to as `d(n)` in mathematical notation.
- `noise_ref` is the reference noise signal. Commonly referred to as `x(n)` in mathematical notation.
More examples can be found in `examples/`.
### Rust
```rust
use adaptif::filters::{LmsFilter, LmsOptions, ProcessingMode};
use adaptif::types::{InputSignal, NoiseReference};
// Sample inputs
let input_signal = InputSignal::new(vec![1.0, -2.5, 3.0])?;
let noise_ref = NoiseReference::new(vec![2.0, -1.2, -3.8])?;
// Initialize the filter
let mut lms = LmsFilter::new(
LmsOptions {
step_size: 0.1, // How fast the filter adapts
window_size: 16, // How many samples the filter processes at a time
},
ProcessingMode::Sample,
)?;
// Adapt the filter to the inputs and get the iteratively cleaned signal.
let cleaned_signal = lms.adapt(&input_signal, &noise_ref)?;
Ok(())
```
### Python
```python
from adaptif import LMSFilter
# setting up filter
lms = LMSFilter(step_size=0.1, window_size=16)
# Assuming signals are already present and named accordingly
cleaned_signal = lms.adapt(input_signal=noisy_signal, noise_ref=noise)
```
---
## Contributing
See [CONTRIBUTING.md](https://github.com/bglid/adaptif/blob/main/CONTRIBUTING.md) for setup and contribution guidelines.
In short,
- Open an issue for a discussion. We will likely handle it.
- Undisclosed AI PRs will be closed and no further PRs from said user will be considered.
---
## Citation
If you found any of this helpful, feel free to cite it, or just send us an email.
```bibtex
@misc{adaptif,
authors = {Benjamin Glidden, Elias Naske},
title = {Adaptif: Rust crate for DSP adaptive filters with Python bindings},
year = {2026},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/bglid/adaptif}}
}
```
---