From: Dieter K. <cra...@us...> - 2011-04-25 14:20:57
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Maxima, A Computer Algebra System". The branch, master has been updated via 6211ffd0300c0cf1f9b4aeaeebeb0b9608f9619c (commit) via 7ec68513b157f06c24a51c5fb37e98cd315207f6 (commit) from 040bace13aca54cff6980c9827d507f6dc8dac22 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6211ffd0300c0cf1f9b4aeaeebeb0b9608f9619c Author: crategus <cra...@us...> Date: Mon Apr 25 15:46:07 2011 +0200 Adding tests related to bug ID: 3247367 - expand returns unsimplified diff --git a/tests/rtest16.mac b/tests/rtest16.mac index eb30fff..4f0a03e 100644 --- a/tests/rtest16.mac +++ b/tests/rtest16.mac @@ -1953,3 +1953,107 @@ arrayinfo(a); reset(use_fast_arrays); [use_fast_arrays]; +kill(a); +done; + +/* Bug ID: 3247367 - expand returns unsimplified + */ +sqrt(2)+sqrt(2); +2^(3/2); +sqrt(2)+sqrt(2)+sqrt(2); +3*sqrt(2); +sqrt(2)+sqrt(2)+sqrt(2)+sqrt(2); +2^(5/2); +sqrt(2)+sqrt(2)+sqrt(2)+sqrt(2)+sqrt(2); +5*sqrt(2); + +2*sqrt(2)+3*sqrt(2); +5*sqrt(2); +3*sqrt(2)+2*sqrt(2); +5*sqrt(2); +3*sqrt(2)+2*sqrt(2)+sqrt(2); +3*2^(3/2); +sqrt(2)+3*sqrt(2)+2*sqrt(2); +3*2^(3/2); + +sqrt(1/2)+sqrt(1/2); +sqrt(2); +sqrt(1/2)+sqrt(1/2)+sqrt(1/2); +3/sqrt(2); +sqrt(1/2)+sqrt(1/2)+sqrt(1/2)+sqrt(1/2); +2^(3/2); +sqrt(1/2)+sqrt(1/2)+sqrt(1/2)+sqrt(1/2)+sqrt(1/2); +5/sqrt(2); + +2*sqrt(1/2)+3*sqrt(1/2); +5/sqrt(2); +3*sqrt(1/2)+2*sqrt(1/2); +5/sqrt(2); +3*sqrt(1/2)+2*sqrt(1/2)+sqrt(1/2); +3*sqrt(2); +sqrt(1/2)+3*sqrt(1/2)+2*sqrt(1/2); +3*sqrt(2); + +2^(1/5)+2^(1/5); +2^(6/5); +2^(1/5)+2^(1/5)+2^(1/5); +3*2^(1/5); +2^(1/5)+2^(1/5)+2^(1/5)+2^(1/5); +2^(11/5); +2^(1/5)+2^(1/5)+2^(1/5)+2^(1/5)+2^(1/5); +5*2^(1/5); + +(1/2)^(1/5)+(1/2)^(1/5); +2^(4/5); +(1/2)^(1/5)+(1/2)^(1/5)+(1/2)^(1/5); +3/2^(1/5); +(1/2)^(1/5)+(1/2)^(1/5)+(1/2)^(1/5)+(1/2)^(1/5); +2^(9/5); +(1/2)^(1/5)+(1/2)^(1/5)+(1/2)^(1/5)+(1/2)^(1/5)+(1/2)^(1/5); +5/2^(1/5); + +2*(1/2)^(1/5)+3*(1/2)^(1/5); +5/2^(1/5); +3*(1/2)^(1/5)+2*(1/2)^(1/5); +5/2^(1/5); + +2^sin(x)+2^sin(x); +2^(sin(x)+1); +2^sin(x)+2^sin(x)+2^sin(x); +3*2^sin(x); +2^sin(x)+2^sin(x)+2^sin(x)+2^sin(x); +2^(sin(x)+2); +2^sin(x)+2^sin(x)+2^sin(x)+2^sin(x)+2^sin(x); +5*2^sin(x); + +(1/2)^sin(x)+(1/2)^sin(x); +2^(1-sin(x)); +(1/2)^sin(x)+(1/2)^sin(x)+(1/2)^sin(x); +3/2^sin(x); +(1/2)^sin(x)+(1/2)^sin(x)+(1/2)^sin(x)+(1/2)^sin(x); +2^(2-sin(x)); +(1/2)^sin(x)+(1/2)^sin(x)+(1/2)^sin(x)+(1/2)^sin(x)+(1/2)^sin(x); +5/2^sin(x); + +(1-sqrt(5))^3-4*(1-sqrt(5))^2+8, expand; +0; +1/sqrt(2)+1/sqrt(2)+1/sqrt(2); +3/sqrt(2); +2^(9/5)+2^(4/5); +3*2^(4/5); +3*sqrt(2)+2*sqrt(2); +5*sqrt(2); +2*sqrt(2)+3*sqrt(2); +5*sqrt(2); +(1-sqrt(5))^3, expand; +16-8*sqrt(5); +p : z^3-2^(3/2)*%i*z^2-4*z^2+2^(5/2)*%i*z+2*z; +z^3-2^(3/2)*%i*z^2-4*z^2+2^(5/2)*%i*z+2*z; +divide(p, (z-2-sqrt(2)*%i),z); +[z^2+(-sqrt(2)*%i-2)*z,0]; +2^a + 3*2^(a+1); +7*2^a; +2^(3/5)+2^(-2/5); +3/2^(2/5); +2^(3/5+x)+2^(-2/5+x); +3*2^(x-2/5); commit 7ec68513b157f06c24a51c5fb37e98cd315207f6 Author: crategus <cra...@us...> Date: Mon Apr 25 15:45:15 2011 +0200 Implement the simplification of v*a^(c+n)+w*a^(c+m) The expressions simplifies to (v*a^n+w*a^m)*a^c where a, v, w, and (n-m) are integers. 1. n and m are integers: The result is (v*a^n+w*a^m)*a^c. 2. n and m are rational numbers: The difference n-m is an integer. The rational numbers might be improper fractions. The mixed numbers are: n = n1 + d1/r and m = n2 + d2/r, where r is the common denominator. We have two cases: I) d1 = d2: e.g. 2^(1/3+c)+2^(4/3+c) The result is (v*a^n1+w*a^n2)*a^(c+d1/r) II) d1 # d2: e.g. 2^(1/2+c)+2^(-1/2+c) In this case one of the exponents d1 or d2 must be negative. The negative exponent is factored out. This guarantees that the factor (v*a^n1+w*a^n2) is an integer. But the positive exponent has to be adjusted accordingly. E.g. when we factor out a^(d2/r) because d2 is negative, then we have to adjust the positive exponent to n1 -> n1+(d1-d2)/r. Remark: Part of the simplification is done in simptimes. E.g. this algorithm simplifies the sum sqrt(2)+3*sqrt(2) to 4*sqrt(2). In simptimes this is further simplified to 2^(5/2). Related bug report: ID: 3247367 - expand returns unsimplified diff --git a/src/simp.lisp b/src/simp.lisp index 5c1dccc..111e295 100644 --- a/src/simp.lisp +++ b/src/simp.lisp @@ -1178,8 +1178,9 @@ ;;;----------------------------------------------------------------------------- (defun plusin (x fm) - (prog (x1 flag check w xnew) + (prog (x1 x2 flag check v w xnew a n m c) (setq w 1) + (setq v 1) (cond ((mtimesp x) (setq check x) (if (mnump (cadr x)) (setq w (cadr x) x (cddr x)) @@ -1189,6 +1190,96 @@ xnew (list* '(mtimes) w x)) start (cond ((null (cdr fm))) + ((and (alike1 x1 (cadr fm)) (null (cdr x))) + (go equ)) + ;; Implement the simplification of + ;; v*a^(c+n)+w*a^(c+m) -> (v*a^n+w*a^m)*a^c + ;; where a, v, w, and (n-m) are integers. + ((and (or (mexptp (setq x2 (cadr fm))) + (and (mtimesp x2) + (not (alike1 x1 x2)) + (null (cadddr x2)) + (integerp (setq v (cadr x2))) + (mexptp (setq x2 (caddr x2))))) + (integerp (setq a (cadr x2))) + (mexptp x1) + (equal a (cadr x1)) + (integerp (sub (caddr x2) (caddr x1)))) + (setq n (if (and (mplusp (caddr x2)) + (mnump (cadr (caddr x2)))) + (cadr (caddr x2)) + (if (mnump (caddr x2)) + (caddr x2) + 0))) + (setq m (if (and (mplusp (caddr x1)) + (mnump (cadr (caddr x1)))) + (cadr (caddr x1)) + (if (mnump (caddr x1)) + (caddr x1) + 0))) + (setq c (sub (caddr x2) n)) + (cond ((integerp n) + ;; The simple case: + ;; n and m are integers and the result is (v*a^n+w*a^m)*a^c. + (setq x1 (mul (addk (timesk v (exptb a n)) + (timesk w (exptb a m))) + (power a c))) + (go equt2)) + (t + ;; n and m are rational numbers: The difference n-m is an + ;; integer. The rational numbers might be improper fractions. + ;; The mixed numbers are: n = n1 + d1/r and m = n2 + d2/r, + ;; where r is the common denominator. We have two cases: + ;; I) d1 = d2: e.g. 2^(1/3+c)+2^(4/3+c) + ;; The result is (v*a^n1+w*a^n2)*a^(c+d1/r) + ;; II) d1 # d2: e.g. 2^(1/2+c)+2^(-1/2+c) + ;; In this case one of the exponents d1 or d2 must + ;; be negative. The negative exponent is factored out. + ;; This guarantees that the factor (v*a^n1+w*a^n2) + ;; is an integer. But the positive exponent has to be + ;; adjusted accordingly. E.g. when we factor out + ;; a^(d2/r) because d2 is negative, then we have to + ;; adjust the positive exponent to n1 -> n1+(d1-d2)/r. + ;; Remark: + ;; Part of the simplification is done in simptimes. E.g. + ;; this algorithm simplifies the sum sqrt(2)+3*sqrt(2) + ;; to 4*sqrt(2). In simptimes this is further simplified + ;; to 2^(5/2). + (multiple-value-bind (n1 d1) + (truncate (num1 n) (denom1 n)) + (multiple-value-bind (n2 d2) + (truncate (num1 m) (denom1 m)) + (cond ((equal d1 d2) + ;; Case I: -> (v*a^n1+w*a^n2)*a^(c+d1/r) + (setq x1 + (mul (addk (timesk v (exptb a n1)) + (timesk w (exptb a n2))) + (power a + (add c + (div d1 (denom1 n)))))) + (go equt2)) + ((minusp d2) + ;; Case II:: d2 is negative, adjust n1. + (setq n1 (add n1 (div (sub d1 d2) (denom1 n)))) + (setq x1 + (mul (addk (timesk v (exptb a n1)) + (timesk w (exptb a n2))) + (power a + (add c + (div d2 (denom1 n)))))) + (go equt2)) + ((minusp d1) + ;; Case II: d1 is negative, adjust n2. + (setq n2 (add n2 (div (sub d2 d1) (denom1 n)))) + (setq x1 + (mul (addk (timesk v (exptb a n1)) + (timesk w (exptb a n2))) + (power a + (add c + (div d1 (denom1 n)))))) + (go equt2)) + ;; This clause should never be reached. + (t (merror "Internal error in simplus.")))))))) ((mtimesp (cadr fm)) (cond ((alike1 x1 (cadr fm)) (go equt)) @@ -1196,8 +1287,6 @@ (setq flag t) ; found common factor (go equt)) ((great xnew (cadr fm)) (go gr)))) - ((and (alike1 x1 (cadr fm)) (null (cdr x))) - (go equ)) ((great x1 (cadr fm)) (go gr))) (setq xnew (eqtest (testt xnew) (or check '((foo))))) (return (cdr (rplacd fm (cons xnew (cdr fm))))) @@ -1234,6 +1323,7 @@ equt ;; Call muln to get a simplified product. (setq x1 (muln (cons (addk w (if flag (cadadr fm) 1)) x) t)) + equt2 (rplaca (cdr fm) (if (zerop1 x1) (list* '(mtimes) x1 x) ----------------------------------------------------------------------- Summary of changes: src/simp.lisp | 96 +++++++++++++++++++++++++++++++++++++++++++++++-- tests/rtest16.mac | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 3 deletions(-) hooks/post-receive -- Maxima, A Computer Algebra System |