Re: Re: Derivatives D[ ] as Functions: Summary (LONGISH)

*To*: mathgroup at smc.vnet.net*Subject*: [mg13353] Re: [mg13253] Re: Derivatives D[ ] as Functions: Summary (LONGISH)*From*: Carl Woll <carlw at fermi.phys.washington.edu>*Date*: Mon, 20 Jul 1998 02:50:08 -0400*Sender*: owner-wri-mathgroup at wolfram.com

On Fri, 17 Jul 1998, AES wrote: > I recently posed the question of defining a function f2 as the > derivative of another function f1, e.g. > > Remove["Global`*"]; > > f1[a_,x_] :=a Cos[x] + a^2 Sin[x]; > f2[a_,x_] := D[f1[a,x],x]; > > and then finding that f2 would not behave "as expected" in a subsequent > Plot[ ] or Table[ ]. > > Thanks to several people for their responses, and apologies for my > several typos in earlier postings. It's clear what my difficulty was. > > > However, let's look at the general issue a little further. If for > example we do the above and then look at the FullForm version of the > two functions, they look very similar: > > f1[a,x]//FullForm > > Plus[Times[a,Cos[x]],Times[Power[a,2],Sin[x]]] > > f2[a,x] // FullForm > > Plus[Times[Power[a,2],Cos[x]],Times[-1,a,Sin[x]]] > > Note that these FullForm results, if not misleading, certainly give no > clue that f2 has a different character than f1 and will behave totally > differently if you try to use it in Plot[ ] or Table[ ] . Since FullForm evaluates its argument first and then displays the FullForm output, it's not surprising that the two look similar. The thing that you should look at is the definitions of the two functions, most commonly done by using the function ?? (or equivalently, Information). That is, if you try ??f1 and ??f2 you will see that the definitions of the two functions are very different, although they will produce similar output when called. > A general and frequent and serious problem with Mathematica, in fact, > is that it often does things that may be totally logical and even > necessary by its rules, but that can be mysterious, non-intuitive, and > frustrating to ordinary users; and the nature of the beast often makes > these problems obscure and hard to find. > > ... > > [Another general observation is that when problems -- or anyway > "apparent problems" -- with Mathematica's ways of doing things are > pointed out, I find it's much more common to get a detailed explanation > of why Mathematica does what it does, rather than any discussion of the > design choices, or design necessities, that make it necessary -- if it > is necessary -- for Mathematica to function in this way.] > It seems to me that if you are having a problem with Mathematica, you would be interested in why things are not behaving the way that you expect, that is, what is Mathematica really doing that is different from what you thought it would do. That way you can avoid the problem in the future. You are welcome to ask why Mathematica does what it does, and you will probably get some interesting responses. > In any event one way to avoid the derivative problem above is to use an > immediate definition, i.e., use " = " instead of " := "in defining f2: > > f1[a_,x_] :=a Cos[x] + a^2 Sin[x]; > f2[a_,x_] = D[f1[a,x],x]; > > That's fine -- except, suppose you do this deep in a notebook in which > "a" has already been given a value; you may not get what you want, or > think you're getting.. > > Several people also suggested using Evaluate[f2[a,x]], or more complex > tricks, every time you use f2 subsequently in a Plot[ ] or Table[ ], > and that of course works. > > However, so far as I can see the preferred way to accomplish this > would seem to be to do it globally, i.e., to write: > > f1[a_,x_] := a Cos[x] + a^2 Sin[x]; > f2[a_,x_] := Evaluate[ D[f1[a,x],x]]; > > That's reasonably easy to remember, somewhat intuitive (to me anyway), > seems to meet the need, and what I propose to do from now on. But, are > there still hidden pitfalls in this? Further comments welcome. > I think that there is no difference between the two statements f2[a_,x_] := Evaluate[ D[f1[a,x],x]]; f2[a_,x_] = D[f1[a,x],x]; Try out each definition, and check if they are different with ??f2, and you will see that they are essentially the same (the DownValues are the same, which is what really counts, but the information is slightly different). Still, you raised a good point about previous definitions of your argument. Look at the following example: a=1; f2[a_,x_] = D[f1[a,x],x]; f3[a_,x_]:= Evaluate[D[f1[a,x],x]; DownValues[f2] DownValues[f3] Information[f2] Information[f3] and you will see that both f2 and f3 have the same downvalues, and Information (or ??) gives f2[a_,x_] =Cos[x]-Sin[x] f3[a_,x_]:=Cos[x]-Sin[x] but that this is not the definition you wanted. It's probably not good programming practice to give values to commonly used argument names, and avoiding that practice is probably the best solution to the above conundrum. On the other hand, if you insist on using argument names which may already have values, and you want to use an immediate evaluation like that above, one approach is to use Block as follows: Block[{a,x}, f2[a_,x_]=D[f1[a,x],x] ] Try the above, and check ??f2 and you will see that the definition you wanted has been established even though a already has a value. The function Block temporarily "forgets" about the values of its arguments. The above may be a deficiency in the way Mathematica handles Set (that is the = statement), and perhaps you could ask Wolfram or the newsgroup why they implemented Set in the way that they did. Carl Woll Dept of Physics U of Washington