Logarithmic Functions

AUTHORS:

class sage.functions.log.Function_dilog

Bases: sage.symbolic.function.GinacFunction

The dilogarithm function \(\text{Li}_2(z) = \sum_{k=1}^{\infty} z^k / k^2\).

This is simply an alias for polylog(2, z).

EXAMPLES:

sage: dilog(1)
1/6*pi^2
sage: dilog(1/2)
1/12*pi^2 - 1/2*log(2)^2
sage: dilog(x^2+1)
dilog(x^2 + 1)
sage: dilog(-1)
-1/12*pi^2
sage: dilog(-1.0)
-0.822467033424113
sage: dilog(-1.1)
-0.890838090262283
sage: dilog(1/2)
1/12*pi^2 - 1/2*log(2)^2
sage: dilog(.5)
0.582240526465012
sage: dilog(1/2).n()
0.582240526465012
sage: var('z')
z
sage: dilog(z).diff(z, 2)
log(-z + 1)/z^2 - 1/((z - 1)*z)
sage: dilog(z).series(z==1/2, 3)
(1/12*pi^2 - 1/2*log(2)^2) + (-2*log(1/2))*(z - 1/2) + (2*log(1/2) + 2)*(z - 1/2)^2 + Order(1/8*(2*z - 1)^3)

sage: latex(dilog(z))
{\rm Li}_2\left(z\right)

Dilog has a branch point at \(1\). Sage’s floating point libraries may handle this differently from the symbolic package:

sage: dilog(1)
1/6*pi^2
sage: dilog(1.)
1.64493406684823
sage: dilog(1).n()
1.64493406684823
sage: float(dilog(1))
1.6449340668482262
class sage.functions.log.Function_exp

Bases: sage.symbolic.function.GinacFunction

The exponential function, \(\exp(x) = e^x\).

EXAMPLES:

sage: exp(-1)
e^(-1)
sage: exp(2)
e^2
sage: exp(2).n(100)
7.3890560989306502272304274606
sage: exp(x^2 + log(x))
e^(x^2 + log(x))
sage: exp(x^2 + log(x)).simplify()
x*e^(x^2)
sage: exp(2.5)
12.1824939607035
sage: exp(float(2.5))
12.182493960703473
sage: exp(RDF('2.5'))
12.182493960703473
sage: exp(I*pi/12)
(1/4*I + 1/4)*sqrt(6) - (1/4*I - 1/4)*sqrt(2)

To prevent automatic evaluation, use the hold parameter:

sage: exp(I*pi,hold=True)
e^(I*pi)
sage: exp(0,hold=True)
e^0

To then evaluate again, we currently must use Maxima via sage.symbolic.expression.Expression.simplify():

sage: exp(0,hold=True).simplify()
1
sage: exp(pi*I/2)
I
sage: exp(pi*I)
-1
sage: exp(8*pi*I)
1
sage: exp(7*pi*I/2)
-I

For the sake of simplification, the argument is reduced modulo the period of the complex exponential function, \(2\pi i\):

sage: k = var('k', domain='integer')
sage: exp(2*k*pi*I)
1
sage: exp(log(2) + 2*k*pi*I)
2

The precision for the result is deduced from the precision of the input. Convert the input to a higher precision explicitly if a result with higher precision is desired:

sage: t = exp(RealField(100)(2)); t
7.3890560989306502272304274606
sage: t.prec()
100
sage: exp(2).n(100)
7.3890560989306502272304274606
class sage.functions.log.Function_exp_polar

Bases: sage.symbolic.function.BuiltinFunction

Representation of a complex number in a polar form.

INPUT:

  • z – a complex number \(z = a + ib\).

OUTPUT:

A complex number with modulus \(\exp(a)\) and argument \(b\).

If \(-\pi < b \leq \pi\) then \(\operatorname{exp\_polar}(z)=\exp(z)\). For other values of \(b\) the function is left unevaluated.

