|
10 | 10 | sequentially in memory to compute the rolling statistic. |
11 | 11 | */ |
12 | 12 |
|
13 | | -#undef SUM_WINDOW_STEP_FRONT |
14 | | -#define SUM_WINDOW_STEP_FRONT \ |
15 | | -if (R_FINITE(x[i])) { \ |
16 | | - w += x[i]; \ |
17 | | -} else if (ISNAN(x[i])) { \ |
18 | | - nc++; \ |
19 | | -} else if (x[i]==R_PosInf) { \ |
20 | | - pinf++; \ |
21 | | -} else if (x[i]==R_NegInf) { \ |
22 | | - ninf++; \ |
23 | | -} |
24 | | -#undef SUM_WINDOW_STEP_BACK |
25 | | -#define SUM_WINDOW_STEP_BACK \ |
26 | | -if (R_FINITE(x[i-k])) { \ |
27 | | - w -= x[i-k]; \ |
28 | | -} else if (ISNAN(x[i-k])) { \ |
29 | | - nc--; \ |
30 | | -} else if (x[i-k]==R_PosInf) { \ |
31 | | - pinf--; \ |
32 | | -} else if (x[i-k]==R_NegInf) { \ |
33 | | - ninf--; \ |
34 | | -} |
35 | | - |
36 | 13 | /* rolling fun - router for fun and algo |
37 | 14 | * early stopping for window bigger than input |
38 | 15 | * handles 'align' in single place for center or left |
@@ -107,6 +84,62 @@ void frollfun(rollfun_t rfun, unsigned int algo, const double *x, uint64_t nx, a |
107 | 84 | snprintf(end(ans->message[0]), 500, _("%s: processing fun %d algo %u took %.3fs\n"), __func__, rfun, algo, omp_get_wtime()-tic); |
108 | 85 | } |
109 | 86 |
|
| 87 | +#undef SUM_WINDOW_STEP_FRONT |
| 88 | +#define SUM_WINDOW_STEP_FRONT \ |
| 89 | + if (R_FINITE(x[i])) { \ |
| 90 | + w += x[i]; \ |
| 91 | + } else if (ISNAN(x[i])) { \ |
| 92 | + nc++; \ |
| 93 | + } else if (x[i]==R_PosInf) { \ |
| 94 | + pinf++; \ |
| 95 | + } else if (x[i]==R_NegInf) { \ |
| 96 | + ninf++; \ |
| 97 | + } |
| 98 | +#undef SUM_WINDOW_STEP_BACK |
| 99 | +#define SUM_WINDOW_STEP_BACK \ |
| 100 | + if (R_FINITE(x[i-k])) { \ |
| 101 | + w -= x[i-k]; \ |
| 102 | + } else if (ISNAN(x[i-k])) { \ |
| 103 | + nc--; \ |
| 104 | + } else if (x[i-k]==R_PosInf) { \ |
| 105 | + pinf--; \ |
| 106 | + } else if (x[i-k]==R_NegInf) { \ |
| 107 | + ninf--; \ |
| 108 | + } |
| 109 | +#undef MEAN_WINDOW_STEP_VALUE |
| 110 | +#define MEAN_WINDOW_STEP_VALUE \ |
| 111 | + if (nc == 0) { \ |
| 112 | + if (pinf == 0) { \ |
| 113 | + if (ninf == 0) { \ |
| 114 | + ans->dbl_v[i] = (double) (w / k); \ |
| 115 | + } else { \ |
| 116 | + ans->dbl_v[i] = R_NegInf; \ |
| 117 | + } \ |
| 118 | + } else if (ninf == 0) { \ |
| 119 | + ans->dbl_v[i] = R_PosInf; \ |
| 120 | + } else { \ |
| 121 | + ans->dbl_v[i] = R_NaN; \ |
| 122 | + } \ |
| 123 | + } else if (nc == k) { \ |
| 124 | + ans->dbl_v[i] = narm ? R_NaN : NA_REAL; \ |
| 125 | + } else { \ |
| 126 | + if (narm) { \ |
| 127 | + if (pinf == 0) { \ |
| 128 | + if (ninf == 0) { \ |
| 129 | + ans->dbl_v[i] = (double) (w / (k - nc)); \ |
| 130 | + } else { \ |
| 131 | + ans->dbl_v[i] = R_NegInf; \ |
| 132 | + } \ |
| 133 | + } else if (ninf == 0) { \ |
| 134 | + ans->dbl_v[i] = R_PosInf; \ |
| 135 | + } else { \ |
| 136 | + ans->dbl_v[i] = R_NaN; \ |
| 137 | + } \ |
| 138 | + } else { \ |
| 139 | + ans->dbl_v[i] = NA_REAL; \ |
| 140 | + } \ |
| 141 | + } |
| 142 | + |
110 | 143 | /* fast rolling mean - fast |
111 | 144 | * when no info on NF (has.nf argument) then assume no NFs run faster version |
112 | 145 | * rollmean implemented as single pass sliding window for align="right" |
@@ -157,41 +190,6 @@ void frollmeanFast(const double *x, uint64_t nx, ans_t *ans, int k, double fill, |
157 | 190 | if (truehasnf) { |
158 | 191 | int nc = 0, pinf = 0, ninf = 0; // NA counter within sliding window |
159 | 192 | int i; // iterator declared here because it is being used after for loop |
160 | | - |
161 | | -#undef MEAN_WINDOW_STEP_VALUE |
162 | | -#define MEAN_WINDOW_STEP_VALUE \ |
163 | | - if (nc == 0) { \ |
164 | | - if (pinf == 0) { \ |
165 | | - if (ninf == 0) { \ |
166 | | - ans->dbl_v[i] = (double) (w / k); \ |
167 | | - } else { \ |
168 | | - ans->dbl_v[i] = R_NegInf; \ |
169 | | - } \ |
170 | | - } else if (ninf == 0) { \ |
171 | | - ans->dbl_v[i] = R_PosInf; \ |
172 | | - } else { \ |
173 | | - ans->dbl_v[i] = R_NaN; \ |
174 | | - } \ |
175 | | - } else if (nc == k) { \ |
176 | | - ans->dbl_v[i] = narm ? R_NaN : NA_REAL; \ |
177 | | - } else { \ |
178 | | - if (narm) { \ |
179 | | - if (pinf == 0) { \ |
180 | | - if (ninf == 0) { \ |
181 | | - ans->dbl_v[i] = (double) (w / (k - nc)); \ |
182 | | - } else { \ |
183 | | - ans->dbl_v[i] = R_NegInf; \ |
184 | | - } \ |
185 | | - } else if (ninf == 0) { \ |
186 | | - ans->dbl_v[i] = R_PosInf; \ |
187 | | - } else { \ |
188 | | - ans->dbl_v[i] = R_NaN; \ |
189 | | - } \ |
190 | | - } else { \ |
191 | | - ans->dbl_v[i] = NA_REAL; \ |
192 | | - } \ |
193 | | - } |
194 | | - |
195 | 193 | for (i=0; i<k-1; i++) { // loop over leading observation, all partial window only; #loop_counter_not_local_scope_ok |
196 | 194 | SUM_WINDOW_STEP_FRONT |
197 | 195 | ans->dbl_v[i] = fill; // partial window fill all |
@@ -299,6 +297,40 @@ void frollmeanExact(const double *x, uint64_t nx, ans_t *ans, int k, double fill |
299 | 297 | } |
300 | 298 | } |
301 | 299 |
|
| 300 | +#undef SUM_WINDOW_STEP_VALUE |
| 301 | +#define SUM_WINDOW_STEP_VALUE \ |
| 302 | + if (nc == 0) { \ |
| 303 | + if (pinf == 0) { \ |
| 304 | + if (ninf == 0) { \ |
| 305 | + ans->dbl_v[i] = (double) w; \ |
| 306 | + } else { \ |
| 307 | + ans->dbl_v[i] = R_NegInf; \ |
| 308 | + } \ |
| 309 | + } else if (ninf == 0) { \ |
| 310 | + ans->dbl_v[i] = R_PosInf; \ |
| 311 | + } else { \ |
| 312 | + ans->dbl_v[i] = R_NaN; \ |
| 313 | + } \ |
| 314 | + } else if (nc == k) { \ |
| 315 | + ans->dbl_v[i] = narm ? 0.0 : NA_REAL; \ |
| 316 | + } else { \ |
| 317 | + if (narm) { \ |
| 318 | + if (pinf == 0) { \ |
| 319 | + if (ninf == 0) { \ |
| 320 | + ans->dbl_v[i] = (double) w; \ |
| 321 | + } else { \ |
| 322 | + ans->dbl_v[i] = R_NegInf; \ |
| 323 | + } \ |
| 324 | + } else if (ninf == 0) { \ |
| 325 | + ans->dbl_v[i] = R_PosInf; \ |
| 326 | + } else { \ |
| 327 | + ans->dbl_v[i] = R_NaN; \ |
| 328 | + } \ |
| 329 | + } else { \ |
| 330 | + ans->dbl_v[i] = NA_REAL; \ |
| 331 | + } \ |
| 332 | + } |
| 333 | + |
302 | 334 | /* fast rolling sum - fast |
303 | 335 | * same as mean fast |
304 | 336 | */ |
@@ -347,41 +379,6 @@ void frollsumFast(const double *x, uint64_t nx, ans_t *ans, int k, double fill, |
347 | 379 | if (truehasnf) { |
348 | 380 | int nc = 0, pinf = 0, ninf = 0; // NA counter within sliding window |
349 | 381 | int i; // iterator declared here because it is being used after for loop |
350 | | - |
351 | | -#undef SUM_WINDOW_STEP_VALUE |
352 | | -#define SUM_WINDOW_STEP_VALUE \ |
353 | | -if (nc == 0) { \ |
354 | | - if (pinf == 0) { \ |
355 | | - if (ninf == 0) { \ |
356 | | - ans->dbl_v[i] = (double) w; \ |
357 | | - } else { \ |
358 | | - ans->dbl_v[i] = R_NegInf; \ |
359 | | - } \ |
360 | | - } else if (ninf == 0) { \ |
361 | | - ans->dbl_v[i] = R_PosInf; \ |
362 | | - } else { \ |
363 | | - ans->dbl_v[i] = R_NaN; \ |
364 | | - } \ |
365 | | -} else if (nc == k) { \ |
366 | | - ans->dbl_v[i] = narm ? 0.0 : NA_REAL; \ |
367 | | -} else { \ |
368 | | - if (narm) { \ |
369 | | - if (pinf == 0) { \ |
370 | | - if (ninf == 0) { \ |
371 | | - ans->dbl_v[i] = (double) w; \ |
372 | | - } else { \ |
373 | | - ans->dbl_v[i] = R_NegInf; \ |
374 | | - } \ |
375 | | - } else if (ninf == 0) { \ |
376 | | - ans->dbl_v[i] = R_PosInf; \ |
377 | | - } else { \ |
378 | | - ans->dbl_v[i] = R_NaN; \ |
379 | | - } \ |
380 | | - } else { \ |
381 | | - ans->dbl_v[i] = NA_REAL; \ |
382 | | - } \ |
383 | | -} |
384 | | - |
385 | 382 | for (i=0; i<k-1; i++) { // loop over leading observation, all partial window only; #loop_counter_not_local_scope_ok |
386 | 383 | SUM_WINDOW_STEP_FRONT |
387 | 384 | ans->dbl_v[i] = fill; // partial window fill all |
@@ -472,7 +469,6 @@ void frollsumExact(const double *x, uint64_t nx, ans_t *ans, int k, double fill, |
472 | 469 | } |
473 | 470 | } |
474 | 471 |
|
475 | | - |
476 | 472 | static inline void wmax(const double * restrict x, uint64_t o, int k, double * restrict w, uint64_t *iw, bool narm) { |
477 | 473 | if (narm) { |
478 | 474 | for (int i=0; i<k; i++) { |
@@ -889,6 +885,50 @@ void frollminExact(const double *x, uint64_t nx, ans_t *ans, int k, double fill, |
889 | 885 | } |
890 | 886 | } |
891 | 887 |
|
| 888 | +#undef PROD_WINDOW_STEP_FRONT |
| 889 | +#define PROD_WINDOW_STEP_FRONT \ |
| 890 | + if (R_FINITE(x[i])) { \ |
| 891 | + w *= x[i]; \ |
| 892 | + } else if (ISNAN(x[i])) { \ |
| 893 | + nc++; \ |
| 894 | + } else if (x[i]==R_PosInf) { \ |
| 895 | + pinf++; \ |
| 896 | + } else if (x[i]==R_NegInf) { \ |
| 897 | + ninf++; \ |
| 898 | + } |
| 899 | +#undef PROD_WINDOW_STEP_BACK |
| 900 | +#define PROD_WINDOW_STEP_BACK \ |
| 901 | + if (R_FINITE(x[i-k])) { \ |
| 902 | + w /= x[i-k]; \ |
| 903 | + } else if (ISNAN(x[i-k])) { \ |
| 904 | + nc--; \ |
| 905 | + } else if (x[i-k]==R_PosInf) { \ |
| 906 | + pinf--; \ |
| 907 | + } else if (x[i-k]==R_NegInf) { \ |
| 908 | + ninf--; \ |
| 909 | + } |
| 910 | +#undef PROD_WINDOW_STEP_VALUE |
| 911 | +#define PROD_WINDOW_STEP_VALUE \ |
| 912 | + if (nc == 0) { \ |
| 913 | + if (pinf == 0 && ninf == 0) { \ |
| 914 | + ans->dbl_v[i] = (double) w; \ |
| 915 | + } else { \ |
| 916 | + ans->dbl_v[i] = (ninf+(w<0))%2 ? R_NegInf : R_PosInf; \ |
| 917 | + } \ |
| 918 | + } else if (nc == k) { \ |
| 919 | + ans->dbl_v[i] = narm ? 1.0 : NA_REAL; \ |
| 920 | + } else { \ |
| 921 | + if (narm) { \ |
| 922 | + if (pinf == 0 && ninf == 0) { \ |
| 923 | + ans->dbl_v[i] = (double) w; \ |
| 924 | + } else { \ |
| 925 | + ans->dbl_v[i] = (ninf+(w<0))%2 ? R_NegInf : R_PosInf; \ |
| 926 | + } \ |
| 927 | + } else { \ |
| 928 | + ans->dbl_v[i] = NA_REAL; \ |
| 929 | + } \ |
| 930 | + } |
| 931 | + |
892 | 932 | /* fast rolling prod - fast |
893 | 933 | * same as mean fast |
894 | 934 | */ |
@@ -937,51 +977,6 @@ void frollprodFast(const double *x, uint64_t nx, ans_t *ans, int k, double fill, |
937 | 977 | if (truehasnf) { |
938 | 978 | int nc = 0, pinf = 0, ninf = 0; // NA counter within sliding window |
939 | 979 | int i; // iterator declared here because it is being used after for loop |
940 | | - |
941 | | -#undef PROD_WINDOW_STEP_FRONT |
942 | | -#define PROD_WINDOW_STEP_FRONT \ |
943 | | - if (R_FINITE(x[i])) { \ |
944 | | - w *= x[i]; \ |
945 | | - } else if (ISNAN(x[i])) { \ |
946 | | - nc++; \ |
947 | | - } else if (x[i]==R_PosInf) { \ |
948 | | - pinf++; \ |
949 | | - } else if (x[i]==R_NegInf) { \ |
950 | | - ninf++; \ |
951 | | - } |
952 | | -#undef PROD_WINDOW_STEP_BACK |
953 | | -#define PROD_WINDOW_STEP_BACK \ |
954 | | - if (R_FINITE(x[i-k])) { \ |
955 | | - w /= x[i-k]; \ |
956 | | - } else if (ISNAN(x[i-k])) { \ |
957 | | - nc--; \ |
958 | | - } else if (x[i-k]==R_PosInf) { \ |
959 | | - pinf--; \ |
960 | | - } else if (x[i-k]==R_NegInf) { \ |
961 | | - ninf--; \ |
962 | | - } |
963 | | -#undef PROD_WINDOW_STEP_VALUE |
964 | | -#define PROD_WINDOW_STEP_VALUE \ |
965 | | - if (nc == 0) { \ |
966 | | - if (pinf == 0 && ninf == 0) { \ |
967 | | - ans->dbl_v[i] = (double) w; \ |
968 | | - } else { \ |
969 | | - ans->dbl_v[i] = (ninf+(w<0))%2 ? R_NegInf : R_PosInf; \ |
970 | | - } \ |
971 | | - } else if (nc == k) { \ |
972 | | - ans->dbl_v[i] = narm ? 1.0 : NA_REAL; \ |
973 | | - } else { \ |
974 | | - if (narm) { \ |
975 | | - if (pinf == 0 && ninf == 0) { \ |
976 | | - ans->dbl_v[i] = (double) w; \ |
977 | | - } else { \ |
978 | | - ans->dbl_v[i] = (ninf+(w<0))%2 ? R_NegInf : R_PosInf; \ |
979 | | - } \ |
980 | | - } else { \ |
981 | | - ans->dbl_v[i] = NA_REAL; \ |
982 | | - } \ |
983 | | - } |
984 | | - |
985 | 980 | for (i=0; i<k-1; i++) { // loop over leading observation, all partial window only; #loop_counter_not_local_scope_ok |
986 | 981 | PROD_WINDOW_STEP_FRONT |
987 | 982 | ans->dbl_v[i] = fill; // partial window fill all |
|
0 commit comments