Plus¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
x + y + ... or Plus[x, y, ...] represents a sum of terms. Plus is Flat, Orderless, OneIdentity, Listable, and NumericFunction: nested Plus is auto-flattened, terms are sorted into canonical order, like terms are combined, and integer arguments are summed exactly via GMP (with int64 fast path and BigInt overflow promotion).
Examples (14)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic examples (4)¶
In[1]:= 1 + 2 + x + 2*x
Out[1]= 3 + 3 x
In[2]:= a + b - (a + b)
Out[2]= 0
In[3]:= Interval[{1, 2}] + Interval[{-1, 3}]
Out[3]= Interval[{0, 5}]
In[4]:= NDArray[{1., 2., 3.}] + 10
Out[4]= NDArray[{11.0, 12.0, 13.0}]
Applications (10)¶
Integer overflow promotes to a bignum
Exact rationals reduce to an integer
Like terms collect
A negated sum is distributed so it cancels
An inexact summand numericalises the exact ones
Hash-based collection: 10^5 terms in linear time
Power series add through the series algebra
In[11]:= Series[Exp[x], {x, 0, 4}] + Series[Sin[x], {x, 0, 4}]
Out[11]= 1 + 2 x + 1/2 x^2 + 1/24 x^4 + O[x]^5
Interval arithmetic
Element-wise on the raw buffer, with scalar broadcasting
Indeterminate, with the Infinity::indet message
Implementation notes¶
Algorithm. Plus is Flat | Listable | NumericFunction | OneIdentity | Orderless | Protected, so the evaluator has already flattened nested sums and threaded over List arguments before builtin_plus runs. Plus[] is 0 and Plus[x] is x. The builtin then works in a fixed order. (1) Machine-integer fast path. When every argument is an int64, they are summed with overflow-checked ci_add_i64. On overflow it falls through, and the generic path promotes the sum to a GMP bigint. (2) algnum_plus_combine adds same-generator AlgebraicNumber terms in the number field, folding loose rationals in. (3) A single fused guard pass checks whether any argument is an NDArray, a -(...) sum, a SeriesData, an inexact number or an infinity. For an ordinary symbolic or rational sum, which is the common case, it jumps straight to term grouping. Otherwise the special passes run in order. NDArray operands add element-wise over raw buffers (ndarray_elementwise, which broadcasts numeric scalars); mismatched shapes give NDArray::shape and the sum stays unevaluated. Times[-1, Plus[...]] is distributed, so a + b - (a + b) cancels. SeriesData summands fold through series_combine_plus. Inexact contagion (numeric_contagion_args) numericalises the exact numeric parts, so 1. + Pi is 4.14159. Finally, Infinity and Indeterminate follow Mathematica's table: Infinity - Infinity and any ComplexInfinity clash give Infinity::indet and Indeterminate, and a finite part is absorbed by a real infinity. (4) Grouping. get_coeff_base splits each term into a numeric coefficient and a base. Bare numbers go to a running numeric total via add_numbers, which also handles Rational, bigint, Complex, MPFR and Interval (interval_add). Bases are collected through an open-addressing hash table keyed by expr_hash, and like coefficients are summed. (5) Reassembly. Zero groups are dropped, and each c·base is emitted as a flat Times, with the coefficient spliced in front of the base's factors (never Times[2, Times[a, b]]). The result is sorted with expr_orderless_sort only when an O(n) check finds it out of order.
Data structures. There is a TermGroup {base, coeff} array and a power-of-two open-addressing table (slot_group/slot_hash, at least 2n slots). For sums of at most 8 terms both live on the stack, as does the result vector, so a small Plus in a tight loop allocates nothing beyond its result. Overflow is propagated as Overflow[]. The packed and NDArray surfaces work through pack.c: Plus is on the AWARE and broadcast lists, so packed integer or real lists add without unpacking (Range[10^6] + Range[10^6] stays packed). Compile[] lowers Plus at scalar and array shapes, with overflow-checked integer arithmetic and real, complex and array arms (compile_infer.c, compile_emit_arith.c).
Complexity / limits. Like-term collection is O(n) expected, through the hash table plus one canonical sort of the collapsed terms only, so Plus @@ of 10^5 monomials does not pay an O(n²) scan or an O(n log n) sort of the raw input. Two caveats. A product times a sum, c (a + b), is not distributed, as in Mathematica. And like-term collection is purely structural, so Sin[x]^2 + Cos[x]^2 is left alone: that is Simplify's job.
Flat,Orderless,Listable.- Combines numeric constants and collects like terms (e.g.,
x + 2xbecomes3x). - Like-term collection is hash-based (O(N) expected) and canonically sorts only
the collapsed result, so a large flat sum (e.g.
Totalof 10^5 monomials) does not pay the genericOrderlesssort over all N raw terms.Timescollects factors the same way. - A collected term is a flat
Times:2 a b + xholdsTimes[2, a, b], neverTimes[2, Times[a, b]]. The coefficient is spliced in front of the monomial's factors. - Returns
0if no arguments are provided. - Returns
Overflow[]if integer addition overflows or if any argument isOverflow[]. - A finite term plus a real
±Infinityabsorbs the finite part (Infinity + 3 → Infinity), but a finite term plus a directed (complex) infinity keeps its direction rather than collapsing to a realInfinity:1/2 - I InfinitystaysPlus[1/2, Times[Complex[0, -1], Infinity]](so a Mellin–Barnes / Bromwich vertical lines = c ± I Infinityremains recognisable toIntegrate).
Attributes: Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected.
References¶
See also: Flat, Orderless, Total, Times, Integrate
- Knuth, "The Art of Computer Programming, Vol. 2: Seminumerical Algorithms", on arbitrary-precision integer addition.
- Geddes, Czapor & Labahn, "Algorithms for Computer Algebra" (1992), on normal forms for sums.
- Source:
src/plus.c - Specification:
docs/spec/builtins/arithmetic.md - Tests:
tests/test_assoc_ops.c - Tests:
tests/test_association.c - Tests:
tests/test_bigint.c - Tests:
tests/test_characteristicpolynomial.c
Notes & additional examples¶
Notes¶
PlusisFlat,Listable,NumericFunction,OneIdentity,OrderlessandProtected.Plus[]is0andPlus[x]isx.- Like terms are collected structurally, by an exact match of the non-numeric part, through a hash table. The result is canonically sorted, and only when it is out of order. A collected term is a flat
Times, so2 a bisTimes[2, a, b]. - A sum is not distributed over a product (
c (a + b)stays as it is), and no algebraic identities are applied:Sin[x]^2 + Cos[x]^2needsSimplify. - Integer sums overflow into GMP bignums. An inexact summand makes the whole numeric part inexact (
1. + Pi), at the lowest precision present. - Infinities follow Mathematica: a real infinity absorbs finite terms;
Infinity - InfinityandComplexInfinity + ComplexInfinitygiveIndeterminatewithInfinity::indet. A directed complex infinity keeps its direction. - Numeric surfaces. Packed lists add without unpacking, NDArrays add element-wise with scalar broadcasting (mismatched shapes give
NDArray::shapeand the sum stays unevaluated), andCompile[]lowersPlusfor integer, real, complex and array arguments. - See also:
Total,Times,Subtract,Accumulate.