Beispiel #1
0
/*
 * form factor of a spherical Cylinder with radius R, height L and scattering
 * length density eta
 */
scalar sasfit_ff_long_cyl(scalar q, sasfit_param * param)
{
	scalar mu, sigma, pi_mu, G1, G2, I_sp, Sum, V, omega;
	scalar R, L, eta;

	SASFIT_ASSERT_PTR(param);

	sasfit_get_param(param, 4, &R, &L, EMPTY, &eta);

	SASFIT_CHECK_COND1((q < 0.0), param, "q(%lg) < 0",q);
	SASFIT_CHECK_COND1((R < 0.0), param, "R(%lg) < 0",R);
	SASFIT_CHECK_COND1((L < 0.0), param, "L(%lg) < 0",L);

	if (R == 0.0) return 0.0;
	if (L == 0.0) return 0.0;

	mu = L*q;
	sigma = 2.0*R*q;
	V = M_PI*R*R*L;

	if (R==0 || L==0) return 0;
	if (q==0) return V*V*eta*eta;

	pi_mu = gsl_sf_Si(mu)+cos(mu)/mu+sin(mu)/mu/mu;
	G1 = 2.0/(0.5*sigma) *  gsl_sf_bessel_J1(0.5*sigma);
	G2 = 8.0/sigma/sigma * gsl_sf_bessel_Jn(2,sigma);
//	I_sp = 3.0 * (sin(sigma*0.5)-0.5*sigma*cos(0.5*sigma)) / pow(sigma/2.0,3);
//	I_sp = I_sp*I_sp;
	omega = 8/gsl_pow_2(sigma)*(3*gsl_sf_bessel_Jn(2,sigma)+gsl_sf_bessel_J0(sigma)-1);

//	Sum = 2.0/mu * (pi_mu*G1*G1 - 1.0/mu*(2.0*G2-I_sp) - sin(mu)/mu/mu);
	Sum = 2.0/mu * (pi_mu*G1*G1 - omega/mu - sin(mu)/mu/mu);

	return eta*eta *V*V* Sum;
}
Beispiel #2
0
double poisson_finite_cylinder(double kx, double kr, double x0,double r0) {
  double result;

  if ((kx>=tol) & (kr>=tol)) {
    result = 4.0*kr*r0*gsl_sf_bessel_Jn(1, kr*r0)*int_aux(0, kx, kr, x0, r0, PFC_F_0)
      - 4.0*gsl_sf_bessel_Jn(0, kr*r0)*int_aux(1, kx, kr, x0, r0, PFC_F_0)
      + 4.0*M_PI/(kx*kx + kr*kr)*(1.0 + exp(-kr*x0)*(kx/kr*sin(kx*x0) - cos(kx*x0)));
  }
  else if ((kx < tol) & (kr >= tol)){
    result = int_aux(0, kx, kr, x0, r0, PFC_F_KX);
  }
  else if ((kx >= tol) & (kr < tol)){
    result = int_aux(0, kx, kr, x0, r0, PFC_F_KR);
  }
  else 
    result = -2.0*M_PI*( log(r0/(x0 + sqrt(r0*r0 + x0*x0)))
			 *r0*r0 + x0*(x0 - sqrt(r0*r0 + x0*x0)));
  
  /* the 1/(4pi) factor is due to the factor on the poissonsolver3d (end)*/
  return result/(4.0*M_PI);
}
Beispiel #3
0
/*
  input: alpha:   k*dx (wavenumber * grid spacing)
         points:  points to evaluate bessles at
         npoints: number of points in points
	 M:       highest order bessel function to use

  output: return value: matrix A where
          A[i][j] = J_{j'}(alpha*r_i) /  * f(j'*\theta_i) where
	    0 <= i < npoints
	    0 <= j <= M
	    j' = j     if j <= M
	         j - M if j > M
	    f = 1   if j = 0
	        sin if 1 <= j <= M
	        cos if j > M
 */
