On Sat, Aug 9, 2008 at 12:10 AM, John Lapeyre <pdl at johnlapeyre.com> wrote:
> I am trying to write a function to rewrite z*conjugate(z) as abs(z)^2 , and do this when z is other expressions, as well.
>
> Based on my attempts and reading the archives, I think this is impossible.
That's a bold claim!!
What I would suggest is to *not* try to evade or override built-in
Maxima simplification, but to work with it. If Maxima simplifies
sin(x)*conjugate(sin(x)) to sin(x)*sin(conjugate(x)), then the latter
form is what you need to simplify.
Here is one approach. Note that conjsimp_pair makes an assumption
which you may want to revisit. You may or may not want to replace
standalone conjugate(w) with abs(2)^2/w, but that's easy enough to
add.
/* conjsimp replaces z^a*conjugate(z^a) by abs(z)^(2*a) in an expression */
/* Copyright 2008 Stavros Macrakis; licensed under LGPL */
conjugate_to_abs(ex):=
block([inflag:true,
args,
prod: 1], /* return value */
if mapatom(ex) then ex
elseif part(ex,0)="*"
then (args: args(ex),
while (n:find_pair(conjsimp_pair,args))#false do
(args: delete(n[1],delete(n[2],args)),
prod: prod*n[3]),
prod*xreduce("*",args))
else map(conjugate_to_abs,ex))$
/* find first i<j s.t. f(l[i],l[j]) is not false
and return [ l[i], l[j], f(l[i],l[j]) ]
if no such i<j, then return false */
find_pair(f,l):=
block([lenl:length(l),val],
catch(
(for i thru lenl-1 do
for j:i+1 thru lenl do
if false # val:f(l[i],l[j])
then throw([l[i],l[j],val]),
false)))$
/* assumes that z2 is the one that contains the conjugate, which it
usually is */
conjsimp_pair(be1,be2):=
(be1: base_exp(be1),
be2: base_exp(be2),
if be1[1]=conjugate(be2[1])
then abs(be1[1])^(2*be2[2]) * be1[1]^(be1[2]-be2[2])
else false)$
base_exp(ex):=
block([inflag:true],
if mapatom(ex) or part(ex,0) # "^"
then [ex,1]
else args(ex))$
>>>>>>>>>>>>examples<<<<<<<<<<<<<<<
z*conjugate(z) => abs(z)^2
w*z*conjugate(z) => w*abs(z)^2
conjugate(w)*z*conjugate(z) => conjugate(w)*abs(z)^2
sin(z)*sin(conjugate(z)) => sin(z)^2
z^3/conjugate(z) => z^4/abs(z)^2
conjugate(w)*conjugate(z)/z^2 => conjugate(w)*abs(z)^2/z^3