{"id":31223480,"url":"https://github.com/mathiswellmann/whittaker_smoother","last_synced_at":"2025-09-21T22:45:26.772Z","repository":{"id":187554532,"uuid":"677121132","full_name":"MathisWellmann/whittaker_smoother","owner":"MathisWellmann","description":"A perfect smoother; A discrete time version of spline smoothing for equally spaced data","archived":false,"fork":false,"pushed_at":"2023-10-05T09:19:49.000Z","size":3171,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2023-10-05T13:20:23.769Z","etag":null,"topics":["derivative","filter","linear-algebra","lu","rust","signal-processing","smoother"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MathisWellmann.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-10T19:41:12.000Z","updated_at":"2023-08-12T19:31:35.000Z","dependencies_parsed_at":"2023-08-11T03:54:59.487Z","dependency_job_id":"a73bbe1e-649e-4f7c-94d5-44898ac8855a","html_url":"https://github.com/MathisWellmann/whittaker_smoother","commit_stats":null,"previous_names":["mathiswellmann/whittaker_smoother"],"tags_count":1,"template":null,"template_full_name":null,"purl":"pkg:github/MathisWellmann/whittaker_smoother","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MathisWellmann%2Fwhittaker_smoother","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MathisWellmann%2Fwhittaker_smoother/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MathisWellmann%2Fwhittaker_smoother/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MathisWellmann%2Fwhittaker_smoother/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MathisWellmann","download_url":"https://codeload.github.com/MathisWellmann/whittaker_smoother/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MathisWellmann%2Fwhittaker_smoother/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276319015,"owners_count":25621651,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-21T02:00:07.055Z","response_time":72,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["derivative","filter","linear-algebra","lu","rust","signal-processing","smoother"],"created_at":"2025-09-21T22:45:25.834Z","updated_at":"2025-09-21T22:45:26.754Z","avatar_url":"https://github.com/MathisWellmann.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Whittaker Smoother\nAka Whittaker-Henderson, Whittaker-Eilers Smoother is known as the perfect smoother.\nIts a discrete-time version of spline smoothing for equally spaced data.\nIt minimizes the functional\n\n$$\\sum_{i=0}^n (z_i - y_i)^2 + \\lambda \\sum_{i=0}^n (\\delta ^p z)_i ^2  $$\n\nwhere y are the datapoints, z is the smoothed function, and $\\delta^2\nz$ is the pth derivative of $z_i$, which is evaluated numerically.\nA penalty is imposed on nonsmooth functions, with higher values of $\\lambda$ increasing the penalty and leading to a smoother output.\n\nThe smoothed output can be obtained by solving the linear system\n$$x = (W + \\lambda * D^T D )^{-1} W y $$\nWhere W is the weight matrix (Identity matrix in practice) and D is the difference matrix \n(See [`difference_matrix`](src/whittaker_smoother.rs) for its construction).\n\n### Examples\nHere we see the wood dataset smoothed whith both order 2 and 3.\n![wood_2](img/whittaker_on_wood_lambda_20000_order_2.png)\n![wood_3](img/whittaker_on_wood_lambda_20000_order_3.png)\n\n### Comparison to Moving Averages and Convolution Kernels\nCompared to a moving average smoother, this method does not suffer from a group-delay.\n\nCompared to a convolution kernel such as the savitzky-golay filter, \nthe values at the edge are well defined and don't need to be interpolated. \nThe savitzky-golay filter does have a nice flat passband,\nbut suffers from unsatisfactory high-frequency noise, which is not sufficiently suppressed. \nThis is a particular problem when the derivative of the data is of importance.\n\nHowever, this smoother takes future values into account and therefore suffers from a look-ahead bias.\n\n### Usage\nTo use this smoother in you project, add this to your `Cargo.toml`:\n```toml\n[dependencies]\nwhittaker_smoother = \"0.1\"\n```\n\nNow you can use the smoothing function as such:\n```ignore\nuse whittaker_smoother::whittaker_smoother;\n\n// Here we use the WOOD_DATASET, but this can be any series that you would like to smooth\nlet raw = Vec::from_iter(WOOD_DATASET.iter().map(|v| *v as f64));\nlet lambda = 2e4;\nlet order = 3;\nlet smoothed = whittaker_smoother(\u0026raw, lambda, order).unwrap();\n```\nAnd BAM, that's it! There is you perfectly smoothed series.\n\n### Further Reading:\nSee the [papers](./papers/) folder for two papers showing additional details of the method.\n\nThis implementation was inspired by [A python implementation](https://github.com/mhvwerts/whittaker-eilers-smoother).\n\n### Potential Upgrades:\n- Add benchmarks\n- Use sparse matrices if available\n- Add function for computing the optimal lambda based on cross-validation (See eilers2003)\n\n### License\nCopyright (C) 2020  \u003cMathis Wellmann wellmannmathis@gmail.com\u003e\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU Affero General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU Affero General Public License for more details.\n\nYou should have received a copy of the GNU Affero General Public License\nalong with this program.  If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n\n![GNU AGPLv3](img/agplv3.png)\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathiswellmann%2Fwhittaker_smoother","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmathiswellmann%2Fwhittaker_smoother","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathiswellmann%2Fwhittaker_smoother/lists"}