24 #include <gsl/gsl_math.h>
25 #include <gsl/gsl_blas.h>
26 #include <gsl/gsl_linalg.h>
28 #include <lal/MetricUtils.h>
29 #include <lal/XLALError.h>
30 #include <lal/LogPrintf.h>
31 #include <lal/Factorial.h>
33 #include <lal/GSLHelpers.h>
36 #define POW2(a) ( (a) * (a) )
37 #define POW3(a) ( (a) * (a) * (a) )
38 #define POW4(a) ( (a) * (a) * (a) * (a) )
39 #define POW5(a) ( (a) * (a) * (a) * (a) * (a) )
53 const gsl_matrix *g1_ij,
54 const gsl_matrix *g2_ij
73 UINT4 dim = g1_ij->size1;
76 REAL8 norm = sqrt( gsl_matrix_get( g1_ij,
i,
i ) * gsl_matrix_get( g1_ij,
j,
j ) );
77 REAL8 e1 = gsl_matrix_get( g1_ij,
i,
j ) / norm;
78 REAL8 e2 = gsl_matrix_get( g2_ij,
i,
j ) / norm;
85 REAL8 reldiff = fabs( e1 - e2 ) / base;
87 errmax =
fmax( errmax, reldiff );
99 const gsl_matrix *g_ij
106 const size_t n = g_ij->size1;
109 gsl_matrix *GAMAT_REAL8( LU_decomp,
n,
n );
110 gsl_permutation *GAPERM_REAL8( LU_perm,
n );
113 gsl_matrix_memcpy( LU_decomp, g_ij );
118 const double determinant = gsl_linalg_LU_det( LU_decomp, LU_sign );
132 const gsl_matrix *g_ij,
133 const double max_mismatch
141 const size_t n = g_ij->size1;
144 gsl_matrix *GAMAT_NULL( LU_decomp,
n,
n );
145 gsl_permutation *GAPERM_NULL( LU_perm,
n );
146 gsl_matrix *GAMAT_NULL( diag_norm,
n,
n );
147 gsl_matrix *GAMAT_NULL( inverse,
n,
n );
148 gsl_vector *GAVEC_NULL( bounding_box,
n );
159 for (
size_t i = 0;
i <
n; ++
i ) {
160 const double diag_norm_i = gsl_matrix_get( diag_norm,
i,
i );
161 const double bounding_box_i = 2.0 * sqrt( max_mismatch * gsl_matrix_get( inverse,
i,
i ) ) * diag_norm_i;
162 gsl_vector_set( bounding_box,
i, bounding_box_i );
166 GFMAT( LU_decomp, diag_norm, inverse );
183 gsl_matrix **p_gpr_ij,
184 const gsl_matrix *g_ij,
193 if ( *p_gpr_ij != NULL ) {
197 GAMAT( *p_gpr_ij, g_ij->size1, g_ij->size2 );
202 gsl_matrix *GAMAT( ret_ij, g_ij->size1, g_ij->size2 );
205 for (
UINT4 i = 0;
i < g_ij->size1;
i++ ) {
206 for (
UINT4 j = 0;
j < g_ij->size2;
j++ ) {
207 if (
i ==
c ||
j ==
c ) {
208 gsl_matrix_set( ret_ij,
i,
j, 0.0 );
210 double proj = gsl_matrix_get( g_ij,
i,
j ) - ( gsl_matrix_get( g_ij,
i,
c ) * gsl_matrix_get( g_ij,
j,
c ) / gsl_matrix_get( g_ij,
c,
c ) );
211 gsl_matrix_set( ret_ij,
i,
j, proj );
216 gsl_matrix_memcpy( *p_gpr_ij, ret_ij );
232 gsl_matrix **p_cholesky,
233 const gsl_matrix *g_ij
242 if ( *p_cholesky != NULL ) {
246 GAMAT( *p_cholesky, g_ij->size1, g_ij->size2 );
250 gsl_matrix_set_zero( *p_cholesky );
251 #define A(i,j) *gsl_matrix_const_ptr( g_ij, i, j )
252 #define D(j) *gsl_matrix_ptr( *p_cholesky, j, j )
253 #define L(i,j) *gsl_matrix_ptr( *p_cholesky, i, j )
254 for (
size_t i = 0;
i < g_ij->size1; ++
i ) {
255 for (
size_t j = 0;
j <=
i; ++
j ) {
258 for (
size_t k = 0;
k <
j; ++
k ) {
263 for (
size_t k = 0;
k <
j; ++
k ) {
287 gsl_matrix **p_gpr_ij,
288 const gsl_matrix *transform,
289 const gsl_matrix *g_ij
299 if ( *p_gpr_ij != NULL ) {
303 GAMAT( *p_gpr_ij, transform->size2, transform->size2 );
307 gsl_matrix *tmp = gsl_matrix_alloc( g_ij->size1, transform->size2 );
311 gsl_blas_dgemm( CblasNoTrans, CblasNoTrans, 1.0, g_ij, transform, 0.0, tmp );
312 gsl_blas_dgemm( CblasTrans, CblasNoTrans, 1.0, transform, tmp, 0.0, *p_gpr_ij );
315 for (
size_t i = 0;
i < ( *p_gpr_ij )->size1; ++
i ) {
316 for (
size_t j =
i + 1;
j < ( *p_gpr_ij )->size2; ++
j ) {
317 const double gij = gsl_matrix_get( *p_gpr_ij,
i,
j );
318 const double gji = gsl_matrix_get( *p_gpr_ij,
j,
i );
319 const double g = 0.5 * ( gij + gji );
320 gsl_matrix_set( *p_gpr_ij,
i,
j, g );
321 gsl_matrix_set( *p_gpr_ij,
j,
i, g );
326 gsl_matrix_free( tmp );
342 gsl_matrix **p_gpr_ij,
343 const gsl_matrix *transform,
344 const gsl_matrix *g_ij
357 gsl_matrix *GAMAT( LU_decomp, transform->size1, transform->size2 );
358 gsl_permutation *GAPERM( LU_perm, transform->size1 );
359 gsl_matrix *GAMAT( inverse, transform->size1, transform->size2 );
363 gsl_matrix_memcpy( LU_decomp, transform );
364 XLAL_CHECK( gsl_linalg_LU_decomp( LU_decomp, LU_perm, &LU_sign ) == 0,
XLAL_EFAILED,
"'transform' cannot be LU-decomposed" );
365 XLAL_CHECK( gsl_linalg_LU_invert( LU_decomp, LU_perm, inverse ) == 0,
XLAL_EFAILED,
"'transform' cannot be inverted" );
371 GFMAT( LU_decomp, inverse );
392 gsl_matrix **p_gpr_ij,
393 gsl_matrix **p_transform,
394 const gsl_matrix *g_ij
401 if ( p_transform != NULL ) {
402 if ( *p_transform != NULL ) {
406 GAMAT( *p_transform, g_ij->size1, g_ij->size2 );
411 gsl_matrix *GAMAT( transform, g_ij->size1, g_ij->size2 );
412 gsl_matrix_set_zero( transform );
413 for (
size_t i = 0;
i < g_ij->size1; ++
i ) {
414 const double gii = gsl_matrix_get( g_ij,
i,
i );
415 XLAL_CHECK( gii > 0,
XLAL_EINVAL,
"Diagonal normalization not defined for non-positive diagonal elements! g_ii(%zu,%zu) = %g\n",
i,
i, gii );
416 gsl_matrix_set( transform,
i,
i, 1.0 / sqrt( gii ) );
420 if ( p_gpr_ij != NULL ) {
425 if ( p_transform != NULL ) {
426 gsl_matrix_memcpy( *p_transform, transform );
457 gsl_matrix **p_gpr_ij,
458 gsl_matrix **p_transform,
459 const gsl_matrix *g_ij,
467 if ( p_transform != NULL ) {
468 if ( *p_transform != NULL ) {
472 GAMAT( *p_transform, g_ij->size1, g_ij->size2 );
481 for (
UINT4 k = 0;
k < Nseg;
k ++ ) {
486 REAL8 avgTseg = sumTseg / Nseg;
489 gsl_matrix *GAMAT( transform, g_ij->size1, g_ij->size2 );
490 gsl_matrix_set_zero( transform );
491 for (
size_t i = 0;
i < g_ij->size1; ++
i ) {
494 const double T = avgTseg;
547 gsl_matrix_set( transform,
i,
i, 1.0 /
scale );
551 if ( p_gpr_ij != NULL ) {
556 if ( p_transform != NULL ) {
557 gsl_matrix_memcpy( *p_transform, transform );
579 gsl_matrix **p_gpr_ij,
580 gsl_matrix **p_transform,
581 const gsl_matrix *g_ij,
590 if ( p_transform != NULL ) {
591 if ( *p_transform != NULL ) {
595 GAMAT( *p_transform, g_ij->size1, g_ij->size2 );
600 for (
size_t i = 0;
i < coordSys->
dim; ++
i ) {
614 gsl_matrix *GAMAT( transform, g_ij->size1, g_ij->size2 );
615 gsl_matrix_set_identity( transform );
617 for (
size_t i = 0;
i < coordSys->
dim; ++
i ) {
622 for (
size_t j =
i + 1;
j < coordSys->
dim; ++
j ) {
627 if ( jspinorder > ispinorder ) {
628 const double tij =
LAL_FACT_INV[jspinorder - ispinorder] * pow( -1 * Dtau, jspinorder - ispinorder );
629 gsl_matrix_set( transform,
i,
j, tij );
640 if ( p_gpr_ij != NULL ) {
645 if ( p_transform != NULL ) {
646 gsl_matrix_memcpy( *p_transform, transform );
#define __func__
log an I/O error, i.e.
const double scale
multiplicative scaling factor of the coordinate
static const REAL8 LAL_FACT_INV[]
void void int XLALfprintfGSLmatrix(FILE *fp, const char *fmt, const gsl_matrix *gij) _LAL_GCC_VPRINTF_FORMAT_(2)
int XLALChangeMetricReferenceTime(gsl_matrix **p_gpr_ij, gsl_matrix **p_transform, const gsl_matrix *g_ij, const DopplerCoordinateSystem *coordSys, const double Dtau)
Compute the transform which changes the metric reference time .
int XLALProjectMetric(gsl_matrix **p_gpr_ij, const gsl_matrix *g_ij, const UINT4 c)
Calculate the projected metric onto the subspace orthogonal to coordinate-axis c, namely ,...
REAL8 XLALCompareMetrics(const gsl_matrix *g1_ij, const gsl_matrix *g2_ij)
Flexible comparison function between two metrics and .
int XLALCholeskyLDLTDecompMetric(gsl_matrix **p_cholesky, const gsl_matrix *g_ij)
Decompose a metric as , where is a lower-triangular matrix with unit diagonal, and is a diagonal ...
int XLALInverseTransformMetric(gsl_matrix **p_gpr_ij, const gsl_matrix *transform, const gsl_matrix *g_ij)
Apply the inverse of a transform to a metric such that , or equivalently .
int XLALDiagNormalizeMetric(gsl_matrix **p_gpr_ij, gsl_matrix **p_transform, const gsl_matrix *g_ij)
Diagonally-normalize a metric .
double XLALMetricDeterminant(const gsl_matrix *g_ij)
Compute the determinant of a metric .
int XLALTransformMetric(gsl_matrix **p_gpr_ij, const gsl_matrix *transform, const gsl_matrix *g_ij)
Apply a transform to a metric such that , or equivalently .
gsl_vector * XLALMetricEllipseBoundingBox(const gsl_matrix *g_ij, const double max_mismatch)
Compute the extent of the bounding box of the mismatch ellipse of a metric .
int XLALNaturalizeMetric(gsl_matrix **p_gpr_ij, gsl_matrix **p_transform, const gsl_matrix *g_ij, const DopplerMetricParams *metricParams)
Return a metric in naturalized coordinates.
int XLALSegListIsInitialized(const LALSegList *seglist)
DopplerCoordinateID
enum listing symbolic 'names' for all Doppler Coordinates supported by the metric codes in FstatMetri...
@ DOPPLERCOORD_N3SX_EQU
X spin-component of unconstrained super-sky position in equatorial coordinates [Units: none].
@ DOPPLERCOORD_N2X_ECL
X component of contrained sky position in ecliptic coordinates [Units: none].
@ DOPPLERCOORD_N3X_ECL
X component of unconstrained super-sky position in ecliptic coordinates [Units: none].
@ DOPPLERCOORD_N3X_EQU
X component of unconstrained super-sky position in equatorial coordinates [Units: none].
@ DOPPLERCOORD_N3OY_ECL
Y orbit-component of unconstrained super-sky position in ecliptic coordinates [Units: none].
@ DOPPLERCOORD_N3Z_EQU
Z component of unconstrained super-sky position in equatorial coordinates [Units: none].
@ DOPPLERCOORD_F2DOT
Second spindown [Units: Hz/s^2].
@ DOPPLERCOORD_N2X_EQU
X component of contrained sky position in equatorial coordinates [Units: none].
@ DOPPLERCOORD_DELTA
Declination [Units: radians].
@ DOPPLERCOORD_N2Y_ECL
Y component of contrained sky position in ecliptic coordinates [Units: none].
@ DOPPLERCOORD_GC_NU1
Global correlation first spindown [Units: Hz/s].
@ DOPPLERCOORD_GC_NU0
Global correlation frequency [Units: Hz].
@ DOPPLERCOORD_N3Y_EQU
Y component of unconstrained super-sky position in equatorial coordinates [Units: none].
@ DOPPLERCOORD_F1DOT
First spindown [Units: Hz/s].
@ DOPPLERCOORD_N2Y_EQU
Y component of contrained sky position in equatorial coordinates [Units: none].
@ DOPPLERCOORD_GC_NU2
Global correlation second spindown [Units: Hz/s^2].
@ DOPPLERCOORD_GC_NU3
Global correlation third spindown [Units: Hz/s^3].
@ DOPPLERCOORD_ALPHA
Right ascension [Units: radians].
@ DOPPLERCOORD_NONE
No Doppler component.
@ DOPPLERCOORD_N3Y_ECL
Y component of unconstrained super-sky position in ecliptic coordinates [Units: none].
@ DOPPLERCOORD_F3DOT
Third spindown [Units: Hz/s^3].
@ DOPPLERCOORD_N3OX_ECL
X orbit-component of unconstrained super-sky position in ecliptic coordinates [Units: none].
@ DOPPLERCOORD_N3Z_ECL
Z component of unconstrained super-sky position in ecliptic coordinates [Units: none].
@ DOPPLERCOORD_N3SY_EQU
Y spin-component of unconstrained super-sky position in equatorial coordinates [Units: none].
@ DOPPLERCOORD_FREQ
Frequency [Units: Hz].
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_REAL8(assertion,...)
#define XLAL_CHECK_NULL(assertion,...)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
type describing a Doppler coordinate system: lists the number of dimensions and the symbolic names of...
DopplerCoordinateID coordIDs[DOPPLERMETRIC_MAX_DIM]
coordinate 'names'
UINT4 dim
number of dimensions covered
meta-info specifying a Doppler-metric
MultiLALDetector multiIFO
detectors to compute metric for
PulsarParams signalParams
parameter-space point to compute metric for (doppler + amplitudes)
LALSegList segmentList
segment list: Nseg segments of the form (startGPS endGPS numSFTs)
DopplerCoordinateSystem coordSys
number of dimensions and coordinate-IDs of Doppler-metric
REAL8 vertexLatitudeRadians
LALDetector sites[PULSAR_MAX_DETECTORS]
array of site information
PulsarSpins fkdot
Intrinsic spins: [Freq, f1dot, f2dot, ...
PulsarDopplerParams Doppler
'Phase-evolution parameters': {skypos, fkdot, orbital params }