# Ticket #11888: trac_11888_v3.patch

File trac_11888_v3.patch, 9.3 KB (added by benjaminfjones, 8 years ago)

• ## sage/functions/all.py

# HG changeset patch
# User Benjamin Jones <benjaminfjones@gmail.com>
# Date 1328501390 21600
diff --git a/sage/functions/all.py b/sage/functions/all.py
diff --git a/sage/functions/log.py b/sage/functions/log.py
 a """ Logarithmic functions """ from sage.symbolic.function import GinacFunction from sage.symbolic.function import GinacFunction, BuiltinFunction, is_inexact from sage.symbolic.pynac import symbol_table from sage.libs.mpmath import utils as mpmath_utils from sage.structure.coerce import parent from sage.symbolic.expression import Expression from sage.rings.real_double import RDF from sage.rings.complex_double import CDF class Function_exp(GinacFunction): def __init__(self): dilog = Function_dilog() class Function_lambert_w_branch(BuiltinFunction): r""" The integral branches of the Lambert W function W_n(z). This function satisfies the equation .. math:: z = W_n(z) e^{W_n(z)} INPUT: - z - a complex number - n - an integer. n=0 corresponds to the principal branch. ALGORITHM: Numerical evaluation is handled using the mpmath and SciPy libraries. REFERENCES: - http://en.wikipedia.org/wiki/Lambert_W_function EXAMPLES: Evaluation of the principal branch:: sage: lambert_w_branch(1.0, 0) 0.567143290409784 sage: lambert_w_branch(-1,0).n() -0.318131505204764 + 1.33723570143069*I sage: lambert_w_branch(-1.5 + 5*I, 0) 1.17418016254171 + 1.10651494102011*I Evaluation of other branches:: sage: lambert_w_branch(1.0, 2) -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_branch(5, 0) 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 """ def __init__(self): """ See the docstring for :meth:Function_lambert_w. EXAMPLES:: sage: lambert_w_branch(1.0, 0) 0.567143290409784 """ BuiltinFunction.__init__(self, "lambert_w_branch", nargs=2, latex_name=r'W') def _eval_(self, z, n): """ EXAMPLES:: sage: lambert_w_branch(0, 0) lambert_w_branch(0, 0) sage: x = var('x') sage: lambert_w_branch(x, 1) lambert_w_branch(x, 1) sage: lambert_w_branch(0.0, 0) 0.000000000000000 """ if not isinstance(z, Expression) and is_inexact(z): return self._evalf_(z, n, parent=parent(z)) return None def _evalf_(self, z, n, parent=None): """ EXAMPLES:: sage: N(lambert_w_branch(1,0)) 0.567143290409784 sage: lambert_w_branch(RealField(100)(1),0) 0.56714329040978387299996866221 SciPy is used to evalute for RDF or CDF inputs:: sage: lambert_w_branch(RDF(1),0) 0.56714329041 """ if parent(z) == RDF or parent(z) == CDF: import scipy.special return scipy.special.lambertw(z, n) else: import mpmath return mpmath_utils.call(mpmath.lambertw, z, n, parent=parent) def _derivative_(self, z, n, diff_param=None): """ The derivative of W_n(x) is W_n(x)/(x \cdot W_n(x) + x). EXAMPLES:: sage: x = var('x') sage: derivative(lambert_w(x), x) lambert_w_branch(x, 0)/(x*lambert_w_branch(x, 0) + x) """ return lambert_w(z, n)/(z*lambert_w(z, n)+z) lambert_w_branch = Function_lambert_w_branch() def lambert_w(z, *args, **kwds): """ The principal branch of the Lambert W function. This is a wrapper for lambert_w_branch(z,0). INPUT: - z - complex number OUTPUT: - The value W_0(z) of the principal branch of the lambert_w function. The output satisfies the equation .. math:: z = W_0(z) e^{W_0(z)} ALGORITHM: Numerical evaluation is handled using the mpmath and SciPy libraries. REFERENCES: - http://en.wikipedia.org/wiki/Lambert_W_function EXAMPLES:: sage: lambert_w(1.0) 0.567143290409784 sage: lambert_w(2) lambert_w_branch(2, 0) sage: lambert_w(2).n() 0.852605502013726 """ if not args: return lambert_w_branch(z, 0, **kwds) elif len(args) > 1: raise ArgumentError("lambert_w takes at most two arguments.") else: return lambert_w_branch(z, args[0], **kwds) symbol_table['functions']['lambert_w'] = lambert_w
diff --git a/sage/symbolic/random_tests.py b/sage/symbolic/random_tests.py