Handle two 3 rows x 2 columns matrices in NonlinearModelFit?

Hi Mathematica Community!

I have a question related to non linear data fitting and I really need some guide on this. I am trying to fit my data to a non linear model fit function. However, it says “NonlinearModelFit::fitd: First argument {{{0,1},{1,0},{3,2}},{{0,2},{1,3},{3,4}}} in NonlinearModelFit is not a list or a rectangular array”. I think the non linear model fit function could not recognize sub lists and it can only handle a 3 rows x 2 columns matrix instead of two 3 rows x 2 columns matrices.

Thanks for spending your time and i really appreciate your help. I have also attached a copy of my codes.

In[1]:=  data = {{{0, 1}, {1, 0}, {3, 2}}, {{0, 2}, {1, 3}, {3, 4}}};

In [2]:= Dimensions[data]

Out[2]:= {2, 3, 2}

In[3]:= nlm = NonlinearModelFit[data, Log[a + bx^2], {a, b}, x]

NonlinearModelFit::fitd: First argument {{{0,1},{1,0},{3,2}},{{0,2},{1,3},{3,4}}} in NonlinearModelFit is not a list or a rectangular array. 

NonlinearModelFit::fitd: First argument {{{0,1},{1,0},{3,2}},{{0,2},{1,3},{3,4}}} in NonlinearModelFit is not a list or a rectangular array. 

Out[3] := NonlinearModelFit[{{{0, 1}, {1, 0}, {3, 2}}, {{0, 2}, {1, 3}, {3, 4}}}, Log[a + bx^2], {a, b}, x]

Your data structure is not accepted by NonlinearModelFit. What is the meaning of the two sublists {{0, 1}, {1, 0}, {3, 2}} and {{0, 2}, {1, 3}, {3, 4}}? Are they two separate datasets? If so, you can fit them separately:

NonlinearModelFit[data[[1]], Log[a + b x^2], {a, b}, x]
NonlinearModelFit[data[[2]], Log[a + b x^2], {a, b}, x]

By sublists, I mean that I am hoping to perform the NonlinearModelFit to a large group of functions. In this case, I posted a simple example of just two lists but ultimately need to perform the function on about 1000 lists for the data I am analyzing. How should I write the code so it performs the function a certain number of times, all with matrices of data that are outputs of another function?

Going into the NonlinearModelFit will be ~1000 or so 855x3 matrices of data which I am hoping to perform the model on and then eventually take the average of these 1000 values.

Please let me know if you can help in any way. Thank you.

If your model Log[a + b x^2] is always the same, you can do it this way:

data = {{{0, 1}, {1, 0}, {3, 2}}, {{0, 2}, {1, 3}, {3, 4}}};
myModelFit[dataMatrix_] := 
  NonlinearModelFit[dataMatrix, Log[a + b x^2], {a, b}, x];
Map[myModelFit, data]

By the way, there is a typo in your original code: Log[a + bx^2] should be Log[a + b*x^2]. Without a space bx is a single symbol, not the product of b and x.

Hi GianLuca,

Thanks for pointing out my mistakes. I really appreciate your help.

I run the codes and it worked really well! I have question related to the best fit parameters. How do I assess my best fit parameters?

Thanks again for your help.

The output of NonlinearModelFit is a complicated structure, containing a lot of “Properties” that you can extract. You get a list this way:

NonlinearModelFit[Range[10], Exp[a x], a, x]
%["Properties"]

Look up the documentation of NonlinearModelFit, in the Scope > Properties section.

Hi Gianluca,

Thanks again for your help. I looked up the NonlinearModelFit and found a few interesting “Properties”. I tried to output the Model [“BestFitParameters”], however the program returned the fitted model instead of values. I think the reason is because I change the format from data to an expression called dataMatrix. Hence, the program cannot recognize the first argument in NonlinearModelFit.

Do you know any way I can solve this problem? I will greatly appreciate any advice on this. I have also attached my codes to this discussion.

Thanks.

You need to assign your output to a variable.

sampledata = {{{0, 1}, {1, 0}, {3, 2}}, {{0, 2}, {1, 3}, {3, 4}}};
myModelFit[dataMatrix_] := 
  NonlinearModelFit[dataMatrix, Log[a + b *x^2], {a, b}, x];
{nlm1, nlm2} = Map[myModelFit, sampledata]
nlm1["BestFitParameters"]
nlm2["BestFitParameters"]

I also recommend to always check out the residuals after a fit

GraphicsRow[{Show[ListPlot[sampledata[[1]], Frame -> True], 
   Plot[nlm1[x], {x, 0, 3}, PlotStyle -> Red]], 
  ListPlot[nlm1["FitResiduals"], Frame -> True]}, ImageSize -> Large]

Best of luck!
Cheers,
-Will