2 unstable releases

0.1.0 May 22, 2024
0.0.1 Jan 29, 2024

#176 in Robotics

Download history 14/week @ 2024-02-17 9/week @ 2024-02-24 1/week @ 2024-03-02 10/week @ 2024-03-30 2/week @ 2024-04-06 140/week @ 2024-05-18 10/week @ 2024-05-25

150 downloads per month

MIT/Apache

28KB
438 lines

butterworth - simple filters for noisy data

This crate implements digital Butterworth filters for time series data. Filters of arbitrary order can be created and applied to data. Lowpass, highpass, bandpass, and bandstop filters are supported.

Transfer function creation is primarily based on scipy.signal.butter. The bidirectional filter function is designed to match the behavior of MATLAB's filtfilt function. If the default signal padding behavior of used by SciPy's filtfilt is desired, the bidirectional_with_padding function can be used with a padding length of 3 * (filter.order() + 1).


lib.rs:

Butterworth Filter - Simple filters for noisy data

This crate implements digital Butterworth filters for time series data. Filters of arbitrary order can be created and applied to data. Lowpass, highpass, bandpass, and bandstop filters are supported.

Transfer function creation is primarily based on scipy.signal.butter. The bidirectional filter function is designed to match the behavior of MATLAB's filtfilt function. If the default signal padding behavior of used by SciPy's filtfilt is desired, the bidirectional_with_padding function can be used with a padding length of 3 * (filter.order() + 1).

Examples

use butterworth::{Filter, Cutoff};

// Create a mix of low and high frequency sine functions
let data = (0..=100).map(|x| x as f64).map(|x| (x * 0.1).sin() + (x * 0.75).sin()).collect();
// Assuming the sample rate is 100 Hz, design a 4th order lowpass filter with an 8 Hz cutoff
let filter = Filter::new(4, 100., Cutoff::LowPass(8.)).unwrap();
// Apply a bidirectional filter to the data
let filtered_data = filter.bidirectional(&data).unwrap();
// Create expected lower frequency component output
let expected = (0..=100).map(|x| x as f64).map(|x| (x * 0.1).sin()).collect::<Vec<f64>>();
// The filtered data should roughly match the lower frequency component, particularly in middle
for i in 8..filtered_data.len() - 8 {
    assert!((filtered_data[i] - expected[i]).abs() < 5e-2);
}

// Manually specify a padding length if the default behavior of SciPy is desired
let filtered_data = filter.bidirectional_with_padding(&data, 3 * (filter.order() + 1)).unwrap();

Dependencies

~270KB