TBCI Numerical high perf. C++ Library 2.8.0
TOMS404.C
Go to the documentation of this file.
1
4/* toms404.f -- translated by f2c (version 19970219).
5 You must link the resulting object file with the libraries:
6 -lf2c -lm (in that order)
7*/
8
9/* $Id: TOMS404.C,v 1.2.2.12 2019/05/28 11:13:02 garloff Exp $ */
10
11#if defined(__GNUC__) && __GNUC__ == 2 && defined(__cplusplus)
12# undef __cplusplus /* workaround for buggy gcc-2.96 */
13#endif
14
15#include "tbci/specfun/prototypes.h"
16#include "tbci/specfun/prototypes2.h"
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21#include "tbci/lapack/f2c.h"
22/* Table of constant values */
23
24static integer c__2 = 2;
25
26/* ALGORITHM 404 COLLECTED ALGORITHMS FROM ACM. */
27/* ALGORITHM APPEARED IN COMM. ACM, VOL. 14, NO. 01, */
28/* P. 048. */
29/* Complex */ /*VOID*/
30void cgamma_(complex *ret_val, complex *z__)
31{
32 /* Format strings */
33 static char fmt_900[] = "(1x,2e14.7,10x,\002ARGUMENT OF GAMMA FUNCTION I\
34S TOO CLOSE TO A POLE\002)";
35 static char fmt_910[] = "(\002 ERROR - STIRLING*S SERIES HAS NOT CONVERG\
36ED\002/14x,\002Z = \002,2e14.7)";
37
38 /* System generated locals */
39 integer i__1;
40 real r__1;
41 complex q__1, q__2, q__3, q__4, q__5, q__6;
42
43 /* Builtin functions: declared in prototypes.h */
44
45 /* Local variables */
46 static complex term;
47 static integer iout;
48 static complex a;
49 static real c__[12];
50 static integer i__, j, m;
51 static complex t;
52 static real x, y, xdist;
53 static complex pi, zm, tt;
54 static logical reflek;
55 static complex den;
56 static real tol;
57 static complex sum;
58
59 /* Fortran I/O blocks */
60 static cilist io___9 = { 0, 0, 0, fmt_900, 0 };
61 static cilist io___18 = { 0, 0, 0, fmt_910, 0 };
62
63
64/* SET IOUT FOR PROPER OUTPUT CHANNEL OF COMPUTER SYSTEM FOR */
65/* ERROR MESSAGES */
66 iout = 3;
67 pi.r = (float)3.14159265359, pi.i = (float)0.;
68 x = z__->r;
69 y = r_imag(z__);
70/* TOL = LIMIT OF PRECISION OF COMPUTER SYSTEM IN SINGLE PRECISI */
71 tol = (float)1e-7;
72 reflek = TRUE_;
73/* DETERMINE WHETHER Z IS TOO CLOSE TO A POLE */
74/* CHECK WHETHER TOO CLOSE TO ORIGIN */
75 if (x >= tol) {
76 goto L20;
77 }
78/* FIND THE NEAREST POLE AND COMPUTE DISTANCE TO IT */
79 xdist = x - (integer) (x - (float).5);
80 q__1.r = xdist, q__1.i = y;
81 zm.r = q__1.r, zm.i = q__1.i;
82 if (c_abs(&zm) >= tol) {
83 goto L10;
84 }
85/* IF Z IS TOO CLOSE TO A POLE, PRINT ERROR MESSAGE AND RETURN */
86/* WITH CGAMMA = (1.E7,0.0E0) */
87 io___9.ciunit = iout;
88 s_wsfe(&io___9);
89 do_fio(&c__2, (char *)&(*z__), (ftnlen)sizeof(real));
90 e_wsfe();
91 ret_val->r = (float)1e7, ret_val->i = (float)0.;
92 return ;
93/* FOR REAL(Z) NEGATIVE EMPLOY THE REFLECTION FORMULA */
94/* GAMMA(Z) = PI/(SIN(PI*Z)*GAMMA(1-Z)) */
95/* AND COMPUTE GAMMA(1-Z). NOTE REFLEK IS A TAG TO INDICATE THA */
96/* THIS RELATION MUST BE USED LATER. */
97L10:
98 if (x >= (float)0.) {
99 goto L20;
100 }
101 reflek = FALSE_;
102 q__1.r = (float)1. - z__->r, q__1.i = (float)0. - z__->i;
103 z__->r = q__1.r, z__->i = q__1.i;
104 x = (float)1. - x;
105 y = -y;
106/* IF Z IS NOT TOO CLOSE TO A POLE, MAKE REAL(Z)>10 AND ARG(Z)<P */
107L20:
108 m = 0;
109L40:
110 if (x >= (float)10.) {
111 goto L50;
112 }
113 x += (float)1.;
114 ++m;
115 goto L40;
116L50:
117 if (dabs(y) < x) {
118 goto L60;
119 }
120 x += (float)1.;
121 ++m;
122 goto L50;
123L60:
124 q__1.r = x, q__1.i = y;
125 t.r = q__1.r, t.i = q__1.i;
126 q__1.r = t.r * t.r - t.i * t.i, q__1.i = t.r * t.i + t.i * t.r;
127 tt.r = q__1.r, tt.i = q__1.i;
128 den.r = t.r, den.i = t.i;
129/* COEFFICIENTS IN STIRLING*S APPROXIMATION FOR LN(GAMMA(T)) */
130 c__[0] = (float).08333333333333333;
131 c__[1] = (float)-.002777777777777778;
132 c__[2] = (float)7.936507936507937e-4;
133 c__[3] = (float)-5.952380952380953e-4;
134 c__[4] = (float)8.417508417508417e-4;
135 c__[5] = (float)-.001917526917526918;
136 c__[6] = (float).00641025641025641;
137 c__[7] = (float)-.02955065359477124;
138 c__[8] = (float).1796443723688306;
139 c__[9] = (float)-1.392432216905901;
140 c__[10] = (float)13.40286404416839;
141 q__4.r = t.r - (float).5, q__4.i = t.i + (float)0.;
142 c_log(&q__5, &t);
143 q__3.r = q__4.r * q__5.r - q__4.i * q__5.i, q__3.i = q__4.r * q__5.i +
144 q__4.i * q__5.r;
145 q__2.r = q__3.r - t.r, q__2.i = q__3.i - t.i;
146 r__1 = log((float)6.28318) * (float).5;
147 q__6.r = r__1, q__6.i = (float)0.;
148 q__1.r = q__2.r + q__6.r, q__1.i = q__2.i + q__6.i;
149 sum.r = q__1.r, sum.i = q__1.i;
150 j = 1;
151L70:
152 i__1 = j - 1;
153 q__2.r = c__[i__1], q__2.i = (float)0.;
154 c_div(&q__1, &q__2, &den);
155 term.r = q__1.r, term.i = q__1.i;
156/* TEST REAL AND IMAGINARY PARTS OF LN(GAMMA(Z)) SEPARATELY FOR */
157/* CONVERGENCE. IF Z IS REAL SKIP IMAGINARY PART OF CHECK. */
158 if ((r__1 = term.r / sum.r, dabs(r__1)) >= tol) {
159 goto L80;
160 }
161 if (y == (float)0.) {
162 goto L100;
163 }
164 if ((r__1 = r_imag(&term) / r_imag(&sum), dabs(r__1)) < tol) {
165 goto L100;
166 }
167L80:
168 q__1.r = sum.r + term.r, q__1.i = sum.i + term.i;
169 sum.r = q__1.r, sum.i = q__1.i;
170 ++j;
171 q__1.r = den.r * tt.r - den.i * tt.i, q__1.i = den.r * tt.i + den.i *
172 tt.r;
173 den.r = q__1.r, den.i = q__1.i;
174/* TEST FOR NONCONVERGENCE */
175 if (j == 12) {
176 goto L90;
177 }
178 goto L70;
179/* STIRLING*S SERIES DID NOT CONVERGE. PRINT ERROR MESSAGE AND */
180/* PROCEDE. */
181L90:
182 io___18.ciunit = iout;
183 s_wsfe(&io___18);
184 do_fio(&c__2, (char *)&(*z__), (ftnlen)sizeof(real));
185 e_wsfe();
186/* RECURSION RELATION USED TO OBTAIN LN(GAMMA(Z)) */
187/* LN(GAMMA(Z)) = LN(GAMMA(Z+M)/(Z*(Z+1)*...*(Z+M-1))) */
188/* = LN(GAMMA(Z+M)-LN(Z)-LN(Z+1)-...-LN(Z+M */
189L100:
190 if (m == 0) {
191 goto L120;
192 }
193 i__1 = m;
194 for (i__ = 1; i__ <= i__1; ++i__) {
195 r__1 = i__ * (float)1. - (float)1.;
196 q__1.r = r__1, q__1.i = (float)0.;
197 a.r = q__1.r, a.i = q__1.i;
198/* L110: */
199 q__3.r = z__->r + a.r, q__3.i = z__->i + a.i;
200 c_log(&q__2, &q__3);
201 q__1.r = sum.r - q__2.r, q__1.i = sum.i - q__2.i;
202 sum.r = q__1.r, sum.i = q__1.i;
203 }
204/* CHECK TO SEE IF REFLECTION FORMULA SHOULD BE USED */
205L120:
206 if (reflek) {
207 goto L130;
208 }
209 q__5.r = pi.r * z__->r - pi.i * z__->i, q__5.i = pi.r * z__->i + pi.i *
210 z__->r;
211 c_sin(&q__4, &q__5);
212 c_div(&q__3, &pi, &q__4);
213 c_log(&q__2, &q__3);
214 q__1.r = q__2.r - sum.r, q__1.i = q__2.i - sum.i;
215 sum.r = q__1.r, sum.i = q__1.i;
216 q__1.r = (float)1. - z__->r, q__1.i = (float)0. - z__->i;
217 z__->r = q__1.r, z__->i = q__1.i;
218L130:
219 c_exp(&q__1, &sum);
220 ret_val->r = q__1.r, ret_val->i = q__1.i;
221 return ;
222} /* cgamma_ */
223
224#ifdef __cplusplus
225}
226#endif
227
const Vector< T > const Vector< T > & x
Definition LM_fit.h:97
return
Definition LM_fit.h:82
void cgamma_(complex *ret_val, complex *z__)
Definition TOMS404.C:30
static integer c__2
Definition TOMS404.C:24
doublereal y
Definition TOMS_707.C:27
const double pi
Definition constants.h:38
TBCI__ cplx< T > log(const TBCI__ cplx< T > &z)
Definition cplx.h:771
long int ftnlen
Definition f2c.h:67
int logical
Definition f2c.h:35
#define TRUE_
Definition f2c.h:49
#define dabs(x)
Definition f2c.h:179
#define FALSE_
Definition f2c.h:50
T sum(const FS_Vector< dims, T > &fv)
Definition fs_vector.h:599
const unsigned TMatrix< T > const Matrix< T > * a
#define complex
#define integer
#define real
integer do_fio(integer *, char *, ftnlen)
double r_imag(const complex *)
void c_sin(complex *, const complex *)
void c_exp(complex *, const complex *)
integer s_wsfe(cilist *)
double c_abs(const complex *)
void c_log(complex *, const complex *)
integer e_wsfe()
void c_div(complex *, const complex *, const complex *)
Definition f2c.h:73
ftnint ciunit
Definition f2c.h:74
real r
Definition f2c.h:33
real i
Definition f2c.h:33