How to obtain the gradient of a scipy interpolant directly?
I have a largish 3D numpy array of scalar values (OK call it a "volume" if you must). I want to interpolate a smooth scalar field over this at a succession of irregular, not all known up-front non-integral xyz coordinates.
Now Scipy's support for this is just excellent: I filter the volume with
filtered_volume = scipy.ndimage.interpolation.spline_filter(volume)
and invoke
scipy.ndimage.interpolation.map_coordinates(
filtered_volume,
[[z],[y],[x]],
prefilter=False)
for (x,y,z) of interest to obtain apparently nicely behaved (smooth etc) interpolated values.
So far so good. However, my application also needs the local derivatives of the interpolated field. Currently I obtain these by central-differencing: I also sample the volume at 6 additional points (this can at least be done with just one call to map_coordinates
) and calculate e.g the x derivative from (i(x+h,y,z)-i(x-h,y,z))/(2*h)
. (Yes I know I could reduce the number of additional taps to 3 and do "one sided" differences, but the asymmetry would annoy me.)
My instinct is that there ought to be a more direct way of obtaining the gradient
but I don't know enough spline math (yet) to开发者_开发知识库 figure it out, or understand what's
going on in the guts of the Scipy implementation: scipy/scipy/ndimage/src/ni_interpolation.c
.
Is there a better way of obtaining my gradients "more directly" than central differencing ? Preferably one which allows them to be obtained using the existing functionality rather than hacking on Scipy's innards.
Aha: according to the classic paper on splines cited in the numpy code, splines of order n and their derivatives are related by
n n-1 n-1
dB (x)/dx = B (x+1/2) - B (x-1/2)
So using SciPy's spline interpolation I could get my derivatives by also maintaining a lower-order prefiltered volume and querying that a couple of times per derivative. This means adding a fair amount of memory (maybe competition with the "main" volume for cache), but presumably evaluation of the lower order splines is faster, so it's not obvious to me whether it would be faster or not overall than the central differencing using small offsets I'm doing currently. Haven't tried it yet.
精彩评论