Skip to content

A register of function names, by what a mathematician calls each #2182

Open

Description

@Rafael-SOWNet

The names and conventions of functions the library does not have yet, fixed before any of them is implemented, so that they land in any order without being argued again. This replaces a first version that copied an older table and its rule that SymPy's spelling wins. That rule gave lambertw beside zeta, and SymPy's cryptic ff and rf.

The rule

  1. A function is named by what a mathematician calls it. That is its Wikipedia article and MathWorld entry, in lower case, without spaces or the word "function": lambertw (Lambert W function), harmonicnumber, doublefactorial, fallingfactorial.
  2. Where mathematicians call a function by its standard symbol alone, the symbol's name is used: zeta (ζ), beta (B). This is how gamma (Γ) and erf are already named. Where mathematics writes an operator rather than a function, the operator is the spelling: the double factorial is the postfix n!!, as the factorial is n!, and congruence is a = b (mod n).
  3. A name that already means something else in mathematics is not used.
    • div is the divergence, so the integer quotient is quotient.
    • delta is Kronecker's and Dirac's, so the forward difference is forwarddifference.
    • catalan alone is also Catalan's constant, and harmonic also the harmonic mean, so catalannumber and harmonicnumber.
    • pochhammer, and the notation (x)_n, mean the rising factorial in special functions and the falling one in combinatorics, so neither is used.
  4. Mathematica's name is accepted on input where it is another spelling of the same function, and SymPy's where it is unambiguous. Only the chosen name is printed.
  5. Nothing is added that the library already writes another way. isprime(n) is n in PP, clamp(x, a, b) is min(max(x, a), b), the fractional part is x mod 1 (floored, so in [0, 1)) and the integer quotient is floor(a/b). The Heaviside step function is the same case. Its sources disagree on its value at 0, so heaviside would have to pick one: Wikipedia lists 0, 1/2, 1, [0, 1] and none, MathWorld gives 1/2, DLMF 1.16.13 0, Mathematica's UnitStep 1 and its HeavisideTheta none. Each is already written exactly: iverson(x > 0), iverson(x >= 0) and (1 + sgn(x))/2, so neither heaviside nor unitstep is added; both are refused with those three spellings (see A register of function names, by what a mathematician calls each #2182).

The sources are listed for each row as evidence, not as the reason.

LaTeX reads back as what it came from. A Greek letter or a capital that could be a variable is wrapped in \operatorname, as phi(n) already draws as \operatorname{\varphi}\left(n\right), since mu * (n + 1) draws as \mu \left(n+1\right). Braces are left for sets. A constant is upright, as pi is \mathrm{\pi}.

Shipped

