00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if 0
00021 <lalVerbatim file="LALInspiralComputePTFMetricCV">
00022 Author: Yi Pan, Duncan Brown
00023 $Id: LALInspiralComputePTFMetric.c,v 1.8 2008/08/12 04:56:16 dfazi Exp $
00024 </lalVerbatim>
00025
00026 <lalLaTeX>
00027 \subsection{Module \texttt{LALInspiralComputePTFMetric.c}}
00028
00029 Module to compute the components of the metric which is used to describe
00030 distances on Physical Template Family signal manifold.
00031
00032 \subsubsection*{Prototypes}
00033 \vspace{0.1in}
00034 \input{XLALInspiralComputePTFIntrinsicMetricCP}
00035 \idx{XLALInspiralComputePTFIntrinsicMetric()}
00036 \begin{itemize}
00037 \item \texttt{metric,} Output, the metric at the lattice point defined by \texttt{params}
00038 \item \texttt{psd,} Input, the power spectral density of the data
00039 \item \texttt{params,} Input, the parameters where metric must be computed
00040 in the computation of the metric.
00041 \end{itemize}
00042
00043 \input{XLALInspiralComputePTFFullMetricCP}
00044 \idx{XLALInspiralComputePTFFullMetric()}
00045 \begin{itemize}
00046 \item \texttt{metric,} Output, the metric at the lattice point defined by \texttt{params}
00047 \item \texttt{psd,} Input, the power spectral density of the data
00048 \item \texttt{params,} Input, the parameters where metric must be computed
00049 in the computation of the metric.
00050 \end{itemize}
00051
00052 \input{XLALInspiralComputePTFWaveformCP}
00053 \idx{XLALInspiralComputePTFWaveform()}
00054 \begin{itemize}
00055 \item \texttt{ptfwave,} Output, the waveform at the lattice point defined
00056 by \texttt{params}
00057 \item \texttt{params,} Input, the parameters where metric must be computed
00058 in the computation of the metric.
00059 \end{itemize}
00060
00061 \input{XLALInspiralComputePTFWDerivCP}
00062 \idx{XLALInspiralComputePTFWDeriv()}
00063 \begin{itemize}
00064 \item \texttt{Wderiv,} Output, the time derivative of waveform at the lattice
00065 point defined by \texttt{params}
00066 \item \texttt{psd,} Input, the power spectral density of the data
00067 \item \texttt{params,} Input, the parameters where metric must be computed
00068 in the computation of the metric
00069 \item \texttt{paramid,} Input, id of the parameter to take derivative on
00070 \item \texttt{initdelta,} Input, initial difference in parameters
00071 \item \texttt{tolerance,} Input, stop iteration when difference between two
00072 bisections is smaller than tolerance.
00073 \end{itemize}
00074
00075 \input{XLALInspiralComputePTFQDerivCP}
00076 \idx{XLALInspiralComputePTFQDeriv()}
00077 \begin{itemize}
00078 \item \texttt{Qderiv,} Output, the time derivative of Q at the lattice point
00079 defined by \texttt{params}
00080 \item \texttt{params,} Input, the parameters where metric must be computed
00081 in the computation of the metric.
00082 \end{itemize}
00083
00084 \subsubsection*{Description}
00085 We calculate the components of the metric using the procedure outlined
00086 by Yi.
00087
00088 \subsubsection*{Algorithm}
00089
00090 \subsubsection*{Uses}
00091
00092 \begin{verbatim}
00093 LALMalloc
00094 LALFree
00095 \end{verbatim}
00096
00097 \subsubsection*{Notes}
00098
00099 \vfill{\footnotesize\input{LALInspiralComputePTFMetricCV}}
00100
00101 </lalLaTeX>
00102 #endif
00103
00104 #include <stdlib.h>
00105 #include <lal/LALStdlib.h>
00106 #include <stdio.h>
00107 #include <lal/AVFactories.h>
00108 #include <lal/SeqFactories.h>
00109 #include <lal/LALInspiralBank.h>
00110 #include <lal/LALNoiseModels.h>
00111 #include <lal/MatrixUtils.h>
00112
00113
00114 INT4 XLALInspiralComputePTFIntrinsicMetric (
00115 InspiralMetric *metric,
00116 REAL8Vector *fullmetric,
00117 REAL8FrequencySeries *psd,
00118 InspiralTemplate *params
00119 )
00120
00121 {
00122
00123 INT4 errcode = XLAL_SUCCESS;
00124 static const char* func = "XLALInspiralComputePTFIntrinsticMetric";
00125
00126
00127 UINT4 N = 2 * (psd->data->length - 1);
00128 UINT4 i, j, k;
00129
00130
00131 REAL4 sqrtoftwo = sqrt(2.0);
00132 REAL4 onebysqrtoftwo = 1.0 / sqrtoftwo;
00133 REAL4 onebysqrtofsix = 1.0 / sqrt(6.0);
00134
00135
00136 REAL8 Theta = params->sourceTheta;
00137 REAL8 Phi = params->sourcePhi;
00138 REAL8 Psi = params->polarisationAngle;
00139 REAL8 phi0 = params->startPhase;
00140
00141
00142 REAL8 deltaT = params->tSampling;
00143 REAL8 deltaF = 1.0 / ((REAL8)N * deltaT);
00144
00145
00146 REAL8 P[5];
00147 REAL8 PdTh[5];
00148 REAL8 PdPh[5];
00149 REAL8 PdPs[5];
00150 REAL8Vector Q[5];
00151 COMPLEX16Vector Qtilde[5];
00152
00153 FILE *derivsfile;
00154
00155
00156
00157
00158
00159
00160 REAL8VectorSequence *PTFQ;
00161 COMPLEX16VectorSequence *PTFQtilde;
00162 REAL4Vector *PTFphi;
00163 REAL4Vector *PTFomega_2_3;
00164 REAL4VectorSequence *PTFe1;
00165 REAL4VectorSequence *PTFe2;
00166 REAL8FFTPlan *fwdPlan;
00167 REAL8FFTPlan *revPlan;
00168 COMPLEX16Vector *fsig0;
00169 COMPLEX16Vector *fsig1;
00170 COMPLEX16Vector *fsig;
00171 COMPLEX16Vector *intrinsicderiv;
00172 COMPLEX16VectorSequence *derivs;
00173 REAL8 initdelta = 0.001;
00174 REAL8 tolerance = 0.001;
00175 REAL8Vector *invpsd;
00176 REAL8Vector *tempnorm;
00177 COMPLEX16Vector *tempnormtilde;
00178 REAL8 wavenorm;
00179 REAL8Array *IntInt_matrix;
00180 REAL8Array *ExtExt_matrix;
00181 REAL8Array *ExtExt_inverse;
00182 REAL8Array *IntExt_matrix;
00183 REAL8Array *IntExt_transp;
00184 REAL8Array *matrix_5_x_4;
00185 REAL8Array *matrix_4_x_4;
00186 REAL8 *det;
00187 LALStatus status;
00188
00189 PTFQ = XLALCreateREAL8VectorSequence( 5, N );
00190 PTFQtilde = XLALCreateCOMPLEX16VectorSequence( 5, N / 2 + 1 );
00191 PTFphi = XLALCreateVector( N );
00192 PTFomega_2_3 = XLALCreateVector( N );
00193 PTFe1 = XLALCreateVectorSequence( 3, N );
00194 PTFe2 = XLALCreateVectorSequence( 3, N );
00195 fwdPlan = XLALCreateForwardREAL8FFTPlan( N, 0 );
00196 revPlan = XLALCreateReverseREAL8FFTPlan( N, 0 );
00197 IntInt_matrix = XLALCreateREAL8ArrayL ( 2, 4, 4 );
00198 ExtExt_matrix = XLALCreateREAL8ArrayL ( 2, 5, 5 );
00199 ExtExt_inverse = XLALCreateREAL8ArrayL ( 2, 5, 5 );
00200 IntExt_matrix = XLALCreateREAL8ArrayL ( 2, 4, 5 );
00201 IntExt_transp = XLALCreateREAL8ArrayL ( 2, 5, 4 );
00202 matrix_5_x_4 = XLALCreateREAL8ArrayL ( 2, 5, 4 );
00203 matrix_4_x_4 = XLALCreateREAL8ArrayL ( 2, 4, 4 );
00204
00205 det = NULL;
00206
00207 memset( &status, 0, sizeof(LALStatus) );
00208
00209
00210 errcode = XLALFindChirpPTFWaveform( PTFphi, PTFomega_2_3, PTFe1, PTFe2,
00211 params, deltaT);
00212
00213 if ( errcode != XLAL_SUCCESS ) XLAL_ERROR( func, errcode );
00214
00215
00216 for ( i = 0; i < 5; ++i )
00217 {
00218 Q[i].length = N;
00219 Qtilde[i].length = N / 2 + 1;
00220 Q[i].data = PTFQ->data + (i * N);
00221 Qtilde[i].data = PTFQtilde->data + (i * (N / 2 + 1)) ;
00222 }
00223
00224
00225 for ( j = 0; j < N; ++j )
00226 {
00227 REAL8 omega_2_3 = PTFomega_2_3->data[j];
00228 REAL8 phi = PTFphi->data[j];
00229 REAL8 e1x = PTFe1->data[j];
00230 REAL8 e1y = PTFe1->data[N + j];
00231 REAL8 e1z = PTFe1->data[2 * N + j];
00232 REAL8 e2x = PTFe2->data[j];
00233 REAL8 e2y = PTFe2->data[N + j];
00234 REAL8 e2z = PTFe2->data[2 * N + j];
00235
00236 Q[0].data[j] = omega_2_3 * onebysqrtoftwo * ( cos(2 * phi) * ( e1x * e1x +
00237 e2y * e2y - e2x * e2x - e1y * e1y ) + 2 * sin(2 * phi) *
00238 ( e1x * e2x - e1y * e2y ));
00239 Q[1].data[j] = omega_2_3 * sqrtoftwo * ( cos(2 * phi) * ( e1x * e1y -
00240 e2x * e2y ) + sin(2 * phi) * ( e1x * e2y + e1y * e2x ));
00241 Q[2].data[j] = omega_2_3 * sqrtoftwo * ( cos(2 * phi) * ( e1x * e1z -
00242 e2x * e2z ) + sin(2 * phi) * ( e1x * e2z + e1z * e2x ));
00243 Q[3].data[j] = omega_2_3 * sqrtoftwo * ( cos(2 * phi) * ( e1y * e1z -
00244 e2y * e2z ) + sin(2 * phi) * ( e1y * e2z + e1z * e2y ));
00245 Q[4].data[j] = omega_2_3 * onebysqrtofsix * ( cos(2 * phi) *
00246 ( 2 * e2z * e2z - 2 * e1z * e1z + e1x * e1x + e1y * e1y -
00247 e2x * e2x - e2y * e2y ) + 2 * sin(2 * phi) * ( e1x * e2x +
00248 e1y * e2y - 2 * e1z * e2z ));
00249 }
00250
00251
00252 for ( i = 0; i < 5; ++i )
00253 {
00254 XLALREAL8ForwardFFT( &Qtilde[i], &Q[i], fwdPlan);
00255 }
00256
00257
00258 P[0] = -(1 + cos(Theta) * cos(Theta)) * cos(2 * Phi) * cos(Psi)
00259 + 2 * cos(Theta) * sin(2 * Phi) * sin(Psi);
00260 P[1] = - 2 * cos(Theta) * cos(2 * Phi) * sin(Psi)
00261 -(1 + cos(Theta) * cos(Theta)) * sin(2 * Phi) * cos(Psi);
00262 P[2] = 2 * sin(Theta) * (-sin(Phi) * sin(Psi) + cos(Theta) * cos(Phi) * cos(Psi));
00263 P[3] = 2 * sin(Theta) * ( cos(Phi) * sin(Psi) + cos(Theta) * sin(Phi) * cos(Psi));
00264 P[4] = 3 * sin(Theta) * sin(Theta) * cos(Psi);
00265
00266
00267 PdTh[0] = -(1 - sin(2 * Theta)) * cos(2 * Phi) * cos(Psi)
00268 - 2 * sin(Theta) * sin(2 * Phi) * sin(Psi);
00269 PdTh[1] = 2 * sin(Theta) * cos(2 * Phi) * sin(Psi)
00270 -(1 - sin(2 * Theta)) * sin(2 * Phi) * cos(Psi);
00271 PdTh[2] = 2 * cos(Theta) * (-sin(Phi) * sin(Psi) - sin(Theta) * cos(Phi) * cos(Psi));
00272 PdTh[3] = 2 * cos(Theta) * ( cos(Phi) * sin(Psi) - sin(Theta) * sin(Phi) * cos(Psi));
00273 PdTh[4] = 3 * sin(2 * Theta) * cos(Psi);
00274
00275
00276 PdPh[0] = - 2 * (1 + cos(Theta) * cos(Theta)) * sin(2 * Phi) * cos(Psi)
00277 + 4 * cos(Theta) * cos(2 * Phi) * sin(Psi);
00278 PdPh[1] = 4 * cos(Theta) * sin(2 * Phi) * sin(Psi)
00279 - 2 * (1 + cos(Theta) * cos(Theta)) * cos(2 * Phi) * cos(Psi);
00280 PdPh[2] = 2 * sin(Theta) * (-cos(Phi) * sin(Psi) - cos(Theta) * sin(Phi) * cos(Psi));
00281 PdPh[3] = 2 * sin(Theta) * (-sin(Phi) * sin(Psi) + cos(Theta) * cos(Phi) * cos(Psi));
00282 PdPh[4] = 0;
00283
00284
00285 PdPs[0] = (1 + cos(Theta) * cos(Theta)) * cos(2 * Phi) * sin(Psi)
00286 + 2 * cos(Theta) * sin(2 * Phi) * cos(Psi);
00287 PdPs[1] = - 2 * cos(Theta) * cos(2 * Phi) * cos(Psi)
00288 + (1 + cos(Theta) * cos(Theta)) * sin(2 * Phi) * sin(Psi);
00289 PdPs[2] = 2 * sin(Theta) * (-sin(Phi) * cos(Psi) - cos(Theta) * cos(Phi) * sin(Psi));
00290 PdPs[3] = 2 * sin(Theta) * ( cos(Phi) * cos(Psi) - cos(Theta) * sin(Phi) * sin(Psi));
00291 PdPs[4] = - 3 * sin(Theta) * sin(Theta) * sin(Psi);
00292
00293
00294 fsig0 = XLALCreateCOMPLEX16Vector(N / 2 + 1);
00295 fsig1 = XLALCreateCOMPLEX16Vector(N / 2 + 1);
00296 fsig = XLALCreateCOMPLEX16Vector(N / 2 + 1);
00297
00298 for (k = 0; k < N / 2 + 1; ++k)
00299 {
00300 fsig0->data[k].re = 0.0;
00301 fsig0->data[k].im = 0.0;
00302 fsig1->data[k].re = 0.0;
00303 fsig1->data[k].im = 0.0;
00304 for (i = 0; i < 5; ++i)
00305 {
00306 fsig0->data[k].re += P[i] * Qtilde[i].data[k].re;
00307 fsig0->data[k].im += P[i] * Qtilde[i].data[k].im;
00308 }
00309 fsig1->data[k].re = fsig0->data[k].im;
00310 fsig1->data[k].im = - fsig0->data[k].re;
00311 }
00312 fsig1->data[0].re = fsig0->data[0].re;
00313 fsig1->data[0].im = fsig0->data[0].im;
00314 fsig1->data[N / 2].re = fsig0->data[N / 2].re;
00315 fsig1->data[N / 2].im = fsig0->data[N / 2].im;
00316 for (k = 0; k < N / 2 + 1; ++k)
00317 {
00318 fsig->data[k].re = cos(phi0) * fsig0->data[k].re + sin(phi0) * fsig1->data[k].re;
00319 fsig->data[k].im = cos(phi0) * fsig0->data[k].im + sin(phi0) * fsig1->data[k].im;
00320 }
00321
00322
00323 intrinsicderiv = XLALCreateCOMPLEX16Vector(N / 2 + 1);
00324 derivs = XLALCreateCOMPLEX16VectorSequence(9, N / 2 + 1);
00325
00326
00327 for (k = 0; k < N / 2 + 1; ++k)
00328 {
00329
00330 derivs->data[k].re = - LAL_TWOPI * deltaF * k * fsig->data[k].im;
00331 derivs->data[k].im = LAL_TWOPI * deltaF * k * fsig->data[k].re;
00332
00333 derivs->data[N / 2 + 1 + k].re = - sin(phi0) * fsig0->data[k].re + cos(phi0) * fsig1->data[k].re;
00334 derivs->data[N / 2 + 1 + k].im = - sin(phi0) * fsig0->data[k].im + cos(phi0) * fsig1->data[k].im;
00335
00336 derivs->data[N + 2 + k].re = 0.0;
00337 derivs->data[N + 2 + k].im = 0.0;
00338 for (i = 0; i < 5; ++i)
00339 {
00340 derivs->data[N + 2 + k].re += PdTh[i] * Qtilde[i].data[k].re;
00341 derivs->data[N + 2 + k].im += PdTh[i] * Qtilde[i].data[k].im;
00342 }
00343
00344 derivs->data[3 * N / 2 + 3 + k].re = 0.0;
00345 derivs->data[3 * N / 2 + 3 + k].im = 0.0;
00346 for (i = 0; i < 5; ++i)
00347 {
00348 derivs->data[3 * N / 2 + 3 + k].re += PdPh[i] * Qtilde[i].data[k].re;
00349 derivs->data[3 * N / 2 + 3 + k].im += PdPh[i] * Qtilde[i].data[k].im;
00350 }
00351
00352 derivs->data[2 * N + 4 + k].re = 0.0;
00353 derivs->data[2 * N + 4 + k].im = 0.0;
00354 for (i = 0; i < 5; ++i)
00355 {
00356 derivs->data[2 * N + 4 + k].re += PdPs[i] * Qtilde[i].data[k].re;
00357 derivs->data[2 * N + 4 + k].im += PdPs[i] * Qtilde[i].data[k].im;
00358 }
00359 }
00360
00361
00362 for (i = 5; i < 9; ++i)
00363 {
00364 errcode = XLALInspiralComputePTFWDeriv(intrinsicderiv, psd, params, i - 4, initdelta, tolerance);
00365 if ( errcode != XLAL_SUCCESS )
00366 {
00367 fprintf( stderr, "XLALInspiralComputePTFDeriv failed\n" );
00368 exit( 1 );
00369 }
00370 for (k = 0; k < N / 2 + 1; ++k)
00371 {
00372 derivs->data[i * (N / 2 + 1) + k].re = cos(phi0) * intrinsicderiv->data[k].re
00373 + sin(phi0) * intrinsicderiv->data[k].im;
00374 derivs->data[i * (N / 2 + 1) + k].im = cos(phi0) * intrinsicderiv->data[k].im
00375 - sin(phi0) * intrinsicderiv->data[k].re;
00376 }
00377 derivs->data[i * (N / 2 + 1)].re = (cos(phi0) + sin(phi0)) * intrinsicderiv->data[0].re;
00378 derivs->data[i * (N / 2 + 1)].im = (cos(phi0) + sin(phi0)) * intrinsicderiv->data[0].im;
00379 derivs->data[i * (N / 2 + 1) + N / 2].re = (cos(phi0) + sin(phi0)) * intrinsicderiv->data[N / 2].re;
00380 derivs->data[i * (N / 2 + 1) + N / 2].im = (cos(phi0) + sin(phi0)) * intrinsicderiv->data[N / 2].im;
00381 }
00382
00383
00384 derivsfile = fopen( "myderivs.dat", "w" );
00385
00386 if( derivsfile != NULL )
00387 {
00388 for (j = 0; j < N / 2 + 1; ++j)
00389 {
00390 fprintf( derivsfile, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
00391 derivs->data[j].re, derivs->data[j].im,
00392 derivs->data[(N / 2 + 1) + j].re, derivs->data[(N / 2 + 1) + j].im,
00393 derivs->data[2 * (N / 2 + 1) + j].re, derivs->data[2 * (N / 2 + 1) + j].im,
00394 derivs->data[3 * (N / 2 + 1) + j].re, derivs->data[3 * (N / 2 + 1) + j].im,
00395 derivs->data[4 * (N / 2 + 1) + j].re, derivs->data[4 * (N / 2 + 1) + j].im,
00396 derivs->data[5 * (N / 2 + 1) + j].re, derivs->data[5 * (N / 2 + 1) + j].im,
00397 derivs->data[6 * (N / 2 + 1) + j].re, derivs->data[6 * (N / 2 + 1) + j].im,
00398 derivs->data[7 * (N / 2 + 1) + j].re, derivs->data[7 * (N / 2 + 1) + j].im,
00399 derivs->data[8 * (N / 2 + 1) + j].re, derivs->data[8 * (N / 2 + 1) + j].im);
00400 }
00401 }
00402 fclose(derivsfile);
00403
00404
00405 invpsd = XLALCreateREAL8Vector(N / 2 + 1);
00406 tempnorm = XLALCreateREAL8Vector(N);
00407 tempnormtilde = XLALCreateCOMPLEX16Vector(N / 2 + 1);
00408
00409 for (k = 0; k < N / 2 + 1; ++k)
00410 {
00411 if (psd->data->data[k] == 0.)
00412 invpsd->data[k] = 0.;
00413 else
00414 invpsd->data[k] = 1.0 / psd->data->data[k];
00415 }
00416
00417 for (i = 0; i < 9; ++i)
00418 {
00419 for (j = 0; j < i + 1; ++j)
00420 {
00421 for (k = 0; k < N / 2 + 1; ++k)
00422 {
00423 tempnormtilde->data[k].re =
00424 ( derivs->data[i * (N/2+1) + k].re * derivs->data[j * (N/2+1) + k].re
00425 + derivs->data[i * (N/2+1) + k].im * derivs->data[j * (N/2+1) + k].im)
00426 * invpsd->data[k];
00427 tempnormtilde->data[k].im =
00428 ( derivs->data[i * (N/2+1) + k].im * derivs->data[j * (N/2+1) + k].re
00429 - derivs->data[i * (N/2+1) + k].re * derivs->data[j * (N/2+1) + k].im)
00430 * invpsd->data[k];
00431 }
00432
00433 XLALREAL8ReverseFFT(tempnorm, tempnormtilde, revPlan);
00434 fullmetric->data[i * (i + 1) / 2 + j] = 4.0 * tempnorm->data[0];
00435 }
00436 }
00437
00438 wavenorm = fullmetric->data[2];
00439 for (i = 0; i < 45; ++i)
00440 {
00441 fullmetric->data[i] /= wavenorm;
00442 }
00443
00444
00445 for (i = 0; i < 5; ++i)
00446 {
00447 for (j = 0; j < i + 1; ++j)
00448 {
00449 ExtExt_matrix->data[ 5 * i + j] = ExtExt_matrix->data[ 5 * j + i] =
00450 fullmetric->data[i * (i + 1) / 2 + j];
00451 }
00452 }
00453
00454
00455 LALDMatrixInverse( &status, det, ExtExt_matrix, ExtExt_inverse );
00456 if ( status.statusCode )
00457 {
00458 REPORTSTATUS( &status );
00459 exit( 1 );
00460 }
00461
00462
00463 for (i = 5; i < 9; ++i)
00464 {
00465 for (j = 5; j < i + 1; ++j)
00466 {
00467 IntInt_matrix->data[ 4 * (i-5) + j - 5] = IntInt_matrix->data[ 4 * (j-5) + i - 5]=
00468 fullmetric->data[i * (i + 1) / 2 + j];
00469 }
00470 }
00471
00472
00473 for (i = 5; i < 9; ++i)
00474 {
00475 for (j = 0; j < 5; ++j)
00476 {
00477 IntExt_matrix->data[ 5 * (i-5) + j] = fullmetric->data[i * (i + 1) / 2 + j];
00478 }
00479 }
00480
00481
00482 LALDMatrixTranspose ( &status, IntExt_transp, IntExt_matrix );
00483 if ( status.statusCode )
00484 {
00485 REPORTSTATUS( &status );
00486 exit( 1 );
00487 }
00488
00489 for (i = 0; i < 5; ++i)
00490 {
00491 for (j=0; j < 4; ++j)
00492 {
00493 IntExt_transp->data[ 4 * i + j] = IntExt_matrix->data[ j * 5 + i];
00494 }
00495 }
00496
00497
00498
00499 LALDMatrixMultiply ( &status, matrix_5_x_4, ExtExt_inverse, IntExt_transp );
00500 if ( status.statusCode )
00501 {
00502 REPORTSTATUS( &status );
00503 exit( 1 );
00504 }
00505
00506 LALDMatrixMultiply ( &status, matrix_4_x_4, IntExt_matrix, matrix_5_x_4 );
00507 if ( status.statusCode )
00508 {
00509 REPORTSTATUS( &status );
00510 exit( 1 );
00511 }
00512
00513 for ( i = 0; i < 4; ++i )
00514 {
00515 for ( j = 0; j < i + 1; ++j )
00516 {
00517 params->Gamma[i * (i + 1) / 2 + j] = metric->Gamma[i * (i + 1) / 2 + j] =
00518 IntInt_matrix->data[i * 4 + j] - matrix_4_x_4->data[i * 4 + j];
00519 }
00520 }
00521
00522
00523 XLALDestroyCOMPLEX16Vector(fsig0);
00524 XLALDestroyCOMPLEX16Vector(fsig1);
00525 XLALDestroyCOMPLEX16Vector(fsig);
00526 XLALDestroyCOMPLEX16Vector(intrinsicderiv);
00527 XLALDestroyCOMPLEX16VectorSequence(derivs);
00528 XLALDestroyCOMPLEX16Vector(tempnormtilde);
00529 XLALDestroyREAL8Vector(tempnorm);
00530 XLALDestroyREAL8VectorSequence( PTFQ );
00531 XLALDestroyCOMPLEX16VectorSequence( PTFQtilde );
00532 XLALDestroyVector( PTFphi );
00533 XLALDestroyVector( PTFomega_2_3 );
00534 XLALDestroyVectorSequence( PTFe1 );
00535 XLALDestroyVectorSequence( PTFe2 );
00536 XLALDestroyREAL8FFTPlan( fwdPlan );
00537 XLALDestroyREAL8FFTPlan( revPlan );
00538 XLALDestroyREAL8Array( IntInt_matrix );
00539 XLALDestroyREAL8Array( ExtExt_matrix );
00540 XLALDestroyREAL8Array( IntExt_matrix );
00541 XLALDestroyREAL8Array( IntExt_transp );
00542 XLALDestroyREAL8Array( ExtExt_inverse );
00543 XLALDestroyREAL8Array( matrix_5_x_4 );
00544 XLALDestroyREAL8Array( matrix_4_x_4 );
00545
00546
00547 return errcode;
00548 }
00549
00550
00551 INT4 XLALInspiralComputePTFFullMetric (
00552 InspiralMetric *metric,
00553 REAL8FrequencySeries *psd,
00554 InspiralTemplate *params
00555 )
00556
00557 {
00558 return XLAL_SUCCESS;
00559 }
00560
00561
00562
00563 INT4 XLALInspiralComputePTFWaveform (
00564 REAL8Vector *ptfwave,
00565 InspiralTemplate *params
00566 )
00567
00568 {
00569
00570 INT4 errcode = XLAL_SUCCESS;
00571 static const char* func = "XLALInspiralComputePTFWaveform";
00572
00573
00574 UINT4 N = ptfwave->length;
00575 UINT4 i, j;
00576
00577
00578 REAL8 sqrtoftwo = sqrt(2.0);
00579 REAL8 onebysqrtoftwo = 1.0 / sqrtoftwo;
00580 REAL8 onebysqrtofsix = 1.0 / sqrt(6.0);
00581
00582
00583 REAL8 Theta = params->sourceTheta;
00584 REAL8 Phi = params->sourcePhi;
00585 REAL8 Psi = params->polarisationAngle;
00586 REAL8 phi0 = params->startPhase;
00587
00588
00589 REAL8 deltaT = params->tSampling;
00590
00591
00592 REAL8 P[5];
00593
00594 REAL8Vector Q[5];
00595 REAL8Vector Qp[5];
00596
00597
00598
00599
00600
00601
00602
00603 REAL8VectorSequence *PTFQ;
00604 REAL8VectorSequence *PTFQp;
00605 REAL4Vector *PTFphi;
00606 REAL4Vector *PTFomega_2_3;
00607 REAL4VectorSequence *PTFe1;
00608 REAL4VectorSequence *PTFe2;
00609 REAL8FFTPlan *fwdPlan;
00610
00611 PTFQ = XLALCreateREAL8VectorSequence( 5, N );
00612 PTFQp = XLALCreateREAL8VectorSequence( 5, N );
00613 PTFphi = XLALCreateREAL4Vector( N );
00614 PTFomega_2_3 = XLALCreateREAL4Vector( N );
00615 PTFe1 = XLALCreateREAL4VectorSequence( 3, N );
00616 PTFe2 = XLALCreateREAL4VectorSequence( 3, N );
00617 fwdPlan = XLALCreateForwardREAL8FFTPlan( N, 0 );
00618
00619
00620 errcode = XLALFindChirpPTFWaveform( PTFphi, PTFomega_2_3, PTFe1, PTFe2,
00621 params, deltaT);
00622
00623 if ( errcode != XLAL_SUCCESS ) XLAL_ERROR( func, errcode );
00624
00625
00626 for ( i = 0; i < 5; ++i )
00627 {
00628 Q[i].length = N;
00629 Qp[i].length = N;
00630 Q[i].data = PTFQ->data + (i * N);
00631 Qp[i].data = PTFQp->data + (i * N);
00632 }
00633
00634
00635 for ( j = 0; j < N; ++j )
00636 {
00637 REAL8 omega_2_3 = PTFomega_2_3->data[j];
00638 REAL8 phi = PTFphi->data[j];
00639 REAL8 e1x = PTFe1->data[j];
00640 REAL8 e1y = PTFe1->data[N + j];
00641 REAL8 e1z = PTFe1->data[2 * N + j];
00642 REAL8 e2x = PTFe2->data[j];
00643 REAL8 e2y = PTFe2->data[N + j];
00644 REAL8 e2z = PTFe2->data[2 * N + j];
00645
00646 Q[0].data[j] = omega_2_3 * onebysqrtoftwo * ( cos(2 * phi) * ( e1x * e1x +
00647 e2y * e2y - e2x * e2x - e1y * e1y ) + 2 * sin(2 * phi) *
00648 ( e1x * e2x - e1y * e2y ));
00649 Q[1].data[j] = omega_2_3 * sqrtoftwo * ( cos(2 * phi) * ( e1x * e1y -
00650 e2x * e2y ) + sin(2 * phi) * ( e1x * e2y + e1y * e2x ));
00651 Q[2].data[j] = omega_2_3 * sqrtoftwo * ( cos(2 * phi) * ( e1x * e1z -
00652 e2x * e2z ) + sin(2 * phi) * ( e1x * e2z + e1z * e2x ));
00653 Q[3].data[j] = omega_2_3 * sqrtoftwo * ( cos(2 * phi) * ( e1y * e1z -
00654 e2y * e2z ) + sin(2 * phi) * ( e1y * e2z + e1z * e2y ));
00655 Q[4].data[j] = omega_2_3 * onebysqrtofsix * ( cos(2 * phi) *
00656 ( 2 * e2z * e2z - 2 * e1z * e1z + e1x * e1x + e1y * e1y -
00657 e2x * e2x - e2y * e2y ) + 2 * sin(2 * phi) * ( e1x * e2x +
00658 e1y * e2y - 2 * e1z * e2z ));
00659
00660 Qp[0].data[j] = omega_2_3 * onebysqrtoftwo * ( - sin(2 * phi) * ( e1x * e1x +
00661 e2y * e2y - e2x * e2x - e1y * e1y ) + 2 * cos(2 * phi) *
00662 ( e1x * e2x - e1y * e2y ));
00663 Qp[1].data[j] = omega_2_3 * sqrtoftwo * ( - sin(2 * phi) * ( e1x * e1y -
00664 e2x * e2y ) + cos(2 * phi) * ( e1x * e2y + e1y * e2x ));
00665 Qp[2].data[j] = omega_2_3 * sqrtoftwo * ( - sin(2 * phi) * ( e1x * e1z -
00666 e2x * e2z ) + cos(2 * phi) * ( e1x * e2z + e1z * e2x ));
00667 Qp[3].data[j] = omega_2_3 * sqrtoftwo * ( - sin(2 * phi) * ( e1y * e1z -
00668 e2y * e2z ) + cos(2 * phi) * ( e1y * e2z + e1z * e2y ));
00669 Qp[4].data[j] = omega_2_3 * onebysqrtofsix * ( - sin(2 * phi) *
00670 ( 2 * e2z * e2z - 2 * e1z * e1z + e1x * e1x + e1y * e1y -
00671 e2x * e2x - e2y * e2y ) + 2 * cos(2 * phi) * ( e1x * e2x +
00672 e1y * e2y - 2 * e1z * e2z ));
00673 }
00674
00675
00676 P[0] = -(1 + cos(Theta) * cos(Theta)) * cos(2 * Phi) * cos(Psi)
00677 + 2 * cos(Theta) * sin(2 * Phi) * sin(Psi);
00678 P[1] = - 2 * cos(Theta) * cos(2 * Phi) * sin(Psi)
00679 -(1 + cos(Theta) * cos(Theta)) * sin(2 * Phi) * cos(Psi);
00680 P[2] = 2 * sin(Theta) * (-sin(Phi) * sin(Psi) + cos(Theta) * cos(Phi) * cos(Psi));
00681 P[3] = 2 * sin(Theta) * ( cos(Phi) * sin(Psi) + cos(Theta) * sin(Phi) * cos(Psi));
00682 P[4] = 3 * sin(Theta) * sin(Theta) * cos(Psi);
00683
00684
00685
00686 for ( j = 0; j < N; ++j )
00687 {
00688 ptfwave->data[j] = P[0] * ( Q[0].data[j] * cos(phi0) + Qp[0].data[j] * sin(phi0) )
00689 + P[1] * ( Q[1].data[j] * cos(phi0) + Qp[1].data[j] * sin(phi0) )
00690 + P[2] * ( Q[2].data[j] * cos(phi0) + Qp[2].data[j] * sin(phi0) )
00691 + P[3] * ( Q[3].data[j] * cos(phi0) + Qp[3].data[j] * sin(phi0) )
00692 + P[4] * ( Q[4].data[j] * cos(phi0) + Qp[4].data[j] * sin(phi0) );
00693 }
00694
00695
00696 XLALDestroyREAL8VectorSequence( PTFQ );
00697 XLALDestroyREAL8VectorSequence( PTFQp );
00698 XLALDestroyREAL4Vector( PTFphi );
00699 XLALDestroyREAL4Vector( PTFomega_2_3 );
00700 XLALDestroyREAL4VectorSequence( PTFe1 );
00701 XLALDestroyREAL4VectorSequence( PTFe2 );
00702 XLALDestroyREAL8FFTPlan( fwdPlan );
00703
00704
00705 return XLAL_SUCCESS;
00706
00707 }
00708
00709
00710 INT4 XLALInspiralComputePTFWDeriv (
00711 COMPLEX16Vector *Wderiv,
00712 REAL8FrequencySeries *psd,
00713 InspiralTemplate *params,
00714 INT4 paramid,
00715 REAL8 initdelta,
00716 REAL8 tolerance
00717 )
00718
00719 {
00720
00721 INT4 errcode = XLAL_SUCCESS;
00722 static const char* func = "XLALInspiralComputePTFWDeriv";
00723
00724
00725 UINT4 N = (Wderiv->length - 1) * 2;
00726 UINT4 j, k;
00727
00728
00729 REAL8 totalMass = params->totalMass;
00730 REAL8 eta = params->eta;
00731 REAL8 chi = params->chi;
00732 REAL8 kappa = params->kappa;
00733
00734
00735 REAL8 deltaT = params->tSampling;
00736
00737
00738 InspiralTemplate pparams = *params;
00739 InspiralTemplate mparams = *params;
00740
00741
00742 UINT4 clen, plen, mlen;
00743 INT4 dlen;
00744
00745
00746
00747 REAL8Vector *cwave;
00748 REAL8Vector *pwavenew;
00749 REAL8Vector *mwavenew;
00750 REAL8Vector *pwaveold;
00751 REAL8Vector *mwaveold;
00752 REAL8Vector *pwaveold2;
00753 REAL8Vector *mwaveold2;
00754 REAL8Vector *wavederivnew;
00755 REAL8Vector *wavederivold;
00756 REAL8Vector *wavederivdiff;
00757 REAL8Vector *wavederiv_2;
00758 REAL8Vector *wavederivdiff_2;
00759 COMPLEX16Vector *derivtilde;
00760 COMPLEX16Vector *derivdifftilde;
00761 COMPLEX16Vector *derivpowertilde;
00762 COMPLEX16Vector *derivdiffpowertilde;
00763 REAL8FFTPlan *fwdPlan;
00764 REAL8FFTPlan *revPlan;
00765 UINT4 iter = 1;
00766 UINT4 maxiter = 20;
00767 REAL8 reldelta = initdelta;
00768 REAL8 absdelta;
00769 REAL8 relderivdiff = 1.0;
00770 REAL8 relderivdifflist[20];
00771 REAL8 invpsd;
00772 REAL8 powerderiv;
00773 REAL8 powerderivdiff;
00774
00775 LALStatus status;
00776 memset( &status, 0, sizeof(LALStatus) );
00777 pparams.massChoice = totalMassAndEta;
00778 mparams.massChoice = totalMassAndEta;
00779
00780 cwave = XLALCreateREAL8Vector( N );
00781 pwavenew = XLALCreateREAL8Vector( N );
00782 mwavenew = XLALCreateREAL8Vector( N );
00783 pwaveold = XLALCreateREAL8Vector( N );
00784 mwaveold = XLALCreateREAL8Vector( N );
00785 pwaveold2 = XLALCreateREAL8Vector( N );
00786 mwaveold2 = XLALCreateREAL8Vector( N );
00787 wavederivnew = XLALCreateREAL8Vector( N );
00788 wavederivold = XLALCreateREAL8Vector( N );
00789 wavederivdiff = XLALCreateREAL8Vector( N );
00790 wavederiv_2 = XLALCreateREAL8Vector( N );
00791 wavederivdiff_2 = XLALCreateREAL8Vector( N );
00792 derivtilde = XLALCreateCOMPLEX16Vector( N / 2 + 1 );
00793 derivdifftilde = XLALCreateCOMPLEX16Vector( N / 2 + 1 );
00794 derivpowertilde = XLALCreateCOMPLEX16Vector( N / 2 + 1 );
00795 derivdiffpowertilde = XLALCreateCOMPLEX16Vector( N / 2 + 1 );
00796 fwdPlan = XLALCreateForwardREAL8FFTPlan( N, 0 );
00797 revPlan = XLALCreateReverseREAL8FFTPlan( N, 0 );
00798
00799
00800
00801
00802 errcode = XLALInspiralComputePTFWaveform(cwave, params);
00803 if ( errcode != XLAL_SUCCESS )
00804 {
00805 fprintf( stderr, "XLALInspiralComputePTFWaveform failed\n" );
00806 exit( 1 );
00807 }
00808 clen = params->tC / deltaT + 0.5;
00809
00810
00811 while (relderivdiff > tolerance && iter < maxiter + 1)
00812 {
00813 switch (paramid)
00814 {
00815 case 1:
00816 absdelta = totalMass * reldelta;
00817 pparams.totalMass = totalMass + absdelta;
00818 mparams.totalMass = totalMass - absdelta;
00819 break;
00820 case 2:
00821 absdelta = params->eta * reldelta;
00822 pparams.eta = eta + absdelta;
00823 mparams.eta = eta - absdelta;
00824 break;
00825 case 3:
00826 absdelta = reldelta;
00827 pparams.chi = chi + absdelta;
00828 mparams.chi = chi - absdelta;
00829 break;
00830 case 4:
00831 absdelta = reldelta;
00832 pparams.kappa = kappa + absdelta;
00833 mparams.kappa = kappa - absdelta;
00834 break;
00835 default:
00836 fprintf( stdout, "XLALInspiralComputePTFWDeriv failed\n" );
00837