Bug report ID 2123651 "min and max of imaginary and real numbers"



  Something to consider  is that occasionally a program wili  return a 
result like 3.0+1.0e-203*%i,

where the imaginary part is a numerical error.

Comparisons maybe should be allowed.

RJF
On 9/5/2010 12:09 PM, Stavros Macrakis wrote:
> Hi, Dieter,
>
> Thanks for your work.
>
> One thing: I'd think that any comparisons involving imaginary 
> quantities should give errors, not nounforms or unknown.  It is not 
> that %i < 3 is unknown, it is actually not defined.  True, a*%i < 3 
> for a=0, so a nounform might be sensible there, but I'd rather catch 
> the anomaly. (Robert may disagree with me on this...)
>
>              -s
>
> On Sun, Sep 5, 2010 at 14:41, Dieter Kaiser <drdieterkaiser at web.de 
> <mailto:drdieterkaiser at web.de>> wrote:
>
>     I had a look at the open bug report ID 2123651 "min and max of
>     imaginary
>     and real numbers". To correct the behavior I have tried the following
>     changes:
>
>     1. In $compare
>       Check for infinities, infinitesimal, indeterminate.
>       Take the limit for this case. This simplifies -minf to minf
>       or 7+inf to inf.
>
>     2. In $compare
>       First, do the check lenient-extended-realp.
>       We do not try to do the test meqp for complex expressions.
>
>     3. In simp-max
>       In the final clause, do not remove a minf, when issue-warning is T.
>       Do not simplify to inf, when issue-warning is T.
>
>     With these changes we get a noun form for expression like max(%i*inf,
>     minf).
>
>     We will get 5 changes in the testsuite (3 different results and 2
>     correct results for expected failures):
>
>     Running tests in rtest_allnummod:
>     ********************** Problem 127 ***************
>     Input:
>     is(compare(%i, %i) = =)
>
>
>     Result:
>     false
>
>     This differed from the expected result:
>     true
>
>     ********************** Problem 128 ***************
>     Input:
>     is(compare(a < b, a < b) = =)
>
>
>     Result:
>     false
>
>     This differed from the expected result:
>     true
>
>     ********************** Problem 132 ***************
>     Input:
>     is(compare(infinity, infinity) = =)
>
>
>     Result:
>     false
>
>     This differed from the expected result:
>     true
>
>     ********************** Problem 135 ***************
>     Input:
>     is(compare(inf, - minf) = =)
>
>
>     Result:
>     true
>
>     ... Which was correct, but was expected to be wrong due to a known bug
>     in
>      Maxima.
>
>     ********************** Problem 136 ***************
>     Input:
>     is(compare(inf, 7 + inf) = =)
>
>
>     Result:
>     true
>
>     ... Which was correct, but was expected to be wrong due to a known bug
>     in
>      Maxima.
>
>     This is the complete code with the changes:
>
>     (defun $compare (a b)
>      (when (amongl '($ind $und $inf $minf $infinity $zeroa $zerob) a)
>        (setq a ($limit a)))
>      (when (amongl '($ind $und $inf $minf $infinity $zeroa $zerob) b)
>        (setq b ($limit b)))
>      (cond ((or (not (lenient-extended-realp a))
>                 (not (lenient-extended-realp b)))
>             '$notcomparable)
>            ((eq t (meqp a b)) "=")
>            (t
>             (let ((sgn (csign (specrepcheck (sub a b)))))
>               (cond ((eq sgn '$neg) "<")
>                     ((eq sgn '$nz) "<=")
>                     ((eq sgn '$zero) "=")
>                     ((eq sgn '$pz) ">=")
>                     ((eq sgn '$pos) ">")
>                     ((eq sgn '$pn) "#")
>                     ((eq sgn '$pnz) '$unknown)
>                     (t '$unknown))))))
>
>     (defun simp-max (l tmp z)
>      (let ((acc nil) (sgn) (num-max nil) (issue-warning))
>        (setq l (margs (specrepcheck l)))
>        (dolist (li l)
>          (if (op-equalp li '$max)
>              (setq acc (append acc (mapcar #'(lambda (s) (simplifya s z))
>     (margs li))))
>              (push (simplifya li z) acc)))
>
>        ;; First, delete duplicate members of l.
>
>        (setq l (sorted-remove-duplicates (sort acc '$orderlessp)))
>        (setq acc nil)
>
>        ;; Second, find the largest real number in l. Since (mnump
>     '$%i) -->
>     false,
>        ;; we don't have to worry that num-max is complex.
>
>        (dolist (li l)
>          (if (mnump li)
>              (setq num-max (if (or (null num-max) (mgrp li num-max)) li
>     num-max))
>              (push li acc)))
>        (setq l acc)
>        (setq acc (if (null num-max) num-max (list num-max)))
>
>        ;; Third, accumulate the maximum in the list acc. For each x in l,
>     do:
>
>        ;; (a) if x is > or >= every member of acc, set acc to (x),
>        ;; (b) if x is < or <= to some member of acc, do nothing,
>        ;; (c) if neither 'a' or 'b', push x into acc,
>        ;; (d) if x cannot be compared to some member of acc, set
>     issue-warning to true.
>
>        (dolist (x l)
>          (catch 'done
>            (dolist (ai acc)
>              (setq sgn ($compare x ai))
>              (cond ((member sgn '(">" ">=") :test #'equal)
>                     (setq acc (delete ai acc :test #'eq)))
>                    ((eq sgn '$notcomparable) (setq issue-warning t))
>                    ((member sgn '("<" "=" "<=") :test #'equal)
>                     (throw 'done t))))
>                 (push x acc)))
>
>        ;; Fourth, when when trylevel is 2 or higher e and -e are
>     members of
>     acc,
>        ;; replace e by |e|.
>
>        (cond ((eq t (mgrp ($get '$trylevel '$maxmin) 1))
>               (setq sgn nil)
>               (dolist (ai acc)
>                 (setq tmp (if (lenient-realp ai)
>                               (member-if #'(lambda (s) (add-inversep
>     ai s))
>     sgn)
>                               nil))
>                 (if tmp
>                     (setf (car tmp) (take '(mabs) ai))
>                     (push ai sgn)))
>               (setq acc sgn)))
>
>        ;; Fifth, when trylevel is 3 or higher and issue-warning is false,
>     try the
>        ;; betweenp simplification.
>
>        (cond ((and (not issue-warning) (eq t (mgrp ($get '$trylevel
>     '$maxmin) 2)))
>               (setq l nil)
>               (setq sgn (cdr acc))
>               (dolist (ai acc)
>                 (if (not (betweenp ai sgn sgn)) (push ai l))
>                 (setq sgn `(,@(cdr sgn) ,ai)))
>               (setq acc l)))
>
>        ;; Finally, do a few clean ups:
>
>        (setq acc (if (not issue-warning) (delete '$minf acc) acc))
>        (cond ((null acc) '$minf)
>              ((and (not issue-warning) (member '$inf acc :test #'eq))
>     '$inf)
>              ((null (cdr acc)) (car acc))
>              (t  `(($max simp) ,@(sort acc '$orderlessp))))))
>
>     Comments? Should I commit the code?
>
>     Dieter Kaiser
>
>
>     _______________________________________________
>     Maxima mailing list
>     Maxima at math.utexas.edu <mailto:Maxima at math.utexas.edu>
>     http://www.math.utexas.edu/mailman/listinfo/maxima
>
>
>
> _______________________________________________
> Maxima mailing list
> Maxima at math.utexas.edu
> http://www.math.utexas.edu/mailman/listinfo/maxima