floor, ceil, round, mod, min, max, gcd, lcm, phi, binomial, sum, product, erf, erfc, digamma, polygamma, gamma, and congruence as a = b (mod n). Also prime(n), valuation, iverson, det, transpose, dot, cross and resultant (#2180), conjugate/conj and arg (#2181), Re and Im (#2185), the double factorial n!! (#2187), and mobius, divisorsigma, primenu, primeomega and primepi (#2188). laplacian, jacobian and hessian (#2190), and fallingfactorial, factorialpower and risingfactorial (#2194). multinomial, the gamma ratio agreed below (#2197), catalannumber (#2198), harmonicnumber (#2200), forwarddifference (#2201) and lambertw (#2202), with K (a x + b) c^(g x + d) = k solved through it (#2203). The constant eulergamma, \mathrm{\gamma}, also read as EulerGamma, with digamma exact at a whole or half-whole argument and harmonicnumber at a half-whole one (#2204).

Proposed

Name Also accepted Wikipedia MathWorld Mathematica SymPy LaTeX Convention
beta(a, b) Beta function Beta Function Beta beta \operatorname{B}\left(a, b\right)
zeta(s), zeta(s, a) Riemann zeta function, Hurwitz zeta function Riemann Zeta Function, Hurwitz Zeta Function Zeta, HurwitzZeta zeta \operatorname{\zeta}\left(s\right), \operatorname{\zeta}\left(s, a\right) To decide: rule 2 gives zeta, rule 1 gives riemannzeta and hurwitzzeta
norm(v), (v, p) Norm (mathematics) Vector Norm Norm Matrix.norm \left| v \right|_{p} p = 2 by default; p = +oo is the largest modulus
grad(f, x) gradient Gradient Gradient Grad gradient \nabla f a column
div(F, x) divergence Divergence Divergence Div divergence \nabla \cdot F
curl(F, x) Curl (mathematics) Curl Curl curl \nabla \times F three dimensions only

Reserved until implemented

An unknown name followed by a bracket is read as a product, so zeta(s) is zeta * s today, silently. #2184 refuses the long names by name until each is implemented. Short names that could be somebody's variable before a bracket are not reserved: beta, norm, grad, div, curl, frac.

Related: #809 (the research), #2145, #2147.

🤖 Generated with Claude Code

https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

Activity

  1. added this to the 2.8 milestone on Oct 28, 2026
  2. Happypig375 commented on Oct 28, 2026

    @Happypig375
    Member

    Do we really need a isprime function when in PP suffices?

    Do we not have a better notation for rising and falling factorials when they literally look like superscripts and subscripts as written here? Something with overbars and underbars perhaps?

    doublefactorial is reserved as a function but not !!?

    We have lambertw but zeta not riemannzeta (we can't have the greek zeta as a variable anymore????)? Blindly following Sympy is producing inconsistencies, and you didn't even list Mathematica's name! How about Wikipedia and MathWorld's naming? What happened to your agentic instructions - this table is so arbitrary despite you are to be a mathematician first?

  3. changed the title [-]A register of function names to add, and the long ones reserved until then[/-] [+]A register of function names, by what a mathematician calls each[/+] on Oct 28, 2026
  4. Rafael-SOWNet commented on Oct 28, 2026

    @Rafael-SOWNet
    MemberAuthor

    You're right on all three, and the fault is mine. I copied the August table, whose rule was "SymPy wins", instead of naming each function. That is what you asked me to stop doing on #1239.

    The body is replaced. The new register states its rule, and each row gives its Wikipedia, MathWorld, Mathematica and SymPy names as evidence:

    • isprime is dropped, since n in PP is the statement. So is clamp, which is min(max(x, a), b).
    • Falling and rising factorials are fallingfactorial and risingfactorial, drawn with Knuth's underbar and overbar from Concrete Mathematics: x^{\underline{n}} and x^{\overline{n}}.
      • pochhammer is not accepted, since (x)_n is the rising factorial in special functions and the falling one in combinatorics.
      • ff and rf are gone. Mathematica's FactorialPower is accepted for the falling one.
    • A name that already means something else is not used.
      • quotient, not div, which is the divergence.
      • forwarddifference, not delta.
      • catalannumber and harmonicnumber, not catalan, which is also Catalan's constant, or harmonic.

    Two calls I'd like yours on:

    • zeta, or riemannzeta and hurwitzzeta. I lean to zeta. Mathematicians say "the zeta function" and write ζ, as they do Γ and erf, both named by their symbol here. Nobody says "the W function" alone, which is why that one is lambertw.
    • The value of heaviside at 0. It is 1/2 in MathWorld and SymPy, and 1 in Mathematica's UnitStep.

    #2184 is back to draft until the names settle. Some of what it reserves changes: harmonic becomes harmonicnumber, and isprime goes.

    🤖 Generated with Claude Code

    https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

  5. Happypig375 commented on Oct 28, 2026

    @Happypig375
    Member

    The value of heaviside at 0. It is 1/2 in MathWorld and SymPy, and 1 in Mathematica's UnitStep.

    This is an incomplete description of Mathematica. Mathematica has HeavisideTheta[0] unevaluated and UnitStep[0] as 1. So the Heaviside function is considered as a different function than the "unit step" function. This may need more thought... How do other online sources discuss this?

  6. Happypig375 commented on Oct 28, 2026

    @Happypig375
    Member

    Also, doublefactorial is dubious as a function when the factorial is the postfix ! operator and we likely want the postfix !! here.

  7. Rafael-SOWNet commented on Oct 28, 2026

    @Rafael-SOWNet
    MemberAuthor

    Agreed, and it settles more than the value. The sources disagree on H(0), and some on whether there is one:

    Source H(0)
    Wikipedia no single value. 1 where H must be right-continuous (distribution functions, Lebesgue–Stieltjes), 0 left-continuous, 1/2 by the half-maximum convention, [0, 1] set-valued in optimization, and none as a distribution
    MathWorld 1/2, "the conventional definition", noting that UnitStep takes 1
    DLMF 1.16.13 0: H(x) = 1 for x > 0 and 0 for x <= 0
    Mathematica HeavisideTheta[0] stays unevaluated, "as a distribution"; UnitStep[0] is 1; the two "are not mathematically equivalent"
    Maple undefined by default, or 1 with _EnvUseHeavisideAsUnitStep
    MATLAB 1/2 by default, set by HeavisideAtOrigin
    NumPy a required second argument
    SymPy Heaviside(x, H0=1/2) since 1.9, undefined before

    So heaviside(x) would have to pick one, and whichever it picks is a different function to half its readers. Each convention is already written exactly here, without ambiguity:

    0 at 0 (DLMF) iverson(x > 0)
    1 at 0 (the unit step, right-continuous) iverson(x >= 0)
    1/2 at 0 (MathWorld, SymPy, MATLAB) (1 + sgn(x))/2

    I propose rule 5 for both heaviside and unitstep: no function. They would be refused by name, with a message giving those three spellings, as arcsinh is refused with the spellings the library accepts. The distributional reading, where H(0) has no value and H' = δ, needs a Dirac delta, which is a question of its own and not this one. I'll move the row in the register.

    🤖 Generated with Claude Code

    https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

  8. Rafael-SOWNet commented on Oct 28, 2026

    @Rafael-SOWNet
    MemberAuthor

    Yes. n!! is how Wikipedia and MathWorld write it, and how Mathematica reads it. Today 5!! is a parse error ("extraneous input '!'"), so it can be the double factorial with nothing changing meaning, and (n!)! keeps its parentheses. The register now has a rule for it: where mathematics writes an operator rather than a function, the operator is the spelling, as with n! and a = b (mod n). The double factorial's row is n!!, with no function name.

    🤖 Generated with Claude Code

    https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

  9. Happypig375 commented on Oct 28, 2026

    @Happypig375
    Member

    I agree that unclear notations should be rejected with clear alternatives: this is what we did with NN forcing ZZ+ or ZZ*, rejecting the notion of "heaviside" or "unit step" and forcing a clear alternative is what we go for. The user will be able to redefine their conventions using let statements (#352 coming v3).

    let NN = ZZ+
    0 in NN // false
    
    let heaviside(x) = (1 + sgn(x))/2 // syntax TBD, especially regarding domain/codomain etc
    heaviside(0) // 1/2
    
  10. Happypig375 commented on Oct 28, 2026

    @Happypig375
    Member

    actually, maybe this might also be a potential thought for v3:

    let 0 in NN // disambiguator - possible other syntaxes: assume 0 in NN, suppose 0 in NN
    1 in NN // usable after resolving the ambiguity
    
    let heaviside(0) = 1/2 // disambiguator
    heaviside(1) // usable after disambiguator
    
  11. Rafael-SOWNet commented on Oct 28, 2026

    @Rafael-SOWNet
    MemberAuthor

    Recorded on #352, where the v3 let statement is tracked, so the disambiguator is designed with it.

    🤖 Generated with Claude Code

    https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura

  12. Happypig375 commented on Oct 28, 2026

    @Happypig375
    Member

    The table now looks mostly fine, but LaTeX also needs to consider roundtripping, for example {x} really looks like a one-element set.

  13. 6 remaining items

  14. Rafael-SOWNet commented on Oct 29, 2026

    @Rafael-SOWNet
    MemberAuthor

    multinomial needs a decision before it can be added. On the non-negative integers, (k₁ + … + kₘ)! / (k₁! ⋯ kₘ!) is unambiguous. Off them, the definitions disagree:

    • Built as the product of binomials, as the multinomial theorem factors it, the result inherits binomial's convention that a negative whole lower index gives 0. That breaks symmetry. multinomial(-3, 1) comes out as binomial(-2, 1) = -2, while multinomial(1, -3) comes out as binomial(-2, -3) = 0.
    • As the gamma ratio Γ(k₁ + … + kₘ + 1) / ∏ Γ(kᵢ + 1), it is symmetric. It has no value where an argument is a negative integer: there the limit depends on how it is approached, and binomial(n, k) itself does not follow the gamma ratio.

    My proposal: the gamma ratio, with no value where an argument or the sum is a negative integer. Then multinomial(a, b) agrees with binomial(a + b, b) everywhere both are defined by the ratio, and the two differ only at negative integers.

  15. Happypig375 commented on Oct 29, 2026

    @Happypig375
    Member

    Seems fine, we already implicitly use the gamma function for non-integer factorials instead of not defining a value for non-integer factorials.

  16. Rafael-SOWNet commented on Oct 29, 2026

    @Rafael-SOWNet
    MemberAuthor

    Merged since the register was posted: #2187 (n!!), #2188 (mobius, divisorsigma, primenu, primeomega, primepi), #2190 (laplacian, jacobian, hessian), #2194 (factorial powers), #2197 (multinomial), #2198 (catalannumber) and #2200 (harmonicnumber). #2201 (forwarddifference) is open, and I'm writing lambertw next.

    Two decisions are left, both yours:

    1. zeta. Rule 2, a function named by its symbol as gamma is, gives zeta(s) and zeta(s, a), as Mathematica's Zeta and SymPy's zeta. Rule 1 gives riemannzeta and hurwitzzeta. My suggestion is zeta, with the two long names read as the same function.
    2. The short names beta, norm, grad, div, curl. These are read as products today, beta(x) being beta * x, so making them functions changes what existing input means. div is also integer division in several languages. My suggestion: beta(a, b), norm(v) and norm(v, p), and gradient, divergence and curl spelled out; div itself stays a variable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions