Skip to content

Commit

Permalink
ci: 👷 GitHub actions added to build out Python package
Browse files Browse the repository at this point in the history
  • Loading branch information
AnBowell committed Oct 12, 2023
1 parent d144d48 commit bb621e3
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 368 deletions.
Binary file added .github/workflows/CI.yml
Binary file not shown.
52 changes: 40 additions & 12 deletions whittaker-eilers-py/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 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 package provides a sparse-matrix implementation for additional speed and memory efficiency and can handle both equally and unequally spaced measurements. This package was originally written in Rust, so additional examples, tests, and benchmarks are also available. The API is almost identical.
**The Whittaker-Eilers smoother is the perfect smoother.** It offers extremely quick, efficient smoothing with built-in interpolation via weights on each measurement. This package provides a sparse-matrix implementation for additional speed and memory efficiency and can handle both equally and unequally spaced measurements. This package was originally written in Rust so additional examples, tests, and benchmarks are also available in addition to it being super speedy. The API is almost identical.

---

Expand Down Expand Up @@ -47,27 +47,55 @@ print("Smoothed non-equally spaced data: {}".format(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.
```rust
use whittaker_eilers::WhittakerSmoother;
```python
from whittaker_eilers import 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;
x_input = [1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0]
data_to_smooth = [1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0]
weights = [1.0] * len(x_input)
weights[5] = 0.0

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

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

println!("Smoothed data: {:?}", smoothed_data);
print("Smoothed and interpolated weighted data: {}".format(smoothed_data))

```
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](https://github.com/AnBowell/whittaker-eilers) repository. Here's an image of some smoothed data from an example:

<img src="/examples/images/smoothed_data.png" alt="Time-series smoothed by Whittaker-Eilers method" width="800" />

### Other methods
```python
from whittaker_eilers import WhittakerSmoother
x_input = [1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0]
data_to_smooth = [1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0]
weights = [1.0] * len(x_input)
weights[5] = 0.0

whittaker_smoother = WhittakerSmoother(
lmbda=2e4,
order=2,
data_length=len(data_to_smooth),
x_input=x_input,
weights=weights,
)

whittaker_smoother.get_order()
whittaker_smoother.get_lambda()
whittaker_smoother.get_data_length()
whittaker_smoother.update_weights([0.5] * len(x_input))
whittaker_smoother.update_order(3)
whittaker_smoother.update_lambda(4321.0)
```

## Future Features
- Cross validation options to find optimal lambda.
- Scatter plot smoothing
Expand Down
28 changes: 28 additions & 0 deletions whittaker-eilers-py/examples/smooth_and_interpolate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from whittaker_eilers import WhittakerSmoother
from time import perf_counter_ns


def smooth_equally_spaced():
Expand Down Expand Up @@ -45,7 +46,34 @@ def smoothed_weighted_and_interpolation():
print("Smoothed and interpolated weighted data: {}".format(smoothed_data))


def update_smoother():
x_input = [1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0]
data_to_smooth = [1.1, 1.9, 3.1, 3.91, 5.0, 6.02, 7.01, 7.7, 9.0, 10.0]
weights = [1.0] * len(x_input)
weights[5] = 0.0

whittaker_smoother = WhittakerSmoother(
lmbda=2e4,
order=2,
data_length=len(data_to_smooth),
x_input=x_input,
weights=weights,
)

whittaker_smoother.update_lambda(3e4)
whittaker_smoother.update_order(3)
whittaker_smoother.update_weights([0.5] * len(x_input))

smoothed_data = whittaker_smoother.smooth(data_to_smooth)

print("Updated & Smoothed data: {}".format(smoothed_data))


if __name__ == "__main__":
start_time = perf_counter_ns()
smooth_equally_spaced()
smoothed_non_equally_spaced_data()
smoothed_weighted_and_interpolation()
update_smoother()
end_time = perf_counter_ns()
print("Smoothing tests took : {} ms".format((end_time - start_time) / 1e6))
1 change: 1 addition & 0 deletions whittaker-eilers-py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ authors = [{ name = "Andrew Bowell" }]
readme = "README.md"
[project.urls]
repository = "https://github.com/AnBowell/whittaker-eilers/tree/main/whittaker-eilers-py"
documentation = "https://github.com/AnBowell/whittaker-eilers/tree/main/whittaker-eilers-py"
Loading

0 comments on commit bb621e3

Please sign in to comment.