|
a/SpezFunkt2.mod.m2pp |
|
b/SpezFunkt2.mod.m2pp |
|
... |
|
... |
41 |
(* 27.08.16, MRi: Argument von dGamma ist nicht mehr "VAR" *)
|
41 |
(* 27.08.16, MRi: Argument von dGamma ist nicht mehr "VAR" *)
|
42 |
(* 27.08.16, MRi: Erstellen der ersten Verionsn von IGamma,JGamma,IBeta *)
|
42 |
(* 27.08.16, MRi: Erstellen der ersten Verionsn von IGamma,JGamma,IBeta *)
|
43 |
(* 16.02.17, MRi: Erstellen der ersten Version (aLnGamma,GamamaIn,dGamit) *)
|
43 |
(* 16.02.17, MRi: Erstellen der ersten Version (aLnGamma,GamamaIn,dGamit) *)
|
44 |
(* 14.02.18, MRi: Hinzufuegen von CLnGamma und CGamma *)
|
44 |
(* 14.02.18, MRi: Hinzufuegen von CLnGamma und CGamma *)
|
45 |
(* 14.02.18, MRi: Erstellen der ersten Version von CdGamma *)
|
45 |
(* 14.02.18, MRi: Erstellen der ersten Version von CdGamma *)
|
46 |
(* 23.05.18, MRi: Erweiterung von CdGamma und aufnahme in SpezFunkt2 *)
|
46 |
(* 23.05.18, MRi: Erweiterung von CdGamma und Aufnahme in SpezFunkt2 *)
|
|
|
47 |
(* 19.12.18, MRi: Ersetzen von GammaIn durch Neuuebersetzng von AS239 *)
|
|
|
48 |
(* da die alte Routine (basierend auf AS32) fuer grosse X *)
|
|
|
49 |
(* teilweise falsche Ergebnisse erzielt hatte. *)
|
47 |
(*------------------------------------------------------------------------*)
|
50 |
(*------------------------------------------------------------------------*)
|
48 |
(* Testroutinen vorhanden, IBeta gegen unabhaengigen Fortran-Code ge- *)
|
51 |
(* Testroutinen vorhanden, IBeta gegen unabhaengigen Fortran-Code ge- *)
|
49 |
(* testet, IGamma & JGamma nur gegen Pascal-Aequivalent *)
|
52 |
(* testet, IGamma & JGamma nur gegen Pascal-Aequivalent *)
|
50 |
(* Testcode (parially against Fortran versions) in TstSpzFun2 *)
|
53 |
(* Testcode (parially against Fortran versions) in TstSpzFun2 *)
|
51 |
(* dGamit wird in BoysInt2Lib intensiv genutzt *)
|
54 |
(* dGamit wird in BoysInt2Lib intensiv genutzt *)
|
52 |
(*------------------------------------------------------------------------*)
|
55 |
(*------------------------------------------------------------------------*)
|
53 |
(* Offene Punkte *)
|
56 |
(* Offene Punkte *)
|
54 |
(* *)
|
57 |
(* *)
|
55 |
(* - Modulstruktur durchsehen und eventuell bereinigen. *)
|
58 |
(* - Modulstruktur durchsehen und eventuell bereinigen. *)
|
56 |
(* - besserer Test fuer CLnGamma, CGamma *)
|
59 |
(* - besserer Test fuer CLnGamma, CGamma *)
|
57 |
(* - Zusammenfuehren von SpezFunkt2 und SpezFunkt2b *)
|
|
|
58 |
(*------------------------------------------------------------------------*)
|
60 |
(*------------------------------------------------------------------------*)
|
59 |
(* Implementation : Michael Riedl *)
|
61 |
(* Implementation : Michael Riedl *)
|
60 |
(* Licence : GNU Lesser General Public License (LGPL) *)
|
62 |
(* Licence : GNU Lesser General Public License (LGPL) *)
|
61 |
(*------------------------------------------------------------------------*)
|
63 |
(*------------------------------------------------------------------------*)
|
62 |
|
64 |
|
|
... |
|
... |
69 |
FROM LongMath IMPORT pi,sqrt,power,ln,exp,sin,cos,round;
|
71 |
FROM LongMath IMPORT pi,sqrt,power,ln,exp,sin,cos,round;
|
70 |
FROM LMathLib IMPORT INF,NAN,MachEps,MinLog,MaxLog,sqrtpi,
|
72 |
FROM LMathLib IMPORT INF,NAN,MachEps,MinLog,MaxLog,sqrtpi,
|
71 |
sinh,cosh,tanh,arctan2;
|
73 |
sinh,cosh,tanh,arctan2;
|
72 |
IMPORT LongComplexMath;
|
74 |
IMPORT LongComplexMath;
|
73 |
FROM LongComplexMath IMPORT zero,one,conj,scalarMult;
|
75 |
FROM LongComplexMath IMPORT zero,one,conj,scalarMult;
|
74 |
FROM F77func IMPORT D1Mach;
|
76 |
FROM F77func IMPORT D1Mach,DMIN;
|
75 |
|
77 |
|
76 |
VAR fast : BOOLEAN;
|
78 |
VAR fast : BOOLEAN;
|
77 |
Sqrt2Pi : LONGREAL; (* sqrt(2 pi) *)
|
79 |
Sqrt2Pi : LONGREAL; (* sqrt(2 pi) *)
|
78 |
bot : LONGREAL; (* wird in d9Gamit genutzt *)
|
80 |
bot : LONGREAL; (* wird in d9Gamit genutzt *)
|
79 |
|
81 |
|
|
... |
|
... |
87 |
ELSE
|
89 |
ELSE
|
88 |
RETURN - ABS(a);
|
90 |
RETURN - ABS(a);
|
89 |
END;
|
91 |
END;
|
90 |
END DSIGN;
|
92 |
END DSIGN;
|
91 |
|
93 |
|
|
|
94 |
PROCEDURE AlNorm(X : LONGREAL;
|
|
|
95 |
Upper : BOOLEAN) : LONGREAL;
|
|
|
96 |
|
|
|
97 |
(*----------------------------------------------------------------*)
|
|
|
98 |
(* Algorithm AS66 Applied Statistics (1973) vol22 no.3 *)
|
|
|
99 |
(* *)
|
|
|
100 |
(* Evaluates the tail area of the standardised normal curve *)
|
|
|
101 |
(* from x to infinity if upper is .true. or *)
|
|
|
102 |
(* from minus infinity to x if upper is .false. *)
|
|
|
103 |
(*----------------------------------------------------------------*)
|
|
|
104 |
|
|
|
105 |
(* machine dependent constants *)
|
|
|
106 |
|
|
|
107 |
CONST ltone = 7.0; utzero = 18.66; con = 1.28;
|
|
|
108 |
|
|
|
109 |
p = 0.398942280444; q = 0.39990348504;
|
|
|
110 |
r = 0.398942280385;
|
|
|
111 |
a1 = 5.75885480458; a2 = 2.62433121679;
|
|
|
112 |
a3 = 5.92885724438;
|
|
|
113 |
b1 = -29.8213557807; b2 = 48.6959930692;
|
|
|
114 |
c1 = -3.8052E-08; c2 = 3.98064794E-04;
|
|
|
115 |
c3 = -0.151679116635; c4 = 4.8385912808;
|
|
|
116 |
c5 = 0.742380924027; c6 = 3.99019417011;
|
|
|
117 |
d1 = 1.00000615302; d2 = 1.98615381364;
|
|
|
118 |
d3 = 5.29330324926; d4 = -15.1508972451;
|
|
|
119 |
d5 = 30.789933034;
|
|
|
120 |
|
|
|
121 |
VAR z,y,alnorm : LONGREAL;
|
|
|
122 |
up : BOOLEAN;
|
|
|
123 |
BEGIN
|
|
|
124 |
up := Upper;
|
|
|
125 |
z := X;
|
|
|
126 |
IF (z < 0.0) THEN
|
|
|
127 |
up := NOT up;
|
|
|
128 |
z := -z;
|
|
|
129 |
END; (* IF *)
|
|
|
130 |
IF (((z <= ltone) OR up) AND (z <= utzero)) THEN
|
|
|
131 |
y := 0.5*z*z;
|
|
|
132 |
IF (z > con) THEN
|
|
|
133 |
alnorm := r*exp(-y) / (z + c1 + d1 / (z + c2 + d2 /
|
|
|
134 |
(z + c3 + d3 / (z + c4 + d4 /
|
|
|
135 |
(z + c5 + d5 / (z + c6))))));
|
|
|
136 |
ELSE
|
|
|
137 |
alnorm := 0.5 - z*(p-q*y / (y + a1 + b1 /
|
|
|
138 |
(y + a2 + b2 / (y + a3))));
|
|
|
139 |
END;
|
|
|
140 |
ELSE
|
|
|
141 |
alnorm := 0.0;
|
|
|
142 |
END; (* IF *)
|
|
|
143 |
IF (NOT up) THEN
|
|
|
144 |
alnorm := 1.0 - alnorm;
|
|
|
145 |
END;
|
|
|
146 |
RETURN alnorm;
|
|
|
147 |
END AlNorm;
|
|
|
148 |
|
92 |
PROCEDURE GammaIn( X : LONGREAL; (* SLATEC *)
|
149 |
PROCEDURE GammaIn( X : LONGREAL;
|
93 |
P : LONGREAL;
|
150 |
P : LONGREAL;
|
94 |
VAR iFehl : INTEGER) : LONGREAL;
|
151 |
VAR Ifault : INTEGER) : LONGREAL;
|
95 |
|
152 |
|
|
|
153 |
(*----------------------------------------------------------------*)
|
|
|
154 |
(* Auxiliary functions required: ALOGAM := logarithm of the gamma *)
|
|
|
155 |
(* function, and AlNorm := algorithm AS66 *)
|
|
|
156 |
(*----------------------------------------------------------------*)
|
|
|
157 |
|
96 |
CONST eps = 1.0E-08;
|
158 |
CONST Tol = 1.0E-14;
|
97 |
Big = 1.0E+37;
|
159 |
Xbig = 1.0E+08; Oflow = MAX(REAL);
|
98 |
Small = 1.0E-37;
|
160 |
Elimit = -88.0; Plimit = 1000.0;
|
99 |
|
161 |
|
100 |
VAR a,an,arg,b,dif,factor : LONGREAL;
|
162 |
VAR pn1,pn2,pn3,pn4,pn5,pn6 : LONGREAL;
|
101 |
g,gin,rn,term,GInc : LONGREAL;
|
163 |
a,b,c,an,rn,arg,gamma : LONGREAL;
|
102 |
i : INTEGER;
|
|
|
103 |
pn : ARRAY [1..6] OF LONGREAL;
|
|
|
104 |
BEGIN
|
164 |
BEGIN
|
105 |
(* check the input. *)
|
165 |
(* Check that we have valid values for X and P *)
|
106 |
IF (P <= 0.0) THEN
|
166 |
IF ((P <= 0.0) OR (X < 0.0)) THEN
|
107 |
iFehl := 1;
|
167 |
Ifault := 1;
|
108 |
RETURN 0.0;
|
168 |
RETURN 0.0;
|
|
|
169 |
END; (* IF *)
|
|
|
170 |
Ifault := 0;
|
109 |
ELSIF (X < 0.0) THEN
|
171 |
IF (X = 0.0) THEN
|
110 |
iFehl:=2;
|
|
|
111 |
RETURN 0.0;
|
172 |
RETURN 0.0;
|
112 |
ELSIF (X = 0.0) THEN
|
173 |
END; (* IF *)
|
113 |
iFehl:=0;
|
174 |
(* Use a normal approximation if P > Plimit *)
|
|
|
175 |
IF (P > Plimit) THEN
|
|
|
176 |
pn1 := 3.0*sqrt(P)*((X/P)**(1.0/3.0)+1.0/(9.0*P)-1.0);
|
|
|
177 |
RETURN AlNorm(pn1,FALSE);
|
|
|
178 |
END; (* IF *)
|
|
|
179 |
(* If X is extremely large compared to P then set gamma = 1 *)
|
|
|
180 |
IF (X > Xbig) THEN
|
114 |
RETURN 0.0;
|
181 |
RETURN 1.0;
|
115 |
END;
|
182 |
END; (* IF *)
|
116 |
|
183 |
IF (X <= 1.0) OR (X < P) THEN
|
117 |
g := aLnGamma(P,iFehl);
|
184 |
(* Use Pearson's series expansion. *)
|
118 |
|
185 |
(* Note that P is not large enough to force overflow in ALOGAM. *)
|
119 |
IF (iFehl # 0) THEN
|
186 |
(* No need to test IFAULT on exit since P > 0. *)
|
120 |
iFehl:=4;
|
187 |
arg := P*ln(X) - X - aLnGamma(P+1.0,Ifault);
|
121 |
RETURN 0.0;
|
|
|
122 |
END;
|
|
|
123 |
|
|
|
124 |
arg := P*ln(X) - X - g;
|
|
|
125 |
|
|
|
126 |
IF (arg < ln(Small)) THEN
|
|
|
127 |
iFehl:=3;
|
|
|
128 |
RETURN 0.0;
|
|
|
129 |
END;
|
|
|
130 |
|
|
|
131 |
iFehl:=0;
|
|
|
132 |
factor := exp(arg);
|
|
|
133 |
|
|
|
134 |
IF (X <= 1.0) OR (X < P) THEN (* calculation by series expansion. *)
|
|
|
135 |
|
|
|
136 |
gin := 1.0;
|
188 |
c := 1.0;
|
137 |
term := 1.0;
|
189 |
gamma := 1.0;
|
138 |
rn := P;
|
190 |
a := P;
|
139 |
LOOP
|
191 |
LOOP
|
140 |
rn := rn + 1.0;
|
192 |
a := a + 1.0;
|
141 |
term := term*X / rn;
|
193 |
c := c*X/a;
|
142 |
gin := gin + term;
|
194 |
gamma := gamma + c;
|
143 |
IF (term <= eps) THEN
|
195 |
IF (c <= Tol) THEN
|
|
|
196 |
arg := arg + ln(gamma);
|
|
|
197 |
gamma := 0.0;
|
|
|
198 |
IF (arg >= Elimit) THEN
|
|
|
199 |
gamma := exp(arg);
|
|
|
200 |
END; (* IF *)
|
144 |
EXIT;
|
201 |
EXIT;
|
145 |
END;
|
202 |
END; (* IF *)
|
146 |
END; (* LOOP *)
|
203 |
END; (* LOOP *)
|
147 |
GInc := gin*factor / P;
|
204 |
ELSE
|
148 |
|
205 |
(* Use a continued fraction expansion *)
|
149 |
ELSE (* calculation by continued fraction. *)
|
206 |
arg := P*ln(X) - X - aLnGamma(P,Ifault);
|
150 |
|
|
|
151 |
a := 1.0 - P;
|
207 |
a := 1.0 - P;
|
152 |
b := a + X + 1.0;
|
208 |
b := a + X + 1.0;
|
153 |
term := 0.0;
|
209 |
c := 0.0;
|
154 |
|
|
|
155 |
pn[1] := 1.0;
|
210 |
pn1 := 1.0;
|
156 |
pn[2] := X;
|
211 |
pn2 := X;
|
157 |
pn[3] := X + 1.0;
|
212 |
pn3 := X + 1.0;
|
158 |
pn[4] := X*b;
|
213 |
pn4 := X*b;
|
159 |
|
|
|
160 |
gin := pn[3] / pn[4];
|
214 |
gamma := pn3/pn4;
|
161 |
|
|
|
162 |
LOOP
|
215 |
LOOP
|
163 |
a:=a + 1.0;
|
216 |
a := a + 1.0;
|
164 |
b:=b + 2.0;
|
217 |
b := b + 2.0;
|
165 |
term:=term + 1.0;
|
218 |
c := c + 1.0;
|
166 |
an := a*term;
|
219 |
an := a*c;
|
167 |
FOR i:=1 TO 2 DO
|
|
|
168 |
pn[i+4] := b*pn[i+2] - an*pn[i];
|
220 |
pn5 := b*pn3 - an*pn1;
|
169 |
END;
|
221 |
pn6 := b*pn4 - an*pn2;
|
170 |
IF (pn[6] # 0.0) THEN
|
222 |
IF (ABS(pn6) > 0.0) THEN
|
171 |
rn := pn[5] / pn[6];
|
223 |
rn := pn5/pn6;
|
172 |
dif := ABS(gin - rn);
|
224 |
IF (ABS(gamma-rn) <= DMIN(Tol,Tol*rn)) THEN
|
173 |
IF (dif <= eps) THEN (* absolute error tolerance satisfied *)
|
225 |
arg := arg + ln(gamma);
|
174 |
IF (dif <= eps*rn) THEN (* relative error tolerance satisfied *)
|
226 |
gamma := 1.0;
|
175 |
GInc := 1.0 - factor*gin;
|
227 |
IF (arg >= Elimit) THEN
|
|
|
228 |
gamma := 1.0 - exp(arg);
|
|
|
229 |
END; (* IF *)
|
176 |
EXIT;
|
230 |
EXIT
|
177 |
END;
|
|
|
178 |
END;
|
231 |
ELSE
|
179 |
gin := rn;
|
232 |
gamma := rn;
|
|
|
233 |
END; (* IF *)
|
180 |
END;
|
234 |
END; (* IF *)
|
181 |
FOR i:=1 TO 4 DO
|
|
|
182 |
pn[i] := pn[i+2];
|
235 |
pn1 := pn3;
|
183 |
END;
|
236 |
pn2 := pn4;
|
|
|
237 |
pn3 := pn5;
|
|
|
238 |
pn4 := pn6;
|
184 |
IF (ABS(pn[5]) >= Big) THEN
|
239 |
IF (ABS(pn5) >= Oflow) THEN
|
185 |
FOR i:=1 TO 4 DO
|
240 |
(* Re-scale terms in continued fraction if terms are large *)
|
186 |
pn[i] := pn[i] / Big;
|
241 |
pn1 := pn1 / Oflow;
|
187 |
END;
|
242 |
pn2 := pn2 / Oflow;
|
|
|
243 |
pn3 := pn3 / Oflow;
|
|
|
244 |
pn4 := pn4 / Oflow;
|
188 |
END;
|
245 |
END; (* IF *)
|
189 |
END; (* LOOP *)
|
246 |
END; (* LOOP *)
|
190 |
|
|
|
191 |
END; (* IF *)
|
247 |
END; (* IF *)
|
192 |
RETURN GInc;
|
248 |
RETURN gamma;
|
193 |
END GammaIn;
|
249 |
END GammaIn;
|
194 |
|
250 |
|
195 |
PROCEDURE GammaU(a,x : LONGREAL) : LONGREAL;
|
251 |
PROCEDURE GammaU(a,x : LONGREAL) : LONGREAL;
|
196 |
|
252 |
|
197 |
(*----------------------------------------------------------------*)
|
253 |
(*----------------------------------------------------------------*)
|