3
$\begingroup$

I met with a problem when trying to find the interpolation function of a 2 variable function. The function is like below (already simplified for brevity):

testfun = x/(1 + y^2);

Then, use FunctionInterpolation to find the interpolation function:

intfun = FunctionInterpolation[ testfun, {y, -20, 20}, {x, 0, 2}];

If I plot the original function and the interpolation function together, the plot looks like this:

p1 = Plot[testfun /. x -> 1, {y, -20, 20}, PlotRange -> All, PlotStyle -> Red];
p2 = Plot[intfun[x, 1], {x, -20, 20}, PlotRange -> All, PlotStyle -> Blue];
Show[p1, p2]

enter image description here

The FunctionInterpolation normally works well with simple functions (like fun = x^2+a), but I don't know what lead to the result like this. Anyone have an idea? Thanks!

And the 3D-plot for 2 variables is shown as below:

Plot3D[{testfun, intfun[y, x]}, {y, -20, 20}, {x, 0, 2}, 
 PlotRange -> All, PlotStyle -> {Red, Blue}]

enter image description here

$\endgroup$
4
  • $\begingroup$ "Two variable interpolation function" means that the function to be interpolated is of two variables, generally $x$ and $y$. You have a one-dimensional function. $\endgroup$ Apr 26 '16 at 22:02
  • $\begingroup$ David, thanks for your reply! I do have $x$ and $y$ in the function. $\endgroup$
    – wenhao
    Apr 26 '16 at 22:18
  • $\begingroup$ Plot the two-dimensional function, not a one-dimensional slice of it. $\endgroup$ Apr 26 '16 at 22:20
  • $\begingroup$ Please see above. $\endgroup$
    – wenhao
    Apr 26 '16 at 22:31
4
$\begingroup$

Short Answer

You need to set the InterpolationPoints to a higher value than the default in order to get a decent result out of FunctionInterpolation. For this example, 125 is the lowest I found that gives a good plot,

testfun[y_, x_] := x/(1 + y^2);
intfun = FunctionInterpolation[testfun[y, x], {y, -20, 20}, {x, 0, 2},
    InterpolationPoints -> 125];
Plot[{testfun[y, 1], intfun[y, 1]}, {y, -20, 20}, PlotRange -> All]

Mathematica graphics

Long Answer

Let's look at the default options for FunctionInterpolation,

Options[FunctionInterpolation]
(* {InterpolationOrder -> 3, 
 InterpolationPrecision -> Automatic, AccuracyGoal -> Automatic, 
 PrecisionGoal -> Automatic, InterpolationPoints -> 11, 
 MaxRecursion -> 6} *)

What InterpolationPoints means is that for every variable, the input range is subdivided into 11 points. Let's take the default result from FunctionInterpolation and see if we can recreate it using Interpolation.

intfun1 = FunctionInterpolation[testfun[y, x], {y, -20, 20}, {x, 0, 2}]
interpolatingdata = 
  Table[{{y, x}, testfun[y, x]}, {y, Subdivide[-20, 20, 10]}, {x, 
     Subdivide[0, 2, 10]}]~Flatten~1;
intfun2 = Interpolation[interpolatingdata]
intfun1 == intfun2

enter image description here

You can see from the last line that the results are identical. By plotting the actual input points alongside the plot, you can see that the resulting interpolating function does go through the points, it just doesn't correctly reproduce the regions in between:

Plot[{testfun[y, 1], intfun1[y, 1], intfun2[y, 1]}, {y, -20, 20}, 
  PlotRange -> All]~Show~
 Graphics[{Red, PointSize[Large], 
   Point@Cases[interpolatingdata, {{a_, 1}, b_} :> {a, b}, Infinity]}]

Mathematica graphics

Why do you need to use so many points? I'm no expert, but I would say it is because your function is not a polynomial, and the documentation says

Interpolation works by fitting polynomial curves between successive data points

Interestingly, if you had tried this as a one-dimensional function from the start, FunctionInterpolation would automatically increase the number of InterpolationPoints:

testfun[y_, x_] := x/(1 + y^2);
intfun = FunctionInterpolation[testfun[y, 1], {y, -20, 20}];
Plot[{testfun[y, 1], intfun[y]}, {y, -20, 20}, PlotRange -> All]

enter image description here

You can see the number of points that were finally used with

Length[intfun[[3, 1]]]
(* 133 *)

Why it doesn't recursively increase the number of points for a 2D function is not clear - the documentation for FunctionInterpolation is sparse. Could be a bug, or expected behavior.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.