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 [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.