Sage can (awkwardly) do some simplifications of symbolic sums. For example

sage: var("j,p", domain="integer")
(j, p)
sage: X,Y=function("X,Y")
sage: (sum(X(j),j,1,p)+sum(Y(j),j,1,p)).maxima_methods().sumcontract()
sum(X(j) + Y(j), j, 1, p)

but, to the best of my (limited) knowledge, the reverse operation, useful 
in sime situations (trivial example : derive maximum likelihood estimators 
of the parameters of some distributions) is not possible (in other words, 
sum does not distribute over +).

The needed function can be written in Sage :

def expand_sum(ex):
    ## Only way I found to denote the needed operator constants
    def init_consts():
        a=function("a")
        b,c,d=SR.var("b,c,d")
        op_sum=sum(a(b),b,c,d).operator()
        op_add=(c-b).operator()
        return(op_sum,op_add)
    ## Build a term of the result
    def treat_term(term,loopargs):
        L=copy(loopargs) ## Copy is needed, under penalty of side effects !!
        L.insert(0,term)
        return(apply(sum,L))
    op_sum,op_add=init_consts()
    if ex.parent() is not SR:return(ex)
    op=ex.operator()
    largs=ex.operands()
    if op is None:return(ex)
    if op is op_sum:
        fa=largs[0]
        op1=fa.operator()
        if op1 is op_add:
            ra=largs[1:]    # index variable and bounds
            return(sum(map(lambda t:treat_term(expand_sum(t),ra),
                           fa.operands())))
    ## Default case : recurse to ex arguments
    return(apply(op, map(expand_sum, largs)))

It can also be written in Maxima (or in lisp) and used via one of the 
Maxima interfaces :

expand_sum(ex):=block([sum_op,add_op,a,b,c,d],
  sum_op:op(sum(a(b),b,c,d)),
  add_op:op(c-b),
  if atom(ex)
  then ex
  else block([op1:op(ex), largs:args(ex)],
    if equal(op1,sum_op)
    and not(atom(largs[1]))
    and equal(op(args(ex)[1]), add_op)
    then block([fa:first(largs), ra:rest(largs), lres,z],
      lres:map(lambda([t],apply(sum,append([expand_sum(t)],ra))), args(fa)),
      lsum(z,z,lres))
    else apply(op1, map(expand_sum, largs))));

Both versions allow the needed expansion. In Sage :

sage: load("/home/charpent/Feuilles Sage brutes/expand_sum.sage")
sage: expand_sum(sum(X(j)+Y(j),j,1,p))
sum(X(j), j, 1, p) + sum(Y(j), j, 1, p)

(the Maxima version also works (not shown)). Hence a few questions :

   1. Did I oversee an existing way to do this ?
   2. Is that a worthwile addition to Sage ?
   3. Should it be implemented in Sage (probably as a method for SR), or 
   via Maxima (like other sum functions) ?
   4. Should this be a special case of the expand() method ?
   5. Are there possible improvements (I think so : for example, I have 
   been unable to find the "right" designation of the operators : op_sum 
   might be sage.functions.other.symbolic_sum, but I found nothing usable 
   for op_add, hence the ridiculous re-computation of these constants at 
   each call...).


Sincerely,

--
Emmanuel Charpentier

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.

Reply via email to