1 /* specfunc/mathieu_radfunc.c
3 * Copyright (C) 2002 Lowell Johnson
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* Author: L. Johnson */
25 #include <gsl/gsl_math.h>
26 #include <gsl/gsl_sf.h>
27 #include <gsl/gsl_sf_mathieu.h>
30 int gsl_sf_mathieu_Mc(int kind, int order, double qq, double zz,
31 gsl_sf_result *result)
33 int even_odd, kk, mm, status;
34 double maxerr = 1e-14, amax, pi = M_PI, fn, factor;
35 double coeff[GSL_SF_MATHIEU_COEFF], fc;
36 double j1c, z2c, j1pc, z2pc;
41 /* Check for out of bounds parameters. */
44 GSL_ERROR("q must be greater than zero", GSL_EINVAL);
46 if (kind < 1 || kind > 2)
48 GSL_ERROR("kind must be 1 or 2", GSL_EINVAL);
54 u1 = sqrt(qq)*exp(-1.0*zz);
55 u2 = sqrt(qq)*exp(zz);
61 /* Compute the characteristic value. */
62 status = gsl_sf_mathieu_a(order, qq, &aa);
63 if (status != GSL_SUCCESS)
68 /* Compute the series coefficients. */
69 status = gsl_sf_mathieu_a_coeff(order, qq, aa.val, coeff);
70 if (status != GSL_SUCCESS)
77 for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
79 amax = GSL_MAX(amax, fabs(coeff[kk]));
80 if (fabs(coeff[kk])/amax < maxerr)
83 j1c = gsl_sf_bessel_Jn(kk, u1);
86 z2c = gsl_sf_bessel_Jn(kk, u2);
90 z2c = gsl_sf_bessel_Yn(kk, u2);
93 fc = pow(-1.0, 0.5*order+kk)*coeff[kk];
97 fn *= sqrt(pi/2.0)/coeff[0];
101 for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
103 amax = GSL_MAX(amax, fabs(coeff[kk]));
104 if (fabs(coeff[kk])/amax < maxerr)
107 j1c = gsl_sf_bessel_Jn(kk, u1);
108 j1pc = gsl_sf_bessel_Jn(kk+1, u1);
111 z2c = gsl_sf_bessel_Jn(kk, u2);
112 z2pc = gsl_sf_bessel_Jn(kk+1, u2);
116 z2c = gsl_sf_bessel_Yn(kk, u2);
117 z2pc = gsl_sf_bessel_Yn(kk+1, u2);
119 fc = pow(-1.0, 0.5*(order-1)+kk)*coeff[kk];
120 fn += fc*(j1c*z2pc + j1pc*z2c);
123 fn *= sqrt(pi/2.0)/coeff[0];
127 result->err = 2.0*GSL_DBL_EPSILON;
130 result->err *= factor;
136 int gsl_sf_mathieu_Ms(int kind, int order, double qq, double zz,
137 gsl_sf_result *result)
139 int even_odd, kk, mm, status;
140 double maxerr = 1e-14, amax, pi = M_PI, fn, factor;
141 double coeff[GSL_SF_MATHIEU_COEFF], fc;
142 double j1c, z2c, j1mc, z2mc, j1pc, z2pc;
147 /* Check for out of bounds parameters. */
150 GSL_ERROR("q must be greater than zero", GSL_EINVAL);
152 if (kind < 1 || kind > 2)
154 GSL_ERROR("kind must be 1 or 2", GSL_EINVAL);
160 u1 = sqrt(qq)*exp(-1.0*zz);
161 u2 = sqrt(qq)*exp(zz);
167 /* Compute the characteristic value. */
168 status = gsl_sf_mathieu_b(order, qq, &aa);
169 if (status != GSL_SUCCESS)
174 /* Compute the series coefficients. */
175 status = gsl_sf_mathieu_b_coeff(order, qq, aa.val, coeff);
176 if (status != GSL_SUCCESS)
183 for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
185 amax = GSL_MAX(amax, fabs(coeff[kk]));
186 if (fabs(coeff[kk])/amax < maxerr)
189 j1mc = gsl_sf_bessel_Jn(kk, u1);
190 j1pc = gsl_sf_bessel_Jn(kk+2, u1);
193 z2mc = gsl_sf_bessel_Jn(kk, u2);
194 z2pc = gsl_sf_bessel_Jn(kk+2, u2);
198 z2mc = gsl_sf_bessel_Yn(kk, u2);
199 z2pc = gsl_sf_bessel_Yn(kk+2, u2);
202 fc = pow(-1.0, 0.5*order+kk+1)*coeff[kk];
203 fn += fc*(j1mc*z2pc - j1pc*z2mc);
206 fn *= sqrt(pi/2.0)/coeff[0];
210 for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
212 amax = GSL_MAX(amax, fabs(coeff[kk]));
213 if (fabs(coeff[kk])/amax < maxerr)
216 j1c = gsl_sf_bessel_Jn(kk, u1);
217 j1pc = gsl_sf_bessel_Jn(kk+1, u1);
220 z2c = gsl_sf_bessel_Jn(kk, u2);
221 z2pc = gsl_sf_bessel_Jn(kk+1, u2);
225 z2c = gsl_sf_bessel_Yn(kk, u2);
226 z2pc = gsl_sf_bessel_Yn(kk+1, u2);
229 fc = pow(-1.0, 0.5*(order-1)+kk)*coeff[kk];
230 fn += fc*(j1c*z2pc - j1pc*z2c);
233 fn *= sqrt(pi/2.0)/coeff[0];
237 result->err = 2.0*GSL_DBL_EPSILON;
240 result->err *= factor;
246 int gsl_sf_mathieu_Mc_array(int kind, int nmin, int nmax, double qq,
247 double zz, gsl_sf_mathieu_workspace *work,
248 double result_array[])
250 int even_odd, order, ii, kk, mm, status;
251 double maxerr = 1e-14, amax, pi = M_PI, fn;
252 double coeff[GSL_SF_MATHIEU_COEFF], fc;
253 double j1c, z2c, j1pc, z2pc;
255 double *aa = work->aa;
258 /* Initialize the result array to zeroes. */
259 for (ii=0; ii<nmax-nmin+1; ii++)
260 result_array[ii] = 0.0;
262 /* Check for out of bounds parameters. */
265 GSL_ERROR("q must be greater than zero", GSL_EINVAL);
267 if (kind < 1 || kind > 2)
269 GSL_ERROR("kind must be 1 or 2", GSL_EINVAL);
275 u1 = sqrt(qq)*exp(-1.0*zz);
276 u2 = sqrt(qq)*exp(zz);
278 /* Compute all eigenvalues up to nmax. */
279 gsl_sf_mathieu_a_array(0, nmax, qq, work, aa);
281 for (ii=0, order=nmin; order<=nmax; ii++, order++)
287 /* Compute the series coefficients. */
288 status = gsl_sf_mathieu_a_coeff(order, qq, aa[order], coeff);
289 if (status != GSL_SUCCESS)
296 for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
298 amax = GSL_MAX(amax, fabs(coeff[kk]));
299 if (fabs(coeff[kk])/amax < maxerr)
302 j1c = gsl_sf_bessel_Jn(kk, u1);
305 z2c = gsl_sf_bessel_Jn(kk, u2);
309 z2c = gsl_sf_bessel_Yn(kk, u2);
312 fc = pow(-1.0, 0.5*order+kk)*coeff[kk];
316 fn *= sqrt(pi/2.0)/coeff[0];
320 for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
322 amax = GSL_MAX(amax, fabs(coeff[kk]));
323 if (fabs(coeff[kk])/amax < maxerr)
326 j1c = gsl_sf_bessel_Jn(kk, u1);
327 j1pc = gsl_sf_bessel_Jn(kk+1, u1);
330 z2c = gsl_sf_bessel_Jn(kk, u2);
331 z2pc = gsl_sf_bessel_Jn(kk+1, u2);
335 z2c = gsl_sf_bessel_Yn(kk, u2);
336 z2pc = gsl_sf_bessel_Yn(kk+1, u2);
338 fc = pow(-1.0, 0.5*(order-1)+kk)*coeff[kk];
339 fn += fc*(j1c*z2pc + j1pc*z2c);
342 fn *= sqrt(pi/2.0)/coeff[0];
345 result_array[ii] = fn;
352 int gsl_sf_mathieu_Ms_array(int kind, int nmin, int nmax, double qq,
353 double zz, gsl_sf_mathieu_workspace *work,
354 double result_array[])
356 int even_odd, order, ii, kk, mm, status;
357 double maxerr = 1e-14, amax, pi = M_PI, fn;
358 double coeff[GSL_SF_MATHIEU_COEFF], fc;
359 double j1c, z2c, j1mc, z2mc, j1pc, z2pc;
361 double *bb = work->bb;
364 /* Initialize the result array to zeroes. */
365 for (ii=0; ii<nmax-nmin+1; ii++)
366 result_array[ii] = 0.0;
368 /* Check for out of bounds parameters. */
371 GSL_ERROR("q must be greater than zero", GSL_EINVAL);
373 if (kind < 1 || kind > 2)
375 GSL_ERROR("kind must be 1 or 2", GSL_EINVAL);
381 u1 = sqrt(qq)*exp(-1.0*zz);
382 u2 = sqrt(qq)*exp(zz);
384 /* Compute all eigenvalues up to nmax. */
385 gsl_sf_mathieu_b_array(0, nmax, qq, work, bb);
387 for (ii=0, order=nmin; order<=nmax; ii++, order++)
393 /* Compute the series coefficients. */
394 status = gsl_sf_mathieu_b_coeff(order, qq, bb[order], coeff);
395 if (status != GSL_SUCCESS)
402 for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
404 amax = GSL_MAX(amax, fabs(coeff[kk]));
405 if (fabs(coeff[kk])/amax < maxerr)
408 j1mc = gsl_sf_bessel_Jn(kk, u1);
409 j1pc = gsl_sf_bessel_Jn(kk+2, u1);
412 z2mc = gsl_sf_bessel_Jn(kk, u2);
413 z2pc = gsl_sf_bessel_Jn(kk+2, u2);
417 z2mc = gsl_sf_bessel_Yn(kk, u2);
418 z2pc = gsl_sf_bessel_Yn(kk+2, u2);
421 fc = pow(-1.0, 0.5*order+kk+1)*coeff[kk];
422 fn += fc*(j1mc*z2pc - j1pc*z2mc);
425 fn *= sqrt(pi/2.0)/coeff[0];
429 for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
431 amax = GSL_MAX(amax, fabs(coeff[kk]));
432 if (fabs(coeff[kk])/amax < maxerr)
435 j1c = gsl_sf_bessel_Jn(kk, u1);
436 j1pc = gsl_sf_bessel_Jn(kk+1, u1);
439 z2c = gsl_sf_bessel_Jn(kk, u2);
440 z2pc = gsl_sf_bessel_Jn(kk+1, u2);
444 z2c = gsl_sf_bessel_Yn(kk, u2);
445 z2pc = gsl_sf_bessel_Yn(kk+1, u2);
448 fc = pow(-1.0, 0.5*(order-1)+kk)*coeff[kk];
449 fn += fc*(j1c*z2pc - j1pc*z2c);
452 fn *= sqrt(pi/2.0)/coeff[0];
455 result_array[ii] = fn;