# Fitting two-dimensional data

For this question, I cannot use random sample data. So the actual data can be found here. The data file contains three columns, where the first two are the coordinates $$(x,y)$$, while the third is the value of a function $$f$$. Now we plot them, thus obtaining the shape of $$f$$

data = Import["L1.dat", "Table"];


or

data = Import["https://pastebin.com/raw/YMCFB4mK", "TSV"]


Plot

L0 = ListPlot3D[data]


My question is the following: is there a way to interpolate the data and obtain an analytical fitting function $$f(x,y)$$? Taking into account that the distribution of $$f$$ is rather smooth, without peaks and holes, I suppose it should be rather easy to obtain its fitting function. Any ideas?

• have you tried Interpolation? E.g., iF = Interpolation[data];Plot3D[iF[x, y], {x, 0, .5}, {y, 0, 1}]? – kglr Jul 21 '19 at 10:39
• @kglr I want to obtain an analytical equation of the form f = ax^2 + b*y^2 +.... – Vaggelis_Z Jul 21 '19 at 10:42
• It's either Interpolation or fit. What is it? – rhermans Jul 21 '19 at 10:54
• Thanks for accepting my answer, but I think you were too hasty doing that. While accepting is one of the things to do after your question is answered, we recommend that users should test answers before voting and wait 24 hours before accepting the best one. That allows people in all timezones to answer your question and an opportunity for other users to point alternatives, caveats or limitations of the available answers. I have edited my answer so you can accept the best one later. – rhermans Jul 21 '19 at 11:28

## Interpolation

intFunc = With[
{
order = 1,
dat = Import["https://pastebin.com/raw/YMCFB4mK", "TSV"]
},
Interpolation[{{#1, #2}, #3} & @@@ dat, InterpolationOrder -> order]
]

Plot3D[
intFunc[x, y]
, {x, 0.001, 1/2}
, {y, 0, 1}
, PlotStyle -> Green
]


## Fit

fitModel = With[
{
order = 4,
dat = Import["https://pastebin.com/raw/YMCFB4mK", "TSV"]
},
LinearModelFit[
dat
, Flatten@Outer[Times, Sequence @@ Transpose@Array[Power[{x, y}, # - 1] &, order + 1]]
, {x, y}
]
]

fitModel[x,y]
(* 0.839678 - 3.39587 x + 10.2762 x^2 - 23.2243 x^3 + 18.9954 x^4 -
0.870772 y - 1.85421 x y + 14.7251 x^2 y - 36.8365 x^3 y +
31.9079 x^4 y + 1.78944 y^2 + 5.55233 x y^2 - 43.8506 x^2 y^2 +
111.182 x^3 y^2 - 96.807 x^4 y^2 - 1.99269 y^3 - 5.49884 x y^3 +
46.2492 x^2 y^3 - 118.606 x^3 y^3 + 103.764 x^4 y^3 + 0.819593 y^4 +
1.98819 x y^4 - 17.6815 x^2 y^4 + 45.7184 x^3 y^4 - 40.1317 x^4 y^4 *)

Show[
Plot3D[
fitModel[x, y]
, {x, 0, 1/2}
, {y, 0, 1}
, PlotStyle -> Blue
]
, ListPlot3D[
dat
, PlotStyle -> Directive[Red, Opacity[0.5]]
]
]


• @Vaggelis_Z I think you misunderstand the output of LinearModelFit. The fit is linear only on the coefficients. See my edit. – rhermans Jul 21 '19 at 10:59

Adapting the approach from this answer:

vars = {x, y};
maxdegree = 3;
cols = Join @@ (MonomialList[(Plus @@ vars)^#] /. _Integer x_ :> x & /@ Range[maxdegree]);
nparams = 5;
models = Prepend[#, 1] & /@ Subsets[cols, {1, nparams}];
Length@models


381

fits = Table[Join[{j}, {Length@j}, LinearModelFit[l1dat, j, vars][{"BestFit", "AICc", "BIC",
"AdjustedRSquared", "RSquared"}]], {j, models}]

topTenByAICc = SortBy[fits, #[[4]] &][[;; 10]];
Style[# /. x_Real :> Round[x, .00001]] &@
Grid[{{"Model", "Length", "BestFit", "AICc", "BIC",
"AdjustedRSquared", "RSquared"}, ## & @@ topTenByAICc}, Dividers -> All]


bestmodel = topTenByAICc[[1, 3]];
Show[Plot3D[bestmodel, {x, 0, .6}, {y, 0, .1}, Mesh -> None],
ListPointPlot3D[l1dat, PlotStyle -> Opacity[.5, Red]]]