static VALUE rb_gsl_spline_eval_integ_e(VALUE obj, VALUE a, VALUE b) { rb_gsl_spline *rgs = NULL; double val; int status; Data_Get_Struct(obj, rb_gsl_spline, rgs); Need_Float(a); Need_Float(b); status = gsl_spline_eval_integ_e(rgs->s, NUM2DBL(a), NUM2DBL(b), rgs->a, &val); switch (status) { case GSL_EDOM: rb_gsl_error_handler("gsl_spline_eval_integ_e error", __FILE__, __LINE__, status); break; default: return rb_float_new(val); break; } return Qnil; }
void integ_mass(bool update) { double *dmdr_tab = (double *) allocate(ntab * sizeof(double)); gsl_spline *spl_dmdr = gsl_spline_alloc(gsl_interp_cspline, ntab); gsl_interp_accel *acc_dmdr = gsl_interp_accel_alloc(); int i, stat; double alpha, mass_int, del_mass, mass_end = mass_tab[ntab - 1]; for (i = 0; i < ntab; i++) dmdr_tab[i] = 4 * M_PI * gsl_pow_2(radius_tab[i]) * density_tab[i]; gsl_spline_init(spl_dmdr, radius_tab, dmdr_tab, ntab); if (radius_tab[0] > 0.0) { alpha = rlog10(density_tab[1] / density_tab[0]) / rlog10(radius_tab[1] / radius_tab[0]); mass_int = (4 * M_PI / (alpha + 3)) * gsl_pow_3(radius_tab[0]) * density_tab[0]; } else mass_int = 0.0; if (update) mass_tab[0] = mass_int; for (i = 1; i < ntab; i++) { stat = gsl_spline_eval_integ_e(spl_dmdr, radius_tab[i-1], radius_tab[i], acc_dmdr, &del_mass); if (stat != 0) error("%s: spline error: %s\n", getprog(), gsl_strerror(stat)); mass_int = mass_int + del_mass; if (update) mass_tab[i] = mass_int; } gsl_interp_accel_free(acc_dmdr); gsl_spline_free(spl_dmdr); free(dmdr_tab); eprintf("[%s: mass[] = %e:%e]\n", getprog(), mass_tab[0], mass_tab[ntab - 1]); if (mass_int < 0.99 * mass_end || mass_int > 1.01 * mass_end) eprintf("[%s: WARNING: final mass = %e integ mass = %e]\n", getprog(), mass_end, mass_int); }