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.

As the question says, can one force a fit through the origin $(0,0)$ as one can when fitting a trendline to your data in MS Excel? If so, how do you do that?

share|improve this question
add comment

4 Answers 4

up vote 12 down vote accepted
data = Table[{i, 3 i + RandomReal[2]}, {i, 10}]
line = Fit[data, {x}, x]
Show[ListPlot[data, PlotStyle -> Red], Plot[line, {x, 0, 10}], PlotLabel -> line]

Mathematica graphics

share|improve this answer
8  
Also: LinearModelFit[..., IncludeConstantBasis -> False]. –  Oleksandr R. Sep 17 '12 at 19:00
    
@OleksandrR. also Minimize[Sum[(i[[2]] - a i[[1]])^2, {i, data}], a] and zillions more :) –  belisarius Sep 17 '12 at 19:08
1  
Yes, that surely fits the description of "force"! :) –  Oleksandr R. Sep 17 '12 at 20:28
    
Thank you, belisarius, for your answer. –  WalidSaladin Sep 20 '12 at 10:17
add comment

Another possibility, a bit more general :

data = Table[{i, 3 i + RandomReal[2]}, {i, 10}];

model[x_] = a Cos[x] + b x^2 + c;

sol = FindFit[data, {model[x]}, {a, b, c}, x];

One can add constraints on the parameters to the model :

sol2 = FindFit[data, {model[x], model[0] == 0}, {a, b, c}, x];

Show[ListPlot[data],  Plot[{model[x] /. sol, model[x] /. sol2}, {x, 0, 10}]]

plot

share|improve this answer
7  
Important consideration with this approach: the interior point method (which is used for all constrained fits unless Method -> NMinimize is specified) requires that the residual and any additional constraints be twice differentiable, preferably analytically. If not, it will usually have trouble converging. –  Oleksandr R. Sep 17 '12 at 20:32
    
@OleksandrR. Good point, thanks, I was not aware of this - is it in the documentation ? –  b.gatessucks Sep 18 '12 at 11:15
    
Sort of--you can find it discussed in relation to FindMinimum here. –  Oleksandr R. Sep 18 '12 at 11:26
    
@OleksandrR. Thanks. –  b.gatessucks Sep 18 '12 at 11:50
    
Thank you all for answering. I really appreciate it. –  WalidSaladin Sep 20 '12 at 10:16
add comment

I have given a derivation of the needed formulae in this math.SE answer. As already mentioned by belisarius, the canonical method for finding the equation of the least-squares line constrained to pass through the origin in Mathematica would be either of

Fit[data, {x}, x]

which produces the explicit linear function, or

FindFit[data, m x, m, x]

which produces just the slope of the best-fit line as a replacement rule.

To handle the case of a least-squares line constrained to pass through an arbitrary point $(h,k)$, you can again use either of Fit[] or FindFit[], but things are slightly trickier. (I'll leave the task of encapsulating that method in a Mathematica routine as an exercise.) For this answer, I'll present the explicit formula, as implemented in Mathematica:

fixedLine[data_?MatrixQ, pt : (_?VectorQ) : {0, 0}] := Module[{a, b, dat, sx, sy},
  dat = If[Precision[data] === Infinity, N[data], data];
  {sx, sy} = Transpose[dat] - pt;
  b = sx.sy/sx.sx;
  a = #2 - b #1 & @@ pt;
  Function[\[FormalX], Evaluate[Chop[a + b \[FormalX]]]]]

This returns the best-fit line as a pure function. Here are a few examples, taken from Kolb's Curve Fitting for Programmable Calculators:

fixedLine[{{100, 140}, {200, 230}, {300, 310}, {400, 400}, {500, 480}}, {300, 310}]
   Function[\[FormalX]$, 55. + 0.85 \[FormalX]$]

fixedLine[{{11, 15}, {17, 23}, {23, 31}, {29, 39}}]
   Function[\[FormalX]$, 1.34831 \[FormalX]$]
share|improve this answer
    
Thank you J.M. for answering my question. –  WalidSaladin Sep 20 '12 at 10:16
add comment

belisarius gives the solution but forgot to tell why it is the solution.

The general equation for your linear regression line is

$y = a x + b$

which you write in the Fit function as

line = Fit[data, {x, 1}, x]

The second parameter is a list of functions. Fit will find the best fit by making a weighted sum of these functions, i.e.

$ a_1 \cdot x + a_2 \cdot 1 $

If you want a line through the origin the constant term should be zero, and the Fit becomes

line = Fit[data, {x}, x]

Example:

data = Table[{i, 10 + 3 i + RandomReal[2]}, {i, 10}];
line1 = Fit[data, {1, x}, x]
line2 = Fit[data, {x}, x]
Show[ListPlot[data, PlotStyle -> PointSize[0.02]], 
     Plot[{line1, line2}, {x, 0, 10}, PlotStyle -> Thick]]

gives us

11.673984 + 2.9005496 x  
4.5682616 x  

points and best-fit lines

share|improve this answer
    
Thank you very much stevenh for the clarification. –  WalidSaladin Sep 20 '12 at 10:15
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.