gsl_matrix *bessel_matrix(double alpha, point *points, int npoints, int M, double r_typical) {
  gsl_matrix *out = gsl_matrix_alloc(npoints, 2*M+1);
  int i,j;
  double x, y, r, theta;

  double column_scale;

  for (i = 0 ; i < npoints ; i++) { // loop over rows
    x = points[i].x;
    y = points[i].y;
    r = R(x, y);
    theta = THETA(x,y);

    // loops over columns
    gsl_matrix_set(out, i, 0, gsl_sf_bessel_J0(alpha * r) / gsl_sf_bessel_J0(alpha * r_typical));
    for (j = 1 ; j <= M ; j++) {
      column_scale = gsl_sf_bessel_Jn(j, alpha * r_typical);
      gsl_matrix_set(out, i, j, gsl_sf_bessel_Jn(j, alpha * r) * sin(j * theta) / column_scale);
      gsl_matrix_set(out, i, j+M, gsl_sf_bessel_Jn(j, alpha * r) * cos(j * theta) / column_scale);
    }
  }

  return out;
}
/**
 * Compute the fourier decomposition of array to -m:m in angular components and 1:nmax in radial components
 * 
 * Note that the gridding scheme used here is defined on [-1..1] x [-1..1], the cmx and cmy specified here should
 * be given in these units. The function "compute_com" defined below can be used to do this.
 * 
 * @arg mmax - largest angular moment computed
 * @arg nmax - largest radial moment computed
 * @arg array - 2d matrix (npts x npts) of energy density in the event
 * @arg npts - number of points in in the array
 * @arg AmnReal - 2d matrix ((2*mmax+1) x nmax), filled with Real parts of the coeffs on return
 * @arg AmnIm - 2d matrix ((2*mmax+1) x nmax), filled with Im parts of the coeffs on return
 * @arg cmx - x location of the CM of the event
 * @arg cmy - y location of the CM of the event
 */ 
void compute_amn(int mmax, int nmax, gsl_matrix *array, int npts, gsl_matrix* AmnReal, gsl_matrix* AmnIm, double cmx, double cmy)
{
  int i,j,k,l;
  int nm, nn;
  int mtemp, ntemp;
  double dx;// = 2/((double)npts-1);
  double dxy;// = 4/pow(((double)npts-1),2.0);
  double xv, yv;
  double coeff = 0;
  double phiMod, phiRe, phiIm;
  double ftemp;
  double AmnRealAcc, AmnImAcc;
  // for compensated summation
  double alphaRe, alphaIm;
  double epsRe, epsIm;

  double rzero = fabs(xmin);
  
  dx = 2*rzero/((double)npts-1);
  dxy = 4*pow(rzero,2.0)/pow(((double)npts-1),2.0);
  //printf("# xmin: %lf dx: %lf dxy: %lf\n", xmin, dx, dxy);
  
  gsl_vector *xvec = gsl_vector_alloc(npts);
  gsl_matrix * rMat = gsl_matrix_alloc(npts, npts);
  gsl_matrix * thMat = gsl_matrix_alloc(npts, npts);
  gsl_matrix *lamMat = NULL;

  gsl_matrix_set_zero(rMat);
  gsl_matrix_set_zero(thMat);
  gsl_vector_set_zero(xvec);

  nm = 2*mmax+1;
  nn = nmax;

  lamMat = gsl_matrix_alloc(nm, nn);

  // fill in r and Theta matrices
  for(i = 0; i < npts; i++)
    gsl_vector_set(xvec ,i, xmin + dx*i);
  
  for(i = 0; i < npts; i++){      
    xv = gsl_vector_get(xvec, i);
    for(j = 0; j < npts;j ++){
      yv = gsl_vector_get(xvec, j);
      gsl_matrix_set(rMat, i, j, sqrt((xv-cmx)*(xv-cmx) + (yv-cmy)*(yv-cmy)));
      gsl_matrix_set(thMat, i, j, atan2((yv-cmy), (xv-cmx)));
    }
  }

  // fill in lambda matrix
  for(i=0; i < nm; i++){
    for(j = 0; j < nn; j++){
      ntemp = j + 1;
      mtemp = -1.0 * mmax + i;
      gsl_matrix_set(lamMat, i, j, gsl_sf_bessel_zero_Jnu(fabs(mtemp), ntemp));
    }
  }
  
  for(i = 0; i < nm; i++){
    for(j = 0; j < nn; j++){
      AmnImAcc = 0.0;
      AmnRealAcc = 0.0;
      epsRe = 0.0;
      epsIm = 0.0;
      
      ntemp = j + 1;
      mtemp = -1.0*mmax + i;
      // note that we have to scale the coeff by rzero, then the system is properly scale invariant
      coeff = pow(rzero,2)*sqrt(M_PI)*gsl_sf_bessel_Jn(fabs(mtemp)+1, gsl_matrix_get(lamMat, i, j));
      
      // now loop over the grid, a lot
      for(k = 0; k < npts; k++){
        for(l = 0; l < npts; l++){
          phiMod = gsl_sf_bessel_Jn(mtemp, gsl_matrix_get(lamMat, i, j)*gsl_matrix_get(rMat, k, l)/rzero) / coeff;
          phiRe = phiMod * cos(mtemp*gsl_matrix_get(thMat, k, l));
          phiIm = phiMod * sin(mtemp*gsl_matrix_get(thMat, k, l));
          ftemp = gsl_matrix_get(array, k, l);

          /* kahan compensated summation (http://en.wikipedia.org/wiki/Kahan_summation_algorithm)
           * we're adding up a lot of little numbers here
           * this trick keeps accumulation errors from, well, accumulating
           */
          alphaRe = AmnRealAcc;
          epsRe += ftemp * phiRe;
          AmnRealAcc = alphaRe + epsRe;
          epsRe += (alphaRe - AmnRealAcc);

          alphaIm = AmnImAcc;
          epsIm += ftemp * phiIm;
          AmnImAcc = alphaIm + epsIm;
          epsIm += (alphaIm - AmnImAcc);
        }
      }
      // and save the coeffs
      gsl_matrix_set(AmnReal, i, j, AmnRealAcc*dxy);
      gsl_matrix_set(AmnIm, i, j, -1.0 * AmnImAcc*dxy);
    }
  }

  gsl_matrix_free(rMat);
  gsl_matrix_free(thMat);
  gsl_vector_free(xvec);
  gsl_matrix_free(lamMat);
}
Beispiel #5
0
	double BesselJ (int n, double z) {
		return gsl_sf_bessel_Jn (n,z);
	}
