sicif.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /* sicif.c
  2. *
  3. * Sine and cosine integrals
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float x, Ci, Si;
  10. *
  11. * sicif( x, &Si, &Ci );
  12. *
  13. *
  14. * DESCRIPTION:
  15. *
  16. * Evaluates the integrals
  17. *
  18. * x
  19. * -
  20. * | cos t - 1
  21. * Ci(x) = eul + ln x + | --------- dt,
  22. * | t
  23. * -
  24. * 0
  25. * x
  26. * -
  27. * | sin t
  28. * Si(x) = | ----- dt
  29. * | t
  30. * -
  31. * 0
  32. *
  33. * where eul = 0.57721566490153286061 is Euler's constant.
  34. * The integrals are approximated by rational functions.
  35. * For x > 8 auxiliary functions f(x) and g(x) are employed
  36. * such that
  37. *
  38. * Ci(x) = f(x) sin(x) - g(x) cos(x)
  39. * Si(x) = pi/2 - f(x) cos(x) - g(x) sin(x)
  40. *
  41. *
  42. * ACCURACY:
  43. * Test interval = [0,50].
  44. * Absolute error, except relative when > 1:
  45. * arithmetic function # trials peak rms
  46. * IEEE Si 30000 2.1e-7 4.3e-8
  47. * IEEE Ci 30000 3.9e-7 2.2e-8
  48. */
  49. /*
  50. Cephes Math Library Release 2.1: January, 1989
  51. Copyright 1984, 1987, 1989 by Stephen L. Moshier
  52. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  53. */
  54. #include <math.h>
  55. static float SN[] = {
  56. -8.39167827910303881427E-11,
  57. 4.62591714427012837309E-8,
  58. -9.75759303843632795789E-6,
  59. 9.76945438170435310816E-4,
  60. -4.13470316229406538752E-2,
  61. 1.00000000000000000302E0,
  62. };
  63. static float SD[] = {
  64. 2.03269266195951942049E-12,
  65. 1.27997891179943299903E-9,
  66. 4.41827842801218905784E-7,
  67. 9.96412122043875552487E-5,
  68. 1.42085239326149893930E-2,
  69. 9.99999999999999996984E-1,
  70. };
  71. static float CN[] = {
  72. 2.02524002389102268789E-11,
  73. -1.35249504915790756375E-8,
  74. 3.59325051419993077021E-6,
  75. -4.74007206873407909465E-4,
  76. 2.89159652607555242092E-2,
  77. -1.00000000000000000080E0,
  78. };
  79. static float CD[] = {
  80. 4.07746040061880559506E-12,
  81. 3.06780997581887812692E-9,
  82. 1.23210355685883423679E-6,
  83. 3.17442024775032769882E-4,
  84. 5.10028056236446052392E-2,
  85. 4.00000000000000000080E0,
  86. };
  87. static float FN4[] = {
  88. 4.23612862892216586994E0,
  89. 5.45937717161812843388E0,
  90. 1.62083287701538329132E0,
  91. 1.67006611831323023771E-1,
  92. 6.81020132472518137426E-3,
  93. 1.08936580650328664411E-4,
  94. 5.48900223421373614008E-7,
  95. };
  96. static float FD4[] = {
  97. /* 1.00000000000000000000E0,*/
  98. 8.16496634205391016773E0,
  99. 7.30828822505564552187E0,
  100. 1.86792257950184183883E0,
  101. 1.78792052963149907262E-1,
  102. 7.01710668322789753610E-3,
  103. 1.10034357153915731354E-4,
  104. 5.48900252756255700982E-7,
  105. };
  106. static float FN8[] = {
  107. 4.55880873470465315206E-1,
  108. 7.13715274100146711374E-1,
  109. 1.60300158222319456320E-1,
  110. 1.16064229408124407915E-2,
  111. 3.49556442447859055605E-4,
  112. 4.86215430826454749482E-6,
  113. 3.20092790091004902806E-8,
  114. 9.41779576128512936592E-11,
  115. 9.70507110881952024631E-14,
  116. };
  117. static float FD8[] = {
  118. /* 1.00000000000000000000E0,*/
  119. 9.17463611873684053703E-1,
  120. 1.78685545332074536321E-1,
  121. 1.22253594771971293032E-2,
  122. 3.58696481881851580297E-4,
  123. 4.92435064317881464393E-6,
  124. 3.21956939101046018377E-8,
  125. 9.43720590350276732376E-11,
  126. 9.70507110881952025725E-14,
  127. };
  128. static float GN4[] = {
  129. 8.71001698973114191777E-2,
  130. 6.11379109952219284151E-1,
  131. 3.97180296392337498885E-1,
  132. 7.48527737628469092119E-2,
  133. 5.38868681462177273157E-3,
  134. 1.61999794598934024525E-4,
  135. 1.97963874140963632189E-6,
  136. 7.82579040744090311069E-9,
  137. };
  138. static float GD4[] = {
  139. /* 1.00000000000000000000E0,*/
  140. 1.64402202413355338886E0,
  141. 6.66296701268987968381E-1,
  142. 9.88771761277688796203E-2,
  143. 6.22396345441768420760E-3,
  144. 1.73221081474177119497E-4,
  145. 2.02659182086343991969E-6,
  146. 7.82579218933534490868E-9,
  147. };
  148. static float GN8[] = {
  149. 6.97359953443276214934E-1,
  150. 3.30410979305632063225E-1,
  151. 3.84878767649974295920E-2,
  152. 1.71718239052347903558E-3,
  153. 3.48941165502279436777E-5,
  154. 3.47131167084116673800E-7,
  155. 1.70404452782044526189E-9,
  156. 3.85945925430276600453E-12,
  157. 3.14040098946363334640E-15,
  158. };
  159. static float GD8[] = {
  160. /* 1.00000000000000000000E0,*/
  161. 1.68548898811011640017E0,
  162. 4.87852258695304967486E-1,
  163. 4.67913194259625806320E-2,
  164. 1.90284426674399523638E-3,
  165. 3.68475504442561108162E-5,
  166. 3.57043223443740838771E-7,
  167. 1.72693748966316146736E-9,
  168. 3.87830166023954706752E-12,
  169. 3.14040098946363335242E-15,
  170. };
  171. #define EUL 0.57721566490153286061
  172. extern float MAXNUMF, PIO2F, MACHEPF;
  173. #ifdef ANSIC
  174. float logf(float), sinf(float), cosf(float);
  175. float polevlf(float, float *, int);
  176. float p1evlf(float, float *, int);
  177. #else
  178. float logf(), sinf(), cosf(), polevlf(), p1evlf();
  179. #endif
  180. int sicif( float xx, float *si, float *ci )
  181. {
  182. float x, z, c, s, f, g;
  183. int sign;
  184. x = xx;
  185. if( x < 0.0 )
  186. {
  187. sign = -1;
  188. x = -x;
  189. }
  190. else
  191. sign = 0;
  192. if( x == 0.0 )
  193. {
  194. *si = 0.0;
  195. *ci = -MAXNUMF;
  196. return( 0 );
  197. }
  198. if( x > 1.0e9 )
  199. {
  200. *si = PIO2F - cosf(x)/x;
  201. *ci = sinf(x)/x;
  202. return( 0 );
  203. }
  204. if( x > 4.0 )
  205. goto asympt;
  206. z = x * x;
  207. s = x * polevlf( z, SN, 5 ) / polevlf( z, SD, 5 );
  208. c = z * polevlf( z, CN, 5 ) / polevlf( z, CD, 5 );
  209. if( sign )
  210. s = -s;
  211. *si = s;
  212. *ci = EUL + logf(x) + c; /* real part if x < 0 */
  213. return(0);
  214. /* The auxiliary functions are:
  215. *
  216. *
  217. * *si = *si - PIO2;
  218. * c = cos(x);
  219. * s = sin(x);
  220. *
  221. * t = *ci * s - *si * c;
  222. * a = *ci * c + *si * s;
  223. *
  224. * *si = t;
  225. * *ci = -a;
  226. */
  227. asympt:
  228. s = sinf(x);
  229. c = cosf(x);
  230. z = 1.0/(x*x);
  231. if( x < 8.0 )
  232. {
  233. f = polevlf( z, FN4, 6 ) / (x * p1evlf( z, FD4, 7 ));
  234. g = z * polevlf( z, GN4, 7 ) / p1evlf( z, GD4, 7 );
  235. }
  236. else
  237. {
  238. f = polevlf( z, FN8, 8 ) / (x * p1evlf( z, FD8, 8 ));
  239. g = z * polevlf( z, GN8, 8 ) / p1evlf( z, GD8, 9 );
  240. }
  241. *si = PIO2F - f * c - g * s;
  242. if( sign )
  243. *si = -( *si );
  244. *ci = f * s - g * c;
  245. return(0);
  246. }