Edit
It turned out ArrayBase::windows()
is mostly what I need, but instead of this:
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[ 0, 1, 2] -> window 1
[ 1, 2, 3] -> window 2
...
I need something like the following to compute a center weighted average:
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[ 0, 0, 0] -> window 1
[ 0, 0, 1] -> window 2
[ 0, 1, 2] -> window 3
...
Is there a way to get this windowing behavior from ndarray
itself, or do I need to implement it myself.
original question
I'm trying to port this algorithm from python
to rust
using ndarray
:
I think I'm almost done, but I'm stuck at:
I think the base idea is to compute a moving average for each window, but I can't find out how to do this using ndarray.
Here is my code so far:
pub fn nth_octave_smoothing(signal: &[f32], num_fractions: usize) -> Vec<f32> {
let signal = ArrayView::from(signal);
let len = signal.len() as f32;
let n_lin = Array::range(0., len as f32, 1.0);
let n_log = n_lin.mapv(|n| n / (len - 1.0)).mapv(|n| len.powf(n));
let delta_n = n_log[1].log2();
let n_window = (2.0 * (1.0 / (num_fractions as f32 * delta_n * 2.0)).floor() + 1.0) as usize;
if n_window == 1 {
panic!("num_fraction below frequency");
}
let window = Array1::<f32>::ones(n_window);
let interpolator = Interp1DBuilder::new(signal)
.strategy(CubicSpline::new())
.x(n_lin + 1.0)
.build()
.unwrap();
let result = interpolator.interp_array(&n_log).unwrap();
let result = /* windowed moving average */
Is ArrayBase::windows() the way to go here?
Any help is highly appreciated.