fn smoothing_width(prox: f64, n: f64, sigma: f64) -> f64Expand description
The Gaussian width SDF smooths a voxel with: sigma*round(prox^n, 2), as sdf_curvature.m
computes it.
Rounding to two decimals makes the width a discrete choice, which has to come out the same on
every target (or the browser and qsmxt run smooth a voxel on a rounding boundary with
different widths, and the inner inversion spreads the difference) and the same as MATLAB’s:
prox^ncomes fromportable_math::pow, and the proximity map it is computed from uses only portable functions too (the Gaussian kernels here and the curvature’s angles). The platform’spowfdiffers between targets in the last bit for about one input in ten, and a one-ulp difference flips the rounding whenever the value sits within an ulp of a hundredth’s midpoint.- The operations are MATLAB’s, in MATLAB’s order:
round(x, 2)isround(x*100)/100, with halves rounded away from zero (asf64::rounddoes), then multiplied bysigma. With QSMART’s own proximity map (prox.niifrom its 3 T reference run) as input, this gives itsalpha.niibit for bit, for both stages.sigma*round(x*100)/100evaluated left to right (as before) differs in the last bit in a quarter of the brain.
No libm is correctly rounded, MATLAB’s included, so a value within an ulp of a midpoint can
still round differently from MATLAB; away from midpoints every pow within an ulp of the
exact value gives MATLAB’s width.