Bug report ID 2123651 "min and max of imaginary and real numbers"
Subject: Bug report ID 2123651 "min and max of imaginary and real numbers"
From: Stavros Macrakis
Date: Sun, 5 Sep 2010 15:09:34 -0400
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> 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
> http://www.math.utexas.edu/mailman/listinfo/maxima
>