@@ -122,9 +122,9 @@ def roll_sum(const float64_t[:] values, ndarray[int64_t] start,
122
122
ndarray[int64_t] end , int64_t minp ) -> np.ndarray:
123
123
cdef:
124
124
Py_ssize_t i , j
125
- float64_t sum_x = 0 , compensation_add = 0 , compensation_remove = 0
125
+ float64_t sum_x , compensation_add , compensation_remove
126
126
int64_t s , e
127
- int64_t nobs = 0 , N = len (values )
127
+ int64_t nobs = 0 , N = len (start )
128
128
ndarray[float64_t] output
129
129
bint is_monotonic_increasing_bounds
130
130
@@ -139,10 +139,12 @@ def roll_sum(const float64_t[:] values, ndarray[int64_t] start,
139
139
s = start[i]
140
140
e = end[i]
141
141
142
- if i == 0 or not is_monotonic_increasing_bounds:
142
+ if i == 0 or not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
143
143
144
144
# setup
145
145
146
+ sum_x = compensation_add = compensation_remove = 0
147
+ nobs = 0
146
148
for j in range (s, e):
147
149
add_sum(values[j], & nobs, & sum_x, & compensation_add)
148
150
@@ -226,9 +228,9 @@ cdef inline void remove_mean(float64_t val, Py_ssize_t *nobs, float64_t *sum_x,
226
228
def roll_mean (const float64_t[:] values , ndarray[int64_t] start ,
227
229
ndarray[int64_t] end , int64_t minp ) -> np.ndarray:
228
230
cdef:
229
- float64_t val , compensation_add = 0 , compensation_remove = 0 , sum_x = 0
231
+ float64_t val , compensation_add , compensation_remove , sum_x
230
232
int64_t s , e
231
- Py_ssize_t nobs = 0 , i , j , neg_ct = 0 , N = len (values )
233
+ Py_ssize_t nobs , i , j , neg_ct , N = len (start )
232
234
ndarray[float64_t] output
233
235
bint is_monotonic_increasing_bounds
234
236
@@ -243,8 +245,10 @@ def roll_mean(const float64_t[:] values, ndarray[int64_t] start,
243
245
s = start[i]
244
246
e = end[i]
245
247
246
- if i == 0 or not is_monotonic_increasing_bounds:
248
+ if i == 0 or not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
247
249
250
+ compensation_add = compensation_remove = sum_x = 0
251
+ nobs = neg_ct = 0
248
252
# setup
249
253
for j in range (s, e):
250
254
val = values[j]
@@ -349,11 +353,11 @@ def roll_var(const float64_t[:] values, ndarray[int64_t] start,
349
353
Numerically stable implementation using Welford's method.
350
354
"""
351
355
cdef:
352
- float64_t mean_x = 0 , ssqdm_x = 0 , nobs = 0 , compensation_add = 0 ,
353
- float64_t compensation_remove = 0 ,
356
+ float64_t mean_x , ssqdm_x , nobs , compensation_add ,
357
+ float64_t compensation_remove ,
354
358
float64_t val , prev , delta , mean_x_old
355
359
int64_t s , e
356
- Py_ssize_t i , j , N = len (values )
360
+ Py_ssize_t i , j , N = len (start )
357
361
ndarray[float64_t] output
358
362
bint is_monotonic_increasing_bounds
359
363
@@ -372,8 +376,9 @@ def roll_var(const float64_t[:] values, ndarray[int64_t] start,
372
376
373
377
# Over the first window, observations can only be added
374
378
# never removed
375
- if i == 0 or not is_monotonic_increasing_bounds:
379
+ if i == 0 or not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
376
380
381
+ mean_x = ssqdm_x = nobs = compensation_add = compensation_remove = 0
377
382
for j in range (s, e):
378
383
add_var(values[j], & nobs, & mean_x, & ssqdm_x, & compensation_add)
379
384
@@ -500,11 +505,11 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
500
505
cdef:
501
506
Py_ssize_t i , j
502
507
float64_t val , prev , min_val , mean_val , sum_val = 0
503
- float64_t compensation_xxx_add = 0 , compensation_xxx_remove = 0
504
- float64_t compensation_xx_add = 0 , compensation_xx_remove = 0
505
- float64_t compensation_x_add = 0 , compensation_x_remove = 0
506
- float64_t x = 0 , xx = 0 , xxx = 0
507
- int64_t nobs = 0 , N = len (values), nobs_mean = 0
508
+ float64_t compensation_xxx_add , compensation_xxx_remove
509
+ float64_t compensation_xx_add , compensation_xx_remove
510
+ float64_t compensation_x_add , compensation_x_remove
511
+ float64_t x , xx , xxx
512
+ int64_t nobs = 0 , N = len (start), V = len ( values), nobs_mean = 0
508
513
int64_t s , e
509
514
ndarray[float64_t] output , mean_array , values_copy
510
515
bint is_monotonic_increasing_bounds
@@ -518,7 +523,7 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
518
523
values_copy = np.copy(values)
519
524
520
525
with nogil:
521
- for i in range(0, N ):
526
+ for i in range(0, V ):
522
527
val = values_copy[i]
523
528
if notnan(val):
524
529
nobs_mean += 1
@@ -527,7 +532,7 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
527
532
# Other cases would lead to imprecision for smallest values
528
533
if min_val - mean_val > - 1e5 :
529
534
mean_val = round (mean_val)
530
- for i in range (0 , N ):
535
+ for i in range (0 , V ):
531
536
values_copy[i] = values_copy[i] - mean_val
532
537
533
538
for i in range (0 , N):
@@ -537,8 +542,13 @@ def roll_skew(ndarray[float64_t] values, ndarray[int64_t] start,
537
542
538
543
# Over the first window, observations can only be added
539
544
# never removed
540
- if i == 0 or not is_monotonic_increasing_bounds:
545
+ if i == 0 or not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
541
546
547
+ compensation_xxx_add = compensation_xxx_remove = 0
548
+ compensation_xx_add = compensation_xx_remove = 0
549
+ compensation_x_add = compensation_x_remove = 0
550
+ x = xx = xxx = 0
551
+ nobs = 0
542
552
for j in range (s, e):
543
553
val = values_copy[j]
544
554
add_skew(val, & nobs, & x, & xx, & xxx, & compensation_x_add,
@@ -682,12 +692,12 @@ def roll_kurt(ndarray[float64_t] values, ndarray[int64_t] start,
682
692
cdef:
683
693
Py_ssize_t i , j
684
694
float64_t val , prev , mean_val , min_val , sum_val = 0
685
- float64_t compensation_xxxx_add = 0 , compensation_xxxx_remove = 0
686
- float64_t compensation_xxx_remove = 0 , compensation_xxx_add = 0
687
- float64_t compensation_xx_remove = 0 , compensation_xx_add = 0
688
- float64_t compensation_x_remove = 0 , compensation_x_add = 0
689
- float64_t x = 0 , xx = 0 , xxx = 0 , xxxx = 0
690
- int64_t nobs = 0 , s , e , N = len (values), nobs_mean = 0
695
+ float64_t compensation_xxxx_add , compensation_xxxx_remove
696
+ float64_t compensation_xxx_remove , compensation_xxx_add
697
+ float64_t compensation_xx_remove , compensation_xx_add
698
+ float64_t compensation_x_remove , compensation_x_add
699
+ float64_t x , xx , xxx , xxxx
700
+ int64_t nobs , s , e , N = len (start), V = len (values), nobs_mean = 0
691
701
ndarray[float64_t] output , values_copy
692
702
bint is_monotonic_increasing_bounds
693
703
@@ -700,7 +710,7 @@ def roll_kurt(ndarray[float64_t] values, ndarray[int64_t] start,
700
710
min_val = np.nanmin(values)
701
711
702
712
with nogil:
703
- for i in range(0, N ):
713
+ for i in range(0, V ):
704
714
val = values_copy[i]
705
715
if notnan(val):
706
716
nobs_mean += 1
@@ -709,7 +719,7 @@ def roll_kurt(ndarray[float64_t] values, ndarray[int64_t] start,
709
719
# Other cases would lead to imprecision for smallest values
710
720
if min_val - mean_val > - 1e4 :
711
721
mean_val = round (mean_val)
712
- for i in range (0 , N ):
722
+ for i in range (0 , V ):
713
723
values_copy[i] = values_copy[i] - mean_val
714
724
715
725
for i in range (0 , N):
@@ -719,8 +729,14 @@ def roll_kurt(ndarray[float64_t] values, ndarray[int64_t] start,
719
729
720
730
# Over the first window, observations can only be added
721
731
# never removed
722
- if i == 0 or not is_monotonic_increasing_bounds:
732
+ if i == 0 or not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
723
733
734
+ compensation_xxxx_add = compensation_xxxx_remove = 0
735
+ compensation_xxx_remove = compensation_xxx_add = 0
736
+ compensation_xx_remove = compensation_xx_add = 0
737
+ compensation_x_remove = compensation_x_add = 0
738
+ x = xx = xxx = xxxx = 0
739
+ nobs = 0
724
740
for j in range (s, e):
725
741
add_kurt(values_copy[j], & nobs, & x, & xx, & xxx, & xxxx,
726
742
& compensation_x_add, & compensation_xx_add,
@@ -764,7 +780,7 @@ def roll_median_c(const float64_t[:] values, ndarray[int64_t] start,
764
780
Py_ssize_t i , j
765
781
bint err = False , is_monotonic_increasing_bounds
766
782
int midpoint , ret = 0
767
- int64_t nobs = 0 , N = len (values ), s , e , win
783
+ int64_t nobs , N = len (start ), s , e , win
768
784
float64_t val , res , prev
769
785
skiplist_t *sl
770
786
ndarray[float64_t] output
@@ -791,8 +807,11 @@ def roll_median_c(const float64_t[:] values, ndarray[int64_t] start,
791
807
s = start[i]
792
808
e = end[i]
793
809
794
- if i == 0 or not is_monotonic_increasing_bounds:
810
+ if i == 0 or not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
795
811
812
+ skiplist_destroy(sl)
813
+ sl = skiplist_init(< int > win)
814
+ nobs = 0
796
815
# setup
797
816
for j in range (s, e):
798
817
val = values[j]
@@ -948,7 +967,7 @@ cdef _roll_min_max(ndarray[numeric_t] values,
948
967
cdef:
949
968
numeric_t ai
950
969
int64_t curr_win_size, start
951
- Py_ssize_t i, k, nobs = 0 , N = len (values )
970
+ Py_ssize_t i, k, nobs = 0 , N = len (starti )
952
971
deque Q[int64_t] # min/max always the front
953
972
deque W[int64_t] # track the whole window for nobs compute
954
973
ndarray[float64_t, ndim= 1 ] output
@@ -1031,7 +1050,7 @@ def roll_quantile(const float64_t[:] values, ndarray[int64_t] start,
1031
1050
O(N log(window )) implementation using skip list
1032
1051
"""
1033
1052
cdef:
1034
- Py_ssize_t i , j , s , e , N = len (values ), idx
1053
+ Py_ssize_t i , j , s , e , N = len (start ), idx
1035
1054
int ret = 0
1036
1055
int64_t nobs = 0 , win
1037
1056
float64_t val , prev , midpoint , idx_with_fraction
@@ -1068,8 +1087,8 @@ def roll_quantile(const float64_t[:] values, ndarray[int64_t] start,
1068
1087
s = start[i]
1069
1088
e = end[i]
1070
1089
1071
- if i == 0 or not is_monotonic_increasing_bounds:
1072
- if not is_monotonic_increasing_bounds:
1090
+ if i == 0 or not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
1091
+ if not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
1073
1092
nobs = 0
1074
1093
skiplist_destroy(skiplist)
1075
1094
skiplist = skiplist_init(< int > win)
@@ -1160,7 +1179,7 @@ def roll_rank(const float64_t[:] values, ndarray[int64_t] start,
1160
1179
derived from roll_quantile
1161
1180
"""
1162
1181
cdef:
1163
- Py_ssize_t i , j , s , e , N = len (values ), idx
1182
+ Py_ssize_t i , j , s , e , N = len (start ), idx
1164
1183
float64_t rank_min = 0 , rank = 0
1165
1184
int64_t nobs = 0 , win
1166
1185
float64_t val
@@ -1193,8 +1212,8 @@ def roll_rank(const float64_t[:] values, ndarray[int64_t] start,
1193
1212
s = start[i]
1194
1213
e = end[i]
1195
1214
1196
- if i == 0 or not is_monotonic_increasing_bounds:
1197
- if not is_monotonic_increasing_bounds:
1215
+ if i == 0 or not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
1216
+ if not is_monotonic_increasing_bounds or s >= end[i - 1 ] :
1198
1217
nobs = 0
1199
1218
skiplist_destroy(skiplist)
1200
1219
skiplist = skiplist_init(< int > win)
0 commit comments