23 #include <gsl/gsl_errno.h>
24 #include <gsl/gsl_multifit.h>
25 #include <gsl/gsl_min.h>
26 #include <gsl/gsl_nan.h>
27 #include <gsl/gsl_poly.h>
28 #include <gsl/gsl_sf_trig.h>
30 #include <lal/TriggerInterpolation.h>
56 for (i = -window; i <= window; i ++)
59 ret = applyfunc(interp, &tmax_full, &ymax_full, y_full);
60 if (ret == GSL_SUCCESS)
84 for (i = -window; i <= window; i ++)
87 ret = applyfunc(interp, &tmax_full, &ymax_full, y_full);
88 if (ret == GSL_SUCCESS)
91 *ymax = creal(ymax_full);
112 for (i = -window; i <= window; i ++)
115 ret = applyfunc(interp, &tmax_full, &ymax_full, y_full);
116 if (ret == GSL_SUCCESS)
119 *ymax = creal(ymax_full);
133 return gsl_pow_2(creal(z)) + gsl_pow_2(cimag(z));
159 for (; n > 0 &&
a[n - 1] == 0; n--)
166 static void poly_mac(
double *
y,
const double *
a,
size_t na,
const double *b,
size_t nb)
171 for (ia = 0; ia < na; ia++)
172 for (ib = 0; ib < nb; ib++)
173 y[ia + ib] +=
a[ia] * b[ib];
181 for (i = 0; i < n; i ++)
187 static void poly_interp(
double *
a,
const double y_0,
const double y_1,
const double y_2,
const double y_3)
189 a[3] = 0.5 * (y_3 - y_0) + 1.5 * (y_1 - y_2);
190 a[2] = y_0 - 2.5 * y_1 + 2 * y_2 - 0.5 * y_3;
191 a[1] = 0.5 * (y_2 - y_0);
201 static int interp_find_roots(
size_t *nroots,
COMPLEX16 *roots,
const double *are,
const double *aim,
size_t n, gsl_poly_complex_workspace *workspace)
203 int ret = GSL_EFAILED;
210 memset(b, 0,
sizeof(
double) * (2 * n - 2));
212 memcpy(ad, are,
sizeof(
double) * n);
216 memcpy(ad, aim,
sizeof(
double) * n);
228 ret = gsl_poly_complex_solve(b, n, workspace, (
double *) roots);
229 if (ret == GSL_SUCCESS)
245 double argmax = NAN, new_argmax;
247 double max_abs2, new_max_abs2;
250 double are[n], aim[n];
253 size_t nroots, iroot;
263 if (result != GSL_SUCCESS)
269 max_abs2 =
cabs2(maxval);
273 new_max_abs2 =
cabs2(new_maxval);
274 if (new_max_abs2 > max_abs2) {
277 max_abs2 = new_max_abs2;
281 for (iroot = 0; iroot < nroots; iroot++) {
283 if (cimag(roots[iroot]) != 0)
286 new_argmax = creal(roots[iroot]);
289 if (new_argmax <= 0 || new_argmax >= 1)
292 new_maxval = gsl_poly_eval(are, n, new_argmax) + gsl_poly_eval(aim, n, new_argmax) * I;
293 new_max_abs2 =
cabs2(new_maxval);
295 if (new_max_abs2 > max_abs2) {
309 CubicSplineTriggerInterpolant *interp = calloc(1,
sizeof(CubicSplineTriggerInterpolant));
317 interp->workspace = gsl_poly_complex_workspace_alloc(6);
318 if (!interp->workspace)
332 gsl_poly_complex_workspace_free(interp->workspace);
333 interp->workspace = NULL;
340 CubicSplineTriggerInterpolant *interp,
346 double max1_abs1, max2_abs2;
347 double argmax1, argmax2;
350 result =
cubic_interp_1(interp->workspace, &argmax1, &max1, &data[-2]);
351 if (result != GSL_SUCCESS)
353 result =
cubic_interp_1(interp->workspace, &argmax2, &max2, &data[-1]);
354 if (result != GSL_SUCCESS)
356 max1_abs1 =
cabs2(max1);
357 max2_abs2 =
cabs2(max2);
359 if (max1_abs1 > max2_abs2) {
372 CubicSplineTriggerInterpolant *interp,
384 CubicSplineTriggerInterpolant *interp,
396 CubicSplineTriggerInterpolant *interp,
429 return gsl_sf_sinc(t) * gsl_sf_sinc(t /
a);
439 for (ret = 0, i = -(
int)params->
window; i <= (
int)params->
window; i ++)
455 LanczosTriggerInterpolant *interp = calloc(1,
sizeof(LanczosTriggerInterpolant));
460 interp->fminimizer = gsl_min_fminimizer_alloc(gsl_min_fminimizer_brent);
461 if (!interp->fminimizer)
464 interp->window = window;
477 gsl_min_fminimizer_free(interp->fminimizer);
478 interp->fminimizer = NULL;
485 LanczosTriggerInterpolant *interp,
490 static const double epsabs = 1e-5;
497 result = gsl_min_fminimizer_set_with_values(interp->fminimizer, &func,
499 if (result != GSL_SUCCESS)
500 GSL_ERROR(
"failed to initialize minimizer", result);
503 result = gsl_min_fminimizer_iterate(interp->fminimizer);
504 if (result != GSL_SUCCESS)
505 GSL_ERROR(
"failed to perform minimizer iteration", result);
507 t1 = gsl_min_fminimizer_x_lower(interp->fminimizer);
508 t2 = gsl_min_fminimizer_x_upper(interp->fminimizer);
509 }
while (t2 - t1 > epsabs);
511 *t = gsl_min_fminimizer_x_minimum(interp->fminimizer);
519 LanczosTriggerInterpolant *interp,
526 interp->window, tmax, ymax,
y);
531 LanczosTriggerInterpolant *interp,
538 interp->window, tmax, ymax,
y);
543 LanczosTriggerInterpolant *interp,
550 interp->window, tmax, ymax,
y);
566 NearestNeighborTriggerInterpolant *interp = calloc(1,
sizeof(NearestNeighborTriggerInterpolant));
574 interp->window = window;
590 __attribute__ ((unused)) NearestNeighborTriggerInterpolant *interp,
602 NearestNeighborTriggerInterpolant *interp,
609 interp->window, tmax, ymax,
y);
614 NearestNeighborTriggerInterpolant *interp,
621 interp->window, tmax, ymax,
y);
626 NearestNeighborTriggerInterpolant *interp,
633 interp->window, tmax, ymax,
y);
654 QuadraticFitTriggerInterpolant *interp = calloc(1,
sizeof(QuadraticFitTriggerInterpolant));
663 interp->window = window;
665 interp->workspace = gsl_multifit_linear_alloc(2 * window + 1, 3);
666 if (!interp->workspace)
669 interp->X = gsl_matrix_alloc(2 * window + 1, 3);
673 for (i = 0; i < 2 * (int)window + 1; i ++)
675 double x = i - window;
676 gsl_matrix_set(interp->X, i, 0, 1);
677 gsl_matrix_set(interp->X, i, 1,
x);
678 gsl_matrix_set(interp->X, i, 2, gsl_pow_2(
x));
681 interp->cov = gsl_matrix_alloc(3, 3);
685 interp->y = gsl_vector_alloc(2 * window + 1);
689 interp->c = gsl_vector_alloc(3);
693 interp->window = window;
706 gsl_multifit_linear_free(interp->workspace);
707 interp->workspace = NULL;
708 gsl_matrix_free(interp->X);
710 gsl_matrix_free(interp->cov);
712 gsl_vector_free(interp->y);
714 gsl_vector_free(interp->c);
722 QuadraticFitTriggerInterpolant *interp,
732 for (i = -(
int)interp->window; i <= (
int)interp->window; i ++)
733 gsl_vector_set(interp->y, i + interp->window, cabs(
y[i]));
735 result = gsl_multifit_linear(interp->X, interp->y, interp->c, interp->cov, &chisq, interp->workspace);
736 if (result != GSL_SUCCESS)
737 GSL_ERROR(
"regression failed", result);
739 a = gsl_vector_get(interp->c, 2);
740 b = gsl_vector_get(interp->c, 1);
743 if ((
a > 0 || (
a == 0 && b > 0)) && tmax > -1 && tmax < 1)
755 QuadraticFitTriggerInterpolant *interp,
762 interp->window, tmax, ymax,
y);
767 QuadraticFitTriggerInterpolant *interp,
774 interp->window, tmax, ymax,
y);
779 QuadraticFitTriggerInterpolant *interp,
786 interp->window, tmax, ymax,
y);
static double lanczos_cost(double t, void *params)
static int XLALCOMPLEX8ApplyTriggerInterpolant(void *interp, XLALCOMPLEX16ApplyFunc applyfunc, int window, double *tmax, COMPLEX8 *ymax, const COMPLEX8 *y)
static double lanczos(double t, double a)
int XLALCOMPLEX16ApplyNearestNeighborTriggerInterpolant(__attribute__((unused)) NearestNeighborTriggerInterpolant *interp, double *t, COMPLEX16 *y, const COMPLEX16 *data)
static int cubic_interp_1(gsl_poly_complex_workspace *workspace, double *t, COMPLEX16 *val, const COMPLEX16 *y)
Perform cubic spline interpolation of a trigger.
static void poly_der(double *a, size_t n)
static size_t poly_strip(const double *a, size_t n)
static void poly_mac(double *y, const double *a, size_t na, const double *b, size_t nb)
int(* XLALCOMPLEX16ApplyFunc)(void *, double *, COMPLEX16 *, const COMPLEX16 *)
static COMPLEX16 lanczos_interpolant(double t, const LanczosTriggerInterpolantParams *params)
static int interp_find_roots(size_t *nroots, COMPLEX16 *roots, const double *are, const double *aim, size_t n, gsl_poly_complex_workspace *workspace)
Treat are and aim as the real and imaginary parts of a polynomial with complex coefficients.
static double cabs2(COMPLEX16 z)
static int XLALREAL4ApplyTriggerInterpolant(void *interp, XLALCOMPLEX16ApplyFunc applyfunc, int window, double *tmax, REAL4 *ymax, const REAL4 *y)
static int XLALREAL8ApplyTriggerInterpolant(void *interp, XLALCOMPLEX16ApplyFunc applyfunc, int window, double *tmax, REAL8 *ymax, const REAL8 *y)
static void poly_interp(double *a, const double y_0, const double y_1, const double y_2, const double y_3)
int XLALCOMPLEX8ApplyCubicSplineTriggerInterpolant(CubicSplineTriggerInterpolant *interp, double *tmax, COMPLEX8 *ymax, const COMPLEX8 *y)
CubicSplineTriggerInterpolant * XLALCreateCubicSplineTriggerInterpolant(unsigned int window)
Constructor.
int XLALCOMPLEX16ApplyCubicSplineTriggerInterpolant(CubicSplineTriggerInterpolant *interp, double *t, COMPLEX16 *y, const COMPLEX16 *data)
Perform interpolation using the allocated workspace.
void XLALDestroyCubicSplineTriggerInterpolant(CubicSplineTriggerInterpolant *interp)
Destructor.
int XLALREAL4ApplyCubicSplineTriggerInterpolant(CubicSplineTriggerInterpolant *interp, double *tmax, REAL4 *ymax, const REAL4 *y)
int XLALREAL8ApplyCubicSplineTriggerInterpolant(CubicSplineTriggerInterpolant *interp, double *tmax, REAL8 *ymax, const REAL8 *y)
double complex COMPLEX16
Double-precision floating-point complex number (16 bytes total)
double REAL8
Double precision real floating-point number (8 bytes).
float complex COMPLEX8
Single-precision floating-point complex number (8 bytes total)
float REAL4
Single precision real floating-point number (4 bytes).
int XLALREAL8ApplyLanczosTriggerInterpolant(LanczosTriggerInterpolant *interp, double *tmax, REAL8 *ymax, const REAL8 *y)
void XLALDestroyLanczosTriggerInterpolant(LanczosTriggerInterpolant *interp)
Destructor.
int XLALREAL4ApplyLanczosTriggerInterpolant(LanczosTriggerInterpolant *interp, double *tmax, REAL4 *ymax, const REAL4 *y)
int XLALCOMPLEX16ApplyLanczosTriggerInterpolant(LanczosTriggerInterpolant *interp, double *t, COMPLEX16 *y, const COMPLEX16 *data)
Perform interpolation using the allocated workspace.
int XLALCOMPLEX8ApplyLanczosTriggerInterpolant(LanczosTriggerInterpolant *interp, double *tmax, COMPLEX8 *ymax, const COMPLEX8 *y)
LanczosTriggerInterpolant * XLALCreateLanczosTriggerInterpolant(unsigned int window)
Constructor.
NearestNeighborTriggerInterpolant * XLALCreateNearestNeighborTriggerInterpolant(unsigned int window)
Constructor.
int XLALREAL4ApplyNearestNeighborTriggerInterpolant(NearestNeighborTriggerInterpolant *interp, double *tmax, REAL4 *ymax, const REAL4 *y)
int XLALREAL8ApplyNearestNeighborTriggerInterpolant(NearestNeighborTriggerInterpolant *interp, double *tmax, REAL8 *ymax, const REAL8 *y)
int XLALCOMPLEX8ApplyNearestNeighborTriggerInterpolant(NearestNeighborTriggerInterpolant *interp, double *tmax, COMPLEX8 *ymax, const COMPLEX8 *y)
void XLALDestroyNearestNeighborTriggerInterpolant(NearestNeighborTriggerInterpolant *interp)
Destructor.
int XLALREAL8ApplyQuadraticFitTriggerInterpolant(QuadraticFitTriggerInterpolant *interp, double *tmax, REAL8 *ymax, const REAL8 *y)
int XLALCOMPLEX16ApplyQuadraticFitTriggerInterpolant(QuadraticFitTriggerInterpolant *interp, double *t, COMPLEX16 *y, const COMPLEX16 *data)
Perform interpolation using the allocated workspace.
int XLALCOMPLEX8ApplyQuadraticFitTriggerInterpolant(QuadraticFitTriggerInterpolant *interp, double *tmax, COMPLEX8 *ymax, const COMPLEX8 *y)
void XLALDestroyQuadraticFitTriggerInterpolant(QuadraticFitTriggerInterpolant *interp)
Destructor.
QuadraticFitTriggerInterpolant * XLALCreateQuadraticFitTriggerInterpolant(unsigned int window)
Constructor.
int XLALREAL4ApplyQuadraticFitTriggerInterpolant(QuadraticFitTriggerInterpolant *interp, double *tmax, REAL4 *ymax, const REAL4 *y)
gsl_poly_complex_workspace * workspace
gsl_min_fminimizer * fminimizer
gsl_multifit_linear_workspace * workspace