1
$\begingroup$

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"}]       

enter image description here

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?

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

2 Answers 2

5
$\begingroup$

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"]
$\endgroup$
2
$\begingroup$

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}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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