Giter Club home page Giter Club logo

whittaker-eilers's Introduction

Whittaker-Eilers Smoothing and Interpolation

The Whittaker-Eilers smoother is the perfect smoother. It offers extremely quick, efficient smoothing with built-in interpolation via weights on each measurement. This crate provides a sparse-matrix implementation for additional speed and memory efficiency and can handle both equally and unequally spaced measurements.


[dependencies]
whittaker-eilers = "0.1.3"

Usage

To start smoothing and interpolating data, create a reusable WhittakerSmoother struct via the new function. You'll only need to recreate this struct if the length or sampling rate of your data changes.

Equally spaced data

This is the fastest smoothing option. It smooths equally spaced y measurements using two tunable parameters, lambda (2e4) and the smoother order (2). The larger the lambda, the smoother the data.

use whittaker_eilers::WhittakerSmoother;

let data_to_smooth = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0];

let whittaker_smoother = 
            WhittakerSmoother::new(2e4, 2, data_to_smooth.len(), None, None)
            .unwrap();

let smoothed_data = whittaker_smoother.smooth(&data_to_smooth).unwrap();
println!("Smoothed data: {:?}", smoothed_data);

Non-equally spaced data

If you wish to smooth unequally spaced data, you need to provide an x_input with the sample times/positions.

use whittaker_eilers::WhittakerSmoother;

let x_input = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0];
let data_to_smooth = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0];

let whittaker_smoother = 
            WhittakerSmoother::new(2e4, 2, data_to_smooth.len(), Some(&x_input), None)
            .unwrap();

let smoothed_data = whittaker_smoother.smooth(&data_to_smooth).unwrap();

println!("Smoothed data: {:?}", smoothed_data);

Weighted data & Interpolation

Each measurement can then be weighted to trust some measurements more than others. Setting weights to 0 for measurements will lead to interpolation.

use whittaker_eilers::WhittakerSmoother;

let x_input = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0];
let data_to_smooth = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0];
let mut weights = vec![1.0; x_input.len()];
weights[5] = 0.0;

let whittaker_smoother =
            WhittakerSmoother::new(2e4, 2, data_to_smooth.len(), Some(&x_input), Some(&weights))
            .unwrap();

let smoothed_data = whittaker_smoother.smooth(&data_to_smooth).unwrap();

println!("Smoothed data: {:?}", smoothed_data);

Smoothing with cross validation

With this package, you can also calculate the cross validation error alongside the smoothed series. This shouldn't really be used in production where speed is necessary though!

use whittaker_eilers::WhittakerSmoother;

let x_input = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0 ,11.0, 12.0, 13.0];
let data_to_smooth = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0, 11.0, 12.0, 13.0];

let whittaker_smoother = 
            WhittakerSmoother::new(2e4, 2, data_to_smooth.len(), Some(&x_input), None)
            .unwrap();

let smoothed_and_cross_validated = whittaker_smoother.smooth_and_cross_validate(&data_to_smooth).unwrap();

println!("Result: {:?}", smoothed_and_cross_validated);

Automatic smoothing

Smoothing data requires a choice of Lambda. This can be done using visual inspection or by finding the lambda which results in the lowest cross validation error. The smooth_optimal function runs the smoother for a variety of lambdas and returns the results with the ability to retrieve the optimal one.

use whittaker_eilers::WhittakerSmoother;

let x_input = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0 ,11.0, 12.0, 13.0];
let data_to_smooth = vec![1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0, 11.0, 12.0, 13.0];

let mut whittaker_smoother = 
            WhittakerSmoother::new(2e4, 2, data_to_smooth.len(), Some(&x_input), None)
            .unwrap();

let results = whittaker_smoother.smooth_optimal(&data_to_smooth,  true).unwrap();

println!("Result: {:?}", results);

println!("Optimal result: {:?}", results.get_optimal());

You can use these methods in combination with each other for instance, interpolating measurements without providing an x input. For more advanced examples of usage take a look at the examples, tests, and benches in the Github repository. Here's an image of some smoothed data from an example:

Time-series smoothed by Whittaker-Eilers method

Further Reading

If you'd like to see a more detailed run through of the library, check out this Medium post. Within it, I run through examples and benchmarks against other smoothing methods.

Future Features

  • Scatter plot smoothing
  • Generic typing

References

The algorithm implemented here mirrors a 2003 implementation by Paul H. C. Eilers in Matlab. I've included scripts and data from the original paper in the tests for this crate. The original paper and code can be found here:

A Perfect Smoother Paul H. C. Eilers Analytical Chemistry 2003 75 (14), 3631-3636 DOI: 10.1021/ac034173t

whittaker-eilers's People

Contributors

anbowell avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.