Beispiel #6
0
double FC_FUNC_(oct_bessel, OCT_BESSEL)
     (const int *n, const double *x)
{
  return gsl_sf_bessel_Jn(*n, *x);
}
static Real _J(UnsignedInteger n, Real z)
{
    return gsl_sf_bessel_Jn(n, z);
}
Beispiel #8
0
int main()
{
#include "bessel_j_int_data.ipp"

   add_data(j0_data);
   add_data(j0_tricky);
   add_data(j1_data);
   add_data(j1_tricky);
   add_data(jn_data);
   add_data(bessel_j_int_data);

   unsigned data_total = data.size();

   screen_data([](const std::vector<double>& v){  return boost::math::cyl_bessel_j(static_cast<int>(v[0]), v[1]);  }, [](const std::vector<double>& v){ return v[2];  });


#if defined(TEST_C99) && !defined(COMPILER_COMPARISON_TABLES)
   screen_data([](const std::vector<double>& v){  return ::jn(static_cast<int>(v[0]), v[1]);  }, [](const std::vector<double>& v){ return v[2];  });
#endif
#if defined(TEST_LIBSTDCXX) && !defined(COMPILER_COMPARISON_TABLES)
   screen_data([](const std::vector<double>& v){  return std::tr1::cyl_bessel_j(static_cast<int>(v[0]), v[1]);  }, [](const std::vector<double>& v){ return v[2];  });
#endif
#if defined(TEST_GSL) && !defined(COMPILER_COMPARISON_TABLES)
   screen_data([](const std::vector<double>& v){  return gsl_sf_bessel_Jn(static_cast<int>(v[0]), v[1]);  }, [](const std::vector<double>& v){ return v[2];  });
#endif
#if defined(TEST_RMATH) && !defined(COMPILER_COMPARISON_TABLES)
   screen_data([](const std::vector<double>& v){  return bessel_j(v[1], static_cast<int>(v[0]));  }, [](const std::vector<double>& v){ return v[2];  });
#endif

   unsigned data_used = data.size();
   std::string function = "cyl_bessel_j (integer order)[br](" + boost::lexical_cast<std::string>(data_used) + "/" + boost::lexical_cast<std::string>(data_total) + " tests selected)";
   std::string function_short = "cyl_bessel_j (integer order)";

   double time;

   time = exec_timed_test([](const std::vector<double>& v){  return boost::math::cyl_bessel_j(static_cast<int>(v[0]), v[1]);  });
   std::cout << time << std::endl;
#if defined(COMPILER_COMPARISON_TABLES)
   report_execution_time(time, std::string("Compiler Option Comparison on ") + platform_name(), "boost::math::cyl_bessel_j (integer orders)", get_compiler_options_name());
#else
#if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH) || defined(TEST_C99) || defined(TEST_LIBSTDCXX))
   report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, boost_name());
