Suppose I have an example expression defined like this:

line = R0*f[R0,x] + R0^2*42*D[g[R0,x],x]

I would like to replace R0 with r, but only in the arguments of functions.

In this example I would like to use a replacement rule line /. { ??? } in order to obtain

R0*f[r,x] + R0^2*42*D[g[r,x],x]

What replacement rule ??? do I need to use here?

In my case, line is hundreds of terms long and it would be very cumbersome to not automate this. (If it helps, all functions always take the same list of arguments.)

  • $\begingroup$ By "functions" do you mean "user-defined functions"? $\endgroup$
    – lericr
    Oct 10, 2022 at 16:11
  • $\begingroup$ If you have a list of the relevant functions, it might be easier to work from that direction. For example, you might add DownValues directly to (for example) f & g that handle R0. Or you might build a helper function, say CleanR0 that replaces f[R0,...] with f[r,...] (and similarly with all relevant functions). $\endgroup$
    – lericr
    Oct 10, 2022 at 16:14
  • $\begingroup$ @lericr Yes, the functions are user defined, but it is a long list and I would prefer not having to think about it. $\endgroup$ Oct 10, 2022 at 17:05

2 Answers 2

line = R0*f[R0, x] + R0^2*42*D[g[R0, x], x]
line /. {p_Symbol[R0, a_] /; Context[p] == "Global`" -> p[r, a], 
  Derivative[k__][p_Symbol][R0, b_] /; Context[p] == "Global`" -> 
   Derivative[k][p][r, b]}

$$\text{R0} f(r,x)+42 \text{R0}^2 g^{(0,1)}(r,x)$$

  • $\begingroup$ This gives warning/message. Screen shot !Mathematica graphics V 13.1. What is the purpose for checking that context is global in your method? $\endgroup$
    – Nasser
    Oct 10, 2022 at 15:56
  • 1
    $\begingroup$ Add parentheses, i.e., line /. {(p_[R0, a_] /; Context[p]) == "Global" :> p[r, a], Derivative[k__][p_][R0, b_] /; Context[p] == "Global" -> Derivative[k][p][r, b]} $\endgroup$
    – Bob Hanlon
    Oct 10, 2022 at 16:00
  • $\begingroup$ @Nasser, I used context "Global`" since Context[Times] and for other built-in functions is "System`" and this way I can avoid conversions in other parts. May be there is a more elegant way to do this. The messages box was in the background so I didn't see it, although it computed. Thanks to Bob Hanlon for the correction. $\endgroup$
    – Syed
    Oct 10, 2022 at 16:16
  • 1
    $\begingroup$ @Syed Thank you, that is perfect! The trick with Context is great, I hadn't thought of that. $\endgroup$ Oct 10, 2022 at 17:16

Something like this maybe?

line = R0*f[R0, x] + R0^2*42*D[g[R0, x], x];
MyFunctions = {f, g, Derivative[0, 1][g]};
Clean[fn_][R0, args___] := fn[r, args];
line /. {fn : Alternatives @@ MyFunctions :> Clean[fn]}

This assumes that R0 will have no OwnValues. Also, you might be able to automate the generation of MyFunctions if there will be several different patterns of derivatives (or other functions).

The following uses Syed's idea for checking the context, and it generalizes a bit (you could build out that generalization further).

line = R0*f[R0, x] + R0^2*42*D[g[R0, x], x];
R0 /: Derivative[params___][fun_Symbol][R0, args___] := 
Derivative[params][fun][r, args] /; Context[f] == "Global`";
R0 /: f_Symbol[R0, args___] := f[r, args] /; Context[f] == "Global`";

This assumes that you don't need the original form with the explicit R0s, because the up values for R0 will be applied automatically.

  • $\begingroup$ Thanks, it is a very nice solution, I just find the other one a bit more practical because I do not need to define MyFunctions. The generalization looks great though! (Although it has the drawback of influencing my entire notebook globally.) $\endgroup$ Oct 10, 2022 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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