# Ticket #1173: trac_1173_add_complex_argument_erf.patch

File trac_1173_add_complex_argument_erf.patch, 5.6 KB (added by D.S. McNeil, 12 years ago)
• ## sage/functions/other.py

# HG changeset patch
# User D. S. McNeil
# Date 1298514253 -28800
# Node ID 678841360c1b8902336e2138ca893236bbc5d7cf
# Parent  8438b7c20d79c02a2ece3e1c3f7224a772ff8f07
Trac 1173: add complex-argument erf

diff -r 8438b7c20d79 -r 678841360c1b sage/functions/other.py
 a one_half = ~SR(2) class Function_erf(BuiltinFunction): _eval_ = BuiltinFunction._eval_default def __init__(self): r""" The error function, defined as \text{erf}(x) = \frac{2}{\sqrt{\pi}} \int_0^x e^{-t^2} dt. Sage currently only implements the error function (via a call to PARI) when the input is real. Sage implements the error function for both real and complex arguments (via mpmath). EXAMPLES:: sage: erf(2) erf(2) sage: erf(2).n() 0.995322265018953 sage: loads(dumps(erf)) erf sage: erf(2).n(100) 0.99532226501895273416206925637 sage: erf(ComplexField(100)(2+3j)) -20.829461427614568389103088452 + 8.6873182714701631444280787545*I sage: a = sqrt(pi)*I*erf(2*I)/2 sage: a 1/2*I*sqrt(pi)*erf(2*I) sage: CC(a) -16.4526277655072 Note that erf(0) is immediately evaluated, but this behaviour can be suppressed via the hold parameter, and then undone via simplify: The following fails because we haven't implemented erf yet for complex values:: sage: complex(erf(3*I)) Traceback (most recent call last): ... TypeError: unable to simplify to complex approximation sage: erf(0) 0 sage: erf(0,hold=True) erf(0) sage: simplify(erf(0,hold=True)) 0 TESTS: TESTS:: Check if conversion from maxima elements work:: sage: merf = maxima(erf(x)).sage().operator() sage: merf == erf True Make sure we can dump and load it: sage: loads(dumps(erf(2))) erf(2) Check to make sure that exact ring inputs return unevaluated (note that zero is an exception), that inexact rings evaluate, and that everything returns an appropriate type: sage: exact = SR, ZZ, QQ, int, long sage: list(erf(ring(1)) for ring in exact) [erf(1), erf(1), erf(1), erf(1), erf(1L)] sage: erf(e), erf(pi) (erf(e), erf(pi)) sage: inexact = (RR, RealField(100), RDF, float, CC, ComplexField(100), CDF, complex) sage: list(erf(ring(1)) for ring in inexact) [0.842700792949715, 0.84270079294971486934122063508, 0.84270079295, 0.84270079294971489, 0.842700792949715, 0.84270079294971486934122063508, 0.84270079295, (0.84270079294971489+0j)] sage: list(parent(ring(1)) == parent(erf(ring(1))) for ring in inexact) [True, True, True, True, True, True, True, True] Make sure that we can hold: sage: erf(ComplexField(100)(2+3j),hold=True) erf(2.0000000000000000000000000000 + 3.0000000000000000000000000000*I) Check that large-precision ComplexField inputs don't trigger an mpmath OverflowError (strange bug while developing): sage: CC(erf(ComplexField(1000)(2+3j))) -20.8294614276146 + 8.68731827147016*I """ BuiltinFunction.__init__(self, "erf", latex_name=r"\text{erf}") def _eval_(self, x): """ EXAMPLES:: sage: erf(1) erf(1) sage: erf(2.0) 0.995322265018953 TESTS:: Test that trac #8983 is fixed -- although it appears to have been fixed by maxima-related changes, let's keep it that way: sage: erf(0) 0 sage: solve(erf(x)==0,x) [x == 0] Verify we're returning the appropriate zero: sage: erf(0) 0 sage: erf(0.0) 0.000000000000000 sage: erf(RealField(100)(0)) 0.00000000000000000000000000000 """ if not isinstance(x, Expression) and is_inexact(x): return self._evalf_(x, parent(x)) if x == 0: return parent(x)(0) def _evalf_(self, x, parent=None): """ EXAMPLES:: sage: erf(2).n() 0.995322265018953 sage: erf(2).n(150) Traceback (most recent call last): ... NotImplementedError: erf not implemented for precision higher than 53 0.99532226501895273416206925636725292861089180 sage: erf(ComplexField(150)(2j)) 18.564802414575552598704291913241017198858002*I """ from mpmath import erf try: prec = parent.prec() except AttributeError: # not a Sage parent prec = 0 if prec > 53: raise NotImplementedError, "erf not implemented for precision higher than 53" return parent(1 - pari(float(x)).erfc()) except AttributeError: prec = 53 return parent(mpmath_utils.call(erf, x, prec=prec)) def _derivative_(self, x, diff_param=None): """ Derivative of erf function