LogIntegral¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
LogIntegral[z]
gives the logarithmic integral li(z), the principal value of Integral_0^z dt/ln t, equal to ExpIntegralEi[Log[z]], with a branch cut on (-Infinity, 1). LogIntegral[0] = 0, LogIntegral[1] = -Infinity,
LogIntegral[Infinity] = Infinity. Real and complex inputs evaluate
Notes
numerically at machine or arbitrary (MPFR) precision; D\[LogIntegral\[z\], z\] = 1/Log\[z\]. Listable.Examples (4)¶
Every input below was run against the current Mathilda build and its output recorded.
Applications (4)¶
In[1]:= N[LogIntegral[2], 40]
Out[1]= 1.0451637801174927848445888891946131365227
In[2]:= D[LogIntegral[z], z]
Out[2]= 1/Log[z]
In[3]:= N[LogIntegral[10^6], 30]
Out[3]= 78627.5491594621819198629107479
In[4]:= N[LogIntegral[1000], 20]
Out[4]= 177.609657990152226688
Algorithm¶
Mathilda -- the logarithmic integral li.
li has a branch cut along (-Infinity, +1); the principal value is taken on the cut. The implementation rests on the identity
where Ei is ExpIntegralEi and Log is the principal logarithm. This lets us reuse ExpIntegralEi's fully-tested numeric stack (mpfr_eint / the real and complex convergent series with cancellation guard bits) without duplicating any of it, and the principal Log automatically supplies the +-i Pi jump that places the branch cut on (-Infinity, +1).
Evaluation is layered so each kind of argument takes the cheapest route:
exact special values -> 0, -Infinity, Infinity, Indeterminate
machine real / complex z -> the double kernels sf_machine_li(_c)
(sf_machine_expint.c, shared with NDArray
and Compile[]), no expression is built
arbitrary-precision z -> evaluate ExpIntegralEi[Log[z]]
everything else -> stays symbolic (return NULL)
Exact non-special numbers (e.g. LogIntegral[2], LogIntegral[1/2]) stay symbolic, matching the Wolfram Language; only inexact input or an explicit N[...] (which rewrites the argument to an MPFR number) evaluates numerically.
Attributes: Listable, NumericFunction, Protected.
Implementation notes¶
Algorithm. builtin_logintegral evaluates li(z) through the identity
li(z) = Ei(Log z), reusing ExpIntegralEi's numeric stack rather than
duplicating it; the principal Log supplies the ±i Pi jump that places the
branch cut on (-Infinity, +1). Exact special values: 0 -> 0,
1 -> -Infinity, Infinity -> Infinity, ComplexInfinity/Indeterminate ->
Indeterminate. Exact non-special numbers (li[2], li[1/2]) stay symbolic,
matching the Wolfram Language; only an inexact argument (or explicit N[...])
evaluates, by building ExpIntegralEi[Log[z]] and evaluating it — a defensive
check drops the result and stays symbolic if the composition did not reduce. The
machine kernel logintegral_machine_complex is Ei(clog z), declining at
z = 0 (Indeterminate) and z = 1 (pole).
Data structures. Expr; reuses the ExpIntegralEi kernels (mpfr_eint /
the real and complex convergent series); double complex machine kernel. ND:
unary kernel NDKU_LogIntegral = { logintegral_machine_complex,
ndk_LogIntegral_r, ... } (the real kernel is sf_machine_li), registered
REG_U, so packed_aware. Attributes: Listable, NumericFunction,
Protected.
Complexity / limits. Cost is one ExpIntegralEi evaluation. The principal
Log puts the cut on the negative real axis, so li[-1.] is complex
(Ei(i Pi)). Exact rationals stay symbolic. Compile[] lowers at both scalar
and rank-1 array shapes (Compiled -> True).
- Exact special values:
LogIntegral[0] = 0,LogIntegral[1] = -Infinity,LogIntegral[Infinity] = Infinity;ComplexInfinityandIndeterminatemap toIndeterminate. - Exact non-special arguments stay symbolic (
LogIntegral[2],LogIntegral[1/2]); numeric values follow from aReal/MPFR argument or fromN. - Numeric evaluation (machine and arbitrary precision) routes through
ExpIntegralEi[Log[z]]: - Real z > 1 (
Log z > 0) → MPFRmpfr_eint, correctly rounded and fast even at very high precision:LogIntegral[20.] = 9.9053,LogIntegral[2.] = 1.04516,N[LogIntegral[2], 50] = 1.0451637801174927848445888891946131365226155781512. - Real 0 < z < 1 (
Log z < 0) → the on-cut convergent series, returning a real principal value:LogIntegral[0.5] = -0.378671,LogIntegral[1.2] = -0.933787. - Complex (and real z < 0, whose principal
Logis complex) → the complex series with guard bits, so machine-precision complex results are fully accurate, e.g.LogIntegral[2. + I] = 1.41126 + 1.22471 I,N[Re[LogIntegral[2 + I]], 30] = 1.41125904201780100568439320706. - Machine precision (real and complex) no longer builds and evaluates
ExpIntegralEi[Log[z]]: double kernels shared bit-for-bit with the packed/NDArray kernels andCompile[](src/special_functions/sf_machine_expint.c; the scalar builtin calls the same function, so scalar == List == packed == NDArray == Compile). A decline (pole, overflow, an underflow to a subnormal) falls through to the MPFR path unchanged, and arbitrary precision is untouched. The real kernel evaluates Ei(log x) with e^(log x) replaced by x itself in the large-argument forms, so the rounding of log x is not amplified by an exponential; a real x < 0 returns the complex value directly. The rounding of log x would otherwise cost ~log x ulps (9 at x = 1e4) through the e^y in Ei(y); it is recovered as dy = (x − e^y)/x and added back as (x/y)·dy. Accuracy vs mpmath: median 0.4 ulp, max 1.9 ulp (real, off the zero μ = 1.4513); max 2.7 ulp (complex). - Derivative:
D[LogIntegral[z], z] = 1/Log[z](chain rule applies, e.g.D[LogIntegral[x^2], x] = (2 x)/Log[x^2]); the Taylor series at a regular point follows from the genericD-based fallback. - Wrong arity emits
LogIntegral::argxand stays unevaluated.
Attributes: Listable, NumericFunction, Protected.
References¶
See also: ExpIntegralEi, Log, Real, N, D
- DLMF §6.2 — the logarithmic integral li.
- Source:
src/special_functions/logintegral.c - Specification:
docs/spec/builtins/special-functions.md - Tests:
tests/test_cherry_li.c - Tests:
tests/test_cherry_sigma.c - Tests:
tests/test_compile.c - Tests:
tests/test_expint_machine.c
Notes & additional examples¶
Notes¶
LogIntegral[z] is the logarithmic integral li(z), the principal value of Integral_0^z dt/Log[t], equal to ExpIntegralEi[Log[z]], with a branch cut on (-Infinity, 1). Its derivative is 1/Log[z]. li(x) is the leading term of the prime-counting approximation PrimePi[x] ~ li(x); for example li(10^6) is about 78627.5, close to PrimePi[10^6] = 78498. Real and complex inputs evaluate numerically at machine or arbitrary (MPFR) precision. LogIntegral[1] = -Infinity. Listable.