EXAMPLES:

The following expressions are evaluated using the exponential function:

sage: exp_polar(pi*I/2)
I
sage: x = var('x', domain='real')
sage: exp_polar(-1/2*I*pi + x)
e^(-1/2*I*pi + x)

The function is left unevaluated when the imaginary part of the input \(z\) does not satisfy \(-\pi < \Im(z) \leq \pi\):

sage: exp_polar(2*pi*I)
exp_polar(2*I*pi)
sage: exp_polar(-4*pi*I)
exp_polar(-4*I*pi)

This fixes trac ticket #18085:

sage: integrate(1/sqrt(1+x^3),x,algorithm='sympy')
1/3*x*gamma(1/3)*hypergeometric((1/3, 1/2), (4/3,), -x^3)/gamma(4/3)

REFERENCES:

class sage.functions.log.Function_harmonic_number

Bases: sage.symbolic.function.BuiltinFunction

Harmonic number function, defined by:

\[ \begin{align}\begin{aligned}H_{n}=H_{n,1}=\sum_{k=1}^n\frac1k\\H_{s}=\int_0^1\frac{1-x^s}{1-x}\end{aligned}\end{align} \]

See the docstring for Function_harmonic_number_generalized().

This class exists as callback for harmonic_number returned by Maxima.

class sage.functions.log.Function_harmonic_number_generalized

Bases: sage.symbolic.function.BuiltinFunction

Harmonic and generalized harmonic number functions, defined by:

\[ \begin{align}\begin{aligned}H_{n}=H_{n,1}=\sum_{k=1}^n\frac{1}{k}\\H_{n,m}=\sum_{k=1}^n\frac{1}{k^m}\end{aligned}\end{align} \]

They are also well-defined for complex argument, through:

\[ \begin{align}\begin{aligned}H_{s}=\int_0^1\frac{1-x^s}{1-x}\\H_{s,m}=\zeta(m)-\zeta(m,s-1)\end{aligned}\end{align} \]

If called with a single argument, that argument is s and m is assumed to be 1 (the normal harmonic numbers H_s).

ALGORITHM:

Numerical evaluation is handled using the mpmath and FLINT libraries.

REFERENCES:

EXAMPLES:

Evaluation of integer, rational, or complex argument:

sage: harmonic_number(5)
137/60
sage: harmonic_number(3,3)
251/216
sage: harmonic_number(5/2)
-2*log(2) + 46/15
sage: harmonic_number(3.,3)
zeta(3) - 0.0400198661225573
sage: harmonic_number(3.,3.)
1.16203703703704
sage: harmonic_number(3,3).n(200)
1.16203703703703703703703...
sage: harmonic_number(1+I,5)
harmonic_number(I + 1, 5)
sage: harmonic_number(5,1.+I)
1.57436810798989 - 1.06194728851357*I

Solutions to certain sums are returned in terms of harmonic numbers:

sage: k=var('k')
sage: sum(1/k^7,k,1,x)
harmonic_number(x, 7)

Check the defining integral at a random integer:

sage: n=randint(10,100)
sage: bool(SR(integrate((1-x^n)/(1-x),x,0,1)) == harmonic_number(n))
True

There are several special values which are automatically simplified:

sage: harmonic_number(0)
0
sage: harmonic_number(1)
1
sage: harmonic_number(x,1)
harmonic_number(x)

Arguments are swapped with respect to the same functions in Maxima:

sage: maxima(harmonic_number(x,2)) # maxima expect interface
gen_harmonic_number(2,_SAGE_VAR_x)
sage: from sage.calculus.calculus import symbolic_expression_from_maxima_string as sefms
sage: sefms('gen_harmonic_number(3,x)')
harmonic_number(x, 3)
sage: from sage.interfaces.maxima_lib import maxima_lib, max_to_sr
sage: c=maxima_lib(harmonic_number(x,2)); c
gen_harmonic_number(2,_SAGE_VAR_x)
sage: max_to_sr(c.ecl())
harmonic_number(x, 2)
class sage.functions.log.Function_lambert_w

