Вопрос касается дополнительной функции ошибок
erfc(x)=2π−−√∫∞xexp(−t2)dt
для «больших» значений ( = n / √Икс в исходном вопросе) - то есть между 100 и 700 000 или около того. (На практике любое значение, большее, чем примерно 6, следует рассматривать как «большое», как мы увидим.) Обратите внимание, что поскольку оно будет использоваться для вычисления p-значений, при получении более трех значащих (десятичных) цифр мало значения. ,= н / 2-√
Для начала рассмотрим приближение, предложенное @Iterator,
е(x)=1−1−exp(−x2(4+ax2π+ax2))−−−−−−−−−−−−−−−−−−−−−−√,
где
a=8(π−3)3(4−π)≈0.439862.
Хотя это отличное приближение к самой функции ошибки, это ужасное приближение к . Однако есть способ систематически исправить это.erfc
Для значений p, связанных с такими большими значениями , нас интересует относительная ошибка f ( x ) / erfc ( x ) - 1 : мы надеемся, что ее абсолютное значение будет менее 0,001 для трех значащих цифр точности. К сожалению, это выражение трудно изучить для больших x из-за недостаточного вычисления при двойной точности. Вот одна попытка, которая показывает относительную ошибку по сравнению с x для 0 ≤ x ≤ 5,8 :x f(x)/erfc(x)−1xx0≤x≤5.8
Расчет становится нестабильным, когда превышает 5,3 или около того и не может поставить одну значащую цифру после 5,8. Это неудивительно: exp ( - 5.8 2 ) ≈ 10 - 14.6 расширяет границы арифметики двойной точности. Поскольку нет никаких доказательств того, что относительная погрешность будет приемлемо мала для больших x , мы должны сделать лучше.xexp(−5.82)≈10−14.6x
Выполнение вычислений в расширенной арифметике (с Mathematica ) улучшает нашу картину происходящего:
Ошибка быстро увеличивается с и не показывает никаких признаков выравнивания. В прошлом х = 10 или около того, это приближение даже не доставляет одну достоверную цифру информации!xx=10
Тем не менее, сюжет начинает выглядеть линейно. Можно предположить, что относительная ошибка прямо пропорциональна . (Это имеет смысл с теоретической точки зрения : erfc является явно нечетной функцией, а f явно четной, поэтому их отношение должно быть нечетной функцией. Таким образом, можно ожидать, что относительная ошибка, если она возрастет, будет вести себя как нечетная степень x .) Это приводит нас к изучению относительной ошибки, деленной на х . Эквивалентно, я выбираю изучить x ⋅ erfc ( x ) / f ( x )xerfcfx xx⋅erfc(x)/f(x)Потому что надежда на это должна иметь постоянное предельное значение. Вот его график:
Наше предположение, похоже, подтверждается: это соотношение, похоже, приближается к пределу около 8 или около того. Когда спрошено, Mathematica предоставит это:
a1 = Limit[x (Erfc[x]/f[x]), x -> \[Infinity]]
Значение 1 = 2. Это позволяет нам улучшить оценку:мы беремa1=2π√e3(−4+π)28(−3+π)≈7.94325
f1(x)=f(x)a1x
в качестве первого уточнения приближения. Когда действительно велико - больше нескольких тысяч - это приближение просто отлично. Поскольку он все еще не будет достаточно хорош для интересного диапазона аргументов между 5.3 и 2000 или около того, давайте повторим процедуру. На этот раз обратная относительная ошибка - в частности, выражение 1 - erfc ( x ) / f 1 ( x ) - должна вести себя как 1 / x 2 для больших x (в силу предыдущих соображений четности). Соответственно умножаем на х 2x5.320001−erfc(x)/f1(x)1/x2xx2 и найдите следующий предел:
a2 = Limit[x^2 (a1 - x (Erfc[x]/f[x])), x -> \[Infinity]]
Значение
a2=132π−−√e3(−4+π)28(−3+π)(32−9(−4+π)3π(−3+π)2)≈114.687.
Этот процесс может продолжаться сколько угодно. Я сделал еще один шаг, найдя
a3 = Limit[x^2 (a2 - x^2 (a1 - x (Erfc[x]/f[x]))), x -> \[Infinity]]
со значением приблизительно 1623,67. (Полное выражение включает рациональную функцию степени восьмого и слишком длинное, чтобы быть здесь полезным.)π
Разматывание этих операций дает наше окончательное приближение
f3(x)=f(x)(a1−a2/x2+a3/x4)/x.
The error is proportional to Икс- 6. Of import is the constant of proportionality, so we plot Икс6( 1 - erfc ( x ) / f3( х ) ):
It rapidly approaches a limiting value around 2660.59. Using the approximation е3, we obtain estimates of эрфк (х) whose relative accuracy is better than 2661 / х6 for all х > 0. Once Икс exceeds 20 or so, we have our three significant digits (or far more, as Икс gets larger). As a check, here is a table comparing the correct values to the approximation for Икс between 10 and 20:
x Erfc Approximation
10 2.088*10^-45 2.094*10^-45
11 1.441*10^-54 1.443*10^-54
12 1.356*10^-64 1.357*10^-64
13 1.740*10^-75 1.741*10^-75
14 3.037*10^-87 3.038*10^-87
15 7.213*10^-100 7.215*10^-100
16 2.328*10^-113 2.329*10^-113
17 1.021*10^-127 1.021*10^-127
18 6.082*10^-143 6.083*10^-143
19 4.918*10^-159 4.918*10^-159
20 5.396*10^-176 5.396*10^-176
х = 8NormSDist
f. However, that's not hard: when x is large enough to cause underflows in the exponential, the square root is well approximated by half the exponential,
f(x)≈12exp(−x2(4+ax2π+ax2)).
Computing the logarithm of this (in base 10) is simple, and readily gives the desired result. For example, let x=1000. The common logarithm of this approximation is
log10(f(x))≈(−10002(4+a⋅10002π+a⋅10002)−log(2))/log(10)∼−434295.63047.
Exponentiating yields
f(1000)≈2.34169⋅10−434296.
Applying the correction (in f3) produces
erfc(1000)≈1.86003 70486 32328⋅10−434298.
Note that the correction reduces the original approximation by over 99% (and indeed, a1/x≈1%.) (This approximation differs from the correct value only in the last digit. Another well-known approximation, exp(−x2)/(xπ−−√), equals 1.860038⋅10−434298, erring in the sixth significant digit. I'm sure we could improve that one, too, if we wanted, using the same techniques.)