4
$\begingroup$

Suppose that I have a function f[x_,y_,z_]=x*y*z

and now suppose I want to consider a specific application where z is a function of x and y,

For example, suppose I want to consider z=x^2*y^2

Obviously, in this simple example I could just plug in z and define a new function g[x,y]=x^3*y^3.

But in a more complicated example this is not feasible (for example, what if we instead had f[x_,y_,z_]:= x*y^2*z^3 + x^2*y*z^2 + x^(.2)y^(.8) z^(.1)). I figure a more general approach is to define z[x,y] separately and then evaluate f[x,y,z[x,y]]. I am wondering about using a module to do this

Specifically, consider the following way to define z[x,y] and calculate f[x,y,z[x,y]]: (note: this MWE has typo, see bottom of Question for a fixed version)

g[x_,y_]:=Module[{zfunc},
zfunc[x_,y_]:=x^2*y*2;
f[x,y,zfunc[x,y]]
]

My question is, in the above code, is there a reason to use := when define zfunc[x_,y_] as opposed to using =?

I ask because, if I wasn't using a module, say if i instead had

   zfunc[x_,y_]:=x^2*y*2;
    g[x_,y_]:=f[x,y,zfunc[x,y]]

then I would want to use :=, because if I redefine zfunc then I want g to be evaluated with this new zfunc. However, in the module zfunc is local, so I think every time I call g the module redefines zfunc, even if i use = instead of :=?


Aside: I realize that a different solution could be to use a named pattern for the z argument, i.e.

f[x_,y_, func_Symbol]:=x*y*func[x,y]

I am not asking about this solution though, I am asking whether, when using module to define z[x_,y] as above, using := is different than using =


Edit: MWE had a typo (and I am leaving it unchanged above because some comments might be useful to others, and may not make sense if I remove the typo)

The MWE should be

f[x_,y_,z_]=x*y*z;
g[x_,y_]:=Module[{zfunc},
zfunc=x^2*y*2;
f[x,y,zfunc]
]

I will also try to rephrase my question, since I have not received an answer:

Question: is there a reason to use zfunc:=x^2*y*2 instead of zfunc=x^2*y*2 in the above MWE?

The usual reasons I think of to use = instead of := are

  • Computation time
  • Possibility that, in something like f[x]=x^2, x may have been defined earlier already (but this can be avoided by using clear or a module or something)

    When using a module like in the MWE, the variable zfunc is local.

  • It is my understanding that this means, that every time the module is called Mathematica will define a new variable -- i.e. zfunc$1, zfunc$2 etc -- I imagine that this would erase the computation time benefit of using = versus :=.
$\endgroup$
  • $\begingroup$ Comments are not for extended discussion; this conversation has been moved to chat. $\endgroup$ – halirutan Feb 27 at 2:41
  • 1
    $\begingroup$ The MWE still seems broken to me. $\endgroup$ – Jason B. Apr 27 at 14:25
  • $\begingroup$ @JasonB. Yeah, I mentioned this in the comment (now it's moved to the chat), but OP doesn't reply. $\endgroup$ – xzczd Apr 27 at 14:26
  • $\begingroup$ @JasonB. I think that in the third line of the MWE I meant to type f[x,y,zfunc]. I can't see if that fixes it right now, but when I get a chance I'll do so and respond here. @xzczd, I was not aware of chat, and now is frozen. Sorry. $\endgroup$ – user106860 Apr 27 at 14:33
  • $\begingroup$ @JasonB. @xzczd the MWE should be fixed now (and should be the equivalent to the function h[x_,y_]:= x^3 *2*y^2 $\endgroup$ – user106860 Apr 28 at 8:30
2
$\begingroup$

Consider using a pure function to represent zfunc. Like so:

f[x_, y_, z_] := x y^2 z^3 + x^2 y z^2 + x^.2 y^.8 z^.1
g[x_, y_] := f[x, y, #1^2 #2^2 &[x, y]]

The definition of g is nicely concise and

g[u, v]

evaluates to

u^6 v^5 + u^7 v^8 + u^0.2 v^0.8 (u^2 v^2)^0.1

much more efficiently than any of the module constructs you show in the question.

| improve this answer | |
$\endgroup$
  • $\begingroup$ This doesn't directly answer my question, but it is elegant and does the job much better than my example. Thank you. The only potential concern I have with this solution is that, for me at least, the equation for the pure function is harder to identify than if the pure function was on a separate line (I don't know if this is possible though). (This might matter if say, we had f[x_,y_,z_,u_,v_] and wanted to substitute pure functions for z,u, and v. Granted such a situation probably occurs rarely if ever) $\endgroup$ – user106860 Apr 28 at 8:37
  • 1
    $\begingroup$ @user106860 If you don't like pure functions like #1^2 * #2^2&, you can instead do zfunc = Function[{x, y}, x^2 * y^2] in your Module, which is more readable. It is also faster than using a pattern-based function definition (like zfunc[x_, y_] := ...). You can speed it up more by using With instead of Module. $\endgroup$ – Sjoerd Smit Apr 28 at 9:27
  • $\begingroup$ @SjoerdSmit Thank you! $\endgroup$ – user106860 Apr 28 at 17:02
0
$\begingroup$

I will post a (weak) answer myself:

There is at least one reason to use := instead of = (at least some times).

This reason would be if the definition of zfunc included a condition.

For example, if instead of zfunc=x^2*y*2 we had

zfunc:=x^2/; x>y;
zfunc:= y*2/; x<=y;

Then this above code does not work properly if we instead use set (=).

Note, however, that if we instead use If or Piecewise then we might be able to have zfunc include a condition and still use Set (=) -- I have not looked into this.

There are likely better reasons why one use := over = in this context; I am simply trying to put forward one example.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.