In the original question, the functions f
and g
are defined as pattern replacement rules of the type g[x_, y_]
. There is an alternative way of defining functions which can be very handy - whether it's better in your case depends on the details, but it should be mentioned for completeness:
Using Function
By defining functions such as g[x_, y_]
, you essentially add a (delayed) replacement rule to the DownValues
of the symbol g
. Using Set
instead of SetDelayed
in such a definition means that the replacements are made using the expression as it evaluates at the time of the definition. This is what you want to happen with your "expensive" function f
.
However, what if your definition of the function g
also depends on another function in addition to f
- say h
. And what if the definition of h
is allowed to change between invocations of f
? Here is an example where I use the Set
(=
) approach to defining g[x_, y_]
, to illustrate what happens when g
is changed:
Clear[f, g, h, x, y]
f[x_, y_] := x + y
h[x_] := 1
g[x_, y_] = (f[x, y] + h[x])^3
(* ==> (1 + x + y)^3 *)
g[x, y]
(* ==> (1 + x + y)^3 *)
h[x_] := 2
g[x, y]
(* ==> (1 + x + y)^3 *)
Since the definition of g
has used the definition of h
at the time where Set
was called, I can't affect the outcome of g[x, y]
by subsequently changing the definition of h
, as done above.
But let's say we actually want a change in h
to affect f
, too. One way to mix the two effects (have f
evaluated at definition time but let h
be evaluated only at the time f
is called), is as follows:
Clear[g]
g = Function[{x, y}, (# + h[x])^3] &@f[x, y]
(* ==> Function[{x, y}, ((x + y) + h[x])^3] *)
g[x, y]
(* ==> (2 + x + y)^3 *)
h[x_] := 3
g[x, y]
(*
==> (3 + x + y)^3
Now you see first of all that f
does still contain the evaluated result of f[x, y]
as desired (because that was the expensive function), but at the same time it does not use the definition of the other function h
until f
is actually called.
In contrast to pattern definitions, the Function
expression is assigned to g
as an OwnValue
, which I sometimes find more convenient to work with (e.g., when forming functions of functions, compositions, inverses etc). The way the above works is by exploiting the HoldAll
attribute of Function
which prevents h
from being evaluated. On the other hand, the f[x,y]
appears outside the body of Function
and is therefore evaluated. It is injected into the Function
only afterwards, because it appears as the argument of another anonymous function that wraps the Function
.
Instead of this anonymous function construction, one can achieve the same thing by using a replacement rule for a dummy variable (fTemp
) - it plays the same role as the anonymous function slot #
above:
Clear[g, fTemp]
*)
g = Function[{x, y}, (fTemp + h[x])^3] /. fTemp -> f[x, y]
(* ==> Function[{x, y}, ((x + y) + h[x])^3] *)
Added note
I am assuming that the use of Block
to protect the variables like x
and y
is not necessary in my definitions because the original question explicitly states that symbolic manipulations were performed (to get the result f[x,y] = x + y
), so of course the relevant symbols must not have values assigned to them. I added Clear
at the beginning just to make sure that this assumption really holds.
f
is, we can not help you. For example, maybef
can be defined withSet
instead ofSetDelayed
. You can alwaysh[x_,y_]=f[x,y]
and then work onh
withg
. $\endgroup$ – Kuba♦ Aug 10 '13 at 8:32h
ing
, then when I evaluateg
, wouldf
will be evaluated? $\endgroup$ – user565739 Aug 10 '13 at 8:35g[x_, y_] := ...f[x,y]
, notg[x_, y_] =: ...
. But thank you for your reply, because I don't know the difference between:=
and=
. Would you mind explain a bit or a source? $\endgroup$ – user565739 Aug 10 '13 at 8:50=
and:=
there is reference.wolfram.com/mathematica/tutorial/… $\endgroup$ – andre314 Aug 10 '13 at 9:11