1
$\begingroup$

I would like to define a function that has the following property $f(-x,y)=f(x,-y)$. An example is $f(x,y)=x y$. For simple inputs, I can impose this easily enough as:

f[-x, y] + f[x, -y] /. {f[-A_, B_] :> f[A, -B]}
(*2f[x, -y]*)

However when I want to examples with more complex arguments this does not work any longer, e.g.

f[-x + y, z] + f[x - y, -z] /. {f[-A_, B_] :> f[A, -B]}
(*f[x - y, -z] + f[-x + y, z]*)

How can I make the rule work in the second case?

In general, can I set the Attributes of the function so that this is done automatically? I would eventually want to work with some longer expressions of type

f[x1 + x2 - x3, y] + f[x1 + x2 + x3, y] + f[-x1 - x2 + x3, -y] +  f[-x1 - x2 - x3, -y]/.rule
(* 2 f[x1 + x2 + x3, y] + 2 f[x1 + x2 - x3, y] *)
$\endgroup$
4
  • $\begingroup$ Upvalues perhaps? f /: f[-x_, y_] := f[x, -y] $\endgroup$ Jun 26, 2021 at 17:33
  • $\begingroup$ hm... it don't seem to work for the second example f[-x + y, z] + f[x - y, -z]. $\endgroup$
    – z.v.
    Jun 26, 2021 at 17:49
  • $\begingroup$ Right, I was think of using up values to look at patterns with a minus, f/:f[Minus[x_] + y_ + Minus[z_], x + Minus[y_] +z]:=f[-x+y-z, etc, but didn’t try it yet. Just a suggestion of a direction to try $\endgroup$ Jun 26, 2021 at 17:57
  • $\begingroup$ Perhaps a peak at FullForm[f[x-y+z,-x-y+z] might help? $\endgroup$ Jun 26, 2021 at 17:59

1 Answer 1

4
$\begingroup$

We need a general function that compares $f(a,b)$ with $f(-a,-b)$ and decides which one to prefer, for any choice of $(a,b)$. It's a matter of taste which form is more desired; here I use Sort (always picking the form that is higher in sorting order), which is unambiguous but may not be what you are looking for.

rule = f[a_, b_] :> Last[Sort[{f[a, b], f[-a, -b]}]];

f[-x, y] + f[x, -y] /. rule
(*    2 f[x, -y]    *)

f[-x + y, z] + f[x - y, -z] /. rule
(*    2 f[-x + y, z]    *)

f[x1 + x2 - x3, y] + f[x1 + x2 + x3, y] + f[-x1 - x2 + x3, -y] + f[-x1 - x2 - x3, -y] /. rule
(*    2 f[-x1 - x2 + x3, -y] + 2 f[x1 + x2 + x3, y]    *)

You may also need to use automatic simplifications to bring all terms into a common form, so that they can be combined:

f[-2 (x + y), z] + f[2 x + 2 y, -z] /. rule
(*    f[-2 x - 2 y, z] + f[-2 (x + y), z]    *)

rule2 = f[a_, b_] :> Last[Sort[FullSimplify[{f[a, b], f[-a, -b]}]]];

f[-2 (x + y), z] + f[2 x + 2 y, -z] /. rule2
(*    2 f[-2 (x + y), z]    *)
$\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.