Use interpolation with better float accuracy in percentile
@@ -245,10 +245,17 @@ def _quantile_unchecked(a, q, axis=None, out=None, interpolation='linear',
ptrdiff_t idx_below = floor(idx);
U weight_above = idx - idx_below;
- ptrdiff_t offset_i = _ind.get()[0] * offset;
ptrdiff_t max_idx = size - 1;
- ret = a[offset_i + idx_below] * (1.0 - weight_above)
- + a[min(offset_i + idx_below + 1, max_idx)] * weight_above;
+ ptrdiff_t offset_bottom = _ind.get()[0] * offset + idx_below;
+ ptrdiff_t offset_top = min(offset_bottom + 1, max_idx);
+
+ U diff = a[offset_top] - a[offset_bottom];
+
+ if (weight_above < 0.5) {
+ ret = a[offset_bottom] + diff * weight_above;
+ } else {
+ ret = a[offset_top] - diff * (1 - weight_above);
+ }
''',
'percentile_weightnening'
)(indices, ap, ap.shape[-1] if ap.ndim > 1 else 0, ap.size, ret)
