CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoLocalTracker/SiPixelRecHits/src/sicif.h

Go to the documentation of this file.
00001 /*                                                      sicif.c
00002  *
00003  *      Sine and cosine integrals
00004  *
00005  *
00006  *
00007  * SYNOPSIS:
00008  *
00009  * float x, Ci, Si;
00010  *
00011  * sicif( x, &Si, &Ci );
00012  *
00013  *
00014  * DESCRIPTION:
00015  *
00016  * Evaluates the integrals
00017  *
00018  *                          x
00019  *                          -
00020  *                         |  cos t - 1
00021  *   Ci(x) = eul + ln x +  |  --------- dt,
00022  *                         |      t
00023  *                        -
00024  *                         0
00025  *             x
00026  *             -
00027  *            |  sin t
00028  *   Si(x) =  |  ----- dt
00029  *            |    t
00030  *           -
00031  *            0
00032  *
00033  * where eul = 0.57721566490153286061 is Euler's constant.
00034  * The integrals are approximated by rational functions.
00035  * For x > 8 auxiliary functions f(x) and g(x) are employed
00036  * such that
00037  *
00038  * Ci(x) = f(x) sin(x) - g(x) cos(x)
00039  * Si(x) = pi/2 - f(x) cos(x) - g(x) sin(x)
00040  *
00041  *
00042  * ACCURACY:
00043  *    Test interval = [0,50].
00044  * Absolute error, except relative when > 1:
00045  * arithmetic   function   # trials      peak         rms
00046  *    IEEE        Si        30000       2.1e-7      4.3e-8
00047  *    IEEE        Ci        30000       3.9e-7      2.2e-8
00048  */
00049 
00050 /*
00051 Cephes Math Library Release 2.1:  January, 1989
00052 Copyright 1984, 1987, 1989 by Stephen L. Moshier
00053 Direct inquiries to 30 Frost Street, Cambridge, MA 02140
00054 */
00055 
00056 #include "vdt/vdtMath.h"
00057 
00058 
00059 static float SN[] = {
00060 -8.39167827910303881427E-11,
00061  4.62591714427012837309E-8,
00062 -9.75759303843632795789E-6,
00063  9.76945438170435310816E-4,
00064 -4.13470316229406538752E-2,
00065  1.00000000000000000302E0,
00066 };
00067 static float SD[] = {
00068   2.03269266195951942049E-12,
00069   1.27997891179943299903E-9,
00070   4.41827842801218905784E-7,
00071   9.96412122043875552487E-5,
00072   1.42085239326149893930E-2,
00073   9.99999999999999996984E-1,
00074 };
00075 
00076 static float CN[] = {
00077  2.02524002389102268789E-11,
00078 -1.35249504915790756375E-8,
00079  3.59325051419993077021E-6,
00080 -4.74007206873407909465E-4,
00081  2.89159652607555242092E-2,
00082 -1.00000000000000000080E0,
00083 };
00084 static float CD[] = {
00085   4.07746040061880559506E-12,
00086   3.06780997581887812692E-9,
00087   1.23210355685883423679E-6,
00088   3.17442024775032769882E-4,
00089   5.10028056236446052392E-2,
00090   4.00000000000000000080E0,
00091 };
00092 
00093 
00094 static float FN4[] = {
00095   4.23612862892216586994E0,
00096   5.45937717161812843388E0,
00097   1.62083287701538329132E0,
00098   1.67006611831323023771E-1,
00099   6.81020132472518137426E-3,
00100   1.08936580650328664411E-4,
00101   5.48900223421373614008E-7,
00102 };
00103 static float FD4[] = {
00104 /*  1.00000000000000000000E0,*/
00105   8.16496634205391016773E0,
00106   7.30828822505564552187E0,
00107   1.86792257950184183883E0,
00108   1.78792052963149907262E-1,
00109   7.01710668322789753610E-3,
00110   1.10034357153915731354E-4,
00111   5.48900252756255700982E-7,
00112 };
00113 
00114 
00115 static float FN8[] = {
00116   4.55880873470465315206E-1,
00117   7.13715274100146711374E-1,
00118   1.60300158222319456320E-1,
00119   1.16064229408124407915E-2,
00120   3.49556442447859055605E-4,
00121   4.86215430826454749482E-6,
00122   3.20092790091004902806E-8,
00123   9.41779576128512936592E-11,
00124   9.70507110881952024631E-14,
00125 };
00126 static float FD8[] = {
00127 /*  1.00000000000000000000E0,*/
00128   9.17463611873684053703E-1,
00129   1.78685545332074536321E-1,
00130   1.22253594771971293032E-2,
00131   3.58696481881851580297E-4,
00132   4.92435064317881464393E-6,
00133   3.21956939101046018377E-8,
00134   9.43720590350276732376E-11,
00135   9.70507110881952025725E-14,
00136 };
00137 
00138 static float GN4[] = {
00139   8.71001698973114191777E-2,
00140   6.11379109952219284151E-1,
00141   3.97180296392337498885E-1,
00142   7.48527737628469092119E-2,
00143   5.38868681462177273157E-3,
00144   1.61999794598934024525E-4,
00145   1.97963874140963632189E-6,
00146   7.82579040744090311069E-9,
00147 };
00148 static float GD4[] = {
00149 /*  1.00000000000000000000E0,*/
00150   1.64402202413355338886E0,
00151   6.66296701268987968381E-1,
00152   9.88771761277688796203E-2,
00153   6.22396345441768420760E-3,
00154   1.73221081474177119497E-4,
00155   2.02659182086343991969E-6,
00156   7.82579218933534490868E-9,
00157 };
00158 
00159 static float GN8[] = {
00160   6.97359953443276214934E-1,
00161   3.30410979305632063225E-1,
00162   3.84878767649974295920E-2,
00163   1.71718239052347903558E-3,
00164   3.48941165502279436777E-5,
00165   3.47131167084116673800E-7,
00166   1.70404452782044526189E-9,
00167   3.85945925430276600453E-12,
00168   3.14040098946363334640E-15,
00169 };
00170 static float GD8[] = {
00171 /*  1.00000000000000000000E0,*/
00172   1.68548898811011640017E0,
00173   4.87852258695304967486E-1,
00174   4.67913194259625806320E-2,
00175   1.90284426674399523638E-3,
00176   3.68475504442561108162E-5,
00177   3.57043223443740838771E-7,
00178   1.72693748966316146736E-9,
00179   3.87830166023954706752E-12,
00180   3.14040098946363335242E-15,
00181 };
00182 
00183 inline
00184 float polevlf( float xx, float *coef, int N ) {
00185 float ans, x;
00186 float *p;
00187 int i;
00188 
00189 x = xx;
00190 p = coef;
00191 ans = *p++;
00192 
00193 i = N;
00194 do
00195         ans = ans * x  +  *p++;
00196 while( --i );
00197 
00198 return( ans );
00199 }
00200 
00201 /*                                                      p1evl() */
00202 /*                                          N
00203  * Evaluate polynomial when coefficient of x  is 1.0.
00204  * Otherwise same as polevl.
00205  */
00206 inline
00207 float p1evlf( float xx, float *coef, int N ){
00208 float ans, x;
00209 float *p;
00210 int i;
00211 
00212 x = xx;
00213 p = coef;
00214 ans = x + *p++;
00215 i = N-1;
00216 
00217 do
00218         ans = ans * x  + *p++;
00219 while( --i );
00220 
00221 return( ans );
00222 }
00223 
00224 
00225 
00226 inline
00227 int sicif( float xx, float & si, float & ci ){
00228   const float MAXNUMF = 1.7014117331926442990585209174225846272e38;
00229   const float PIO2F = 1.5707963267948966192;
00230   // const float MACHEPF = 5.9604644775390625E-8;
00231   const float EUL = 0.57721566490153286061;
00232 
00233   float x, z, c, s, f, g;
00234   int sign;
00235   
00236   x = xx;
00237   if( x < 0.0f )
00238     {
00239       sign = -1;
00240       x = -x;
00241     }
00242   else
00243     sign = 0;
00244   
00245   
00246   if( x == 0.0f )
00247     {
00248       si = 0.0;
00249       ci = -MAXNUMF;
00250       return( 0 );
00251     }
00252   
00253   
00254   if( x > 1.0e9f )
00255     {
00256       float su,cu; vdt::fast_sincosf(x,su,cu);
00257       si = PIO2F - cu/x;
00258       ci = su/x;
00259       return( 0 );
00260     }
00261   
00262   
00263 
00264   if( x > 4.0f )
00265     goto asympt;
00266   
00267   z = x * x;
00268   s = x * polevlf( z, SN, 5 ) / polevlf( z, SD, 5 );
00269   c = z * polevlf( z, CN, 5 ) / polevlf( z, CD, 5 );
00270 
00271   if( sign )
00272         s = -s;
00273   si = s;
00274   ci = EUL + vdt::fast_logf(x) + c;     /* real part if x < 0 */
00275   return(0);
00276 
00277 
00278 
00279   /* The auxiliary functions are:
00280    *
00281    *
00282    * *si = *si - PIO2;
00283    * c = cos(x);
00284    * s = sin(x);
00285    *
00286    * t = *ci * s - *si * c;
00287    * a = *ci * c + *si * s;
00288    *
00289    * *si = t;
00290    * *ci = -a;
00291    */
00292   
00293   
00294  asympt:
00295   vdt::fast_sincosf(x,s,c);
00296   z = 1.0f/(x*x);
00297   if( x < 8.0f )
00298     {
00299       f = polevlf( z, FN4, 6 ) / (x * p1evlf( z, FD4, 7 ));
00300       g = z * polevlf( z, GN4, 7 ) / p1evlf( z, GD4, 7 );
00301     }
00302   else
00303     {
00304       f = polevlf( z, FN8, 8 ) / (x * p1evlf( z, FD8, 8 ));
00305       g = z * polevlf( z, GN8, 8 ) / p1evlf( z, GD8, 9 );
00306     }
00307   si = PIO2F - f * c - g * s;
00308   if( sign )
00309     si = -( si );
00310   ci = f * s - g * c;
00311 
00312   return(0);
00313 }