# Simplifying x Conjugate[x]

I am trying to simplify a big expression containing many times terms of the form x Conjugate[x]. While this works for a single term:

FullSimplify[a  Conjugate[a]]
(* Out: Abs[a]^2 *)


it does not work for combines expressions:

FullSimplify[  Conjugate[a] y  Conjugate[y]]
(* Out: y Conjugate[a] Conjugate[y] *)


I have tried rearranging and MapAll with no improvement.

Any hints on what I could do?

• Try replacement Rules maybe, like expr // . HoldPattern[Times[x_, y__, Conjugate[x_]]] :> Times[Abs[x]^2, y]. Commented Jun 30, 2016 at 18:52
• @march, Times is Flat so you don't need to include the y__ bit of the pattern. expr //. x_ Conjugate[x_] :> Abs[x]^2 Commented Jun 30, 2016 at 19:26
• @SimonWoods. The Flat Attribute gives me trouble sometimes, especially in replacement rules with Plus and Times, where I have to worry about pre-evaluation; thus the HoldPattern. But I guess I should have tested the simplest possibility first! Commented Jun 30, 2016 at 20:38

I suspect that the reason why your simplifications work differently lies in the LeafCount of their outputs, which is a major contributor to the complexity function that the *Simplify functions use by default.

Consider for instance:

FullSimplify[Conjugate[a] a b]  (* Out: a b Conjugate[a]*)
% // LeafCount                  (* Out: 5 *)

Abs[a^2] b //LeafCount          (* Out: 6 *)


Crucially, the LeafCount of the "simpler" expression containing Abs is actually higher (see its FullForm), so it won't be selected as the simplest by FullSimplify.

The first approach I tried was to modify the complexity function to include a penalty for the presence of multiple Conjugate expressions:

FullSimplify[y a Conjugate[y] Conjugate[a],
ComplexityFunction -> (LeafCount[#] + 100 Count[#, _Conjugate, {0, Infinity}] &)
]

(* Out: a y Conjugate[a] Conjugate[y] *)


As you can see, no joy there. This is probably because no version containing fewer Conjugate expressions was even generated as a candidate during the internal evaluation of FullSimplify.

We can try to nudge FullSimplify in the right direction using an approach similar to the one march outlined in comments, while still maintaining the rest of the FullSimplify machinery, by adding a custom transformation function (see TransformationFunctions in the docs) to apply to the expressions to be simplified:

FullSimplify[y a Conjugate[y],
ComplexityFunction -> (LeafCount[#] + 100 Count[#, _Conjugate, {0, Infinity}] &),
TransformationFunctions -> {
Automatic,
Function[{expr}, ReplaceAll[expr, Times[a__, Conjugate[b_], b_] :> Times[a, Abs[b^2]]]]
}
]

(* Out: a Abs[y]^2 *)


Finally! A note: using Automatic in the list of trasnformation functions lets FullSimplify use anything from its usual bag of tricks, and simply adds our own custom function.

So let's make this into a handy function:

conjSimplify = (FullSimplify[#,
ComplexityFunction -> (LeafCount[#] + 100 Count[#, _Conjugate, {0, Infinity}] &),
TransformationFunctions -> {
Automatic,
Function[{expr}, ReplaceAll[expr, Times[a__, Conjugate[b_], b_] :> Times[a, Abs[b^2]]]]
}
] &);

conjSimplify[a b x Conjugate[a] Conjugate[b]]
(* Out: x Abs[a b]^2 *)

• With Simplify instead of FullSimplify it works for my more complex expressions too. Thanks a lot! Commented Jul 1, 2016 at 19:48
• @wolfgang6444 Excellent! I'm curious though: Simplify worked better for you? Was that because FullSimplify got bogged down on the more complex expression, or it returned an expression, but it just wouldn't give you the desired result? In any case, I'm glad that it worked out! Commented Jul 1, 2016 at 20:47
• No wrong or unwanted results - FullSimplify just didn't finish Commented Jul 2, 2016 at 6:17

I'm surprised nobody mentioned using ComplexExpand with TargetFunctions->{Abs}, possibly with an assist from Simplify:

ComplexExpand[a  Conjugate[a], _, TargetFunctions->{Abs}]


Abs[a]^2

Simplify @ ComplexExpand[Conjugate[a] y  Conjugate[y], _, TargetFunctions->{Abs}]


(Abs[a]^2 Abs[y]^2)/a

Simplify @ ComplexExpand[Conjugate[a] a b, _, TargetFunctions->{Abs}]


b Abs[a]^2

ComplexExpand[y a Conjugate[y] Conjugate[a], _, TargetFunctions->{Abs}]


Abs[a]^2 Abs[y]^2

Simplify @ ComplexExpand[y a Conjugate[y], _, TargetFunctions->{Abs}]


a Abs[y]^2

Simplify @ ComplexExpand[a b x Conjugate[a] Conjugate[b], _, TargetFunctions->{Abs}]


x Abs[a]^2 Abs[b]^2