1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use rhai::plugin::*;
#[export_module]
pub mod moving_functions {
use crate::if_list_do;
use rhai::{Array, Dynamic, EvalAltResult, INT};
fn mov<G>(arr: &mut Array, k: INT, mut f: G) -> Result<Array, Box<EvalAltResult>>
where
G: FnMut(&mut Array) -> Dynamic,
{
if_list_do(arr, |arr| {
// First, validate the inputs
let mut new_arr = vec![];
let n = arr.len() as INT;
for i in 0..n {
new_arr.push(f(&mut arr
.get(if k % 2 != 0 {
(std::cmp::max(i - (k - 1) / 2, 0) as usize)
..=(std::cmp::min(i + (k - 1) / 2, n - 1) as usize)
} else {
(std::cmp::max(i - k / 2, 0) as usize)
..=(std::cmp::min(i + k / 2 - 1, n - 1) as usize)
})
.unwrap()
.to_vec()))
}
Ok(new_arr)
})
}
/// Returns an array of the moving minimum (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 4, -1, -2, -3, -1, 3, 2, 1];
/// let m = movmin(data, 3);
/// assert_eq(m, [1, 1, -1, -2, -3, -3, -3, -1, 1, 1]);
/// ```
#[rhai_fn(name = "movmin", return_raw, pure)]
pub fn movmin(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::array_min(x).unwrap())
}
/// Returns an array of the moving maximum (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 4, -1, -2, -3, -1, 3, 2, 1];
/// let m = movmax(data, 3);
/// assert_eq(m, [2, 4, 4, 4, -1, -1, 3, 3, 3, 2]);
/// ```
#[rhai_fn(name = "movmax", return_raw, pure)]
pub fn movmax(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::array_max(x).unwrap())
}
/// Returns an array of the moving maximum absolute deviation (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 4, -1, -2, -3, -1, 3, 2, 1];
/// let m = movmad(data, 3);
/// assert_eq(m, [0.5, 1.0, 2.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 0.5]);
/// ```
#[rhai_fn(name = "movmad", return_raw, pure)]
pub fn movmad(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::mad(x).unwrap())
}
/// Returns an array of the moving average (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 3, 4, 5, 6];
/// let m = movmean(data, 3);
/// assert_eq(m, [1.5, 2.0, 3.0, 4.0, 5.0, 5.5]);
/// ```
#[rhai_fn(name = "movmean", return_raw, pure)]
pub fn movmean(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::mean(x).unwrap())
}
/// Returns an array of the moving median (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 3, 4, 5, 6];
/// let m = movmedian(data, 3);
/// assert_eq(m, [1.5, 2.0, 3.0, 4.0, 5.0, 5.5]);
/// ```
#[rhai_fn(name = "movmedian", return_raw, pure)]
pub fn movmedian(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::median(x).unwrap())
}
/// Returns an array of the moving product (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 3, 4, 5, 6];
/// let m = movprod(data, 3);
/// assert_eq(m, [2, 6, 24, 60, 120, 30]);
/// ```
#[rhai_fn(name = "movprod", return_raw, pure)]
pub fn movprod(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::prod(x).unwrap())
}
/// Returns an array of the moving standard deviation (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 3, 4, 5, 6];
/// let m = movstd(data, 3);
/// assert_eq(m, [0.7071067811865476, 1.0, 1.0, 1.0, 1.0, 0.7071067811865476]);
/// ```
#[rhai_fn(name = "movstd", return_raw, pure)]
pub fn movstd(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::std(x).unwrap())
}
/// Returns an array of the moving variance (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 3, 4, 5, 6];
/// let m = movvar(data, 3);
/// assert_eq(m, [0.5, 1.0, 1.0, 1.0, 1.0, 0.5]);
/// ```
#[rhai_fn(name = "movvar", return_raw, pure)]
pub fn movvar(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::variance(x).unwrap())
}
/// Returns an array of the moving sum (with a given width) across the input array.
/// ```typescript
/// let data = [1, 2, 3, 4, 5, 6];
/// let m = movsum(data, 3);
/// assert_eq(m, [3, 6, 9, 12, 15, 11]);
/// ```
#[rhai_fn(name = "movsum", return_raw, pure)]
pub fn movsum(arr: &mut Array, k: INT) -> Result<Array, Box<EvalAltResult>> {
mov(arr, k, |x| crate::stats::sum(x).unwrap())
}
}