Bug introduced in 7 or earlier and persisting through 11.0.1 or later
[CASE:3487737]
I have a 2-d array that I would like to resample into a different coordinate system and integrate along one of the new coordinates. Here is an example array:
arr = GaussianMatrix[50]*ArrayPad[DiamondMatrix[5], {45, 45}, DiamondMatrix[5]];
ArrayPlot[arr, PixelConstrained -> {1, 1}]
To accomplish the resampling, I interpolate:
if = ListInterpolation[arr, InterpolationOrder -> 1, Method -> "Hermite"];
DensityPlot[if[x, y], {x, 1, 101}, {y, 1, 101},
PlotPoints -> 101, MaxRecursion -> 0
]
(The interpolation is good, even if the DensityPlot
looks a bit ragged.)
It is easy to integrate the InterpolationFunction
along one of the "natural" coordinates (i.e., without resampling):
int = Integrate[if[x, y], {x, 40, 60}]
(* -> InterpolatingFunction[{{1., 101.}}, <>][y] *)
Plot[int, {y, 1, 101}]
However, any change (even a trivial one) to the coordinate system causes Integrate
to produce a nonsensical answer:
Integrate[if[(x + y)/2, y], {x, 40, 60}]
(* -> 20 InterpolatingFunction[{{1., 101.}, {1., 101.}}, <>][(x + y)/2, y] *)
Integrate[if[x + 1, y], {x, 40, 60}]
(* -> 20 InterpolatingFunction[{{1., 101.}, {1., 101.}}, <>][1 + x, y] *)
As the answers to this related question propose, we could work around this by re-interpolating the resampled function using FunctionInterpolation
before integrating. This would work:
if2 = FunctionInterpolation[
if[(x + y)/2, y], {x, 1, 101}, {y, 1, 101},
InterpolationOrder -> 1
];
int2 = Integrate[if2[x, y], {x, 40, 60}]
(* -> InterpolatingFunction[{{1., 101.}}, <>][y] *)
The problem is that FunctionInterpolation
does a very poor job of sampling the function unless InterpolationPoints
is far above twice the "resolution" of the underlying interpolation. In this case over 500(!) InterpolationPoints
are needed to get a reasonable reproduction of the resampled function:
- Default (11)
InterpolationPoints
- 101
InterpolationPoints
- 301
InterpolationPoints
- and so on...
As you can see, the result is aliased to the point of uselessness until InterpolationPoints
gets really high. With so many sampling points required, this is not an intelligent way to proceed, and there is no benefit to using FunctionInterpolation
and Integrate
over tabulating the function values at high resolution and summing over the resulting array.
So:
- Is it possible to construct the resampled
InterpolatingFunction
from the originalListInterpolation
more intelligently, to obtain better results than those given byFunctionInterpolation
? Or, - Can
Integrate
be made to behave more reasonably when given the integration directly?