Ticket #11888: trac_11888.patch

File trac_11888.patch, 3.8 KB (added by benjaminfjones, 8 years ago)

add lambert_w symbolic function

  • sage/functions/all.py

    # HG changeset patch
    # User Benjamin Jones <benjaminfjones@gmail.com>
    # Date 1326163188 18000
    # Node ID 3321434bbf8b1fcca0efa3ec726f85659fac6fef
    # Parent  92c93226b64f933e0af00bbcbd1a8a79c444f43f
    Trac 11888: add the lambert_w symbolic function
    
    diff --git a/sage/functions/all.py b/sage/functions/all.py
    a b  
    2121                    real_part, real,
    2222                    imag_part, imag, imaginary, conjugate)
    2323
    24 from log import (exp, log, ln, polylog, dilog)
     24from log import (exp, log, ln, polylog, dilog, lambert_w)
    2525
    2626
    2727from transcendental import (exponential_integral_1,
  • sage/functions/log.py

    diff --git a/sage/functions/log.py b/sage/functions/log.py
    a b  
    11"""
    22Logarithmic functions
    33"""
    4 from sage.symbolic.function import GinacFunction
     4from sage.symbolic.function import GinacFunction, BuiltinFunction, is_inexact
     5
     6from sage.libs.mpmath import utils as mpmath_utils
     7from sage.structure.coerce import parent
     8from sage.symbolic.expression import Expression
     9
    510
    611class Function_exp(GinacFunction):
    712    def __init__(self):
     
    435440
    436441dilog = Function_dilog()
    437442
     443
     444class Function_lambert_w(BuiltinFunction):
     445    r"""
     446        The principle branch of the Lambert W function `W_0(z)`.
     447
     448        This function satisfies the equation:
     449
     450        .. math::
     451
     452            z = W_0(z) e^{W_0(z)}
     453
     454        IMPUT:
     455
     456        ``z`` - a complex number
     457
     458        ALGORITHM:
     459
     460        Numerical evaluation is handled using the mpmath library.
     461
     462        REFERENCES:
     463
     464        http://en.wikipedia.org/wiki/Lambert_W_function
     465
     466        EXAMPLES::
     467
     468            sage: lambert_w(1.0)
     469            0.567143290409784
     470            sage: lambert_w(-1).n()
     471            -0.318131505204764 + 1.33723570143069*I
     472            sage: lambert_w(-1.5 + 5*I)
     473            1.17418016254171 + 1.10651494102011*I
     474
     475            sage: lambert_w(RealField(100)(1))
     476            0.56714329040978387299996866221
     477
     478            sage: S = solve(e^(5*x)+x==0, x, to_poly_solve=True)
     479            sage: z = S[0].rhs(); z
     480            -1/5*lambert_w(5)
     481            sage: N(z)
     482            -0.265344933048440
     483
     484       Check the defining equation numerically at `z=5`::
     485
     486            sage: N(lambert_w(5)*exp(lambert_w(5)) - 5)
     487            0.000000000000000
     488
     489    """
     490    def __init__(self):
     491        """
     492        See the docstring for :meth:`Function_lambert_w`.
     493
     494        EXAMPLES::
     495
     496            sage: lambert_w(1.0)
     497            0.567143290409784
     498
     499        """
     500        BuiltinFunction.__init__(self, "lambert_w", nargs=1, latex_name=r'W_0',
     501                                 conversions=dict(maxima='lambert_w'))
     502
     503    def _eval_(self, z):
     504        """
     505        EXAMPLES::
     506
     507            sage: lambert_w(0)
     508            lambert_w(0)
     509            sage: x = var('x')
     510            sage: lambert_w(x)
     511            lambert_w(x)
     512            sage: lambert_w(0.0)
     513            0.000000000000000
     514
     515        """
     516        if not isinstance(z, Expression) and is_inexact(z):
     517            return self._evalf_(z, parent(z))
     518
     519        return None
     520
     521    def _evalf_(self, z, parent=None):
     522        """
     523        EXAMPLES::
     524
     525            sage: N(lambert_w(1))
     526            0.567143290409784
     527            sage: lambert_w(RealField(100)(1))
     528            0.56714329040978387299996866221
     529
     530        """
     531        import mpmath
     532        return mpmath_utils.call(mpmath.lambertw, z, parent=parent)
     533
     534    def _derivative_(self, z, diff_param=None):
     535        """
     536        The derivative of `W_0(x)` is `W_0(x)/(x \cdot W_0(x) + x)`.
     537
     538        EXAMPLES::
     539
     540            sage: x = var('x')
     541            sage: derivative(lambert_w(x), x)
     542            lambert_w(x)/(x*lambert_w(x) + x)
     543
     544        """
     545        return lambert_w(z)/(z*lambert_w(z)+z)
     546
     547lambert_w = Function_lambert_w()
     548