diff --git a/NEWS.md b/NEWS.md index 6152fe738..0b61bf779 100644 --- a/NEWS.md +++ b/NEWS.md @@ -49,6 +49,7 @@ - Delay distribution discretisation now properly accounts for primary event censoring during model fitting, matching the correction already applied on the R side since v1.8.0. This improves accuracy for short delays where the observation window is large relative to the delay. - Left truncation of delay distributions (e.g. excluding generation times of zero) is now handled analytically rather than by zeroing and renormalising, giving more accurate PMFs near the truncation point. +- Reduced Stan convolution overhead by inlining index bookkeeping in the report-generation hot path. ## Package changes diff --git a/inst/stan/functions/convolve.stan b/inst/stan/functions/convolve.stan index 2a84df929..fc2db38b1 100644 --- a/inst/stan/functions/convolve.stan +++ b/inst/stan/functions/convolve.stan @@ -73,14 +73,20 @@ vector convolve_with_rev_pmf(vector x, vector y, int len) { } for (s in 1:xlen) { - array[4] int indices = calc_conv_indices_xlen(s, xlen, ylen); - z[s] = dot_product(x[indices[1]:indices[2]], y[indices[3]:indices[4]]); + int s_minus_ylen = s - ylen; + int start_x = max(1, s_minus_ylen + 1); + int end_x = s; + int start_y = max(1, 1 - s_minus_ylen); + z[s] = dot_product(x[start_x:end_x], y[start_y:ylen]); } if (len > xlen) { for (s in (xlen + 1):len) { - array[4] int indices = calc_conv_indices_len(s, xlen, ylen); - z[s] = dot_product(x[indices[1]:indices[2]], y[indices[3]:indices[4]]); + int s_minus_ylen = s - ylen; + int start_x = max(1, s_minus_ylen + 1); + int start_y = max(1, 1 - s_minus_ylen); + int end_y = ylen + xlen - s; + z[s] = dot_product(x[start_x:xlen], y[start_y:end_y]); } }