I had a look at the implementation of simplifications for expressions
like exp(x*%i*%pi) where x is an arbitrary expression.
With revision 1.88 of simp.lisp the call of %especial has been disabled
for x a float or bigfloat value to avoid curious results. But %especial
can do a lot of more general simplifications. Unfortunately, these have
been disabled too (my error).
Some simplifications of %especial are problematic, e.g.
exp((2+x)^2*%pi*%i) -> %e^(%i*%pi*(x+2)^2-4*%i*%pi)
exp((2+x)^10*%pi*%i) -> %e^(%i*%pi*(x+2)^10-1024*%i*%pi)
Now the handling of expressions is inconsistent, e.g. the following is
simplified
exp((2+x)*%i*%pi) -> exp(%i*%pi*x)
but not the expanded form
exp(2*%i*%pi%+%i*%pi*x) -> e^(%i*%pi*x+2*%i*%pi)
Furthermore, we have inconsistent simplifications of expressions which
contain float or bigfloat values.
The following shows some examples of a testfile to check the
simplification of expressions like exp(x*%pi*%) and the desired results:
********************** Problem 5 ***************
Input:
exp(2*%i*%pi)
Result:
1
... Which was correct.
********************** Problem 6 ***************
Input:
exp((x+2)*%i*%pi)
Result:
%e^(%i*%pi*x)
... Which was correct.
********************** Problem 7 ***************
Input:
exp(x*%i*%pi+2*%i*%pi)
Result:
%e^(%i*%pi*x+2*%i*%pi)
This differed from the expected result:
exp(x*%i*%pi)
********************** Problem 8 ***************
Input:
log(exp((x+2)^2*%i*%pi))
Result:
%i*%pi*(x+2)^2-4*%i*%pi
This differed from the expected result:
(x+2)^2*%i*%pi
********************** Problem 9 ***************
Input:
exp(2.0*%i*%pi)
Result:
%e^(2.0*%i*%pi)
This differed from the expected result:
1.0
********************** Problem 10 ***************
Input:
exp((x+2.0)*%i*%pi)
Result:
%e^(%i*%pi*x)
This differed from the expected result:
exp(1.0*x*%i*%pi)
********************** Problem 11 ***************
Input:
exp(x*%i*%pi+2.0*%i*%pi)
Result:
%e^(%i*%pi*x+2.0*%i*%pi)
This differed from the expected result:
exp(1.0*x*%i*%pi)
********************** Problem 12 ***************
Input:
log(exp((x+2.0)^2*%i*%pi))
Result:
%i*%pi*(x+2.0)^2-4*%i*%pi
This differed from the expected result:
(x+2.0)^2*%i*%pi
********************** Problem 13 ***************
Input:
exp(2.0b0*%i*%pi)
Result:
%e^(2.0b0*%i*%pi)
This differed from the expected result:
1.0b0
********************** Problem 14 ***************
Input:
exp((x+2.0b0)*%i*%pi)
Result:
%e^(%i*%pi*x)
This differed from the expected result:
exp(1.0b0*x*%i*%pi)
********************** Problem 15 ***************
Input:
exp(x*%i*%pi+2.0b0*%i*%pi)
Result:
%e^(%i*%pi*x+2.0b0*%i*%pi)
This differed from the expected result:
exp(1.0b0*x*%i*%pi)
********************** Problem 16 ***************
Input:
log(exp((x+2.0b0)^2*%i*%pi))
Result:
%i*%pi*(x+2.0b0)^2-4*%i*%pi
This differed from the expected result:
(x+2.0b0)^2*%i*%pi
********************** Problem 17 ***************
Input:
exp(3*%pi*%i/2)
Result:
-%i
... Which was correct.
********************** Problem 18 ***************
Input:
exp(1.5*%pi*%i)
Result:
%e^(1.5*%i*%pi)
This differed from the expected result:
-1.0*%i
********************** Problem 19 ***************
Input:
exp(1.5b0*%pi*%i)
Result:
%e^(1.5b0*%i*%pi)
This differed from the expected result:
-1.0b0*%i
********************** Problem 20 ***************
Input:
exp((x+3/2)*%pi*%i)
Result:
-%i*%e^(%i*%pi*x)
... Which was correct.
********************** Problem 21 ***************
Input:
exp((x+1.5)*%pi*%i)
Result:
-%i*%e^(%i*%pi*x)
This differed from the expected result:
-%i*exp(1.0*%i*%pi*x)
********************** Problem 22 ***************
Input:
exp((x+1.5b0)*%pi*%i)
Result:
-%i*%e^(%i*%pi*x)
This differed from the expected result:
-%i*exp(1.0b0*%i*%pi*x)
To get all desired simplifications we have to modify the routine %
especial. This could be the new code:
(defun %especial (e)
(prog (varlist y k kk j ans $%emode $ratprint genvar)
(let ()
(unless (setq y (pip ($ratcoef e '$%i))) (return nil))
;; Subtract the term y*%i*%pi from the expression e.
(setq k ($expand (add e (mul -1 '$%pi '$%i y)) 1))
;; This is a workaround to get the type (integer, float, or
bigfloat)
;; of the expression. kk must evaluate to 1, 1.0, or 1.0b0.
;; Furthermore, if e is nonlinear, kk does not simplify to a
number ONE.
;; Because of this we do not simplify something like exp((2+x)^2*
%i*%pi)
(setq kk (div (sub ($expand e) k) (mul '$%i '$%pi y)))
;; Return if kk is not an integer or kk is ONE, but y not an
integer
;; or a half integral value.
(if (not (or (integerp kk)
(and (onep1 kk)
(integerp (add y y)))))
(return nil))
(setq j (trigred y))
(setq ans (spang1 j t)))
(cond ((among '%sin ans)
(cond ((equal y j) (return nil))
((zerop1 k)
;; To preverse the type we add k into the expression.
(return (power '$%e (mul %p%i (add k j)))))
(t
;; To preserve the type we multiply kk into the
result.
(return (power '$%e (add (mul kk k) (mul kk %p%i
j))))))))
(setq y (spang1 j nil))
;; To preserve the type we multiply kk into the expression.
(return (mul (power '$%e (mul kk k)) (add y (mul '$%i ans))))))
Dieter Kaiser