26 #include <gsl/gsl_vector.h>
27 #include <gsl/gsl_matrix.h>
28 #include <gsl/gsl_blas.h>
29 #include <gsl/gsl_permutation.h>
30 #include <gsl/gsl_linalg.h>
32 #include <lal/ExtrapolatePulsarSpins.h>
34 #include <lal/FstatisticTools.h>
37 #define SQ(x) ( (x) * (x) )
38 #define MYSIGN(x) ( ((x) < 0) ? (-1.0):(+1.0) )
62 REAL8 A1h, A2h, A3h, A4h;
63 REAL8 Ad, Bd, Cd, Dd, Ed;
65 REAL8 A1check, A2check, A3check, A4check;
74 REAL8 cosphi0, sinphi0, cos2psi, sin2psi;
78 gsl_vector *x_mu, *A_Mu;
81 gsl_permutation *permh;
82 gsl_matrix *tmp, *tmp2;
88 "Fa = (%g, %g) is not finite", creal( Fa ), cimag( Fa ) );
90 "Fb = (%g, %g) is not finite", creal( Fb ), cimag( Fb ) );
97 Dd = Ad * Bd - Cd * Cd - Ed * Ed;
99 normAmu = 2.0 / sqrt( 2.0 * Mmunu->
Sinv_Tsft );
112 gsl_vector_set( x_mu, 0, creal( Fa ) );
113 gsl_vector_set( x_mu, 1, creal( Fb ) );
114 gsl_vector_set( x_mu, 2, - cimag( Fa ) );
115 gsl_vector_set( x_mu, 3, - cimag( Fb ) );
118 gsl_matrix_set( M_Mu_Nu, 0, 0, Bd / Dd );
119 gsl_matrix_set( M_Mu_Nu, 1, 1, Ad / Dd );
120 gsl_matrix_set( M_Mu_Nu, 0, 1, - Cd / Dd );
122 gsl_matrix_set( M_Mu_Nu, 0, 3, - Ed / Dd );
123 gsl_matrix_set( M_Mu_Nu, 1, 2, Ed / Dd );
125 gsl_matrix_set( M_Mu_Nu, 2, 2, Bd / Dd );
126 gsl_matrix_set( M_Mu_Nu, 3, 3, Ad / Dd );
127 gsl_matrix_set( M_Mu_Nu, 2, 3, - Cd / Dd );
142 A1h = gsl_vector_get( A_Mu, 0 );
143 A2h = gsl_vector_get( A_Mu, 1 );
144 A3h = gsl_vector_get( A_Mu, 2 );
145 A4h = gsl_vector_get( A_Mu, 3 );
147 Asq =
SQ( A1h ) +
SQ( A2h ) +
SQ( A3h ) +
SQ( A4h );
148 Da = A1h * A4h - A2h * A3h;
149 disc = sqrt(
SQ( Asq ) - 4.0 *
SQ( Da ) );
151 Ap2 = 0.5 * ( Asq + disc );
154 Ac2 = 0.5 * ( Asq - disc );
155 aCross = sqrt( Ac2 );
158 beta = aCross / aPlus;
160 b1 = A4h - beta * A1h;
161 b2 = A3h + beta * A2h;
162 b3 = - A1h + beta * A4h ;
164 psi = 0.5 * atan(
b1 /
b2 );
168 A1check = aPlus * cos(
phi0 ) * cos( 2.0 * psi ) - aCross * sin(
phi0 ) * sin( 2 * psi );
169 if ( A1check * A1h < 0 ) {
173 cosphi0 = cos(
phi0 );
174 sinphi0 = sin(
phi0 );
175 cos2psi = cos( 2 * psi );
176 sin2psi = sin( 2 * psi );
179 A1check = aPlus * cosphi0 * cos2psi - aCross * sinphi0 * sin2psi;
180 A2check = aPlus * cosphi0 * sin2psi + aCross * sinphi0 * cos2psi;
181 A3check = - aPlus * sinphi0 * cos2psi - aCross * cosphi0 * sin2psi;
182 A4check = - aPlus * sinphi0 * sin2psi + aCross * cosphi0 * cos2psi;
184 if ( ( fabs( ( A1check - A1h ) / A1h ) > tolerance ) ||
185 ( fabs( ( A2check - A2h ) / A2h ) > tolerance ) ||
186 ( fabs( ( A3check - A3h ) / A3h ) > tolerance ) ||
187 ( fabs( ( A4check - A4h ) / A4h ) > tolerance ) ) {
189 XLALPrintError(
"WARNING %s(): Difference between estimated and reconstructed Amu exceeds tolerance of %g\n",
201 gsl_matrix_set( Jh_Mu_nu, 0, 0, cosphi0 * cos2psi );
202 gsl_matrix_set( Jh_Mu_nu, 0, 1, - sinphi0 * sin2psi );
203 gsl_matrix_set( Jh_Mu_nu, 0, 2, A3h );
204 gsl_matrix_set( Jh_Mu_nu, 0, 3, - 2.0 * A2h );
207 gsl_matrix_set( Jh_Mu_nu, 1, 0, cosphi0 * sin2psi );
208 gsl_matrix_set( Jh_Mu_nu, 1, 1, sinphi0 * cos2psi );
209 gsl_matrix_set( Jh_Mu_nu, 1, 2, A4h );
210 gsl_matrix_set( Jh_Mu_nu, 1, 3, 2.0 * A1h );
213 gsl_matrix_set( Jh_Mu_nu, 2, 0, - sinphi0 * cos2psi );
214 gsl_matrix_set( Jh_Mu_nu, 2, 1, - cosphi0 * sin2psi );
215 gsl_matrix_set( Jh_Mu_nu, 2, 2, - A1h );
216 gsl_matrix_set( Jh_Mu_nu, 2, 3, - 2.0 * A4h );
219 gsl_matrix_set( Jh_Mu_nu, 3, 0, - sinphi0 * sin2psi );
220 gsl_matrix_set( Jh_Mu_nu, 3, 1, cosphi0 * cos2psi );
221 gsl_matrix_set( Jh_Mu_nu, 3, 2, - A2h );
222 gsl_matrix_set( Jh_Mu_nu, 3, 3, 2.0 * A3h );
230 gsl_matrix_memcpy( Jh_Mu_nu, tmp );
243 XLAL_CHECK( gsl_blas_dgemm( CblasNoTrans, CblasTrans, 1.0, M_Mu_Nu, Jh_Mu_nu, 0.0, tmp ) == 0,
XLAL_EERR );
245 XLAL_CHECK( gsl_blas_dgemm( CblasNoTrans, CblasNoTrans, 1.0, Jh_Mu_nu, tmp, 0.0, tmp2 ) == 0,
XLAL_EERR );
246 gsl_matrix_memcpy( Jh_Mu_nu, tmp2 );
255 pulsarParams->
Amp.
aPlus = normAmu * aPlus;
256 pulsarParams->
Amp.
aCross = normAmu * aCross;
258 pulsarParams->
Amp.
psi = psi;
261 pulsarParams->
dAmp.
aPlus = normAmu * sqrt( gsl_matrix_get( Jh_Mu_nu, 0, 0 ) );
262 pulsarParams->
dAmp.
aCross = normAmu * sqrt( gsl_matrix_get( Jh_Mu_nu, 1, 1 ) );
263 pulsarParams->
dAmp.
phi0 = sqrt( gsl_matrix_get( Jh_Mu_nu, 2, 2 ) );
264 pulsarParams->
dAmp.
psi = sqrt( gsl_matrix_get( Jh_Mu_nu, 3, 3 ) );
271 gsl_vector_free( x_mu );
272 gsl_vector_free( A_Mu );
273 gsl_matrix_free( M_Mu_Nu );
274 gsl_matrix_free( Jh_Mu_nu );
275 gsl_permutation_free( permh );
276 gsl_matrix_free( tmp2 );
295 REAL8 cos2psi = cos( 2.0 * Amp.
psi );
296 REAL8 sin2psi = sin( 2.0 * Amp.
psi );
302 A_Mu[0] = aPlus * cos2psi * cosphi0 - aCross * sin2psi * sinphi0;
303 A_Mu[1] = aPlus * sin2psi * cosphi0 + aCross * cos2psi * sinphi0;
304 A_Mu[2] = -aPlus * cos2psi * sinphi0 - aCross * sin2psi * cosphi0;
305 A_Mu[3] = -aPlus * sin2psi * sinphi0 + aCross * cos2psi * cosphi0;
321 REAL8 psiRet, phi0Ret;
323 REAL8 A1, A2, A3, A4, Asq, Da, disc;
324 REAL8 Ap2, Ac2, aPlus, aCross;
335 Asq =
SQ( A1 ) +
SQ( A2 ) +
SQ( A3 ) +
SQ( A4 );
336 Da = A1 * A4 - A2 * A3;
338 disc = sqrt(
SQ( Asq ) - 4.0 *
SQ( Da ) );
340 Ap2 = 0.5 * ( Asq + disc );
343 Ac2 = 0.5 * ( Asq - disc );
344 aCross =
MYSIGN( Da ) * sqrt( Ac2 );
346 beta = aCross / aPlus;
350 b3 = - A1 + beta * A4 ;
353 psiRet = 0.5 * atan2(
b1,
b2 );
354 phi0Ret = atan2(
b2, b3 );
357 REAL8 A1check = aPlus * cos( phi0Ret ) * cos( 2.0 * psiRet ) - aCross * sin( phi0Ret ) * sin( 2 * psiRet );
358 if ( A1check * A1 < 0 ) {
371 while ( phi0Ret < 0 ) {
406 REAL8 cos2psi = cos( 2.0 * pap.
psi );
407 REAL8 sin2psi = sin( 2.0 * pap.
psi );
408 REAL8 cos2psiSq =
SQ( cos2psi );
409 REAL8 sin2psiSq =
SQ( sin2psi );
#define __func__
log an I/O error, i.e.
REAL8 PulsarAmplitudeVect[4]
Struct for 'canonical' coordinates in amplitude-params space A^mu = {A1, A2, A3, A4}.
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
Struct holding the "antenna-pattern" matrix , in terms of the multi-detector scalar product.
REAL8 Sinv_Tsft
normalization-factor (using single-sided PSD!)
Type containing the JKS 'amplitude parameters' {h0, cosi, phi0, psi}.
REAL8 aCross
Signal amplitude (cross)
REAL8 psi
polarization angle psi
REAL8 aPlus
Signal amplitude (plus)
REAL8 phi0
initial signal-phase (at some reference time)
Type containing a "candidate": parameter-space point with estimated errors and Fstat-value/significan...
PulsarAmplitudeParams dAmp
amplitude-parameters and error-estimates
PulsarAmplitudeParams Amp
gsl_matrix * AmpFisherMatrix
Fisher-matrix of amplitude-subspace: has more info than dAmp!
PulsarDopplerParams Doppler
PulsarSpins fkdot
Intrinsic spins: [Freq, f1dot, f2dot, ...
LIGOTimeGPS refTime
Reference time of pulsar parameters (in SSB!)