gsl_specfunc__synchrotron.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* specfunc/synchrotron.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_exp.h"
  24. #include "gsl_sf_pow_int.h"
  25. #include "gsl_sf_synchrotron.h"
  26. #include "gsl_specfunc__error.h"
  27. #include "gsl_specfunc__chebyshev.h"
  28. #include "gsl_specfunc__cheb_eval.c"
  29. static double synchrotron1_data[13] = {
  30. 30.364682982501076273,
  31. 17.079395277408394574,
  32. 4.560132133545072889,
  33. 0.549281246730419979,
  34. 0.372976075069301172e-01,
  35. 0.161362430201041242e-02,
  36. 0.481916772120371e-04,
  37. 0.10512425288938e-05,
  38. 0.174638504670e-07,
  39. 0.22815486544e-09,
  40. 0.240443082e-11,
  41. 0.2086588e-13,
  42. 0.15167e-15
  43. };
  44. static cheb_series synchrotron1_cs = {
  45. synchrotron1_data,
  46. 12,
  47. -1.0, 1.0,
  48. 9
  49. };
  50. static double synchrotron2_data[12] = {
  51. 0.4490721623532660844,
  52. 0.898353677994187218e-01,
  53. 0.81044573772151290e-02,
  54. 0.4261716991089162e-03,
  55. 0.147609631270746e-04,
  56. 0.3628633615300e-06,
  57. 0.66634807498e-08,
  58. 0.949077166e-10,
  59. 0.1079125e-11,
  60. 0.10022e-13,
  61. 0.77e-16,
  62. 0.5e-18
  63. };
  64. static cheb_series synchrotron2_cs = {
  65. synchrotron2_data,
  66. 11,
  67. -1.0, 1.0,
  68. 7
  69. };
  70. static double synchrotron1a_data[23] = {
  71. 2.1329305161355000985,
  72. 0.741352864954200240e-01,
  73. 0.86968099909964198e-02,
  74. 0.11703826248775692e-02,
  75. 0.1645105798619192e-03,
  76. 0.240201021420640e-04,
  77. 0.35827756389389e-05,
  78. 0.5447747626984e-06,
  79. 0.838802856196e-07,
  80. 0.13069882684e-07,
  81. 0.2053099071e-08,
  82. 0.325187537e-09,
  83. 0.517914041e-10,
  84. 0.83002988e-11,
  85. 0.13352728e-11,
  86. 0.2159150e-12,
  87. 0.349967e-13,
  88. 0.56994e-14,
  89. 0.9291e-15,
  90. 0.152e-15,
  91. 0.249e-16,
  92. 0.41e-17,
  93. 0.7e-18
  94. };
  95. static cheb_series synchrotron1a_cs = {
  96. synchrotron1a_data,
  97. 22,
  98. -1.0, 1.0,
  99. 11
  100. };
  101. static double synchrotron21_data[13] = {
  102. 38.617839923843085480,
  103. 23.037715594963734597,
  104. 5.3802499868335705968,
  105. 0.6156793806995710776,
  106. 0.406688004668895584e-01,
  107. 0.17296274552648414e-02,
  108. 0.51061258836577e-04,
  109. 0.110459595022e-05,
  110. 0.18235530206e-07,
  111. 0.2370769803e-09,
  112. 0.24887296e-11,
  113. 0.21529e-13,
  114. 0.156e-15
  115. };
  116. static cheb_series synchrotron21_cs = {
  117. synchrotron21_data,
  118. 12,
  119. -1.0, 1.0,
  120. 9
  121. };
  122. static double synchrotron22_data[13] = {
  123. 7.9063148270660804288,
  124. 3.1353463612853425684,
  125. 0.4854879477453714538,
  126. 0.394816675827237234e-01,
  127. 0.19661622334808802e-02,
  128. 0.659078932293042e-04,
  129. 0.15857561349856e-05,
  130. 0.286865301123e-07,
  131. 0.4041202360e-09,
  132. 0.45568444e-11,
  133. 0.420459e-13,
  134. 0.3232e-15,
  135. 0.21e-17
  136. };
  137. static cheb_series synchrotron22_cs = {
  138. synchrotron22_data,
  139. 12,
  140. -1.0, 1.0,
  141. 8
  142. };
  143. static double synchrotron2a_data[17] = {
  144. 2.020337094170713600,
  145. 0.10956237121807404e-01,
  146. 0.8542384730114676e-03,
  147. 0.723430242132822e-04,
  148. 0.63124427962699e-05,
  149. 0.5648193141174e-06,
  150. 0.512832480138e-07,
  151. 0.47196532914e-08,
  152. 0.4380744214e-09,
  153. 0.410268149e-10,
  154. 0.38623072e-11,
  155. 0.3661323e-12,
  156. 0.348023e-13,
  157. 0.33301e-14,
  158. 0.319e-15,
  159. 0.307e-16,
  160. 0.3e-17
  161. };
  162. static cheb_series synchrotron2a_cs = {
  163. synchrotron2a_data,
  164. 16,
  165. -1.0, 1.0,
  166. 8
  167. };
  168. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  169. int gsl_sf_synchrotron_1_e(const double x, gsl_sf_result * result)
  170. {
  171. /* CHECK_POINTER(result) */
  172. if(x < 0.0) {
  173. DOMAIN_ERROR(result);
  174. }
  175. else if(x < 2.0*M_SQRT2 * GSL_SQRT_DBL_EPSILON) {
  176. /* BJG: added first order correction term. The taylor series
  177. is S1(x) = ((4pi)/(sqrt(3)gamma(1/3))) * (x/2)^(1/3)
  178. * (1 - (gamma(1/3)/2)*(x/2)^2/3 + (3/4) * (x/2)^2 ....) */
  179. double z = pow(x, 1.0/3.0);
  180. double cf = 1 - 8.43812762813205e-01 * z * z;
  181. result->val = 2.14952824153447863671 * z * cf;
  182. result->err = GSL_DBL_EPSILON * result->val;
  183. return GSL_SUCCESS;
  184. }
  185. else if(x <= 4.0) {
  186. const double c0 = M_PI/M_SQRT3;
  187. const double px = pow(x,1.0/3.0);
  188. const double px11 = gsl_sf_pow_int(px,11);
  189. const double t = x*x/8.0 - 1.0;
  190. gsl_sf_result result_c1;
  191. gsl_sf_result result_c2;
  192. cheb_eval_e(&synchrotron1_cs, t, &result_c1);
  193. cheb_eval_e(&synchrotron2_cs, t, &result_c2);
  194. result->val = px * result_c1.val - px11 * result_c2.val - c0 * x;
  195. result->err = px * result_c1.err + px11 * result_c2.err + c0 * x * GSL_DBL_EPSILON;
  196. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  197. return GSL_SUCCESS;
  198. }
  199. else if(x < -8.0*GSL_LOG_DBL_MIN/7.0) {
  200. const double c0 = 0.2257913526447274323630976; /* log(sqrt(pi/2)) */
  201. const double t = (12.0 - x) / (x + 4.0);
  202. gsl_sf_result result_c1;
  203. cheb_eval_e(&synchrotron1a_cs, t, &result_c1);
  204. result->val = sqrt(x) * result_c1.val * exp(c0 - x);
  205. result->err = 2.0 * GSL_DBL_EPSILON * result->val * (fabs(c0-x)+1.0);
  206. return GSL_SUCCESS;
  207. }
  208. else {
  209. UNDERFLOW_ERROR(result);
  210. }
  211. }
  212. int gsl_sf_synchrotron_2_e(const double x, gsl_sf_result * result)
  213. {
  214. /* CHECK_POINTER(result) */
  215. if(x < 0.0) {
  216. DOMAIN_ERROR(result);
  217. }
  218. else if(x < 2.0*M_SQRT2*GSL_SQRT_DBL_EPSILON) {
  219. /* BJG: added first order correction term. The taylor series
  220. is S2(x) = ((2pi)/(sqrt(3)*gamma(1/3))) * (x/2)^(1/3)
  221. * (1 - (gamma(1/3)/gamma(4/3))*(x/2)^(4/3) + (gamma(1/3)/gamma(4/3))*(x/2)^2...) */
  222. double z = pow(x, 1.0/3.0);
  223. double cf = 1 - 1.17767156510235e+00 * z * x;
  224. result->val = 1.07476412076723931836 * z * cf ;
  225. result->err = 2.0 * GSL_DBL_EPSILON * result->val;
  226. return GSL_SUCCESS;
  227. }
  228. else if(x <= 4.0) {
  229. const double px = pow(x, 1.0/3.0);
  230. const double px5 = gsl_sf_pow_int(px,5);
  231. const double t = x*x/8.0 - 1.0;
  232. gsl_sf_result cheb1;
  233. gsl_sf_result cheb2;
  234. cheb_eval_e(&synchrotron21_cs, t, &cheb1);
  235. cheb_eval_e(&synchrotron22_cs, t, &cheb2);
  236. result->val = px * cheb1.val - px5 * cheb2.val;
  237. result->err = px * cheb1.err + px5 * cheb2.err;
  238. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  239. return GSL_SUCCESS;
  240. }
  241. else if(x < -8.0*GSL_LOG_DBL_MIN/7.0) {
  242. const double c0 = 0.22579135264472743236; /* log(sqrt(pi/2)) */
  243. const double t = (10.0 - x) / (x + 2.0);
  244. gsl_sf_result cheb1;
  245. cheb_eval_e(&synchrotron2a_cs, t, &cheb1);
  246. result->val = sqrt(x) * exp(c0-x) * cheb1.val;
  247. result->err = GSL_DBL_EPSILON * result->val * (fabs(c0-x)+1.0);
  248. return GSL_SUCCESS;
  249. }
  250. else {
  251. UNDERFLOW_ERROR(result);
  252. }
  253. }
  254. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  255. #include "gsl_specfunc__eval.h"
  256. double gsl_sf_synchrotron_1(const double x)
  257. {
  258. EVAL_RESULT(gsl_sf_synchrotron_1_e(x, &result));
  259. }
  260. double gsl_sf_synchrotron_2(const double x)
  261. {
  262. EVAL_RESULT(gsl_sf_synchrotron_2_e(x, &result));
  263. }