This is now Trac#22915 <https://trac.sagemath.org/ticket/22915>, which 
needs discussion.

--
Emmanuel Charpentier

Le mercredi 26 avril 2017 08:35:30 UTC+2, Emmanuel Charpentier a écrit :
>
> 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 sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
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