Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

If I do something like this

f[x_]:=x^2

Plot[f[x],{x,1,10}]

Mathematica plots the function $f(x)=x^2$, as expected. However, if I do something like this instead

data=Table[x^2,{x,1,10}]

f[x_]:=Fit[data,{1,x},x]

Plot[f[x],{x,1,10}]

Mathematica throws me some weird errors such as -4.9998 is not a valid variable. What is going on here?

share|improve this question
    
As an aside, how is one supposed to go about typesetting multi-line code on this website? Is there a better way to do it than exiting the code environment, adding spaces, and entering the code environment again? –  Jonathan Gleason Jul 20 '12 at 16:07
    
@JonathanGleason Are you using f[x_]:=... ? It seems you are missing the = sign. –  b.gatessucks Jul 20 '12 at 16:12
    
@b.gatessucks Yeah, sorry about that. That was a typo on here. In Mathematica, I was using f[x_]:=.... –  Jonathan Gleason Jul 20 '12 at 16:13
add comment

5 Answers

up vote 3 down vote accepted

The definition of your function f[x_] is the problem. Here is the corrected version:

data = Table[x^2, {x, 1, 10}]

(* ==> {1, 4, 9, 16, 25, 36, 49, 64, 81, 100} *)

f[x_] = Fit[data, {1, x}, x]

(* ==> -22. + 11. x *)

Plot[f[x], {x, 1, 10}]

fit

The mistake was to define the function with SetDelayed. In that case, the symbol x on the right-hand side of the definition will be given the value with which the function is called, whereas Fit expects x to be a symbol and not a numeric value.

share|improve this answer
add comment

As an alternative, you can use FindFit[] instead of Fit[] for defining your regression function:

data = Table[x^2, {x, 1, 10}];
f = Function[x, a + b x] /. FindFit[data, a + b x, {a, b}, x];

Plot[f[x], {x, 1, 10}] ~Show~ ListPlot[data]

regression function and points

This hinges on the fact that FindFit[] returns the parameters (as replacement rules) as opposed to the regression function itself, making substitution into the regression model easy.


Mr. Wizard reminds me that variable localization might be necessary, especially if this is being done in the midst of a long session, where the variables may have had previous un-Clear[]ed assignments. One way to go about it is to use so-called "formal symbols" which are guaranteed to never have taken previous values, since you can's assign to them.

Here's how to go about it in this case:

f = Function[\[FormalX], \[FormalA] + \[FormalB] \[FormalX]] /.
   FindFit[data, \[FormalA] + \[FormalB] \[FormalX], {\[FormalA], \[FormalB]}, \[FormalX]]

(It looks somewhat complicated here, since the SE interface does not have the proper font faces for the characters that denote formal symbols. It looks better when pasted into Mathematica.)

share|improve this answer
add comment

An example:

data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}}

f[x_] = Fit[data, {1, x}, x]

Plot[f[x], {x, 0, 10}]

Please note that I used = instead of :=. The right hand side needs to evaluate before being assigned to f.

share|improve this answer
    
IMHO you should localize x in Fit. –  Mr.Wizard Jul 20 '12 at 22:05
    
Yeah. Probably. –  Searke Jul 23 '12 at 13:48
add comment

Also

data = Table[x^2, {x, 1, 10}];
f1 = Fit[data, {1, x}, x];
f2 = Fit[data, {1, x^2}, x];
Show[Plot[{f1, f2}, {x, 1, 10}], ListPlot@data]

enter image description here

Edit

Note that the following gives you the same result

data = Table[x^2, {x, 1, 10}];
f1 = Fit[data, {1, #}, x] & /@ {x, x x}
Show[Plot[f1, {x, 1, 10}], ListPlot@data]
share|improve this answer
add comment

At present none of the answers given localize variables during the definition of f to protect against global assignments. For actual use I strongly suggest you do:

x = 0; (*example left-over assignment*)

data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}}

Block[{x},
  f[x_] = Fit[data, {1, x}, x]
]

Plot[f[x], {x, 0, 10}]

Or:

f[\[FormalX]_] = Fit[data, {1, \[FormalX]}, \[FormalX]]

Plot[f[x], {x, 0, 10}]

I also wrote a function localSet to answer a prior question which you could use:

x = 0; (*example left-over assignment*)

data = {{0, 1}, {1, 0}, {3, 2}, {5, 4}}

localSet[ f[x_], Fit[data, {1, x}, x] ]

DownValues[f]
{HoldPattern[f[x_]] :> 0.186441 + 0.694915 x}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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