gsl_specfunc__sinint.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /* specfunc/sinint.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. /* Author: G. Jungman */
  20. #include "gsl__config.h"
  21. #include "gsl_math.h"
  22. #include "gsl_errno.h"
  23. #include "gsl_sf_trig.h"
  24. #include "gsl_sf_expint.h"
  25. #include "gsl_specfunc__error.h"
  26. #include "gsl_specfunc__chebyshev.h"
  27. #include "gsl_specfunc__cheb_eval.c"
  28. /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/
  29. /* based on SLATEC r9sifg.f, W. Fullerton */
  30. /*
  31. series for f1 on the interval 2.00000e-02 to 6.25000e-02
  32. with weighted error 2.82e-17
  33. log weighted error 16.55
  34. significant figures required 15.36
  35. decimal places required 17.20
  36. */
  37. static double f1_data[20] = {
  38. -0.1191081969051363610,
  39. -0.0247823144996236248,
  40. 0.0011910281453357821,
  41. -0.0000927027714388562,
  42. 0.0000093373141568271,
  43. -0.0000011058287820557,
  44. 0.0000001464772071460,
  45. -0.0000000210694496288,
  46. 0.0000000032293492367,
  47. -0.0000000005206529618,
  48. 0.0000000000874878885,
  49. -0.0000000000152176187,
  50. 0.0000000000027257192,
  51. -0.0000000000005007053,
  52. 0.0000000000000940241,
  53. -0.0000000000000180014,
  54. 0.0000000000000035063,
  55. -0.0000000000000006935,
  56. 0.0000000000000001391,
  57. -0.0000000000000000282
  58. };
  59. static cheb_series f1_cs = {
  60. f1_data,
  61. 19,
  62. -1, 1,
  63. 10
  64. };
  65. /*
  66. series for f2 on the interval 0.00000e+00 to 2.00000e-02
  67. with weighted error 4.32e-17
  68. log weighted error 16.36
  69. significant figures required 14.75
  70. decimal places required 17.10
  71. */
  72. static double f2_data[29] = {
  73. -0.0348409253897013234,
  74. -0.0166842205677959686,
  75. 0.0006752901241237738,
  76. -0.0000535066622544701,
  77. 0.0000062693421779007,
  78. -0.0000009526638801991,
  79. 0.0000001745629224251,
  80. -0.0000000368795403065,
  81. 0.0000000087202677705,
  82. -0.0000000022601970392,
  83. 0.0000000006324624977,
  84. -0.0000000001888911889,
  85. 0.0000000000596774674,
  86. -0.0000000000198044313,
  87. 0.0000000000068641396,
  88. -0.0000000000024731020,
  89. 0.0000000000009226360,
  90. -0.0000000000003552364,
  91. 0.0000000000001407606,
  92. -0.0000000000000572623,
  93. 0.0000000000000238654,
  94. -0.0000000000000101714,
  95. 0.0000000000000044259,
  96. -0.0000000000000019634,
  97. 0.0000000000000008868,
  98. -0.0000000000000004074,
  99. 0.0000000000000001901,
  100. -0.0000000000000000900,
  101. 0.0000000000000000432
  102. };
  103. static cheb_series f2_cs = {
  104. f2_data,
  105. 28,
  106. -1, 1,
  107. 14
  108. };
  109. /*
  110. series for g1 on the interval 2.00000e-02 to 6.25000e-02
  111. with weighted error 5.48e-17
  112. log weighted error 16.26
  113. significant figures required 15.47
  114. decimal places required 16.92
  115. */
  116. static double g1_data[21] = {
  117. -0.3040578798253495954,
  118. -0.0566890984597120588,
  119. 0.0039046158173275644,
  120. -0.0003746075959202261,
  121. 0.0000435431556559844,
  122. -0.0000057417294453025,
  123. 0.0000008282552104503,
  124. -0.0000001278245892595,
  125. 0.0000000207978352949,
  126. -0.0000000035313205922,
  127. 0.0000000006210824236,
  128. -0.0000000001125215474,
  129. 0.0000000000209088918,
  130. -0.0000000000039715832,
  131. 0.0000000000007690431,
  132. -0.0000000000001514697,
  133. 0.0000000000000302892,
  134. -0.0000000000000061400,
  135. 0.0000000000000012601,
  136. -0.0000000000000002615,
  137. 0.0000000000000000548
  138. };
  139. static cheb_series g1_cs = {
  140. g1_data,
  141. 20,
  142. -1, 1,
  143. 13
  144. };
  145. /*
  146. series for g2 on the interval 0.00000e+00 to 2.00000e-02
  147. with weighted error 5.01e-17
  148. log weighted error 16.30
  149. significant figures required 15.12
  150. decimal places required 17.07
  151. */
  152. static double g2_data[34] = {
  153. -0.0967329367532432218,
  154. -0.0452077907957459871,
  155. 0.0028190005352706523,
  156. -0.0002899167740759160,
  157. 0.0000407444664601121,
  158. -0.0000071056382192354,
  159. 0.0000014534723163019,
  160. -0.0000003364116512503,
  161. 0.0000000859774367886,
  162. -0.0000000238437656302,
  163. 0.0000000070831906340,
  164. -0.0000000022318068154,
  165. 0.0000000007401087359,
  166. -0.0000000002567171162,
  167. 0.0000000000926707021,
  168. -0.0000000000346693311,
  169. 0.0000000000133950573,
  170. -0.0000000000053290754,
  171. 0.0000000000021775312,
  172. -0.0000000000009118621,
  173. 0.0000000000003905864,
  174. -0.0000000000001708459,
  175. 0.0000000000000762015,
  176. -0.0000000000000346151,
  177. 0.0000000000000159996,
  178. -0.0000000000000075213,
  179. 0.0000000000000035970,
  180. -0.0000000000000017530,
  181. 0.0000000000000008738,
  182. -0.0000000000000004487,
  183. 0.0000000000000002397,
  184. -0.0000000000000001347,
  185. 0.0000000000000000801,
  186. -0.0000000000000000501
  187. };
  188. static cheb_series g2_cs = {
  189. g2_data,
  190. 33,
  191. -1, 1,
  192. 20
  193. };
  194. /* x >= 4.0 */
  195. static void fg_asymp(const double x, gsl_sf_result * f, gsl_sf_result * g)
  196. {
  197. /*
  198. xbig = sqrt (1.0/r1mach(3))
  199. xmaxf = exp (amin1(-alog(r1mach(1)), alog(r1mach(2))) - 0.01)
  200. xmaxg = 1.0/sqrt(r1mach(1))
  201. xbnd = sqrt(50.0)
  202. */
  203. const double xbig = 1.0/GSL_SQRT_DBL_EPSILON;
  204. const double xmaxf = 1.0/GSL_DBL_MIN;
  205. const double xmaxg = 1.0/GSL_SQRT_DBL_MIN;
  206. const double xbnd = 7.07106781187;
  207. const double x2 = x*x;
  208. if(x <= xbnd) {
  209. gsl_sf_result result_c1;
  210. gsl_sf_result result_c2;
  211. cheb_eval_e(&f1_cs, (1.0/x2-0.04125)/0.02125, &result_c1);
  212. cheb_eval_e(&g1_cs, (1.0/x2-0.04125)/0.02125, &result_c2);
  213. f->val = (1.0 + result_c1.val)/x;
  214. g->val = (1.0 + result_c2.val)/x2;
  215. f->err = result_c1.err/x + 2.0 * GSL_DBL_EPSILON * fabs(f->val);
  216. g->err = result_c2.err/x2 + 2.0 * GSL_DBL_EPSILON * fabs(g->val);
  217. }
  218. else if(x <= xbig) {
  219. gsl_sf_result result_c1;
  220. gsl_sf_result result_c2;
  221. cheb_eval_e(&f2_cs, 100.0/x2-1.0, &result_c1);
  222. cheb_eval_e(&g2_cs, 100.0/x2-1.0, &result_c2);
  223. f->val = (1.0 + result_c1.val)/x;
  224. g->val = (1.0 + result_c2.val)/x2;
  225. f->err = result_c1.err/x + 2.0 * GSL_DBL_EPSILON * fabs(f->val);
  226. g->err = result_c2.err/x2 + 2.0 * GSL_DBL_EPSILON * fabs(g->val);
  227. }
  228. else {
  229. f->val = (x < xmaxf ? 1.0/x : 0.0);
  230. g->val = (x < xmaxg ? 1.0/x2 : 0.0);
  231. f->err = 2.0 * GSL_DBL_EPSILON * fabs(f->val);
  232. g->err = 2.0 * GSL_DBL_EPSILON * fabs(g->val);
  233. }
  234. return;
  235. }
  236. /* based on SLATEC si.f, W. Fullerton
  237. series for si on the interval 0.00000e+00 to 1.60000e+01
  238. with weighted error 1.22e-17
  239. log weighted error 16.91
  240. significant figures required 16.37
  241. decimal places required 17.45
  242. */
  243. static double si_data[12] = {
  244. -0.1315646598184841929,
  245. -0.2776578526973601892,
  246. 0.0354414054866659180,
  247. -0.0025631631447933978,
  248. 0.0001162365390497009,
  249. -0.0000035904327241606,
  250. 0.0000000802342123706,
  251. -0.0000000013562997693,
  252. 0.0000000000179440722,
  253. -0.0000000000001908387,
  254. 0.0000000000000016670,
  255. -0.0000000000000000122
  256. };
  257. static cheb_series si_cs = {
  258. si_data,
  259. 11,
  260. -1, 1,
  261. 9
  262. };
  263. /*
  264. series for ci on the interval 0.00000e+00 to 1.60000e+01
  265. with weighted error 1.94e-18
  266. log weighted error 17.71
  267. significant figures required 17.74
  268. decimal places required 18.27
  269. */
  270. static double ci_data[13] = {
  271. -0.34004281856055363156,
  272. -1.03302166401177456807,
  273. 0.19388222659917082877,
  274. -0.01918260436019865894,
  275. 0.00110789252584784967,
  276. -0.00004157234558247209,
  277. 0.00000109278524300229,
  278. -0.00000002123285954183,
  279. 0.00000000031733482164,
  280. -0.00000000000376141548,
  281. 0.00000000000003622653,
  282. -0.00000000000000028912,
  283. 0.00000000000000000194
  284. };
  285. static cheb_series ci_cs = {
  286. ci_data,
  287. 12,
  288. -1, 1,
  289. 9
  290. };
  291. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  292. int gsl_sf_Si_e(const double x, gsl_sf_result * result)
  293. {
  294. double ax = fabs(x);
  295. /* CHECK_POINTER(result) */
  296. if(ax < GSL_SQRT_DBL_EPSILON) {
  297. result->val = x;
  298. result->err = 0.0;
  299. return GSL_SUCCESS;
  300. }
  301. else if(ax <= 4.0) {
  302. gsl_sf_result result_c;
  303. cheb_eval_e(&si_cs, (x*x-8.0)*0.125, &result_c);
  304. result->val = x * (0.75 + result_c.val);
  305. result->err = ax * result_c.err;
  306. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  307. return GSL_SUCCESS;
  308. }
  309. else {
  310. /* Note there is no loss of precision
  311. * here bcause of the leading constant.
  312. */
  313. gsl_sf_result f;
  314. gsl_sf_result g;
  315. fg_asymp(ax, &f, &g);
  316. result->val = 0.5 * M_PI - f.val*cos(ax) - g.val*sin(ax);
  317. result->err = f.err + g.err;
  318. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  319. if(x < 0.0) result->val = -result->val;
  320. return GSL_SUCCESS;
  321. }
  322. }
  323. int gsl_sf_Ci_e(const double x, gsl_sf_result * result)
  324. {
  325. /* CHECK_POINTER(result) */
  326. if(x <= 0.0) {
  327. DOMAIN_ERROR(result);
  328. }
  329. else if(x <= 4.0) {
  330. const double lx = log(x);
  331. const double y = (x*x-8.0)*0.125;
  332. gsl_sf_result result_c;
  333. cheb_eval_e(&ci_cs, y, &result_c);
  334. result->val = lx - 0.5 + result_c.val;
  335. result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lx) + 0.5) + result_c.err;
  336. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  337. return GSL_SUCCESS;
  338. }
  339. else {
  340. gsl_sf_result sin_result;
  341. gsl_sf_result cos_result;
  342. int stat_sin = gsl_sf_sin_e(x, &sin_result);
  343. int stat_cos = gsl_sf_cos_e(x, &cos_result);
  344. gsl_sf_result f;
  345. gsl_sf_result g;
  346. fg_asymp(x, &f, &g);
  347. result->val = f.val*sin_result.val - g.val*cos_result.val;
  348. result->err = fabs(f.err*sin_result.val);
  349. result->err += fabs(g.err*cos_result.val);
  350. result->err += fabs(f.val*sin_result.err);
  351. result->err += fabs(g.val*cos_result.err);
  352. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  353. return GSL_ERROR_SELECT_2(stat_sin, stat_cos);
  354. }
  355. }
  356. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  357. #include "gsl_specfunc__eval.h"
  358. double gsl_sf_Si(const double x)
  359. {
  360. EVAL_RESULT(gsl_sf_Si_e(x, &result));
  361. }
  362. double gsl_sf_Ci(const double x)
  363. {
  364. EVAL_RESULT(gsl_sf_Ci_e(x, &result));
  365. }