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.

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?

share|improve this question

2 Answers 2

up vote 10 down vote accepted

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}]

Addendum by Mr. Wizard

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]]
    
share|improve this answer
    
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... –  J. M. 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}]. –  J. M. Jul 13 '12 at 8:01
    
Thanks for the addendum, Wizard. :) –  J. M. 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]]]
Plot[ntcrr[kelvin[t]]/line2[t], {t, 30, 35}, Evaluated -> True]
share|improve this answer
1  
Now, try executing line2[0]. –  J. M. 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
    
@stevenvh On my computer (Mathematica v 8.0.1 on Win7) the code I suggested works just fine, even though J.M.'s solution is superior beyond a shadow of a doubt. –  Andrea Colonna Jul 13 '12 at 15:52
    
@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 '13 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 '13 at 12:28

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.