Matlab has a special function that is not available in any of the collections for Python that I know (numpy, scipy, mpmath, ...).
Perhaps there are other places where you can find such features?
UPD For anyone who thinks the question is trivial, try computing this function first for an argument of ~ 30.
UPD2 Arbitrary precision is a good workaround, but if possible, I would rather avoid this. I need the "standard" accuracy of the machine (no more no less) and maximum speed.
UPD3 It turns out mpmath
gives a surprisingly inaccurate result. Even where standard python math
works, mpmath
results mpmath
worse. This makes it completely useless.
UPD4 Code for comparing different methods of calculating erfcx.
import numpy as np def int_erfcx(x): "Integral which gives erfcx" from scipy import integrate def f(xi): return np.exp(-x*xi)*np.exp(-0.5*xi*xi) return 0.79788456080286535595*integrate.quad(f, 0.0,min(2.0,50.0/(1.0+x))+100.0,limit=500)[0] def my_erfcx(x): """MM Shepherd and JG Laframboise, MATHEMATICS OF COMPUTATION 36, 249 (1981) Note that it is reasonable to compute it in long double (or whatever python has) """ ch_coef=[np.float128(0.1177578934567401754080e+01), np.float128( -0.4590054580646477331e-02), np.float128( -0.84249133366517915584e-01), np.float128( 0.59209939998191890498e-01), np.float128( -0.26658668435305752277e-01), np.float128( 0.9074997670705265094e-02), np.float128( -0.2413163540417608191e-02), np.float128( 0.490775836525808632e-03), np.float128( -0.69169733025012064e-04), np.float128( 0.4139027986073010e-05), np.float128( 0.774038306619849e-06), np.float128( -0.218864010492344e-06), np.float128( 0.10764999465671e-07), np.float128( 0.4521959811218e-08), np.float128( -0.775440020883e-09), np.float128( -0.63180883409e-10), np.float128( 0.28687950109e-10), np.float128( 0.194558685e-12), np.float128( -0.965469675e-12), np.float128( 0.32525481e-13), np.float128( 0.33478119e-13), np.float128( -0.1864563e-14), np.float128( -0.1250795e-14), np.float128( 0.74182e-16), np.float128( 0.50681e-16), np.float128( -0.2237e-17), np.float128( -0.2187e-17), np.float128( 0.27e-19), np.float128( 0.97e-19), np.float128( 0.3e-20), np.float128( -0.4e-20)] K=np.float128(3.75) y = (xK) / (x+K) y2 = np.float128(2.0)*y (d, dd) = (ch_coef[-1], np.float128(0.0)) for cj in ch_coef[-2:0:-1]: (d, dd) = (y2 * d - dd + cj, d) d = y * d - dd + ch_coef[0] return d/(np.float128(1)+np.float128(2)*x) def math_erfcx(x): import scipy.special as spec return spec.erfc(x) * np.exp(x*x) def mpmath_erfcx(x): import mpmath return mpmath.exp(x**2) * mpmath.erfc(x) if __name__ == "__main__": x=np.linspace(1.0,26.0,200) X=np.linspace(1.0,100.0,200) intY = np.array([int_erfcx(xx*np.sqrt(2)) for xx in X]) myY = np.array([my_erfcx(xx) for xx in X]) myy = np.array([my_erfcx(xx) for xx in x]) mathy = np.array([math_erfcx(xx) for xx in x]) mpmathy = np.array([mpmath_erfcx(xx) for xx in x]) mpmathY = np.array([mpmath_erfcx(xx) for xx in X]) print ("Integral vs exact: %g"%max(np.abs(intY-myY)/myY)) print ("math vs exact: %g"%max(np.abs(mathy-myy)/myy)) print ("mpmath vs math: %g"%max(np.abs(mpmathy-mathy)/mathy)) print ("mpmath vs integral:%g"%max(np.abs(mpmathY-intY)/intY)) exit()
For me he gives
Integral vs exact: 6.81236e-16 math vs exact: 7.1137e-16 mpmath vs math: 4.90899e-14 mpmath vs integral:8.85422e-13
Obviously, math
gives the best possible accuracy when it works, and mpmath
gives an error a couple of orders of magnitude more, where math
works and even more for large arguments.