#endif
   report_execution_time(time, std::string("Compiler Comparison on ") + std::string(platform_name()), function_short, compiler_name() + std::string("[br]") + boost_name());
#endif
   //
   // Boost again, but with promotion to long double turned off:
   //
#if !defined(COMPILER_COMPARISON_TABLES)
   if(sizeof(long double) != sizeof(double))
   {
      time = exec_timed_test([](const std::vector<double>& v){  return boost::math::cyl_bessel_j(static_cast<int>(v[0]), v[1], boost::math::policies::make_policy(boost::math::policies::promote_double<false>()));  });
      std::cout << time << std::endl;
#if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH) || defined(TEST_C99) || defined(TEST_LIBSTDCXX))
      report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, boost_name() + "[br]promote_double<false>");
#endif
      report_execution_time(time, std::string("Compiler Comparison on ") + std::string(platform_name()), function_short, compiler_name() + std::string("[br]") + boost_name() + "[br]promote_double<false>");
   }
#endif


#if defined(TEST_C99) && !defined(COMPILER_COMPARISON_TABLES)
   time = exec_timed_test([](const std::vector<double>& v){  return ::jn(static_cast<int>(v[0]), v[1]);  });
   std::cout << time << std::endl;
   report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "math.h");
#endif
#if defined(TEST_LIBSTDCXX) && !defined(COMPILER_COMPARISON_TABLES)
   time = exec_timed_test([](const std::vector<double>& v){  return std::tr1::cyl_bessel_j(static_cast<int>(v[0]), v[1]);  });
   std::cout << time << std::endl;
   report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "tr1/cmath");
#endif
#if defined(TEST_GSL) && !defined(COMPILER_COMPARISON_TABLES)
   time = exec_timed_test([](const std::vector<double>& v){  return gsl_sf_bessel_Jn(static_cast<int>(v[0]), v[1]);  });
   std::cout << time << std::endl;
   report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "GSL " GSL_VERSION);
#endif
#if defined(TEST_RMATH) && !defined(COMPILER_COMPARISON_TABLES)
   time = exec_timed_test([](const std::vector<double>& v){  return bessel_j(v[1], static_cast<int>(v[0]));  });
   std::cout << time << std::endl;
   report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "Rmath "  R_VERSION_STRING);
