cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
thirdparty.h
Go to the documentation of this file.
1 /* This file contains routines (perhaps in modified form) by third parties.
2  * Use and distribution of these works are determined by their respective copyrights. */
3 
4 #ifndef THIRDPARTY_H_
5 #define THIRDPARTY_H_
6 
7 #include "physconst.h"
8 
9 /*============================================================================*/
10 
11 /* these are the routines in thirdparty.cpp */
12 
13 bool linfit(
14  long n,
15  const double x[], /* x[n] */
16  const double y[], /* y[n] */
17  double &a,
18  double &siga,
19  double &b,
20  double &sigb
21 );
22 
25 static const int NPRE_FACTORIAL = 171;
26 
27 /* largest value of fct function corresponding to factorial in six j sjs calculation */
28 static const int MXDSF = 340;
29 
31 double factorial(long n);
32 
34 double lfactorial(long n);
35 
36 complex<double> cdgamma(complex<double> x);
37 
38 double bessel_j0(double x);
39 double bessel_y0(double x);
40 double bessel_j1(double x);
41 double bessel_y1(double x);
42 double bessel_jn(int n, double x);
43 double bessel_yn(int n, double x);
44 
45 double ellpk(double x);
46 
51 double expn(int n, double x);
52 
54 #ifndef HAVE_ERF
55 double erf(double);
56 #endif
57 #ifndef HAVE_ERFC
58 double erfc(double);
59 #endif
60 
61 double erfce(double);
62 
63 double igam (double a, double x);
64 double igamc (double a, double x);
65 double igamc_scaled(double a, double x);
66 
67 double bessel_k0(double x);
68 double bessel_k0_scaled(double x);
69 double bessel_k1(double x);
70 double bessel_k1_scaled(double x);
71 void bessel_k0_k1(double x, double* k0val, double* k1val);
72 void bessel_k0_k1_scaled(double x, double* k0val, double* k1val);
73 
74 double bessel_i0(double x);
75 double bessel_i0_scaled(double x);
76 double bessel_i1(double x);
77 double bessel_i1_scaled(double x);
78 void bessel_i0_i1(double x, double* k0val, double* k1val);
79 void bessel_i0_i1_scaled(double x, double* k0val, double* k1val);
80 
81 #ifndef HAVE_SINCOS
82 // this is a GNU extension
83 inline void sincos(double x, double* s, double* c)
84 {
85  *s = sin(x);
86  *c = cos(x);
87 }
88 #endif
89 
92 double e1(double x);
93 
95 double e1_scaled(double x);
96 
99 double e2(double t);
100 
101 /* initializes mt[N] with a seed */
102 void init_genrand(unsigned long s);
103 
104 /* initialize by an array with array-length */
105 /* init_key is the array for initializing keys */
106 /* key_length is its length */
107 /* slight change for C++, 2004/2/26 */
108 void init_by_array(unsigned long init_key[], int key_length);
109 
110 /* generates a random number on [0,0xffffffff]-interval */
111 unsigned long genrand_int32(void);
112 
113 /* generates a random number on [0,0x7fffffff]-interval */
114 long genrand_int31(void);
115 
116 /* These real versions are due to Isaku Wada, 2002/01/09 added */
117 /* generates a random number on [0,1]-real-interval */
118 double genrand_real1(void);
119 
120 /* generates a random number on [0,1)-real-interval */
121 double genrand_real2(void);
122 
123 /* generates a random number on (0,1)-real-interval */
124 double genrand_real3(void);
125 
126 /* generates a random number on [0,1) with 53-bit resolution*/
127 double genrand_res53(void);
128 
129 /*============================================================================*/
130 
131 /* these are the routines in thirdparty_interpolate.cpp */
132 
133 void spline_cubic_set( long n, const double t[], const double y[], double ypp[],
134  int ibcbeg, double ybcbeg, int ibcend, double ybcend );
135 void spline_cubic_val( long n, const double t[], double tval, const double y[], const double ypp[],
136  double *yval, double *ypval, double *yppval );
137 
150 inline void spline(const double x[],
151  const double y[],
152  long int n,
153  double yp1,
154  double ypn,
155  double y2a[])
156 {
157  int ibcbeg = ( yp1 > 0.99999e30 ) ? 2 : 1;
158  double ybcbeg = ( yp1 > 0.99999e30 ) ? 0. : yp1;
159  int ibcend = ( ypn > 0.99999e30 ) ? 2 : 1;
160  double ybcend = ( ypn > 0.99999e30 ) ? 0. : ypn;
161  spline_cubic_set( n, x, y, y2a, ibcbeg, ybcbeg, ibcend, ybcend );
162  return;
163 }
164 
173 inline void splint(const double xa[],
174  const double ya[],
175  const double y2a[],
176  long int n,
177  double x,
178  double *y)
179 {
180  spline_cubic_val( n, xa, x, ya, y2a, y, NULL, NULL );
181  return;
182 }
183 
184 inline void spldrv(const double xa[],
185  const double ya[],
186  const double y2a[],
187  long int n,
188  double x,
189  double *y)
190 {
191  spline_cubic_val( n, xa, x, ya, y2a, NULL, y, NULL );
192  return;
193 }
194 
195 /* wrapper routine for splint that checks whether x-value is within bounds
196  * if the x-value is out of bounds, a flag will be raised and the function
197  * will be evaluated at the nearest boundary */
198 /* >>chng 03 jan 15, added splint_safe, PvH */
199 inline void splint_safe(const double xa[],
200  const double ya[],
201  const double y2a[],
202  long int n,
203  double x,
204  double *y,
205  bool *lgOutOfBounds)
206 {
207  double xsafe;
208 
209  const double lo_bound = MIN2(xa[0],xa[n-1]);
210  const double hi_bound = MAX2(xa[0],xa[n-1]);
211  const double SAFETY = MAX2(hi_bound-lo_bound,1.)*10.*DBL_EPSILON;
212 
213  DEBUG_ENTRY( "splint_safe()" );
214 
215  if( x < lo_bound-SAFETY )
216  {
217  xsafe = lo_bound;
218  *lgOutOfBounds = true;
219  }
220  else if( x > hi_bound+SAFETY )
221  {
222  xsafe = hi_bound;
223  *lgOutOfBounds = true;
224  }
225  else
226  {
227  xsafe = x;
228  *lgOutOfBounds = false;
229  }
230 
231  splint(xa,ya,y2a,n,xsafe,y);
232  return;
233 }
234 
235 /* wrapper routine for spldrv that checks whether x-value is within bounds
236  * if the x-value is out of bounds, a flag will be raised and the function
237  * will be evaluated at the nearest boundary */
238 /* >>chng 03 jan 15, added spldrv_safe, PvH */
239 inline void spldrv_safe(const double xa[],
240  const double ya[],
241  const double y2a[],
242  long int n,
243  double x,
244  double *y,
245  bool *lgOutOfBounds)
246 {
247  double xsafe;
248 
249  const double lo_bound = MIN2(xa[0],xa[n-1]);
250  const double hi_bound = MAX2(xa[0],xa[n-1]);
251  const double SAFETY = MAX2(fabs(lo_bound),fabs(hi_bound))*10.*DBL_EPSILON;
252 
253  DEBUG_ENTRY( "spldrv_safe()" );
254 
255  if( x < lo_bound-SAFETY )
256  {
257  xsafe = lo_bound;
258  *lgOutOfBounds = true;
259  }
260  else if( x > hi_bound+SAFETY )
261  {
262  xsafe = hi_bound;
263  *lgOutOfBounds = true;
264  }
265  else
266  {
267  xsafe = x;
268  *lgOutOfBounds = false;
269  }
270 
271  spldrv(xa,ya,y2a,n,xsafe,y);
272  return;
273 }
274 
283 double lagrange(const double x[], /* x[n] */
284  const double y[], /* y[n] */
285  long n,
286  double xval);
287 
295 double linint(const double x[], /* x[n] */
296  const double y[], /* y[n] */
297  long n,
298  double xval);
299 
302 template<class T>
303 inline long hunt_bisect(const T x[], /* x[n] */
304  long n,
305  T xval)
306 {
307  /* do bisection hunt */
308  long ilo = 0, ihi = n-1;
309  while( ihi-ilo > 1 )
310  {
311  long imid = (ilo+ihi)/2;
312  if( xval < x[imid] )
313  ihi = imid;
314  else
315  ilo = imid;
316  }
317  return ilo;
318 }
319 
321 template<class T>
322 inline long hunt_bisect(const vector<T>& x,
323  T xval)
324 {
325  return hunt_bisect(get_ptr(x), x.size(), xval);
326 }
327 
328 template<class T>
329 inline long hunt_bisect(const vector<T>& x,
330  size_t n,
331  T xval)
332 {
333  ASSERT( n <= x.size() );
334  return hunt_bisect(get_ptr(x), n, xval);
335 }
336 
339 template<class T>
340 inline long hunt_bisect_reverse(const T x[], /* x[n] */
341  long n,
342  T xval)
343 {
344  /* do bisection hunt */
345  long ilo = 0, ihi = n-1;
346  while( ihi-ilo > 1 )
347  {
348  long imid = (ilo+ihi)/2;
349  if( xval <= x[imid] )
350  ilo = imid;
351  else
352  ihi = imid;
353  }
354  return ilo;
355 }
356 
358 template<class T>
359 inline long hunt_bisect_reverse(const vector<T>& x,
360  T xval)
361 {
362  return hunt_bisect_reverse(get_ptr(x), x.size(), xval);
363 }
364 
365 template<class T>
366 inline long hunt_bisect_reverse(const vector<T>& x,
367  size_t n,
368  T xval)
369 {
370  ASSERT( n <= x.size() );
371  return hunt_bisect_reverse(get_ptr(x), n, xval);
372 }
373 
374 /*============================================================================*/
375 
376 /* these are the routines in thirdparty_lapack.cpp */
377 
378 /* there are wrappers for lapack linear algebra routines.
379  * there are two versions of the lapack routines - a fortran
380  * version that I converted to C with forc to use if nothing else is available
381  * (included in the Cloudy distribution),
382  * and an option to link into an external lapack library that may be optimized
383  * for your machine. By default the tralated C routines will be used.
384  * To use your machine's lapack library instead, define the macro
385  * LAPACK and link into your library. This is usually done with a command line
386  * switch "-DLAPACK" on the compiler command, and the linker option "-llapack"
387  */
388 
397 void getrf_wrapper(long M, long N, double *A, long lda, int32 *ipiv, int32 *info);
398 
410 void getrs_wrapper(char trans, long N, long nrhs, double *A, long lda, int32 *ipiv, double *B, long ldb, int32 *info);
411 
412 void humlik(int n, const realnum x[], realnum y, realnum k[]);
413 
415 void FastVoigtH(realnum a, const realnum v[], realnum y[], size_t n);
416 
417 // calculates y[i] = H(a,v[i]) as defined in Eq. 9-44 of Mihalas
418 inline void VoigtH(realnum a, const realnum v[], realnum y[], int n)
419 {
420  if( a <= 0.1f )
421  {
422  FastVoigtH( a, v, y, n );
423  }
424  else
425  {
426  humlik( n, v, a, y );
427  }
428 }
429 
430 // calculates y[i] = U(a,v[i]) as defined in Eq. 9-45 of Mihalas
431 inline void VoigtU(realnum a, const realnum v[], realnum y[], int n)
432 {
433  VoigtH( a, v, y, n );
434  for( int i=0; i < n; ++i )
435  y[i] /= realnum(SQRTPI);
436 }
437 
438 // VoigtH0(a) returns the value H(a,0) following Eq. 9-44 of Mihalas
439 inline double VoigtH0(double a)
440 {
441  return erfce(a);
442 }
443 
444 // VoigtU0(a) returns the value U(a,0) following Eq. 9-45 of Mihalas
445 inline double VoigtU0(double a)
446 {
447  return erfce(a)/SQRTPI;
448 }
449 
451 static const unsigned int NMD5 = 32;
452 
454 string MD5file(const char* fnam, access_scheme scheme=AS_DEFAULT);
456 string MD5datafile(const char* fnam, access_scheme scheme=AS_DEFAULT);
458 string MD5datastream(fstream& ioFile);
460 string MD5string(const string& str);
461 
462 void test_expn();
463 void chbfit(double a, double b, vector<double>& c, double (*func)(double));
464 
465 void svd(const int nm, const int m, const int n, double *a,
466  double *w, bool matu, double *u, bool matv,
467  double *v, int *ierr, double *rv1);
468 
469 // Evaluate the Gegenbauer (aka ultraspherical) polynomial C_n^(alpha)(x)
470 double gegenbauer(long n, double al, double x);
471 
472 // Diagonal generating function for ultraspherical polynomials,
473 // following Badnell analysis. Integer argument to constructor is
474 // sum of raised and lowered index to the ultraspherical function.
475 class UltraGen
476 {
477  long m_a, m_n;
478  double m_x, m_c1, m_c2;
479 public:
480 UltraGen(long a, double x) : m_a(a), m_n(0), m_x(x), m_c1(0.), m_c2(1.)
481  {}
482  void step()
483  {
484  double c1 = m_c1;
485  --m_a;
486  m_c1 = 2.*m_a*(m_c2-m_x*c1)/(m_n+2*m_a);
487  m_c2 = 2.*m_a*(m_x*m_c2-c1)/(m_n+1);
488  ++m_n;
489  }
490  double val() const
491  {
492  return m_c2;
493  }
494 };
495 
496 // this is the triangular inequality for angular momenta in 2*J format
497 inline bool Triangle2(long J1, long J2, long J3)
498 {
499  return ( J1 >= 0 && J2 >= 0 && J3 >= 0 &&
500  J1 >= abs(J2-J3) && J1 <= J2+J3 &&
501  J1%2 == (J2+J3)%2 );
502 }
503 
504 // 6j Wigner evaluation, original routine Fortran Nigel Badnell 6j for Autostructure
505 double sjs(long j1, long j2, long j3, long l1, long l2, long l3);
506 // version of the above with less range in j, is exported for testing purposes
507 double SixJFull(long j1, long j2, long j3, long j4, long j5, long j6);
508 // Implementation utlizing recursion relation for vector of sixj values,
509 // should be robust to high j
510 void rec6j(double *sixcof, double l2, double l3,
511  double l4, double l5, double l6, double *l1min,
512  double *l1max, double *lmatch, long ndim, long *ier);
513 
514 
515 #endif /* THIRDPARTY_H_ */
void bessel_i0_i1(double x, double *i0val, double *i1val)
double bessel_k0_scaled(double x)
string MD5datastream(fstream &ioFile)
long genrand_int31()
double bessel_i1_scaled(double x)
void getrs_wrapper(char trans, long N, long nrhs, double *A, long lda, int32 *ipiv, double *B, long ldb, int32 *info)
double val() const
Definition: thirdparty.h:490
T * get_ptr(T *v)
Definition: cddefines.h:1109
void chbfit(double a, double b, vector< double > &c, double(*func)(double))
double genrand_real1()
void sincos(double x, double *s, double *c)
Definition: thirdparty.h:83
double m_x
Definition: thirdparty.h:478
void spldrv_safe(const double xa[], const double ya[], const double y2a[], long int n, double x, double *y, bool *lgOutOfBounds)
Definition: thirdparty.h:239
double e1(double x)
void svd(const int nm, const int m, const int n, double *a, double *w, bool matu, double *u, bool matv, double *v, int *ierr, double *rv1)
static const int N
double lfactorial(long n)
Definition: thirdparty.cpp:756
double bessel_i1(double x)
double SixJFull(long j1, long j2, long j3, long j4, long j5, long j6)
realnum FastVoigtH(realnum a, realnum v)
void spline_cubic_val(long n, const double t[], double tval, const double y[], const double ypp[], double *yval, double *ypval, double *yppval)
bool Triangle2(long J1, long J2, long J3)
Definition: thirdparty.h:497
access_scheme
Definition: cpu.h:262
void spline_cubic_set(long n, const double t[], const double y[], double ypp[], int ibcbeg, double ybcbeg, int ibcend, double ybcend)
void spldrv(const double xa[], const double ya[], const double y2a[], long int n, double x, double *y)
Definition: thirdparty.h:184
long hunt_bisect_reverse(const T x[], long n, T xval)
Definition: thirdparty.h:340
unsigned long genrand_int32()
string MD5datafile(const char *fnam, access_scheme scheme)
double sjs(long j1, long j2, long j3, long l1, long l2, long l3)
void bessel_i0_i1_scaled(double x, double *i0val, double *i1val)
double expn(int n, double x)
complex< double > cdgamma(complex< double > x)
Definition: thirdparty.cpp:789
double m_c2
Definition: thirdparty.h:478
#define MIN2(a, b)
Definition: cddefines.h:803
static const int MXDSF
Definition: thirdparty.h:28
void splint(const double xa[], const double ya[], const double y2a[], long int n, double x, double *y)
Definition: thirdparty.h:173
long hunt_bisect(const T x[], long n, T xval)
Definition: thirdparty.h:303
void bessel_k0_k1(double x, double *k0val, double *k1val)
static const int NPRE_FACTORIAL
Definition: thirdparty.h:25
double VoigtU0(double a)
Definition: thirdparty.h:445
void init_by_array(unsigned long init_key[], int key_length)
double bessel_k1(double x)
double erfc(double)
void spline(const double x[], const double y[], long int n, double yp1, double ypn, double y2a[])
Definition: thirdparty.h:150
void getrf_wrapper(long M, long N, double *A, long lda, int32 *ipiv, int32 *info)
double VoigtH0(double a)
Definition: thirdparty.h:439
double bessel_i0_scaled(double x)
double bessel_i0(double x)
double genrand_real2()
double bessel_jn(int n, double x)
static const int M
void bessel_k0_k1_scaled(double x, double *k0val, double *k1val)
float realnum
Definition: cddefines.h:124
double bessel_y0(double x)
string MD5file(const char *fnam, access_scheme scheme)
double bessel_j0(double x)
double bessel_j1(double x)
double igamc(double a, double x)
long m_n
Definition: thirdparty.h:477
bool linfit(long n, const double xorg[], const double yorg[], double &a, double &siga, double &b, double &sigb)
Definition: thirdparty.cpp:46
void test_expn()
double lagrange(const double x[], const double y[], long n, double xval)
double igam(double a, double x)
double factorial(long n)
Definition: thirdparty.cpp:356
static const double SAFETY
#define ASSERT(exp)
Definition: cddefines.h:613
double bessel_yn(int n, double x)
double bessel_k1_scaled(double x)
double erfce(double x)
void VoigtU(realnum a, const realnum v[], realnum y[], int n)
Definition: thirdparty.h:431
void step()
Definition: thirdparty.h:482
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
double m_c1
Definition: thirdparty.h:478
double linint(const double x[], const double y[], long n, double xval)
void humlik(int n, const realnum x[], realnum y, realnum k[])
double bessel_y1(double x)
static const unsigned int NMD5
Definition: thirdparty.h:451
double genrand_res53()
double erf(double)
void splint_safe(const double xa[], const double ya[], const double y2a[], long int n, double x, double *y, bool *lgOutOfBounds)
Definition: thirdparty.h:199
double e1_scaled(double x)
void rec6j(double *sixcof, double l2, double l3, double l4, double l5, double l6, double *l1min, double *l1max, double *lmatch, long ndim, long *ier)
#define MAX2(a, b)
Definition: cddefines.h:824
double ellpk(double x)
double igamc_scaled(double a, double x)
double e2(double x)
void init_genrand(unsigned long s)
UltraGen(long a, double x)
Definition: thirdparty.h:480
long m_a
Definition: thirdparty.h:477
double gegenbauer(long n, double al, double x)
double bessel_k0(double x)
double genrand_real3()
string MD5string(const string &str)
void VoigtH(realnum a, const realnum v[], realnum y[], int n)
Definition: thirdparty.h:418