LALPulsar  6.1.0.1-89842e6
NormalizeSFTRngMedTest.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2012 Reinhard Prix
3 * Copyright (C) 2005,2006 Badri Krishnan
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with with program; see the file COPYING. If not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301 USA
19 */
20 
21 #include <lal/FrequencySeries.h>
22 #include <lal/NormalizeSFTRngMed.h>
23 #include <lal/Units.h>
24 
25 #define REL_ERR(x,y) ( fabs((x) - (y)) / fabs( (x) ) )
26 
27 /* Default parameters. */
28 
30 
31 int main( void )
32 {
33  const char *fn = __func__;
34 
35  SFTtype *mySFT;
36  LIGOTimeGPS epoch = { 731210229, 0 };
37  REAL8 dFreq = 1.0 / 1800.0;
38  REAL8 f0 = 150.0 - 2.0 * dFreq;
39 
40  /* init data array */
41  COMPLEX8 vals[] = {
42  crectf( -1.249241e-21, 1.194085e-21 ),
43  crectf( 2.207420e-21, 2.472366e-22 ),
44  crectf( 1.497939e-21, 6.593609e-22 ),
45  crectf( 3.544089e-20, -9.365807e-21 ),
46  crectf( 1.292773e-21, -1.402466e-21 )
47  };
48  UINT4 numBins = sizeof( vals ) / sizeof( vals[0] );
49 
50  if ( ( mySFT = XLALCreateSFT( numBins ) ) == NULL ) {
51  XLALPrintError( "%s: Failed to create test-SFT using XLALCreateSFT(), xlalErrno = %d\n", fn, xlalErrno );
52  return XLAL_EFAILED;
53  }
54  /* init header */
55  strcpy( mySFT->name, "H1;testSFTRngmed" );
56  mySFT->epoch = epoch;
57  mySFT->f0 = f0;
58  mySFT->deltaF = dFreq;
59 
60  /* we simply copy over these data-values into the SFT */
61  UINT4 iBin;
62  for ( iBin = 0; iBin < numBins; iBin ++ ) {
63  mySFT->data->data[iBin] = vals[iBin];
64  }
65 
66  /* get memory for running-median vector */
68  XLAL_CHECK( ( rngmed.data = XLALCreateREAL8Vector( numBins ) ) != NULL, XLAL_EFUNC, "Failed XLALCreateREAL8Vector ( %d )", numBins );
69 
70  // ---------- Test running-median PSD estimation in simple blocksize cases
71  // ------------------------------------------------------------
72  // TEST 1: odd blocksize = 3
73  // ------------------------------------------------------------
74  UINT4 blockSize3 = 3;
75 
76  /* reference result for 3-bin block running-median computed in octave:
77  octave> sft = [ \
78  -1.249241e-21 + 1.194085e-21i, \
79  2.207420e-21 + 2.472366e-22i, \
80  1.497939e-21 + 6.593609e-22i, \
81  3.544089e-20 - 9.365807e-21i, \
82  1.292773e-21 - 1.402466e-21i \
83  ];
84  octave> periodo = abs(sft).^2;
85  octave> m1 = median ( periodo(1:3) ); m2 = median ( periodo(2:4) ); m3 = median ( periodo (3:5 ) );
86  octave> rngmed = [ m1, m1, m2, m3, m3 ];
87  octave> printf ("rngmedREF3 = { %.16g, %.16g, %.16g, %.16g, %.16g };\n", rngmed );
88  rngmedREF3[] = { 2.986442063306e-42, 2.986442063306e-42, 4.933828992779561e-42, 3.638172910684999e-42, 3.638172910684999e-42 };
89  */
90  REAL8 rngmedREF3[] = { 2.986442063306e-42, 2.986442063306e-42, 4.933828992779561e-42, 3.638172910684999e-42, 3.638172910684999e-42 };
91 
92  /* compute running median */
93  XLAL_CHECK( XLALSFTtoRngmed( &rngmed, mySFT, blockSize3 ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALSFTtoRngmed() failed." );
94 
95  /* get median->mean bias correction, needed for octave-reference results, to make
96  * them comparable to the bias-corrected results from XLALSFTtoRngmed()
97  */
98  REAL8 medianBias3 = XLALRngMedBias( blockSize3 );
99  XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC, "XLALRngMedBias() failed." );
100 
101  BOOLEAN pass = 1;
102  const CHAR *passStr;
103  printf( "%4s %22s %22s %8s <%g\n", "Bin", "rngmed(LAL)", "rngmed(Octave)", "relError", tol );
104  for ( iBin = 0; iBin < numBins; iBin ++ ) {
105  REAL8 rngmedVAL = rngmed.data->data[iBin];
106  REAL8 rngmedREF = rngmedREF3[iBin] / medianBias3; // apply median-bias correction
107  REAL8 relErr = REL_ERR( rngmedREF, rngmedVAL );
108  if ( relErr > tol ) {
109  pass = 0;
110  passStr = "fail";
111  } else {
112  passStr = "OK.";
113  }
114 
115  printf( "%4d %22.16g %22.16g %8.1g %s\n", iBin, rngmedVAL, rngmedREF, relErr, passStr );
116 
117  } /* for iBin < numBins */
118 
119  // ------------------------------------------------------------
120  // TEST 2: even blocksize = 4
121  // ------------------------------------------------------------
122  UINT4 blockSize4 = 4;
123 
124  /* reference result for 4-bin block running-median computed in octave:
125  octave> m1 = median ( periodo(1:4) ); m2 = median ( periodo(2:5) );
126  octave> rngmed = [ m1, m1, m1, m2, m2 ];
127  octave> printf ("rngmedREF4[] = { %.16g, %.16g, %.16g, %.16g, %.16g };\n", rngmed );
128  rngmedREF4[] = { 3.96013552804278e-42, 3.96013552804278e-42, 3.96013552804278e-42, 4.28600095173228e-42, 4.28600095173228e-42 };
129  */
130  REAL8 rngmedREF4[] = { 3.96013552804278e-42, 3.96013552804278e-42, 3.96013552804278e-42, 4.28600095173228e-42, 4.28600095173228e-42 };
131 
132  /* compute running median */
133  XLAL_CHECK( XLALSFTtoRngmed( &rngmed, mySFT, blockSize4 ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALSFTtoRngmed() failed." );
134 
135  /* get median->mean bias correction, needed for octave-reference results, to make
136  * them comparable to the bias-corrected results from XLALSFTtoRngmed()
137  */
138  REAL8 medianBias4 = XLALRngMedBias( blockSize4 );
139  XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC, "XLALRngMedBias() failed." );
140 
141  printf( "%4s %22s %22s %8s <%g\n", "Bin", "rngmed(LAL)", "rngmed(Octave)", "relError", tol );
142  for ( iBin = 0; iBin < numBins; iBin ++ ) {
143  REAL8 rngmedVAL = rngmed.data->data[iBin];
144  REAL8 rngmedREF = rngmedREF4[iBin] / medianBias4; // apply median-bias correction
145  REAL8 relErr = REL_ERR( rngmedREF, rngmedVAL );
146  if ( relErr > tol ) {
147  pass = 0;
148  passStr = "fail";
149  } else {
150  passStr = "OK.";
151  }
152 
153  printf( "%4d %22.16g %22.16g %8.1g %s\n", iBin, rngmedVAL, rngmedREF, relErr, passStr );
154 
155  } /* for iBin < numBins */
156 
157  /* free memory */
158  XLALDestroyREAL8Vector( rngmed.data );
159  XLALDestroySFT( mySFT );
160 
162 
163  if ( !pass ) {
164  printf( "Test failed! Difference exceeded tolerance.\n" );
165  return XLAL_EFAILED;
166  } else {
167  printf( "Test passed.\n" );
168  return XLAL_SUCCESS;
169  }
170 
171 } /* main() */
#define __func__
log an I/O error, i.e.
void LALCheckMemoryLeaks(void)
#define REL_ERR(x, y)
int main(void)
REAL8 tol
#define LAL_REAL4_EPS
unsigned char BOOLEAN
double REAL8
#define XLAL_INIT_DECL(var,...)
#define crectf(re, im)
char CHAR
uint32_t UINT4
float complex COMPLEX8
int XLALSFTtoRngmed(REAL8FrequencySeries *rngmed, const SFTtype *sft, UINT4 blockSize)
Calculates a smoothed (running-median) periodogram for the given SFT.
REAL8 XLALRngMedBias(INT4 blkSize)
SFTtype * XLALCreateSFT(UINT4 numBins)
XLAL function to create one SFT-struct.
Definition: SFTtypes.c:152
void XLALDestroySFT(SFTtype *sft)
Destructor for one SFT.
Definition: SFTtypes.c:176
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
#define xlalErrno
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EFAILED
vals
CHAR name[LALNameLength]
COMPLEX8Sequence * data
COMPLEX8 * data
enum @1 epoch