46 return (0.5*log(6.28*N)-N*log(1.36*X/N));
66 N0=(int)(floor(1.1*A0)+1.0);
70 for (IT=1; IT<=20; IT++) {
72 NN = N1-(int)((
double)(N1-N0) / (1.0-F0/F1));
74 if (abs(NN-N1) < 1)
goto e20;
96 double A0,EJN,F,F0,F1,HMP,OBJ;
105 N0=(int)floor(1.1*A0);
114 for (IT=1; IT<=20; IT++) {
116 NN = N1-(int)((
double)(N1-N0)/(1.0-F0/F1));
118 if (abs(NN-N1) < 1)
goto e20;
148 double CS, F, F0, F1, SI0;
151 if (fabs(X) < 1e-20) {
152 for (K=0; K<=N; K++) {
157 DI[1]=0.333333333333333;
161 SI[1]=-(sinh(X)/X-cosh(X))/X;
180 for (K=M; K>-1; K--) {
181 F=(2.0*K+3.0)*F1/X+F0;
182 if (K <= *NM) SI[K]=F;
187 for (K=0; K<=*NM; K++) SI[K] *= CS;
190 for (K=1; K<=*NM; K++)
191 DI[K]=SI[K-1]-(K+1.0)/X*SI[K];
215 for (K=0; K<=N; K++) {
222 SK[1]=SK[0]*(1.0+1.0/X);
225 for (K=2; K<=N; K++) {
226 F=(2.0*K-1.0)*F1/X+F0;
228 if (fabs(F) > 1.0e+300)
goto e20;
234 for (K=1; K<=*NM; K++)
235 DK[K]=-SK[K-1]-(K+1.0)/X*SK[K];
259 double CS, F, F0, F1, SA, SB;
262 if (fabs(X) < 1e-80) {
263 for (K=0; K<=N; K++) {
268 DJ[1]=0.333333333333333;
272 SJ[1]=(SJ[0]-cos(X))/X;
293 for (K=M; K>-1; K--) {
294 F=(2.0*K+3.0)*F1/X-F0;
295 if (K <= *NM) SJ[K]=F;
299 if (fabs(SA) > fabs(SB)) CS=SA/F;
300 if (fabs(SA) <= fabs(SB)) CS=SB/F0;
301 for (K=0; K<=*NM; K++) SJ[K] *= CS;
303 DJ[0]=(cos(X)-sin(X)/X)/X;
304 for (K=1; K<=*NM; K++)
305 DJ[K]=SJ[K-1]-(K+1.0)*SJ[K]/X;
328 for (K=0; K<=N; K++) {
335 SY[1]=(SY[0]-sin(X))/X;
338 for (K=2; K<=N; K++) {
339 F=(2.0*K-1.0)*F1/X-F0;
341 if (fabs(F) >= 1e+300)
goto e20;
346 DY[0]=(sin(X)+cos(X)/X)/X;
347 for (K=1; K<=*NM; K++)
348 DY[K]=SY[K-1]-(K+1.0)*SY[K]/X;
354static double Jn(
int n,
double z)
366static double Yn(
int n,
double z)
400 J_n[i] =
Jn(N, z[i]);
401 if(N==0 && dJ_n!=NULL)
402 dJ_n[i] = -
Jn(1, z[i]);
404 dJ_n[i] = (
Jn(N-1, z[i])-
Jn(N+1, z[i]))/2.0;
422 for(n=0; n<N+1; n++){
424 J_n[i*(N+1)+n] = 0.0;
426 dJ_n[i*(N+1)+n] = 0.0;
430 for(n=0; n<N+1; n++){
432 J_n[i*(N+1)+n] =
Jn(n, z[i]);
433 if(n==0 && dJ_n!=NULL)
434 dJ_n[i*(N+1)+n] = -
Jn(1, z[i]);
436 dJ_n[i*(N+1)+n] = (
Jn(n-1, z[i])-
Jn(n+1, z[i]))/2.0;
462 Y_n[i] =
Yn(N, z[i]);
463 if(N==0 && dY_n!=NULL)
464 dY_n[i] = -
Yn(1, z[i]);
466 dY_n[i] = (
Yn(N-1, z[i])-
Yn(N+1, z[i]))/2.0;
484 for(n=0; n<N+1; n++){
486 Y_n[i*(N+1)+n] = 0.0;
488 dY_n[i*(N+1)+n] = 0.0;
492 for(n=0; n<N+1; n++){
494 Y_n[i*(N+1)+n] =
Yn(n, z[i]);
495 if(n==0 && dY_n!=NULL)
496 dY_n[i*(N+1)+n] = -
Yn(1, z[i]);
498 dY_n[i*(N+1)+n] = (
Yn(n-1, z[i])-
Yn(n+1, z[i]))/2.0;
509 double_complex* H_n1,
510 double_complex* dH_n1
518 H_n1[i] = cmplx(0.0, 0.0);
520 dH_n1[i] = cmplx(0.0, 0.0);
524 H_n1[i] = cmplx(
Jn(N, z[i]),
Yn(N, z[i]));
526 dH_n1[i] = ccsub(crmul(cmplx(
Jn(N, z[i]),
Yn(N, z[i])), (
double)N/
SAF_MAX(z[i],2.23e-13f)), cmplx(
Jn(N+1, z[i]),
Yn(N+1, z[i])));
536 double_complex* H_n1,
537 double_complex* dH_n1
544 for(n=0; n<N+1; n++){
546 H_n1[i*(N+1)+n] = cmplx(0.0, 0.0);
548 dH_n1[i*(N+1)+n] = cmplx(0.0, 0.0);
552 for(n=0; n<N+1; n++){
554 H_n1[i*(N+1)+n] = cmplx(
Jn(n, z[i]),
Yn(n, z[i]));
556 dH_n1[i*(N+1)+n] = ccsub(crmul(cmplx(
Jn(n, z[i]),
Yn(n, z[i])), (double)n/
SAF_MAX(z[i],2.23e-13f)), cmplx(
Jn(n+1, z[i]),
Yn(n+1, z[i])));
567 double_complex* H_n2,
568 double_complex* dH_n2
576 H_n2[i] = cmplx(0.0, 0.0);
578 dH_n2[i] = cmplx(0.0, 0.0);
582 H_n2[i] = cmplx(
Jn(N, z[i]), -
Yn(N, z[i]));
583 if(N==0 && dH_n2!=NULL)
584 dH_n2[i] = crmul(ccsub(ccmul(cmplx(
Jn(1, z[i]),
Yn(1, z[i])), cexp(cmplx(0.0, -
SAF_PId))), cmplx(
Jn(1, z[i]), -
Yn(1, z[i]))), 0.5);
586 dH_n2[i] = crmul(ccsub(cmplx(
Jn(N-1, z[i]), -
Yn(N-1, z[i])), cmplx(
Jn(N+1, z[i]), -
Yn(N+1, z[i]))), 0.5);
596 double_complex* H_n2,
597 double_complex* dH_n2
604 for(n=0; n<N+1; n++){
606 H_n2[i*(N+1)+n] = cmplx(0.0, 0.0);
608 dH_n2[i*(N+1)+n] = cmplx(0.0, 0.0);
612 for(n=0; n<N+1; n++){
614 H_n2[i*(N+1)+n] = cmplx(
Jn(n, z[i]), -
Yn(n, z[i]));
615 if(n==0 && dH_n2!=NULL)
616 dH_n2[i*(N+1)+n] = crmul(ccsub(ccmul(cmplx(
Jn(1, z[i]),
Yn(1, z[i])), cexp(cmplx(0.0, -
SAF_PId))), cmplx(
Jn(1, z[i]), -
Yn(1, z[i]))), 0.5);
618 dH_n2[i*(N+1)+n] = crmul(ccsub(cmplx(
Jn(n-1, z[i]), -
Yn(n-1, z[i])), cmplx(
Jn(n+1, z[i]), -
Yn(n+1, z[i]))), 0.5);
639 double* j_0N, *dj_0N;
641 saf_assert(j_n!=NULL || dj_n!=NULL,
"Either j_n or dj_n must be not NULL!");
644 j_0N = j_n==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(
double));
645 dj_0N = dj_n==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(
double));
651 j_n[i] = computedN==N ? j_0N[i*(N+1)+(N)] : 0.0;
654 dj_n[i] = computedN==N ? dj_0N[i*(N+1)+(N)] : 0.0;
659 return computedN==N ? 1 : 0;
673 double* j_n_tmp, *dj_n_tmp;
675 j_n_tmp =
malloc1d((N+1)*
sizeof(
double));
676 dj_n_tmp =
malloc1d((N+1)*
sizeof(
double));
681 memset(&j_n[0], 0, (N+1)*
sizeof(
double));
685 memset(&dj_n[0], 0, (N+1)*
sizeof(
double));
691 SPHJ(N, z[i], &NM, j_n_tmp, dj_n_tmp);
693 for(n=0; n<NM+1; n++){
695 j_n [i*(N+1)+n] = j_n_tmp[n];
697 dj_n[i*(N+1)+n] = dj_n_tmp[n];
701 j_n [i*(N+1)+n] = 0.0;
703 dj_n [i*(N+1)+n] = 0.0;
707 *maxN = *maxN==1e8 ? 0 : *maxN;
715 saf_print_warning(
"Unable to compute the spherical Bessel (jn) function at the specified order and input value(s).");
733 double* i_0N, *di_0N;
735 saf_assert(i_n!=NULL || di_n!=NULL,
"Either i_n or di_n must be not NULL!");
738 i_0N = i_n==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(
double));
739 di_0N = di_n==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(
double));
745 i_n[i] = computedN==N ? i_0N[i*(N+1)+(N)] : 0.0;
748 di_n[i] = computedN==N ? di_0N[i*(N+1)+(N)] : 0.0;
753 return computedN==N ? 1 : 0;
767 double* i_n_tmp, *di_n_tmp;
769 i_n_tmp =
malloc1d((N+1)*
sizeof(
double));
770 di_n_tmp =
malloc1d((N+1)*
sizeof(
double));
775 memset(&i_n[0], 0, (N+1)*
sizeof(
double));
779 memset(&di_n[0], 0, (N+1)*
sizeof(
double));
785 SPHI(N, z[i], &NM, i_n_tmp, di_n_tmp);
787 for(n=0; n<NM+1; n++){
789 i_n [i*(N+1)+n] = i_n_tmp[n];
791 di_n[i*(N+1)+n] = di_n_tmp[n];
795 i_n [i*(N+1)+n] = 0.0;
797 di_n [i*(N+1)+n] = 0.0;
801 *maxN = *maxN==1e8 ? 0 : *maxN;
809 saf_print_warning(
"Unable to compute the spherical Bessel (in) function at the specified order and input value(s).");
827 double* y_0N, *dy_0N;
829 saf_assert(y_n!=NULL || dy_n!=NULL,
"Either y_n or dy_n must be not NULL!");
832 y_0N = y_n==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(
double));
833 dy_0N = dy_n==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(
double));
839 y_n[i] = computedN==N ? y_0N[i*(N+1)+(N)] : 0.0;
842 dy_n[i] = computedN==N ? dy_0N[i*(N+1)+(N)] : 0.0;
847 return computedN==N ? 1 : 0;
861 double* y_n_tmp, *dy_n_tmp;
863 y_n_tmp =
malloc1d((N+1)*
sizeof(
double));
864 dy_n_tmp =
malloc1d((N+1)*
sizeof(
double));
869 memset(&y_n[0], 0, (N+1)*
sizeof(
double));
871 memset(&dy_n[0], 0, (N+1)*
sizeof(
double));
874 SPHY(N, z[i], &NM, y_n_tmp, dy_n_tmp);
876 for(n=0; n<NM+1; n++){
878 y_n [i*(N+1)+n] = y_n_tmp[n];
880 dy_n[i*(N+1)+n] = dy_n_tmp[n];
884 y_n [i*(N+1)+n] = 0.0;
886 dy_n [i*(N+1)+n] = 0.0;
890 *maxN = *maxN==1e8 ? 0 : *maxN;
898 saf_print_warning(
"Unable to compute the spherical Bessel (yn) function at the specified order and input value(s).");
916 double* k_0N, *dk_0N;
918 saf_assert(k_n!=NULL || dk_n!=NULL,
"Either k_n or dk_n must be not NULL!");
921 k_0N = k_n==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(
double));
922 dk_0N = dk_n==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(
double));
928 k_n[i] = computedN==N ? k_0N[i*(N+1)+(N)] : 0.0;
931 dk_n[i] = computedN==N ? dk_0N[i*(N+1)+(N)] : 0.0;
936 return computedN==N ? 1 : 0;
950 double* k_n_tmp, *dk_n_tmp;
952 k_n_tmp =
malloc1d((N+1)*
sizeof(
double));
953 dk_n_tmp =
malloc1d((N+1)*
sizeof(
double));
958 memset(&k_n[0], 0, (N+1)*
sizeof(
double));
960 memset(&dk_n[0], 0, (N+1)*
sizeof(
double));
963 SPHK(N, z[i], &NM, k_n_tmp, dk_n_tmp);
965 for(n=0; n<NM+1; n++){
967 k_n [i*(N+1)+n] = k_n_tmp[n];
969 dk_n[i*(N+1)+n] = dk_n_tmp[n];
973 k_n [i*(N+1)+n] = 0.0;
975 dk_n [i*(N+1)+n] = 0.0;
979 *maxN = *maxN==1e8 ? 0 : *maxN;
987 saf_print_warning(
"Unable to compute the spherical Bessel (kn) function at the specified order and input value(s).");
1000 double_complex* h_n1,
1001 double_complex* dh_n1
1005 double_complex* h1_0N, *dh1_0N;
1007 saf_assert(h_n1!=NULL || dh_n1!=NULL,
"Either h_n1 or dh_n1 must be not NULL!");
1010 h1_0N = h_n1==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(double_complex));
1011 dh1_0N = dh_n1==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(double_complex));
1017 h_n1[i] = computedN==N ? h1_0N[i*(N+1)+(N)] : cmplx(0.0, 0.0);
1020 dh_n1[i] = computedN==N ? dh1_0N[i*(N+1)+(N)] : cmplx(0.0, 0.0);
1025 return computedN==N ? 1 : 0;
1034 double_complex* h_n1,
1035 double_complex* dh_n1
1039 double* j_n_tmp, *dj_n_tmp, *y_n_tmp, *dy_n_tmp;
1041 j_n_tmp =
calloc1d((N+1),
sizeof(
double));
1042 dj_n_tmp =
calloc1d((N+1),
sizeof(
double));
1043 y_n_tmp =
calloc1d((N+1),
sizeof(
double));
1044 dy_n_tmp =
calloc1d((N+1),
sizeof(
double));
1046 for(i=0; i<nZ; i++){
1049 memset(&h_n1[0], 0, (N+1)*
sizeof(double_complex));
1050 h_n1[0] = cmplx(1.0, 0.0);
1053 memset(&dh_n1[0], 0, (N+1)*
sizeof(double_complex));
1056 SPHJ(N, z[i], &NM1, j_n_tmp, dj_n_tmp);
1058 SPHY(N, z[i], &NM2, y_n_tmp, dy_n_tmp);
1060 for(n=0; n<
SAF_MIN(NM1,NM2)+1; n++){
1062 h_n1 [i*(N+1)+n] = cmplx(j_n_tmp[n], y_n_tmp[n]);
1064 dh_n1[i*(N+1)+n] = cmplx(dj_n_tmp[n], dy_n_tmp[n]);
1068 h_n1 [i*(N+1)+n] = cmplx(0.0,0.0);
1070 dh_n1 [i*(N+1)+n] = cmplx(0.0,0.0);
1074 *maxN = *maxN==1e8 ? 0 : *maxN;
1082 saf_print_warning(
"Unable to compute the spherical Hankel (hn1) function at the specified order and input value(s).");
1097 double_complex* h_n2,
1098 double_complex* dh_n2
1102 double_complex* h2_0N, *dh2_0N;
1104 saf_assert(h_n2!=NULL || dh_n2!=NULL,
"Either h_n2 or dh_n2 must be not NULL!");
1107 h2_0N = h_n2==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(double_complex));
1108 dh2_0N = dh_n2==NULL ? NULL :
malloc1d(nZ*(N+1)*
sizeof(double_complex));
1114 h_n2[i] = computedN==N ? h2_0N[i*(N+1)+(N)] : cmplx(0.0, 0.0);
1117 dh_n2[i] = computedN==N ? dh2_0N[i*(N+1)+(N)] : cmplx(0.0, 0.0);
1122 return computedN==N ? 1 : 0;
1131 double_complex* h_n2,
1132 double_complex* dh_n2
1136 double* j_n_tmp, *dj_n_tmp, *y_n_tmp, *dy_n_tmp;
1138 j_n_tmp =
calloc1d((N+1),
sizeof(
double));
1139 dj_n_tmp =
calloc1d((N+1),
sizeof(
double));
1140 y_n_tmp =
calloc1d((N+1),
sizeof(
double));
1141 dy_n_tmp =
calloc1d((N+1),
sizeof(
double));
1143 for(i=0; i<nZ; i++){
1146 memset(&h_n2[0], 0, (N+1)*
sizeof(double_complex));
1147 h_n2[0] = cmplx(1.0, 0.0);
1150 memset(&dh_n2[0], 0, (N+1)*
sizeof(double_complex));
1153 SPHJ(N, z[i], &NM1, j_n_tmp, dj_n_tmp);
1155 SPHY(N, z[i], &NM2, y_n_tmp, dy_n_tmp);
1157 for(n=0; n<
SAF_MIN(NM1,NM2)+1; n++){
1159 h_n2 [i*(N+1)+n] = cmplx(j_n_tmp[n], -y_n_tmp[n]);
1161 dh_n2[i*(N+1)+n] = cmplx(dj_n_tmp[n], -dy_n_tmp[n]);
1165 h_n2 [i*(N+1)+n] = cmplx(0.0,0.0);
1167 dh_n2 [i*(N+1)+n] = cmplx(0.0,0.0);
1171 *maxN = *maxN==1e8 ? 0 : *maxN;
1179 saf_print_warning(
"Unable to compute the spherical Hankel (hn2) function at the specified order and input value(s).");
void bessel_jn_ALL(int N, double *z, int nZ, int *maxN, double *j_n, double *dj_n)
Computes the spherical Bessel function of the first kind (jn) and their derivatives (djn) for ALL ord...
#define saf_assert(x, message)
Macro to make an assertion, along with a string explaining its purpose.
void bessel_Yn_ALL(int N, double *z, int nZ, double *Y_n, double *dY_n)
Computes the (cylindrical) Bessel function of the second kind (Yn) and their derivatives (dYn) for AL...
int hankel_hn2(int N, double *z, int nZ, double_complex *h_n2, double_complex *dh_n2)
Computes the values of the spherical Hankel function of the second kind (hn2) and it's derivative (dh...
void hankel_hn2_ALL(int N, double *z, int nZ, int *maxN, double_complex *h_n2, double_complex *dh_n2)
Computes the spherical Hankel function of the second kind (hn2) and their derivatives (dhn2) for ALL ...
void bessel_yn_ALL(int N, double *z, int nZ, int *maxN, double *y_n, double *dy_n)
Computes the spherical Bessel function of the second kind (yn) and their derivatives (dyn) for ALL or...
void hankel_Hn1_ALL(int N, double *z, int nZ, double_complex *H_n1, double_complex *dH_n1)
Computes the (cylindrical) Hankel function of the first kind (Hn1) and their derivatives (dHn1) for A...
#define SAF_MAX(a, b)
Returns the maximum of the two values.
void bessel_Jn(int N, double *z, int nZ, double *J_n, double *dJ_n)
Computes the values of the (cylindrical) Bessel function of the first kind (Jn) and it's derivative (...
#define SAF_PId
pi constant (double precision)
int hankel_hn1(int N, double *z, int nZ, double_complex *h_n1, double_complex *dh_n1)
Computes the values of the spherical Hankel function of the first kind (hn1) and it's derivative (dhn...
void hankel_hn1_ALL(int N, double *z, int nZ, int *maxN, double_complex *h_n1, double_complex *dh_n1)
Computes the spherical Hankel function of the first kind (hn1) and their derivatives (dhn1) for ALL o...
void bessel_Jn_ALL(int N, double *z, int nZ, double *J_n, double *dJ_n)
Computes the (cylindrical) Bessel function of the first kind (Jn) and their derivatives (dJn) for ALL...
void bessel_in_ALL(int N, double *z, int nZ, int *maxN, double *i_n, double *di_n)
Computes the modified spherical Bessel function of the first kind (in) and their derivatives (din) fo...
void hankel_Hn2(int N, double *z, int nZ, double_complex *H_n2, double_complex *dH_n2)
Computes the values of the (cylindrical) Hankel function of the second kind (Hn2) and it's derivative...
#define SAF_MIN(a, b)
Returns the minimum of the two values.
#define saf_print_warning(message)
Macro to print a warning message along with the filename and line number.
void hankel_Hn2_ALL(int N, double *z, int nZ, double_complex *H_n2, double_complex *dH_n2)
Computes the (cylindrical) Hankel function of the second kind (Hn2) and their derivatives (dHn2) for ...
int bessel_yn(int N, double *z, int nZ, double *y_n, double *dy_n)
Computes the values of the spherical Bessel function of the second kind (yn) and it's derivative (dyn...
void hankel_Hn1(int N, double *z, int nZ, double_complex *H_n1, double_complex *dH_n1)
Computes the values of the (cylindrical) Hankel function of the first kind (Hn1) and it's derivative ...
int bessel_jn(int N, double *z, int nZ, double *j_n, double *dj_n)
Computes the values of the spherical Bessel function of the first kind (jn) and it's derivative (djn)
int bessel_kn(int N, double *z, int nZ, double *k_n, double *dk_n)
Computes the values of the modified spherical Bessel function of the second kind (kn) and it's deriva...
void bessel_Yn(int N, double *z, int nZ, double *Y_n, double *dY_n)
Computes the values of the (cylindrical) Bessel function of the second kind (Yn) and it's derivative ...
void bessel_kn_ALL(int N, double *z, int nZ, int *maxN, double *k_n, double *dk_n)
Computes the modified spherical Bessel function of the second kind (kn) and their derivatives (dkn) f...
int bessel_in(int N, double *z, int nZ, double *i_n, double *di_n)
Computes the values of the modified spherical Bessel function of the first kind (in) and it's derivat...
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
void * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, but with error checking)
Main header for the utilities module (SAF_UTILITIES_MODULE)
static int MSTA2(double X, int N, int MP)
Helper function, used when computing spherical bessel function values.
static void SPHK(int N, double X, int *NM, double *SK, double *DK)
Helper function for bessel_kn.
static double Jn(int n, double z)
Wrapper for the cylindrical Bessel function of the first kind.
static void SPHJ(int N, double X, int *NM, double *SJ, double *DJ)
Helper function for bessel_in.
static void SPHY(int N, double X, int *NM, double *SY, double *DY)
Helper function for bessel_yn.
static double ENVJ(int N, double X)
Helper function, used when computing spherical bessel function values.
static int MSTA1(double X, int MP)
Helper function, used when computing spherical bessel function values.
static void SPHI(int N, double X, int *NM, double *SI, double *DI)
Helper function for bessel_in.
static double Yn(int n, double z)
Wrapper for the cylindrical Bessel function of the second kind.