Redefine function after change of coordinates (variables)

I wish to define functions of (possibly) several variables and then apply variable transformations in order to obtain a more comfortable expression. But I run into trouble because I need to redefine the function by calling the previous definition. So I guess here is where I run into trouble.

Here ist a little toy example:

f[{x_,y_}] := 2*x^2+4*x*y+y^2;
R[{x_,y_}] := {x,y-2*x};


Now I would like to redefine f as the composition of f and R. The "obvious" method

f[{x_,y_}] := Composition[f,R][{x,y}];


does not work since this leads to an infinite iteration process. So I would like to find a way to first evaluate the composition and then redefine f[{x_,y_}] to be the resulting expression. Can anybody help me out here? Thanks a lot!

I think this is a good example of when you can use Set for defining a function, or rather when it's a good idea to not use SetDelayed. Since you want to assign the evaluated rhs of the composition to f (and the result has a closed form), instead of redoing the composition each time the new f is called (leading to the infinite recursion), you can directly assign the result of the composition.

f[{x_, y_}] := 2*x^2 + 4*x*y + y^2
R[{x_, y_}] := {x, y - 2*x}
f[{x_, y_}] = f@*R@{x, y} (*@* is the infix notation for Composition*)
f[{A,B}]


2 x^2 + 4 x (-2 x + y) + (-2 x + y)^2

2 A^2 + 4 A (-2 A + B) + (-2 A + B)^2

It even has the right DownValues.

DownValues@f


{HoldPattern[f[{x_, y_}]] :> 2 x^2 + 4 x (-2 x + y) + (-2 x + y)^2}

• Thanks a lot, this is pretty much what I was looking for! Commented Oct 27, 2019 at 17:25
f[{x_, y_}] := 2*x^2 + 4*x*y + y^2;
R[{x_, y_}] := {x, y - 2*x};

f[{x_, y_}] := Evaluate@Composition[f, R][{x, y}]

f[{A, B}]

(* 2 A^2 + 4 A (-2 A + B) + (-2 A + B)^2 *)

• Thank you very much. This also works pretty well. I assume that "Evaluate@" tells the compiler to first evaluate the rhs before everything else? Commented Oct 27, 2019 at 17:29
• Yes, so the rhs no longer refers to f, which avoids the infinite recursion. Commented Oct 27, 2019 at 20:44

Since your definition of R

f[{x_, y_}] := 2*x^2 + 4*x*y + y^2;
R[{x_, y_}] := {x, y - 2*x};


returns a list of two elements, it has the correct structure to serve as input to f. So you can simply do

f[R[{A, B}]]


2 A^2 + 4 A (-2 A + B) + (-2 A + B)^2

to obtain f evaluated on R, evaluated on arbitrary input {A,B}.

EDIT

If you want to redefine f, then simply save the new entry as

f[{A_,B_}] = f[R[{A, B}]];


Now, whenever you call f[{x,y}] the new definition is going to be invoked.

• Yes, but my intention is do redefine f as the composition of f and R. The reason being that I will probably have to perform a series of such coordinate changes so I don't want to use new functions everytime. Commented Oct 27, 2019 at 17:24
• @Teddyboer see the edit above. Commented Oct 28, 2019 at 3:24