00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <math.h>
00021 #include <string.h>
00022 #include <lal/LALComplex.h>
00023 #include <lal/FrequencySeries.h>
00024 #include <lal/LALStdlib.h>
00025 #include <lal/LALConstants.h>
00026 #include <lal/AVFactories.h>
00027 #include <lal/Sequence.h>
00028 #include <lal/TimeFreqFFT.h>
00029 #include <lal/Units.h>
00030 #include <lal/Window.h>
00031 #include <lal/Date.h>
00032
00033 #include <lal/LALRCSID.h>
00034 NRCSID (AVERAGESPECTRUMC,"$Id: AverageSpectrum.c,v 1.26 2008/09/30 00:52:56 kipp Exp $");
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 int XLALREAL4ModifiedPeriodogram(
00046 REAL4FrequencySeries *periodogram,
00047 const REAL4TimeSeries *tseries,
00048 const REAL4Window *window,
00049 const REAL4FFTPlan *plan
00050 )
00051 {
00052 static const char *func = "XLALREAL4ModifiedPeriodogram";
00053 REAL4Sequence *work;
00054 REAL4 normfac;
00055 UINT4 k;
00056 int result;
00057
00058 if ( ! periodogram || ! tseries || ! plan )
00059 XLAL_ERROR( func, XLAL_EFAULT );
00060 if ( ! periodogram->data || ! tseries->data )
00061 XLAL_ERROR( func, XLAL_EINVAL );
00062 if ( tseries->deltaT <= 0.0 )
00063 XLAL_ERROR( func, XLAL_EINVAL );
00064 if ( periodogram->data->length != tseries->data->length/2 + 1 )
00065 XLAL_ERROR( func, XLAL_EBADLEN );
00066 if ( window )
00067 {
00068 if ( ! window->data )
00069 XLAL_ERROR( func, XLAL_EINVAL );
00070 if ( window->sumofsquares <= 0.0 )
00071 XLAL_ERROR( func, XLAL_EINVAL );
00072 if ( window->data->length != tseries->data->length )
00073 XLAL_ERROR( func, XLAL_EBADLEN );
00074 }
00075
00076
00077 if ( window )
00078 {
00079 UINT4 j;
00080
00081
00082 work = XLALCutREAL4Sequence( tseries->data, 0, tseries->data->length );
00083 if ( ! work )
00084 XLAL_ERROR( func, XLAL_EFUNC );
00085
00086
00087 for ( j = 0; j < tseries->data->length; ++j )
00088 work->data[j] *= window->data->data[j];
00089 }
00090 else
00091
00092 work = tseries->data;
00093
00094
00095
00096 result = XLALREAL4PowerSpectrum( periodogram->data, work, plan );
00097
00098 if ( window )
00099 XLALDestroyREAL4Sequence( work );
00100
00101 if ( result == XLAL_FAILURE )
00102 XLAL_ERROR( func, XLAL_EFUNC );
00103
00104
00105
00106 if ( window )
00107 normfac = tseries->deltaT / window->sumofsquares;
00108 else
00109 normfac = tseries->deltaT / tseries->data->length;
00110 for ( k = 0; k < periodogram->data->length; ++k )
00111 periodogram->data->data[k] *= normfac;
00112
00113
00114 periodogram->epoch = tseries->epoch;
00115 periodogram->f0 = tseries->f0;
00116 periodogram->deltaF = 1.0 / ( tseries->data->length * tseries->deltaT );
00117
00118
00119 if ( ! XLALUnitSquare( &periodogram->sampleUnits, &tseries->sampleUnits ) )
00120 XLAL_ERROR( func, XLAL_EFUNC );
00121 if ( ! XLALUnitMultiply( &periodogram->sampleUnits,
00122 &periodogram->sampleUnits, &lalSecondUnit ) )
00123 XLAL_ERROR( func, XLAL_EFUNC );
00124
00125 return 0;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134 int XLALREAL8ModifiedPeriodogram(
00135 REAL8FrequencySeries *periodogram,
00136 const REAL8TimeSeries *tseries,
00137 const REAL8Window *window,
00138 const REAL8FFTPlan *plan
00139 )
00140 {
00141 static const char *func = "XLALREAL8ModifiedPeriodogram";
00142 REAL8Sequence *work;
00143 REAL8 normfac;
00144 UINT4 k;
00145 int result;
00146
00147 if ( ! periodogram || ! tseries || ! plan )
00148 XLAL_ERROR( func, XLAL_EFAULT );
00149 if ( ! periodogram->data || ! tseries->data )
00150 XLAL_ERROR( func, XLAL_EINVAL );
00151 if ( tseries->deltaT <= 0.0 )
00152 XLAL_ERROR( func, XLAL_EINVAL );
00153 if ( periodogram->data->length != tseries->data->length/2 + 1 )
00154 XLAL_ERROR( func, XLAL_EBADLEN );
00155 if ( window )
00156 {
00157 if ( ! window->data )
00158 XLAL_ERROR( func, XLAL_EINVAL );
00159 if ( window->sumofsquares <= 0.0 )
00160 XLAL_ERROR( func, XLAL_EINVAL );
00161 if ( window->data->length != tseries->data->length )
00162 XLAL_ERROR( func, XLAL_EBADLEN );
00163 }
00164
00165
00166 if ( window )
00167 {
00168 UINT4 j;
00169
00170
00171 work = XLALCutREAL8Sequence( tseries->data, 0, tseries->data->length );
00172 if ( ! work )
00173 XLAL_ERROR( func, XLAL_EFUNC );
00174
00175
00176 for ( j = 0; j < tseries->data->length; ++j )
00177 work->data[j] *= window->data->data[j];
00178 }
00179 else
00180
00181 work = tseries->data;
00182
00183
00184
00185 result = XLALREAL8PowerSpectrum( periodogram->data, work, plan );
00186
00187 if ( window )
00188 XLALDestroyREAL8Sequence( work );
00189
00190 if ( result == XLAL_FAILURE )
00191 XLAL_ERROR( func, XLAL_EFUNC );
00192
00193
00194
00195 if ( window )
00196 normfac = tseries->deltaT / window->sumofsquares;
00197 else
00198 normfac = tseries->deltaT / tseries->data->length;
00199 for ( k = 0; k < periodogram->data->length; ++k )
00200 periodogram->data->data[k] *= normfac;
00201
00202
00203 periodogram->epoch = tseries->epoch;
00204 periodogram->f0 = tseries->f0;
00205 periodogram->deltaF = 1.0 / ( tseries->data->length * tseries->deltaT );
00206
00207
00208 if ( ! XLALUnitSquare( &periodogram->sampleUnits, &tseries->sampleUnits ) )
00209 XLAL_ERROR( func, XLAL_EFUNC );
00210 if ( ! XLALUnitMultiply( &periodogram->sampleUnits,
00211 &periodogram->sampleUnits, &lalSecondUnit ) )
00212 XLAL_ERROR( func, XLAL_EFUNC );
00213
00214 return 0;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 int XLALREAL4AverageSpectrumWelch(
00229 REAL4FrequencySeries *spectrum,
00230 const REAL4TimeSeries *tseries,
00231 UINT4 seglen,
00232 UINT4 stride,
00233 const REAL4Window *window,
00234 const REAL4FFTPlan *plan
00235 )
00236 {
00237 static const char *func = "XLALREAL4AverageSpectrumWelch";
00238 REAL4FrequencySeries *work;
00239 REAL4Sequence sequence;
00240 REAL4TimeSeries tseriescopy;
00241 UINT4 numseg;
00242 UINT4 seg;
00243 UINT4 k;
00244
00245 if ( ! spectrum || ! tseries || ! plan )
00246 XLAL_ERROR( func, XLAL_EFAULT );
00247 if ( ! spectrum->data || ! tseries->data )
00248 XLAL_ERROR( func, XLAL_EINVAL );
00249 if ( tseries->deltaT <= 0.0 )
00250 XLAL_ERROR( func, XLAL_EINVAL );
00251
00252
00253 sequence = *tseries->data;
00254 tseriescopy = *tseries;
00255 tseriescopy.data = &sequence;
00256 tseriescopy.data->length = seglen;
00257
00258 numseg = 1 + (tseries->data->length - seglen)/stride;
00259
00260
00261
00262 if ( (numseg - 1)*stride + seglen != tseries->data->length )
00263 XLAL_ERROR( func, XLAL_EBADLEN );
00264 if ( spectrum->data->length != seglen/2 + 1 )
00265 XLAL_ERROR( func, XLAL_EBADLEN );
00266
00267
00268 if ( window )
00269 {
00270 if ( ! window->data )
00271 XLAL_ERROR( func, XLAL_EINVAL );
00272 if ( window->sumofsquares <= 0.0 )
00273 XLAL_ERROR( func, XLAL_EINVAL );
00274 if ( window->data->length != seglen )
00275 XLAL_ERROR( func, XLAL_EBADLEN );
00276 }
00277
00278
00279 memset( spectrum->data->data, 0,
00280 spectrum->data->length * sizeof( *spectrum->data->data ) );
00281
00282
00283 work = XLALCutREAL4FrequencySeries( spectrum, 0, spectrum->data->length );
00284 if( ! work )
00285 XLAL_ERROR( func, XLAL_EFUNC );
00286
00287 for ( seg = 0; seg < numseg; seg++, tseriescopy.data->data += stride )
00288 {
00289
00290 if ( XLALREAL4ModifiedPeriodogram( work, &tseriescopy, window, plan ) == XLAL_FAILURE )
00291 {
00292 XLALDestroyREAL4FrequencySeries( work );
00293 XLAL_ERROR( func, XLAL_EFUNC );
00294 }
00295
00296
00297 for ( k = 0; k < spectrum->data->length; ++k )
00298 spectrum->data->data[k] += work->data->data[k];
00299 }
00300
00301
00302 spectrum->epoch = work->epoch;
00303 spectrum->f0 = work->f0;
00304 spectrum->deltaF = work->deltaF;
00305 spectrum->sampleUnits = work->sampleUnits;
00306
00307
00308 for ( k = 0; k < spectrum->data->length; ++k )
00309 spectrum->data->data[k] /= numseg;
00310
00311
00312 XLALDestroyREAL4FrequencySeries( work );
00313
00314 return 0;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 int XLALREAL8AverageSpectrumWelch(
00328 REAL8FrequencySeries *spectrum,
00329 const REAL8TimeSeries *tseries,
00330 UINT4 seglen,
00331 UINT4 stride,
00332 const REAL8Window *window,
00333 const REAL8FFTPlan *plan
00334 )
00335 {
00336 static const char *func = "XLALREAL8AverageSpectrumWelch";
00337 REAL8FrequencySeries *work;
00338 REAL8Sequence sequence;
00339 REAL8TimeSeries tseriescopy;
00340 UINT4 numseg;
00341 UINT4 seg;
00342 UINT4 k;
00343
00344 if ( ! spectrum || ! tseries || ! plan )
00345 XLAL_ERROR( func, XLAL_EFAULT );
00346 if ( ! spectrum->data || ! tseries->data )
00347 XLAL_ERROR( func, XLAL_EINVAL );
00348 if ( tseries->deltaT <= 0.0 )
00349 XLAL_ERROR( func, XLAL_EINVAL );
00350
00351
00352 sequence = *tseries->data;
00353 tseriescopy = *tseries;
00354 tseriescopy.data = &sequence;
00355 tseriescopy.data->length = seglen;
00356
00357 numseg = 1 + (tseries->data->length - seglen)/stride;
00358
00359
00360
00361 if ( (numseg - 1)*stride + seglen != tseries->data->length )
00362 XLAL_ERROR( func, XLAL_EBADLEN );
00363 if ( spectrum->data->length != seglen/2 + 1 )
00364 XLAL_ERROR( func, XLAL_EBADLEN );
00365
00366
00367 if ( window )
00368 {
00369 if ( ! window->data )
00370 XLAL_ERROR( func, XLAL_EINVAL );
00371 if ( window->sumofsquares <= 0.0 )
00372 XLAL_ERROR( func, XLAL_EINVAL );
00373 if ( window->data->length != seglen )
00374 XLAL_ERROR( func, XLAL_EBADLEN );
00375 }
00376
00377
00378 memset( spectrum->data->data, 0,
00379 spectrum->data->length * sizeof( *spectrum->data->data ) );
00380
00381
00382 work = XLALCutREAL8FrequencySeries( spectrum, 0, spectrum->data->length );
00383 if( ! work )
00384 XLAL_ERROR( func, XLAL_EFUNC );
00385
00386 for ( seg = 0; seg < numseg; seg++, tseriescopy.data->data += stride )
00387 {
00388
00389 if ( XLALREAL8ModifiedPeriodogram( work, &tseriescopy, window, plan ) == XLAL_FAILURE )
00390 {
00391 XLALDestroyREAL8FrequencySeries( work );
00392 XLAL_ERROR( func, XLAL_EFUNC );
00393 }
00394
00395
00396 for ( k = 0; k < spectrum->data->length; ++k )
00397 spectrum->data->data[k] += work->data->data[k];
00398 }
00399
00400
00401 spectrum->epoch = work->epoch;
00402 spectrum->f0 = work->f0;
00403 spectrum->deltaF = work->deltaF;
00404 spectrum->sampleUnits = work->sampleUnits;
00405
00406
00407 for ( k = 0; k < spectrum->data->length; ++k )
00408 spectrum->data->data[k] /= numseg;
00409
00410
00411 XLALDestroyREAL8FrequencySeries( work );
00412
00413 return 0;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 REAL8 XLALMedianBias( UINT4 nn )
00425 {
00426 const UINT4 nmax = 1000;
00427 REAL8 ans = 1;
00428 UINT4 n = (nn - 1)/2;
00429 UINT4 i;
00430
00431 if ( nn >= nmax )
00432 return LAL_LN2;
00433
00434 for ( i = 1; i <= n; ++i )
00435 {
00436 ans -= 1.0/(2*i);
00437 ans += 1.0/(2*i + 1);
00438 }
00439
00440 return ans;
00441 }
00442
00443
00444 static void median_cleanup_REAL4( REAL4FrequencySeries *work, UINT4 n )
00445 {
00446 int saveErrno = xlalErrno;
00447 UINT4 i;
00448 for ( i = 0; i < n; ++i )
00449 if ( work[i].data )
00450 XLALDestroyREAL4Vector( work[i].data );
00451 XLALFree( work );
00452 xlalErrno = saveErrno;
00453 return;
00454 }
00455 static void median_cleanup_REAL8( REAL8FrequencySeries *work, UINT4 n )
00456 {
00457 int saveErrno = xlalErrno;
00458 UINT4 i;
00459 for ( i = 0; i < n; ++i )
00460 if ( work[i].data )
00461 XLALDestroyREAL8Vector( work[i].data );
00462 XLALFree( work );
00463 xlalErrno = saveErrno;
00464 return;
00465 }
00466
00467
00468 static int compare_REAL4( const void *p1, const void *p2 )
00469 {
00470 REAL4 x1 = *(const REAL4 *)p1;
00471 REAL4 x2 = *(const REAL4 *)p2;
00472 return (x1 > x2) - (x1 < x2);
00473 }
00474 static int compare_REAL8( const void *p1, const void *p2 )
00475 {
00476 REAL8 x1 = *(const REAL8 *)p1;
00477 REAL8 x2 = *(const REAL8 *)p2;
00478 return (x1 > x2) - (x1 < x2);
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 int XLALREAL4AverageSpectrumMedian(
00492 REAL4FrequencySeries *spectrum,
00493 const REAL4TimeSeries *tseries,
00494 UINT4 seglen,
00495 UINT4 stride,
00496 const REAL4Window *window,
00497 const REAL4FFTPlan *plan
00498 )
00499 {
00500 static const char *func = "XLALREAL4AverageSpectrumMedian";
00501 REAL4FrequencySeries *work;
00502 REAL4 *bin;
00503 REAL4 biasfac;
00504 REAL4 normfac;
00505 UINT4 reclen;
00506 UINT4 numseg;
00507 UINT4 seg;
00508 UINT4 k;
00509
00510 if ( ! spectrum || ! tseries || ! plan )
00511 XLAL_ERROR( func, XLAL_EFAULT );
00512 if ( ! spectrum->data || ! tseries->data )
00513 XLAL_ERROR( func, XLAL_EINVAL );
00514 if ( tseries->deltaT <= 0.0 )
00515 XLAL_ERROR( func, XLAL_EINVAL );
00516
00517 reclen = tseries->data->length;
00518 numseg = 1 + (reclen - seglen)/stride;
00519
00520
00521
00522 if ( (numseg - 1)*stride + seglen != reclen )
00523 XLAL_ERROR( func, XLAL_EBADLEN );
00524 if ( spectrum->data->length != seglen/2 + 1 )
00525 XLAL_ERROR( func, XLAL_EBADLEN );
00526
00527
00528 if ( window )
00529 {
00530 if ( ! window->data )
00531 XLAL_ERROR( func, XLAL_EINVAL );
00532 if ( window->sumofsquares <= 0.0 )
00533 XLAL_ERROR( func, XLAL_EINVAL );
00534 if ( window->data->length != seglen )
00535 XLAL_ERROR( func, XLAL_EBADLEN );
00536 }
00537
00538
00539 work = XLALCalloc( numseg, sizeof( *work ) );
00540 if ( ! work )
00541 XLAL_ERROR( func, XLAL_ENOMEM );
00542 for ( seg = 0; seg < numseg; ++seg )
00543 {
00544 work[seg].data = XLALCreateREAL4Vector( spectrum->data->length );
00545 if ( ! work[seg].data )
00546 {
00547 median_cleanup_REAL4( work, numseg );
00548 XLAL_ERROR( func, XLAL_EFUNC );
00549 }
00550 }
00551
00552 for ( seg = 0; seg < numseg; ++seg )
00553 {
00554 REAL4Vector savevec;
00555 int code;
00556
00557
00558 savevec = *tseries->data;
00559
00560
00561 tseries->data->length = seglen;
00562 tseries->data->data += seg * stride;
00563
00564
00565 code = XLALREAL4ModifiedPeriodogram( work + seg, tseries, window, plan );
00566
00567
00568 *tseries->data = savevec;
00569
00570
00571 if ( code == XLAL_FAILURE )
00572 {
00573 median_cleanup_REAL4( work, numseg );
00574 XLAL_ERROR( func, XLAL_EFUNC );
00575 }
00576 }
00577
00578
00579 bin = XLALMalloc( numseg * sizeof( *bin ) );
00580 if ( ! bin )
00581 {
00582 median_cleanup_REAL4( work, numseg );
00583 XLAL_ERROR( func, XLAL_ENOMEM );
00584 }
00585
00586
00587 biasfac = XLALMedianBias( numseg );
00588
00589
00590 normfac = 1.0 / biasfac;
00591
00592
00593 for ( k = 0; k < spectrum->data->length; ++k )
00594 {
00595
00596 for ( seg = 0; seg < numseg; ++seg )
00597 bin[seg] = work[seg].data->data[k];
00598
00599
00600 qsort( bin, numseg, sizeof( *bin ), compare_REAL4 );
00601 if ( numseg % 2 )
00602 spectrum->data->data[k] = bin[numseg/2];
00603 else
00604 spectrum->data->data[k] = 0.5*(bin[numseg/2-1] + bin[numseg/2]);
00605
00606
00607 spectrum->data->data[k] *= normfac;
00608 }
00609
00610
00611 spectrum->epoch = work->epoch;
00612 spectrum->f0 = work->f0;
00613 spectrum->deltaF = work->deltaF;
00614 spectrum->sampleUnits = work->sampleUnits;
00615
00616
00617 XLALFree( bin );
00618 median_cleanup_REAL4( work, numseg );
00619
00620 return 0;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 int XLALREAL8AverageSpectrumMedian(
00633 REAL8FrequencySeries *spectrum,
00634 const REAL8TimeSeries *tseries,
00635 UINT4 seglen,
00636 UINT4 stride,
00637 const REAL8Window *window,
00638 const REAL8FFTPlan *plan
00639 )
00640 {
00641 static const char *func = "XLALREAL8AverageSpectrumMedian";
00642 REAL8FrequencySeries *work;
00643 REAL8 *bin;
00644 REAL8 biasfac;
00645 REAL8 normfac;
00646 UINT4 reclen;
00647 UINT4 numseg;
00648 UINT4 seg;
00649 UINT4 k;
00650
00651 if ( ! spectrum || ! tseries || ! plan )
00652 XLAL_ERROR( func, XLAL_EFAULT );
00653 if ( ! spectrum->data || ! tseries->data )
00654 XLAL_ERROR( func, XLAL_EINVAL );
00655 if ( tseries->deltaT <= 0.0 )
00656 XLAL_ERROR( func, XLAL_EINVAL );
00657
00658 reclen = tseries->data->length;
00659 numseg = 1 + (reclen - seglen)/stride;
00660
00661
00662
00663 if ( (numseg - 1)*stride + seglen != reclen )
00664 XLAL_ERROR( func, XLAL_EBADLEN );
00665 if ( spectrum->data->length != seglen/2 + 1 )
00666 XLAL_ERROR( func, XLAL_EBADLEN );
00667
00668
00669 if ( window )
00670 {
00671 if ( ! window->data )
00672 XLAL_ERROR( func, XLAL_EINVAL );
00673 if ( window->sumofsquares <= 0.0 )
00674 XLAL_ERROR( func, XLAL_EINVAL );
00675 if ( window->data->length != seglen )
00676 XLAL_ERROR( func, XLAL_EBADLEN );
00677 }
00678
00679
00680 work = XLALCalloc( numseg, sizeof( *work ) );
00681 if ( ! work )
00682 XLAL_ERROR( func, XLAL_ENOMEM );
00683 for ( seg = 0; seg < numseg; ++seg )
00684 {
00685 work[seg].data = XLALCreateREAL8Vector( spectrum->data->length );
00686 if ( ! work[seg].data )
00687 {
00688 median_cleanup_REAL8( work, numseg );
00689 XLAL_ERROR( func, XLAL_EFUNC );
00690 }
00691 }
00692
00693 for ( seg = 0; seg < numseg; ++seg )
00694 {
00695 REAL8Vector savevec;
00696 int code;
00697
00698
00699 savevec = *tseries->data;
00700
00701
00702 tseries->data->length = seglen;
00703 tseries->data->data += seg * stride;
00704
00705
00706 code = XLALREAL8ModifiedPeriodogram( work + seg, tseries, window, plan );
00707
00708
00709 *tseries->data = savevec;
00710
00711
00712 if ( code == XLAL_FAILURE )
00713 {
00714 median_cleanup_REAL8( work, numseg );
00715 XLAL_ERROR( func, XLAL_EFUNC );
00716 }
00717 }
00718
00719
00720 bin = XLALMalloc( numseg * sizeof( *bin ) );
00721 if ( ! bin )
00722 {
00723 median_cleanup_REAL8( work, numseg );
00724 XLAL_ERROR( func, XLAL_ENOMEM );
00725 }
00726
00727
00728 biasfac = XLALMedianBias( numseg );
00729
00730
00731 normfac = 1.0 / biasfac;
00732
00733
00734 for ( k = 0; k < spectrum->data->length; ++k )
00735 {
00736
00737 for ( seg = 0; seg < numseg; ++seg )
00738 bin[seg] = work[seg].data->data[k];
00739
00740
00741 qsort( bin, numseg, sizeof( *bin ), compare_REAL8 );
00742 if ( numseg % 2 )
00743 spectrum->data->data[k] = bin[numseg/2];
00744 else
00745 spectrum->data->data[k] = 0.5*(bin[numseg/2-1] + bin[numseg/2]);
00746
00747
00748 spectrum->data->data[k] *= normfac;
00749 }
00750
00751
00752 spectrum->epoch = work->epoch;
00753 spectrum->f0 = work->f0;
00754 spectrum->deltaF = work->deltaF;
00755 spectrum->sampleUnits = work->sampleUnits;
00756
00757
00758 XLALFree( bin );
00759 median_cleanup_REAL8( work, numseg );
00760
00761 return 0;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 static void median_mean_cleanup_REAL4( REAL4FrequencySeries *even, REAL4FrequencySeries *odd, UINT4 n )
00774 {
00775 int saveErrno = xlalErrno;
00776 UINT4 i;
00777 for ( i = 0; i < n; ++i )
00778 {
00779 if ( even[i].data )
00780 XLALDestroyREAL4Vector( even[i].data );
00781 if ( odd[i].data )
00782 XLALDestroyREAL4Vector( odd[i].data );
00783 }
00784 XLALFree( even );
00785 XLALFree( odd );
00786 xlalErrno = saveErrno;
00787 return;
00788 }
00789 static void median_mean_cleanup_REAL8( REAL8FrequencySeries *even, REAL8FrequencySeries *odd, UINT4 n )
00790 {
00791 int saveErrno = xlalErrno;
00792 UINT4 i;
00793 for ( i = 0; i < n; ++i )
00794 {
00795 if ( even[i].data )
00796 XLALDestroyREAL8Vector( even[i].data );
00797 if ( odd[i].data )
00798 XLALDestroyREAL8Vector( odd[i].data );
00799 }
00800 XLALFree( even );
00801