Skip to content

Sum, Product with integer bounds: add the terms, do not go through SymPy - #2012

Merged
rocky merged 2 commits into
Mathics3:masterfrom
tombouctou:fix-sum-integer-bounds
Oct 16, 2026
Merged

rocky merged 2 commits into
Mathics3:masterfrom
tombouctou:fix-sum-integer-bounds

Conversation

@tombouctou

Copy link
Copy Markdown
Collaborator

Sum and Product with integer bounds now add (or multiply) the terms directly. SymPy is used only when the bounds are not integers.

Before this change, IterationFunction.eval_iter sent every Sum/Product with step 1 through SymPy. The summand was converted to SymPy, the terms were evaluated by Mathics3, the result was converted to SymPy again, put through Together, converted back to Mathics3 and then put through Cancel. With integer bounds, all that is needed is to evaluate the terms and add them, as Table does. When the terms are large symbolic expressions, the round trip costs far more than the sum itself.

In[1]:= Sum[1/(x + i), {i, 1, 2}]
master:  (3 + 2 x) / ((1 + x) (2 + x))
branch:  1 / (1 + x) + 1 / (2 + x)

The new form is, as far as I can tell, also what WMA returns: it does not put an explicit finite sum over a common denominator. Symbolic bounds (Sum[i, {i, 1, n}]) and infinite sums go through SymPy as before.

Tests: test_sum_product_bounds in test/builtin/test_arithmetic.py. The full pytest suite and doctests pass.

Context: we found this while profiling the lambda-algebra homology computation from the Toda-bracket project we are running on Mathics3 (see #2001). In that workload, SymPy conversion inside Sum took about 40% of the profile on small cases. Adding the terms is itself costly, though, so on the same core the end-to-end gain is a few percent.

🤖 Generated with Claude Code

With step 1, IterationFunction.eval_iter always converted Sum/Product to
SymPy: the summand was converted, the terms were evaluated by Mathics3,
the result converted to SymPy again, then Together, back to Mathics3 and
Cancel.  For integer bounds all that is needed is to evaluate the terms
and add them, as Table does, and the round trip costs far more than the
sum itself when the terms are large symbolic expressions.

Now SymPy is used only when the bounds are not integers.  A sum of
rational functions with integer bounds is no longer put over a common
denominator: Sum[1/(x + i), {i, 1, 2}] gives 1/(1 + x) + 1/(2 + x).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mmatera

mmatera commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

LGTM

@rocky

rocky commented Oct 16, 2026

Copy link
Copy Markdown
Member

Thanks for profiling and fixing this!

@rocky
rocky merged commit 7fad934 into Mathics3:master Oct 16, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants