# How to fit a data a long 3D path?

I have two data sets in the form dat1={{x,y,z}, f1[x,y,z]} and dat2={{x,y,z}, f2[x,y,z]} I want to fit a model with common parameters. A minimum example: first these two functions to synthesize some data

f1[{x_, y_, z_}] =
G0 - Sqrt[G^2 + c24^2 x^2 + c24^2 y^2 + c23^2 z^2];
f2[{x_, y_, z_}] =
G0 + Sqrt[G^2 + c24^2 x^2 + c24^2 y^2 + c23^2 z^2];
G = c01 - c11 z^2 - c12 (x^2 + y^2);
G0 = c02 + c21 z^2 + c22 (x^2 + y^2);


the points xyzdata={x,y,z} are known

xyzdata={{1.28228, 0., 1.28228}, {1.21817, 0., 1.21817}, {1.15405, 0.,
1.15405}, {1.08994, 0., 1.08994}, {1.02583, 0., 1.02583}, {0.961712,
0., 0.961712}, {0.897598, 0., 0.897598}, {0.833484, 0.,
0.833484}, {0.76937, 0., 0.76937}, {0.705256, 0.,
0.705256}, {0.641141, 0., 0.641141}, {0.577027, 0.,
0.577027}, {0.512913, 0., 0.512913}, {0.448799, 0.,
0.448799}, {0.384685, 0., 0.384685}, {0.320571, 0.,
0.320571}, {0.256457, 0., 0.256457}, {0.192342, 0.,
0.192342}, {0.128228, 0., 0.128228}, {0.0641141, 0.,
0.0641141}, {2.50691*10^-16, 0., 2.50691*10^-16}, {0., 0.,
0.}, {0.0641141, 0., 0.}, {0.128228, 0., 0.}, {0.192342, 0.,
0.}, {0.256457, 0., 0.}, {0.320571, 0., 0.}, {0.384685, 0.,
0.}, {0.448799, 0., 0.}, {0.512913, 0., 0.}, {0.577027, 0.,
0.}, {0.641141, 0., 0.}, {0.705256, 0., 0.}, {0.76937, 0.,
0.}, {0.833484, 0., 0.}, {0.897598, 0., 0.}, {0.961712, 0.,
0.}, {1.02583, 0., 0.}, {1.08994, 0., 0.}, {1.15405, 0.,
0.}, {1.21817, 0., 0.}};


Now we get the two data as

Block[{c01 = 0.108, c02 = 0.052, c11 = -0.15, c12 = 1.42,
c21 = 0.075, , c22 = 0.425, c23 = -0.34, c24 = 0.51, kx, ky, kz},
data1 = Table[{xyzdata[[i]], f1[xyzdata[[i]]]}, {i, Length@xyzdata}];
data2 =
Table[{xyzdata[[i]], f2[xyzdata[[i]]]}, {i, 1, Length@xyzdata}]]


Finally, we can plot these data as

ListPlot[{data1[[All, 2]], data2[[All, 2]]}, PlotRange -> {-1, 1},
PlotLegends -> {"dat1", "dat2"}]


my question is assuming that we don't know the constants {c01,c02,c11,c12,c21,c22,c23,c24} that are used to generate data1 and data1 how can we fit the data to get the constants?

• See the documentation on NonlinearFit. Commented Sep 18, 2023 at 13:38
• Similar to this ? Commented Sep 18, 2023 at 13:39
• Have you looked at ResourceFunction["MultiNonlinearModelFit"]? Commented Sep 18, 2023 at 14:37

Fitting functions with shared parameters is what I wrote ResourceFunction["MultiNonlinearModelFit"] for. You just need to punch the data into the right format:

fit = ResourceFunction["MultiNonlinearModelFit"][
{
Flatten /@ data1,
Flatten /@ data2
},
{f1[{x, y, z}], f2[{x, y, z}]},
{c01, c02, c11, c12, c21, c22, c23, c24},
{x, y, z}
]
fit["BestFitParameters"]


To get a fit, we must first bring the data in a suitable form: {x,y,z,f[xy,z]} (note, define G and G0= before f1 and f2):

dat1 = Map[Flatten, data1, {1}];
dat2 = Map[Flatten, data2, {1}];


With the data adapted we can do the fit:

fun1 = NonlinearModelFit[dat1,
f1[{x, y, z}], {c01, c11, c12, c02, c21, c22, c23, c24}, {x, y, z}];
fun2 = NonlinearModelFit[dat2,
f2[{x, y, z}], {c01, c11, c12, c02, c21, c22, c23, c24}, {x, y,
z}];


To get the fitted parameters:

fun1["BestFitParameters"]

{c01 -> 0.108, c11 -> -0.15, c12 -> 1.42, c02 -> 0.052, c21 -> 0.075,
c22 -> 0.425, c23 -> -0.34, c24 -> 0.51}

fun2["BestFitParameters"]

{c01 -> 0.108, c11 -> -0.15, c12 -> 1.42, c02 -> 0.052, c21 -> 0.075,
c22 -> 0.425, c23 -> -0.34, c24 -> 0.51}