Two suggestions:
(1) Instead of setting simp to false, try subst('fake_conjugate,
'conjugate, ...). After processing, revert the substitution. It might
help to declare fake_conjugate to be additive and multiplicative (but
it might hurt too).
(2) Instead of apply1 + a rule, try using ratsubst.
Here is some CL code and some tests--expect bugs!
;; start of file conjugate_to_abs.lisp ------------
(mfuncall '$declare 'non-simp-conjugate '$additive)
(mfuncall '$declare 'non-simp-conjugate '$multiplicative)
(defmspec $conj_to_abs (e)
(setq e ($substitute 'non-simp-conjugate '$conjugate (cadr e)))
($substitute '$conjugate 'non-simp-conjugate (conj-to-abs e e)))
(defun conj-to-abs (e p)
(cond ((or ($mapatom e) ($mapatom p)) e)
((and (not ($mapatom p)) (eq (mop p) 'non-simp-conjugate))
(setq p (cadr p))
($ratsubst (power (take '($cabs) p) 2) (mul p (take '(non-simp-conjugate)
p)) e))
(t
(mapcar #'(lambda (s) (setq e (conj-to-abs e s))) (cdr p))
e)))
;; end of file conjugate_to_abs.lisp ------------
Examples:
(%i12) load("conjugate_to_abs.lisp")$
(%i13) declare([x,y,z],complex)$
(%i14) conj_to_abs(x * conjugate(5*x));
(%o14) 5*cabs(x)^2
(%i15) conj_to_abs(x^3 * conjugate(5*x));
(%o15) 5*x^2*cabs(x)^2
(%i16) conj_to_abs( 2 * y * conjugate(y) * z * conjugate(z) * w * conjugate
(w));
(%o16) 2*cabs(w)^2*cabs(y)^2*cabs(z)^2
(%i17) conj_to_abs(sqrt(z)*conjugate(sqrt(z)));
(%o17) cabs(sqrt(z))^2
(%i18) conj_to_abs( foo(z) * conjugate(foo(z)));
(%o18) cabs(foo(z))^2
(%i19) conj_to_abs(z * conjugate(42 + z));
(%o19) cabs(z)^2+42*z
(%i20) conj_to_abs((z + 42) * conjugate(z));
(%o20) 42*conjugate(z)+cabs(z)^2
(%i21) conj_to_abs(z^5 * conjugate(z + 12));
(%o21) z^4*cabs(z)^2+12*z^5
(%i22) conj_to_abs(z^5 * conjugate(z^2+12));
(%o22) z^3*cabs(z^2)^2+12*z^5
Here, it would be better if non-simp-conjugate was not additive :(
(%i23) conj_to_abs((x + y) * conjugate(x + y));
(%o23) x*conjugate(y)+cabs(y)^2+conjugate(x)*y+cabs(x)^2
Again, my code is almost surely buggy, but maybe it is a start for
something
that will work for you. One problem is
(%i11) conj_to_abs(6.7b0 + conjugate(x));
`rat' replaced 6.7B0 by 67/10 = 6.7B0
(%o11) (10*conjugate(x)+67)/10
I don't know of a way around that---for doubles, keepfloat takes care of
this,
but not for big floats.
Barton
-----maxima-bounces at math.utexas.edu 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.