12
$\begingroup$

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 Microsoft Excel? If so, how do you do that?

$\endgroup$
17
$\begingroup$
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

| improve this answer | |
$\endgroup$
  • 12
    $\begingroup$ Also: LinearModelFit[..., IncludeConstantBasis -> False]. $\endgroup$ – Oleksandr R. Sep 17 '12 at 19:00
  • $\begingroup$ @OleksandrR. also Minimize[Sum[(i[[2]] - a i[[1]])^2, {i, data}], a] and zillions more :) $\endgroup$ – Dr. belisarius Sep 17 '12 at 19:08
  • 1
    $\begingroup$ Yes, that surely fits the description of "force"! :) $\endgroup$ – Oleksandr R. Sep 17 '12 at 20:28
15
$\begingroup$

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

| improve this answer | |
$\endgroup$
  • 8
    $\begingroup$ 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. $\endgroup$ – Oleksandr R. Sep 17 '12 at 20:32
  • $\begingroup$ @OleksandrR. Good point, thanks, I was not aware of this - is it in the documentation ? $\endgroup$ – b.gates.you.know.what Sep 18 '12 at 11:15
  • $\begingroup$ Sort of--you can find it discussed in relation to FindMinimum here. $\endgroup$ – Oleksandr R. Sep 18 '12 at 11:26
  • $\begingroup$ @OleksandrR. Thanks. $\endgroup$ – b.gates.you.know.what Sep 18 '12 at 11:50
  • $\begingroup$ Thank you all for answering. I really appreciate it. $\endgroup$ – WalidSaladin Sep 20 '12 at 10:16
7
$\begingroup$

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]$]
| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you J.M. for answering my question. $\endgroup$ – WalidSaladin Sep 20 '12 at 10:16
6
$\begingroup$

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

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you very much stevenh for the clarification. $\endgroup$ – WalidSaladin Sep 20 '12 at 10:15

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.