Skip to content

Implement a "distribute" method #22937

Closed
Closed
@EmmanuelCharpentier

Description

@EmmanuelCharpentier

Motivation : some "obvious" transformations, sometimes helpful in routine calculations, cannot be obtained via the current methods. Some (elementary,
i. e. high-school- or undergrad-level) exemples : given the declarations :

var("a,b")
var("j,p", domain="integer")
f,g,X=function("f,g,X")

the following equalities, true under no or mild conditions, cannot be deduced currently :

sum(X(j)+Y(j),j,1,p)==sum(X(j),j,1,p)+sum(Y(j),j,1,p) ## (1)
prod(X(j)*Y(j),j,1,p)==prod(X(j),j,1,p)*prod(Y(j),j,1,p) ## (2)
integrate(f(x)+g(x),x,a,b)==integrate(f(x),x,a,b)+integrate(g(x),x,a,b) ## (3)

Similarly, if A, B and C are matrices over a suitable ring and of
suitable dimensions, the following equalities cannot be
straightforwardly obtained.

(A+B).trace()==A.trace()+B.trace() ## (4)
(A*B).det()==A.det()*B.det() ## (5)

(Curiously, (f(x)+g(x)).diff(x) does return
diff(f(x),x)+diff(g(x),x) (and a way to return to the original
expression does not seem to exist currently)).

The ability to generate the right-hand form from the left-hand form of
these various examples is sometimes useful in (low-level)
examples. The examples (1) and/or (2) arise naturally when deriving the
maximum-likelihood estimators of the mean and variance of a given
distribution. The third one is often encountered in elementary calculus
exercises.

In all cases, an operator is "distributed" over another one :
(1) : symbolic_sum is distributed over addition.
(2) : symbolic product is distributed over multiplication.
(3) : integration is ditributed over addition.
(4) : trace is distributed over (matrix) addition.
(5) : determinant is distributed over (matrix) multiplication.

Implementing (1) as an extension of the expand() method of
Expression is tempting (see #22915). However, there are situations
where this expansion is not useful. So, creating a method for such
situations seems useful.

One should note that such "distributions" are not systematically
valid : we have a collection of special cases rather than a general
mechanism. So this method shoud either limit itself to a few
recognized cases or take keyword argument(s) specifying what should be
distributed over what.

Another design choice is to know if these distributions should be
recursive or run only on the top level of a given expression
(possibly controlled by another keyword argument).

The present ticket aims at implementing this method for sage.symbolic.expression.Expression, at least in cases (1) to (3) (case (2) needs an implementation of the symbolic products, see #17505). Further suggestions for other classes are welcome...

Depends on #17505

Upstream: None of the above - read trac for reasoning.

CC: @rwst @tscrim

Component: symbolics

Author: Emmanuel Charpentier, Ralf Stephan

Branch: 7aee739

Reviewer: Travis Scrimshaw

Issue created by migration from https://trac.sagemath.org/ticket/22937

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions