Mirror symmetry and realpart/imagpart of functions
Subject: Mirror symmetry and realpart/imagpart of functions
From: Dieter Kaiser
Date: Sun, 1 Feb 2009 19:26:10 +0100
We know that realpart/imagpart do not work correctly for most functions with
complex arguments.
An example is:
(%i1) realpart(gamma(1+%i));
(%o1) gamma(1+%i)
(%i2) imagpart(gamma(1+%i));
(%o2) 0
Maxima assumes a function always to be real valued. This can be changed by
declaring the symbol gamma to be complex. Then we get the noun form for the
realpart and the imagpart.
For functions which have mirror symmetry we can do more. In general we have
realpart(f(x+%i*y)) = 1/2* (conjugate(f(x+%i)) + f(x+%i*y))
imagpart(f(x+%i*y)) = 1/2*%i*(conjugate(f(x+%i)) - f(x+%i*y))
If the function has mirror symmetry this simplifies to:
realpart(f(x+%i*y)) = 1/2* (f(x-%i) + f(x+%i*y))
imagpart(f(x+%i*y)) = 1/2*%i*(f(x-%i) - f(x+%i*y))
This is implemented directly into the routine risplit for the Erf function.
It is possible to support this simplification in general for function which are
declared to have mirror symmetry (or partially). We have to add the following
code to the routine risplit:
((or (get (mop l) 'commutes-with-conjugate)
(get (mop l) 'conjugate-function))
;; The function has mirror symmetry
(cons (mul (div 1 2)
(add (simplify (list '($conjugate) l)) l))
(mul (div 1 2) '$%i
(sub (simplify (list '($conjugate) l)) l))))
If we add this code every function with mirror symmetry calls the function
conjugate to get a more simple expression for the realpart and imagpart of the
function.
Example:
For a real argument the conjugate expression simplifies as expected:
(%i1) realpart(gamma(x));
(%o1) gamma(x)
(%i2) imagpart(gamma(x));
(%o2) 0
Now a a complex argument. We get correct expressions for the realpart and
imagpart:
(%i2) realpart(gamma(1+%i));
(%o2) (gamma(%i+1)+gamma(1-%i))/2
(%i2) imagpart(gamma(1+%i));
(%o2) %i*(gamma(1-%i)-gamma(%i+1))/2
If we include functions with a conjugate-function on the property list, we do
not always get the most simple result, but a correct. E.g. the function
gamma_incomplete has no mirror symmetry on the negative x-axis.
For complex values we get the results from above:
(%i2) realpart(gamma_incomplete(a,1+%i));
(%o2) (gamma_incomplete(a,%i+1)+gamma_incomplete(a,1-%i))/2
(%i3) imagpart(gamma_incomplete(a,1+%i));
(%o3) %i*(gamma_incomplete(a,1-%i)-gamma_incomplete(a,%i+1))/2
For a real symbol the conjugate function does not simplify, because the sign is
unknown. The result is correct, but looks more complicated as the noun form:
(%i4) realpart(gamma_incomplete(a,x));
(%o4) (conjugate(gamma_incomplete(a,x))+gamma_incomplete(a,x))/2
(%i5) imagpart(gamma_incomplete(a,x));
(%o5) %i*(conjugate(gamma_incomplete(a,x))-gamma_incomplete(a,x))/2
But if we tell Maxima the sign of x, we againg get a simple answer:
(%i6) assume(x>0)$
(%i7) realpart(gamma_incomplete(a,x));
(%o7) gamma_incomplete(a,x)
(%i8) imagpart(gamma_incomplete(a,x));
(%o8) 0
I have run the testsuite and the share_testsuite. Both have no problems with
this extension. (We have to add the code at the right place in risplit.)
So what do you think. Should we extend Maxima to handle the realpart/imagpart of
functions with mirror symmetry more correctly.
Remarks:
If the function has in addition reflection symmetry and this is implemented too
we can get further simplifications.
With this extension we get more simple expressions for the abs and the carg
functions too, because the realpart/imagpart are needed.
Examples:
(%i19) abs(gamma(1+%i));
(%o19) sqrt((gamma(%i+1)+gamma(1-%i))^2/4-(gamma(1-%i)-gamma(%i+1))^2/4)
We have to help Maxima to get the most simple expression for abs:
(%i20) radcan(%);
(%o20) sqrt(gamma(1-%i))*sqrt(gamma(%i+1))
That would be the result for carg:
(%i21) carg(gamma(1+%i));
(%o21) atan2(%i*(gamma(1-%i)-gamma(%i+1))/2,(gamma(%i+1)+gamma(1-%i))/2)
Dieter Kaiser