Interpolator surface

Writing:

Clear[u, v];
{a0, b0, c0} = {1, 2, 3};

f = ((x/a)^2 + (y/b)^2) c;
g = {a0 Sqrt[u] Cos[v], b0 Sqrt[u] Sin[v], c0 u};
h = {};

For[u = 0, u <= 1, u = u + 0.05,
For[v = 0, v <= 2 Pi, v = v + 0.05,
h = Join[h, {g}]
]
];

FindFit[h, f, {{a, a0}, {b, b0}, {c, c0}}, {x, y}]


I get:

{a -> 1., b -> 2., c -> 3.}

that's exactly how much you want.

Unfortunately a0, b0, c0 in reality I do not know them, so I should write:

FindFit[h, f, {a, b, c}, {x, y}]


I get:

{a -> 0.533886, b -> 1.06777, c -> 0.855104}

which is a result very far from what is expected. How could I fix it?

There are no differences in the predictions. What you have is an over-parameterized model. You have attempted to fit too many parameters. The basic model is

$$f=a_x x^2+a_y y^2$$

There are really only 2 parameters to fit.

sol0 = FindFit[h, f, {{a, a0}, {b, b0}, {c, c0}}, {x, y}]
(* {a -> 1., b -> 2., c -> 3.} *)
f /. sol0 // Expand
(* 3. x^2 + 0.75 y^2 *)

sol1 = FindFit[h, f, {a, b, c}, {x, y}]
(* {a -> 0.533886, b -> 1.06777, c -> 0.855104} *)
f /. sol1 // Expand
(* 3. x^2 + 0.75 y^2 *)

• Sometimes I think I should take a break. Thank you so much for opening my eyes! – TeM Jan 20 at 16:09
• Same here. You might consider just using $(x/a)^2 + (y/b)^2$ which is just setting $c=1$ if the parameters $a$ and $b$ are easier to interpret. Also, using the mean of the $x$ and $y$ values for the starting values for $a$ and $b$ might be more numerically stable if the $x$'s and $y$'s are very large or very small. – JimB Jan 20 at 16:15

This is not an answer, but a hint on how to improve your coding by coding in a more functional style. Functional code is almost always more concise and more efficient than procedural code.

{a0, b0, c0} = {1, 2, 3};
g[a_, b_, c_] = {a Sqrt[#1] Cos[#2], b Sqrt[#1] Sin[#2], c #1} &;
h = Table[g[a0, b0, c0][u, v], {u, 0, 1, .05}, {v, 0, 2 π, .05}] // Catenate;

• Actually this was my first approach, but not knowing Catenate I left it. Thank you, very useful! – TeM Jan 21 at 21:37