@@ -183,7 +183,8 @@ cdef inline void remove_sum(float64_t val, int64_t *nobs, float64_t *sum_x) nogi
183
183
184
184
185
185
def roll_sum_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
186
- ndarray[int64_t] end , int64_t minp ):
186
+ ndarray[int64_t] end , int64_t minp ,
187
+ bint is_monotonic_bounds = True ):
187
188
cdef:
188
189
float64_t sum_x = 0
189
190
int64_t s, e
@@ -198,11 +199,10 @@ def roll_sum_variable(ndarray[float64_t] values, ndarray[int64_t] start,
198
199
s = start[i]
199
200
e = end[i]
200
201
201
- if i == 0 :
202
+ if i == 0 or not is_monotonic_bounds :
202
203
203
204
# setup
204
- sum_x = 0.0
205
- nobs = 0
205
+
206
206
for j in range (s, e):
207
207
add_sum(values[j], & nobs, & sum_x)
208
208
@@ -218,6 +218,10 @@ def roll_sum_variable(ndarray[float64_t] values, ndarray[int64_t] start,
218
218
219
219
output[i] = calc_sum(minp, nobs, sum_x)
220
220
221
+ if not is_monotonic_bounds:
222
+ for j in range (s, e):
223
+ remove_sum(values[j], & nobs, & sum_x)
224
+
221
225
return output
222
226
223
227
@@ -327,7 +331,8 @@ def roll_mean_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
327
331
328
332
329
333
def roll_mean_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
330
- ndarray[int64_t] end , int64_t minp ):
334
+ ndarray[int64_t] end , int64_t minp ,
335
+ bint is_monotonic_bounds = True ):
331
336
cdef:
332
337
float64_t val, sum_x = 0
333
338
int64_t s, e
@@ -342,11 +347,9 @@ def roll_mean_variable(ndarray[float64_t] values, ndarray[int64_t] start,
342
347
s = start[i]
343
348
e = end[i]
344
349
345
- if i == 0 :
350
+ if i == 0 or not is_monotonic_bounds :
346
351
347
352
# setup
348
- sum_x = 0.0
349
- nobs = 0
350
353
for j in range (s, e):
351
354
val = values[j]
352
355
add_mean(val, & nobs, & sum_x, & neg_ct)
@@ -365,6 +368,10 @@ def roll_mean_variable(ndarray[float64_t] values, ndarray[int64_t] start,
365
368
366
369
output[i] = calc_mean(minp, nobs, neg_ct, sum_x)
367
370
371
+ if not is_monotonic_bounds:
372
+ for j in range (s, e):
373
+ val = values[j]
374
+ remove_mean(val, & nobs, & sum_x, & neg_ct)
368
375
return output
369
376
370
377
# ----------------------------------------------------------------------
@@ -486,7 +493,8 @@ def roll_var_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
486
493
487
494
488
495
def roll_var_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
489
- ndarray[int64_t] end , int64_t minp , int ddof = 1 ):
496
+ ndarray[int64_t] end , int64_t minp , int ddof = 1 ,
497
+ bint is_monotonic_bounds = True ):
490
498
"""
491
499
Numerically stable implementation using Welford's method.
492
500
"""
@@ -508,7 +516,7 @@ def roll_var_variable(ndarray[float64_t] values, ndarray[int64_t] start,
508
516
509
517
# Over the first window, observations can only be added
510
518
# never removed
511
- if i == 0 :
519
+ if i == 0 or not is_monotonic_bounds :
512
520
513
521
for j in range (s, e):
514
522
add_var(values[j], & nobs, & mean_x, & ssqdm_x)
@@ -528,6 +536,10 @@ def roll_var_variable(ndarray[float64_t] values, ndarray[int64_t] start,
528
536
529
537
output[i] = calc_var(minp, ddof, nobs, ssqdm_x)
530
538
539
+ if not is_monotonic_bounds:
540
+ for j in range (s, e):
541
+ remove_var(values[j], & nobs, & mean_x, & ssqdm_x)
542
+
531
543
return output
532
544
533
545
# ----------------------------------------------------------------------
@@ -629,7 +641,8 @@ def roll_skew_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
629
641
630
642
631
643
def roll_skew_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
632
- ndarray[int64_t] end , int64_t minp ):
644
+ ndarray[int64_t] end , int64_t minp ,
645
+ bint is_monotonic_bounds = True ):
633
646
cdef:
634
647
float64_t val, prev
635
648
float64_t x = 0 , xx = 0 , xxx = 0
@@ -648,7 +661,7 @@ def roll_skew_variable(ndarray[float64_t] values, ndarray[int64_t] start,
648
661
649
662
# Over the first window, observations can only be added
650
663
# never removed
651
- if i == 0 :
664
+ if i == 0 or not is_monotonic_bounds :
652
665
653
666
for j in range (s, e):
654
667
val = values[j]
@@ -671,6 +684,11 @@ def roll_skew_variable(ndarray[float64_t] values, ndarray[int64_t] start,
671
684
672
685
output[i] = calc_skew(minp, nobs, x, xx, xxx)
673
686
687
+ if not is_monotonic_bounds:
688
+ for j in range (s, e):
689
+ val = values[j]
690
+ remove_skew(val, & nobs, & x, & xx, & xxx)
691
+
674
692
return output
675
693
676
694
# ----------------------------------------------------------------------
@@ -776,7 +794,8 @@ def roll_kurt_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
776
794
777
795
778
796
def roll_kurt_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
779
- ndarray[int64_t] end , int64_t minp ):
797
+ ndarray[int64_t] end , int64_t minp ,
798
+ bint is_monotonic_bounds = True ):
780
799
cdef:
781
800
float64_t val, prev
782
801
float64_t x = 0 , xx = 0 , xxx = 0 , xxxx = 0
@@ -794,7 +813,7 @@ def roll_kurt_variable(ndarray[float64_t] values, ndarray[int64_t] start,
794
813
795
814
# Over the first window, observations can only be added
796
815
# never removed
797
- if i == 0 :
816
+ if i == 0 or not is_monotonic_bounds :
798
817
799
818
for j in range (s, e):
800
819
add_kurt(values[j], & nobs, & x, & xx, & xxx, & xxxx)
@@ -814,6 +833,10 @@ def roll_kurt_variable(ndarray[float64_t] values, ndarray[int64_t] start,
814
833
815
834
output[i] = calc_kurt(minp, nobs, x, xx, xxx, xxxx)
816
835
836
+ if not is_monotonic_bounds:
837
+ for j in range (s, e):
838
+ remove_kurt(values[j], & nobs, & x, & xx, & xxx, & xxxx)
839
+
817
840
return output
818
841
819
842
@@ -1007,7 +1030,8 @@ def roll_min_fixed(ndarray[float64_t] values, ndarray[int64_t] start,
1007
1030
1008
1031
1009
1032
def roll_min_variable (ndarray[float64_t] values , ndarray[int64_t] start ,
1010
- ndarray[int64_t] end , int64_t minp ):
1033
+ ndarray[int64_t] end , int64_t minp ,
1034
+ bint is_monotonic_bounds = True ):
1011
1035
"""
1012
1036
Moving max of 1d array of any numeric type along axis=0 ignoring NaNs.
1013
1037
@@ -1400,7 +1424,10 @@ def roll_generic_variable(object obj,
1400
1424
ndarray[int64_t] start , ndarray[int64_t] end ,
1401
1425
int64_t minp ,
1402
1426
int offset , object func , bint raw ,
1403
- object args , object kwargs ):
1427
+ object args , object kwargs ,
1428
+ bint is_monotonic_bounds = True ):
1429
+ # is_monotonic_bounds unused since variable algorithm doesn't calculate
1430
+ # adds/subtracts across windows, but matches other *_variable functions
1404
1431
cdef:
1405
1432
ndarray[float64_t] output, counts, bufarr
1406
1433
ndarray[float64_t, cast= True ] arr
0 commit comments