# How can I assign a Fit result to a function?

I have this code

ntcrr[t_] := E^(a + b/t + c/t^2 + d/t^3)
kelvin[t_] := t + 273.15
a = -13.40956889; b = 4481.798865; c = -150521.6916; d = 1877102.652;
p1 = {30, ntcrr[kelvin[30]]}; p2 = {35, ntcrr[kelvin[35]]};
line := Fit[{p1, p2}, {1, x}, x]


{ 1.67709 - 0.0285019 x }

Then I plug in this function in my Plot

Plot[ntcrr[kelvin[t]]/(1.67709 - 0.0285019 t), {t, 30, 35}]


and that works, but I'd rather like to assign the Fit result to a function, like this:

line[x_] := Fit[{p1, p2}, {1, x}, x]
Plot[ntcrr[kelvin[t]]/line[t], {t, 30, 35}]


but that doesn't work. How can I assign a Fit result to a function?

-

Use Set[] (=) instead of SetDelayed[] (:=) on the output of Fit[], like so:

line[x_] = Fit[{p1, p2}, {1, x}, x];

Plot[ntcrr[kelvin[t]]/line[t], {t, 30, 35}]


You may wish to localize the variable in this construct, so that the creation of the definition is safe from a global assignment. Here are two ways of achieving this:

• Block

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

• Formal Symbols (looks better in a notebook):

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

-
That was almost too easy, I don't think I should upvote you for this ;-). Thanks a bunch! (I did upvote, of course) –  stevenvh Jul 13 '12 at 7:48
No problem; though I should also probably tell you about FindFit[], which returns the parameters only instead of the function itself. It might be more convenient for you to use... –  Ｊ. Ｍ. Jul 13 '12 at 7:50
Do you think so? I'm not really interested in the separate coefficients, just the function. With FindFit I would have to reconstruct the function myself, right? –  stevenvh Jul 13 '12 at 7:53
Well, I said "might be"; you could, for instance, do {m, k} = {m0, k0} /. FindFit[{p1, p2}, m0 x + k0, {m0, k0}, x] and then Plot[ntcrr[kelvin[t]]/(m t + k), {t, 30, 35}]. –  Ｊ. Ｍ. Jul 13 '12 at 8:01
Thanks for the addendum, Wizard. :) –  Ｊ. Ｍ. Jul 14 '12 at 4:31
If, for any conceivable reason, you want to preserve the SetDelayed (:=), you might want to try
line2 := Function[{y}, Evaluate[Fit[{p1, p2}, {1, y}, y]]]

Now, try executing line2[0]. –  Ｊ. Ｍ. Jul 13 '12 at 14:20
@J.M. Touché. Adding Evaluate should have fixed the issue, though one may wonder if there is any point in keeping the SetDelayed at this point. Not a very good answer, I reckon. –  Andrea Colonna Jul 13 '12 at 14:24
@AndreaColonna: if you wonder about SetDelayed, why don't you just exchange it to Set (=). That works alright and is the thing to do here. With that change, I think it is a perfect way to define such a function, to some extent I like that even better than the function definition per downvalues. You should also note that the Evaluated -> True option isn't actually necessary then. –  Albert Retey Apr 26 at 12:26
@AndreaColonna: one more point: you can/should use the same techniques to localize or protect the symbols used as function arguments as in J.M.s answer, e.g.: line2=Block[{y},Function[{y}, Evaluate[Fit[{p1, p2}, {1, y}, y]]]] –  Albert Retey Apr 26 at 12:28