# Specifying properties of a function as assumptions

I am trying to simplify expressions involving a function $$f: \mathbb C \to \mathbb C$$ which satisfies $$f(-z) = -f(z), \quad f(z^*) = f(z)^*, \quad \forall z \in \mathbb C.$$ I do not want to specify any explicit form for $$f$$, but I want to tell the Simplify function that it can use the above properties. However, I can't quite get it to work.

As a minimal example of my problem consider the following input:

expr = a f[x - y\[Conjugate]] + b f[y - x\[Conjugate]]\[Conjugate];
asmp = {ForAll[z, f[-z] == -f[z]],
ForAll[z, f[z\[Conjugate]] == f[z]\[Conjugate]]};
Simplify[expr, asmp]


I would have hoped to get something like the output

(a - b) f[x - Conjugate[y]]


b Conjugate[f[y - Conjugate[x]]] + a f[x - Conjugate[y]]


What am I doing wrong, and what is the correct way to specify properties like these?

P.S. I am using Mathematica 12.1.

For further context, the actual expression I am trying to simplify is a monster of the following calibre ($$\alpha$$ is the actual name of the function previously referred to as $$f$$):

• What about Simplify[-f[-x] f[x], Assumptions -> f[-x] == -f[x]] it gives f[x]^2. Commented May 20 at 19:36
• Use TagSetDelayed, e.g., f /: f[-z_] := -f[z]; along wth f[z_?Negative] := -f[-z] Commented May 20 at 19:45
• @yarchik That only works on the minimal example above, but not on the actual problem, since it relies on the argument litterally being x. I want it to work for arbitrary arguments, since it is a property of the function.
– ummg
Commented May 20 at 20:00
• Please edit your post to include one or a few examples that are big enough, but not HUGE, to demonstrate exactly the problems that you are having with all the suggested fixes.
– Bill
Commented May 20 at 20:43

I usually implement such identities via TransformationFunctions. In this case, neither Simplify nor FullSimplify would apply all the combinations of the identities, so I supplied various combinations of them. The Block[..] ones apply an identity to the first instance of f[] only. At one point, I thought I might need them all. Then I hit on the right combinations. We need either the first or the third one, but not all three. So who knows in the actual problem which may be needed. Hence I will leave them all in.

expr = a  f[x - y\[Conjugate]] + b  f[y - x\[Conjugate]]\[Conjugate];
Simplify[expr
, TransformationFunctions -> {
Automatic
(*,Replace[#,f[z_]:>-f[-z]]&,Replace[#,f[z_]:>f[z\[Conjugate]]\[Conjugate]]&*)
, Simplify[# /. f[z_] :> f[z\[Conjugate]]\[Conjugate]] &
, Simplify[# /. f[z_] :> -f[-z]] &
, Simplify[# /. f[z_] :> -f[-z\[Conjugate]]\[Conjugate]] &
, Simplify@
Block[{n = 0}, # /. f[z_] :> If[++n <= 1, -f[-z], f[z]]] &
, Simplify@
Block[{n = 0}, # /.
f[z_] :> If[++n <= 1, f[z\[Conjugate]]\[Conjugate], f[z]]] &
, Simplify@
Block[{n = 0}, # /.
f[z_] :> If[++n <= 1, -f[-z\[Conjugate]]\[Conjugate], f[z]]] &
}]

(*  (a - b) f[x - Conjugate[y]]  *)


Update: Alternatives

Another way is to use a ComplexityFunction that scores a chosen form of f[x - Conjugate[y]] (or forms if there are arguments that cannot be reduced to a single form):

Simplify[expr
, TransformationFunctions -> {Automatic
, ReplaceAll[f[z_] :> f[z\[Conjugate]]\[Conjugate]],
ReplaceAll[f[z_] :> -f[-z]]}
, ComplexityFunction -> (LeafCount[#] -
5 Count[#, f[x - y\[Conjugate]], Infinity] &)]


Or possible differentiating some aspect of a desired argument or arguments, although it can be tricky to solve problem Y by solving an indirectly related problem X. These complexity functions work on the example input:

ComplexityFunction -> (LeafCount[#] -
5 Count[#, -Conjugate[y], Infinity] &)
ComplexityFunction -> (LeafCount[#] +
5 Count[#, _Conjugate, Infinity] -
5 Count[#, -Conjugate[_], Infinity] &)

• Thank you for your answer. I am surprised that things like these seem to require so much trial and error, but maybe I am overestimating the power of the algorithms used by Simplify. In the end I had more luck defining replacement rules and using ReplaceRepeated.
– ummg
Commented May 22 at 13:05