tags:

views:

65

answers:

2

This list is a simple function that maps a 2D point to a number, if you regard each {{x,y},z} as f[x,y]=z

{ {{1,3},9}, {{1,4},16}, {{2,4},8}, {{2,5},10} }

I now want a function that interpolates/extrapolates f[x,y] for any {x,y}.

Mathematica refuses to do this:

Interpolation[{{{1,3},9}, {{1,4},16},{{2,4},8}, {{2,5},10}},
InterpolationOrder->1]

Interpolation::indim:
The coordinates do not lie on a structured tensor product grid.

I understand why (Mathematica wants a "rectangular" domain), but what's the easiest way to force Mathematica to create an interpolation?

This doesn't work:

f[1,3]=9; f[1,4]=16; f[2,4]=8; f[2,5]=10; g=FunctionInterpolation[f[x,y],{x,1,2},{y,3,5}]

FunctionInterpolation::nreal:
16 Near {x, y} = {1, --}, the function did not evaluate to a real number. 5

FunctionInterpolation::nreal:
17 Near {x, y} = {1, --}, the function did not evaluate to a real number. 5

FunctionInterpolation::nreal:
18 Near {x, y} = {1, --}, the function did not evaluate to a real number. 5

General::stop: Further output of FunctionInterpolation::nreal will be suppressed during this calculation.

Even if you ignore the warnings above, evaluating g gives errors

g[1.5,4] // FortranForm

     f(1.5,4) + 0.*(-9.999999999999991*(f(1.4,4) - f(1.5,4)) +  
 -      0.10000000000000009* 
 -       (9.999999999999991* 
 -          (9.999999999999991*(f(1.4,4) - f(1.5,4)) +  
 -            4.999999999999996*(-f(1.4,4) + f(1.6,4))) +  
 -         0.5000000000000006* 
 -          (-10.000000000000014* 
 -             (-3.333333333333333*(f(1.3,4) - f(1.6,4)) -  
 -               4.999999999999996*(-f(1.4,4) + f(1.6,4))) -  
 -            9.999999999999991* 
 -             (9.999999999999991*(f(1.4,4) - f(1.5,4)) +  
 -               4.999999999999996*(-f(1.4,4) + f(1.6,4)))))) 

The other "obvious" idea (interpolating interpolating functions themselves) doesn't work either.

+4  A: 

If polynomial interpolation is acceptable, InterpolatingPolynomial does what you want (where data is your list of points above):

In[63]:= InterpolatingPolynomial[data, {x, y}]

Out[63]= -24 + x (12 - 5 y) + 12 y

In[64]:= f[2, 3]

Out[64]= 6

You could also use Fit to do least-squares fitting on the linear combination of functions specified in the second argument:

In[65]:= Fit[Flatten /@ data, {1, x, y}, {x, y}]

Out[65]= 4.75 - 8. x + 4.5 y

Of course, a fitted function may not exactly interpolate your data points. If such fitting is acceptable though, FindFit can fit to any (linear or non-linear) model function you specify:

In[72]:= FindFit[Flatten/@data, x y (a Sin[x] + b Cos[y]) + c, {a,b,c}, {x,y}]

Out[72]= {a -> -0.683697, b -> 0.414257, c -> 15.3805}

HTH!

Michael Pilat
A: 
barrycarter