Bases: sage.symbolic.function.BuiltinFunction

The integral branches of the Lambert W function \(W_n(z)\).

This function satisfies the equation

\[z = W_n(z) e^{W_n(z)}\]

INPUT:

  • n – an integer. \(n=0\) corresponds to the principal branch.

  • z – a complex number

If called with a single argument, that argument is z and the branch n is assumed to be 0 (the principal branch).

ALGORITHM:

Numerical evaluation is handled using the mpmath and SciPy libraries.

REFERENCES:

EXAMPLES:

Evaluation of the principal branch:

sage: lambert_w(1.0)
0.567143290409784
sage: lambert_w(-1).n()
-0.318131505204764 + 1.33723570143069*I
sage: lambert_w(-1.5 + 5*I)
1.17418016254171 + 1.10651494102011*I

Evaluation of other branches:

sage: lambert_w(2, 1.0)
-2.40158510486800 + 10.7762995161151*I

Solutions to certain exponential equations are returned in terms of lambert_w:

sage: S = solve(e^(5*x)+x==0, x, to_poly_solve=True)
sage: z = S[0].rhs(); z
-1/5*lambert_w(5)
sage: N(z)
-0.265344933048440

Check the defining equation numerically at \(z=5\):

sage: N(lambert_w(5)*exp(lambert_w(5)) - 5)
0.000000000000000

There are several special values of the principal branch which are automatically simplified:

sage: lambert_w(0)
0
sage: lambert_w(e)
1
sage: lambert_w(-1/e)
-1

Integration (of the principal branch) is evaluated using Maxima:

sage: integrate(lambert_w(x), x)
(lambert_w(x)^2 - lambert_w(x) + 1)*x/lambert_w(x)
sage: integrate(lambert_w(x), x, 0, 1)
(lambert_w(1)^2 - lambert_w(1) + 1)/lambert_w(1) - 1
sage: integrate(lambert_w(x), x, 0, 1.0)
0.3303661247616807

Warning: The integral of a non-principal branch is not implemented, neither is numerical integration using GSL. The numerical_integral() function does work if you pass a lambda function:

sage: numerical_integral(lambda x: lambert_w(x), 0, 1)
(0.33036612476168054, 3.667800782666048e-15)
class sage.functions.log.Function_log1

Bases: sage.symbolic.function.GinacFunction

The natural logarithm of x.

See log() for extensive documentation.

EXAMPLES:

sage: ln(e^2)
2
sage: ln(2)
log(2)
sage: ln(10)
log(10)
class sage.functions.log.Function_log2

Bases: sage.symbolic.function.GinacFunction

Return the logarithm of x to the given base.

See log() for extensive documentation.

EXAMPLES:

sage: from sage.functions.log import logb
sage: logb(1000,10)
3
class sage.functions.log.Function_polylog

Bases: sage.symbolic.function.GinacFunction

The polylog function \(\text{Li}_s(z) = \sum_{k=1}^{\infty} z^k / k^s\).

The first argument is \(s\) (usually an integer called the weight) and the second argument is \(z\) : polylog(s, z).

This definition is valid for arbitrary complex numbers \(s\) and \(z\) with \(|z| < 1\). It can be extended to \(|z| \ge 1\) by the process of analytic continuation, with a branch cut along the positive real axis from \(1\) to \(+\infty\). A \(NaN\) value may be returned for floating point arguments that are on the branch cut.

EXAMPLES:

sage: polylog(2.7, 0)
0.000000000000000
sage: polylog(2, 1)
1/6*pi^2
sage: polylog(2, -1)
-1/12*pi^2
sage: polylog(3, -1)
-3/4*zeta(3)
sage: polylog(2, I)
I*catalan - 1/48*pi^2
sage: polylog(4, 1/2)
polylog(4, 1/2)
sage: polylog(4, 0.5)
0.517479061673899

