1
$\begingroup$

i ve got quite simple function:

$f(t) = x1 * a(t) + x2 * b(t)$

and table of results like this one:

t | f(t) | a(t) | b(t)
----------------------
1 |  2   |   5  |  3
----------------------
2 |  4   |   9  | -4 
----------------------
3 |  10  |  12  | 5
----------------------

And I need this to solve with NonlinearModelFit, Ive looked across the internet, but I was not able to find solve and plot function like this..

My (wrong, not functionall solution):

data = {{2,5,3}, {4,9,-4}, {10,12,5}
// This line will ends with error: Number of coordinates (3) is not equal to the number of variables (2).
nls  = NonlinearModelFit[data, x1*y + x2*x, {{y, 0.3}, {x, -0.24}}, {y,z}} 

// Next thing is problem with plot.. offcourse i can do sth like this:
f = { {1, 2}, {2,4}, {3, 10}}

// This plot is incomplete, because I was no able to find
// how to write x in data array :(
Show[ListPlot[f], Plot[nls[t,x,y], ...

I bet someone will find solution immediatelly, but Iam new in Mathematica.. Sorry for the dataset (i cant send full dataset, its bigger).

Thanks

EDIT:

Thank you very much to @jens_bo, I solve that with his help and his response. The main problem was caused by sharing variables across notebooks in mathematica... restart mathematica and everything works great :)

$\endgroup$
  • $\begingroup$ Your model is manifestly linear, so there's no need for the elaboration of a nonlinear fit. $\endgroup$ – J. M. will be back soon May 6 '15 at 14:03
  • $\begingroup$ Welcome to Mathematica.SE! I suggest that: 1) You take the introductory Tour now! 2) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! 3) As you receive help, try to give it too, by answering questions in your area of expertise. $\endgroup$ – bbgodfrey May 6 '15 at 14:19
  • $\begingroup$ do you know what kind of functions a(t) and b(t) are? $\endgroup$ – jens_bo May 6 '15 at 15:00
  • $\begingroup$ @bbgodfrey Dont worry, Iam using stackoverflow and Iam not a begginer on stackxxx forums ;) $\endgroup$ – Jan Strnádek May 6 '15 at 18:18
  • $\begingroup$ @jens_bo a(t) and b(t) is meassurment data in the "T" time, I have a lot of data a(t) and b(t) but only few f(t), Imagine like continuos meassurment of load server nad free capacity of memory (per 1 second), but just few times of load your web application (per 1 minute) and you´re looking for relation between them... It´s not good example and Iam looking for sth quite different, but the idea is almost the same. $\endgroup$ – Jan Strnádek May 6 '15 at 18:32
0
$\begingroup$

Note: You should check if the code I am using matches your problem, since I had to guess some unclear parts (parenthesis and x,y,z naming).

Since I don't know anything about $a(t)$ and $b(t)$ I threat $f(t)$ as a function of two unknowns $a$ and $b$, or $f(a,b)$.

If we want to fit the data we can use NonlinearFit, but NonlinearFit takes data of the form {{x11,x12,...,y1},{x21,x22,...,y2},...}} if you have multiple variables. So in your case that would be {{a(t1),b(t1),f(t1)},{a(t2),b(t2),f(t2)},...}, so:

data = {{5, 3, 2}, {9, -4, 4}, {12, 5, 10}};

nls = NonlinearModelFit[data, x1*a + x2*b, {{x1, 0.3}, {x2, -0.24}}, {a, b}]

Now, in order to check the fit we can use a 3D plot (since your function only depends on two variables).

Show[
     ListPointPlot3D[data, PlotStyle -> Directive[Red, PointSize -> .025]], 
     Plot3D[nls[a, b], {a, -15, 15}, {b, -15, 15},PlotStyle ->Opacity[.75]]
    ]

gives you:

enter image description here

If you have more than two dependencies or you just want to see the deviations of the model from the data in a more presentable (2D) way, you can use the residuals of the fit and maybe plot them vs. the times $t$.

times = {1, 2, 3};
ListPlot[Transpose@{times, nls["FitResiduals"]}, Joined -> True, PlotMarkers -> Automatic]

