Mercurial > emacs
diff lisp/calc/calc-arith.el @ 88155:d7ddb3e565de
sync with trunk
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Mon, 16 Jan 2006 00:03:54 +0000 |
parents | 0d8b17d428b5 |
children |
line wrap: on
line diff
--- a/lisp/calc/calc-arith.el Sun Jan 15 23:02:10 2006 +0000 +++ b/lisp/calc/calc-arith.el Mon Jan 16 00:03:54 2006 +0000 @@ -1,10 +1,10 @@ ;;; calc-arith.el --- arithmetic functions for Calc -;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc. +;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004, +;; 2005 Free Software Foundation, Inc. ;; Author: David Gillespie <daveg@synaptics.com> -;; Maintainers: D. Goel <deego@gnufans.org> -;; Colin Walters <walters@debian.org> +;; Maintainer: Jay Belanger <belanger@truman.edu> ;; This file is part of GNU Emacs. @@ -28,11 +28,77 @@ ;;; Code: ;; This file is autoloaded from calc-ext.el. + (require 'calc-ext) - (require 'calc-macs) -(defun calc-Need-calc-arith () nil) +;;; The following lists are not exhaustive. +(defvar math-scalar-functions '(calcFunc-det + calcFunc-cnorm calcFunc-rnorm + calcFunc-vlen calcFunc-vcount + calcFunc-vsum calcFunc-vprod + calcFunc-vmin calcFunc-vmax)) + +(defvar math-nonscalar-functions '(vec calcFunc-idn calcFunc-diag + calcFunc-cvec calcFunc-index + calcFunc-trn + | calcFunc-append + calcFunc-cons calcFunc-rcons + calcFunc-tail calcFunc-rhead)) + +(defvar math-scalar-if-args-functions '(+ - * / neg)) + +(defvar math-real-functions '(calcFunc-arg + calcFunc-re calcFunc-im + calcFunc-floor calcFunc-ceil + calcFunc-trunc calcFunc-round + calcFunc-rounde calcFunc-roundu + calcFunc-ffloor calcFunc-fceil + calcFunc-ftrunc calcFunc-fround + calcFunc-frounde calcFunc-froundu)) + +(defvar math-positive-functions '()) + +(defvar math-nonnegative-functions '(calcFunc-cnorm calcFunc-rnorm + calcFunc-vlen calcFunc-vcount)) + +(defvar math-real-scalar-functions '(% calcFunc-idiv calcFunc-abs + calcFunc-choose calcFunc-perm + calcFunc-eq calcFunc-neq + calcFunc-lt calcFunc-gt + calcFunc-leq calcFunc-geq + calcFunc-lnot + calcFunc-max calcFunc-min)) + +(defvar math-real-if-arg-functions '(calcFunc-sin calcFunc-cos + calcFunc-tan calcFunc-sec + calcFunc-csc calcFunc-cot + calcFunc-arctan + calcFunc-sinh calcFunc-cosh + calcFunc-tanh calcFunc-sech + calcFunc-csch calcFunc-coth + calcFunc-exp + calcFunc-gamma calcFunc-fact)) + +(defvar math-integer-functions '(calcFunc-idiv + calcFunc-isqrt calcFunc-ilog + calcFunc-vlen calcFunc-vcount)) + +(defvar math-num-integer-functions '()) + +(defvar math-rounding-functions '(calcFunc-floor + calcFunc-ceil + calcFunc-round calcFunc-trunc + calcFunc-rounde calcFunc-roundu)) + +(defvar math-float-rounding-functions '(calcFunc-ffloor + calcFunc-fceil + calcFunc-fround calcFunc-ftrunc + calcFunc-frounde calcFunc-froundu)) + +(defvar math-integer-if-args-functions '(+ - * % neg calcFunc-abs + calcFunc-min calcFunc-max + calcFunc-choose calcFunc-perm)) ;;; Arithmetic. @@ -164,6 +230,20 @@ ;;; TYPES is a list of type symbols (any, int, frac, ...) ;;; RANGE is a sorted vector of intervals describing the range. +(defvar math-super-types + '((int numint rat real number) + (numint real number) + (frac rat real number) + (rat real number) + (float real number) + (real number) + (number) + (scalar) + (sqmatrix matrix vector) + (matrix vector) + (vector) + (const))) + (defun math-setup-declarations () (or (eq math-decls-cache-tag (calc-var-value 'var-Decls)) (let ((p (calc-var-value 'var-Decls)) @@ -214,19 +294,6 @@ (error nil))))) (setq math-decls-all (assq 'var-All math-decls-cache))))) -(defvar math-super-types - '((int numint rat real number) - (numint real number) - (frac rat real number) - (rat real number) - (float real number) - (real number) - (number) - (scalar) - (matrix vector) - (vector) - (const))) - (defun math-known-scalarp (a &optional assume-scalar) (math-setup-declarations) (if (if calc-matrix-mode @@ -239,6 +306,10 @@ (and (not (Math-scalarp a)) (not (math-known-scalarp a t)))) +(defun math-known-square-matrixp (a) + (and (math-known-matrixp a) + (math-check-known-square-matrixp a))) + ;;; Try to prove that A is a scalar (i.e., a non-vector). (defun math-check-known-scalarp (a) (cond ((Math-objectp a) t) @@ -257,8 +328,17 @@ (let ((decl (if (eq (car a) 'var) (or (assq (nth 2 a) math-decls-cache) math-decls-all) - (assq (car a) math-decls-cache)))) - (memq 'scalar (nth 1 decl)))))) + (assq (car a) math-decls-cache))) + val) + (cond + ((memq 'scalar (nth 1 decl)) + t) + ((and (eq (car a) 'var) + (boundp (nth 2 a)) + (setq val (symbol-value (nth 2 a)))) + (math-check-known-scalarp val)) + (t + nil)))))) ;;; Try to prove that A is *not* a scalar. (defun math-check-known-matrixp (a) @@ -276,9 +356,53 @@ (let ((decl (if (eq (car a) 'var) (or (assq (nth 2 a) math-decls-cache) math-decls-all) - (assq (car a) math-decls-cache)))) - (memq 'vector (nth 1 decl)))))) + (assq (car a) math-decls-cache))) + val) + (cond + ((memq 'matrix (nth 1 decl)) + t) + ((and (eq (car a) 'var) + (boundp (nth 2 a)) + (setq val (symbol-value (nth 2 a)))) + (math-check-known-matrixp val)) + (t + nil)))))) +;;; Given that A is a matrix, try to prove that it is a square matrix. +(defun math-check-known-square-matrixp (a) + (cond ((math-square-matrixp a) + t) + ((eq (car-safe a) '^) + (math-check-known-square-matrixp (nth 1 a))) + ((or + (eq (car-safe a) '*) + (eq (car-safe a) '+) + (eq (car-safe a) '-)) + (and + (math-check-known-square-matrixp (nth 1 a)) + (math-check-known-square-matrixp (nth 2 a)))) + (t + (let ((decl (if (eq (car a) 'var) + (or (assq (nth 2 a) math-decls-cache) + math-decls-all) + (assq (car a) math-decls-cache))) + val) + (cond + ((memq 'sqmatrix (nth 1 decl)) + t) + ((and (eq (car a) 'var) + (boundp (nth 2 a)) + (setq val (symbol-value (nth 2 a)))) + (math-check-known-square-matrixp val)) + ((and (or + (integerp calc-matrix-mode) + (eq calc-matrix-mode 'sqmatrix)) + (eq (car-safe a) 'var)) + t) + ((memq 'matrix (nth 1 decl)) + nil) + (t + nil)))))) ;;; Try to prove that A is a real (i.e., not complex). (defun math-known-realp (a) @@ -326,9 +450,12 @@ ((Math-negp a) 1) ((Math-zerop a) 2) ((eq (car a) 'intv) - (cond ((Math-zerop (nth 2 a)) 6) - ((Math-zerop (nth 3 a)) 3) - (t 7))) + (cond + ((math-known-posp (nth 2 a)) 4) + ((math-known-negp (nth 3 a)) 1) + ((Math-zerop (nth 2 a)) 6) + ((Math-zerop (nth 3 a)) 3) + (t 7))) ((eq (car a) 'sdev) (if (math-known-realp (nth 1 a)) 7 15)) (t 8))) @@ -819,71 +946,6 @@ (math-reject-arg a 'objectp 'quiet)))) -;;; The following lists are not exhaustive. -(defvar math-scalar-functions '(calcFunc-det - calcFunc-cnorm calcFunc-rnorm - calcFunc-vlen calcFunc-vcount - calcFunc-vsum calcFunc-vprod - calcFunc-vmin calcFunc-vmax)) - -(defvar math-nonscalar-functions '(vec calcFunc-idn calcFunc-diag - calcFunc-cvec calcFunc-index - calcFunc-trn - | calcFunc-append - calcFunc-cons calcFunc-rcons - calcFunc-tail calcFunc-rhead)) - -(defvar math-scalar-if-args-functions '(+ - * / neg)) - -(defvar math-real-functions '(calcFunc-arg - calcFunc-re calcFunc-im - calcFunc-floor calcFunc-ceil - calcFunc-trunc calcFunc-round - calcFunc-rounde calcFunc-roundu - calcFunc-ffloor calcFunc-fceil - calcFunc-ftrunc calcFunc-fround - calcFunc-frounde calcFunc-froundu)) - -(defvar math-positive-functions '()) - -(defvar math-nonnegative-functions '(calcFunc-cnorm calcFunc-rnorm - calcFunc-vlen calcFunc-vcount)) - -(defvar math-real-scalar-functions '(% calcFunc-idiv calcFunc-abs - calcFunc-choose calcFunc-perm - calcFunc-eq calcFunc-neq - calcFunc-lt calcFunc-gt - calcFunc-leq calcFunc-geq - calcFunc-lnot - calcFunc-max calcFunc-min)) - -(defvar math-real-if-arg-functions '(calcFunc-sin calcFunc-cos - calcFunc-tan calcFunc-arctan - calcFunc-sinh calcFunc-cosh - calcFunc-tanh calcFunc-exp - calcFunc-gamma calcFunc-fact)) - -(defvar math-integer-functions '(calcFunc-idiv - calcFunc-isqrt calcFunc-ilog - calcFunc-vlen calcFunc-vcount)) - -(defvar math-num-integer-functions '()) - -(defvar math-rounding-functions '(calcFunc-floor - calcFunc-ceil - calcFunc-round calcFunc-trunc - calcFunc-rounde calcFunc-roundu)) - -(defvar math-float-rounding-functions '(calcFunc-ffloor - calcFunc-fceil - calcFunc-fround calcFunc-ftrunc - calcFunc-frounde calcFunc-froundu)) - -(defvar math-integer-if-args-functions '(+ - * % neg calcFunc-abs - calcFunc-min calcFunc-max - calcFunc-choose calcFunc-perm)) - - ;;;; Arithmetic. (defsubst calcFunc-neg (a) @@ -1331,6 +1393,7 @@ (and (eq (car-safe b) '^) (Math-looks-negp (nth 2 b)) (not (and (eq (car-safe a) '^) (Math-looks-negp (nth 2 a)))) + (not (math-known-matrixp (nth 1 b))) (math-div a (math-normalize (list '^ (nth 1 b) (math-neg (nth 2 b)))))) (and (eq (car-safe a) '/) @@ -1372,6 +1435,30 @@ (list 'calcFunc-idn (math-mul a (nth 1 b)))) (and (math-known-matrixp a) (math-mul a (nth 1 b))))) + (and (math-identity-matrix-p a t) + (or (and (eq (car-safe b) 'calcFunc-idn) + (= (length b) 2) + (list 'calcFunc-idn (math-mul + (nth 1 (nth 1 a)) + (nth 1 b)) + (1- (length a)))) + (and (math-known-scalarp b) + (list 'calcFunc-idn (math-mul + (nth 1 (nth 1 a)) b) + (1- (length a)))) + (and (math-known-matrixp b) + (math-mul (nth 1 (nth 1 a)) b)))) + (and (math-identity-matrix-p b t) + (or (and (eq (car-safe a) 'calcFunc-idn) + (= (length a) 2) + (list 'calcFunc-idn (math-mul (nth 1 a) + (nth 1 (nth 1 b))) + (1- (length b)))) + (and (math-known-scalarp a) + (list 'calcFunc-idn (math-mul a (nth 1 (nth 1 b))) + (1- (length b)))) + (and (math-known-matrixp a) + (math-mul a (nth 1 (nth 1 b)))))) (and (math-looks-negp b) (math-mul (math-neg a) (math-neg b))) (and (eq (car-safe b) '-) @@ -1606,8 +1693,54 @@ (math-reject-arg b "*Division by zero")) a)))) +;; For math-div-symb-fancy +(defvar math-trig-inverses + '((calcFunc-sin . calcFunc-csc) + (calcFunc-cos . calcFunc-sec) + (calcFunc-tan . calcFunc-cot) + (calcFunc-sec . calcFunc-cos) + (calcFunc-csc . calcFunc-sin) + (calcFunc-cot . calcFunc-tan) + (calcFunc-sinh . calcFunc-csch) + (calcFunc-cosh . calcFunc-sech) + (calcFunc-tanh . calcFunc-coth) + (calcFunc-sech . calcFunc-cosh) + (calcFunc-csch . calcFunc-sinh) + (calcFunc-coth . calcFunc-tanh))) + +(defvar math-div-trig) +(defvar math-div-non-trig) + +(defun math-div-new-trig (tr) + (if math-div-trig + (setq math-div-trig + (list '* tr math-div-trig)) + (setq math-div-trig tr))) + +(defun math-div-new-non-trig (ntr) + (if math-div-non-trig + (setq math-div-non-trig + (list '* ntr math-div-non-trig)) + (setq math-div-non-trig ntr))) + +(defun math-div-isolate-trig (expr) + (if (eq (car-safe expr) '*) + (progn + (math-div-isolate-trig-term (nth 1 expr)) + (math-div-isolate-trig (nth 2 expr))) + (math-div-isolate-trig-term expr))) + +(defun math-div-isolate-trig-term (term) + (let ((fn (assoc (car-safe term) math-trig-inverses))) + (if fn + (math-div-new-trig + (cons (cdr fn) (cdr term))) + (math-div-new-non-trig term)))) + (defun math-div-symb-fancy (a b) - (or (and math-simplify-only + (or (and (math-known-matrixp b) + (math-mul a (math-pow b -1))) + (and math-simplify-only (not (equal a math-simplify-only)) (list '/ a b)) (and (Math-equal-int b 1) a) @@ -1664,6 +1797,15 @@ (list 'calcFunc-idn (math-div a (nth 1 b)))) (and (math-known-matrixp a) (math-div a (nth 1 b))))) + (and math-simplifying + (let ((math-div-trig nil) + (math-div-non-trig nil)) + (math-div-isolate-trig b) + (if math-div-trig + (if math-div-non-trig + (math-div (math-mul a math-div-trig) math-div-non-trig) + (math-mul a math-div-trig)) + nil))) (if (and calc-matrix-mode (or (math-known-matrixp a) (math-known-matrixp b))) (math-combine-prod a b nil t nil) @@ -1712,6 +1854,11 @@ (math-mul-zero b a)))) (list '/ a b))) +;;; Division from the left. +(defun calcFunc-ldiv (a b) + (if (math-known-scalarp a) + (math-div b a) + (math-mul (math-pow a -1) b))) (defun calcFunc-mod (a b) (math-normalize (list '% a b))) @@ -1742,23 +1889,35 @@ (math-normalize (list '^ a b))) (defun math-pow-of-zero (a b) - (if (Math-zerop b) - (if calc-infinite-mode - '(var nan var-nan) - (math-reject-arg (list '^ a b) "*Indeterminate form")) - (if (math-floatp b) (setq a (math-float a))) - (if (math-posp b) - a - (if (math-negp b) - (math-div 1 a) - (if (math-infinitep b) - '(var nan var-nan) - (if (and (eq (car b) 'intv) (math-intv-constp b) - calc-infinite-mode) - '(intv 3 (neg (var inf var-inf)) (var inf var-inf)) - (if (math-objectp b) - (list '^ a b) - a))))))) + "Raise A to the power of B, where A is a form of zero." + (if (math-floatp b) (setq a (math-float a))) + (cond + ;; 0^0 = 1 + ((eq b 0) + 1) + ;; 0^0.0, etc., are undetermined + ((Math-zerop b) + (if calc-infinite-mode + '(var nan var-nan) + (math-reject-arg (list '^ a b) "*Indeterminate form"))) + ;; 0^positive = 0 + ((math-known-posp b) + a) + ;; 0^negative is undefined (let math-div handle it) + ((math-known-negp b) + (math-div 1 a)) + ;; 0^infinity is undefined + ((math-infinitep b) + '(var nan var-nan)) + ;; Some intervals + ((and (eq (car b) 'intv) + calc-infinite-mode + (math-negp (nth 2 b)) + (math-posp (nth 3 b))) + '(intv 3 (neg (var inf var-inf)) (var inf var-inf))) + ;; If none of the above, leave it alone. + (t + (list '^ a b)))) (defun math-pow-zero (a b) (if (eq (car-safe a) 'mod) @@ -1800,6 +1959,22 @@ (cond ((and math-simplify-only (not (equal a math-simplify-only))) (list '^ a b)) + ((and (eq (car-safe a) '*) + (or + (and + (math-known-matrixp (nth 1 a)) + (math-known-matrixp (nth 2 a))) + (and + calc-matrix-mode + (not (eq calc-matrix-mode 'scalar)) + (and (not (math-known-scalarp (nth 1 a))) + (not (math-known-scalarp (nth 2 a))))))) + (if (and (= b -1) + (math-known-square-matrixp (nth 1 a)) + (math-known-square-matrixp (nth 2 a))) + (math-mul (math-pow-fancy (nth 2 a) -1) + (math-pow-fancy (nth 1 a) -1)) + (list '^ a b))) ((and (eq (car-safe a) '*) (or (math-known-num-integerp b) (math-known-nonnegp (nth 1 a)) @@ -2185,6 +2360,10 @@ (defalias 'calcFunc-float 'math-float) +;; The variable math-trunc-prec is local to math-trunc in calc-misc.el, +;; but used by math-trunc-fancy which is called by math-trunc. +(defvar math-trunc-prec) + (defun math-trunc-fancy (a) (cond ((eq (car a) 'frac) (math-quotient (nth 1 a) (nth 2 a))) ((eq (car a) 'cplx) (math-trunc (nth 1 a))) @@ -2214,7 +2393,7 @@ (math-trunc (nth 3 a))))) ((math-provably-integerp a) a) ((Math-vectorp a) - (math-map-vec (function (lambda (x) (math-trunc x prec))) a)) + (math-map-vec (function (lambda (x) (math-trunc x math-trunc-prec))) a)) ((math-infinitep a) (if (or (math-posp a) (math-negp a)) a @@ -2251,6 +2430,10 @@ a (math-float (math-trunc a prec)))) +;; The variable math-floor-prec is local to math-floor in calc-misc.el, +;; but used by math-floor-fancy which is called by math-floor. +(defvar math-floor-prec) + (defun math-floor-fancy (a) (cond ((math-provably-integerp a) a) ((eq (car a) 'hms) @@ -2273,7 +2456,7 @@ (math-add (math-floor (nth 3 a)) -1) (math-floor (nth 3 a))))) ((Math-vectorp a) - (math-map-vec (function (lambda (x) (math-floor x prec))) a)) + (math-map-vec (function (lambda (x) (math-floor x math-floor-prec))) a)) ((math-infinitep a) (if (or (math-posp a) (math-negp a)) a @@ -2629,6 +2812,11 @@ (defvar math-combine-prod-e '(var e var-e)) ;;; The following is expanded out four ways for speed. + +;; math-unit-prefixes is defined in calc-units.el, +;; but used here. +(defvar math-unit-prefixes) + (defun math-combine-prod (a b inva invb scalar-okay) (cond ((or (and inva (Math-zerop a)) @@ -2646,6 +2834,8 @@ invb (math-looks-negp (nth 2 b))) (math-mul a (math-pow (nth 1 b) (math-neg (nth 2 b))))) + ((and math-simplifying + (math-combine-prod-trig a b))) (t (let ((apow 1) (bpow 1)) (and (consp a) (cond ((and (eq (car a) '^) @@ -2743,6 +2933,83 @@ (math-pow a apow) (inexact-result (list '^ a apow))))))))))) +(defun math-combine-prod-trig (a b) + (cond + ((and (eq (car-safe a) 'calcFunc-sin) + (eq (car-safe b) 'calcFunc-csc) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + 1) + ((and (eq (car-safe a) 'calcFunc-sin) + (eq (car-safe b) 'calcFunc-sec) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-tan (cdr a))) + ((and (eq (car-safe a) 'calcFunc-sin) + (eq (car-safe b) 'calcFunc-cot) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-cos (cdr a))) + ((and (eq (car-safe a) 'calcFunc-cos) + (eq (car-safe b) 'calcFunc-sec) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + 1) + ((and (eq (car-safe a) 'calcFunc-cos) + (eq (car-safe b) 'calcFunc-csc) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-cot (cdr a))) + ((and (eq (car-safe a) 'calcFunc-cos) + (eq (car-safe b) 'calcFunc-tan) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-sin (cdr a))) + ((and (eq (car-safe a) 'calcFunc-tan) + (eq (car-safe b) 'calcFunc-cot) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + 1) + ((and (eq (car-safe a) 'calcFunc-tan) + (eq (car-safe b) 'calcFunc-csc) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-sec (cdr a))) + ((and (eq (car-safe a) 'calcFunc-sec) + (eq (car-safe b) 'calcFunc-cot) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-csc (cdr a))) + ((and (eq (car-safe a) 'calcFunc-sinh) + (eq (car-safe b) 'calcFunc-csch) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + 1) + ((and (eq (car-safe a) 'calcFunc-sinh) + (eq (car-safe b) 'calcFunc-sech) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-tanh (cdr a))) + ((and (eq (car-safe a) 'calcFunc-sinh) + (eq (car-safe b) 'calcFunc-coth) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-cosh (cdr a))) + ((and (eq (car-safe a) 'calcFunc-cosh) + (eq (car-safe b) 'calcFunc-sech) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + 1) + ((and (eq (car-safe a) 'calcFunc-cosh) + (eq (car-safe b) 'calcFunc-csch) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-coth (cdr a))) + ((and (eq (car-safe a) 'calcFunc-cosh) + (eq (car-safe b) 'calcFunc-tanh) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-sinh (cdr a))) + ((and (eq (car-safe a) 'calcFunc-tanh) + (eq (car-safe b) 'calcFunc-coth) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + 1) + ((and (eq (car-safe a) 'calcFunc-tanh) + (eq (car-safe b) 'calcFunc-csch) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-sech (cdr a))) + ((and (eq (car-safe a) 'calcFunc-sech) + (eq (car-safe b) 'calcFunc-coth) + (= 0 (math-simplify (math-sub (cdr a) (cdr b))))) + (cons 'calcFunc-csch (cdr a))) + (t + nil))) + (defun math-mul-or-div (a b ainv binv) (if (or (Math-vectorp a) (Math-vectorp b)) (math-normalize @@ -2761,23 +3028,28 @@ (math-div a b) (math-mul a b))))) +;; The variable math-com-bterms is local to math-commutative-equal, +;; but is used by math-commutative collect, which is called by +;; math-commutative-equal. +(defvar math-com-bterms) + (defun math-commutative-equal (a b) (if (memq (car-safe a) '(+ -)) (and (memq (car-safe b) '(+ -)) - (let ((bterms nil) aterms p) + (let ((math-com-bterms nil) aterms p) (math-commutative-collect b nil) - (setq aterms bterms bterms nil) + (setq aterms math-com-bterms math-com-bterms nil) (math-commutative-collect a nil) - (and (= (length aterms) (length bterms)) + (and (= (length aterms) (length math-com-bterms)) (progn (while (and aterms (progn - (setq p bterms) + (setq p math-com-bterms) (while (and p (not (equal (car aterms) (car p)))) (setq p (cdr p))) p)) - (setq bterms (delq (car p) bterms) + (setq math-com-bterms (delq (car p) math-com-bterms) aterms (cdr aterms))) (not aterms))))) (equal a b))) @@ -2791,6 +3063,9 @@ (progn (math-commutative-collect (nth 1 b) neg) (math-commutative-collect (nth 2 b) (not neg))) - (setq bterms (cons (if neg (math-neg b) b) bterms))))) + (setq math-com-bterms (cons (if neg (math-neg b) b) math-com-bterms))))) +(provide 'calc-arith) + +;;; arch-tag: 6c396b5b-14c6-40ed-bb2a-7cc2e8111465 ;;; calc-arith.el ends here