sage: polylog(1, x)
-log(-x + 1)
sage: polylog(2,x^2+1)
dilog(x^2 + 1)

sage: f = polylog(4, 1); f
1/90*pi^4
sage: f.n()
1.08232323371114

sage: polylog(4, 2).n()
2.42786280675470 - 0.174371300025453*I
sage: complex(polylog(4,2))
(2.4278628067547032-0.17437130002545306j)
sage: float(polylog(4,0.5))
0.5174790616738993

sage: z = var('z')
sage: polylog(2,z).series(z==0, 5)
1*z + 1/4*z^2 + 1/9*z^3 + 1/16*z^4 + Order(z^5)

sage: loads(dumps(polylog))
polylog

sage: latex(polylog(5, x))
{\rm Li}_{5}(x)
sage: polylog(x, x)._sympy_()
polylog(x, x)
sage.functions.log.log(*args, **kwds)

Return the logarithm of the first argument to the base of the second argument which if missing defaults to e.

It calls the log method of the first argument when computing the logarithm, thus allowing the use of logarithm on any object containing a log method. In other words, log works on more than just real numbers.

EXAMPLES:

sage: log(e^2)
2

To change the base of the logarithm, add a second parameter:

sage: log(1000,10)
3

The synonym ln can only take one argument:

sage: ln(RDF(10))
2.302585092994046
sage: ln(2.718)
0.999896315728952
sage: ln(2.0)
0.693147180559945
sage: ln(float(-1))
3.141592653589793j
sage: ln(complex(-1))
3.141592653589793j

You can use RDF, RealField or n to get a numerical real approximation:

sage: log(1024, 2)
10
sage: RDF(log(1024, 2))
10.0
sage: log(10, 4)
1/2*log(10)/log(2)
sage: RDF(log(10, 4))
1.6609640474436813
sage: log(10, 2)
log(10)/log(2)
sage: n(log(10, 2))
3.32192809488736
sage: log(10, e)
log(10)
sage: n(log(10, e))
2.30258509299405

The log function works for negative numbers, complex numbers, and symbolic numbers too, picking the branch with angle between \(-\pi\) and \(\pi\):

sage: log(-1+0*I)
I*pi
sage: log(CC(-1))
3.14159265358979*I
sage: log(-1.0)
3.14159265358979*I

Small integer powers are factored out immediately:

sage: log(4)
2*log(2)
sage: log(1000000000)
9*log(10)
sage: log(8) - 3*log(2)
0
sage: bool(log(8) == 3*log(2))
True

The hold parameter can be used to prevent automatic evaluation:

sage: log(-1,hold=True)
log(-1)
sage: log(-1)
I*pi
sage: I.log(hold=True)
log(I)
sage: I.log(hold=True).simplify()
1/2*I*pi

For input zero, the following behavior occurs:

sage: log(0)
-Infinity
sage: log(CC(0))
-infinity
sage: log(0.0)
-infinity

The log function also works in finite fields as long as the argument lies in the multiplicative group generated by the base:

sage: F = GF(13); g = F.multiplicative_generator(); g
2
sage: a = F(8)
sage: log(a,g); g^log(a,g)
3
8
sage: log(a,3)
Traceback (most recent call last):
...
ValueError: No discrete log of 8 found to base 3 modulo 13
sage: log(F(9), 3)
2

The log function also works for p-adics (see documentation for p-adics for more information):

sage: R = Zp(5); R
5-adic Ring with capped relative precision 20
sage: a = R(16); a
1 + 3*5 + O(5^20)
sage: log(a)
3*5 + 3*5^2 + 3*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 2*5^8 + 5^9 +
5^11 + 2*5^12 + 5^13 + 3*5^15 + 2*5^16 + 4*5^17 + 3*5^18 +
3*5^19 + O(5^20)