1
$\begingroup$

I would like to make an independent multivariable fit, but I have problems using a Table that I generated. I can´t use their elements because it isn´t in a list or a rectangular array.

Using Table[ ] to generate data

I want to make a kind of fit, for data that I got from a numerical solved integral. To get this multiple results I used Table[ ], by iterating. In this example I have table´s elements with three components.

data = Table[{i, j, 
    NIntegrate[((i^2)*
        j) (-Cos[θ] Cos[ϕ] - 
         Sin[θ] Sin[ϕ])/((i^2)*(Cos[ϕ] - 
              Cos[θ])^2 + (i^2)*(Sin[ϕ] - 
              Sin[θ])^2 + (j^2))^(3/2), {θ, 0, 
      2 π}, {ϕ, 0, 2 π}, Method -> "Trapezoidal", 
     AccuracyGoal -> 10]}, {i, 0.01, 1, 0.01}, {j, 0.2, 1, 0.01}];
ListPointPlot3D[data, PlotStyle -> Directive[PointSize[Medium], Red]] 

Making a Fit

I was writing the following code based on examples in this forum and Mathematica documentation. I was hoping that my data generated with Table[ ] runs well.

model = -a (x/y)^2; 
fit = FindFit[data, model, {a}, {x, y}] 
Show[Plot3D[model /. fit, {x, 0, 1}, {y, 0, 1}, PlotRange -> All], 
 ListPointPlot3D[data, 
  PlotStyle -> Directive[PointSize[Medium], Red]]]  

But after second line I get:

FindFit::fitd: First argument {{{0.01,0.2,-0.000365534},{0.01,0.21,-0.000301072},{0.01,0.22,-0.000250202},<<5>>,{0.01,0.28,-0.0000957317},{0.01,0.29,-0.0000832305},<<71>>},<<9>>,<<90>>} in FindFit is not a list or a rectangular array. 

For this reason I'm looking for how to make this format conversion. Grid[ ] doesn´t work. I've been watching examples where using data generated with MapThreat[ ] it works, and I ask again, how to convert my data got with Table[ ] to MapThreat[ ]?

How to do it using a function?

I think that an alternative way is use a function, but i don´t have idea how to implement this in fit´s code.

h[i_, j_] := 
  NIntegrate[((i^2)*j) (-Cos[θ] Cos[ϕ] - 
       Sin[θ] Sin[ϕ])/((i^2)*(Cos[ϕ] - 
            Cos[θ])^2 + (i^2)*(Sin[ϕ] - 
            Sin[θ])^2 + (j^2))^(3/2), {θ, 0, 
    2 π}, {ϕ, 0, 2 π}, Method -> "Trapezoidal", 
   AccuracyGoal -> 10]; 

I apologize if this question is trivial, I was looking for information but I can´t make it works. Thank you for read.

$\endgroup$

1 Answer 1

2
$\begingroup$

When you fit using FindFit it is better not to take too much points. The error message tells us, that one needs to Flattenyour nested list. Try this:

data = Flatten[
  Table[{i, j, 
    NIntegrate[((i^2)*
        j) (-Cos[\[Theta]] Cos[\[Phi]] - 
         Sin[\[Theta]] Sin[\[Phi]])/((i^2)*(Cos[\[Phi]] - 
              Cos[\[Theta]])^2 + (i^2)*(Sin[\[Phi]] - 
              Sin[\[Theta]])^2 + (j^2))^(3/2), {\[Theta], 0, 
      2 \[Pi]}, {\[Phi], 0, 2 \[Pi]}, Method -> "Trapezoidal", 
     AccuracyGoal -> 10]}, {i, 0.1, 1, 0.1}, {j, 0.1, 1, 0.1}], 1];


model = -a*(x/y)^2;
fit = FindFit[data, model, {a}, {x, y}]
Show[Plot3D[model /. fit, {x, 0.1, 1}, {y, 0.1, 1}, PlotRange -> All],
  ListPointPlot3D[data, 
  PlotStyle -> Directive[PointSize[Medium], Red]]]

(*  {a -> 1.79013}  *)

enter image description here

I recommend changing your model a bit:

Manipulate[
 model = -a*(x/y)^c + b;
 fit = FindFit[data, model, {a, b}, {x, y}];
 Show[Plot3D[model /. fit, {x, 0.1, 1}, {y, 0.1, 1}, 
   PlotRange -> All], 
  ListPointPlot3D[data, 
   PlotStyle -> Directive[PointSize[Medium], Red]]], {{c, 1.038}, 0.5,
   1.5, Appearance -> "Labeled"}]

and play with the parameter c a bit. It returns the following

enter image description here

Very nice. Let me add that after you have found a suitable value of c you can find its finer value using FindFit as follows:

model = -a*(x/y)^c + b;
fit = FindFit[data, model, {a, b, {c, 1.038}}, {x, y}]
Show[Plot3D[model /. fit, {x, 0.1, 1}, {y, 0.1, 1}, PlotRange -> All],
  ListPointPlot3D[data, 
  PlotStyle -> Directive[PointSize[Medium], Red]]]

(*  {a -> 9.34242, b -> 1.86593, c -> 1.20022}  *)

Have fun!

$\endgroup$
1
  • 1
    $\begingroup$ Wow! I have no words to express how grateful I am, thank you. Thanks for not ignoring my question even though there was a simple solution, I was looking for it for a long time, but I think I would never find the function Flatten[ ]. And your last recommendation it was far from my point of view about how to use Mathematica, is fantastic, blow my mind, i will use this approaching in the future. $\endgroup$ Mar 17, 2021 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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