enter image description here

$\endgroup$
  • $\begingroup$ Thank you too, but your solution not working, Iam getting an error General::ivar: "{{-26.92` Inverse", I google it but still not sure if its problem of "notation" or data? :( $\endgroup$ – Jan Strnádek May 6 '15 at 18:38
  • $\begingroup$ Where did you get this error? Does it work with the data you posted here? $\endgroup$ – jens_bo May 6 '15 at 19:09
  • $\begingroup$ I try your example, Ive just run: data = {{5, 3, 2}, {9, -4, 4}, {12, 5, 10}}; nls = NonlinearModelFit[data, x1*a + x2*b, {{x1, 0.3}, {x2, -0.24}}, {a, b}] and this error occurs, the same thing happens with my original data or with just data = {{5, 3, 2}}... $\endgroup$ – Jan Strnádek May 6 '15 at 19:11
  • $\begingroup$ Also you can plot f(t) and the f(t) according to the fit using the residuals, if that's what you need instead of just the quality of the fit. $\endgroup$ – jens_bo May 6 '15 at 19:11
  • $\begingroup$ The error does not occur for me. Maybe start with a fresh kernel (new mathematica session)? Maybe you are using some of the variables somewhere else... $\endgroup$ – jens_bo May 6 '15 at 19:12
2
$\begingroup$

In the format you propose, the dependence of $f$ on $t$ is left implicit in your model. $a(t)$ and $b(t)$ seem to be some quadratic function of $t$, but as @jens_bo mentioned, you need to tell us or find out more about $a(t)$ and $b(t)$ to obtain a fit of $f$ as a function of $t$.

Data format: Data needs to be presented to all fitting functions as a list of data points, each data point being itself a list of numbers, with the values of the independent variables coming first, and the dependent variable last. For example, see this format specified in the documentation page for NonLinearModelFit. In other words, data to be fit needs to conform to the pattern {{x1 , y1, f1}, {x2 , y2, f2}, ...}. Your data has the value of $f$ first instead.

In this case, it would be easy to fix this by hand, but a programmatic solution could be the following:

data = {{2, 5, 3}, {4, 9, -4}, {10, 12, 5}}
rearrangeddata = Transpose@RotateLeft[Transpose@data, 1]

(* Out: {{5, 3, 2}, {9, -4, 4}, {12, 5, 10}}, i.e.

a    b    f
-----------
5    3    2
9   -4    4
12   5   10

*)

Fitting: In all cases, the functions depend linearly on the parameters (see also my answer to question 80998 on the distinction between non-linear and linear fitting), so you don't need to carry out an iterative non-linear fit: a linear model will suffice.

You could then take two approaches to fitting this function. You could obtain a fit of $f$ as a function of variables $a$ and $b$, disregarding their dependence on $t$. $f(a,b)=x1\ a+x2\ b$ from your data.

linearmodelfit = Fit[rearrangeddata, {y, x}, {y, x}]

(* Out: 0.321159 x + 0.613899 y *)

Alternatively, you could obtain a fit of $f$ as a function of the single variable $t$. Even though $f\propto t^2$, the model itself is still linear, so again we don't need to use NonlinearModelFit; LinearModelFit will do just fine.

LinearModelFit[{{1, 2}, {2, 4}, {3, 10}}, {t, t^2}, x][t]

(* Out: 4 - 4 t + 2 t^2 *)
$\endgroup$
  • $\begingroup$ Thank you for your help, whole table is Meassurment data in the time "T", so Ive got 3 values for every time "t" and i need aproximate function f(t) = x1*a(t) + x2*b(t). Thats the second problem with plot, I need to draw that function... For the plot of the result of NonlinearModelFit, I probably can provide a function a(t) and b(t) (It can be some kind of approximation, because Ive got a lot of data for a(t) and b(t) but ive got a few values for f(t))... $\endgroup$ – Jan Strnádek May 6 '15 at 18:23
  • $\begingroup$ @Jan, consider following Marco's advice to use LinearModelFit[] instead; unless you have a genuinely nonlinear model, you don't need such am expensive function. $\endgroup$ – J. M. will be back soon May 6 '15 at 20:20

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.