Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
PiecewiseModel.c
Go to the documentation of this file.
1//
2// Copyright (C) 2019--2023 Benjamin Grace
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with with program; see the file COPYING. If not, write to the
16// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17// MA 02110-1301 USA
18//
19
20#include <stdio.h>
21#include <math.h>
22#include <lal/LatticeTiling.h>
23#include <lal/LogPrintf.h>
24#include <lal/PiecewiseModel.h>
25
26#ifdef __GNUC__
27#define UNUSED __attribute__ ((unused))
28#else
29#define UNUSED
30#endif
31
32///
33/// A struct containing the relevant information for calculating upper and lower bounds on a specific piecewise segment
34///
35typedef struct tagPiecewiseBoundInfo {
36 size_t s; ///< Number of frequency/spindown parameters per knot
37 double n; ///< Braking index
38 double k; ///< k value
39 double dt; ///< Time between knots
41
42///
43/// The general torque equation and its first two derivatives
44///
45static double GTEAndDerivs(
46 double f0, ///< Initial frequency
47 double n, ///< Braking index
48 double k, ///< k value
49 double t, ///< Time at which to evaluate the GTE
50 int d ///< Derivative order (d <= 2)
51)
52{
53 double base = 1 + ( n - 1 ) * k * pow( f0, n - 1 ) * t;
54 double power = 1 / ( 1 - n );
55
56 if ( d == 0 ) {
57 return f0 * pow( base, power );
58 } else if ( d == 1 ) {
59 double factor = -1 * pow( f0, n ) * k;
60 return factor * pow( base, power - 1 );
61 } else if ( d == 2 ) {
62 double factor = pow( f0, 2 * n - 1 ) * k * k * n;
63 double secondderiv = factor * pow( base, power - 2 );
64 return secondderiv;
65 }
66
67 return NAN;
68}
69
70///
71/// Sets the bound on the frequency parameter
72///
73static double F0Bound(
74 const void *data,
75 const size_t dim UNUSED,
76 const gsl_matrix *cache UNUSED,
77 const gsl_vector *point
78)
79{
81
82 // Frequency at previous knot
83 const double f0 = gsl_vector_get( point, dim - info->s );
84
85 // Frequency at this knot, propagated by dt
86 const double f = GTEAndDerivs( f0, info->n, info->k, info->dt, 0 );
87
88 if ( f >= f0 ) {
89 printf( "f >= f0, %g >= %g", f, f0 );
90 }
91
92 return f;
93}
94
95///
96/// Sets the bound on the first derivative frequency parameter
97///
98static double F1Bound(
99 const void *data,
100 const size_t dim UNUSED,
101 const gsl_matrix *cache UNUSED,
102 const gsl_vector *point
103)
104{
106
107 // Frequency at this knot
108 const double f0 = gsl_vector_get( point, dim - 1 );
109
110 // First derivative of the general torque equation
111 // - Evaluated at dt=0, i.e. at this knot
112 const double fd = GTEAndDerivs( f0, info->n, info->k, 0, 1 );
113
114 return fd;
115}
116
117///
118/// Sets the bounds on the second derivative frequency parameter
119///
120static double F2Bound(
121 const void *data,
122 const size_t dim UNUSED,
123 const gsl_matrix *cache UNUSED,
124 const gsl_vector *point
125)
126{
128
129 // Frequency at this knot
130 const double f0 = gsl_vector_get( point, dim - 2 );
131
132 // Second derivative of the general torque equation
133 // - Evaluated at dt=0, i.e. at this knot
134 const double fdd = GTEAndDerivs( f0, info->n, info->k, 0, 2 );
135
136 return fdd;
137}
138
139///
140/// Sets the bounds for the piecewise model
141///
143 LatticeTiling *tiling, ///< Lattice tiling
144 const size_t s, ///< Number of frequency/spindown parameters per knot
145 const double fmin, ///< Minimum initial frequency
146 const double fmax, ///< Maximum initial frequency
147 const double nmin, ///< Minimum braking index
148 const double nmax, ///< Maximum braking index
149 const double kmin, ///< Minimum k value
150 const double kmax, ///< Maximum k value
151 const gsl_vector *knots, ///< List of knots
152 const gsl_vector *bboxpad, ///< Vector containing fractional bounding box padding
153 const gsl_vector_int *intpad ///< Vector containing number of integer points to use for padding
154)
155{
156
157 XLAL_CHECK( tiling != NULL, XLAL_EINVAL );
158 XLAL_CHECK( s == 2 || s == 3, XLAL_EINVAL );
159 XLAL_CHECK( fmin <= fmax, XLAL_EINVAL, "fmin greater than fmax: [%g, %g]", fmin, fmax );
160 XLAL_CHECK( nmin <= nmax, XLAL_EINVAL, "nmin greater than nmax: [%g, %g]", nmin, nmax );
161 XLAL_CHECK( kmin <= kmax, XLAL_EINVAL, "kmin greater than kmax: [%g, %g]", kmin, kmax );
162
163 PiecewiseBoundInfo XLAL_INIT_DECL( info_knot_lower );
164 PiecewiseBoundInfo XLAL_INIT_DECL( info_knot_upper );
165
166 info_knot_lower.s = info_knot_upper.s = s;
167
168 info_knot_lower.n = nmax;
169 info_knot_lower.k = kmax;
170
171 info_knot_upper.n = nmin;
172 info_knot_upper.k = kmin;
173
174 // Setting the first knot bounds
175 // - dt is not used
177 XLAL_CHECK( XLALSetLatticeTilingBound( tiling, 1, F1Bound, sizeof( info_knot_lower ), &info_knot_lower, &info_knot_upper ) == XLAL_SUCCESS, XLAL_EFAILED );
178
179 if ( s == 3 ) {
180 XLAL_CHECK( XLALSetLatticeTilingBound( tiling, 2, F2Bound, sizeof( info_knot_lower ), &info_knot_lower, &info_knot_upper ) == XLAL_SUCCESS, XLAL_EFAILED );
181 }
182
183 // Setting the bounds for all following knots
184 for ( size_t knot = 1; knot < knots->size; ++knot ) {
185 info_knot_lower.dt = info_knot_upper.dt = gsl_vector_get( knots, knot ) - gsl_vector_get( knots, knot - 1 );
186 size_t dimindex = s * knot;
187 XLAL_CHECK( XLALSetLatticeTilingBound( tiling, dimindex, F0Bound, sizeof( info_knot_lower ), &info_knot_lower, &info_knot_upper ) == XLAL_SUCCESS, XLAL_EFAILED );
188 XLAL_CHECK( XLALSetLatticeTilingBound( tiling, dimindex + 1, F1Bound, sizeof( info_knot_lower ), &info_knot_lower, &info_knot_upper ) == XLAL_SUCCESS, XLAL_EFAILED );
189 if ( s == 3 ) {
190 XLAL_CHECK( XLALSetLatticeTilingBound( tiling, dimindex + 2, F2Bound, sizeof( info_knot_lower ), &info_knot_lower, &info_knot_upper ) == XLAL_SUCCESS, XLAL_EFAILED );
191 }
192 }
193
194 // Disabling using extrema for parameter space bounds
195 /*
196 for ( size_t dim = 0; dim < s * knots->size; ++dim ) {
197 XLAL_CHECK( XLALSetLatticeTilingPadding( tiling, dim, -1, -1, -1, -1, false ) == XLAL_SUCCESS, XLAL_EFAILED );
198 }
199 */
200
201 for ( size_t dim = 0; dim < s * knots->size; ++dim ) {
202 XLAL_CHECK( XLALSetLatticeTilingPadding( tiling, dim, gsl_vector_get( bboxpad, dim ), gsl_vector_get( bboxpad, dim ), gsl_vector_int_get( intpad, dim ), gsl_vector_int_get( intpad, dim ), false ) == XLAL_SUCCESS, XLAL_EFAILED );
203 }
204
205 return XLAL_SUCCESS;
206}
int k
static double F1Bound(const void *data, const size_t dim UNUSED, const gsl_matrix *cache UNUSED, const gsl_vector *point)
Sets the bound on the first derivative frequency parameter.
static double GTEAndDerivs(double f0, double n, double k, double t, int d)
The general torque equation and its first two derivatives.
int XLALSetLatticeTilingPiecewiseBounds(LatticeTiling *tiling, const size_t s, const double fmin, const double fmax, const double nmin, const double nmax, const double kmin, const double kmax, const gsl_vector *knots, const gsl_vector *bboxpad, const gsl_vector_int *intpad)
Sets the bounds for the piecewise model.
static double F2Bound(const void *data, const size_t dim UNUSED, const gsl_matrix *cache UNUSED, const gsl_vector *point)
Sets the bounds on the second derivative frequency parameter.
static double F0Bound(const void *data, const size_t dim UNUSED, const gsl_matrix *cache UNUSED, const gsl_vector *point)
Sets the bound on the frequency parameter.
#define XLAL_INIT_DECL(var,...)
int XLALSetLatticeTilingBound(LatticeTiling *tiling, const size_t dim, const LatticeTilingBound func, const size_t data_len, const void *data_lower, const void *data_upper)
Set a parameter-space bound on a dimension of the lattice tiling.
int XLALSetLatticeTilingConstantBound(LatticeTiling *tiling, const size_t dim, const double bound1, const double bound2)
Set a constant lattice tiling parameter-space bound, given by the minimum and maximum of the two supp...
int XLALSetLatticeTilingPadding(LatticeTiling *tiling, const size_t dim, const double lower_bbox_pad, const double upper_bbox_pad, const int lower_intp_pad, const int upper_intp_pad, const int find_bound_extrema)
Control the padding of lattice tiling parameter-space bounds in the given dimension.
#define XLAL_CHECK(assertion,...)
XLAL_SUCCESS
XLAL_EINVAL
XLAL_EFAILED
float data[BLOCKSIZE]
Definition: hwinject.c:360
n
A struct containing the relevant information for calculating upper and lower bounds on a specific pie...
double n
Braking index.
double k
k value
double dt
Time between knots.
size_t s
Number of frequency/spindown parameters per knot.