AmpTools
URMath.cc
Go to the documentation of this file.
1 // @(#)root/base:$Name: $:$Id: URMath.cc,v 1.1.1.1 2006/11/15 18:01:50 mashephe Exp $
2 // Author: Fons Rademakers 29/07/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
13 // //
14 // URMath //
15 // //
16 // Encapsulate math routines (i.e. provide a kind of namespace). //
17 // For the time being avoid templates. //
18 // //
20 
21 #include "UpRootMinuit/URMath.h"
22 //#include "TError.h"
23 #include <math.h>
24 #include <string.h>
25 
26 //const Double_urt
27 // URMath::Pi = 3.14159265358979323846,
28 // URMath::E = 2.7182818284590452354;
29 
30 #if defined(hocuspocus)
31 //______________________________________________________________________________
32 #if defined(R__MAC) || defined(R__KCC)
33 Double_urt hypot(Double_urt x, Double_urt y) {
34  return sqrt(x*x+y*y);
35 }
36 #endif
37 
38 //______________________________________________________________________________
40 {
41  return (Long_urt) (sqrt((Double_urt)x) + 0.5);
42 }
43 
44 //______________________________________________________________________________
46 {
47  return (Long_urt) (hypot((Double_urt)x, (Double_urt)y) + 0.5);
48 }
49 
50 //______________________________________________________________________________
52 {
53  return hypot(x, y);
54 }
55 
56 //______________________________________________________________________________
58 {
59 #if defined(WIN32) || defined(R__KCC)
60  return log(x+sqrt(x*x+1));
61 #else
62  return asinh(x);
63 #endif
64 }
65 
66 //______________________________________________________________________________
68 {
69 #if defined(WIN32) || defined(R__KCC)
70  return log(x+sqrt(x*x-1));
71 #else
72  return acosh(x);
73 #endif
74 }
75 
76 //______________________________________________________________________________
78 {
79 #if defined(WIN32) || defined(R__KCC)
80  return log((1+x)/(1-x))/2;
81 #else
82  return atanh(x);
83 #endif
84 }
85 
86 //______________________________________________________________________________
88 {
89  return ceil(x);
90 }
91 
92 //______________________________________________________________________________
94 {
95  return floor(x);
96 }
97 
98 //______________________________________________________________________________
100 {
101  return log(x)/log(2.0);
102 }
103 
104 //______________________________________________________________________________
106 {
107  // Return next prime number after x, unless x is a prime in which case
108  // x is returned.
109 
110  if (x < 2)
111  return 2;
112  if (x == 3)
113  return 3;
114 
115  if (x % 2 == 0)
116  x++;
117 
118  Long_urt sqr = (Long_urt) sqrt((Double_urt)x) + 1;
119 
120  for (;;) {
121  Long_urt n;
122  for (n = 3; (n <= sqr) && ((x % n) != 0); n += 2)
123  ;
124  if (n > sqr)
125  return x;
126  x += 2;
127  }
128 }
129 
130 //______________________________________________________________________________
132 {
133  // Round to nearest integer. Rounds half integers to the nearest
134  // even integer.
135 
136  int i;
137  if (x >= 0) {
138  i = int(x + 0.5);
139  if (x + 0.5 == Float_urt(i) && i & 1) i--;
140  } else {
141  i = int(x - 0.5);
142  if (x - 0.5 == Float_urt(i) && i & 1) i++;
143 
144  }
145  return i;
146 }
147 
148 //______________________________________________________________________________
150 {
151  // Round to nearest integer. Rounds half integers to the nearest
152  // even integer.
153 
154  int i;
155  if (x >= 0) {
156  i = int(x + 0.5);
157  if (x + 0.5 == Double_urt(i) && i & 1) i--;
158  } else {
159  i = int(x - 0.5);
160  if (x - 0.5 == Double_urt(i) && i & 1) i++;
161 
162  }
163  return i;
164 }
165 
166 //______________________________________________________________________________
168 {
169  // Calculate the Cross Product of two vectors:
170  // out = [v1 x v2]
171 
172  out[0] = v1[1] * v2[2] - v1[2] * v2[1];
173  out[1] = v1[2] * v2[0] - v1[0] * v2[2];
174  out[2] = v1[0] * v2[1] - v1[1] * v2[0];
175 
176  return out;
177 }
178 
179 //______________________________________________________________________________
181 {
182  // Calculate the Cross Product of two vectors:
183  // out = [v1 x v2]
184 
185  out[0] = v1[1] * v2[2] - v1[2] * v2[1];
186  out[1] = v1[2] * v2[0] - v1[0] * v2[2];
187  out[2] = v1[0] * v2[1] - v1[1] * v2[0];
188  return out;
189 }
190 
191 //______________________________________________________________________________
193 {
194  // Computation of the error function erf(x).
195  // Erf(x) = (2/sqrt(pi)) Integral(exp(-t^2))dt between 0 and x
196 
197  //--- NvE 14-nov-1998 UU-SAP Utrecht
198 
199  return (1-Erfc(x));
200 }
201 
202 //______________________________________________________________________________
204 {
205  // Compute the complementary error function erfc(x).
206  // Erfc(x) = (2/sqrt(pi)) Integral(exp(-t^2))dt between x and infinity
207  //
208  //--- Nve 14-nov-1998 UU-SAP Utrecht
209 
210  // The parameters of the Chebyshev fit
211  const Double_urt a1 = -1.26551223, a2 = 1.00002368,
212  a3 = 0.37409196, a4 = 0.09678418,
213  a5 = -0.18628806, a6 = 0.27886807,
214  a7 = -1.13520398, a8 = 1.48851587,
215  a9 = -0.82215223, a10 = 0.17087277;
216 
217  Double_urt v = 1; // The return value
218  Double_urt z = Abs(x);
219 
220  if (z <= 0) return v; // erfc(0)=1
221 
222  Double_urt t = 1/(1+0.5*z);
223 
224  v = t*Exp((-z*z) +a1+t*(a2+t*(a3+t*(a4+t*(a5+t*(a6+t*(a7+t*(a8+t*(a9+t*a10)))))))));
225 
226  if (x < 0) v = 2-v; // erfc(-x)=2-erfc(x)
227 
228  return v;
229 }
230 
231 //______________________________________________________________________________
233 {
234  // Compute factorial(n)
235 
236  if(n <= 0) return 1.;
237  Double_urt x=1;
238  Int_urt b=0;
239  do {
240  b++;
241  x *= b;
242  } while(b!=n);
243  return x;
244 }
245 
246 //______________________________________________________________________________
248 {
249  // Computation of the normal frequency function freq(x).
250  // Freq(x) = (1/sqrt(2pi)) Integral(exp(-t^2/2))dt between -infinity and x.
251  //
252  // Translated from CERNLIB C300 by Rene Brun.
253 
254  const Double_urt C1 = 0.56418958354775629;
255  const Double_urt W2 = 1.41421356237309505;
256 
257  const Double_urt p10 = 2.4266795523053175e+2, q10 = 2.1505887586986120e+2,
258  p11 = 2.1979261618294152e+1, q11 = 9.1164905404514901e+1,
259  p12 = 6.9963834886191355e+0, q12 = 1.5082797630407787e+1,
260  p13 =-3.5609843701815385e-2, q13 = 1;
261 
262  const Double_urt p20 = 3.00459261020161601e+2, q20 = 3.00459260956983293e+2,
263  p21 = 4.51918953711872942e+2, q21 = 7.90950925327898027e+2,
264  p22 = 3.39320816734343687e+2, q22 = 9.31354094850609621e+2,
265  p23 = 1.52989285046940404e+2, q23 = 6.38980264465631167e+2,
266  p24 = 4.31622272220567353e+1, q24 = 2.77585444743987643e+2,
267  p25 = 7.21175825088309366e+0, q25 = 7.70001529352294730e+1,
268  p26 = 5.64195517478973971e-1, q26 = 1.27827273196294235e+1,
269  p27 =-1.36864857382716707e-7, q27 = 1;
270 
271  const Double_urt p30 =-2.99610707703542174e-3, q30 = 1.06209230528467918e-2,
272  p31 =-4.94730910623250734e-2, q31 = 1.91308926107829841e-1,
273  p32 =-2.26956593539686930e-1, q32 = 1.05167510706793207e+0,
274  p33 =-2.78661308609647788e-1, q33 = 1.98733201817135256e+0,
275  p34 =-2.23192459734184686e-2, q34 = 1;
276 
277  Double_urt v = URMath::Abs(x)/W2;
278  Double_urt vv = v*v;
279  Double_urt ap, aq, h, hc, y;
280  if (v < 0.5) {
281  y=vv;
282  ap=p13;
283  aq=q13;
284  ap = p12 +y*ap;
285  ap = p11 +y*ap;
286  ap = p10 +y*ap;
287  aq = q12 +y*aq;
288  aq = q11 +y*aq;
289  aq = q10 +y*aq;
290  h = v*ap/aq;
291  hc = 1-h;
292  } else if (v < 4) {
293  ap = p27;
294  aq = q27;
295  ap = p26 +v*ap;
296  ap = p25 +v*ap;
297  ap = p24 +v*ap;
298  ap = p23 +v*ap;
299  ap = p22 +v*ap;
300  ap = p21 +v*ap;
301  ap = p20 +v*ap;
302  aq = q26 +v*aq;
303  aq = q25 +v*aq;
304  aq = q24 +v*aq;
305  aq = q23 +v*aq;
306  aq = q22 +v*aq;
307  aq = q21 +v*aq;
308  aq = q20 +v*aq;
309  hc = URMath::Exp(-vv)*ap/aq;
310  h = 1-hc;
311  } else {
312  y = 1/vv;
313  ap = p34;
314  aq = q34;
315  ap = p33 +y*ap;
316  ap = p32 +y*ap;
317  ap = p31 +y*ap;
318  ap = p30 +y*ap;
319  aq = q33 +y*aq;
320  aq = q32 +y*aq;
321  aq = q31 +y*aq;
322  aq = q30 +y*aq;
323  hc = URMath::Exp(-vv)*(C1+y*ap/aq)/v;
324  h = 1-hc;
325  }
326  if (x > 0) return 0.5 +0.5*h;
327  else return 0.5*hc;
328 }
329 
330 //______________________________________________________________________________
332 {
333  // Computation of gamma(z) for all z>0.
334  //
335  // C.Lanczos, SIAM Journal of Numerical Analysis B1 (1964), 86.
336  //
337  //--- Nve 14-nov-1998 UU-SAP Utrecht
338 
339  if (z<=0) return 0;
340 
341  Double_urt v = LnGamma(z);
342  return Exp(v);
343 }
344 
345 //______________________________________________________________________________
347 {
348  // Computation of the incomplete gamma function P(a,x)
349  //
350  //--- Nve 14-nov-1998 UU-SAP Utrecht
351 
352  if (a <= 0 || x <= 0) return 0;
353 
354  if (x < (a+1)) return GamSer(a,x);
355  else return GamCf(a,x);
356 }
357 
358 //______________________________________________________________________________
359 Double_urt URMath::GamCf(Double_urt a,Double_urt x)
360 {
361  // Computation of the incomplete gamma function P(a,x)
362  // via its continued fraction representation.
363  //
364  //--- Nve 14-nov-1998 UU-SAP Utrecht
365 
366  Int_urt itmax = 100; // Maximum number of iterations
367  Double_urt eps = 3.e-7; // Relative accuracy
368  Double_urt fpmin = 1.e-30; // Smallest Double_urt value allowed here
369 
370  if (a <= 0 || x <= 0) return 0;
371 
372  Double_urt gln = LnGamma(a);
373  Double_urt b = x+1-a;
374  Double_urt c = 1/fpmin;
375  Double_urt d = 1/b;
376  Double_urt h = d;
377  Double_urt an,del;
378  for (Int_urt i=1; i<=itmax; i++) {
379  an = Double_urt(-i)*(Double_urt(i)-a);
380  b += 2;
381  d = an*d+b;
382  if (Abs(d) < fpmin) d = fpmin;
383  c = b+an/c;
384  if (Abs(c) < fpmin) c = fpmin;
385  d = 1/d;
386  del = d*c;
387  h = h*del;
388  if (Abs(del-1) < eps) break;
389  //if (i==itmax) cout << "*GamCf(a,x)* a too large or itmax too small" << endl;
390  }
391  Double_urt v = Exp(-x+a*Log(x)-gln)*h;
392  return (1-v);
393 }
394 
395 //______________________________________________________________________________
396 Double_urt URMath::GamSer(Double_urt a,Double_urt x)
397 {
398  // Computation of the incomplete gamma function P(a,x)
399  // via its series representation.
400  //
401  //--- Nve 14-nov-1998 UU-SAP Utrecht
402 
403  Int_urt itmax = 100; // Maximum number of iterations
404  Double_urt eps = 3.e-7; // Relative accuracy
405 
406  if (a <= 0 || x <= 0) return 0;
407 
408  Double_urt gln = LnGamma(a);
409  Double_urt ap = a;
410  Double_urt sum = 1/a;
411  Double_urt del = sum;
412  for (Int_urt n=1; n<=itmax; n++) {
413  ap += 1;
414  del = del*x/ap;
415  sum += del;
416  if (URMath::Abs(del) < Abs(sum*eps)) break;
417  //if (n==itmax) cout << "*GamSer(a,x)* a too large or itmax too small" << endl;
418  }
419  Double_urt v = sum*Exp(-x+a*Log(x)-gln);
420  return v;
421 }
422 
423 //______________________________________________________________________________
425 {
426  // Calculate a Breit Wigner function with mean and gamma.
427 
428  Double_urt bw = gamma/((x-mean)*(x-mean) + gamma*gamma/4);
429  return bw/(2*Pi());
430 }
431 
432 //______________________________________________________________________________
434 {
435  // Calculate a gaussian function with mean and sigma.
436  // if norm=kurTRUE (default is kurFALSE) the result is divided by sqrt(2*Pi)*sigma
437  if (sigma == 0) return 1.e30;
438  Double_urt arg = (x-mean)/sigma;
439  Double_urt res = URMath::Exp(-0.5*arg*arg);
440  if (!norm) return res;
441  return res/(2.50662827463100024*sigma); //sqrt(2*Pi)=2.50662827463100024
442 }
443 
444 //______________________________________________________________________________
446 {
447  // The LANDAU function with mpv(most probable value) and sigma.
448  // This function has been adapted from the CERNLIB routine G110 denlan.
449 
450  Double_urt p1[5] = {0.4259894875,-0.1249762550, 0.03984243700, -0.006298287635, 0.001511162253};
451  Double_urt q1[5] = {1.0 ,-0.3388260629, 0.09594393323, -0.01608042283, 0.003778942063};
452 
453  Double_urt p2[5] = {0.1788541609, 0.1173957403, 0.01488850518, -0.001394989411, 0.0001283617211};
454  Double_urt q2[5] = {1.0 , 0.7428795082, 0.3153932961, 0.06694219548, 0.008790609714};
455 
456  Double_urt p3[5] = {0.1788544503, 0.09359161662,0.006325387654, 0.00006611667319,-0.000002031049101};
457  Double_urt q3[5] = {1.0 , 0.6097809921, 0.2560616665, 0.04746722384, 0.006957301675};
458 
459  Double_urt p4[5] = {0.9874054407, 118.6723273, 849.2794360, -743.7792444, 427.0262186};
460  Double_urt q4[5] = {1.0 , 106.8615961, 337.6496214, 2016.712389, 1597.063511};
461 
462  Double_urt p5[5] = {1.003675074, 167.5702434, 4789.711289, 21217.86767, -22324.94910};
463  Double_urt q5[5] = {1.0 , 156.9424537, 3745.310488, 9834.698876, 66924.28357};
464 
465  Double_urt p6[5] = {1.000827619, 664.9143136, 62972.92665, 475554.6998, -5743609.109};
466  Double_urt q6[5] = {1.0 , 651.4101098, 56974.73333, 165917.4725, -2815759.939};
467 
468  Double_urt a1[3] = {0.04166666667,-0.01996527778, 0.02709538966};
469 
470  Double_urt a2[2] = {-1.845568670,-4.284640743};
471 
472  if (sigma <= 0) return 0;
473  Double_urt v = (x-mpv)/sigma;
474  Double_urt u, ue, us, den;
475  if (v < -5.5) {
476  u = URMath::Exp(v+1.0);
477  ue = URMath::Exp(-1/u);
478  us = URMath::Sqrt(u);
479  den = 0.3989422803*(ue/us)*(1+(a1[0]+(a1[1]+a1[2]*u)*u)*u);
480  } else if(v < -1) {
481  u = URMath::Exp(-v-1);
482  den = URMath::Exp(-u)*URMath::Sqrt(u)*
483  (p1[0]+(p1[1]+(p1[2]+(p1[3]+p1[4]*v)*v)*v)*v)/
484  (q1[0]+(q1[1]+(q1[2]+(q1[3]+q1[4]*v)*v)*v)*v);
485  } else if(v < 1) {
486  den = (p2[0]+(p2[1]+(p2[2]+(p2[3]+p2[4]*v)*v)*v)*v)/
487  (q2[0]+(q2[1]+(q2[2]+(q2[3]+q2[4]*v)*v)*v)*v);
488  } else if(v < 5) {
489  den = (p3[0]+(p3[1]+(p3[2]+(p3[3]+p3[4]*v)*v)*v)*v)/
490  (q3[0]+(q3[1]+(q3[2]+(q3[3]+q3[4]*v)*v)*v)*v);
491  } else if(v < 12) {
492  u = 1/v;
493  den = u*u*(p4[0]+(p4[1]+(p4[2]+(p4[3]+p4[4]*u)*u)*u)*u)/
494  (q4[0]+(q4[1]+(q4[2]+(q4[3]+q4[4]*u)*u)*u)*u);
495  } else if(v < 50) {
496  u = 1/v;
497  den = u*u*(p5[0]+(p5[1]+(p5[2]+(p5[3]+p5[4]*u)*u)*u)*u)/
498  (q5[0]+(q5[1]+(q5[2]+(q5[3]+q5[4]*u)*u)*u)*u);
499  } else if(v < 300) {
500  u = 1/v;
501  den = u*u*(p6[0]+(p6[1]+(p6[2]+(p6[3]+p6[4]*u)*u)*u)*u)/
502  (q6[0]+(q6[1]+(q6[2]+(q6[3]+q6[4]*u)*u)*u)*u);
503  } else {
504  u = 1/(v-v*URMath::Log(v)/(v+1));
505  den = u*u*(1+(a2[0]+a2[1]*u)*u);
506  }
507  return den;
508 }
509 
510 //______________________________________________________________________________
512 {
513  // Computation of ln[gamma(z)] for all z>0.
514  //
515  // C.Lanczos, SIAM Journal of Numerical Analysis B1 (1964), 86.
516  //
517  // The accuracy of the result is better than 2e-10.
518  //
519  //--- Nve 14-nov-1998 UU-SAP Utrecht
520 
521  if (z<=0) return 0;
522 
523  // Coefficients for the series expansion
524  Double_urt c[7] = { 2.5066282746310005, 76.18009172947146, -86.50532032941677
525  ,24.01409824083091, -1.231739572450155, 0.1208650973866179e-2
526  ,-0.5395239384953e-5};
527 
528  Double_urt x = z;
529  Double_urt y = x;
530  Double_urt tmp = x+5.5;
531  tmp = (x+0.5)*Log(tmp)-tmp;
532  Double_urt ser = 1.000000000190015;
533  for (Int_urt i=1; i<7; i++) {
534  y += 1;
535  ser += c[i]/y;
536  }
537  Double_urt v = tmp+Log(c[0]*ser/x);
538  return v;
539 }
540 
541 //______________________________________________________________________________
543 {
544  // Normalize a vector v in place.
545  // Returns the norm of the original vector.
546 
547  Float_urt d = Sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
548  if (d != 0) {
549  v[0] /= d;
550  v[1] /= d;
551  v[2] /= d;
552  }
553  return d;
554 }
555 
556 //______________________________________________________________________________
558 {
559  // Normalize a vector v in place.
560  // Returns the norm of the original vector.
561 
562  Double_urt d = Sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
563  if (d != 0)
564  {
565  v[0] /= d;
566  v[1] /= d;
567  v[2] /= d;
568  }
569  return d;
570 }
571 
572 //______________________________________________________________________________
574 {
575  // Calculate a normal vector of a plane.
576  //
577  // Input:
578  // Float_urt *p1,*p2,*p3 - 3 3D points belonged the plane to define it.
579  //
580  // Return:
581  // Pointer to 3D normal vector (normalized)
582 
583  Float_urt v1[3], v2[3];
584 
585  v1[0] = p2[0] - p1[0];
586  v1[1] = p2[1] - p1[1];
587  v1[2] = p2[2] - p1[2];
588 
589  v2[0] = p3[0] - p1[0];
590  v2[1] = p3[1] - p1[1];
591  v2[2] = p3[2] - p1[2];
592 
593  NormCross(v1,v2,normal);
594  return normal;
595 }
596 
597 //______________________________________________________________________________
599 {
600  // Calculate a normal vector of a plane.
601  //
602  // Input:
603  // Float_urt *p1,*p2,*p3 - 3 3D points belonged the plane to define it.
604  //
605  // Return:
606  // Pointer to 3D normal vector (normalized)
607 
608  Double_urt v1[3], v2[3];
609 
610  v1[0] = p2[0] - p1[0];
611  v1[1] = p2[1] - p1[1];
612  v1[2] = p2[2] - p1[2];
613 
614  v2[0] = p3[0] - p1[0];
615  v2[1] = p3[1] - p1[1];
616  v2[2] = p3[2] - p1[2];
617 
618  NormCross(v1,v2,normal);
619  return normal;
620 }
621 
622 //______________________________________________________________________________
624 {
625  // compute the Poisson distribution function for (x,par)
626 
627  if (x<0) return 0;
628  if (x==0) return URMath::Exp(-par);
629  return URMath::Power(par,x)/URMath::Gamma(x+1)/URMath::Exp(par);
630 }
631 
632 //______________________________________________________________________________
634 {
635  // Computation of the probability for a certain Chi-squared (chi2)
636  // and number of degrees of freedom (ndf).
637  //
638  // Calculations are based on the incomplete gamma function P(a,x),
639  // where a=ndf/2 and x=chi2/2.
640  //
641  // P(a,x) represents the probability that the observed Chi-squared
642  // for a correct model should be less than the value chi2.
643  //
644  // The returned probability corresponds to 1-P(a,x),
645  // which denotes the probability that an observed Chi-squared exceeds
646  // the value chi2 by chance, even for a correct model.
647  //
648  //--- NvE 14-nov-1998 UU-SAP Utrecht
649 
650  if (ndf <= 0) return 0; // Set CL to zero in case ndf<=0
651 
652  if (chi2 <= 0) {
653  if (chi2 < 0) return 0;
654  else return 1;
655  }
656 
657  if (ndf==1) {
658  Double_urt v = 1.-Erf(Sqrt(chi2)/Sqrt(2.));
659  return v;
660  }
661 
662  // Gaussian approximation for large ndf
663  Double_urt q = Sqrt(2*chi2)-Sqrt(Double_urt(2*ndf-1));
664  if (ndf > 30 && q > 5) {
665  Double_urt v = 0.5*(1-Erf(q/Sqrt(2.)));
666  return v;
667  }
668 
669  // Evaluate the incomplete gamma function
670  return (1-Gamma(0.5*ndf,0.5*chi2));
671 }
672 
673 //______________________________________________________________________________
675 {
676  // Calculates the Kolmogorov distribution function,
677  //Begin_Html
678  /*
679  <img src="gif/kolmogorov.gif">
680  */
681  //End_Html
682  // which gives the probability that Kolmogorov's test statistic will exceed
683  // the value z assuming the null hypothesis. This gives a very powerful
684  // test for comparing two one-dimensional distributions.
685  // see, for example, Eadie et al, "statistocal Methods in Experimental
686  // Physics', pp 269-270).
687  //
688  // This function returns the confidence level for the null hypothesis, where:
689  // z = dn*sqrt(n), and
690  // dn is the maximum deviation between a hypothetical distribution
691  // function and an experimental distribution with
692  // n events
693  //
694  // NOTE: To compare two experimental distributions with m and n events,
695  // use z = sqrt(m*n/(m+n))*dn
696  //
697  // Accuracy: The function is far too accurate for any imaginable application.
698  // Probabilities less than 10^-15 are returned as zero.
699  // However, remember that the formula is only valid for "large" n.
700  // Theta function inversion formula is used for z <= 1
701  //
702  // This function was translated by Rene Brun from PROBKL in CERNLIB.
703 
704  Double_urt fj[4] = {-2,-8,-18,-32}, r[4];
705  const Double_urt w = 2.50662827;
706  // c1 - -pi**2/8, c2 = 9*c1, c3 = 25*c1
707  const Double_urt c1 = -1.2337005501361697;
708  const Double_urt c2 = -11.103304951225528;
709  const Double_urt c3 = -30.842513753404244;
710 
711  Double_urt u = URMath::Abs(z);
712  Double_urt p;
713  if (u < 0.2) {
714  p = 1;
715  } else if (u < 0.755) {
716  Double_urt v = 1./(u*u);
717  p = 1 - w*(URMath::Exp(c1*v) + URMath::Exp(c2*v) + URMath::Exp(c3*v))/u;
718  } else if (u < 6.8116) {
719  r[1] = 0;
720  r[2] = 0;
721  r[3] = 0;
722  Double_urt v = u*u;
723  Int_urt maxj = URMath::Max(1,URMath::Nint(3./u));
724  for (Int_urt j=0; j<maxj;j++) {
725  r[j] = URMath::Exp(fj[j]*v);
726  }
727  p = 2*(r[0] - r[1] +r[2] - r[3]);
728  } else {
729  p = 0;
730  }
731  return p;
732  }
733 
734 //______________________________________________________________________________
736 {
737  // Computation of Voigt function (normalised).
738  // Voigt is a convolution of
739  // gauss(x) = 1/(sqrt(2*pi)*sigma) * exp(x*x/(2*sigma*sigma)
740  // and
741  // lorentz(x) = (1/pi) * (lg/2) / (x*x + g*g/4)
742  // functions.
743  //
744  // The Voigt function is known to be the real part of Faddeeva function also
745  // called complex error function [2].
746  //
747  // The algoritm was developed by J. Humlicek [1].
748  // This code is based on fortran code presented by R. J. Wells [2].
749  // Translated and adapted by Miha D. Puc
750  //
751  // To calculate the Faddeeva function with relative error less than 10^(-R).
752  // R can be set by the the user subject to the constraints 2 <= R <= 5.
753  //
754  // [1] J. Humlicek, JQSRT, 21, 437 (1982).
755  // [2] R.J. Wells "Rapid Approximation to the Voigt/Faddeeva Function and its
756  // Derivatives" JQSRT 62 (1999), pp 29-48.
757  // http://www-atm.physics.ox.ac.uk/user/wells/voigt.html
758 
759  if ((sigma < 0 || lg < 0) || (sigma==0 && lg==0)) {
760  return 0; // Not meant to be for those who want to be thinner than 0
761  }
762 
763  if (sigma == 0) {
764  return lg * 0.159154943 / (x*x + lg*lg /4); //pure Lorentz
765  }
766 
767  if (lg == 0) { //pure gauss
768  return 0.39894228 / sigma * URMath::Exp(-x*x / (2*sigma*sigma));
769  }
770 
771  Double_urt X, Y, K;
772  X = x / sigma / 1.41421356;
773  Y = lg / 2 / sigma / 1.41421356;
774 
775  Double_urt R0, R1;
776 
777  if (R < 2) R = 2;
778  if (R > 5) R = 5;
779 
780  R0=1.51 * exp(1.144 * (Double_urt)R);
781  R1=1.60 * exp(0.554 * (Double_urt)R);
782 
783  // Constants
784 
785  const Double_urt RRTPI = 0.56418958; // 1/SQRT(pi)
786 
787  Double_urt Y0, Y0PY0, Y0Q; // for CPF12 algorithm
788  Y0 = 1.5;
789  Y0PY0 = Y0 + Y0;
790  Y0Q = Y0 * Y0;
791 
792  Double_urt C[6] = { 1.0117281, -0.75197147, 0.012557727, 0.010022008, -0.00024206814, 0.00000050084806};
793  Double_urt S[6] = { 1.393237, 0.23115241, -0.15535147, 0.0062183662, 0.000091908299, -0.00000062752596};
794  Double_urt T[6] = { 0.31424038, 0.94778839, 1.5976826, 2.2795071, 3.0206370, 3.8897249};
795 
796  // Local variables
797 
798  int J; // Loop variables
799  int RG1, RG2, RG3; // y polynomial flags
800  Double_urt ABX, XQ, YQ, YRRTPI; // --x--, x^2, y^2, y/SQRT(pi)
801  Double_urt XLIM0, XLIM1, XLIM2, XLIM3, XLIM4; // --x-- on region boundaries
802  Double_urt A0=0, D0=0, D2=0, E0=0, E2=0, E4=0, H0=0, H2=0, H4=0, H6=0;// W4 temporary variables
803  Double_urt P0=0, P2=0, P4=0, P6=0, P8=0, Z0=0, Z2=0, Z4=0, Z6=0, Z8=0;
804  Double_urt XP[6], XM[6], YP[6], YM[6]; // CPF12 temporary values
805  Double_urt MQ[6], PQ[6], MF[6], PF[6];
806  Double_urt D, YF, YPY0, YPY0Q;
807 
808  //***** Start of executable code *****************************************
809 
810  RG1 = 1; // Set flags
811  RG2 = 1;
812  RG3 = 1;
813  YQ = Y * Y; // y^2
814  YRRTPI = Y * RRTPI; // y/SQRT(pi)
815 
816  // Region boundaries when both K and L are required or when R<>4
817 
818  XLIM0 = R0 - Y;
819  XLIM1 = R1 - Y;
820  XLIM3 = 3.097 * Y - 0.45;
821  XLIM2 = 6.8 - Y;
822  XLIM4 = 18.1 * Y + 1.65;
823  if ( Y <= 1e-6 ) { // When y<10^-6 avoid W4 algorithm.
824  XLIM1 = XLIM0;
825  XLIM2 = XLIM0;
826  }
827 
828  ABX = fabs(X); // |x|
829  XQ = ABX * ABX; // x^2
830  if ( ABX > XLIM0 ) { // Region 0 algorithm
831  K = YRRTPI / (XQ + YQ);
832  } else if ( ABX > XLIM1 ) { // Humlicek W4 Region 1
833  if ( RG1 != 0 ) { // First point in Region 1
834  RG1 = 0;
835  A0 = YQ + 0.5; // Region 1 y-dependents
836  D0 = A0*A0;
837  D2 = YQ + YQ - 1.0;
838  }
839  D = RRTPI / (D0 + XQ*(D2 + XQ));
840  K = D * Y * (A0 + XQ);
841  } else if ( ABX > XLIM2 ) { // Humlicek W4 Region 2
842  if ( RG2 != 0 ) { // First point in Region 2
843  RG2 = 0;
844  H0 = 0.5625 + YQ * (4.5 + YQ * (10.5 + YQ * (6.0 + YQ)));
845  // Region 2 y-dependents
846  H2 = -4.5 + YQ * (9.0 + YQ * ( 6.0 + YQ * 4.0));
847  H4 = 10.5 - YQ * (6.0 - YQ * 6.0);
848  H6 = -6.0 + YQ * 4.0;
849  E0 = 1.875 + YQ * (8.25 + YQ * (5.5 + YQ));
850  E2 = 5.25 + YQ * (1.0 + YQ * 3.0);
851  E4 = 0.75 * H6;
852  }
853  D = RRTPI / (H0 + XQ * (H2 + XQ * (H4 + XQ * (H6 + XQ))));
854  K = D * Y * (E0 + XQ * (E2 + XQ * (E4 + XQ)));
855  } else if ( ABX < XLIM3 ) { // Humlicek W4 Region 3
856  if ( RG3 != 0 ) { // First point in Region 3
857  RG3 = 0;
858  Z0 = 272.1014 + Y * (1280.829 + Y *
859  (2802.870 + Y *
860  (3764.966 + Y *
861  (3447.629 + Y *
862  (2256.981 + Y *
863  (1074.409 + Y *
864  (369.1989 + Y *
865  (88.26741 + Y *
866  (13.39880 + Y)
867  )))))))); // Region 3 y-dependents
868  Z2 = 211.678 + Y * (902.3066 + Y *
869  (1758.336 + Y *
870  (2037.310 + Y *
871  (1549.675 + Y *
872  (793.4273 + Y *
873  (266.2987 + Y *
874  (53.59518 + Y * 5.0)
875  ))))));
876  Z4 = 78.86585 + Y * (308.1852 + Y *
877  (497.3014 + Y *
878  (479.2576 + Y *
879  (269.2916 + Y *
880  (80.39278 + Y * 10.0)
881  ))));
882  Z6 = 22.03523 + Y * (55.02933 + Y *
883  (92.75679 + Y *
884  (53.59518 + Y * 10.0)
885  ));
886  Z8 = 1.496460 + Y * (13.39880 + Y * 5.0);
887  P0 = 153.5168 + Y * (549.3954 + Y *
888  (919.4955 + Y *
889  (946.8970 + Y *
890  (662.8097 + Y *
891  (328.2151 + Y *
892  (115.3772 + Y *
893  (27.93941 + Y *
894  (4.264678 + Y * 0.3183291)
895  )))))));
896  P2 = -34.16955 + Y * (-1.322256+ Y *
897  (124.5975 + Y *
898  (189.7730 + Y *
899  (139.4665 + Y *
900  (56.81652 + Y *
901  (12.79458 + Y * 1.2733163)
902  )))));
903  P4 = 2.584042 + Y * (10.46332 + Y *
904  (24.01655 + Y *
905  (29.81482 + Y *
906  (12.79568 + Y * 1.9099744)
907  )));
908  P6 = -0.07272979 + Y * (0.9377051 + Y *
909  (4.266322 + Y * 1.273316));
910  P8 = 0.0005480304 + Y * 0.3183291;
911  }
912  D = 1.7724538 / (Z0 + XQ * (Z2 + XQ * (Z4 + XQ * (Z6 + XQ * (Z8 + XQ)))));
913  K = D * (P0 + XQ * (P2 + XQ * (P4 + XQ * (P6 + XQ * P8))));
914  } else { // Humlicek CPF12 algorithm
915  YPY0 = Y + Y0;
916  YPY0Q = YPY0 * YPY0;
917  K = 0.0;
918  for (J = 0; J <= 5; J++) {
919  D = X - T[J];
920  MQ[J] = D * D;
921  MF[J] = 1.0 / (MQ[J] + YPY0Q);
922  XM[J] = MF[J] * D;
923  YM[J] = MF[J] * YPY0;
924  D = X + T[J];
925  PQ[J] = D * D;
926  PF[J] = 1.0 / (PQ[J] + YPY0Q);
927  XP[J] = PF[J] * D;
928  YP[J] = PF[J] * YPY0;
929  }
930  if ( ABX <= XLIM4 ) { // Humlicek CPF12 Region I
931  for (J = 0; J <= 5; J++) {
932  K = K + C[J]*(YM[J]+YP[J]) - S[J]*(XM[J]-XP[J]) ;
933  }
934  } else { // Humlicek CPF12 Region II
935  YF = Y + Y0PY0;
936  for ( J = 0; J <= 5; J++) {
937  K = K + (C[J] *
938  (MQ[J] * MF[J] - Y0 * YM[J])
939  + S[J] * YF * XM[J]) / (MQ[J]+Y0Q)
940  + (C[J] * (PQ[J] * PF[J] - Y0 * YP[J])
941  - S[J] * YF * XP[J]) / (PQ[J]+Y0Q);
942  }
943  K = Y * K + exp( -XQ );
944  }
945  }
946  return K / 2.506628 / sigma; // Normalize by dividing by sqrt(2*pi)*sigma.
947 }
948 
949 //______________________________________________________________________________
951 {
952  // Return index of array with the minimum element.
953  // If more than one element is minimum returns first found.
954 
955  if (n <= 0) return -1;
956  Short_urt xmin = a[0];
957  Int_urt loc = 0;
958  for (Int_urt i = 1; i < n; i++) {
959  if (xmin > a[i]) {
960  xmin = a[i];
961  loc = i;
962  }
963  }
964  return loc;
965 }
966 
967 //______________________________________________________________________________
969 {
970  // Return index of array with the minimum element.
971  // If more than one element is minimum returns first found.
972 
973  if (n <= 0) return -1;
974  Int_urt xmin = a[0];
975  Int_urt loc = 0;
976  for (Int_urt i = 1; i < n; i++) {
977  if (xmin > a[i]) {
978  xmin = a[i];
979  loc = i;
980  }
981  }
982  return loc;
983 }
984 
985 //______________________________________________________________________________
987 {
988  // Return index of array with the minimum element.
989  // If more than one element is minimum returns first found.
990 
991  if (n <= 0) return -1;
992  Float_urt xmin = a[0];
993  Int_urt loc = 0;
994  for (Int_urt i = 1; i < n; i++) {
995  if (xmin > a[i]) {
996  xmin = a[i];
997  loc = i;
998  }
999  }
1000  return loc;
1001 }
1002 
1003 //______________________________________________________________________________
1005 {
1006  // Return index of array with the minimum element.
1007  // If more than one element is minimum returns first found.
1008 
1009  if (n <= 0) return -1;
1010  Double_urt xmin = a[0];
1011  Int_urt loc = 0;
1012  for (Int_urt i = 1; i < n; i++) {
1013  if (xmin > a[i]) {
1014  xmin = a[i];
1015  loc = i;
1016  }
1017  }
1018  return loc;
1019 }
1020 
1021 //______________________________________________________________________________
1023 {
1024  // Return index of array with the minimum element.
1025  // If more than one element is minimum returns first found.
1026 
1027  if (n <= 0) return -1;
1028  Long_urt xmin = a[0];
1029  Int_urt loc = 0;
1030  for (Int_urt i = 1; i < n; i++) {
1031  if (xmin > a[i]) {
1032  xmin = a[i];
1033  loc = i;
1034  }
1035  }
1036  return loc;
1037 }
1038 
1039 //______________________________________________________________________________
1041 {
1042  // Return index of array with the maximum element.
1043  // If more than one element is maximum returns first found.
1044 
1045  if (n <= 0) return -1;
1046  Short_urt xmax = a[0];
1047  Int_urt loc = 0;
1048  for (Int_urt i = 1; i < n; i++) {
1049  if (xmax < a[i]) {
1050  xmax = a[i];
1051  loc = i;
1052  }
1053  }
1054  return loc;
1055 }
1056 
1057 //______________________________________________________________________________
1059 {
1060  // Return index of array with the maximum element.
1061  // If more than one element is maximum returns first found.
1062 
1063  if (n <= 0) return -1;
1064  Int_urt xmax = a[0];
1065  Int_urt loc = 0;
1066  for (Int_urt i = 1; i < n; i++) {
1067  if (xmax < a[i]) {
1068  xmax = a[i];
1069  loc = i;
1070  }
1071  }
1072  return loc;
1073 }
1074 
1075 //______________________________________________________________________________
1077 {
1078  // Return index of array with the maximum element.
1079  // If more than one element is maximum returns first found.
1080 
1081  if (n <= 0) return -1;
1082  Float_urt xmax = a[0];
1083  Int_urt loc = 0;
1084  for (Int_urt i = 1; i < n; i++) {
1085  if (xmax < a[i]) {
1086  xmax = a[i];
1087  loc = i;
1088  }
1089  }
1090  return loc;
1091 }
1092 
1093 //______________________________________________________________________________
1095 {
1096  // Return index of array with the maximum element.
1097  // If more than one element is maximum returns first found.
1098 
1099  if (n <= 0) return -1;
1100  Double_urt xmax = a[0];
1101  Int_urt loc = 0;
1102  for (Int_urt i = 1; i < n; i++) {
1103  if (xmax < a[i]) {
1104  xmax = a[i];
1105  loc = i;
1106  }
1107  }
1108  return loc;
1109 }
1110 
1111 //______________________________________________________________________________
1113 {
1114  // Return index of array with the maximum element.
1115  // If more than one element is maximum returns first found.
1116 
1117  if (n <= 0) return -1;
1118  Long_urt xmax = a[0];
1119  Int_urt loc = 0;
1120  for (Int_urt i = 1; i < n; i++) {
1121  if (xmax < a[i]) {
1122  xmax = a[i];
1123  loc = i;
1124  }
1125  }
1126  return loc;
1127 }
1128 
1129 //______________________________________________________________________________
1130 Int_urt URMath::BinarySearch(Int_urt n, const Short_urt *array, Short_urt value)
1131 {
1132  // Binary search in an array of n values to locate value.
1133  //
1134  // Array is supposed to be sorted prior to this call.
1135  // If match is found, function returns position of element.
1136  // If no match found, function gives nearest element smaller than value.
1137 
1138  Int_urt nabove, nbelow, middle;
1139  nabove = n+1;
1140  nbelow = 0;
1141  while(nabove-nbelow > 1) {
1142  middle = (nabove+nbelow)/2;
1143  if (value == array[middle-1]) return middle-1;
1144  if (value < array[middle-1]) nabove = middle;
1145  else nbelow = middle;
1146  }
1147  return nbelow-1;
1148 }
1149 
1150 //______________________________________________________________________________
1151 Int_urt URMath::BinarySearch(Int_urt n, const Short_urt **array, Short_urt value)
1152 {
1153  // Binary search in an array of n values to locate value.
1154  //
1155  // Array is supposed to be sorted prior to this call.
1156  // If match is found, function returns position of element.
1157  // If no match found, function gives nearest element smaller than value.
1158 
1159  Int_urt nabove, nbelow, middle;
1160  nabove = n+1;
1161  nbelow = 0;
1162  while(nabove-nbelow > 1) {
1163  middle = (nabove+nbelow)/2;
1164  if (value == *array[middle-1]) return middle-1;
1165  if (value < *array[middle-1]) nabove = middle;
1166  else nbelow = middle;
1167  }
1168  return nbelow-1;
1169 }
1170 
1171 //______________________________________________________________________________
1172 Int_urt URMath::BinarySearch(Int_urt n, const Int_urt *array, Int_urt value)
1173 {
1174  // Binary search in an array of n values to locate value.
1175  //
1176  // Array is supposed to be sorted prior to this call.
1177  // If match is found, function returns position of element.
1178  // If no match found, function gives nearest element smaller than value.
1179 
1180  Int_urt nabove, nbelow, middle;
1181  nabove = n+1;
1182  nbelow = 0;
1183  while(nabove-nbelow > 1) {
1184  middle = (nabove+nbelow)/2;
1185  if (value == array[middle-1]) return middle-1;
1186  if (value < array[middle-1]) nabove = middle;
1187  else nbelow = middle;
1188  }
1189  return nbelow-1;
1190 }
1191 
1192 //______________________________________________________________________________
1193 Int_urt URMath::BinarySearch(Int_urt n, const Int_urt **array, Int_urt value)
1194 {
1195  // Binary search in an array of n values to locate value.
1196  //
1197  // Array is supposed to be sorted prior to this call.
1198  // If match is found, function returns position of element.
1199  // If no match found, function gives nearest element smaller than value.
1200 
1201  Int_urt nabove, nbelow, middle;
1202  nabove = n+1;
1203  nbelow = 0;
1204  while(nabove-nbelow > 1) {
1205  middle = (nabove+nbelow)/2;
1206  if (value == *array[middle-1]) return middle-1;
1207  if (value < *array[middle-1]) nabove = middle;
1208  else nbelow = middle;
1209  }
1210  return nbelow-1;
1211 }
1212 
1213 //______________________________________________________________________________
1214 Int_urt URMath::BinarySearch(Int_urt n, const Float_urt *array, Float_urt value)
1215 {
1216  // Binary search in an array of n values to locate value.
1217  //
1218  // Array is supposed to be sorted prior to this call.
1219  // If match is found, function returns position of element.
1220  // If no match found, function gives nearest element smaller than value.
1221 
1222  Int_urt nabove, nbelow, middle;
1223  nabove = n+1;
1224  nbelow = 0;
1225  while(nabove-nbelow > 1) {
1226  middle = (nabove+nbelow)/2;
1227  if (value == array[middle-1]) return middle-1;
1228  if (value < array[middle-1]) nabove = middle;
1229  else nbelow = middle;
1230  }
1231  return nbelow-1;
1232 }
1233 
1234 //______________________________________________________________________________
1235 Int_urt URMath::BinarySearch(Int_urt n, const Float_urt **array, Float_urt value)
1236 {
1237  // Binary search in an array of n values to locate value.
1238  //
1239  // Array is supposed to be sorted prior to this call.
1240  // If match is found, function returns position of element.
1241  // If no match found, function gives nearest element smaller than value.
1242 
1243  Int_urt nabove, nbelow, middle;
1244  nabove = n+1;
1245  nbelow = 0;
1246  while(nabove-nbelow > 1) {
1247  middle = (nabove+nbelow)/2;
1248  if (value == *array[middle-1]) return middle-1;
1249  if (value < *array[middle-1]) nabove = middle;
1250  else nbelow = middle;
1251  }
1252  return nbelow-1;
1253 }
1254 
1255 //______________________________________________________________________________
1257 {
1258  // Binary search in an array of n values to locate value.
1259  //
1260  // Array is supposed to be sorted prior to this call.
1261  // If match is found, function returns position of element.
1262  // If no match found, function gives nearest element smaller than value.
1263 
1264  Int_urt nabove, nbelow, middle;
1265  nabove = n+1;
1266  nbelow = 0;
1267  while(nabove-nbelow > 1) {
1268  middle = (nabove+nbelow)/2;
1269  if (value == array[middle-1]) return middle-1;
1270  if (value < array[middle-1]) nabove = middle;
1271  else nbelow = middle;
1272  }
1273  return nbelow-1;
1274 }
1275 
1276 //______________________________________________________________________________
1277 Int_urt URMath::BinarySearch(Int_urt n, const Double_urt **array, Double_urt value)
1278 {
1279  // Binary search in an array of n values to locate value.
1280  //
1281  // Array is supposed to be sorted prior to this call.
1282  // If match is found, function returns position of element.
1283  // If no match found, function gives nearest element smaller than value.
1284 
1285  Int_urt nabove, nbelow, middle;
1286  nabove = n+1;
1287  nbelow = 0;
1288  while(nabove-nbelow > 1) {
1289  middle = (nabove+nbelow)/2;
1290  if (value == *array[middle-1]) return middle-1;
1291  if (value < *array[middle-1]) nabove = middle;
1292  else nbelow = middle;
1293  }
1294  return nbelow-1;
1295 }
1296 
1297 //______________________________________________________________________________
1298 Int_urt URMath::BinarySearch(Int_urt n, const Long_urt *array, Long_urt value)
1299 {
1300  // Binary search in an array of n values to locate value.
1301  //
1302  // Array is supposed to be sorted prior to this call.
1303  // If match is found, function returns position of element.
1304  // If no match found, function gives nearest element smaller than value.
1305 
1306  Int_urt nabove, nbelow, middle;
1307  nabove = n+1;
1308  nbelow = 0;
1309  while(nabove-nbelow > 1) {
1310  middle = (nabove+nbelow)/2;
1311  if (value == array[middle-1]) return middle-1;
1312  if (value < array[middle-1]) nabove = middle;
1313  else nbelow = middle;
1314  }
1315  return nbelow-1;
1316 }
1317 
1318 //______________________________________________________________________________
1319 Int_urt URMath::BinarySearch(Int_urt n, const Long_urt **array, Long_urt value)
1320 {
1321  // Binary search in an array of n values to locate value.
1322  //
1323  // Array is supposed to be sorted prior to this call.
1324  // If match is found, function returns position of element.
1325  // If no match found, function gives nearest element smaller than value.
1326 
1327  Int_urt nabove, nbelow, middle;
1328  nabove = n+1;
1329  nbelow = 0;
1330  while(nabove-nbelow > 1) {
1331  middle = (nabove+nbelow)/2;
1332  if (value == *array[middle-1]) return middle-1;
1333  if (value < *array[middle-1]) nabove = middle;
1334  else nbelow = middle;
1335  }
1336  return nbelow-1;
1337 }
1338 
1339 //_____________________________________________________________________________
1341 {
1342  // Function which returns kurTRUE if point xp,yp lies inside the
1343  // polygon defined by the np points in arrays x and y, kurFALSE otherwise
1344  // NOTE that the polygon must be a closed polygon (1st and last point
1345  // must be identical)
1346  Double_urt xint;
1347  Int_urt i;
1348  Int_urt inter = 0;
1349  for (i=0;i<np-1;i++) {
1350  if (y[i] == y[i+1]) continue;
1351  if (yp <= y[i] && yp <= y[i+1]) continue;
1352  if (y[i] < yp && y[i+1] < yp) continue;
1353  xint = x[i] + (yp-y[i])*(x[i+1]-x[i])/(y[i+1]-y[i]);
1354  if (xp < xint) inter++;
1355  }
1356  if (inter%2) return kurTRUE;
1357  return kurFALSE;
1358 }
1359 
1360 //_____________________________________________________________________________
1362 {
1363  // Function which returns kurTRUE if point xp,yp lies inside the
1364  // polygon defined by the np points in arrays x and y, kurFALSE otherwise
1365  // NOTE that the polygon must be a closed polygon (1st and last point
1366  // must be identical)
1367  Double_urt xint;
1368  Int_urt i;
1369  Int_urt inter = 0;
1370  for (i=0;i<np-1;i++) {
1371  if (y[i] == y[i+1]) continue;
1372  if (yp <= y[i] && yp <= y[i+1]) continue;
1373  if (y[i] < yp && y[i+1] < yp) continue;
1374  xint = x[i] + (yp-y[i])*(x[i+1]-x[i])/(y[i+1]-y[i]);
1375  if ((Double_urt)xp < xint) inter++;
1376  }
1377  if (inter%2) return kurTRUE;
1378  return kurFALSE;
1379 }
1380 
1381 //_____________________________________________________________________________
1383 {
1384  // Function which returns kurTRUE if point xp,yp lies inside the
1385  // polygon defined by the np points in arrays x and y, kurFALSE otherwise
1386  // NOTE that the polygon must be a closed polygon (1st and last point
1387  // must be identical)
1388  Double_urt xint;
1389  Int_urt i;
1390  Int_urt inter = 0;
1391  for (i=0;i<np-1;i++) {
1392  if (y[i] == y[i+1]) continue;
1393  if (yp <= y[i] && yp <= y[i+1]) continue;
1394  if (y[i] < yp && y[i+1] < yp) continue;
1395  xint = x[i] + (yp-y[i])*(x[i+1]-x[i])/(y[i+1]-y[i]);
1396  if ((Double_urt)xp < xint) inter++;
1397  }
1398  if (inter%2) return kurTRUE;
1399  return kurFALSE;
1400 }
1401 
1402 //_____________________________________________________________________________
1403 void URMath::Sort(Int_urt n1, const Short_urt *a, Int_urt *index, Bool_urt down)
1404 {
1405  // Sort the n1 elements of the Short_urt array a.
1406  // In output the array index contains the indices of the sorted array.
1407  // If down is false sort in increasing order (default is decreasing order).
1408  // This is a translation of the CERNLIB routine sortzv (M101)
1409  // based on the quicksort algorithm.
1410  // NOTE that the array index must be created with a length >= n1
1411  // before calling this function.
1412 
1413  Int_urt i,i1,n,i2,i3,i33,i222,iswap,n2;
1414  Int_urt i22 = 0;
1415  Short_urt ai;
1416  n = n1;
1417  if (n <= 0) return;
1418  if (n == 1) {index[0] = 0; return;}
1419  for (i=0;i<n;i++) index[i] = i+1;
1420  for (i1=2;i1<=n;i1++) {
1421  i3 = i1;
1422  i33 = index[i3-1];
1423  ai = a[i33-1];
1424  while(1) {
1425  i2 = i3/2;
1426  if (i2 <= 0) break;
1427  i22 = index[i2-1];
1428  if (ai <= a[i22-1]) break;
1429  index[i3-1] = i22;
1430  i3 = i2;
1431  }
1432  index[i3-1] = i33;
1433  }
1434 
1435  while(1) {
1436  i3 = index[n-1];
1437  index[n-1] = index[0];
1438  ai = a[i3-1];
1439  n--;
1440  if(n-1 < 0) {index[0] = i3; break;}
1441  i1 = 1;
1442  while(2) {
1443  i2 = i1+i1;
1444  if (i2 <= n) i22 = index[i2-1];
1445  if (i2-n > 0) {index[i1-1] = i3; break;}
1446  if (i2-n < 0) {
1447  i222 = index[i2];
1448  if (a[i22-1] - a[i222-1] < 0) {
1449  i2++;
1450  i22 = i222;
1451  }
1452  }
1453  if (ai - a[i22-1] > 0) {index[i1-1] = i3; break;}
1454  index[i1-1] = i22;
1455  i1 = i2;
1456  }
1457  }
1458  for (i=0;i<n1;i++) index[i]--;
1459  if (!down) return;
1460  n2 = n1/2;
1461  for (i=0;i<n2;i++) {
1462  iswap = index[i];
1463  index[i] = index[n1-i-1];
1464  index[n1-i-1] = iswap;
1465  }
1466 }
1467 
1468 //_____________________________________________________________________________
1469 void URMath::Sort(Int_urt n1, const Int_urt *a, Int_urt *index, Bool_urt down)
1470 {
1471  // Sort the n1 elements of the Int_urt array a.
1472  // In output the array index contains the indices of the sorted array.
1473  // If down is false sort in increasing order (default is decreasing order).
1474  // This is a translation of the CERNLIB routine sortzv (M101)
1475  // based on the quicksort algorithm.
1476  // NOTE that the array index must be created with a length >= n1
1477  // before calling this function.
1478 
1479  Int_urt i,i1,n,i2,i3,i33,i222,iswap,n2;
1480  Int_urt i22 = 0;
1481  Int_urt ai;
1482  n = n1;
1483  if (n <= 0) return;
1484  if (n == 1) {index[0] = 0; return;}
1485  for (i=0;i<n;i++) index[i] = i+1;
1486  for (i1=2;i1<=n;i1++) {
1487  i3 = i1;
1488  i33 = index[i3-1];
1489  ai = a[i33-1];
1490  while(1) {
1491  i2 = i3/2;
1492  if (i2 <= 0) break;
1493  i22 = index[i2-1];
1494  if (ai <= a[i22-1]) break;
1495  index[i3-1] = i22;
1496  i3 = i2;
1497  }
1498  index[i3-1] = i33;
1499  }
1500 
1501  while(1) {
1502  i3 = index[n-1];
1503  index[n-1] = index[0];
1504  ai = a[i3-1];
1505  n--;
1506  if(n-1 < 0) {index[0] = i3; break;}
1507  i1 = 1;
1508  while(2) {
1509  i2 = i1+i1;
1510  if (i2 <= n) i22 = index[i2-1];
1511  if (i2-n > 0) {index[i1-1] = i3; break;}
1512  if (i2-n < 0) {
1513  i222 = index[i2];
1514  if (a[i22-1] - a[i222-1] < 0) {
1515  i2++;
1516  i22 = i222;
1517  }
1518  }
1519  if (ai - a[i22-1] > 0) {index[i1-1] = i3; break;}
1520  index[i1-1] = i22;
1521  i1 = i2;
1522  }
1523  }
1524  for (i=0;i<n1;i++) index[i]--;
1525  if (!down) return;
1526  n2 = n1/2;
1527  for (i=0;i<n2;i++) {
1528  iswap = index[i];
1529  index[i] = index[n1-i-1];
1530  index[n1-i-1] = iswap;
1531  }
1532 }
1533 
1534 //_____________________________________________________________________________
1535 void URMath::Sort(Int_urt n1, const Float_urt *a, Int_urt *index, Bool_urt down)
1536 {
1537  // Sort the n1 elements of the Float_urt array a.
1538  // In output the array index contains the indices of the sorted array.
1539  // If down is false sort in increasing order (default is decreasing order).
1540  // This is a translation of the CERNLIB routine sortzv (M101)
1541  // based on the quicksort algorithm.
1542  // NOTE that the array index must be created with a length >= n1
1543  // before calling this function.
1544 
1545  Int_urt i,i1,n,i2,i3,i33,i222,iswap,n2;
1546  Int_urt i22 = 0;
1547  Float_urt ai;
1548  n = n1;
1549  if (n <= 0) return;
1550  if (n == 1) {index[0] = 0; return;}
1551  for (i=0;i<n;i++) index[i] = i+1;
1552  for (i1=2;i1<=n;i1++) {
1553  i3 = i1;
1554  i33 = index[i3-1];
1555  ai = a[i33-1];
1556  while(1) {
1557  i2 = i3/2;
1558  if (i2 <= 0) break;
1559  i22 = index[i2-1];
1560  if (ai <= a[i22-1]) break;
1561  index[i3-1] = i22;
1562  i3 = i2;
1563  }
1564  index[i3-1] = i33;
1565  }
1566 
1567  while(1) {
1568  i3 = index[n-1];
1569  index[n-1] = index[0];
1570  ai = a[i3-1];
1571  n--;
1572  if(n-1 < 0) {index[0] = i3; break;}
1573  i1 = 1;
1574  while(2) {
1575  i2 = i1+i1;
1576  if (i2 <= n) i22 = index[i2-1];
1577  if (i2-n > 0) {index[i1-1] = i3; break;}
1578  if (i2-n < 0) {
1579  i222 = index[i2];
1580  if (a[i22-1] - a[i222-1] < 0) {
1581  i2++;
1582  i22 = i222;
1583  }
1584  }
1585  if (ai - a[i22-1] > 0) {index[i1-1] = i3; break;}
1586  index[i1-1] = i22;
1587  i1 = i2;
1588  }
1589  }
1590  for (i=0;i<n1;i++) index[i]--;
1591  if (!down) return;
1592  n2 = n1/2;
1593  for (i=0;i<n2;i++) {
1594  iswap = index[i];
1595  index[i] = index[n1-i-1];
1596  index[n1-i-1] = iswap;
1597  }
1598 }
1599 
1600 //_____________________________________________________________________________
1601 void URMath::Sort(Int_urt n1, const Double_urt *a, Int_urt *index, Bool_urt down)
1602 {
1603  // Sort the n1 elements of the Double_urt array a.
1604  // In output the array index contains the indices of the sorted array.
1605  // If down is false sort in increasing order (default is decreasing order).
1606  // This is a translation of the CERNLIB routine sortzv (M101)
1607  // based on the quicksort algorithm.
1608  // NOTE that the array index must be created with a length >= n1
1609  // before calling this function.
1610 
1611  Int_urt i,i1,n,i2,i3,i33,i222,iswap,n2;
1612  Int_urt i22 = 0;
1613  Double_urt ai;
1614  n = n1;
1615  if (n <= 0) return;
1616  if (n == 1) {index[0] = 0; return;}
1617  for (i=0;i<n;i++) index[i] = i+1;
1618  for (i1=2;i1<=n;i1++) {
1619  i3 = i1;
1620  i33 = index[i3-1];
1621  ai = a[i33-1];
1622  while(1) {
1623  i2 = i3/2;
1624  if (i2 <= 0) break;
1625  i22 = index[i2-1];
1626  if (ai <= a[i22-1]) break;
1627  index[i3-1] = i22;
1628  i3 = i2;
1629  }
1630  index[i3-1] = i33;
1631  }
1632 
1633  while(1) {
1634  i3 = index[n-1];
1635  index[n-1] = index[0];
1636  ai = a[i3-1];
1637  n--;
1638  if(n-1 < 0) {index[0] = i3; break;}
1639  i1 = 1;
1640  while(2) {
1641  i2 = i1+i1;
1642  if (i2 <= n) i22 = index[i2-1];
1643  if (i2-n > 0) {index[i1-1] = i3; break;}
1644  if (i2-n < 0) {
1645  i222 = index[i2];
1646  if (a[i22-1] - a[i222-1] < 0) {
1647  i2++;
1648  i22 = i222;
1649  }
1650  }
1651  if (ai - a[i22-1] > 0) {index[i1-1] = i3; break;}
1652  index[i1-1] = i22;
1653  i1 = i2;
1654  }
1655  }
1656  for (i=0;i<n1;i++) index[i]--;
1657  if (!down) return;
1658  n2 = n1/2;
1659  for (i=0;i<n2;i++) {
1660  iswap = index[i];
1661  index[i] = index[n1-i-1];
1662  index[n1-i-1] = iswap;
1663  }
1664 }
1665 
1666 //_____________________________________________________________________________
1667 void URMath::Sort(Int_urt n1, const Long_urt *a, Int_urt *index, Bool_urt down)
1668 {
1669  // Sort the n1 elements of the Long_urt array a.
1670  // In output the array index contains the indices of the sorted array.
1671  // If down is false sort in increasing order (default is decreasing order).
1672  // This is a translation of the CERNLIB routine sortzv (M101)
1673  // based on the quicksort algorithm.
1674  // NOTE that the array index must be created with a length >= n1
1675  // before calling this function.
1676 
1677  Int_urt i,i1,n,i2,i3,i33,i222,iswap,n2;
1678  Int_urt i22 = 0;
1679  Long_urt ai;
1680  n = n1;
1681  if (n <= 0) return;
1682  if (n == 1) {index[0] = 0; return;}
1683  for (i=0;i<n;i++) index[i] = i+1;
1684  for (i1=2;i1<=n;i1++) {
1685  i3 = i1;
1686  i33 = index[i3-1];
1687  ai = a[i33-1];
1688  while(1) {
1689  i2 = i3/2;
1690  if (i2 <= 0) break;
1691  i22 = index[i2-1];
1692  if (ai <= a[i22-1]) break;
1693  index[i3-1] = i22;
1694  i3 = i2;
1695  }
1696  index[i3-1] = i33;
1697  }
1698 
1699  while(1) {
1700  i3 = index[n-1];
1701  index[n-1] = index[0];
1702  ai = a[i3-1];
1703  n--;
1704  if(n-1 < 0) {index[0] = i3; break;}
1705  i1 = 1;
1706  while(2) {
1707  i2 = i1+i1;
1708  if (i2 <= n) i22 = index[i2-1];
1709  if (i2-n > 0) {index[i1-1] = i3; break;}
1710  if (i2-n < 0) {
1711  i222 = index[i2];
1712  if (a[i22-1] - a[i222-1] < 0) {
1713  i2++;
1714  i22 = i222;
1715  }
1716  }
1717  if (ai - a[i22-1] > 0) {index[i1-1] = i3; break;}
1718  index[i1-1] = i22;
1719  i1 = i2;
1720  }
1721  }
1722  for (i=0;i<n1;i++) index[i]--;
1723  if (!down) return;
1724  n2 = n1/2;
1725  for (i=0;i<n2;i++) {
1726  iswap = index[i];
1727  index[i] = index[n1-i-1];
1728  index[n1-i-1] = iswap;
1729  }
1730 }
1731 
1732 
1733 //______________________________________________________________________________
1734 void URMath::BubbleHigh(Int_urt Narr, Double_urt *arr1, Int_urt *arr2)
1735 {
1736  // Bubble sort variant to obtain the order of an array's elements into
1737  // an index in order to do more useful things than the standard built
1738  // in functions.
1739  // *arr1 is unchanged;
1740  // *arr2 is the array of indicies corresponding to the decending value
1741  // of arr1 with arr2[0] corresponding to the largest arr1 value and
1742  // arr2[Narr] the smallest.
1743  //
1744  // Author: Adrian Bevan (bevan@slac.stanford.edu)
1745  // Copyright: Liverpool University, July 2001
1746 
1747  if (Narr <= 0) return;
1748  double *localArr1 = new double[Narr];
1749  int *localArr2 = new int[Narr];
1750  int iEl;
1751  int iEl2;
1752 
1753  for(iEl = 0; iEl < Narr; iEl++) {
1754  localArr1[iEl] = arr1[iEl];
1755  localArr2[iEl] = iEl;
1756  }
1757 
1758  for (iEl = 0; iEl < Narr; iEl++) {
1759  for (iEl2 = Narr-1; iEl2 > iEl; --iEl2) {
1760  if (localArr1[iEl2-1] < localArr1[iEl2]) {
1761  double tmp = localArr1[iEl2-1];
1762  localArr1[iEl2-1] = localArr1[iEl2];
1763  localArr1[iEl2] = tmp;
1764 
1765  int tmp2 = localArr2[iEl2-1];
1766  localArr2[iEl2-1] = localArr2[iEl2];
1767  localArr2[iEl2] = tmp2;
1768  }
1769  }
1770  }
1771 
1772  for (iEl = 0; iEl < Narr; iEl++) {
1773  arr2[iEl] = localArr2[iEl];
1774  }
1775  delete [] localArr2;
1776  delete [] localArr1;
1777 }
1778 
1779 //______________________________________________________________________________
1780 void URMath::BubbleLow(Int_urt Narr, Double_urt *arr1, Int_urt *arr2)
1781 {
1782  // Opposite ordering of the array arr2[] to that of BubbleHigh.
1783  //
1784  // Author: Adrian Bevan (bevan@slac.stanford.edu)
1785  // Copyright: Liverpool University, July 2001
1786 
1787  if (Narr <= 0) return;
1788  double *localArr1 = new double[Narr];
1789  int *localArr2 = new int[Narr];
1790  int iEl;
1791  int iEl2;
1792 
1793  for (iEl = 0; iEl < Narr; iEl++) {
1794  localArr1[iEl] = arr1[iEl];
1795  localArr2[iEl] = iEl;
1796  }
1797 
1798  for (iEl = 0; iEl < Narr; iEl++) {
1799  for (iEl2 = Narr-1; iEl2 > iEl; --iEl2) {
1800  if (localArr1[iEl2-1] > localArr1[iEl2]) {
1801  double tmp = localArr1[iEl2-1];
1802  localArr1[iEl2-1] = localArr1[iEl2];
1803  localArr1[iEl2] = tmp;
1804 
1805  int tmp2 = localArr2[iEl2-1];
1806  localArr2[iEl2-1] = localArr2[iEl2];
1807  localArr2[iEl2] = tmp2;
1808  }
1809  }
1810  }
1811 
1812  for (iEl = 0; iEl < Narr; iEl++) {
1813  arr2[iEl] = localArr2[iEl];
1814  }
1815  delete [] localArr2;
1816  delete [] localArr1;
1817 }
1818 
1819 #ifdef OLD_HASH
1820 
1821 //______________________________________________________________________________
1822 ULong_urt URMath::Hash(const void *txt, Int_urt ntxt)
1823 {
1824  // Calculates hash index from any char string.
1825  // Based on precalculated table of 256 specially selected random numbers.
1826  //
1827  // For string: i = URMath::Hash(string,nstring);
1828  // For int: i = URMath::Hash(&intword,sizeof(int));
1829  // For pointer: i = URMath::Hash(&pointer,sizeof(void*));
1830  //
1831  // Limitation: for ntxt>256 calculates hash only from first 256 bytes
1832  //
1833  // V.Perev
1834 
1835  const UChar_urt *uc = (const UChar_urt*) txt;
1836  ULong_urt u = 0, uu = 0;
1837 
1838  static ULong_urt utab[256] =
1839  {0xb93f6fc0,0x553dfc51,0xb22c1e8c,0x638462c0,0x13e81418,0x2836e171,0x7c4abb90,0xda1a4f39
1840  ,0x38f211d1,0x8c804829,0x95a6602d,0x4c590993,0x1810580a,0x721057d4,0x0f587215,0x9f49ce2a
1841  ,0xcd5ab255,0xab923a99,0x80890f39,0xbcfa2290,0x16587b52,0x6b6d3f0d,0xea8ff307,0x51542d5c
1842  ,0x189bf223,0x39643037,0x0e4a326a,0x214eca01,0x47645a9b,0x0f364260,0x8e9b2da4,0x5563ebd9
1843  ,0x57a31c1c,0xab365854,0xdd63ab1f,0x0b89acbd,0x23d57d33,0x1800a0fd,0x225ac60a,0xd0e51943
1844  ,0x6c65f669,0xcb966ea0,0xcbafda95,0x2e5c0c5f,0x2988e87e,0xc781cbab,0x3add3dc7,0x693a2c30
1845  ,0x42d6c23c,0xebf85f26,0x2544987e,0x2e315e3f,0xac88b5b5,0x7ebd2bbb,0xda07c87b,0x20d460f1
1846  ,0xc61c3f40,0x182046e7,0x3b6c3b66,0x2fc10d4a,0x0780dfbb,0xc437280c,0x0988dd07,0xe1498606
1847  ,0x8e61d728,0x4f1f3909,0x040a9682,0x49411b29,0x391b0e1c,0xd7905241,0xdd77d95b,0x88426c13
1848  ,0x33033e58,0xe158e30e,0x7e342647,0x1e09544b,0x4637353d,0x18ea0924,0x39212b08,0x12580ae8
1849  ,0x269a6f06,0x3e10b73b,0x123db33b,0x085412da,0x3bb5f464,0xd9b2d442,0x103d26bb,0xd0038bab
1850  ,0x45b6177f,0xfb48f1fe,0x99074c55,0xb545e82e,0x5f79fd0d,0x570f3ae4,0x57e43255,0x037a12ae
1851  ,0x4357bdb2,0x337c2c4d,0x2982499d,0x2ab72793,0x3900e7d1,0x57a6bb81,0x7503609b,0x3f39c0d0
1852  ,0x717b389d,0x5748034f,0x4698162b,0x5801b97c,0x1dfd5d7e,0xc1386d1c,0xa387a72a,0x084547e4
1853  ,0x2e54d8e9,0x2e2f384c,0xe09ccc20,0x8904b71e,0x3e24edc5,0x06a22e16,0x8a2be1df,0x9e5058b2
1854  ,0xe01a2f16,0x03325eed,0x587ecfe6,0x584d9cd3,0x32926930,0xe943d68c,0xa9442da8,0xf9650560
1855  ,0xf003871e,0x1109c663,0x7a2f2f89,0x1c2210bb,0x37335787,0xb92b382f,0xea605cb5,0x336bbe38
1856  ,0x08126bd3,0x1f8c2bd6,0xba6c46f2,0x1a4d1b83,0xc988180d,0xe2582505,0xa8a1b375,0x59a08c49
1857  ,0x3db54b48,0x44400f35,0x272d4e7f,0x5579f733,0x98eb590e,0x8ee09813,0x12cc9301,0xc85c402d
1858  ,0x135c1039,0x22318128,0x4063c705,0x87a8a3fa,0xfc14431f,0x6e27bf47,0x2d080a19,0x01dba174
1859  ,0xe343530b,0xaa1bfced,0x283bb2c8,0x5df250c8,0x4ff9140b,0x045039c1,0xa377780d,0x750f2661
1860  ,0x2b108918,0x0b152120,0x3cbc251f,0x5e87b350,0x060625bb,0xe068ba3b,0xdb73ebd7,0x66014ff3
1861  ,0xdb003000,0x161a3a0b,0xdc24e142,0x97ea5575,0x635a3cab,0xa719100a,0x256084db,0xc1f4a1e7
1862  ,0xe13388f2,0xb8199fc9,0x50c70dc9,0x08154211,0xd60e5220,0xe52c6592,0x584c5fe1,0xfe5e0875
1863  ,0x21072b30,0x3370d773,0x92608fe2,0x2d013d93,0x53414b3c,0x2c066142,0x64676644,0x0420887c
1864  ,0x35c01187,0x6822119b,0xf9bfe6df,0x273f4ee4,0x87973149,0x7b41282d,0x635d0d1f,0x5f7ecc1e
1865  ,0x14c3608a,0x462dfdab,0xc33d8808,0x1dcd995e,0x0fcb11ba,0x11755914,0x5a62044b,0x37f76755
1866  ,0x345bd058,0x8831c2b5,0x204a8468,0x3b0b1cd2,0x444e56f4,0x97a93e2c,0xd5f15067,0x266a95fa
1867  ,0xff4f8036,0x6160060d,0x930c472f,0xed922184,0x37120251,0xc0add74f,0x1c0bc89d,0x018d47f2
1868  ,0xff59ef66,0xd1901a17,0x91f6701b,0x0960082f,0x86f6a8f3,0x1154fecd,0x9867d1de,0x0945482f
1869  ,0x790ffcac,0xe5610011,0x4765637e,0xa745dbff,0x841fdcb3,0x4f7372a0,0x3c05013d,0xf1ac4ab7
1870  ,0x3bc5b5cc,0x49a73349,0x356a7f67,0x1174f031,0x11d32634,0x4413d301,0x1dd285c4,0x3fae4800
1871  };
1872 
1873  if (ntxt > 255) ntxt = 255;
1874 
1875  for ( ; ntxt--; uc++) {
1876  uu = uu<<1 ^ utab[(*uc) ^ ntxt];
1877  u ^= uu;
1878  }
1879  return u;
1880 }
1881 
1882 #else
1883 
1884 //______________________________________________________________________________
1885 ULong_urt URMath::Hash(const void *txt, Int_urt ntxt)
1886 {
1887  // Calculates hash index from any char string.
1888  // Based on precalculated table of 256 specially selected numbers.
1889  // These numbers are selected in such a way, that for string
1890  // length == 4 (integer number) the hash is unambigous, i.e.
1891  // from hash value we can recalculate input (no degeneration).
1892  //
1893  // The quality of hash method is good enough, that
1894  // "random" numbers made as R = Hash(1), Hash(2), ...Hash(N)
1895  // tested by <R>, <R*R>, <Ri*Ri+1> gives the same result
1896  // as for libc rand().
1897  //
1898  // For string: i = URMath::Hash(string,nstring);
1899  // For int: i = URMath::Hash(&intword,sizeof(int));
1900  // For pointer: i = URMath::Hash(&pointer,sizeof(void*));
1901  //
1902  // V.Perev
1903 
1904  static const ULong_urt utab[] = {
1905  0xdd367647,0x9caf993f,0x3f3cc5ff,0xfde25082,0x4c764b21,0x89affca7,0x5431965c,0xce22eeec
1906  ,0xc61ab4dc,0x59cc93bd,0xed3107e3,0x0b0a287a,0x4712475a,0xce4a4c71,0x352c8403,0x94cb3cee
1907  ,0xc3ac509b,0x09f827a2,0xce02e37e,0x7b20bbba,0x76adcedc,0x18c52663,0x19f74103,0x6f30e47b
1908  ,0x132ea5a1,0xfdd279e0,0xa3d57d00,0xcff9cb40,0x9617f384,0x6411acfa,0xff908678,0x5c796b2c
1909  ,0x4471b62d,0xd38e3275,0xdb57912d,0x26bf953f,0xfc41b2a5,0xe64bcebd,0x190b7839,0x7e8e6a56
1910  ,0x9ca22311,0xef28aa60,0xe6b9208e,0xd257fb65,0x45781c2c,0x9a558ac3,0x2743e74d,0x839417a8
1911  ,0x06b54d5d,0x1a82bcb4,0x06e97a66,0x70abdd03,0xd163f30d,0x222ed322,0x777bfeda,0xab7a2e83
1912  ,0x8494e0cf,0x2dca2d4f,0x78f94278,0x33f04a09,0x402b6452,0x0cd8b709,0xdb72a39e,0x170e00a2
1913  ,0x26354faa,0x80e57453,0xcfe8d4e1,0x19e45254,0x04c291c3,0xeb503738,0x425af3bc,0x67836f2a
1914  ,0xfac22add,0xfafc2b8c,0x59b8c2a0,0x03e806f9,0xcb4938b9,0xccc942af,0xcee3ae2e,0xfbe748fa
1915  ,0xb223a075,0x85c49b5d,0xe4576ac9,0x0fbd46e2,0xb49f9cf5,0xf3e1e86a,0x7d7927fb,0x711afe12
1916  ,0xbf61c346,0x157c9956,0x86b6b046,0x2e402146,0xb2a57d8a,0x0d064bb1,0x30ce390c,0x3a3e1eb1
1917  ,0xbe7f6f8f,0xd8e30f87,0x5be2813c,0x73a3a901,0xa3aaf967,0x59ff092c,0x1705c798,0xf610dd66
1918  ,0xb17da91e,0x8e59534e,0x2211ea5b,0xa804ba03,0xd890efbb,0xb8b48110,0xff390068,0xc8c325b4
1919  ,0xf7289c07,0x787e104f,0x3d0df3d0,0x3526796d,0x10548055,0x1d59a42b,0xed1cc5a3,0xdd45372a
1920  ,0x31c50d57,0x65757cb7,0x3cfb85be,0xa329910d,0x6ad8ce39,0xa2de44de,0x0dd32432,0xd4a5b617
1921  ,0x8f3107fc,0x96485175,0x7f94d4f3,0x35097634,0xdb3ca782,0x2c0290b8,0x2045300b,0xe0f5d15a
1922  ,0x0e8cbffa,0xaa1cc38a,0x84008d6f,0xe9a9e794,0x5c602c25,0xfa3658fa,0x98d9d82b,0x3f1497e7
1923  ,0x84b6f031,0xe381eff9,0xfc7ae252,0xb239e05d,0xe3723d1f,0xcc3bda82,0xe21b1ad3,0x9104f7c8
1924  ,0x4bb2dfcd,0x4d14a8bc,0x6ba7f28c,0x8f89886c,0xad44c97e,0xb30fd975,0x633cdab1,0xf6c2d514
1925  ,0x067a49d2,0xdc461ad9,0xebaf9f3f,0x8dc6cac3,0x7a060f16,0xbab063ad,0xf42e25e6,0x60724ca6
1926  ,0xc7245c2e,0x4e48ea3c,0x9f89a609,0xa1c49890,0x4bb7f116,0xd722865c,0xa8ee3995,0x0ee070b1
1927  ,0xd9bffcc2,0xe55b64f9,0x25507a5a,0xc7a3e2b5,0x5f395f7e,0xe7957652,0x7381ba6a,0xde3d21f1
1928  ,0xdf1708dd,0xad0c9d0c,0x00cbc9e5,0x1160e833,0x6779582c,0x29d5d393,0x3f11d7d7,0x826a6b9b
1929  ,0xe73ff12f,0x8bad3d86,0xee41d3e5,0x7f0c8917,0x8089ef24,0x90c5cb28,0x2f7f8e6b,0x6966418a
1930  ,0x345453fb,0x7a2f8a68,0xf198593d,0xc079a532,0xc1971e81,0x1ab74e26,0x329ef347,0x7423d3d0
1931  ,0x942c510b,0x7f6c6382,0x14ae6acc,0x64b59da7,0x2356fa47,0xb6749d9c,0x499de1bb,0x92ffd191
1932  ,0xe8f2fb75,0x848dc913,0x3e8727d3,0x1dcffe61,0xb6e45245,0x49055738,0x827a6b55,0xb4788887
1933  ,0x7e680125,0xd19ce7ed,0x6b4b8e30,0xa8cadea2,0x216035d8,0x1c63bc3c,0xe1299056,0x1ad3dff4
1934  ,0x0aefd13c,0x0e7b921c,0xca0173c6,0x9995782d,0xcccfd494,0xd4b0ac88,0x53d552b1,0x630dae8b
1935  ,0xa8332dad,0x7139d9a2,0x5d76f2c4,0x7a4f8f1e,0x8d1aef97,0xd1cf285d,0xc8239153,0xce2608a9
1936  ,0x7b562475,0xe4b4bc83,0xf3db0c3a,0x70a65e48,0x6016b302,0xdebd5046,0x707e786a,0x6f10200c
1937  };
1938 
1939  static const ULong_urt msk[] = { 0x11111111, 0x33333333, 0x77777777, 0xffffffff };
1940 
1941  const UChar_urt *uc = (const UChar_urt *) txt;
1942  ULong_urt uu = 0;
1943  union {
1944  ULong_urt u;
1945  UShort_urt s[2];
1946  } u;
1947  u.u = 0;
1948  Int_urt i, idx;
1949 
1950  for (i = 0; i < ntxt; i++) {
1951  idx = (uc[i] ^ i) & 255;
1952  uu = (uu << 1) ^ (utab[idx] & msk[i & 3]);
1953  if (i & 3 == 3) u.u ^= uu;
1954  }
1955  if (i & 3) u.u ^= uu;
1956 
1957  u.u *= 1879048201; // prime number
1958  u.s[0] += u.s[1];
1959  u.u *= 1979048191; // prime number
1960  u.s[1] ^= u.s[0];
1961  u.u *= 2079048197; // prime number
1962 
1963  return u.u;
1964 }
1965 
1966 #endif
1967 
1968 //______________________________________________________________________________
1969 ULong_urt URMath::Hash(const char *txt)
1970 {
1971  return Hash(txt, Int_urt(strlen(txt)));
1972 }
1973 
1974 //______________________________________________________________________________
1976 {
1977  // Compute the modified Bessel function I_0(x) for any real x.
1978  //
1979  //--- NvE 12-mar-2000 UU-SAP Utrecht
1980 
1981  // Parameters of the polynomial approximation
1982  const Double_urt p1=1.0, p2=3.5156229, p3=3.0899424,
1983  p4=1.2067492, p5=0.2659732, p6=3.60768e-2, p7=4.5813e-3;
1984 
1985  const Double_urt q1= 0.39894228, q2= 1.328592e-2, q3= 2.25319e-3,
1986  q4=-1.57565e-3, q5= 9.16281e-3, q6=-2.057706e-2,
1987  q7= 2.635537e-2, q8=-1.647633e-2, q9= 3.92377e-3;
1988 
1989  const Double_urt k1 = 3.75;
1990  Double_urt ax = URMath::Abs(x);
1991 
1992  Double_urt y=0, result=0;
1993 
1994  if (ax < k1) {
1995  Double_urt xx = x/k1;
1996  y = xx*xx;
1997  result = p1+y*(p2+y*(p3+y*(p4+y*(p5+y*(p6+y*p7)))));
1998  } else {
1999  y = k1/ax;
2000  result = (URMath::Exp(ax)/URMath::Sqrt(ax))*(q1+y*(q2+y*(q3+y*(q4+y*(q5+y*(q6+y*(q7+y*(q8+y*q9))))))));
2001  }
2002  return result;
2003 }
2004 
2005 //______________________________________________________________________________
2007 {
2008  // Compute the modified Bessel function K_0(x) for positive real x.
2009  //
2010  // M.Abramowitz and I.A.Stegun, Handbook of Mathematical Functions,
2011  // Applied Mathematics Series vol. 55 (1964), Washington.
2012  //
2013  //--- NvE 12-mar-2000 UU-SAP Utrecht
2014 
2015  // Parameters of the polynomial approximation
2016  const Double_urt p1=-0.57721566, p2=0.42278420, p3=0.23069756,
2017  p4= 3.488590e-2, p5=2.62698e-3, p6=1.0750e-4, p7=7.4e-5;
2018 
2019  const Double_urt q1= 1.25331414, q2=-7.832358e-2, q3= 2.189568e-2,
2020  q4=-1.062446e-2, q5= 5.87872e-3, q6=-2.51540e-3, q7=5.3208e-4;
2021 
2022  if (x <= 0) {
2023  Error("URMath::BesselK0", "*K0* Invalid argument x = %g\n",x);
2024  return 0;
2025  }
2026 
2027  Double_urt y=0, result=0;
2028 
2029  if (x <= 2) {
2030  y = x*x/4;
2031  result = (-log(x/2.)*URMath::BesselI0(x))+(p1+y*(p2+y*(p3+y*(p4+y*(p5+y*(p6+y*p7))))));
2032  } else {
2033  y = 2/x;
2034  result = (exp(-x)/sqrt(x))*(q1+y*(q2+y*(q3+y*(q4+y*(q5+y*(q6+y*q7))))));
2035  }
2036  return result;
2037 }
2038 
2039 //______________________________________________________________________________
2041 {
2042  // Compute the modified Bessel function I_1(x) for any real x.
2043  //
2044  // M.Abramowitz and I.A.Stegun, Handbook of Mathematical Functions,
2045  // Applied Mathematics Series vol. 55 (1964), Washington.
2046  //
2047  //--- NvE 12-mar-2000 UU-SAP Utrecht
2048 
2049  // Parameters of the polynomial approximation
2050  const Double_urt p1=0.5, p2=0.87890594, p3=0.51498869,
2051  p4=0.15084934, p5=2.658733e-2, p6=3.01532e-3, p7=3.2411e-4;
2052 
2053  const Double_urt q1= 0.39894228, q2=-3.988024e-2, q3=-3.62018e-3,
2054  q4= 1.63801e-3, q5=-1.031555e-2, q6= 2.282967e-2,
2055  q7=-2.895312e-2, q8= 1.787654e-2, q9=-4.20059e-3;
2056 
2057  const Double_urt k1 = 3.75;
2058  Double_urt ax = URMath::Abs(x);
2059 
2060  Double_urt y=0, result=0;
2061 
2062  if (ax < k1) {
2063  Double_urt xx = x/k1;
2064  y = xx*xx;
2065  result = x*(p1+y*(p2+y*(p3+y*(p4+y*(p5+y*(p6+y*p7))))));
2066  } else {
2067  y = k1/ax;
2068  result = (exp(ax)/sqrt(ax))*(q1+y*(q2+y*(q3+y*(q4+y*(q5+y*(q6+y*(q7+y*(q8+y*q9))))))));
2069  if (x < 0) result = -result;
2070  }
2071  return result;
2072 }
2073 
2074 //______________________________________________________________________________
2076 {
2077  // Compute the modified Bessel function K_1(x) for positive real x.
2078  //
2079  // M.Abramowitz and I.A.Stegun, Handbook of Mathematical Functions,
2080  // Applied Mathematics Series vol. 55 (1964), Washington.
2081  //
2082  //--- NvE 12-mar-2000 UU-SAP Utrecht
2083 
2084  // Parameters of the polynomial approximation
2085  const Double_urt p1= 1., p2= 0.15443144, p3=-0.67278579,
2086  p4=-0.18156897, p5=-1.919402e-2, p6=-1.10404e-3, p7=-4.686e-5;
2087 
2088  const Double_urt q1= 1.25331414, q2= 0.23498619, q3=-3.655620e-2,
2089  q4= 1.504268e-2, q5=-7.80353e-3, q6= 3.25614e-3, q7=-6.8245e-4;
2090 
2091  if (x <= 0) {
2092  Error("URMath::BesselK1", "*K1* Invalid argument x = %g\n",x);
2093  return 0;
2094  }
2095 
2096  Double_urt y=0,result=0;
2097 
2098  if (x <= 2) {
2099  y = x*x/4;
2100  result = (log(x/2.)*URMath::BesselI1(x))+(1./x)*(p1+y*(p2+y*(p3+y*(p4+y*(p5+y*(p6+y*p7))))));
2101  } else {
2102  y = 2/x;
2103  result = (exp(-x)/sqrt(x))*(q1+y*(q2+y*(q3+y*(q4+y*(q5+y*(q6+y*q7))))));
2104  }
2105  return result;
2106 }
2107 
2108 //______________________________________________________________________________
2110 {
2111  // Compute the Integer Order Modified Bessel function K_n(x)
2112  // for n=0,1,2,... and positive real x.
2113  //
2114  //--- NvE 12-mar-2000 UU-SAP Utrecht
2115 
2116  if (x <= 0 || n < 0) {
2117  Error("URMath::BesselK", "*K* Invalid argument(s) (n,x) = (%d, %g)\n",n,x);
2118  return 0;
2119  }
2120 
2121  if (n==0) return URMath::BesselK0(x);
2122  if (n==1) return URMath::BesselK1(x);
2123 
2124  // Perform upward recurrence for all x
2125  Double_urt tox = 2/x;
2126  Double_urt bkm = URMath::BesselK0(x);
2127  Double_urt bk = URMath::BesselK1(x);
2128  Double_urt bkp = 0;
2129  for (Int_urt j=1; j<n; j++) {
2130  bkp = bkm+Double_urt(j)*tox*bk;
2131  bkm = bk;
2132  bk = bkp;
2133  }
2134  return bk;
2135 }
2136 
2137 //______________________________________________________________________________
2139 {
2140  // Compute the Integer Order Modified Bessel function I_n(x)
2141  // for n=0,1,2,... and any real x.
2142  //
2143  //--- NvE 12-mar-2000 UU-SAP Utrecht
2144 
2145  Int_urt iacc = 40; // Increase to enhance accuracy
2146  const Double_urt kBigPositive = 1.e10;
2147  const Double_urt kBigNegative = 1.e-10;
2148 
2149  if (n < 0) {
2150  Error("URMath::BesselI", "*I* Invalid argument (n,x) = (%d, %g)\n",n,x);
2151  return 0;
2152  }
2153 
2154  if (n==0) return URMath::BesselI0(x);
2155  if (n==1) return URMath::BesselI1(x);
2156 
2157  if (URMath::Abs(x) > kBigPositive) return 0;
2158 
2159  Double_urt tox = 2/URMath::Abs(x);
2160  Double_urt bip = 0, bim = 0;
2161  Double_urt bi = 1;
2162  Double_urt result = 0;
2163  Int_urt m = 2*((n+Int_urt(sqrt(Float_urt(iacc*n)))));
2164  for (Int_urt j=m; j>=1; j--) {
2165  bim = bip+Double_urt(j)*tox*bi;
2166  bip = bi;
2167  bi = bim;
2168  // Renormalise to prevent overflows
2169  if (URMath::Abs(bi) > kBigPositive) {
2170  result *= kBigNegative;
2171  bi *= kBigNegative;
2172  bip *= kBigNegative;
2173  }
2174  if (j==n) result=bip;
2175  }
2176 
2177  result *= URMath::BesselI0(x)/bi; // Normalise with BesselI0(x)
2178  if ((x < 0) && (n%2 == 1)) result = -result;
2179 
2180  return result;
2181 }
2182 
2183 //______________________________________________________________________________
2185 {
2186  // Returns the Bessel function J0(x) for any real x.
2187 
2188  Double_urt ax,z;
2189  Double_urt xx,y,result,result1,result2;
2190  const Double_urt p1 = 57568490574.0, p2 = -13362590354.0, p3 = 651619640.7;
2191  const Double_urt p4 = -11214424.18, p5 = 77392.33017, p6 = -184.9052456;
2192  const Double_urt p7 = 57568490411.0, p8 = 1029532985.0, p9 = 9494680.718;
2193  const Double_urt p10 = 59272.64853, p11 = 267.8532712;
2194 
2195  const Double_urt q1 = 0.785398164;
2196  const Double_urt q2 = -0.1098628627e-2, q3 = 0.2734510407e-4;
2197  const Double_urt q4 = -0.2073370639e-5, q5 = 0.2093887211e-6;
2198  const Double_urt q6 = -0.1562499995e-1, q7 = 0.1430488765e-3;
2199  const Double_urt q8 = -0.6911147651e-5, q9 = 0.7621095161e-6;
2200  const Double_urt q10 = 0.934935152e-7, q11 = 0.636619772;
2201 
2202  if ((ax=fabs(x)) < 8) {
2203  y=x*x;
2204  result1 = p1 + y*(p2 + y*(p3 + y*(p4 + y*(p5 + y*p6))));
2205  result2 = p7 + y*(p8 + y*(p9 + y*(p10 + y*(p11 + y))));
2206  result = result1/result2;
2207  } else {
2208  z = 8/ax;
2209  y = z*z;
2210  xx = ax-q1;
2211  result1 = 1 + y*(q2 + y*(q3 + y*(q4 + y*q5)));
2212  result2 = q6 + y*(q7 + y*(q8 + y*(q9 - y*q10)));
2213  result = sqrt(q11/ax)*(cos(xx)*result1-z*sin(xx)*result2);
2214  }
2215  return result;
2216 }
2217 
2218 //______________________________________________________________________________
2220 {
2221  // Returns the Bessel function J1(x) for any real x.
2222 
2223  Double_urt ax,z;
2224  Double_urt xx,y,result,result1,result2;
2225  const Double_urt p1 = 72362614232.0, p2 = -7895059235.0, p3 = 242396853.1;
2226  const Double_urt p4 = -2972611.439, p5 = 15704.48260, p6 = -30.16036606;
2227  const Double_urt p7 = 144725228442.0, p8 = 2300535178.0, p9 = 18583304.74;
2228  const Double_urt p10 = 99447.43394, p11 = 376.9991397;
2229 
2230  const Double_urt q1 = 2.356194491;
2231  const Double_urt q2 = 0.183105e-2, q3 = -0.3516396496e-4;
2232  const Double_urt q4 = 0.2457520174e-5, q5 = -0.240337019e-6;
2233  const Double_urt q6 = 0.04687499995, q7 = -0.2002690873e-3;
2234  const Double_urt q8 = 0.8449199096e-5, q9 = -0.88228987e-6;
2235  const Double_urt q10 = 0.105787412e-6, q11 = 0.636619772;
2236 
2237  if ((ax=fabs(x)) < 8) {
2238  y=x*x;
2239  result1 = x*(p1 + y*(p2 + y*(p3 + y*(p4 + y*(p5 + y*p6)))));
2240  result2 = p7 + y*(p8 + y*(p9 + y*(p10 + y*(p11 + y))));
2241  result = result1/result2;
2242  } else {
2243  z = 8/ax;
2244  y = z*z;
2245  xx = ax-q1;
2246  result1 = 1 + y*(q2 + y*(q3 + y*(q4 + y*q5)));
2247  result2 = q6 + y*(q7 + y*(q8 + y*(q9 + y*q10)));
2248  result = sqrt(q11/ax)*(cos(xx)*result1-z*sin(xx)*result2);
2249  if (x < 0) result = -result;
2250  }
2251  return result;
2252 }
2253 
2254 //______________________________________________________________________________
2256 {
2257  // Returns the Bessel function Y0(x) for positive x.
2258 
2259  Double_urt z,xx,y,result,result1,result2;
2260  const Double_urt p1 = -2957821389., p2 = 7062834065.0, p3 = -512359803.6;
2261  const Double_urt p4 = 10879881.29, p5 = -86327.92757, p6 = 228.4622733;
2262  const Double_urt p7 = 40076544269., p8 = 745249964.8, p9 = 7189466.438;
2263  const Double_urt p10 = 47447.26470, p11 = 226.1030244, p12 = 0.636619772;
2264 
2265  const Double_urt q1 = 0.785398164;
2266  const Double_urt q2 = -0.1098628627e-2, q3 = 0.2734510407e-4;
2267  const Double_urt q4 = -0.2073370639e-5, q5 = 0.2093887211e-6;
2268  const Double_urt q6 = -0.1562499995e-1, q7 = 0.1430488765e-3;
2269  const Double_urt q8 = -0.6911147651e-5, q9 = 0.7621095161e-6;
2270  const Double_urt q10 = -0.934945152e-7, q11 = 0.636619772;
2271 
2272  if (x < 8) {
2273  y = x*x;
2274  result1 = p1 + y*(p2 + y*(p3 + y*(p4 + y*(p5 + y*p6))));
2275  result2 = p7 + y*(p8 + y*(p9 + y*(p10 + y*(p11 + y))));
2276  result = (result1/result2) + p12*URMath::BesselJ0(x)*log(x);
2277  } else {
2278  z = 8/x;
2279  y = z*z;
2280  xx = x-q1;
2281  result1 = 1 + y*(q2 + y*(q3 + y*(q4 + y*q5)));
2282  result2 = q6 + y*(q7 + y*(q8 + y*(q9 + y*q10)));
2283  result = sqrt(q11/x)*(sin(xx)*result1+z*cos(xx)*result2);
2284  }
2285  return result;
2286 }
2287 
2288 //______________________________________________________________________________
2290 {
2291  // Returns the Bessel function Y1(x) for positive x.
2292 
2293  Double_urt z,xx,y,result,result1,result2;
2294  const Double_urt p1 = -0.4900604943e13, p2 = 0.1275274390e13;
2295  const Double_urt p3 = -0.5153438139e11, p4 = 0.7349264551e9;
2296  const Double_urt p5 = -0.4237922726e7, p6 = 0.8511937935e4;
2297  const Double_urt p7 = 0.2499580570e14, p8 = 0.4244419664e12;
2298  const Double_urt p9 = 0.3733650367e10, p10 = 0.2245904002e8;
2299  const Double_urt p11 = 0.1020426050e6, p12 = 0.3549632885e3;
2300  const Double_urt p13 = 0.636619772;
2301  const Double_urt q1 = 2.356194491;
2302  const Double_urt q2 = 0.183105e-2, q3 = -0.3516396496e-4;
2303  const Double_urt q4 = 0.2457520174e-5, q5 = -0.240337019e-6;
2304  const Double_urt q6 = 0.04687499995, q7 = -0.2002690873e-3;
2305  const Double_urt q8 = 0.8449199096e-5, q9 = -0.88228987e-6;
2306  const Double_urt q10 = 0.105787412e-6, q11 = 0.636619772;
2307 
2308  if (x < 8) {
2309  y=x*x;
2310  result1 = x*(p1 + y*(p2 + y*(p3 + y*(p4 + y*(p5 + y*p6)))));
2311  result2 = p7 + y*(p8 + y*(p9 + y*(p10 + y*(p11 + y*(p12+y)))));
2312  result = (result1/result2) + p13*(URMath::BesselJ1(x)*log(x)-1/x);
2313  } else {
2314  z = 8/x;
2315  y = z*z;
2316  xx = x-q1;
2317  result1 = 1 + y*(q2 + y*(q3 + y*(q4 + y*q5)));
2318  result2 = q6 + y*(q7 + y*(q8 + y*(q9 + y*q10)));
2319  result = sqrt(q11/x)*(sin(xx)*result1+z*cos(xx)*result2);
2320  }
2321  return result;
2322 }
2323 
2324 //______________________________________________________________________________
2326 {
2327  // Struve Functions of Order 0
2328  //
2329  // Converted from CERNLIB M342 by Rene Brun.
2330 
2331  const Int_urt n1 = 15;
2332  const Int_urt n2 = 25;
2333  const Double_urt c1[16] = { 1.00215845609911981, -1.63969292681309147,
2334  1.50236939618292819, -.72485115302121872,
2335  .18955327371093136, -.03067052022988,
2336  .00337561447375194, -2.6965014312602e-4,
2337  1.637461692612e-5, -7.8244408508e-7,
2338  3.021593188e-8, -9.6326645e-10,
2339  2.579337e-11, -5.8854e-13,
2340  1.158e-14, -2e-16 };
2341  const Double_urt c2[26] = { .99283727576423943, -.00696891281138625,
2342  1.8205103787037e-4, -1.063258252844e-5,
2343  9.8198294287e-7, -1.2250645445e-7,
2344  1.894083312e-8, -3.44358226e-9,
2345  7.1119102e-10, -1.6288744e-10,
2346  4.065681e-11, -1.091505e-11,
2347  3.12005e-12, -9.4202e-13,
2348  2.9848e-13, -9.872e-14,
2349  3.394e-14, -1.208e-14,
2350  4.44e-15, -1.68e-15,
2351  6.5e-16, -2.6e-16,
2352  1.1e-16, -4e-17,
2353  2e-17, -1e-17 };
2354 
2355  const Double_urt c0 = 2/URMath::Pi();
2356 
2357  Int_urt i;
2358  Double_urt alfa, h, r, y, b0, b1, b2;
2359  Double_urt v = URMath::Abs(x);
2360 
2361  v = URMath::Abs(x);
2362  if (v < 8) {
2363  y = v/8;
2364  h = 2*y*y -1;
2365  alfa = h + h;
2366  b0 = 0;
2367  b1 = 0;
2368  b2 = 0;
2369  for (i = n1; i >= 0; --i) {
2370  b0 = c1[i] + alfa*b1 - b2;
2371  b2 = b1;
2372  b1 = b0;
2373  }
2374  h = y*(b0 - h*b2);
2375  } else {
2376  r = 1/v;
2377  h = 128*r*r -1;
2378  alfa = h + h;
2379  b0 = 0;
2380  b1 = 0;
2381  b2 = 0;
2382  for (i = n2; i >= 0; --i) {
2383  b0 = c2[i] + alfa*b1 - b2;
2384  b2 = b1;
2385  b1 = b0;
2386  }
2387  h = URMath::BesselY0(v) + r*c0*(b0 - h*b2);
2388  }
2389  if (x < 0) h = -h;
2390  return h;
2391 }
2392 
2393 //______________________________________________________________________________
2395 {
2396  // Struve Functions of Order 1
2397  //
2398  // Converted from CERNLIB M342 by Rene Brun.
2399 
2400  const Int_urt n3 = 16;
2401  const Int_urt n4 = 22;
2402  const Double_urt c3[17] = { .5578891446481605, -.11188325726569816,
2403  -.16337958125200939, .32256932072405902,
2404  -.14581632367244242, .03292677399374035,
2405  -.00460372142093573, 4.434706163314e-4,
2406  -3.142099529341e-5, 1.7123719938e-6,
2407  -7.416987005e-8, 2.61837671e-9,
2408  -7.685839e-11, 1.9067e-12,
2409  -4.052e-14, 7.5e-16,
2410  -1e-17 };
2411  const Double_urt c4[23] = { 1.00757647293865641, .00750316051248257,
2412  -7.043933264519e-5, 2.66205393382e-6,
2413  -1.8841157753e-7, 1.949014958e-8,
2414  -2.6126199e-9, 4.236269e-10,
2415  -7.955156e-11, 1.679973e-11,
2416  -3.9072e-12, 9.8543e-13,
2417  -2.6636e-13, 7.645e-14,
2418  -2.313e-14, 7.33e-15,
2419  -2.42e-15, 8.3e-16,
2420  -3e-16, 1.1e-16,
2421  -4e-17, 2e-17,-1e-17 };
2422 
2423  const Double_urt c0 = 2/URMath::Pi();
2424  const Double_urt cc = 2/(3*URMath::Pi());
2425 
2426  Int_urt i, i1;
2427  Double_urt alfa, h, r, y, b0, b1, b2;
2428  Double_urt v = URMath::Abs(x);
2429 
2430  if (v == 0) {
2431  h = 0;
2432  } else if (v <= 0.3) {
2433  y = v*v;
2434  r = 1;
2435  h = 1;
2436  i1 = (Int_urt)(-8. / URMath::Log10(v));
2437  for (i = 1; i <= i1; ++i) {
2438  h = -h*y / ((2*i+ 1)*(2*i + 3));
2439  r += h;
2440  }
2441  h = cc*y*r;
2442  } else if (v < 8) {
2443  h = v*v/32 -1;
2444  alfa = h + h;
2445  b0 = 0;
2446  b1 = 0;
2447  b2 = 0;
2448  for (i = n3; i >= 0; --i) {
2449  b0 = c3[i] + alfa*b1 - b2;
2450  b2 = b1;
2451  b1 = b0;
2452  }
2453  h = b0 - h*b2;
2454  } else {
2455  h = 128/(v*v) -1;
2456  alfa = h + h;
2457  b0 = 0;
2458  b1 = 0;
2459  b2 = 0;
2460  for (i = n4; i >= 0; --i) {
2461  b0 = c4[i] + alfa*b1 - b2;
2462  b2 = b1;
2463  b1 = b0;
2464  }
2465  h = URMath::BesselY1(v) + c0*(b0 - h*b2);
2466  }
2467  return h;
2468 }
2469 
2470 
2471 //______________________________________________________________________________
2473 {
2474  // Modified Struve Function of Order 0
2475  // (from Kirill Filimonov)
2476 
2477  const Double_urt pi=URMath::Pi();
2478 
2479  Double_urt s=1.0;
2480  Double_urt r=1.0;
2481 
2482  Double_urt a0,sl0,a1,bi0;
2483 
2484  Int_urt km,i;
2485 
2486  if (x<=20.) {
2487  a0=2.0*x/pi;
2488  for (int i=1; i<=60;i++) {
2489  r*=(x/(2*i+1))*(x/(2*i+1));
2490  s+=r;
2491  if(URMath::Abs(r/s)<1.e-12) break;
2492  }
2493  sl0=a0*s;
2494  } else {
2495  km=int(5*(x+1.0));
2496  if(x>=50.0)km=25;
2497  for (i=1; i<=km; i++) {
2498  r*=(2*i-1)*(2*i-1)/x/x;
2499  s+=r;
2500  if(URMath::Abs(r/s)<1.0e-12) break;
2501  }
2502  a1=URMath::Exp(x)/URMath::Sqrt(2*pi*x);
2503  r=1.0;
2504  bi0=1.0;
2505  for (i=1; i<=16; i++) {
2506  r=0.125*r*(2.0*i-1.0)*(2.0*i-1.0)/(i*x);
2507  bi0+=r;
2508  if(URMath::Abs(r/bi0)<1.0e-12) break;
2509  }
2510 
2511  bi0=a1*bi0;
2512  sl0=-2.0/(pi*x)*s+bi0;
2513  }
2514  return sl0;
2515 }
2516 
2517 //______________________________________________________________________________
2519 {
2520  // Modified Struve Function of Order 1
2521  // (from Kirill Filimonov)
2522 
2523  const Double_urt pi=URMath::Pi();
2524  Double_urt a1,sl1,bi1,s;
2525  Double_urt r=1.0;
2526  Int_urt km,i;
2527 
2528  if (x<=20.) {
2529  s=0.0;
2530  for (i=1; i<=60;i++) {
2531  r*=x*x/(4.0*i*i-1.0);
2532  s+=r;
2533  if(URMath::Abs(r)<URMath::Abs(s)*1.e-12) break;
2534  }
2535  sl1=2.0/pi*s;
2536  } else {
2537  s=1.0;
2538  km=int(0.5*x);
2539  if(x>50.0)km=25;
2540  for (i=1; i<=km; i++) {
2541  r*=(2*i+3)*(2*i+1)/x/x;
2542  s+=r;
2543  if(URMath::Abs(r/s)<1.0e-12) break;
2544  }
2545  sl1=2.0/pi*(-1.0+1.0/(x*x)+3.0*s/(x*x*x*x));
2546  a1=URMath::Exp(x)/URMath::Sqrt(2*pi*x);
2547  r=1.0;
2548  bi1=1.0;
2549  for (i=1; i<=16; i++) {
2550  r=-0.125*r*(4.0-(2.0*i-1.0)*(2.0*i-1.0))/(i*x);
2551  bi1+=r;
2552  if(URMath::Abs(r/bi1)<1.0e-12) break;
2553  }
2554  sl1+=a1*bi1;
2555  }
2556  return sl1;
2557 }
2558 
2559 void
2560 URMath::Error( const string& errorMessage, double value ) {
2561  cout << errorMessage << ' ' << value << endl;
2562 }
2563 
2564 void
2565 URMath::Error( const string& errorMessage, int iValue, double value ) {
2566  cout << errorMessage << ' ' << intValue << ' ' << value << endl;
2567 }
2568 
2569 #endif
2570 
long Long_urt
Definition: URtypes.h:46
static Int_urt LocMax(Int_urt n, const Short_urt *a)
static ULong_urt Hash(const void *txt, Int_urt ntxt)
double exp(double)
short Short_urt
Definition: URtypes.h:31
static Double_urt ACosH(Double_urt)
static Float_urt * Cross(Float_urt v1[3], Float_urt v2[3], Float_urt out[3])
static Double_urt ASinH(Double_urt)
unsigned long ULong_urt
Definition: URtypes.h:47
static Float_urt Normalize(Float_urt v[3])
static Double_urt KolmogorovProb(Double_urt z)
static void Sort(Int_urt n, const Short_urt *a, Int_urt *index, Bool_urt down=kurTRUE)
static Double_urt Ceil(Double_urt x)
static Double_urt BesselI1(Double_urt x)
static Short_urt Max(Short_urt a, Short_urt b)
Definition: URMath.h:358
int Int_urt
Definition: URtypes.h:37
const Bool_urt kurFALSE
Definition: URtypes.h:76
static Int_urt Nint(Float_urt x)
unsigned char UChar_urt
Definition: URtypes.h:30
static Double_urt BreitWigner(Double_urt x, Double_urt mean=0, Double_urt gamma=1)
static Double_urt StruveH1(Double_urt x)
static Double_urt Log2(Double_urt x)
static Double_urt BesselY0(Double_urt x)
static Double_urt Log10(Double_urt x)
Definition: URMath.h:496
static Double_urt BesselK0(Double_urt x)
static Int_urt LocMin(Int_urt n, const Short_urt *a)
static Double_urt Floor(Double_urt x)
static Double_urt StruveL0(Double_urt x)
static Double_urt K()
Definition: URMath.h:89
static Double_urt Log(Double_urt x)
Definition: URMath.h:493
static Double_urt Hypot(Double_urt x, Double_urt y)
static Double_urt BesselI(Int_urt n, Double_urt x)
static Double_urt LnGamma(Double_urt z)
static Double_urt C()
Definition: URMath.h:57
static Double_urt Exp(Double_urt)
Definition: URMath.h:487
const Bool_urt kurTRUE
Definition: URtypes.h:75
double cos(double)
static Double_urt Factorial(Int_urt)
static Double_urt StruveL1(Double_urt x)
float Float_urt
Definition: URtypes.h:49
double sqrt(double)
static Float_urt * Normal2Plane(Float_urt v1[3], Float_urt v2[3], Float_urt v3[3], Float_urt normal[3])
static Double_urt BesselJ1(Double_urt x)
static Double_urt Erfc(Double_urt x)
static Double_urt Gamma(Double_urt z)
static Double_urt Sqrt(Double_urt x)
Definition: URMath.h:484
void Error(const std::string &errorMessage, double value)
static Double_urt BesselY1(Double_urt x)
static Double_urt Power(Double_urt x, Double_urt y)
Definition: URMath.h:490
static Double_urt BesselK1(Double_urt x)
static Long_urt NextPrime(Long_urt x)
static Short_urt Abs(Short_urt d)
Definition: URMath.h:298
unsigned short UShort_urt
Definition: URtypes.h:32
static Double_urt R()
Definition: URMath.h:103
static Double_urt Freq(Double_urt x)
static Double_urt Poisson(Double_urt x, Double_urt par)
static Float_urt NormCross(Float_urt v1[3], Float_urt v2[3], Float_urt out[3])
Definition: URMath.h:511
static Double_urt StruveH0(Double_urt x)
double Double_urt
Definition: URtypes.h:50
static void BubbleLow(Int_urt Narr, Double_urt *arr1, Int_urt *arr2)
double sin(double)
static Double_urt BesselI0(Double_urt x)
static Bool_urt IsInside(Double_urt xp, Double_urt yp, Int_urt np, Double_urt *x, Double_urt *y)
static Double_urt Pi()
Definition: URMath.h:39
static void BubbleHigh(Int_urt Narr, Double_urt *arr1, Int_urt *arr2)
bool Bool_urt
Definition: URtypes.h:52
double log(double)
static Double_urt ATanH(Double_urt)
static Double_urt BesselJ0(Double_urt x)
static Int_urt BinarySearch(Int_urt n, const Short_urt *array, Short_urt value)
static Double_urt Voigt(Double_urt x, Double_urt sigma, Double_urt lg, Int_urt R=4)
static Double_urt BesselK(Int_urt n, Double_urt x)
static Double_urt Landau(Double_urt x, Double_urt mean=0, Double_urt sigma=1)
static Double_urt Prob(Double_urt chi2, Int_urt ndf)
static Double_urt Gaus(Double_urt x, Double_urt mean=0, Double_urt sigma=1, Bool_urt norm=kurFALSE)
static Double_urt Erf(Double_urt x)