# \[ANN\] AdaptiveSampling.jl

**URL:** <https://discourse.julialang.org/t/ann-adaptivesampling-jl/38153>\
**Category:** Package Announcements\
**Created:** [April 24, 2020, 3:21pm UTC](https://discourse.julialang.org/t/ann-adaptivesampling-jl/38153 "2020-04-24T15:21:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [April 24, 2020, 3:21pm UTC](https://discourse.julialang.org/t/ann-adaptivesampling-jl/38153/1 "2020-04-24T15:21:17Z")

</div>

> **[GitHub - iuliancioarca/AdaptiveSampling.jl: Adaptive sampling rate algorithms...](https://github.com/iuliancioarca/AdaptiveSampling.jl)**
>
> Adaptive sampling rate algorithms for waveform compression - GitHub - iuliancioarca/AdaptiveSampling.jl: Adaptive sampling rate algorithms for waveform compression

I have been using this code to perform lossy compression on oversampled time domain waveforms and decided to transform it into a package and make it available. (not registered yet)  
The main idea behind is approximating the signal with line segments based on a fixed absolute threshold:  
 ![anchor_point](https://global.discourse-cdn.com/julialang/original/3X/2/7/27be78d05a091690fc1366bee3cccfcbf289f74c.gif)

The code is as barebones as possible; initially I had some low pass filtering and wavelet denoising (might add them back in the future if needed).

I hope other people will benefit from this.

---

<div class="post-metadata">

**Author:** ![theogf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/theogf/32/1987_2.png) [@theogf](https://discourse.julialang.org/u/theogf)\
**Post date:** [April 24, 2020, 3:38pm UTC](https://discourse.julialang.org/t/ann-adaptivesampling-jl/38153/2 "2020-04-24T15:38:08Z")

</div>

Cool! It looks really nice! Do you have the reference for the method used somewhere?

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [April 24, 2020, 3:46pm UTC](https://discourse.julialang.org/t/ann-adaptivesampling-jl/38153/3 "2020-04-24T15:46:34Z")

</div>

I didn’t find similar methods, but to be honest I didn’t search too much. I know there are papers on ECG compression with variable sample rate, but they analyse chunks of the signal and decide to decimate by a certain factor the whole chunk.(might add those in the future)

---

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [April 24, 2020, 4:11pm UTC](https://discourse.julialang.org/t/ann-adaptivesampling-jl/38153/4 "2020-04-24T16:11:46Z")

</div>

Interesting. It reminds me of using Gaussian Processes for efficient sampling of costly functions with heterogeneous noise. Something like this:

> **[hetGP\_vignette.pdf](https://rdrr.io/cran/hetGP/f/inst/doc/hetGP_vignette.pdf)**
>
> 937.96 KB

---

<div class="post-metadata">

**Author:** ![waldyrious](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/waldyrious/32/80_2.png) [@waldyrious](https://discourse.julialang.org/u/waldyrious)\
**Post date:** [April 28, 2020, 5:39pm UTC](https://discourse.julialang.org/t/ann-adaptivesampling-jl/38153/5 "2020-04-28T17:39:05Z")

</div>

Not sure if this is useful, but a few years ago I came across the [Ramer–Douglas–Peucker algorithm](https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm) when researching geometry simplification techniques. That article has links and references to various related techniques.

I assume this will also be quite interesting: [Simplify.js - a high-performance JavaScript 2D/3D polyline simplification library](https://mourner.github.io/simplify-js/); as well as this live demo using D3: [Line Simplification - bl.ocks.org](https://bl.ocks.org/mbostock/5732029).

For your specific use case, perhaps it’s not imperative that you use straight line segments in the simplified version; you might want to use a more general [curve fitting](https://en.wikipedia.org/wiki/Curve_fitting) method instead.

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [April 28, 2020, 8:22pm UTC](https://discourse.julialang.org/t/ann-adaptivesampling-jl/38153/6 "2020-04-28T20:22:10Z")

</div>

Thank you for the suggestions! It seems the method in my package is very similar to the [Ramer–Douglas–Peucker algorithm](https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm) and I didn’t even know it existed 😆. The straight line segment approach came only as a consequence of compression speed. In the end, what the code does is it allocates an array corresponding to a straight line segment and subtracts the real chunk of signal in order to find the point where that error is at a maximum(it doesn’t even use the euclidean distance since it would use more than subtractions). That point will be stored as a key point of the compressed waveform.  
Indeed, using more advanced piecewise curve fitting techniques can yield better results and even tackle the noise problem better, but at the expense of run time.  
As a side note, the gif was just an example. The real world waveforms are much more complex than that, with sporadic sharp transients, with typical sizes of millions of points. (they are the (noisy) responses to battery fluctuations of various automotive electronic components)
