gsl_specfunc__log.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /* specfunc/log.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_log.h"
  24. #include "gsl_specfunc__error.h"
  25. #include "gsl_specfunc__chebyshev.h"
  26. #include "gsl_specfunc__cheb_eval.c"
  27. /*-*-*-*-*-*-*-*-*-*-*-* Private Section *-*-*-*-*-*-*-*-*-*-*-*/
  28. /* Chebyshev expansion for log(1 + x(t))/x(t)
  29. *
  30. * x(t) = (4t-1)/(2(4-t))
  31. * t(x) = (8x+1)/(2(x+2))
  32. * -1/2 < x < 1/2
  33. * -1 < t < 1
  34. */
  35. static double lopx_data[21] = {
  36. 2.16647910664395270521272590407,
  37. -0.28565398551049742084877469679,
  38. 0.01517767255690553732382488171,
  39. -0.00200215904941415466274422081,
  40. 0.00019211375164056698287947962,
  41. -0.00002553258886105542567601400,
  42. 2.9004512660400621301999384544e-06,
  43. -3.8873813517057343800270917900e-07,
  44. 4.7743678729400456026672697926e-08,
  45. -6.4501969776090319441714445454e-09,
  46. 8.2751976628812389601561347296e-10,
  47. -1.1260499376492049411710290413e-10,
  48. 1.4844576692270934446023686322e-11,
  49. -2.0328515972462118942821556033e-12,
  50. 2.7291231220549214896095654769e-13,
  51. -3.7581977830387938294437434651e-14,
  52. 5.1107345870861673561462339876e-15,
  53. -7.0722150011433276578323272272e-16,
  54. 9.7089758328248469219003866867e-17,
  55. -1.3492637457521938883731579510e-17,
  56. 1.8657327910677296608121390705e-18
  57. };
  58. static cheb_series lopx_cs = {
  59. lopx_data,
  60. 20,
  61. -1, 1,
  62. 10
  63. };
  64. /* Chebyshev expansion for (log(1 + x(t)) - x(t))/x(t)^2
  65. *
  66. * x(t) = (4t-1)/(2(4-t))
  67. * t(x) = (8x+1)/(2(x+2))
  68. * -1/2 < x < 1/2
  69. * -1 < t < 1
  70. */
  71. static double lopxmx_data[20] = {
  72. -1.12100231323744103373737274541,
  73. 0.19553462773379386241549597019,
  74. -0.01467470453808083971825344956,
  75. 0.00166678250474365477643629067,
  76. -0.00018543356147700369785746902,
  77. 0.00002280154021771635036301071,
  78. -2.8031253116633521699214134172e-06,
  79. 3.5936568872522162983669541401e-07,
  80. -4.6241857041062060284381167925e-08,
  81. 6.0822637459403991012451054971e-09,
  82. -8.0339824424815790302621320732e-10,
  83. 1.0751718277499375044851551587e-10,
  84. -1.4445310914224613448759230882e-11,
  85. 1.9573912180610336168921438426e-12,
  86. -2.6614436796793061741564104510e-13,
  87. 3.6402634315269586532158344584e-14,
  88. -4.9937495922755006545809120531e-15,
  89. 6.8802890218846809524646902703e-16,
  90. -9.5034129794804273611403251480e-17,
  91. 1.3170135013050997157326965813e-17
  92. };
  93. static cheb_series lopxmx_cs = {
  94. lopxmx_data,
  95. 19,
  96. -1, 1,
  97. 9
  98. };
  99. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  100. int
  101. gsl_sf_log_e(const double x, gsl_sf_result * result)
  102. {
  103. /* CHECK_POINTER(result) */
  104. if(x <= 0.0) {
  105. DOMAIN_ERROR(result);
  106. }
  107. else {
  108. result->val = log(x);
  109. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  110. return GSL_SUCCESS;
  111. }
  112. }
  113. int
  114. gsl_sf_log_abs_e(const double x, gsl_sf_result * result)
  115. {
  116. /* CHECK_POINTER(result) */
  117. if(x == 0.0) {
  118. DOMAIN_ERROR(result);
  119. }
  120. else {
  121. result->val = log(fabs(x));
  122. result->err = 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  123. return GSL_SUCCESS;
  124. }
  125. }
  126. int
  127. gsl_sf_complex_log_e(const double zr, const double zi, gsl_sf_result * lnr, gsl_sf_result * theta)
  128. {
  129. /* CHECK_POINTER(lnr) */
  130. /* CHECK_POINTER(theta) */
  131. if(zr != 0.0 || zi != 0.0) {
  132. const double ax = fabs(zr);
  133. const double ay = fabs(zi);
  134. const double min = GSL_MIN(ax, ay);
  135. const double max = GSL_MAX(ax, ay);
  136. lnr->val = log(max) + 0.5 * log(1.0 + (min/max)*(min/max));
  137. lnr->err = 2.0 * GSL_DBL_EPSILON * fabs(lnr->val);
  138. theta->val = atan2(zi, zr);
  139. theta->err = GSL_DBL_EPSILON * fabs(lnr->val);
  140. return GSL_SUCCESS;
  141. }
  142. else {
  143. DOMAIN_ERROR_2(lnr, theta);
  144. }
  145. }
  146. int
  147. gsl_sf_log_1plusx_e(const double x, gsl_sf_result * result)
  148. {
  149. /* CHECK_POINTER(result) */
  150. if(x <= -1.0) {
  151. DOMAIN_ERROR(result);
  152. }
  153. else if(fabs(x) < GSL_ROOT6_DBL_EPSILON) {
  154. const double c1 = -0.5;
  155. const double c2 = 1.0/3.0;
  156. const double c3 = -1.0/4.0;
  157. const double c4 = 1.0/5.0;
  158. const double c5 = -1.0/6.0;
  159. const double c6 = 1.0/7.0;
  160. const double c7 = -1.0/8.0;
  161. const double c8 = 1.0/9.0;
  162. const double c9 = -1.0/10.0;
  163. const double t = c5 + x*(c6 + x*(c7 + x*(c8 + x*c9)));
  164. result->val = x * (1.0 + x*(c1 + x*(c2 + x*(c3 + x*(c4 + x*t)))));
  165. result->err = GSL_DBL_EPSILON * fabs(result->val);
  166. return GSL_SUCCESS;
  167. }
  168. else if(fabs(x) < 0.5) {
  169. double t = 0.5*(8.0*x + 1.0)/(x+2.0);
  170. gsl_sf_result c;
  171. cheb_eval_e(&lopx_cs, t, &c);
  172. result->val = x * c.val;
  173. result->err = fabs(x * c.err);
  174. return GSL_SUCCESS;
  175. }
  176. else {
  177. result->val = log(1.0 + x);
  178. result->err = GSL_DBL_EPSILON * fabs(result->val);
  179. return GSL_SUCCESS;
  180. }
  181. }
  182. int
  183. gsl_sf_log_1plusx_mx_e(const double x, gsl_sf_result * result)
  184. {
  185. /* CHECK_POINTER(result) */
  186. if(x <= -1.0) {
  187. DOMAIN_ERROR(result);
  188. }
  189. else if(fabs(x) < GSL_ROOT5_DBL_EPSILON) {
  190. const double c1 = -0.5;
  191. const double c2 = 1.0/3.0;
  192. const double c3 = -1.0/4.0;
  193. const double c4 = 1.0/5.0;
  194. const double c5 = -1.0/6.0;
  195. const double c6 = 1.0/7.0;
  196. const double c7 = -1.0/8.0;
  197. const double c8 = 1.0/9.0;
  198. const double c9 = -1.0/10.0;
  199. const double t = c5 + x*(c6 + x*(c7 + x*(c8 + x*c9)));
  200. result->val = x*x * (c1 + x*(c2 + x*(c3 + x*(c4 + x*t))));
  201. result->err = GSL_DBL_EPSILON * fabs(result->val);
  202. return GSL_SUCCESS;
  203. }
  204. else if(fabs(x) < 0.5) {
  205. double t = 0.5*(8.0*x + 1.0)/(x+2.0);
  206. gsl_sf_result c;
  207. cheb_eval_e(&lopxmx_cs, t, &c);
  208. result->val = x*x * c.val;
  209. result->err = x*x * c.err;
  210. return GSL_SUCCESS;
  211. }
  212. else {
  213. const double lterm = log(1.0 + x);
  214. result->val = lterm - x;
  215. result->err = GSL_DBL_EPSILON * (fabs(lterm) + fabs(x));
  216. return GSL_SUCCESS;
  217. }
  218. }
  219. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  220. #include "gsl_specfunc__eval.h"
  221. double gsl_sf_log(const double x)
  222. {
  223. EVAL_RESULT(gsl_sf_log_e(x, &result));
  224. }
  225. double gsl_sf_log_abs(const double x)
  226. {
  227. EVAL_RESULT(gsl_sf_log_abs_e(x, &result));
  228. }
  229. double gsl_sf_log_1plusx(const double x)
  230. {
  231. EVAL_RESULT(gsl_sf_log_1plusx_e(x, &result));
  232. }
  233. double gsl_sf_log_1plusx_mx(const double x)
  234. {
  235. EVAL_RESULT(gsl_sf_log_1plusx_mx_e(x, &result));
  236. }