OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
functions.cpp
Go to the documentation of this file.
1 /* fuctions.C
2  Collection of special functions
3 
4  NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5)
5 
6  Revision history
7  Date Description Programmer
8  ------------ -------------------------------------------- ------------
9  30/04/1992 Copied from "numerical recipies" Rene Bakker
10 
11 */
12 
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <math.h>
16 
18 
19 /* Bessel function
20  ======================================================================= */
21 
22 static double bessj0(double x) {
23  double ax, z;
24  double xx, y, ans, ans1, ans2;
25 
26  if((ax = fabs(x)) < 8.0) {
27  y = x * x;
28  ans1 = 57568490574.0 + y * (-13362590354.0 + y * (651619640.7
29  + y * (-11214424.18 + y * (77392.33017 + y * (-184.9052456)))));
30  ans2 = 57568490411.0 + y * (1029532985.0 + y * (9494680.718
31  + y * (59272.64853 + y * (267.8532712 + y * 1.0))));
32  ans = ans1 / ans2;
33  } else {
34  z = 8.0 / ax;
35  y = z * z;
36  xx = ax - 0.785398164;
37  ans1 = 1.0 + y * (-0.1098628627e-2 + y * (0.2734510407e-4
38  + y * (-0.2073370639e-5 + y * 0.2093887211e-6)));
39  ans2 = -0.1562499995e-1 + y * (0.1430488765e-3
40  + y * (-0.6911147651e-5 + y * (0.7621095161e-6
41  - y * 0.934935152e-7)));
42  ans = sqrt(0.636619772 / ax) * (cos(xx) * ans1 - z * sin(xx) * ans2);
43  }
44  return (double) ans;
45 } /* bessj0 */
46 
47 static double bessj1(double x) {
48  double ax, z;
49  double xx, y, ans, ans1, ans2;
50 
51  if((ax = fabs(x)) < 8.0) {
52  y = x * x;
53  ans1 = x * (72362614232.0 + y * (-7895059235.0 + y * (242396853.1
54  + y * (-2972611.439 + y * (15704.48260 + y * (-30.16036606))))));
55  ans2 = 144725228442.0 + y * (2300535178.0 + y * (18583304.74
56  + y * (99447.43394 + y * (376.9991397 + y * 1.0))));
57  ans = ans1 / ans2;
58  } else {
59  z = 8.0 / ax;
60  y = z * z;
61  xx = ax - 2.356194491;
62  ans1 = 1.0 + y * (0.183105e-2 + y * (-0.3516396496e-4
63  + y * (0.2457520174e-5 + y * (-0.240337019e-6))));
64  ans2 = 0.04687499995 + y * (-0.2002690873e-3
65  + y * (0.8449199096e-5 + y * (-0.88228987e-6
66  + y * 0.105787412e-6)));
67  ans = sqrt(0.636619772 / ax) * (cos(xx) * ans1 - z * sin(xx) * ans2);
68  if(x < 0.0) ans = -ans;
69  }
70  return (double) ans;
71 } /* bessj1 */
72 
73 /*************************\
74 * *
75 * External functions *
76 * *
77 \*************************/
78 
79 #define ACC 40.0
80 #define BIGNO 1.0e10
81 #define BIGNI 1.0e-10
82 
83 double bessj(int n, double x) {
84  int j, jsum, m;
85  double ax, bj, bjm, bjp, sum, tox, ans;
86 
87  if(n < 0) {
88  fprintf(stderr, "Illegal argument bessel function.\n");
89  exit(1);
90  }
91  if(n == 0) return bessj0(x);
92  if(n == 1) return bessj1(x);
93 
94  ax = fabs(x);
95  if(ax == 0.0) return 0.0;
96  else if(ax > (double) n) {
97  tox = 2.0 / ax;
98  bjm = bessj0(ax);
99  bj = bessj1(ax);
100  for(j = 1; j < n; j++) {
101  bjp = j * tox * bj - bjm;
102  bjm = bj;
103  bj = bjp;
104  }
105  ans = bj;
106  } else {
107  tox = 2.0 / ax;
108  m = 2 * ((n + (int) sqrt(ACC * n)) / 2);
109  jsum = 0;
110  bjp = ans = sum = 0.0;
111  bj = 1.0;
112  for(j = m; j > 0; j--) {
113  bjm = j * tox * bj - bjp;
114  bjp = bj;
115  bj = bjm;
116  if(fabs(bj) > BIGNO) {
117  bj *= BIGNI;
118  bjp *= BIGNI;
119  ans *= BIGNI;
120  sum *= BIGNI;
121  }
122  if(jsum) sum += bj;
123  jsum = !jsum;
124  if(j == n) ans = bjp;
125  }
126  sum = 2.0 * sum - bj;
127  ans /= sum;
128  }
129  return x < 0.0 && n % 2 == 1 ? -ans : ans;
130 } /* bessj */
131 
132 
133 
134 #undef ACC
135 #undef BIGNO
136 #undef BIGNI
137 
138 
139 /* Error function
140  ======================================================================= */
141 
142 /*
143  errfc()
144  Returns the complementary error function erfc(x) with fractional error
145  everywhere less than 1.2e-07. */
146 double errfc(double x) {
147  double t, z, ans;
148 
149  z = fabs(x);
150  t = 1.0 / (1.0 + 0.5 * z);
151  ans = t * exp(-z * z - 1.26551223 +
152  t * (1.00002368 +
153  t * (0.37409196 +
154  t * (0.09678418 +
155  t * (-0.18628806 +
156  t * (0.27886807 +
157  t * (-1.13520398 +
158  t * (1.48851587 +
159  t * (-0.82215223 +
160  t * 0.17087277)))))))));
161  return x >= 0.0 ? ans : 2.0 - ans;
162 } /*erfc() */
double bessj(int n, double x)
Definition: functions.cpp:83
PETE_TUTree< FnFabs, typename T::PETE_Expr_t > fabs(const PETE_Expr< T > &l)
Definition: PETE.h:815
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Tps< T > exp(const Tps< T > &x)
Exponential.
Definition: TpsMath.h:165
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1213
#define BIGNI
Definition: functions.cpp:81
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
double errfc(double x)
Definition: functions.cpp:146
#define ACC
Definition: functions.cpp:79
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
#define BIGNO
Definition: functions.cpp:80