gsl_specfunc__legendre_poly.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. /* specfunc/legendre_poly.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 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_bessel.h"
  24. #include "gsl_sf_exp.h"
  25. #include "gsl_sf_gamma.h"
  26. #include "gsl_sf_log.h"
  27. #include "gsl_sf_pow_int.h"
  28. #include "gsl_sf_legendre.h"
  29. #include "gsl_specfunc__error.h"
  30. /* Calculate P_m^m(x) from the analytic result:
  31. * P_m^m(x) = (-1)^m (2m-1)!! (1-x^2)^(m/2) , m > 0
  32. * = 1 , m = 0
  33. */
  34. static double legendre_Pmm(int m, double x)
  35. {
  36. if(m == 0)
  37. {
  38. return 1.0;
  39. }
  40. else
  41. {
  42. double p_mm = 1.0;
  43. double root_factor = sqrt(1.0-x)*sqrt(1.0+x);
  44. double fact_coeff = 1.0;
  45. int i;
  46. for(i=1; i<=m; i++)
  47. {
  48. p_mm *= -fact_coeff * root_factor;
  49. fact_coeff += 2.0;
  50. }
  51. return p_mm;
  52. }
  53. }
  54. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  55. int
  56. gsl_sf_legendre_P1_e(double x, gsl_sf_result * result)
  57. {
  58. /* CHECK_POINTER(result) */
  59. {
  60. result->val = x;
  61. result->err = 0.0;
  62. return GSL_SUCCESS;
  63. }
  64. }
  65. int
  66. gsl_sf_legendre_P2_e(double x, gsl_sf_result * result)
  67. {
  68. /* CHECK_POINTER(result) */
  69. {
  70. result->val = 0.5*(3.0*x*x - 1.0);
  71. result->err = GSL_DBL_EPSILON * (fabs(3.0*x*x) + 1.0);
  72. return GSL_SUCCESS;
  73. }
  74. }
  75. int
  76. gsl_sf_legendre_P3_e(double x, gsl_sf_result * result)
  77. {
  78. /* CHECK_POINTER(result) */
  79. {
  80. result->val = 0.5*x*(5.0*x*x - 3.0);
  81. result->err = GSL_DBL_EPSILON * (fabs(result->val) + 0.5 * fabs(x) * (fabs(5.0*x*x) + 3.0));
  82. return GSL_SUCCESS;
  83. }
  84. }
  85. int
  86. gsl_sf_legendre_Pl_e(const int l, const double x, gsl_sf_result * result)
  87. {
  88. /* CHECK_POINTER(result) */
  89. if(l < 0 || x < -1.0 || x > 1.0) {
  90. DOMAIN_ERROR(result);
  91. }
  92. else if(l == 0) {
  93. result->val = 1.0;
  94. result->err = 0.0;
  95. return GSL_SUCCESS;
  96. }
  97. else if(l == 1) {
  98. result->val = x;
  99. result->err = 0.0;
  100. return GSL_SUCCESS;
  101. }
  102. else if(l == 2) {
  103. result->val = 0.5 * (3.0*x*x - 1.0);
  104. result->err = GSL_DBL_EPSILON * (fabs(3.0*x*x) + 1.0);
  105. /*result->err = 3.0 * GSL_DBL_EPSILON * fabs(result->val);
  106. removed this old bogus estimate [GJ]
  107. */
  108. return GSL_SUCCESS;
  109. }
  110. else if(x == 1.0) {
  111. result->val = 1.0;
  112. result->err = 0.0;
  113. return GSL_SUCCESS;
  114. }
  115. else if(x == -1.0) {
  116. result->val = ( GSL_IS_ODD(l) ? -1.0 : 1.0 );
  117. result->err = 0.0;
  118. return GSL_SUCCESS;
  119. }
  120. else if(l < 100000) {
  121. /* upward recurrence: l P_l = (2l-1) z P_{l-1} - (l-1) P_{l-2} */
  122. double p_ellm2 = 1.0; /* P_0(x) */
  123. double p_ellm1 = x; /* P_1(x) */
  124. double p_ell = p_ellm1;
  125. double e_ellm2 = GSL_DBL_EPSILON;
  126. double e_ellm1 = fabs(x)*GSL_DBL_EPSILON;
  127. double e_ell = e_ellm1;
  128. int ell;
  129. for(ell=2; ell <= l; ell++){
  130. p_ell = (x*(2*ell-1)*p_ellm1 - (ell-1)*p_ellm2) / ell;
  131. p_ellm2 = p_ellm1;
  132. p_ellm1 = p_ell;
  133. e_ell = 0.5*(fabs(x)*(2*ell-1.0) * e_ellm1 + (ell-1.0)*e_ellm2)/ell;
  134. e_ellm2 = e_ellm1;
  135. e_ellm1 = e_ell;
  136. }
  137. result->val = p_ell;
  138. result->err = e_ell + l*fabs(p_ell)*GSL_DBL_EPSILON;
  139. return GSL_SUCCESS;
  140. }
  141. else {
  142. /* Asymptotic expansion.
  143. * [Olver, p. 473]
  144. */
  145. double u = l + 0.5;
  146. double th = acos(x);
  147. gsl_sf_result J0;
  148. gsl_sf_result Jm1;
  149. int stat_J0 = gsl_sf_bessel_J0_e(u*th, &J0);
  150. int stat_Jm1 = gsl_sf_bessel_Jn_e(-1, u*th, &Jm1);
  151. double pre;
  152. double B00;
  153. double c1;
  154. /* B00 = 1/8 (1 - th cot(th) / th^2
  155. * pre = sqrt(th/sin(th))
  156. */
  157. if(th < GSL_ROOT4_DBL_EPSILON) {
  158. B00 = (1.0 + th*th/15.0)/24.0;
  159. pre = 1.0 + th*th/12.0;
  160. }
  161. else {
  162. double sin_th = sqrt(1.0 - x*x);
  163. double cot_th = x / sin_th;
  164. B00 = 1.0/8.0 * (1.0 - th * cot_th) / (th*th);
  165. pre = sqrt(th/sin_th);
  166. }
  167. c1 = th/u * B00;
  168. result->val = pre * (J0.val + c1 * Jm1.val);
  169. result->err = pre * (J0.err + fabs(c1) * Jm1.err);
  170. result->err += GSL_SQRT_DBL_EPSILON * fabs(result->val);
  171. return GSL_ERROR_SELECT_2(stat_J0, stat_Jm1);
  172. }
  173. }
  174. int
  175. gsl_sf_legendre_Pl_array(const int lmax, const double x, double * result_array)
  176. {
  177. /* CHECK_POINTER(result_array) */
  178. if(lmax < 0 || x < -1.0 || x > 1.0) {
  179. GSL_ERROR ("domain error", GSL_EDOM);
  180. }
  181. else if(lmax == 0) {
  182. result_array[0] = 1.0;
  183. return GSL_SUCCESS;
  184. }
  185. else if(lmax == 1) {
  186. result_array[0] = 1.0;
  187. result_array[1] = x;
  188. return GSL_SUCCESS;
  189. }
  190. else {
  191. /* upward recurrence: l P_l = (2l-1) z P_{l-1} - (l-1) P_{l-2} */
  192. double p_ellm2 = 1.0; /* P_0(x) */
  193. double p_ellm1 = x; /* P_1(x) */
  194. double p_ell = p_ellm1;
  195. int ell;
  196. result_array[0] = 1.0;
  197. result_array[1] = x;
  198. for(ell=2; ell <= lmax; ell++){
  199. p_ell = (x*(2*ell-1)*p_ellm1 - (ell-1)*p_ellm2) / ell;
  200. p_ellm2 = p_ellm1;
  201. p_ellm1 = p_ell;
  202. result_array[ell] = p_ell;
  203. }
  204. return GSL_SUCCESS;
  205. }
  206. }
  207. int
  208. gsl_sf_legendre_Pl_deriv_array(const int lmax, const double x, double * result_array, double * result_deriv_array)
  209. {
  210. int stat_array = gsl_sf_legendre_Pl_array(lmax, x, result_array);
  211. if(lmax >= 0) result_deriv_array[0] = 0.0;
  212. if(lmax >= 1) result_deriv_array[1] = 1.0;
  213. if(stat_array == GSL_SUCCESS)
  214. {
  215. int ell;
  216. if(fabs(x - 1.0)*(lmax+1.0)*(lmax+1.0) < GSL_SQRT_DBL_EPSILON)
  217. {
  218. /* x is near 1 */
  219. for(ell = 2; ell <= lmax; ell++)
  220. {
  221. const double pre = 0.5 * ell * (ell+1.0);
  222. result_deriv_array[ell] = pre * (1.0 - 0.25 * (1.0-x) * (ell+2.0)*(ell-1.0));
  223. }
  224. }
  225. else if(fabs(x + 1.0)*(lmax+1.0)*(lmax+1.0) < GSL_SQRT_DBL_EPSILON)
  226. {
  227. /* x is near -1 */
  228. for(ell = 2; ell <= lmax; ell++)
  229. {
  230. const double sgn = ( GSL_IS_ODD(ell) ? 1.0 : -1.0 ); /* derivative is odd in x for even ell */
  231. const double pre = sgn * 0.5 * ell * (ell+1.0);
  232. result_deriv_array[ell] = pre * (1.0 - 0.25 * (1.0+x) * (ell+2.0)*(ell-1.0));
  233. }
  234. }
  235. else
  236. {
  237. const double diff_a = 1.0 + x;
  238. const double diff_b = 1.0 - x;
  239. for(ell = 2; ell <= lmax; ell++)
  240. {
  241. result_deriv_array[ell] = - ell * (x * result_array[ell] - result_array[ell-1]) / (diff_a * diff_b);
  242. }
  243. }
  244. return GSL_SUCCESS;
  245. }
  246. else
  247. {
  248. return stat_array;
  249. }
  250. }
  251. int
  252. gsl_sf_legendre_Plm_e(const int l, const int m, const double x, gsl_sf_result * result)
  253. {
  254. /* If l is large and m is large, then we have to worry
  255. * about overflow. Calculate an approximate exponent which
  256. * measures the normalization of this thing.
  257. */
  258. const double dif = l-m;
  259. const double sum = l+m;
  260. const double t_d = ( dif == 0.0 ? 0.0 : 0.5 * dif * (log(dif)-1.0) );
  261. const double t_s = ( dif == 0.0 ? 0.0 : 0.5 * sum * (log(sum)-1.0) );
  262. const double exp_check = 0.5 * log(2.0*l+1.0) + t_d - t_s;
  263. /* CHECK_POINTER(result) */
  264. if(m < 0 || l < m || x < -1.0 || x > 1.0) {
  265. DOMAIN_ERROR(result);
  266. }
  267. else if(exp_check < GSL_LOG_DBL_MIN + 10.0){
  268. /* Bail out. */
  269. OVERFLOW_ERROR(result);
  270. }
  271. else {
  272. /* Account for the error due to the
  273. * representation of 1-x.
  274. */
  275. const double err_amp = 1.0 / (GSL_DBL_EPSILON + fabs(1.0-fabs(x)));
  276. /* P_m^m(x) and P_{m+1}^m(x) */
  277. double p_mm = legendre_Pmm(m, x);
  278. double p_mmp1 = x * (2*m + 1) * p_mm;
  279. if(l == m){
  280. result->val = p_mm;
  281. result->err = err_amp * 2.0 * GSL_DBL_EPSILON * fabs(p_mm);
  282. return GSL_SUCCESS;
  283. }
  284. else if(l == m + 1) {
  285. result->val = p_mmp1;
  286. result->err = err_amp * 2.0 * GSL_DBL_EPSILON * fabs(p_mmp1);
  287. return GSL_SUCCESS;
  288. }
  289. else{
  290. /* upward recurrence: (l-m) P(l,m) = (2l-1) z P(l-1,m) - (l+m-1) P(l-2,m)
  291. * start at P(m,m), P(m+1,m)
  292. */
  293. double p_ellm2 = p_mm;
  294. double p_ellm1 = p_mmp1;
  295. double p_ell = 0.0;
  296. int ell;
  297. for(ell=m+2; ell <= l; ell++){
  298. p_ell = (x*(2*ell-1)*p_ellm1 - (ell+m-1)*p_ellm2) / (ell-m);
  299. p_ellm2 = p_ellm1;
  300. p_ellm1 = p_ell;
  301. }
  302. result->val = p_ell;
  303. result->err = err_amp * (0.5*(l-m) + 1.0) * GSL_DBL_EPSILON * fabs(p_ell);
  304. return GSL_SUCCESS;
  305. }
  306. }
  307. }
  308. int
  309. gsl_sf_legendre_Plm_array(const int lmax, const int m, const double x, double * result_array)
  310. {
  311. /* If l is large and m is large, then we have to worry
  312. * about overflow. Calculate an approximate exponent which
  313. * measures the normalization of this thing.
  314. */
  315. const double dif = lmax-m;
  316. const double sum = lmax+m;
  317. const double t_d = ( dif == 0.0 ? 0.0 : 0.5 * dif * (log(dif)-1.0) );
  318. const double t_s = ( dif == 0.0 ? 0.0 : 0.5 * sum * (log(sum)-1.0) );
  319. const double exp_check = 0.5 * log(2.0*lmax+1.0) + t_d - t_s;
  320. /* CHECK_POINTER(result_array) */
  321. if(m < 0 || lmax < m || x < -1.0 || x > 1.0) {
  322. GSL_ERROR ("domain error", GSL_EDOM);
  323. }
  324. else if(m > 0 && (x == 1.0 || x == -1.0)) {
  325. int ell;
  326. for(ell=m; ell<=lmax; ell++) result_array[ell-m] = 0.0;
  327. return GSL_SUCCESS;
  328. }
  329. else if(exp_check < GSL_LOG_DBL_MIN + 10.0){
  330. /* Bail out. */
  331. GSL_ERROR ("overflow", GSL_EOVRFLW);
  332. }
  333. else {
  334. double p_mm = legendre_Pmm(m, x);
  335. double p_mmp1 = x * (2.0*m + 1.0) * p_mm;
  336. if(lmax == m){
  337. result_array[0] = p_mm;
  338. return GSL_SUCCESS;
  339. }
  340. else if(lmax == m + 1) {
  341. result_array[0] = p_mm;
  342. result_array[1] = p_mmp1;
  343. return GSL_SUCCESS;
  344. }
  345. else {
  346. double p_ellm2 = p_mm;
  347. double p_ellm1 = p_mmp1;
  348. double p_ell = 0.0;
  349. int ell;
  350. result_array[0] = p_mm;
  351. result_array[1] = p_mmp1;
  352. for(ell=m+2; ell <= lmax; ell++){
  353. p_ell = (x*(2.0*ell-1.0)*p_ellm1 - (ell+m-1)*p_ellm2) / (ell-m);
  354. p_ellm2 = p_ellm1;
  355. p_ellm1 = p_ell;
  356. result_array[ell-m] = p_ell;
  357. }
  358. return GSL_SUCCESS;
  359. }
  360. }
  361. }
  362. int
  363. gsl_sf_legendre_Plm_deriv_array(
  364. const int lmax, const int m, const double x,
  365. double * result_array,
  366. double * result_deriv_array)
  367. {
  368. if(m < 0 || m > lmax)
  369. {
  370. GSL_ERROR("m < 0 or m > lmax", GSL_EDOM);
  371. }
  372. else if(m == 0)
  373. {
  374. /* It is better to do m=0 this way, so we can more easily
  375. * trap the divergent case which can occur when m == 1.
  376. */
  377. return gsl_sf_legendre_Pl_deriv_array(lmax, x, result_array, result_deriv_array);
  378. }
  379. else
  380. {
  381. int stat_array = gsl_sf_legendre_Plm_array(lmax, m, x, result_array);
  382. if(stat_array == GSL_SUCCESS)
  383. {
  384. int ell;
  385. if(m == 1 && (1.0 - fabs(x) < GSL_DBL_EPSILON))
  386. {
  387. /* This divergence is real and comes from the cusp-like
  388. * behaviour for m = 1. For example, P[1,1] = - Sqrt[1-x^2].
  389. */
  390. GSL_ERROR("divergence near |x| = 1.0 since m = 1", GSL_EOVRFLW);
  391. }
  392. else if(m == 2 && (1.0 - fabs(x) < GSL_DBL_EPSILON))
  393. {
  394. /* m = 2 gives a finite nonzero result for |x| near 1 */
  395. if(fabs(x - 1.0) < GSL_DBL_EPSILON)
  396. {
  397. for(ell = m; ell <= lmax; ell++) result_deriv_array[ell-m] = -0.25 * x * (ell - 1.0)*ell*(ell+1.0)*(ell+2.0);
  398. }
  399. else if(fabs(x + 1.0) < GSL_DBL_EPSILON)
  400. {
  401. for(ell = m; ell <= lmax; ell++)
  402. {
  403. const double sgn = ( GSL_IS_ODD(ell) ? 1.0 : -1.0 );
  404. result_deriv_array[ell-m] = -0.25 * sgn * x * (ell - 1.0)*ell*(ell+1.0)*(ell+2.0);
  405. }
  406. }
  407. return GSL_SUCCESS;
  408. }
  409. else
  410. {
  411. /* m > 2 is easier to deal with since the endpoints always vanish */
  412. if(1.0 - fabs(x) < GSL_DBL_EPSILON)
  413. {
  414. for(ell = m; ell <= lmax; ell++) result_deriv_array[ell-m] = 0.0;
  415. return GSL_SUCCESS;
  416. }
  417. else
  418. {
  419. const double diff_a = 1.0 + x;
  420. const double diff_b = 1.0 - x;
  421. result_deriv_array[0] = - m * x / (diff_a * diff_b) * result_array[0];
  422. if(lmax-m >= 1) result_deriv_array[1] = (2.0 * m + 1.0) * (x * result_deriv_array[0] + result_array[0]);
  423. for(ell = m+2; ell <= lmax; ell++)
  424. {
  425. result_deriv_array[ell-m] = - (ell * x * result_array[ell-m] - (ell+m) * result_array[ell-1-m]) / (diff_a * diff_b);
  426. }
  427. return GSL_SUCCESS;
  428. }
  429. }
  430. }
  431. else
  432. {
  433. return stat_array;
  434. }
  435. }
  436. }
  437. int
  438. gsl_sf_legendre_sphPlm_e(const int l, int m, const double x, gsl_sf_result * result)
  439. {
  440. /* CHECK_POINTER(result) */
  441. if(m < 0 || l < m || x < -1.0 || x > 1.0) {
  442. DOMAIN_ERROR(result);
  443. }
  444. else if(m == 0) {
  445. gsl_sf_result P;
  446. int stat_P = gsl_sf_legendre_Pl_e(l, x, &P);
  447. double pre = sqrt((2.0*l + 1.0)/(4.0*M_PI));
  448. result->val = pre * P.val;
  449. result->err = pre * P.err;
  450. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  451. return stat_P;
  452. }
  453. else if(x == 1.0 || x == -1.0) {
  454. /* m > 0 here */
  455. result->val = 0.0;
  456. result->err = 0.0;
  457. return GSL_SUCCESS;
  458. }
  459. else {
  460. /* m > 0 and |x| < 1 here */
  461. /* Starting value for recursion.
  462. * Y_m^m(x) = sqrt( (2m+1)/(4pi m) gamma(m+1/2)/gamma(m) ) (-1)^m (1-x^2)^(m/2) / pi^(1/4)
  463. */
  464. gsl_sf_result lncirc;
  465. gsl_sf_result lnpoch;
  466. double lnpre_val;
  467. double lnpre_err;
  468. gsl_sf_result ex_pre;
  469. double sr;
  470. const double sgn = ( GSL_IS_ODD(m) ? -1.0 : 1.0);
  471. const double y_mmp1_factor = x * sqrt(2.0*m + 3.0);
  472. double y_mm, y_mm_err;
  473. double y_mmp1, y_mmp1_err;
  474. gsl_sf_log_1plusx_e(-x*x, &lncirc);
  475. gsl_sf_lnpoch_e(m, 0.5, &lnpoch); /* Gamma(m+1/2)/Gamma(m) */
  476. lnpre_val = -0.25*M_LNPI + 0.5 * (lnpoch.val + m*lncirc.val);
  477. lnpre_err = 0.25*M_LNPI*GSL_DBL_EPSILON + 0.5 * (lnpoch.err + fabs(m)*lncirc.err);
  478. /* Compute exp(ln_pre) with error term, avoiding call to gsl_sf_exp_err BJG */
  479. ex_pre.val = exp(lnpre_val);
  480. ex_pre.err = 2.0*(sinh(lnpre_err) + GSL_DBL_EPSILON)*ex_pre.val;
  481. sr = sqrt((2.0+1.0/m)/(4.0*M_PI));
  482. y_mm = sgn * sr * ex_pre.val;
  483. y_mm_err = 2.0 * GSL_DBL_EPSILON * fabs(y_mm) + sr * ex_pre.err;
  484. y_mm_err *= 1.0 + 1.0/(GSL_DBL_EPSILON + fabs(1.0-x));
  485. y_mmp1 = y_mmp1_factor * y_mm;
  486. y_mmp1_err=fabs(y_mmp1_factor) * y_mm_err;
  487. if(l == m){
  488. result->val = y_mm;
  489. result->err = y_mm_err;
  490. result->err += 2.0 * GSL_DBL_EPSILON * fabs(y_mm);
  491. return GSL_SUCCESS;
  492. }
  493. else if(l == m + 1) {
  494. result->val = y_mmp1;
  495. result->err = y_mmp1_err;
  496. result->err += 2.0 * GSL_DBL_EPSILON * fabs(y_mmp1);
  497. return GSL_SUCCESS;
  498. }
  499. else{
  500. double y_ell = 0.0;
  501. double y_ell_err;
  502. int ell;
  503. /* Compute Y_l^m, l > m+1, upward recursion on l. */
  504. for(ell=m+2; ell <= l; ell++){
  505. const double rat1 = (double)(ell-m)/(double)(ell+m);
  506. const double rat2 = (ell-m-1.0)/(ell+m-1.0);
  507. const double factor1 = sqrt(rat1*(2.0*ell+1.0)*(2.0*ell-1.0));
  508. const double factor2 = sqrt(rat1*rat2*(2.0*ell+1.0)/(2.0*ell-3.0));
  509. y_ell = (x*y_mmp1*factor1 - (ell+m-1.0)*y_mm*factor2) / (ell-m);
  510. y_mm = y_mmp1;
  511. y_mmp1 = y_ell;
  512. y_ell_err = 0.5*(fabs(x*factor1)*y_mmp1_err + fabs((ell+m-1.0)*factor2)*y_mm_err) / fabs(ell-m);
  513. y_mm_err = y_mmp1_err;
  514. y_mmp1_err = y_ell_err;
  515. }
  516. result->val = y_ell;
  517. result->err = y_ell_err + (0.5*(l-m) + 1.0) * GSL_DBL_EPSILON * fabs(y_ell);
  518. return GSL_SUCCESS;
  519. }
  520. }
  521. }
  522. int
  523. gsl_sf_legendre_sphPlm_array(const int lmax, int m, const double x, double * result_array)
  524. {
  525. /* CHECK_POINTER(result_array) */
  526. if(m < 0 || lmax < m || x < -1.0 || x > 1.0) {
  527. GSL_ERROR ("error", GSL_EDOM);
  528. }
  529. else if(m > 0 && (x == 1.0 || x == -1.0)) {
  530. int ell;
  531. for(ell=m; ell<=lmax; ell++) result_array[ell-m] = 0.0;
  532. return GSL_SUCCESS;
  533. }
  534. else {
  535. double y_mm;
  536. double y_mmp1;
  537. if(m == 0) {
  538. y_mm = 0.5/M_SQRTPI; /* Y00 = 1/sqrt(4pi) */
  539. y_mmp1 = x * M_SQRT3 * y_mm;
  540. }
  541. else {
  542. /* |x| < 1 here */
  543. gsl_sf_result lncirc;
  544. gsl_sf_result lnpoch;
  545. double lnpre;
  546. const double sgn = ( GSL_IS_ODD(m) ? -1.0 : 1.0);
  547. gsl_sf_log_1plusx_e(-x*x, &lncirc);
  548. gsl_sf_lnpoch_e(m, 0.5, &lnpoch); /* Gamma(m+1/2)/Gamma(m) */
  549. lnpre = -0.25*M_LNPI + 0.5 * (lnpoch.val + m*lncirc.val);
  550. y_mm = sqrt((2.0+1.0/m)/(4.0*M_PI)) * sgn * exp(lnpre);
  551. y_mmp1 = x * sqrt(2.0*m + 3.0) * y_mm;
  552. }
  553. if(lmax == m){
  554. result_array[0] = y_mm;
  555. return GSL_SUCCESS;
  556. }
  557. else if(lmax == m + 1) {
  558. result_array[0] = y_mm;
  559. result_array[1] = y_mmp1;
  560. return GSL_SUCCESS;
  561. }
  562. else{
  563. double y_ell;
  564. int ell;
  565. result_array[0] = y_mm;
  566. result_array[1] = y_mmp1;
  567. /* Compute Y_l^m, l > m+1, upward recursion on l. */
  568. for(ell=m+2; ell <= lmax; ell++){
  569. const double rat1 = (double)(ell-m)/(double)(ell+m);
  570. const double rat2 = (ell-m-1.0)/(ell+m-1.0);
  571. const double factor1 = sqrt(rat1*(2*ell+1)*(2*ell-1));
  572. const double factor2 = sqrt(rat1*rat2*(2*ell+1)/(2*ell-3));
  573. y_ell = (x*y_mmp1*factor1 - (ell+m-1)*y_mm*factor2) / (ell-m);
  574. y_mm = y_mmp1;
  575. y_mmp1 = y_ell;
  576. result_array[ell-m] = y_ell;
  577. }
  578. }
  579. return GSL_SUCCESS;
  580. }
  581. }
  582. int
  583. gsl_sf_legendre_sphPlm_deriv_array(
  584. const int lmax, const int m, const double x,
  585. double * result_array,
  586. double * result_deriv_array)
  587. {
  588. if(m < 0 || lmax < m || x < -1.0 || x > 1.0)
  589. {
  590. GSL_ERROR ("domain", GSL_EDOM);
  591. }
  592. else if(m == 0)
  593. {
  594. /* m = 0 is easy to trap */
  595. const int stat_array = gsl_sf_legendre_Pl_deriv_array(lmax, x, result_array, result_deriv_array);
  596. int ell;
  597. for(ell = 0; ell <= lmax; ell++)
  598. {
  599. const double prefactor = sqrt((2.0 * ell + 1.0)/(4.0*M_PI));
  600. result_array[ell] *= prefactor;
  601. result_deriv_array[ell] *= prefactor;
  602. }
  603. return stat_array;
  604. }
  605. else if(m == 1)
  606. {
  607. /* Trapping m = 1 is necessary because of the possible divergence.
  608. * Recall that this divergence is handled properly in ..._Plm_deriv_array(),
  609. * and the scaling factor is not large for small m, so we just scale.
  610. */
  611. const int stat_array = gsl_sf_legendre_Plm_deriv_array(lmax, m, x, result_array, result_deriv_array);
  612. int ell;
  613. for(ell = 1; ell <= lmax; ell++)
  614. {
  615. const double prefactor = sqrt((2.0 * ell + 1.0)/(ell + 1.0) / (4.0*M_PI*ell));
  616. result_array[ell-1] *= prefactor;
  617. result_deriv_array[ell-1] *= prefactor;
  618. }
  619. return stat_array;
  620. }
  621. else
  622. {
  623. /* as for the derivative of P_lm, everything is regular for m >= 2 */
  624. int stat_array = gsl_sf_legendre_sphPlm_array(lmax, m, x, result_array);
  625. if(stat_array == GSL_SUCCESS)
  626. {
  627. int ell;
  628. if(1.0 - fabs(x) < GSL_DBL_EPSILON)
  629. {
  630. for(ell = m; ell <= lmax; ell++) result_deriv_array[ell-m] = 0.0;
  631. return GSL_SUCCESS;
  632. }
  633. else
  634. {
  635. const double diff_a = 1.0 + x;
  636. const double diff_b = 1.0 - x;
  637. result_deriv_array[0] = - m * x / (diff_a * diff_b) * result_array[0];
  638. if(lmax-m >= 1) result_deriv_array[1] = sqrt(2.0 * m + 3.0) * (x * result_deriv_array[0] + result_array[0]);
  639. for(ell = m+2; ell <= lmax; ell++)
  640. {
  641. const double c1 = sqrt(((2.0*ell+1.0)/(2.0*ell-1.0)) * ((double)(ell-m)/(double)(ell+m)));
  642. result_deriv_array[ell-m] = - (ell * x * result_array[ell-m] - c1 * (ell+m) * result_array[ell-1-m]) / (diff_a * diff_b);
  643. }
  644. return GSL_SUCCESS;
  645. }
  646. }
  647. else
  648. {
  649. return stat_array;
  650. }
  651. }
  652. }
  653. #ifndef HIDE_INLINE_STATIC
  654. int
  655. gsl_sf_legendre_array_size(const int lmax, const int m)
  656. {
  657. return lmax-m+1;
  658. }
  659. #endif
  660. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  661. #include "gsl_specfunc__eval.h"
  662. double gsl_sf_legendre_P1(const double x)
  663. {
  664. EVAL_RESULT(gsl_sf_legendre_P1_e(x, &result));
  665. }
  666. double gsl_sf_legendre_P2(const double x)
  667. {
  668. EVAL_RESULT(gsl_sf_legendre_P2_e(x, &result));
  669. }
  670. double gsl_sf_legendre_P3(const double x)
  671. {
  672. EVAL_RESULT(gsl_sf_legendre_P3_e(x, &result));
  673. }
  674. double gsl_sf_legendre_Pl(const int l, const double x)
  675. {
  676. EVAL_RESULT(gsl_sf_legendre_Pl_e(l, x, &result));
  677. }
  678. double gsl_sf_legendre_Plm(const int l, const int m, const double x)
  679. {
  680. EVAL_RESULT(gsl_sf_legendre_Plm_e(l, m, x, &result));
  681. }
  682. double gsl_sf_legendre_sphPlm(const int l, const int m, const double x)
  683. {
  684. EVAL_RESULT(gsl_sf_legendre_sphPlm_e(l, m, x, &result));
  685. }