views:

61

answers:

3

FullSimplify fails to recognize that:

 a*Conjugate[b] + b*Conjugate[a] = 2 Re[a*b]  

I have some very complex equations that could be simplified greatly if Mathematica could recognize this simple identity

(and that a*Conjugate[b] - b*Conjugate[a] = 2 Im[a*b]).

See, Mathematica will not finish solving my equations when written in

a*Conjugate[b] +b*Conjugate[a] form, 

but I could at the very least write my final equations in an extremely descriptive and compact form if Mathematica recognized this. The actual expressions look like:

-((I q1 + q2)/(I q0 + Sqrt[-q0^2 + q1^2 + q2^2 + q3^2])) -
 (Conjugate[q1] + I Conjugate[q2])/
 (Conjugate[q0] + I Conjugate[Sqrt[-q0^2 + q1^2 + q2^2 + q3^2]]) 

I would do this myself, but there are 16 of such expressions and they form 4 sets of coupled systems. Since one sign error would render my work useless, I would strongly prefer an automated process.

A: 

Is your identity correct? I'm getting different numbers for two sides

{a*Conjugate[b] + b*Conjugate[a], 2 Re[a*b]} /. {a -> RandomComplex[],b -> RandomComplex[]}
Yaroslav Bulatov
+1  A: 

First pass: Use ComplexExpand[].

    In := Simplify[ ComplexExpand[ a Conjugate[b] + b Conjugate[a], {a, b} ] ]
    Out = 2 (Im[a] Im[b] + Re[a] Re[b])

For more fun, look at ComplexityFunction, although I find that a lot of trial and error is involved in tuning FullSimplify.

Eric Towers
Be careful with ComplexExpand. As explained in its documentation (http://reference.wolfram.com/mathematica/ref/ComplexExpand.html), it explicitly assumes that all variables are real. This is often very useful, but it is not a correct assumption in this case.
Andrew Moylan
@Andrew Moylan: While true, the second argument to ComplexExpand is a list of symbols to be treated as Complex. Thus the {a,b}, above.
Eric Towers
Ah quite right, my mistake. I didn't read your post carefully enough, sorry.
Andrew Moylan
+3  A: 

The identity you gave, b Conjugate[a] + a Conjugate[b] == 2 Re[a b], is only true if at least one of a and b is real:

In[7]:= Simplify[
 Reduce[a*Conjugate[b] + b*Conjugate[a] == 2 Re[a*b], {a, b}]]

Out[7]= Im[a] == 0 || Im[b] == 0

If this additional condition is in fact true in your application then you could give it to Simplify or FullSimplify as an assumption, as their second argument. For example:

In[14]:= FullSimplify[Im[a*Conjugate[b] + b*Conjugate[a]], 
 Im[a] == 0 || Im[b] == 0]

Out[14]= 0

By the way, here is one example when the identity is not true:

In[1]:= FindInstance[
 a*Conjugate[b] + b*Conjugate[a] != 2 Re[a*b], {a, b}]

Out[1]= {{a -> -I, b -> -I}}
Andrew Moylan
In M'ma 7, I've found that Assuming[{...}, _sequence_of_simplification_functions [ _stuff_ ] ] is much less annoying that passing assumptions in to each of the simplification functions. (And substantially less prone to cut/paste errors.)
Eric Towers
Of course, you can also set the global `$Assumptions`
Simon