23#include <lal/LALError.h>
24#include <lal/LALMalloc.h>
26#include <gsl/gsl_integration.h>
27#include <gsl/gsl_interp.h>
28#include <gsl/gsl_sf_bessel.h>
29#include <gsl/gsl_sf_exp.h>
30#include <gsl/gsl_errno.h>
33#include <lal/distance_integrator.h>
75 for (
size_t i = 0;
i < len;
i ++)
90 gsl_error_handler_t *old_handler = gsl_set_error_handler_off();
91 double ret = scale - gsl_pow_2(
p /
r - 0.5 * b /
p);
92 int retval=GSL_SUCCESS;
98 retval = gsl_sf_exp_mult_e(
99 ret, gsl_sf_bessel_I0_scaled(b /
r) * gsl_pow_int(
r,
k),
104 retval = gsl_sf_exp_mult_e(
105 ret, gsl_pow_int(
r,
k),
108 gsl_set_error_handler(old_handler);
133 ret = log(gsl_sf_bessel_I0_scaled(b /
r) * gsl_pow_int(
r,
k))
134 + scale - gsl_pow_2(
p /
r - 0.5 * b /
p);
136 ret = ((double)
k)*log(
r) + scale - gsl_pow_2(
p /
r - 0.5 * b /
p);
144 int cosmology,
int gaussian)
147 double breakpoints[5];
148 unsigned char nbreakpoints = 0;
149 double result = 0, abserr, log_offset = -INFINITY;
167 static const double eta = 0.01;
168 const double middle = 2 * gsl_pow_2(
p) / b;
169 const double left = 1 / (1 / middle + sqrt(-log(
eta)) /
p);
170 const double right = 1 / (1 / middle - sqrt(-log(
eta)) /
p);
176 breakpoints[nbreakpoints++] = r1;
177 if(left > breakpoints[nbreakpoints-1] && left <
r2)
178 breakpoints[nbreakpoints++] = left;
179 if(middle > breakpoints[nbreakpoints-1] && middle <
r2)
180 breakpoints[nbreakpoints++] = middle;
181 if(right > breakpoints[nbreakpoints-1] && right <
r2)
182 breakpoints[nbreakpoints++] = right;
183 breakpoints[nbreakpoints++] =
r2;
186 breakpoints[nbreakpoints++] = r1;
187 breakpoints[nbreakpoints++] =
r2;
194 for (
unsigned char i = 0;
i < nbreakpoints;
i++)
197 if (new_log_offset > log_offset)
198 log_offset = new_log_offset;
204 if (log_offset == -INFINITY)
207 params.scale = -log_offset;
209 double abstol = 1
e-8;
210 double reltol = 1
e-8;
225 gsl_integration_workspace workspace = {
240 ret = gsl_integration_qagp(&
func, breakpoints, nbreakpoints,
241 abstol, reltol,
n, &workspace, &result, &abserr);
249 fprintf(stderr,
"GSL error %s, increasing n to %li\n",gsl_strerror(ret),
n*=2);
254 fprintf(stderr,
"%s unable to handle GSL error: %s\n",__func__,gsl_strerror(ret));
259 while(ret!=GSL_SUCCESS);
260 if(relaxed)
fprintf(stderr,
"Warning: had to relax absolute tolerance to %le during distance integration for r1=%lf, r2=%lf, p=%lf, b=%lf, k=%i\n",
263 return log_offset + log(result);
268 double pmax,
size_t size,
int gaussian)
273 const double alpha = 4;
274 const double p0 = 0.5 * (
k >= 0 ?
r2 : r1);
275 const double xmax = log(pmax);
276 const double x0 = GSL_MIN_DBL(log(p0), xmax);
277 const double xmin = x0 - (1 + M_SQRT2) *
alpha;
278 const double ymax = x0 +
alpha;
279 const double ymin = 2 * x0 - M_SQRT2 *
alpha - xmax;
280 const double d = (xmax - xmin) / (
size - 1);
281 const double umin = - (1 + M_SQRT1_2) *
alpha;
282 const double vmax = x0 - M_SQRT1_2 *
alpha;
284 double *z1=calloc(
size,
sizeof(*z1));
285 double *z2=calloc(
size,
sizeof(*z2));
286 double *z0=calloc(
size*
size,
sizeof(*z0));
301 integrator = malloc(
sizeof(*integrator));
303 gsl_error_handler_t *old_handler = gsl_set_error_handler_off();
305 #pragma omp parallel for
312 const size_t ix =
i /
size;
313 const size_t iy =
i %
size;
314 const double x = xmin + ix * d;
315 const double y = ymin + iy * d;
316 const double p = exp(
x);
317 const double r0 = exp(
y);
318 const double b = 2 * gsl_pow_2(
p) / r0;
322 gsl_set_error_handler(old_handler);
329 for (
size_t i = 0;
i <
size;
i ++)
333 for (
size_t i = 0;
i <
size;
i ++)
341 free(z2); free(z1); free(z0);
342 if (interrupted || !(integrator && region0 && region1 && region2))
354 integrator->
xmax = xmax;
355 integrator->
ymax = ymax;
356 integrator->
vmax = vmax;
381 const double x = log_p;
382 const double y = M_LN2 + 2 * log_p - log_b;
389 int k1 = integrator->
k + 1;
393 result = log(log(integrator->
r2 / integrator->
r1));
395 result = log((gsl_pow_int(integrator->
r2,
k1) - gsl_pow_int(integrator->
r1,
k1)) /
k1);
398 if (
y >= integrator->
ymax) {
401 const double v = 0.5 * (
x +
y);
402 if (v <= integrator->vmax)
404 const double u = 0.5 * (
x -
y);
410 result += gsl_pow_2(0.5 * b /
p);
static const double dVC_dVL_high_z_slope
static const double dVC_dVL_dt
static const double dVC_dVL_tmin
static const double dVC_dVL_high_z_intercept
static const double dVC_dVL_tmax
static const double dVC_dVL_data[]
bicubic_interp * bicubic_interp_init(const double *data, int ns, int nt, double smin, double tmin, double ds, double dt)
void cubic_interp_free(cubic_interp *interp)
void bicubic_interp_free(bicubic_interp *interp)
double bicubic_interp_eval(const bicubic_interp *interp, double s, double t)
cubic_interp * cubic_interp_init(const double *data, int n, double tmin, double dt)
double cubic_interp_eval(const cubic_interp *interp, double t)
double log_radial_integrator_eval(const log_radial_integrator *integrator, double p, double b, double log_p, double log_b)
Evaluate the log distance integrator for given SNRs.
double log_radial_integrand(double r, void *params)
void log_radial_integrator_free(log_radial_integrator *integrator)
Free an integrator.
static gsl_spline * dVC_dVL_interp
log_radial_integrator * log_radial_integrator_init(double r1, double r2, int k, int cosmology, double pmax, size_t size, int gaussian)
Distance integrator for marginalisation.
double log_radial_integral(double r1, double r2, double p, double b, int k, int cosmology, int gaussian)
double log_dVC_dVL(double DL)
static double radial_integrand(double r, void *params)
#define XLAL_ERROR_NULL(...)
#define XLAL_CHECK_ABORT(assertion)
#define OMP_EXIT_LOOP_EARLY
#define OMP_BEGIN_INTERRUPTIBLE
#define OMP_END_INTERRUPTIBLE
#define OMP_WAS_INTERRUPTED