Я могу реализовать функцию ошибки, erf, сам, но я бы предпочел не делать этого. Есть ли пакет python без внешних зависимостей, который содержит реализацию этой функции? Я нашел этот, но это похоже на часть гораздо большего пакета (и это даже не понятно, какой из них).
Есть ли доступная реализация erf() для Python?
Ответ 1
Так как v.2.7. стандартный математический модуль содержит функцию erf. Это должно быть самым простым способом.
Ответ 2
Я рекомендую SciPy для числовых функций в Python, но если вы хотите что-то без зависимостей, вот функция с ошибкой ошибки меньше 1,5 * 10 -7 для всех входов.
def erf(x):
# save the sign of x
sign = 1 if x >= 0 else -1
x = abs(x)
# constants
a1 = 0.254829592
a2 = -0.284496736
a3 = 1.421413741
a4 = -1.453152027
a5 = 1.061405429
p = 0.3275911
# A&S formula 7.1.26
t = 1.0/(1.0 + p*x)
y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*math.exp(-x*x)
return sign*y # erf(-x) = -erf(x)
Алгоритм из Справочник по математическим функциям, формула 7.1.26.
Ответ 3
Я бы порекомендовал вам скачать numpy (иметь эффективную матрицу в python) и scipy (заменитель инструмента Matlab, который использует numpy). Функция erf лежит в scipy.
>>>from scipy.special import erf
>>>help(erf)
Вы также можете использовать функцию erf, определенную в pylab, но это больше предназначено для построения результатов вычислений, которые вы вычисляете с помощью numpy и scipy. Если вы хотите многофункциональное устройство установка этого программного обеспечения вы можете напрямую использовать Python Enthought distribution.
Ответ 4
Реализация чистого python может быть найдена в модуле mpmath (http://code.google.com/p/mpmath/)
Из строки документа:
>>> from mpmath import *
>>> mp.dps = 15
>>> print erf(0)
0.0
>>> print erf(1)
0.842700792949715
>>> print erf(-1)
-0.842700792949715
>>> print erf(inf)
1.0
>>> print erf(-inf)
-1.0
Для больших реальных x
, \mathrm{erf}(x)
приближается к 1
быстро::
>>> print erf(3)
0.999977909503001
>>> print erf(5)
0.999999999998463
Функция ошибки является нечетной функцией::
>>> nprint(chop(taylor(erf, 0, 5)))
[0.0, 1.12838, 0.0, -0.376126, 0.0, 0.112838]
: func: erf
реализует произвольную точность и
поддерживает комплексные номера::
>>> mp.dps = 50
>>> print erf(0.5)
0.52049987781304653768274665389196452873645157575796
>>> mp.dps = 25
>>> print erf(1+j)
(1.316151281697947644880271 + 0.1904534692378346862841089j)
Связанные функции
См. также: func: erfc
, что более точно для больших x
,
и: func: erfi
, который дает первообразность
\exp(t^2)
.
Интегралы Френеля: func: fresnels
и: func: fresnelc
также связаны с функцией ошибки.
Ответ 5
У меня есть функция, которая выполняет 10 ^ 5 erf-вызовов. На моей машине...
scipy.special.erf делает это время при 6.1s
erf Справочник по математическим функциям принимает 8.3s
erf Numerical Recipes 6.2 принимает 9.5s
(средние три пробега, код, взятый из предыдущих плакатов).
Ответ 6
Чтобы ответить на мой собственный вопрос, я закончил использовать следующий код, адаптированный из версии Java, которую я нашел в другом месте в Интернете:
# from: http://www.cs.princeton.edu/introcs/21function/ErrorFunction.java.html
# Implements the Gauss error function.
# erf(z) = 2 / sqrt(pi) * integral(exp(-t*t), t = 0..z)
#
# fractional error in math formula less than 1.2 * 10 ^ -7.
# although subject to catastrophic cancellation when z in very close to 0
# from Chebyshev fitting formula for erf(z) from Numerical Recipes, 6.2
def erf(z):
t = 1.0 / (1.0 + 0.5 * abs(z))
# use Horner method
ans = 1 - t * math.exp( -z*z - 1.26551223 +
t * ( 1.00002368 +
t * ( 0.37409196 +
t * ( 0.09678418 +
t * (-0.18628806 +
t * ( 0.27886807 +
t * (-1.13520398 +
t * ( 1.48851587 +
t * (-0.82215223 +
t * ( 0.17087277))))))))))
if z >= 0.0:
return ans
else:
return -ans
Ответ 7
Одно примечание для тех, кто стремится к более высокой производительности: векторизовать, если возможно.
import numpy as np
from scipy.special import erf
def vectorized(n):
x = np.random.randn(n)
return erf(x)
def loopstyle(n):
x = np.random.randn(n)
return [erf(v) for v in x]
%timeit vectorized(10e5)
%timeit loopstyle(10e5)
дает результаты
# vectorized
10 loops, best of 3: 108 ms per loop
# loops
1 loops, best of 3: 2.34 s per loop