Together¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
Together[expr] combines fractions over a common denominator, then cancels.
Option Extension -> alpha runs the final cancellation over Q(alpha) so
algebraic-coefficient simplifications fire (e.g. 1/(x-Sqrt[2]) + 1/(x+Sqrt[2])
collapses to (2 x)/(x^2 - 2) under Extension -> Sqrt[2]).
Default Extension -> None combines and cancels over the rationals only.
Examples¶
All examples below are verified against the current Mathilda build.
In[1]:= Together[a/b + c/d]
Out[1]= (b c + a d)/(b d)
In[2]:= Together[x^2/(x^2 - 1) + x/(x^2 - 1)]
Out[2]= x/(-1 + x)
In[3]:= Together[1/x + 1/(x + 1) + 1/(x + 2) + 1/(x + 3)]
Out[3]= (6 + 22 x + 18 x^2 + 4 x^3)/(6 x + 11 x^2 + 6 x^3 + x^4)
In[4]:= Together[x^2/(x - y) - x y/(x - y)]
Out[4]= x
In[5]:= Together[y^(5/8)*(y^(19/8) - y^(73/24)/(y^(2/3) - 1/y^(1/3)))]
Out[5]= -y^3/(-1 + y)
In[6]:= Together[1/(x - Sqrt[2]) + 1/(x + Sqrt[2]), Extension -> Sqrt[2]]
Out[6]= (2 x)/(-2 + x^2)
Implementation notes¶
Algorithm. builtin_together is a FactorMemo-keyed memoisation wrapper around builtin_together_compute, so repeated Together[arg, opts] calls issued during one Simplify (which pushes a FactorMemo) hit the cache; standalone calls see no overhead. The compute routine puts everything over a common denominator and cancels.
The core walker together_recursive recurses structurally. For a Plus[t_1, ..., t_n] it first togethers each summand, splits each into numerator/denominator via extract_num_den, computes the iterated PolynomialLCM of the denominators, then for each term forms lcm_den / den_i using cancel_exact_div_strict (exact polynomial division in Q[vars]) — a strict combine: if any quotient is not exact (a sign that PolynomialLCM was only valid in some algebraic-extension ring, e.g. multi-radical sums), it bails cleanly and leaves the Plus uncombined rather than risk the Power[Plus[...], -1]-inside-numerator GCD blowup. When all quotients are exact, it sums the rescaled numerators, multiplies by Power[lcm_den, -1], and runs cancel_recursive (PolynomialGCD-based cancellation) on the result. List/relational/logical heads thread through their args; other heads recurse and then cancel.
Crucially, together_recursive never expands Power[Plus[...], n] — extract_num_den only splits products, powers (pushing negative integer/rational exponents into the denominator), exponentials, complexes, and literal rationals; expansion is left to downstream poly-GCD with size gates. builtin_together_compute additionally handles Extension -> α (and Extension -> Automatic, which calls extension_autodetect): single-generator extensions route through together_recursive_ext over Q(α)[x]; multi-generator towers route through qa_cancel_with_tower, with nested-radical α prefiltered out and a "best generator" guided fallback (pick_best_tower_generator) gated on leaf count. A poly_find_radical_gen pass substitutes a radical generator to a fresh symbol, runs the no-extension path, and substitutes back. Inexact inputs are rationalised then re-numericalised (internal_rationalize_then_numericalize).
Data structures. Expr* trees; numerator/denominator pairs are plain Expr* out-parameters. Extension towers are QATower; exact division and LCM run on the multivariate-polynomial representation behind exact_poly_div / PolynomialLCM / PolynomialGCD. Numerator carries ATTR_LISTABLE.
Complexity / limits. Bounded by the polynomial GCD/LCM machinery on the combined fraction. The strict-quotient gate and the leaf-count gates are deliberate safeguards against multivariate-Euclid runaway on multi-radical / algebraic-extension inputs.
Protected,Listable.- Makes a sum of terms into a single rational function.
- Computes lowest common multiples (LCM) of denominators securely without unconditionally destroying pre-factored bases unnecessarily.
- Handles a single symbolic base appearing with rational fractional exponents (e.g.
y^(1/3),y^(2/3),y^(73/24)) by treating it as an algebraic generator: substitutesy -> g^mwheremis the LCM of denominators, runs the polynomial pipeline ing, then substitutes back. - Option
Extension -> alpha(Phase 0 of the Integrate plan) combines into a single fraction with the standard combiner, then runsCancel[..., Extension -> alpha]on the result so algebraic-coefficient cancellations fire. Effective on simple inputs like1/(x - Sqrt[2]) + 1/(x + Sqrt[2]), which collapses to(2 x)/(x^2 - 2). Inputs whose summands themselves carry algebraic-coefficient denominators are deferred to Phase 0.5 (which will plumbExtensionthroughPolynomialLCM/PolynomialQuotient/together_recursive). - Option
Extension -> Automaticwith polynomial radicands (Phase E, 2026-05-25): when the input contains exactly one distinct radicalSqrt[poly]orPower[poly, 1/q]whose radicand is a polynomial in free symbols (e.g.Sqrt[p+q],Power[1+x^2, 1/3]),qa_cancel_with_poly_radicalsubstitutes the radical with a fresh symbolS, runsTogether, reduces the numerator and denominator moduloS^q - polyviaPolynomialRemainder, optionally rationalises viaPolynomialExtendedGCD(when it shrinks the result), and substitutes back. Sample collapses:Together[1/(x - Sqrt[p+q]) + 1/(x + Sqrt[p+q]), Extension -> Automatic]returns(2 x)/(-p - q + x^2);Cancel[(x^2 - (p+q))/(x - Sqrt[p+q]), Extension -> Automatic]returnsSqrt[p+q] + x. Multi-radical inputs (Cardano-style conjugate pairs) are rejected; the deeper limitation is documented indocs/spec/changelog/2026-05-25.md.
Attributes: Listable, Protected.
Implementation status¶
Stable — documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
References¶
- Geddes, Czapor & Labahn, "Algorithms for Computer Algebra" (1992), on rational function arithmetic and common denominators.
- von zur Gathen & Gerhard, "Modern Computer Algebra", on polynomial GCDs used in cancellation.
- Source:
src/rat.c - Specification:
docs/spec/builtins/algebra.md
Notes & additional examples¶
Worked examples¶
A telescoping sum collapses completely, with the GCD machinery cancelling the
common factor so the result is an exact 1:
Common factors hidden across a factorable denominator are detected and removed:
Notes¶
Together combines a sum of fractions over a single common denominator, the inverse
operation of Apart. It computes the least common denominator and cancels common
polynomial factors via GCD, so 1/(x-1) + 1/(x+1) collapses to (2 x)/(x^2-1)
with the cross terms cleared. Distinct symbolic denominators are simply multiplied,
giving (b c + a d)/(b d) for a/b + c/d. Unlike a raw expansion, Together keeps
the denominator factored where possible and does not multiply out Power[Plus, n]
factors unnecessarily.