Home
Manual
Packages
Global Index
Keywords
Quick Reference
|
/*
* dawson.i
* Dawson's integral and error functions after SLATEC
*/
func dawson (x)
/* DOCUMENT dawson(x)
* return Dawson's integral, exp(-x^2)*integral[0 to x](exp(t^2)*dt)
* maximum is dawson(0.9241388730) = 0.5410442246
* inflection point is dawson(1.5019752682) = 0.4276866160
* SEE ALSO: erf, erfc
*/
{
{ local mask1,mask2,mask3,xx,yy; }
y = abs(x);
if (any_in(,y,1., mask1, yy, x,xx))
d1 = xx * (0.75 + _cheby_eval(_dawson_1, 2.*yy*yy-1.));
if (any_in(1.,y,4., mask2, yy, x,xx))
d2 = xx * (0.25 + _cheby_eval(_dawson_2, 0.125*yy*yy-1.));
if (any_in(4.,y,, mask3, yy, x,xx))
d3 = (0.50 + _cheby_eval(_dawson_3, 32./(yy*yy)-1.)) / xx;
return merge_n(d1,mask1, d2,mask2, d3,mask3);
}
_dawson_1 = [-.006351734375145949, -.229407147967738690, .022130500939084764,
-.001549265453892985, .000084973277156849, -.000003828266270972,
.000000146285480625, -.000000004851982381, .000000000142146357,
-.000000000003728836, .000000000000088549, -.000000000000001920,
.000000000000000038];
_dawson_2 = [-.056886544105215527, -.318113469961681310, .208738454136422370,
-.124754099137791310, .067869305186676777, -.033659144895270940,
.015260781271987972, -.006348370962596214, .002432674092074852,
-.000862195414910650, .000283765733363216, -.000087057549874170,
.000024986849985481, -.000006731928676416, .000001707857878557,
-.000000409175512264, .000000092828292216, -.000000019991403610,
.000000004096349064, -.000000000800324095, .000000000149385031,
-.000000000026687999, .000000000004571221, -.000000000000751873,
.000000000000118931, -.000000000000018116, .000000000000002661,
-.000000000000000377, .000000000000000051];
_dawson_3 = [ .01690485637765704, .00868325227840695, .00024248640424177,
.00001261182399572, .00000106645331463, .00000013581597947,
.00000002171042356, .00000000286701050, -.00000000019013363,
-.00000000030977804, -.00000000010294148, -.00000000000626035,
.00000000000856313, .00000000000303304, -.00000000000025236,
-.00000000000042106, -.00000000000004431, .00000000000004911,
.00000000000001235, -.00000000000000578, -.00000000000000228,
.00000000000000076, .00000000000000038, -.00000000000000011,
-.00000000000000006, .00000000000000002];
func erf (x)
/* DOCUMENT erf(x)
* return erf(x), 2./sqrt(pi) * integral[0 to x](exp(-t^2)*dt)
* SEE ALSO: erfc, dawson
*/
{
{ local mask1,mask2,mask3,mask4,xx,yy,zz; }
y = abs(x);
if (any_in(,y,1., mask1, yy, x,xx))
e1 = xx * (1.0 + _cheby_eval(_erf_1, 2.*yy*yy-1.));
if (any_in(1.,y,, mask2, yy, x,xx)) {
z = yy*yy;
yy = exp(-z)/yy;
if (any_in(,z,4., mask3, zz, yy,y))
e3 = y * (0.5 + _cheby_eval(_erfc_1, (8./zz-5.)/3.));
if (any_in(4.,z,, mask4, zz, yy,y))
e4 = y * (0.5 + _cheby_eval(_erfc_2, 8./zz-1.));
e2 = sign(xx) * (1.0 - merge_n(e3,mask3, e4,mask4));
}
return merge_n(e1,mask1, e2,mask2);
}
func erfc (x)
/* DOCUMENT erfc(x)
* return erfc(x), 2./sqrt(pi) * integral[x to infinity](exp(-t^2)*dt)
* SEE ALSO: erf, dawson
*/
{
{ local mask1,mask2,mask3,mask4,xx,yy,zz; }
y = abs(x);
if (any_in(,y,1., mask1, yy, x,xx))
e1 = 1.0 - xx * (1.0 + _cheby_eval(_erf_1, 2.*yy*yy-1.));
if (any_in(1.,y,, mask2, yy, x,xx)) {
z = yy*yy;
yy = exp(-z)/yy;
if (any_in(,z,4., mask3, zz, yy,y))
e3 = y * (0.5 + _cheby_eval(_erfc_1, (8./zz-5.)/3.));
if (any_in(4.,z,, mask4, zz, yy,y))
e4 = y * (0.5 + _cheby_eval(_erfc_2, 8./zz-1.));
e2 = 2.*(xx<0.) + sign(xx)*merge_n(e3,mask3, e4,mask4);
}
return merge_n(e1,mask1, e2,mask2);
}
_erf_1 = [-.049046121234691808, -.142261205103713640, .010035582187599796,
-.000576876469976748, .000027419931252196, -.000001104317550734,
.000000038488755420, -.000000001180858253, .000000000032334215,
-.000000000000799101, .000000000000017990, -.000000000000000371,
.000000000000000007];
_erfc_1 = [-.069601346602309501, -.041101339362620893, .003914495866689626,
-.000490639565054897, .000071574790013770, -.000011530716341312,
.000001994670590201, -.000000364266647159, .000000069443726100,
-.000000013712209021, .000000002788389661, -.000000000581416472,
.000000000123892049, -.000000000026906391, .000000000005942614,
-.000000000001332386, .000000000000302804, -.000000000000069666,
.000000000000016208, -.000000000000003809, .000000000000000904,
-.000000000000000216, .000000000000000052];
_erfc_2 = [ .071517931020292500, -.026532434337606719, .001711153977920853,
-.000163751663458512, .000019871293500549, -.000002843712412769,
.000000460616130901, -.000000082277530261, .000000015921418724,
-.000000003295071356, .000000000722343973, -.000000000166485584,
.000000000040103931, -.000000000010048164, .000000000002608272,
-.000000000000699105, .000000000000192946, -.000000000000054704,
.000000000000015901, -.000000000000004729, .000000000000001432,
-.000000000000000439, .000000000000000138, -.000000000000000048];
func _cheby_eval (cs, x)
{
n = numberof(cs);
b0 = b1 = 0.;
x *= 2.;
for (i=0 ; i<n ; ++i) {
b2 = b1;
b1 = b0;
b0 = x*b1 - b2 + cs(n-i);
}
return 0.5*(b0-b2);
}
func any_in (left,x,right, &mask, &xx, a,&aa, b,&bb, c,&cc)
/* DOCUMENT any_in(left,x,right, mask, xx, a,aa, b,bb, c,cc
* return the number of elements of the array X which are in the
* interval LEFT < X <= RIGHT. Also return MASK, which has the
* shape of X and is 1 where X is in the interval and 0 otherwise,
* and XX = X(where(MASK)). Up to three optional arrays A, B, and C
* of the same shape as X may be supplied; the arrays AA, BB, and CC
* analogous to XX are returned. LEFT or RIGHT may be [] for the
* interval to extend to infinity on the corresponding side.
* LEFT and/or RIGHT may be arrays as long as they are conformable
* with X.
* SEE ALSO: merge_n, merge
*/
{
if (is_void(left)) mask = array(1n, dimsof(x));
else mask = (x>left);
if (!is_void(right)) mask &= (x<=right);
list = where(mask);
n = numberof(list);
if (n) {
xx = x(list);
if (!is_void(a)) {
aa = a(list);
if (!is_void(b)) {
bb = b(list);
if (!is_void(c)) cc = c(list);
}
}
}
return n;
}
func merge_n (val,mask, ..)
/* DOCUMENT merge_n(val1,mask1, val2,mask2, ...)
* return array with shape of MASKi (which must all have same shape)
* and values VALi where MASKi is true. Unspecified values will be
* zero; the data type of the result is the data type of the first
* non-nil VALi. Each VALi must be a 1D array of length sum(MASKi!=0).
* SEE ALSO: any_in, merge
*/
{
rslt = dimsof(mask);
while (is_void(val)) {
val = next_arg();
mask = next_arg();
if (is_void(mask)) return array(0., rslt);
}
rslt = array(structof(val), rslt);
for (;;) {
rslt(where(mask)) = val;
do {
val = next_arg();
mask = next_arg();
if (is_void(mask)) return rslt;
} while (is_void(val));
}
}
|