1
2
3
4
5
14
15#define max_iter_int 10
16#define num_range 5
17#define PI 3.14159265358979323846L
18#define SQR(x) ((x)*(x))
19#include <errno.h>
20
21double cerf_experimental_integration( int kind, double x, double y )
22
23{
24
25 static int mu = 0;
26 int intgr_debug = 0;
27 static double intgr_delta=2.2e-16, intgr_eps=5.5e-20;
28
29 if( x<0 || y<0 ) {
30 fprintf( stderr, "negative arguments not yet implemented\n" );
31 exit( EDOM );
32 }
33
34 double w = sqrt(2)*x;
35 double gamma = sqrt(2)*y;
36
37 int iter;
38 int kaux;
39 int isig;
40 int N;
41 int j;
42 long double S=0;
43 long double S_last;
44 long double s;
45 long double T;
46
47 static int firstCall=1;
48 static int iterDone[2][num_range];
49 static int Nm[num_range][max_iter_int];
50 static int Np[num_range][max_iter_int];
51 static long double *ak[2][num_range][max_iter_int];
52 static long double *bk[2][num_range][max_iter_int];
53
54 long double u;
55 long double e;
56 long double tk;
57 long double chi;
58 long double dchi;
59 long double h;
60 long double k;
61 long double f;
62 long double ahk;
63 long double chk;
64 long double dhk;
65 double p;
66 double q;
67 const double Smin=2e-20;
68
69
70 if ( firstCall ) {
71 for ( j=0; j<num_range; ++ j ) {
72 iterDone[0][j] = -1;
73 iterDone[1][j] = -1;
74 }
75 firstCall = 0;
76 }
77
78
79 j=1; p=1.4; q=0.6;
80
81
82 if( intgr_debug & 4 )
83 N = 100;
84 else
85 N = 40;
86 for ( iter=0; iter<max_iter_int; ++iter ) {
87
88 if ( iter>iterDone[kind][j] ) {
89 if ( N>1e6 )
90 return -3;
91 Nm[j][iter] = N;
92 Np[j][iter] = N;
93 if ( !( ak[kind][j][iter]=malloc((sizeof(long double))*
94 (Nm[j][iter]+1+Np[j][iter])) ) ||
95 !( bk[kind][j][iter]=malloc((sizeof(long double))*
96 (Nm[j][iter]+1+Np[j][iter])) ) ) {
97 fprintf( stderr, "Workspace allocation failed\n" );
98 exit( ENOMEM );
99 }
100 h = logl( logl( 42*N/intgr_delta/Smin ) / p ) / N;
101 isig=1-2*(Nm[j][iter]&1);
102 for ( kaux=-Nm[j][iter]; kaux<=Np[j][iter]; ++kaux ) {
103 k = kaux;
104 if( !kind )
105 k -= 0.5;
106 u = k*h;
107 chi = 2*p*sinhl(u) + 2*q*u;
108 dchi = 2*p*coshl(u) + 2*q;
109 if ( u==0 ) {
110 if ( k!=0 )
111 return -4;
112
113 ahk = PI/h/dchi;
114 dhk = 0.5;
115 chk = sin( ahk );
116 } else {
117 if ( -chi>DBL_MAX_EXP/2 )
118 return -5;
119 e = expl( -chi );
120 ahk = PI/h * u/(1-e);
121 dhk = 1/(1-e) - u*e*dchi/SQR(1-e);
122 chk = e>1 ?
123 ( kind ? sinl( PI*k/(1-e) ) : cosl( PI*k/(1-e) ) ) :
124 isig * sinl( PI*k*e/(1-e) );
125 }
126 ak[kind][j][iter][kaux+Nm[j][iter]] = ahk;
127 bk[kind][j][iter][kaux+Nm[j][iter]] = dhk * chk;
128 isig = -isig;
129 }
130 iterDone[kind][j] = iter;
131 }
132
133 S_last = S;
134 S = 0;
135 T = 0;
136 for ( kaux=-Nm[j][iter]; kaux<=Np[j][iter]; ++kaux ) {
137 tk = ak[kind][j][iter][kaux+Nm[j][iter]] / w;
138 f = expl(-tk*gamma-SQR(tk)/2);
139 if ( mu )
140 f /= tk;
141 s = bk[kind][j][iter][kaux+Nm[j][iter]] * f;
142 S += s;
143 T += fabsl(s);
144 if( intgr_debug & 2 )
145 printf( "%2i %6i %12.4Lg %12.4Lg"
146 " %12.4Lg %12.4Lg %12.4Lg %12.4Lg\n",
147 iter, kaux, ak[kind][j][iter][kaux+Nm[j][iter]],
148 bk[kind][j][iter][kaux+Nm[j][iter]], f, s, S, T );
149 }
150 if( intgr_debug & 1 )
151 printf( "%23.17Le %23.17Le\n", S, T );
152
153
154 if ( intgr_debug & 4 )
155 return -1;
156 else if ( S < 0 )
157 return -6;
158 else if ( intgr_eps*T > intgr_delta*fabs(S) )
159 return -2;
160 else if ( iter && fabs(S-S_last) + intgr_eps*T < intgr_delta*fabs(S) )
161 return S*sqrt(2*PI)/w;
162
163
164
165 N *= 2;
166 }
167 return -9;
168}
169
170double cerf_experimental_imw( double x, double y )
171{
172 return cerf_experimental_integration( 1, x, y );
173}
174
175double cerf_experimental_rew( double x, double y )
176{
177 return cerf_experimental_integration( 0, x, y );
178}
179 |