开发者

How to redefine a function in Mathematica by appending to it?

When doing calculations in Mathematica I often need to redefine a function by appending to it. For example if I define

f[n_] := n^2 + n + 1

then after some time I'd like to add 2n^3 so from now on

f[n] = 2n^3 + n^2 + n + 1. 

Then I'd like to add Sin[n] and going further

f[n] = 2n^3 + n^2 + n + 1 + Sin[n]. 

And so o开发者_StackOverflow中文版n.

It's easy to do with variables, for example x += 2. Is there something similar for functions?…

Edited to add – yes, I was doing that to semi-manually find a function that fits data the best. I know there are functions to do that but I wanted to see if I can get there myself. I did that but the way was not elegant so that prompted this question.


You can define a list of your basis functions and then just pick up needed number of elements:

fList = {n^2, n, 1, 2 n^3, Sin[n]}; 

f[n_] = Total[Take[fList, 3]]
f[n_] = Total[Take[fList, 4]]
f[n_] = Total[Take[fList, 5]]
(*
=> 1 + n + n^2
=> 1 + n + n^2 + 2 n^3
=> 1 + n + n^2 + 2 n^3 + Sin[n]
*)


A late-to-the-party solution: the code below uses an auxiliary function, and to add a term for all subsequent uses, you just have to call a function once, with a second parameter being a pure function expressing the term you want to add:

ClearAll[f];
Module[{g},
 g[n_] := n^2 + n + 1;
 f[n_, add_: Automatic] /; add === Automatic := g[n];
 f[n_, add_: Automatic] := Block[{m}, g[m] = g[m] + add[m]; g[n]];
]

Examples of use:

In[43]:= f[m]
Out[43]= 1 + m + m^2

In[44]:= f[m, 2 #^3 &]
Out[44]= 1 + m + m^2 + 2 m^3

In[45]:= f[m]
Out[45]= 1 + m + m^2 + 2 m^3

In[46]:= f[m, Sin]
Out[46]= 1 + m + m^2 + 2 m^3 + Sin[m]

In[47]:= f[m]
Out[47]= 1 + m + m^2 + 2 m^3 + Sin[m]

With this approach, you should be careful though to call the two-argument form only once, when you want to add the term to the function - or it will be added every time you call.


There are many subtleties craving under your question. Monster subtleties, I mean.

I'll not enter the meander, but you may do something like:

f[n] = n^2;
f[n] = f[n] + 2
(* but for evaluation *)
f[n] /. n -> 2

So, for example for plotting this:

Plot[f[n] /. n -> x, {x, 0, 1}, AxesOrigin -> {0, 0}, 
                                PlotLabel  -> Framed@f[n]]

How to redefine a function in Mathematica by appending to it?

However, you should NOT do this. Read more about delayed definition!


It really depends why you need to redefine your function f. If the reason is that you realised the previous definition was wrong, then by all means just go back to the cell in question, edit it and re-evaluate it to re-define f.

f[n_] := n^2 + n + 1

Becomes

f[n_] := 2n^3 + n^2 + n + 1 

Note the := syntax and the underscore.

If, instead, you want f to take the first definition for, say n<=100 and the second for n>100, you would use the Condition syntax /;, as shown below.

f[n_] := n^2 + n + 1 /; n<=100
f[n_] := 2n^3 + n^2 + n + 1 /; n>100


This works, but requires separate functions. Generalising the append function is not so easy.

Clear[f]
AppendToFunction := (
   a = DownValues[f];
   b = Append[a[[1, 2]], 2 n^3];
   f[n_] = Evaluate[b]);

AppendSinToFunction := (
   a = DownValues[f];
   b = Append[a[[1, 2]], Sin[n]];
   f[n_] = Evaluate[b]);

f[n_] := n^2 + n + 1;
f[3] == 9 + 4
DownValues[f]

(* 
->True
->{HoldPattern[f[n_]]:>n^2+n+1}
*)

AppendToFunction
f[3] == 9 + 4 + 54
DownValues[f]

(*
->1+n+n^2+2 n^3
->True
->{HoldPattern[f[n_]]:>1+n+n^2+2 n^3}
*)

AppendSinToFunction
f[3] == 9 + 4 + 54 + Sin[3]
DownValues[f]

(*
->1+n+n^2+2 n^3+Sin[n]
->True
->{HoldPattern[f[n_]]:>1+n+n^2+2 n^3+Sin[n]}
*)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