Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Error Functions
This module provides symbolic error functions. These functions use the `mpmath library` for numerical evaluation and Maxima, Pynac for symbolics.
The main objects which are exported from this module are:
* :meth:`erf <Function_erf>` -- The error function * :meth:`erfc <Function_erfc>` -- The complementary error function * :meth:`erfi <Function_erfi>` -- The imaginary error function * :meth:`erfinv <Function_erfinv>` -- The inverse error function
AUTHORS:
* Original authors ``erf``/``error_fcn`` (c) 2006-2014: Karl-Dieter Crisman, Benjamin Jones, Mike Hansen, William Stein, Burcin Erocal, Jeroen Demeyer, W. D. Joyner, R. Andrew Ohana * Reorganisation in new file, addition of ``erfi``/``erfinv``/``erfc`` (c) 2016: Ralf Stephan
REFERENCES:
- [DLMF-Error]_
- [WP-Error]_ """
#***************************************************************************** # Copyright (C) 2016 Ralf Stephan <gtrwst9 at gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
from sage.symbolic.function import BuiltinFunction from sage.libs.mpmath import utils as mpmath_utils from sage.symbolic.expression import Expression from sage.functions.all import sqrt, exp from sage.symbolic.constants import pi from sage.rings.infinity import unsigned_infinity
class Function_erf(BuiltinFunction): r""" The error function.
The error function is defined for real values as
.. MATH::
\operatorname{erf}(x) = \frac{2}{\sqrt{\pi}} \int_0^x e^{-t^2} dt.
This function is also defined for complex values, via analytic continuation.
EXAMPLES:
We can evaluate numerically::
sage: erf(2) erf(2) sage: erf(2).n() 0.995322265018953 sage: erf(2).n(100) 0.99532226501895273416206925637 sage: erf(ComplexField(100)(2+3j)) -20.829461427614568389103088452 + 8.6873182714701631444280787545*I
Basic symbolic properties are handled by Sage and Maxima::
sage: x = var("x") sage: diff(erf(x),x) 2*e^(-x^2)/sqrt(pi) sage: integrate(erf(x),x) x*erf(x) + e^(-x^2)/sqrt(pi)
ALGORITHM:
Sage implements numerical evaluation of the error function via the ``erf()`` function from mpmath. Symbolics are handled by Sage and Maxima.
REFERENCES:
- :wikipedia:`Error_function` - http://mpmath.googlecode.com/svn/trunk/doc/build/functions/expintegrals.html#error-functions
TESTS:
Check limits::
sage: limit(erf(x),x=0) 0 sage: limit(erf(x),x=infinity) 1
Check that it's odd::
sage: erf(1.0) 0.842700792949715 sage: erf(-1.0) -0.842700792949715
Check against other implementations and against the definition::
sage: erf(3).n() 0.999977909503001 sage: maxima.erf(3).n() 0.999977909503001 sage: (1-pari(3).erfc()) 0.999977909503001 sage: RR(3).erf() 0.999977909503001 sage: (integrate(exp(-x**2),(x,0,3))*2/sqrt(pi)).n() 0.999977909503001
:trac:`9044`::
sage: N(erf(sqrt(2)),200) 0.95449973610364158559943472566693312505644755259664313203267
:trac:`11626`::
sage: n(erf(2),100) 0.99532226501895273416206925637 sage: erf(2).n(100) 0.99532226501895273416206925637
Test (indirectly) :trac:`11885`::
sage: erf(float(0.5)) 0.5204998778130465 sage: erf(complex(0.5)) (0.5204998778130465+0j)
Ensure conversion from maxima elements works::
sage: merf = maxima(erf(x)).sage().operator() sage: merf.parent() == erf.parent() True
Make sure we can dump and load it::
sage: loads(dumps(erf(2))) erf(2)
Special-case 0 for immediate evaluation::
sage: erf(0) 0 sage: solve(erf(x)==0,x) [x == 0]
Make sure that we can hold::
sage: erf(0,hold=True) erf(0) sage: simplify(erf(0,hold=True)) 0
Check that high-precision ComplexField inputs work::
sage: CC(erf(ComplexField(1000)(2+3j))) -20.8294614276146 + 8.68731827147016*I """
def __init__(self): r""" See docstring for :meth:`Function_erf`.
EXAMPLES::
sage: maxima(erf(2)) erf(2) sage: erf(2)._sympy_() erf(2) """ conversions=dict(maxima='erf', sympy='erf', fricas='erf', giac='erf'))
def _eval_(self, x): """ EXAMPLES:
Input is not an expression but is exact::
sage: erf(0) 0 sage: erf(1) erf(1) sage: erf(oo) 1 sage: erf(SR(-oo)) -1 sage: erf(unsigned_infinity) Infinity
Input is not an expression and is not exact::
sage: erf(0.0) 0.000000000000000
Input is an expression but not a trivial zero::
sage: erf(x) erf(x)
Input is an expression which is trivially zero::
sage: erf(SR(0)) 0 """ return x else:
def _evalf_(self, x, parent=None, algorithm=None): """ EXAMPLES::
sage: erf(2).n() 0.995322265018953 sage: erf(2).n(200) 0.99532226501895273416206925636725292861089179704006007673835 sage: erf(pi - 1/2*I).n(100) 1.0000111669099367825726058952 + 1.6332655417638522934072124547e-6*I
TESTS:
Check that PARI/GP through the GP interface gives the same answer::
sage: gp.set_real_precision(59) # random 38 sage: print(gp.eval("1 - erfc(1)")); print(erf(1).n(200)); 0.84270079294971486934122063508260925929606699796630290845994 0.84270079294971486934122063508260925929606699796630290845994
Check that for an imaginary input, the output is also imaginary, see :trac:`13193`::
sage: erf(3.0*I) 1629.99462260157*I sage: erf(33.0*I) 1.51286977510409e471*I """
def _derivative_(self, x, diff_param=None): """ Derivative of erf function.
EXAMPLES::
sage: erf(x).diff(x) 2*e^(-x^2)/sqrt(pi)
TESTS:
Check if :trac:`8568` is fixed::
sage: var('c,x') (c, x) sage: derivative(erf(c*x),x) 2*c*e^(-c^2*x^2)/sqrt(pi) sage: erf(c*x).diff(x)._maxima_init_() '((%pi)^(-1/2))*(_SAGE_VAR_c)*(exp(((_SAGE_VAR_c)^(2))*((_SAGE_VAR_x)^(2))*(-1)))*(2)' """
erf = Function_erf()
class Function_erfi(BuiltinFunction): """ The imaginary error function.
The imaginary error function is defined by
.. MATH::
\operatorname{erfi}(x) = -i \operatorname{erf}(ix). """ def __init__(self): r""" Initialize ``self``.
EXAMPLES::
sage: maxima(erfi(2)) erfi(2) sage: erfi(2)._sympy_() erfi(2) """ BuiltinFunction.__init__(self, "erfi", latex_name=r"\operatorname{erfi}", conversions=dict(maxima='erfi', sympy='erfi', fricas='erfi'))
def _eval_(self, x): """ EXAMPLES::
sage: erfi(0) 0 sage: erfi(SR(0)) 0 sage: erfi(oo) Infinity sage: erfi(SR(-oo)) Infinity """ return x
def _evalf_(self, x, parent=None, algorithm=None): """ EXAMPLES::
sage: erfi(2.) 18.5648024145756 sage: erfi(2).n(100) 18.564802414575552598704291913 sage: erfi(-2*I).n(100) -0.99532226501895273416206925637*I """
def _derivative_(self, x, diff_param=None): """ Derivative of erfi function.
EXAMPLES::
sage: erfi(x).diff(x) 2*e^(x^2)/sqrt(pi)
"""
erfi = Function_erfi()
class Function_erfc(BuiltinFunction): r""" The complementary error function.
The complementary error function is defined by
.. MATH::
\frac{2}{\sqrt{\pi}} \int_t^\infty e^{-x^2} dx.
EXAMPLES::
sage: erfc(6) erfc(6) sage: erfc(6).n() 2.15197367124989e-17 sage: erfc(RealField(100)(1/2)) 0.47950012218695346231725334611
sage: 1 - erfc(0.5) 0.520499877813047 sage: erf(0.5) 0.520499877813047 """ def __init__(self): r""" EXAMPLES::
sage: maxima(erfc(2)) erfc(2) sage: erfc(2)._sympy_() erfc(2) """ BuiltinFunction.__init__(self, "erfc", latex_name=r"\operatorname{erfc}", conversions=dict(maxima='erfc', sympy='erfc', fricas='erfc', giac='erfc'))
def _eval_(self, x): """ EXAMPLES::
sage: erfc(0) 1 sage: erfc(SR(0)) 1 sage: erfc(oo) 0 sage: erfc(SR(-oo)) 2 """ return 1 else: return unsigned_infinity
def _evalf_(self, x, parent=None, algorithm=None): """ EXAMPLES::
sage: erfc(4).n() 1.54172579002800e-8 sage: erfc(4).n(100) 1.5417257900280018852159673487e-8 sage: erfc(4*I).n(100) 1.0000000000000000000000000000 - 1.2969597307176392315279409506e6*I """
def _derivative_(self, x, diff_param=None): """ Derivative of erfc function.
EXAMPLES::
sage: erfc(x).diff(x) -2*e^(-x^2)/sqrt(pi) """
erfc = Function_erfc()
class Function_erfinv(BuiltinFunction): """ The inverse error function.
The inverse error function is defined by:
.. MATH::
\operatorname{erfinv}(x) = \operatorname{erf}^{-1}(x). """ def __init__(self): r""" Initialize ``self``.
EXAMPLES::
sage: erfinv(2)._sympy_() erfinv(2) sage: maxima(erfinv(2)) inverse_erf(2)
TESTS:
Check that :trac:`11349` is fixed::
sage: _ = var('z,t') sage: PDF = exp(-x^2 /2)/sqrt(2*pi) sage: integralExpr = integrate(PDF,x,z,oo).subs(z==log(t)) sage: y = solve(integralExpr==z,t)[0].rhs().subs(z==1/4) sage: y e^(sqrt(2)*erfinv(1/2)) sage: y.n() 1.96303108415826 """ BuiltinFunction.__init__(self, "erfinv", latex_name=r"\operatorname{erfinv}", conversions=dict(sympy='erfinv', maxima='inverse_erf'))
def _eval_(self, x): """ EXAMPLES::
sage: erfinv(0) 0 sage: erfinv(SR(0)) 0 sage: erfinv(1) Infinity """ return x return unsigned_infinity
def _evalf_(self, x, parent=None, algorithm=None): """ EXAMPLES::
sage: erfinv(0.2) 0.179143454621292 sage: erfinv(1/5).n(100) 0.17914345462129167649274901663 """
def _derivative_(self, x, diff_param=None): """ Derivative of inverse erf function.
EXAMPLES::
sage: erfinv(x).diff(x) 1/2*sqrt(pi)*e^(erfinv(x)^2) """
erfinv = Function_erfinv()
from sage.structure.sage_object import register_unpickle_override register_unpickle_override('sage.functions.other', 'Function_erf', Function_erf)
|