#endif


   return 0;
}
Beispiel #9
0
static double lenscfm_integrand(double ell, void *p)
{
  lensCorrFunc lcf = (lensCorrFunc) p;
  
  return ell/2.0/M_PI*lens_power_spectrum(ell,lcf->lps)*gsl_sf_bessel_Jn(4,ell*lcf->theta/60.0/180.0*M_PI);
}
int gsl_sf_mathieu_Ms_array(int kind, int nmin, int nmax, double qq,
                            double zz, gsl_sf_mathieu_workspace *work,
                            double result_array[])
{
  int even_odd, order, ii, kk, mm, status;
  double maxerr = 1e-14, amax, pi = M_PI, fn;
  double coeff[GSL_SF_MATHIEU_COEFF], fc;
  double j1c, z2c, j1mc, z2mc, j1pc, z2pc;
  double u1, u2;
  double *bb = work->bb;


  /* Initialize the result array to zeroes. */
  for (ii=0; ii<nmax-nmin+1; ii++)
      result_array[ii] = 0.0;
  
  /* Check for out of bounds parameters. */
  if (qq <= 0.0)
  {
      GSL_ERROR("q must be greater than zero", GSL_EINVAL);
  }
  if (kind < 1 || kind > 2)
  {
      GSL_ERROR("kind must be 1 or 2", GSL_EINVAL);
  }

  mm = 0;
  amax = 0.0;
  fn = 0.0;
  u1 = sqrt(qq)*exp(-1.0*zz);
  u2 = sqrt(qq)*exp(zz);
  
  /* Compute all eigenvalues up to nmax. */
  gsl_sf_mathieu_b_array(0, nmax, qq, work, bb);
  
  for (ii=0, order=nmin; order<=nmax; ii++, order++)
  {
      even_odd = 0;
      if (order % 2 != 0)
          even_odd = 1;
  
      /* Compute the series coefficients. */
      status = gsl_sf_mathieu_b_coeff(order, qq, bb[order], coeff);
      if (status != GSL_SUCCESS)
      {
          return status;
      }

      if (even_odd == 0)
      {
          for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
          {
              amax = GSL_MAX(amax, fabs(coeff[kk]));
              if (fabs(coeff[kk])/amax < maxerr)
                  break;

              j1mc = gsl_sf_bessel_Jn(kk, u1);
              j1pc = gsl_sf_bessel_Jn(kk+2, u1);
              if (kind == 1)
              {
                  z2mc = gsl_sf_bessel_Jn(kk, u2);
                  z2pc = gsl_sf_bessel_Jn(kk+2, u2);
              }
              else /* kind = 2 */
              {
                  z2mc = gsl_sf_bessel_Yn(kk, u2);
                  z2pc = gsl_sf_bessel_Yn(kk+2, u2);
              }
          
              fc = pow(-1.0, 0.5*order+kk+1)*coeff[kk];
              fn += fc*(j1mc*z2pc - j1pc*z2mc);
          }

          fn *= sqrt(pi/2.0)/coeff[0];
      }
      else
      {
          for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
          {
              amax = GSL_MAX(amax, fabs(coeff[kk]));
              if (fabs(coeff[kk])/amax < maxerr)
                  break;

              j1c = gsl_sf_bessel_Jn(kk, u1);
              j1pc = gsl_sf_bessel_Jn(kk+1, u1);
              if (kind == 1)
              {
                  z2c = gsl_sf_bessel_Jn(kk, u2);
                  z2pc = gsl_sf_bessel_Jn(kk+1, u2);
              }
              else /* kind = 2 */
              {
                  z2c = gsl_sf_bessel_Yn(kk, u2);
                  z2pc = gsl_sf_bessel_Yn(kk+1, u2);
              }
          
              fc = pow(-1.0, 0.5*(order-1)+kk)*coeff[kk];
              fn += fc*(j1c*z2pc - j1pc*z2c);
          }

          fn *= sqrt(pi/2.0)/coeff[0];
      }

      result_array[ii] = fn;
  } /* order loop */
  
  return GSL_SUCCESS;
}
int gsl_sf_mathieu_Mc(int kind, int order, double qq, double zz,
                      gsl_sf_result *result)
{
  int even_odd, kk, mm, status;
  double maxerr = 1e-14, amax, pi = M_PI, fn, factor;
  double coeff[GSL_SF_MATHIEU_COEFF], fc;
  double j1c, z2c, j1pc, z2pc;
  double u1, u2;
  gsl_sf_result aa;


  /* Check for out of bounds parameters. */
  if (qq <= 0.0)
  {
      GSL_ERROR("q must be greater than zero", GSL_EINVAL);
  }
  if (kind < 1 || kind > 2)
  {
      GSL_ERROR("kind must be 1 or 2", GSL_EINVAL);
  }

  mm = 0;
  amax = 0.0;
  fn = 0.0;
  u1 = sqrt(qq)*exp(-1.0*zz);
  u2 = sqrt(qq)*exp(zz);
  
  even_odd = 0;
  if (order % 2 != 0)
      even_odd = 1;

  /* Compute the characteristic value. */
  status = gsl_sf_mathieu_a(order, qq, &aa);
  if (status != GSL_SUCCESS)
  {
      return status;
  }
  
  /* Compute the series coefficients. */
  status = gsl_sf_mathieu_a_coeff(order, qq, aa.val, coeff);
  if (status != GSL_SUCCESS)
  {
      return status;
  }

  if (even_odd == 0)
  {
      for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
      {
          amax = GSL_MAX(amax, fabs(coeff[kk]));
          if (fabs(coeff[kk])/amax < maxerr)
              break;

          j1c = gsl_sf_bessel_Jn(kk, u1);
          if (kind == 1)
          {
              z2c = gsl_sf_bessel_Jn(kk, u2);
          }
          else /* kind = 2 */
          {
              z2c = gsl_sf_bessel_Yn(kk, u2);
          }
              
          fc = pow(-1.0, 0.5*order+kk)*coeff[kk];
          fn += fc*j1c*z2c;
      }

      fn *= sqrt(pi/2.0)/coeff[0];
  }
  else
  {
      for (kk=0; kk<GSL_SF_MATHIEU_COEFF; kk++)
      {
          amax = GSL_MAX(amax, fabs(coeff[kk]));
          if (fabs(coeff[kk])/amax < maxerr)
              break;

          j1c = gsl_sf_bessel_Jn(kk, u1);
          j1pc = gsl_sf_bessel_Jn(kk+1, u1);
          if (kind == 1)
          {
              z2c = gsl_sf_bessel_Jn(kk, u2);
              z2pc = gsl_sf_bessel_Jn(kk+1, u2);
          }
          else /* kind = 2 */
          {
              z2c = gsl_sf_bessel_Yn(kk, u2);
              z2pc = gsl_sf_bessel_Yn(kk+1, u2);
          }
          fc = pow(-1.0, 0.5*(order-1)+kk)*coeff[kk];
          fn += fc*(j1c*z2pc + j1pc*z2c);
      }

      fn *= sqrt(pi/2.0)/coeff[0];
  }

  result->val = fn;
  result->err = 2.0*GSL_DBL_EPSILON;
  factor = fabs(fn);
  if (factor > 1.0)
      result->err *= factor;
  
  return GSL_SUCCESS;
}
Beispiel #12
0
int main()
{
   double d = gsl_sf_bessel_Jn(2, 1.0);
   return d != 0 ? 0 : 1;
}
const Real GreensFunction2DAbs::p_int_theta_second(const Real r,
                                                   const Real theta,
                                                   const Real t) const
{
    const Real r_0(this->getr0());
    const Real a(this->geta());
    const Real minusDt(-1e0 * this->getD() * t);

    const Integer num_in_term_use(100);
    const Integer num_out_term_use(100);
    const Real threshold(CUTOFF);

    Real sum(0e0);
    Real term(0e0);
    Integer n(1);
    for(; n < num_out_term_use; ++n)
    {
        Real in_sum(0e0);
        Real in_term(0e0);
        Real in_term1(0e0);
        Real in_term2(0e0);
        Real in_term3(0e0);

        Real a_alpha_mn(0e0);
        Real alpha_mn(0e0);
        Real Jn_r_alpha_mn(0e0);
        Real Jn_r0_alpha_mn(0e0);
        Real Jn_d_1_a_alpha_mn(0e0);// J_n-1(a alpha_mn)
        Real Jn_p_1_a_alpha_mn(0e0);// J_n+1(a alpha_mn)

        Real n_real(static_cast<double>(n));
        int n_int(static_cast<int>(n));
        Integer m(1);

        for(; m < num_in_term_use; ++m)
        {
            a_alpha_mn = gsl_sf_bessel_zero_Jnu(n_real, m);
            alpha_mn = a_alpha_mn / a;
            Jn_r_alpha_mn     = gsl_sf_bessel_Jn(n_int, r * alpha_mn);
            Jn_r0_alpha_mn    = gsl_sf_bessel_Jn(n_int, r_0 * alpha_mn);
            Jn_d_1_a_alpha_mn = gsl_sf_bessel_Jn(n_int - 1, a_alpha_mn);
            Jn_p_1_a_alpha_mn = gsl_sf_bessel_Jn(n_int + 1, a_alpha_mn);

            in_term1 = std::exp(alpha_mn * alpha_mn * minusDt);
            in_term2 = Jn_r_alpha_mn * Jn_r0_alpha_mn;
            in_term3 = Jn_d_1_a_alpha_mn - Jn_p_1_a_alpha_mn;

            in_term = in_term1 * in_term2 / (in_term3 * in_term3);
            in_sum += in_term;

//                 std::cout << "inner sum " << in_sum << ", term" << in_term << std::endl;

            if(fabs(in_term/in_sum) < threshold)
            {
//                     std::cout << "normal exit. m = " << m << " second term" << std::endl;
                break;
            }
        }
        if(m == num_in_term_use)
            std::cout << "warning: use term over num_in_term_use" << std::endl;

//             term = in_sum * std::cos(n_real * theta);
        term = in_sum * std::sin(n_real * theta) / n_real;
        sum += term;

//             std::cout << "outer sum " << sum << ", term" << term << std::endl;

        if(fabs(in_sum / (n_real * sum)) < threshold)
        {
            /* if n * theta is a multiple of \pi, the term may be zero and *
             * term/sum become also zero. this is a problem. sin is in a   *
             * regeon [-1, 1], so the order of term does not depend on     *
             * value of sin, so this considers only (in_sum / n_real).     */

//                 std::cout << "normal exit. n = " << n << " second term" << std::endl;
            break;
        }
    }
    if(n == num_out_term_use)
        std::cout << "warning: use term over num_out_term_use" << std::endl;

    return (8e0 * sum / (M_PI * a * a));
}