$sum, dosum and simplifcation



I had a look at the function dosum in asum.lisp. This is an example to
show the problem:

(%i1) :lisp (let ((index '$i)) 
              (dosum (add (mul 2 index) (take '(%sin) index)) 
                     index 0 '$inf t))

((%SUM) ((MPLUS) ((MTIMES) 2 $I) ((%SIN) $I)) $I 0 $INF)

The simp flags are missing for all terms where the index is involved. In
this case we have no simpflags at all. This happens if we have a sum
which has to return a noun form. 

This seems to be no problem because an user calls the function $sum
which again resimplifies the whole expression, but the examples in
rtest_integrate have shown that we slow down the evaluation of sums
considerable if we call $sum from Lisp code to get correct simplified
expressions.

The problem is in the routine mevalsumargs. I have added some comments
to the lines of code:

...
;; Substitute a gensym for the index of the sum. Do not simplify.
(let (($simp nil))
  (setq summand ($substitute gensym-ind ind summand)))

;; Evaluate and resimplify the new expression. 
;; Remark: meval calls the simplifier too. Because we call resimplify
;; we go two times through the simplifer. Perhaps this can be improved.
(setq foo (mbinding ((list gensym-ind) (list gensym-ind))
                    (resimplify (meval summand))))

;; Substitute the original index back. At this point the simplification 
;; is switched off again. This causes problems. The expression no longer
;; has simp flags for expressions which contain the index of the 
;; summation.
(let (($simp nil))
  (setq foo ($substitute ind gensym-ind foo)))
...

If we do not switch off the simplification e.g. we do

(let (($simp t))
  (setq foo ($substitute ind gensym-ind foo)))

we get a correct simplified expression for the example from above:

(%i2) :lisp (let ((index '$i)) 
              (dosum (add (mul 2 index) (take '(%sin) index)) 
                     index 0 '$inf t))

((%SUM) ((MPLUS SIMP) ((MTIMES SIMP) 2 $I) ((%SIN SIMP) $I)) $I 0 $INF)

The simp flags are present as expected.

The testsuite has two examples in rtest9.mac, which do not work as
expected with the code we have. This is a copy from rtest9.mac:

/* The following test does not work as expected.
 * The product does not preserve the floating point number.
 * Therefore the following taylor expansion gives a result
 * in terms of rational numbers. We change the expected
 * result accordingly.
 */
product((x^i+1)^2.5,i,1,inf)/(x^2+1);
('product((x^i+1)^2.5,i,1,inf))/(x^2+1)$
ev(taylor(%,x,0,3),keepfloat);
/*1+2.5*x+3.375*x^2+6.5625*x^3$*/
1+5/2*x+27/8*x^2+105/16*x^3;

With the change to mevalsumarg this examples work as expected. The
product preserve the floating point number and the taylor expansion
gives a result in terms of floating point numbers:

(%i6) product((x^i+1)^2.5,i,1,inf)/(x^2+1);
(%o6) ('product((x^i+1)^2.5,i,1,inf))/(x^2+1)

(%i7) ev(taylor(%,x,0,3),keepfloat);
(%o7) 1+2.5*x+3.375*x^2+6.5625*x^3

I have got no problems with the testsuite and the share_testsuite.

By the way: All the code to evaluate, simplify, and resimplify the
summand of a sum seems to be quite tricky. Perhaps some more
improvements are possible.

Dieter Kaiser