Further work on the functions for the complex components



After the last extensions I would like to suggest the following
extensions as a next step to improve the functions for the complex
components:

1. Functions are by default complex valued:

To be more consistent the test function $csign should return for an
unknown function the answer $complex. With the last extension to abs we
would get:

(%i41) abs(f(x));
(%o41) sqrt('realpart(f(x))^2+'imagpart(f(x))^2)

The results will be more simple for every function for which Maxima has
more information.

The build in knowledge about the sin function gives:

(%i50) abs(sin(x));
(%o50) abs(sin(x))
(%i51) abs(sin(z));
(%o51) sqrt(cosh('imagpart(z))^2*sin('realpart(z))^2
             +sinh('imagpart(z))^2*cos('realpart(z))^2)

The knowledge about the bessel function, which is given by a
risplit-function gives:

(%i52) abs(bessel_j(1,x));
(%o52) abs(bessel_j(1,x))
(%i53) abs(bessel_j(1,z));
(%o53) sqrt('realpart(bessel_j(1,z))^2+'imagpart(bessel_j(1,z))^2)

This can be extended to functions which are declared to be real or have
a property maps-reals-to-reals.

This is the changed code:

  (cond ((and *complexsign*
              (or (and (atom x) (declared-complex-p x))
                  (and (not (atom x))
                       (symbolp (mop x))
                       (not (get (mop x) 'real-valued)))))
         ;; In Complex Mode look for symbols declared to be complex.
         ;; Functions are by default handled as a complex.
         (when *debug-compar*
           (format t "~&SIGN-ANY with ~A" x)
           (format t "~&Symbol declared to be complex found.~%"))
         (cond ((and (atom x) ($featurep x '$imaginary))
                (setq sign '$imaginary))
               (t (setq sign '$complex))))

2. Return noun form for expressions with mnctimes and mncexpt:

Because of the above change the simplification of expressions with
non-commutative multiplications and exponentiations would change. To
preserve the behavior that a noun form is returned for abs and cabs the
following code could be added to the function absarg:

((eq (caar l) 'mnctimes)
 ;; Noun form for the absolute value and argument of a noncommutative
 ;; multiplication.
 (cons (list '(mabs) l) (list '(%carg) l)))
((eq (caar l) 'mncexpt)
 ;; Noun form for the absolute value and argument of a noncommutative
 ;; exponentiation.
 (cons (list '(mabs) l) (list '(%carg) l)))

3. Simplifying noun forms cabs, carg, realpart and imagpart:

We have a bug report with the topic: Nonsimplifying nounforms: abs,
realpart, carg, etc. - ID: 902290. 

This are some results for simplifying noun forms:

(%i55) 'cabs(1);
(%o55) 1
(%i56) 'cabs(1+%i);
(%o56) sqrt(2)
(%i57) 'cabs(1.b0+%i);
(%o57) 1.414213562373095b0
(%i58) 'carg(1);
(%o58) 0
(%i59) 'carg(-1);
(%o59) %pi
(%i60) 'carg(-1+%i);
(%o60) 3*%pi/4
(%i61) 'carg(-1.0b0+%i);
(%o61) 2.356194490192345b0
(%i62) 'realpart(1+%i);
(%o62) 1
(%i63) 'imagpart(1+%i);
(%o63) 1
(%i65) 'realpart((1+%i)*(1-%i));
(%o65) 2
(%i66) 'imagpart((1+%i)*(1-%i));
(%o66) 0

Only numbers including complex numbers are simplified. In other cases we
get again the noun form.

This is the code:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprop $realpart %realpart verb)
(defprop %realpart $realpart noun)

(defprop %realpart simp-realpart operators)

(defun simp-realpart (expr z simpflag)
  (oneargcheck expr)
  (setq z (simpcheck (cadr expr) simpflag))
  (let ((sgn nil))
    (cond ((eq (setq sgn ($csign z)) '$imaginary)
           0)
          ((eq sgn '$complex)
           (cond ((complex-number-p ($expand z) 'bigfloat-or-number-p)
                  ($realpart z))
                 (t 
                  (eqtest (list '(%realpart) z) expr))))
          (t z))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprop $imagpart %imagpart verb)
(defprop %imagpart $imagpart noun)

(defprop %imagpart simp-imagpart operators)

(defun simp-imagpart (expr z simpflag)
  (oneargcheck expr)
  (setq z (simpcheck (cadr expr) simpflag))
  (let ((sgn nil))
    (cond ((eq (setq sgn ($csign z)) '$imaginary)
           (mul -1 '$%i z))
          ((eq sgn '$complex)
           (cond ((complex-number-p ($expand z) 'bigfloat-or-number-p)
                  ($imagpart z))
                 (t 
                  (eqtest (list '(%imagpart) z) expr))))
          (t 0))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprop $cabs %cabs verb)
(defprop %cabs $cabs noun)

(defprop %cabs simp-cabs operators)

(defun simp-cabs (expr z simpflag)
  (oneargcheck expr)
  (setq z (simpcheck (cadr expr) simpflag))
  (let ((sgn nil))
    (cond ((member (setq sgn ($csign z)) '($complex $imaginary))
           (cond ((complex-number-p ($expand z) 'bigfloat-or-number-p)
                  (simplify (list '(mabs) z)))
                 (t
                  (eqtest (list '(mabs) z) expr))))
          ((eq sgn '$zero)
           0)
          ((member sgn '($pos $pz))
           z)
          ((eq sgn '$neg)
            (mul -1 z))
          (t 
           (eqtest (list '(mabs) z) expr)))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprop $carg %carg verb)
(defprop %carg $carg noun)

(defprop %carg simp-carg operators)

(defun simp-carg (expr z simpflag)
  (oneargcheck expr)
  (setq z (simpcheck (cadr expr) simpflag))
  (let ((sgn nil))
    (cond ((eq z '$%i)
           (div '$%pi 2))
          ((member (setq sgn ($csign z)) '($complex $imaginary))
           (cond ((complex-number-p ($expand z) 'bigfloat-or-number-p)
                  ($carg z))
                 (t 
                  (eqtest (list '(%carg) z) expr))))
          ((eq sgn '$zero)
           (merror "carg: carg(0) is undefined"))
          ((member sgn '($pos $pz))
           0)
          ((eq sgn '$neg)
            '$%pi)
          (t 
           (eqtest (list '(%carg) z) expr)))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

If no one sees a problem, I will commit the suggest code.

Dieter Kaiser