Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-compute/src/ewm/cov.rs
7884 views
1
use std::ops::{AddAssign, DivAssign, MulAssign};
2
3
use arrow::array::{Array, PrimitiveArray};
4
use arrow::trusted_len::TrustedLen;
5
use arrow::types::NativeType;
6
use num_traits::Float;
7
8
use crate::ewm::EwmStateUpdate;
9
10
pub struct EwmCovState<T> {
11
weight: T,
12
mean_x: T,
13
mean_y: T,
14
cov: T,
15
weight_sum: T,
16
weight_square_sum: T,
17
alpha: T,
18
non_null_count: usize,
19
adjust: bool,
20
bias: bool,
21
min_periods: usize,
22
ignore_nulls: bool,
23
}
24
25
impl<T> EwmCovState<T>
26
where
27
T: num_traits::Float,
28
{
29
pub fn new(alpha: T, adjust: bool, bias: bool, min_periods: usize, ignore_nulls: bool) -> Self {
30
Self {
31
mean_x: T::zero(),
32
mean_y: T::zero(),
33
weight: T::zero(),
34
cov: T::zero(),
35
weight_sum: T::zero(),
36
weight_square_sum: T::zero(),
37
alpha,
38
non_null_count: 0,
39
adjust,
40
bias,
41
min_periods: min_periods.max(1),
42
ignore_nulls,
43
}
44
}
45
}
46
47
impl<T> EwmCovState<T>
48
where
49
T: NativeType
50
+ num_traits::Float
51
+ std::ops::AddAssign
52
+ std::ops::DivAssign
53
+ std::ops::MulAssign,
54
{
55
pub fn update_iter<I>(&mut self, values: I) -> impl Iterator<Item = Option<T>>
56
where
57
I: IntoIterator<Item = Option<(T, T)>>,
58
{
59
let other_weight = if self.adjust { T::one() } else { self.alpha };
60
61
values.into_iter().map(move |opt_xy| {
62
if self.non_null_count == 0
63
&& let Some((x, y)) = opt_xy
64
{
65
// Initialize
66
self.non_null_count = 1;
67
self.mean_x = x;
68
self.mean_y = y;
69
self.weight = T::one();
70
self.weight_sum = T::one();
71
self.weight_square_sum = T::one();
72
} else {
73
if opt_xy.is_some() || !self.ignore_nulls {
74
self.weight_sum *= T::one() - self.alpha;
75
self.weight_square_sum *= (T::one() - self.alpha) * (T::one() - self.alpha);
76
self.weight *= T::one() - self.alpha;
77
}
78
79
if let Some((other_x, other_y)) = opt_xy {
80
self.non_null_count += 1;
81
82
let new_weight = self.weight + other_weight;
83
let other_weight_frac = other_weight / new_weight;
84
let delta_mean_x = other_x - self.mean_x;
85
let delta_mean_y = other_y - self.mean_y;
86
87
let new_mean_x = self.mean_x + delta_mean_x * other_weight_frac;
88
let new_mean_y = self.mean_y + delta_mean_y * other_weight_frac;
89
90
let cov = ((self.weight
91
* (self.cov + (self.mean_x - new_mean_x) * (self.mean_y - new_mean_y)))
92
+ other_weight * (other_x - new_mean_x) * (other_y - new_mean_y))
93
/ new_weight;
94
95
self.cov = cov;
96
self.weight = new_weight;
97
self.mean_x = new_mean_x;
98
self.mean_y = new_mean_y;
99
100
self.weight_sum += other_weight;
101
self.weight_square_sum += other_weight * other_weight;
102
103
if !self.adjust {
104
self.weight_sum /= new_weight;
105
self.weight_square_sum /= new_weight * new_weight;
106
self.weight = T::one();
107
}
108
}
109
}
110
111
(opt_xy.is_some() && self.non_null_count >= self.min_periods)
112
.then_some(self.cov)
113
.and_then(|cov| {
114
if self.bias || self.non_null_count == 1 {
115
Some(cov)
116
} else {
117
let numerator = self.weight_sum * self.weight_sum;
118
let denominator = numerator - self.weight_square_sum;
119
if denominator > T::zero() {
120
Some((numerator / denominator) * cov)
121
} else {
122
None
123
}
124
}
125
})
126
})
127
}
128
}
129
130
pub struct EwmVarState<T>(EwmCovState<T>);
131
132
impl<T> EwmVarState<T> {
133
pub fn new(cov_state: EwmCovState<T>) -> Self {
134
Self(cov_state)
135
}
136
}
137
138
impl<T> EwmStateUpdate for EwmVarState<T>
139
where
140
T: NativeType
141
+ num_traits::Float
142
+ std::ops::AddAssign
143
+ std::ops::DivAssign
144
+ std::ops::MulAssign,
145
{
146
fn ewm_state_update(&mut self, values: &dyn Array) -> Box<dyn Array> {
147
let values: &PrimitiveArray<T> = values.as_any().downcast_ref().unwrap();
148
149
let out: PrimitiveArray<T> = self
150
.0
151
.update_iter(values.iter().map(|x| x.map(|x| (*x, *x))))
152
.collect();
153
154
out.boxed()
155
}
156
}
157
158
pub struct EwmStdState<T>(EwmCovState<T>);
159
160
impl<T> EwmStdState<T> {
161
pub fn new(cov_state: EwmCovState<T>) -> Self {
162
Self(cov_state)
163
}
164
}
165
166
impl<T> EwmStateUpdate for EwmStdState<T>
167
where
168
T: NativeType
169
+ num_traits::Float
170
+ std::ops::AddAssign
171
+ std::ops::DivAssign
172
+ std::ops::MulAssign,
173
{
174
fn ewm_state_update(&mut self, values: &dyn Array) -> Box<dyn Array> {
175
let values: &PrimitiveArray<T> = values.as_any().downcast_ref().unwrap();
176
177
let out: PrimitiveArray<T> = self
178
.0
179
.update_iter(values.iter().map(|x| x.map(|x| (*x, *x))))
180
.map(|x| x.map(|x| x.sqrt()))
181
.collect();
182
183
out.boxed()
184
}
185
}
186
187
pub fn ewm_var<I, T>(
188
xs: I,
189
alpha: T,
190
adjust: bool,
191
bias: bool,
192
min_periods: usize,
193
ignore_nulls: bool,
194
) -> PrimitiveArray<T>
195
where
196
I: IntoIterator<Item = Option<T>> + Clone,
197
I::IntoIter: TrustedLen,
198
T: Float + NativeType + AddAssign + MulAssign + DivAssign,
199
{
200
let mut state = EwmCovState::new(alpha, adjust, bias, min_periods, ignore_nulls);
201
let iter = state.update_iter(xs.into_iter().map(|x| x.map(|x| (x, x))));
202
203
iter.collect()
204
}
205
206
pub fn ewm_std<I, T>(
207
xs: I,
208
alpha: T,
209
adjust: bool,
210
bias: bool,
211
min_periods: usize,
212
ignore_nulls: bool,
213
) -> PrimitiveArray<T>
214
where
215
I: IntoIterator<Item = Option<T>>,
216
T: NativeType
217
+ num_traits::Float
218
+ std::ops::AddAssign
219
+ std::ops::DivAssign
220
+ std::ops::MulAssign,
221
{
222
let mut state = EwmCovState::new(alpha, adjust, bias, min_periods, ignore_nulls);
223
let iter = state.update_iter(xs.into_iter().map(|x| x.map(|x| (x, x))));
224
225
iter.map(|opt_x| opt_x.map(|x| x.sqrt())).collect()
226
}
227
228
#[cfg(test)]
229
mod test {
230
use super::super::assert_allclose;
231
use super::*;
232
const ALPHA: f64 = 0.5;
233
const EPS: f64 = 1e-15;
234
use std::f64::consts::SQRT_2;
235
236
const XS: [Option<f64>; 7] = [
237
Some(1.0),
238
Some(5.0),
239
Some(7.0),
240
Some(1.0),
241
Some(2.0),
242
Some(1.0),
243
Some(4.0),
244
];
245
const YS: [Option<f64>; 7] = [None, Some(5.0), Some(7.0), None, None, Some(1.0), Some(4.0)];
246
247
fn ewm_cov<I, T>(
248
xs: I,
249
ys: I,
250
alpha: T,
251
adjust: bool,
252
bias: bool,
253
min_periods: usize,
254
ignore_nulls: bool,
255
) -> PrimitiveArray<T>
256
where
257
I: IntoIterator<Item = Option<T>>,
258
I::IntoIter: TrustedLen,
259
T: Float + NativeType + AddAssign + MulAssign + DivAssign,
260
{
261
let mut state = EwmCovState::new(alpha, adjust, bias, min_periods, ignore_nulls);
262
let iter = state.update_iter(xs.into_iter().zip(ys).map(|(x, y)| x.zip(y)));
263
264
iter.collect()
265
}
266
267
#[test]
268
fn test_ewm_var() {
269
assert_allclose!(
270
ewm_var(XS.to_vec(), ALPHA, true, true, 0, true),
271
PrimitiveArray::from([
272
Some(0.0),
273
Some(3.555_555_555_555_556),
274
Some(4.244_897_959_183_674),
275
Some(7.182_222_222_222_221),
276
Some(3.796_045_785_639_958),
277
Some(2.467_120_181_405_896),
278
Some(2.476_036_952_073_904_3),
279
]),
280
EPS
281
);
282
assert_allclose!(
283
ewm_var(XS.to_vec(), ALPHA, true, true, 0, false),
284
PrimitiveArray::from([
285
Some(0.0),
286
Some(3.555_555_555_555_556),
287
Some(4.244_897_959_183_674),
288
Some(7.182_222_222_222_221),
289
Some(3.796_045_785_639_958),
290
Some(2.467_120_181_405_896),
291
Some(2.476_036_952_073_904_3),
292
]),
293
EPS
294
);
295
assert_allclose!(
296
ewm_var(XS.to_vec(), ALPHA, true, false, 0, true),
297
PrimitiveArray::from([
298
Some(0.0),
299
Some(8.0),
300
Some(7.428_571_428_571_429),
301
Some(11.542_857_142_857_143),
302
Some(5.883_870_967_741_934_5),
303
Some(3.760_368_663_594_470_6),
304
Some(3.743_532_058_492_688_6),
305
]),
306
EPS
307
);
308
assert_allclose!(
309
ewm_var(XS.to_vec(), ALPHA, true, false, 0, false),
310
PrimitiveArray::from([
311
Some(0.0),
312
Some(8.0),
313
Some(7.428_571_428_571_429),
314
Some(11.542_857_142_857_143),
315
Some(5.883_870_967_741_934_5),
316
Some(3.760_368_663_594_470_6),
317
Some(3.743_532_058_492_688_6),
318
]),
319
EPS
320
);
321
assert_allclose!(
322
ewm_var(XS.to_vec(), ALPHA, false, true, 0, true),
323
PrimitiveArray::from([
324
Some(0.0),
325
Some(4.0),
326
Some(6.0),
327
Some(7.0),
328
Some(3.75),
329
Some(2.437_5),
330
Some(2.484_375),
331
]),
332
EPS
333
);
334
assert_allclose!(
335
ewm_var(XS.to_vec(), ALPHA, false, true, 0, false),
336
PrimitiveArray::from([
337
Some(0.0),
338
Some(4.0),
339
Some(6.0),
340
Some(7.0),
341
Some(3.75),
342
Some(2.437_5),
343
Some(2.484_375),
344
]),
345
EPS
346
);
347
assert_allclose!(
348
ewm_var(XS.to_vec(), ALPHA, false, true, 0, false),
349
PrimitiveArray::from([
350
Some(0.0),
351
Some(4.0),
352
Some(6.0),
353
Some(7.0),
354
Some(3.75),
355
Some(2.437_5),
356
Some(2.484_375),
357
]),
358
EPS
359
);
360
assert_allclose!(
361
ewm_var(XS.to_vec(), ALPHA, false, false, 0, true),
362
PrimitiveArray::from([
363
Some(0.0),
364
Some(8.0),
365
Some(9.600_000_000_000_001),
366
Some(10.666_666_666_666_666),
367
Some(5.647_058_823_529_411),
368
Some(3.659_824_046_920_821),
369
Some(3.727_472_527_472_527_6),
370
]),
371
EPS
372
);
373
assert_allclose!(
374
ewm_var(XS.to_vec(), ALPHA, false, false, 0, false),
375
PrimitiveArray::from([
376
Some(0.0),
377
Some(8.0),
378
Some(9.600_000_000_000_001),
379
Some(10.666_666_666_666_666),
380
Some(5.647_058_823_529_411),
381
Some(3.659_824_046_920_821),
382
Some(3.727_472_527_472_527_6),
383
]),
384
EPS
385
);
386
assert_allclose!(
387
ewm_var(YS.to_vec(), ALPHA, true, true, 0, true),
388
PrimitiveArray::from([
389
None,
390
Some(0.0),
391
Some(0.888_888_888_888_889),
392
None,
393
None,
394
Some(7.346_938_775_510_203),
395
Some(3.555_555_555_555_555_4),
396
]),
397
EPS
398
);
399
assert_allclose!(
400
ewm_var(YS.to_vec(), ALPHA, true, true, 0, false),
401
PrimitiveArray::from([
402
None,
403
Some(0.0),
404
Some(0.888_888_888_888_889),
405
None,
406
None,
407
Some(3.922_437_673_130_193_3),
408
Some(2.549_788_542_868_127_3),
409
]),
410
EPS
411
);
412
assert_allclose!(
413
ewm_var(YS.to_vec(), ALPHA, true, false, 0, true),
414
PrimitiveArray::from([
415
None,
416
Some(0.0),
417
Some(2.0),
418
None,
419
None,
420
Some(12.857_142_857_142_856),
421
Some(5.714_285_714_285_714),
422
]),
423
EPS
424
);
425
assert_allclose!(
426
ewm_var(YS.to_vec(), ALPHA, true, false, 0, false),
427
PrimitiveArray::from([
428
None,
429
Some(0.0),
430
Some(2.0),
431
None,
432
None,
433
Some(14.159_999_999_999_997),
434
Some(5.039_513_677_811_549_5),
435
]),
436
EPS
437
);
438
assert_allclose!(
439
ewm_var(YS.to_vec(), ALPHA, false, true, 0, true),
440
PrimitiveArray::from([
441
None,
442
Some(0.0),
443
Some(1.0),
444
None,
445
None,
446
Some(6.75),
447
Some(3.437_5),
448
]),
449
EPS
450
);
451
assert_allclose!(
452
ewm_var(YS.to_vec(), ALPHA, false, true, 0, false),
453
PrimitiveArray::from([None, Some(0.0), Some(1.0), None, None, Some(4.2), Some(3.1)]),
454
EPS
455
);
456
assert_allclose!(
457
ewm_var(YS.to_vec(), ALPHA, false, false, 0, true),
458
PrimitiveArray::from([
459
None,
460
Some(0.0),
461
Some(2.0),
462
None,
463
None,
464
Some(10.8),
465
Some(5.238_095_238_095_238),
466
]),
467
EPS
468
);
469
assert_allclose!(
470
ewm_var(YS.to_vec(), ALPHA, false, false, 0, false),
471
PrimitiveArray::from([
472
None,
473
Some(0.0),
474
Some(2.0),
475
None,
476
None,
477
Some(12.352_941_176_470_589),
478
Some(5.299_145_299_145_3),
479
]),
480
EPS
481
);
482
}
483
484
#[test]
485
fn test_ewm_cov() {
486
assert_allclose!(
487
ewm_cov(XS.to_vec(), YS.to_vec(), ALPHA, true, true, 0, true),
488
PrimitiveArray::from([
489
None,
490
Some(0.0),
491
Some(0.888_888_888_888_889),
492
None,
493
None,
494
Some(7.346_938_775_510_203),
495
Some(3.555_555_555_555_555_4)
496
]),
497
EPS
498
);
499
assert_allclose!(
500
ewm_cov(XS.to_vec(), YS.to_vec(), ALPHA, true, true, 0, false),
501
PrimitiveArray::from([
502
None,
503
Some(0.0),
504
Some(0.888_888_888_888_889),
505
None,
506
None,
507
Some(3.922_437_673_130_193_3),
508
Some(2.549_788_542_868_127_3)
509
]),
510
EPS
511
);
512
assert_allclose!(
513
ewm_cov(XS.to_vec(), YS.to_vec(), ALPHA, true, false, 0, true),
514
PrimitiveArray::from([
515
None,
516
Some(0.0),
517
Some(2.0),
518
None,
519
None,
520
Some(12.857_142_857_142_856),
521
Some(5.714_285_714_285_714)
522
]),
523
EPS
524
);
525
assert_allclose!(
526
ewm_cov(XS.to_vec(), YS.to_vec(), ALPHA, true, false, 0, false),
527
PrimitiveArray::from([
528
None,
529
Some(0.0),
530
Some(2.0),
531
None,
532
None,
533
Some(14.159_999_999_999_997),
534
Some(5.039_513_677_811_549_5)
535
]),
536
EPS
537
);
538
assert_allclose!(
539
ewm_cov(XS.to_vec(), YS.to_vec(), ALPHA, false, true, 0, true),
540
PrimitiveArray::from([
541
None,
542
Some(0.0),
543
Some(1.0),
544
None,
545
None,
546
Some(6.75),
547
Some(3.437_5)
548
]),
549
EPS
550
);
551
assert_allclose!(
552
ewm_cov(XS.to_vec(), YS.to_vec(), ALPHA, false, true, 0, false),
553
PrimitiveArray::from([None, Some(0.0), Some(1.0), None, None, Some(4.2), Some(3.1)]),
554
EPS
555
);
556
assert_allclose!(
557
ewm_cov(XS.to_vec(), YS.to_vec(), ALPHA, false, false, 0, true),
558
PrimitiveArray::from([
559
None,
560
Some(0.0),
561
Some(2.0),
562
None,
563
None,
564
Some(10.8),
565
Some(5.238_095_238_095_238)
566
]),
567
EPS
568
);
569
assert_allclose!(
570
ewm_cov(XS.to_vec(), YS.to_vec(), ALPHA, false, false, 0, false),
571
PrimitiveArray::from([
572
None,
573
Some(0.0),
574
Some(2.0),
575
None,
576
None,
577
Some(12.352_941_176_470_589),
578
Some(5.299_145_299_145_3)
579
]),
580
EPS
581
);
582
}
583
584
#[test]
585
fn test_ewm_std() {
586
assert_allclose!(
587
ewm_std(XS.to_vec(), ALPHA, true, true, 0, true),
588
PrimitiveArray::from([
589
Some(0.0),
590
Some(1.885_618_083_164_126_7),
591
Some(2.060_315_014_550_851_3),
592
Some(2.679_966_832_298_904),
593
Some(1.948_344_370_392_451_5),
594
Some(1.570_706_904_997_204_2),
595
Some(1.573_542_802_746_053_2),
596
]),
597
EPS
598
);
599
assert_allclose!(
600
ewm_std(XS.to_vec(), ALPHA, true, true, 0, false),
601
PrimitiveArray::from([
602
Some(0.0),
603
Some(1.885_618_083_164_126_7),
604
Some(2.060_315_014_550_851_3),
605
Some(2.679_966_832_298_904),
606
Some(1.948_344_370_392_451_5),
607
Some(1.570_706_904_997_204_2),
608
Some(1.573_542_802_746_053_2),
609
]),
610
EPS
611
);
612
assert_allclose!(
613
ewm_std(XS.to_vec(), ALPHA, true, false, 0, true),
614
PrimitiveArray::from([
615
Some(0.0),
616
Some(2.828_427_124_746_190_3),
617
Some(2.725_540_575_476_987_5),
618
Some(3.397_478_056_273_085_3),
619
Some(2.425_669_179_369_259),
620
Some(1.939_167_002_502_484_5),
621
Some(1.934_820_937_061_796_6),
622
]),
623
EPS
624
);
625
assert_allclose!(
626
ewm_std(XS.to_vec(), ALPHA, true, false, 0, false),
627
PrimitiveArray::from([
628
Some(0.0),
629
Some(2.828_427_124_746_190_3),
630
Some(2.725_540_575_476_987_5),
631
Some(3.397_478_056_273_085_3),
632
Some(2.425_669_179_369_259),
633
Some(1.939_167_002_502_484_5),
634
Some(1.934_820_937_061_796_6),
635
]),
636
EPS
637
);
638
assert_allclose!(
639
ewm_std(XS.to_vec(), ALPHA, false, true, 0, true),
640
PrimitiveArray::from([
641
Some(0.0),
642
Some(2.0),
643
Some(2.449_489_742_783_178),
644
Some(2.645_751_311_064_590_7),
645
Some(1.936_491_673_103_708_5),
646
Some(1.561_249_499_599_599_6),
647
Some(1.576_190_026_614_811_4),
648
]),
649
EPS
650
);
651
assert_allclose!(
652
ewm_std(XS.to_vec(), ALPHA, false, true, 0, false),
653
PrimitiveArray::from([
654
Some(0.0),
655
Some(2.0),
656
Some(2.449_489_742_783_178),
657
Some(2.645_751_311_064_590_7),
658
Some(1.936_491_673_103_708_5),
659
Some(1.561_249_499_599_599_6),
660
Some(1.576_190_026_614_811_4),
661
]),
662
EPS
663
);
664
assert_allclose!(
665
ewm_std(XS.to_vec(), ALPHA, false, false, 0, true),
666
PrimitiveArray::from([
667
Some(0.0),
668
Some(2.828_427_124_746_190_3),
669
Some(3.098_386_676_965_933_6),
670
Some(3.265_986_323_710_904),
671
Some(2.376_354_103_144_018_3),
672
Some(1.913_066_660_344_281_2),
673
Some(1.930_666_342_865_210_7),
674
]),
675
EPS
676
);
677
assert_allclose!(
678
ewm_std(XS.to_vec(), ALPHA, false, false, 0, false),
679
PrimitiveArray::from([
680
Some(0.0),
681
Some(2.828_427_124_746_190_3),
682
Some(3.098_386_676_965_933_6),
683
Some(3.265_986_323_710_904),
684
Some(2.376_354_103_144_018_3),
685
Some(1.913_066_660_344_281_2),
686
Some(1.930_666_342_865_210_7),
687
]),
688
EPS
689
);
690
assert_allclose!(
691
ewm_std(YS.to_vec(), ALPHA, true, true, 0, true),
692
PrimitiveArray::from([
693
None,
694
Some(0.0),
695
Some(0.942_809_041_582_063_4),
696
None,
697
None,
698
Some(2.710_523_708_715_753_4),
699
Some(1.885_618_083_164_126_7),
700
]),
701
EPS
702
);
703
assert_allclose!(
704
ewm_std(YS.to_vec(), ALPHA, true, true, 0, false),
705
PrimitiveArray::from([
706
None,
707
Some(0.0),
708
Some(0.942_809_041_582_063_4),
709
None,
710
None,
711
Some(1.980_514_497_076_503),
712
Some(1.596_805_731_098_222),
713
]),
714
EPS
715
);
716
assert_allclose!(
717
ewm_std(YS.to_vec(), ALPHA, true, false, 0, true),
718
PrimitiveArray::from([
719
None,
720
Some(0.0),
721
Some(SQRT_2),
722
None,
723
None,
724
Some(3.585_685_828_003_181),
725
Some(2.390_457_218_668_787),
726
]),
727
EPS
728
);
729
assert_allclose!(
730
ewm_std(YS.to_vec(), ALPHA, true, false, 0, false),
731
PrimitiveArray::from([
732
None,
733
Some(0.0),
734
Some(SQRT_2),
735
None,
736
None,
737
Some(3.762_977_544_445_355_3),
738
Some(2.244_886_116_891_356),
739
]),
740
EPS
741
);
742
assert_allclose!(
743
ewm_std(YS.to_vec(), ALPHA, false, true, 0, true),
744
PrimitiveArray::from([
745
None,
746
Some(0.0),
747
Some(1.0),
748
None,
749
None,
750
Some(2.598_076_211_353_316),
751
Some(1.854_049_621_773_915_7),
752
]),
753
EPS
754
);
755
assert_allclose!(
756
ewm_std(YS.to_vec(), ALPHA, false, true, 0, false),
757
PrimitiveArray::from([
758
None,
759
Some(0.0),
760
Some(1.0),
761
None,
762
None,
763
Some(2.049_390_153_191_92),
764
Some(1.760_681_686_165_901),
765
]),
766
EPS
767
);
768
assert_allclose!(
769
ewm_std(YS.to_vec(), ALPHA, false, false, 0, true),
770
PrimitiveArray::from([
771
None,
772
Some(0.0),
773
Some(SQRT_2),
774
None,
775
None,
776
Some(3.286_335_345_030_997),
777
Some(2.288_688_541_085_317_5),
778
]),
779
EPS
780
);
781
assert_allclose!(
782
ewm_std(YS.to_vec(), ALPHA, false, false, 0, false),
783
PrimitiveArray::from([
784
None,
785
Some(0.0),
786
Some(SQRT_2),
787
None,
788
None,
789
Some(3.514_675_116_774_036_7),
790
Some(2.301_987_249_996_250_4),
791
]),
792
EPS
793
);
794
}
795
796
#[test]
797
fn test_ewm_min_periods() {
798
assert_allclose!(
799
ewm_var(YS.to_vec(), ALPHA, true, true, 0, false),
800
PrimitiveArray::from([
801
None,
802
Some(0.0),
803
Some(0.888_888_888_888_889),
804
None,
805
None,
806
Some(3.922_437_673_130_193_3),
807
Some(2.549_788_542_868_127_3),
808
]),
809
EPS
810
);
811
assert_allclose!(
812
ewm_var(YS.to_vec(), ALPHA, true, true, 1, false),
813
PrimitiveArray::from([
814
None,
815
Some(0.0),
816
Some(0.888_888_888_888_889),
817
None,
818
None,
819
Some(3.922_437_673_130_193_3),
820
Some(2.549_788_542_868_127_3),
821
]),
822
EPS
823
);
824
assert_allclose!(
825
ewm_var(YS.to_vec(), ALPHA, true, true, 2, false),
826
PrimitiveArray::from([
827
None,
828
None,
829
Some(0.888_888_888_888_889),
830
None,
831
None,
832
Some(3.922_437_673_130_193_3),
833
Some(2.549_788_542_868_127_3),
834
]),
835
EPS
836
);
837
}
838
}
839
840