RefInterference.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Jolien Creighton
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /*----------------------------------------------------------------------- 
00021  * 
00022  * File Name: RefInterference.c
00023  * 
00024  * Author: Sintes, A. M.
00025  * 
00026  * Revision: $Id: RefInterference.c,v 1.4 2007/06/08 14:41:43 bema Exp $
00027  * 
00028  *----------------------------------------------------------------------- 
00029  * 
00030  * NAME 
00031  *  RefInterference.c
00032  * 
00033  * SYNOPSIS 
00034  *
00035  *
00036  * DESCRIPTION 
00037  * Generates the reference interference signal.
00038  * 
00039  * DIAGNOSTICS 
00040  *
00041  * CALLS
00042  * 
00043  * NOTES
00044  * 
00045  * 
00046  *
00047  *-----------------------------------------------------------------------
00048  */
00049 
00050 
00051 /************************************ <lalVerbatim file="RefInterferenceCV">
00052 Author: Sintes, A. M. 
00053 $Id: RefInterference.c,v 1.4 2007/06/08 14:41:43 bema Exp $
00054 ************************************* </lalVerbatim> */
00055 
00056 
00057 /* <lalLaTeX>
00058 
00059 \subsection{Module \texttt{RefInterference.c}}
00060 \label{ss:RefInterference.c}
00061 Generates a reference interference signal.
00062 
00063 
00064 \subsubsection*{Prototypes}
00065 \vspace{0.1in}
00066 \input{RefInterferenceD}
00067 \idx{LALRefInterference()}
00068 
00069 \subsubsection*{Description}
00070 Given the complex vector  \verb@*in1@ of length $n/2+1$, containing
00071 the Fourier transform of the data $\tilde x(\nu)$,
00072 \begin{description}
00073 \item[\texttt{in1->length}] The number of elements in 
00074             \texttt{in1->data} $=n/2+1$.
00075 \item[\texttt{in1->data}]   The data $\tilde x(\nu)$,
00076 \end{description}
00077  and given another vector \verb@*par@ containing the  information related 
00078 to the harmonics from which we want to construct the reference signal 
00079 (i.e., indices, and  initial and final frequency bin locations),
00080 \begin{description}
00081 \item[\texttt{par->length}] The number of elements in \texttt{par->data}.
00082        This is equal to three times the number of harmonics that will be 
00083         used to construct the reference signal $M(t)$.
00084 \item[\texttt{par->data}]    $\{ k,\nu_{ik}, \nu_{fk} \} $,
00085       e.g.,  $\{$3, 9868, 9894, 5, 16449, 16487, 9, 29607, 29675$\ldots\}$,
00086 \end{description}
00087 it  generates the time domain
00088 $M(t)$ reference interference signal, \verb@*out@. This is a complex 
00089 vector of length $n$.
00090 \begin{description}
00091 \item[\texttt{out->length}] The number of elements in 
00092             \texttt{out->data} $=n$.
00093 \item[\texttt{out->data}]   $M(t)$ complex data.
00094 \end{description}
00095 $M(t)$ corresponds to a nearly monochromatic function near the 
00096 frequency  $f_0$, that is implicit in the information 
00097 given in \verb@*par@.
00098 
00099 \subsubsection*{Algorithm}
00100 Described before.
00101 
00102 \subsubsection*{Uses}
00103 \begin{verbatim}
00104 LALSCreateVector()
00105 LALCCreateVector()
00106 LALZCreateVector()
00107 LALCreateReverseComplexFFTPlan()
00108 LALCOMPLEX8VectorFFT()
00109 LALSDestroyVector()
00110 LALCDestroyVector()
00111 LALZDestroyVector()
00112 LALDestroyComplexFFTPlan()
00113 \end{verbatim}
00114 
00115 \subsubsection*{Notes}
00116 
00117 The harmonics selected to construct the reference signal
00118 should not be (if possible) buried with other strong lines,
00119  such as violin modes. Choose the strongest harmonics, those
00120 that clearly stand over the noise level.
00121 
00122 \vfill{\footnotesize\input{RefInterferenceCV}}
00123 
00124 </lalLaTeX> */
00125 
00126 
00127 #include <lal/CLR.h>
00128 
00129 
00130 NRCSID (REFINTERFERENCEC, "$Id: RefInterference.c,v 1.4 2007/06/08 14:41:43 bema Exp $");
00131 
00132 /* <lalVerbatim file="RefInterferenceD"> */
00133 void LALRefInterference (LALStatus    *status,
00134                    COMPLEX8Vector     *out,   /*  M(t), size n */
00135                    COMPLEX8Vector     *in1,   /*  x(f), size n/2+1 */
00136                    INT4Vector         *par)
00137 { /* </lalVerbatim> */
00138 
00139   INT4    i,j;
00140   INT4    n;
00141   INT4    l;
00142   INT4    k,binini,binfin;
00143 
00144 /* increased precision */
00145 
00146   REAL4      px;
00147   REAL8      mod2,ampB,phB,inv2k,invk,invN;
00148   REAL8      /*cumsum,*/phaseI,phaseII,diffph;
00149   REAL8      dr,di,br,bi;
00150 
00151   COMPLEX16  lambda,lambdan;
00152   REAL8      lambdad;
00153 /*-----------------------------------*/
00154   INT8       countPI;
00155 
00156   COMPLEX8   *x;
00157   COMPLEX8   *m;
00158 
00159   INT4    *harmo;
00160 
00161   COMPLEX8Vector  *zf  = NULL; 
00162   COMPLEX8Vector  *zt  = NULL; 
00163   COMPLEX16Vector  *b1t = NULL; 
00164   COMPLEX16Vector  *bt  = NULL; 
00165 
00166   REAL4Vector   *invarb = NULL;      
00167   COMPLEX8Vector  *snum = NULL;
00168   REAL4Vector     *sden = NULL;      
00169 
00170   ComplexFFTPlan  *pinv = NULL;
00171 /* --------------------------------------------- */
00172 
00173   INITSTATUS (status, "LALRefInterference", REFINTERFERENCEC);
00174   ATTATCHSTATUSPTR (status);
00175   
00176 
00177   /*   Make sure the arguments are not NULL: */ 
00178   ASSERT (out, status, CLRH_ENULL, CLRH_MSGENULL);
00179   ASSERT (in1 , status, CLRH_ENULL, CLRH_MSGENULL);
00180   ASSERT (par, status, CLRH_ENULL, CLRH_MSGENULL);
00181 
00182   /*   Make sure the data pointers are not NULL: */ 
00183   ASSERT (out->data, status, CLRH_ENULL, CLRH_MSGENULL);
00184   ASSERT (in1->data, status, CLRH_ENULL, CLRH_MSGENULL);
00185   ASSERT (par->data, status, CLRH_ENULL, CLRH_MSGENULL);
00186 
00187   /*   Make sure that the size is correct:  */
00188   ASSERT (out->length > 0, status, CLRH_ESIZE, CLRH_MSGESIZE);
00189   ASSERT (par->length > 0, status, CLRH_ESIZE, CLRH_MSGESIZE);
00190 
00191   /*   Make sure that the parameter length is a multiple of 3:  */
00192   ASSERT (par->length%3 == 0, status, CLRH_ESIZE, CLRH_MSGESIZE);
00193 
00194   /*   Make sure that the lengths are correct (size mismatch): */  
00195   ASSERT (in1->length == (out->length)/2+1, status, CLRH_ESZMM, CLRH_MSGESZMM);
00196   /* -------------------------------------------   */
00197  
00198   n = out->length;
00199   invN = 1.0/n;
00200   m = out->data;
00201   x = in1->data;
00202   l = (par->length)/3;
00203   harmo = par->data;
00204   /* -------------------------------------------   */
00205  
00206   /* Create Vectors and fft plan */
00207   TRY(LALSCreateVector(status->statusPtr, &sden  ,n), status);
00208   TRY(LALSCreateVector(status->statusPtr, &invarb,n), status);
00209 
00210   TRY(LALCCreateVector(status->statusPtr, &zf, n), status);
00211   TRY(LALCCreateVector(status->statusPtr, &zt, n), status);
00212   
00213   TRY(LALZCreateVector(status->statusPtr, &bt, n), status);
00214   TRY(LALZCreateVector(status->statusPtr, &b1t,  n), status);
00215   
00216   TRY(LALCCreateVector(status->statusPtr, &snum, n), status);
00217   
00218   TRY(LALCreateReverseComplexFFTPlan(status->statusPtr, &pinv, n, 0), status);
00219   /* -------------------------------------------   */
00220  
00221   /* -------------------------------------------   */
00222   /* ------ For the 1st harmonic considered ----   */
00223   /* -------------------------------------------   */
00224  
00225   k = *harmo;
00226   ++harmo;
00227   binini =  *harmo;
00228   ++harmo;
00229   binfin =  *harmo;
00230 
00231   /*   Make sure that the frequency interval is correct:  */
00232   ASSERT (binini < binfin, status, CLRH_EINT, CLRH_MSGEINT);
00233   ASSERT (0< binini, status, CLRH_EINT, CLRH_MSGEINT);
00234   ASSERT (binfin < (n/2)+1, status, CLRH_EINT, CLRH_MSGEINT);
00235   
00236   /* Calculate px */
00237 
00238   px= 0.0;
00239 
00240   for (i=10; i > 0; --i) {
00241     px += x[binini-i].re*x[binini-i].re + x[binini-i].im*x[binini-i].im;
00242   }
00243   for (i=1; i < 11; ++i) {
00244     px += x[binfin+i].re*x[binfin+i].re + x[binfin+i].im*x[binfin+i].im;
00245   }
00246 
00247   px = px *(binfin-binini);        /* proportional to the width */
00248 
00249   /* Build z_k(nu) */
00250   for (i=0; i< binini; ++i) {
00251     zf->data[i].re = 0.0;
00252     zf->data[i].im = 0.0;
00253   }
00254   for (i=binini; i< binfin+1; ++i) {
00255     zf->data[i].re = x[i].re;
00256     zf->data[i].im = x[i].im;
00257   }
00258   for (i=binfin+1; i< n; ++i) {
00259     zf->data[i].re = 0.0;
00260     zf->data[i].im = 0.0;
00261   }
00262 
00263   /* Calculate z_k(t) by performing FFTs */
00264   TRY(LALCOMPLEX8VectorFFT(status->statusPtr,zt, zf, pinv), status);
00265 
00266   /* calculate invarb, B_k(1)(t) and initializes sden and snum */
00267 
00268   px  = (k*k)/px;
00269   inv2k= 0.5/k;
00270   invk= 2.0*inv2k;
00271   
00272   /* cumsum = 0.0; */
00273   countPI = 0;
00274   
00275   dr = zt->data[0].re * invN;
00276   di = zt->data[0].im * invN;
00277   
00278   mod2 = dr*dr+di*di;
00279   
00280   if( mod2< LAL_REAL4_MIN)
00281     {  phaseI= 0.0; /* to avoid NaN */ }
00282   else
00283     {  phaseI = atan2(di,dr);  }
00284 
00285   /* calculation of B_k(1)(t) */
00286   ampB = pow(mod2,inv2k); 
00287   phB  = phaseI*invk;
00288  
00289   b1t->data[0].re = ampB * cos(phB);
00290   b1t->data[0].im = ampB * sin(phB);
00291 
00292   invarb->data[0] = px*mod2;
00293   sden->data[0]   = invarb->data[0];
00294 
00295   snum->data[0].re = b1t->data[0].re * invarb->data[0];
00296   snum->data[0].im = b1t->data[0].im * invarb->data[0];
00297 
00298   
00299   for (i=1; i< n; ++i) {
00300     dr = zt->data[i].re * invN;
00301     di = zt->data[i].im * invN;
00302     /* calculation of modulus^2 and phase, and unwrap phase */
00303     mod2 = dr*dr+di*di;
00304     
00305     if( mod2< LAL_REAL4_MIN)
00306       {  phaseII= 0.0; /* to avoid NaN */ }
00307     else
00308       {  phaseII = atan2(di,dr);  }
00309     
00310     diffph = phaseII - phaseI;
00311     phaseI = phaseII;
00312     /* cumsum += LAL_TWOPI*( (diffph < -LAL_PI) - (diffph >  LAL_PI) ); */
00313     countPI += (diffph < -LAL_PI) - (diffph >  LAL_PI); 
00314     
00315     /* calculation of B_k(1)(t) */
00316     
00317     /*  phB = (phaseII + cumsum)*invk; */
00318     phB = (phaseII + LAL_TWOPI*( countPI%k ) )*invk;
00319     
00320     ampB = pow(mod2,inv2k);
00321     
00322     b1t->data[i].re = ampB * cos(phB);
00323     b1t->data[i].im = ampB * sin(phB);
00324 
00325     invarb->data[i] = px*mod2;
00326     sden->data[i] = invarb->data[i];
00327       
00328     snum->data[i].re = b1t->data[i].re * invarb->data[i];
00329     snum->data[i].im = b1t->data[i].im * invarb->data[i];
00330   }
00331   
00332   /* ----------------------------------------------   */
00333   /* ------ For the other harmonics considered ----   */
00334   /* ----------------------------------------------   */
00335   
00336   for(j=1; j< l; ++j) {
00337     ++harmo; 
00338     k = *harmo;
00339     ++harmo;
00340     binini =  *harmo;
00341     ++harmo;
00342     binfin =  *harmo;
00343     
00344     /*   Make sure that the frequency interval is correct:  */
00345     ASSERT (binini < binfin, status, CLRH_EINT, CLRH_MSGEINT);
00346     ASSERT (0< binini, status, CLRH_EINT, CLRH_MSGEINT);
00347     ASSERT (binfin < (n/2)+1, status, CLRH_EINT, CLRH_MSGEINT);
00348     
00349     /* Calculate px */
00350     
00351     px= 0.0;
00352     
00353     for (i=10; i > 0; --i)
00354       {
00355         px += x[binini-i].re*x[binini-i].re + x[binini-i].im*x[binini-i].im;
00356       }
00357     for (i=1; i < 11; ++i)
00358       {
00359         px += x[binfin+i].re*x[binfin+i].re + x[binfin+i].im*x[binfin+i].im;
00360       }
00361     
00362     px = px *(binfin-binini);        /* proportional to the width */
00363     
00364     /* Build z_k(nu) */
00365     for (i=0; i< binini; ++i) {
00366       zf->data[i].re = 0.0;
00367       zf->data[i].im = 0.0;
00368     }
00369     for (i=binini; i< binfin+1; ++i) {
00370       zf->data[i].re = x[i].re;
00371       zf->data[i].im = x[i].im;
00372     }
00373     for (i=binfin+1; i< n; ++i) {
00374       zf->data[i].re = 0.0;
00375       zf->data[i].im = 0.0;
00376     }
00377     
00378     /* Calculate z_k(t) by performing FFTs */
00379     TRY(LALCOMPLEX8VectorFFT(status->statusPtr,zt, zf, pinv), status);
00380     
00381     /* calculate invarb, B_k(t)  */
00382     
00383     px  = (k*k)/px;
00384     inv2k= 0.5/k;
00385     invk= 2.0*inv2k;
00386     
00387     /* cumsum = 0.0; */
00388     countPI = 0;
00389     dr = zt->data[0].re * invN;
00390     di = zt->data[0].im * invN;
00391     
00392     mod2 = dr*dr+di*di;
00393     
00394     if( mod2< LAL_REAL4_MIN)
00395       {  phaseI= 0.0; /* to avoid NaN */ }
00396     else
00397       {  phaseI = atan2(di,dr);  }
00398     
00399     /* calculation of B_k(t) */
00400     ampB = pow(mod2,inv2k); 
00401     phB = phaseI*invk;
00402       
00403     bt->data[0].re = ampB * cos(phB);
00404     bt->data[0].im = ampB * sin(phB);
00405     
00406     /* initialize calculation of Lambda_k */
00407     br =  bt->data[0].re;
00408     bi =  bt->data[0].im;
00409     dr =  b1t->data[0].re;
00410     di =  b1t->data[0].im;
00411     
00412     lambdan.re =  br*dr + bi*di;
00413     lambdan.im = -dr*bi + br*di;
00414     lambdad    =  br*br + bi*bi;
00415     
00416     /* inverse of the variance of beta */
00417     invarb->data[0] = px*mod2;
00418     
00419     for (i=1; i< n; ++i) {
00420       dr = zt->data[i].re * invN;
00421       di = zt->data[i].im * invN;
00422       /* calculation of modulus^2 and phase, and unwrap phase */
00423       mod2 = dr*dr+di*di;
00424       
00425       if( mod2< LAL_REAL4_MIN)
00426         {  phaseII= 0.0; /* to avoid NaN */ }
00427       else
00428         {  phaseII = atan2(di,dr);  }
00429       
00430       diffph = phaseII - phaseI;
00431       phaseI = phaseII;
00432       /*  cumsum += LAL_TWOPI*( (diffph < -LAL_PI) - (diffph> LAL_PI) ); */
00433       countPI += (diffph < -LAL_PI) - (diffph> LAL_PI); 
00434       
00435       /* calculation of B_k(t) */
00436       /*  phB = (phaseII + cumsum)*invk; */
00437       phB = (phaseII + LAL_TWOPI*( countPI%k ) )*invk;
00438       
00439       ampB = pow(mod2,inv2k);
00440       
00441       bt->data[i].re = ampB * cos(phB);
00442       bt->data[i].im = ampB * sin(phB);
00443       
00444       /* for the calculation of Lambda_k */
00445       br =  bt->data[i].re;
00446       bi =  bt->data[i].im;
00447       dr =  b1t->data[i].re;
00448       di =  b1t->data[i].im;
00449       
00450       lambdan.re +=  br*dr + bi*di;
00451       lambdan.im += -dr*bi + br*di;
00452       lambdad    +=  br*br + bi*bi;
00453       
00454       /* inverse of the variance of beta */
00455       invarb->data[i] = px*mod2;
00456     }
00457     
00458     /* update  sden and snum */
00459     lambda.re = lambdan.re/lambdad;
00460     lambda.im = lambdan.im/lambdad;
00461     
00462     for(i=0; i< n; ++i) {
00463       br =  bt->data[i].re;
00464       bi =  bt->data[i].im;
00465       snum->data[i].re += (br*lambda.re - bi*lambda.im) * invarb->data[i];
00466       snum->data[i].im += (br*lambda.im + bi*lambda.re) * invarb->data[i];
00467       sden->data[i]    += invarb->data[i];
00468     }
00469     
00470   } /* the harmonics */
00471   
00472   /* -------------------------------------------   */
00473   /*   calculation of M(t)                         */
00474   /* -------------------------------------------   */
00475   
00476   for(i=0; i< n; ++i){
00477     m[i].re = snum->data[i].re / sden->data[i] ;
00478     m[i].im = snum->data[i].im / sden->data[i] ;
00479   }
00480   /* -------------------------------------------   */
00481   
00482   
00483   /* Destroy Vectors and fft plan */
00484   TRY(LALSDestroyVector(status->statusPtr, &sden), status);
00485   TRY(LALSDestroyVector(status->statusPtr, &invarb), status);
00486   
00487   TRY(LALCDestroyVector(status->statusPtr, &zf), status);
00488   TRY(LALCDestroyVector(status->statusPtr, &zt), status);
00489   TRY(LALZDestroyVector(status->statusPtr, &bt), status);
00490   TRY(LALZDestroyVector(status->statusPtr, &b1t), status);
00491   TRY(LALCDestroyVector(status->statusPtr, &snum), status);
00492   
00493   TRY(LALDestroyComplexFFTPlan(status->statusPtr, &pinv), status);
00494   /* -------------------------------------------   */
00495   
00496   
00497   
00498   DETATCHSTATUSPTR (status);
00499   
00500   /* normal exit */
00501   RETURN (status);
00502 }

Generated on Sun Sep 7 03:07:09 2008 for LAL by  doxygen 1.5.2