Source code for m4opt.utils.sympy
"""Symbolic algebra utilities for SymPy."""
from collections.abc import Collection
from sympy import Add, Basic, Expr
from .functional import groupby_unsorted
__all__ = ("collect_dependence",)
[docs]
def collect_dependence(
expr: Expr, symbols: Collection[Basic]
) -> dict[tuple[Basic, ...], Basic]:
"""
Collect terms in an expression that depend on like combinations of symbols.
Examples
--------
>>> from m4opt.utils.sympy import collect_dependence
>>> from sympy.abc import a, b, c
>>> from sympy import sin, Symbol
>>> symbols = [a, b, c]
>>> expr = a + b + c
>>> collect_dependence(expr, symbols)
{(c,): c, (b,): b, (a,): a}
>>> expr = 42 + a * (sin(a) + sin(b)) + b * (b + c) + c
>>> collect_dependence(expr, symbols)
{(): 42, (c,): c, (b,): b**2, (b, c): b*c, (a,): a*sin(a), (a, b): a*sin(b)}
"""
def depends_on(term: Basic):
return tuple(term.has(symbol) for symbol in symbols)
return {
tuple(symbol for keep, symbol in zip(key, symbols) if keep): Add(*terms)
for key, terms in groupby_unsorted(
expr.expand().as_ordered_terms(), key=depends_on
)
}