LAL  7.5.0.1-bede9b2
Window.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Bruce Allen, Duncan Brown, Jolien Creighton, Kipp
3  * Cannon, Patrick Brady, Teviet Creighton
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with with program; see the file COPYING. If not, write to the Free
17  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301 USA
19  */
20 
21 
22 /*
23  * ============================================================================
24  *
25  * Preamble
26  *
27  * ============================================================================
28  */
29 
30 
31 #include <math.h>
32 #include <string.h>
33 #include <gsl/gsl_sf_bessel.h>
34 #include <lal/LALConstants.h>
35 #include <lal/LALStdlib.h>
36 #include <lal/LALString.h>
37 #include <lal/Sequence.h>
38 #include <lal/Window.h>
39 #include <lal/XLALError.h>
40 
41 
42 /*
43  * ============================================================================
44  *
45  * Private utilities
46  *
47  * ============================================================================
48  */
49 
50 
51 /**
52  * Constructs a REAL4Window from a REAL8Window by quantizing the
53  * double-precision data to single-precision. The REAL8Window is freed
54  * unconditionally. Intended to be used as a wrapper, to convert any
55  * function that constructs a REAL8Window into a function to construct a
56  * REAL4Window.
57  */
59 {
60  REAL4Window *new;
61  REAL4Sequence *data;
62  UINT4 i;
63 
64  if(!orig)
66 
67  new = XLALMalloc(sizeof(*new));
68  data = XLALCreateREAL4Sequence(orig->data->length);
69 
70  if(!new || !data) {
72  XLALFree(new);
75  }
76 
77  for(i = 0; i < data->length; i++)
78  data->data[i] = orig->data->data[i];
79  new->data = data;
80  new->sumofsquares = orig->sumofsquares;
81  new->sum = orig->sum;
82 
84 
85  return new;
86 }
87 
88 
89 /**
90  * Maps the length of a window and the offset within the window to the "y"
91  * co-ordinate of the LAL documentation.
92  *
93  * Input:
94  * length > 0,
95  * 0 <= i < length
96  *
97  * Output:
98  * length < 2 --> return 0.0
99  * i == 0 --> return -1.0
100  * i == (length - 1) / 2 --> return 0.0
101  * i == length - 1 --> return +1.0
102  *
103  * e.g., length = 5 (odd), then i == 2 --> return 0.0
104  * if length = 6 (even), then i == 2.5 --> return 0.0
105  *
106  * (in the latter case, obviously i can't be a non-integer, but that's the
107  * value it would have to be for this function to return 0.0)
108  */
109 static double Y(int length, int i)
110 {
111  length -= 1;
112  return length > 0 ? (2 * i - length) / (double) length : 0;
113 }
114 
115 
116 /**
117  * Computes the sum of squares, and sum, of the samples in a window
118  * function.
119  *
120  * Two techniques are employed to achieve accurate results. Firstly, the
121  * loop iterates from the edges to the centre. Generally, window functions
122  * have smaller values at the edges and larger values in the middle, so
123  * adding them in this order avoids adding small numbers to big numbers.
124  * The loops also implement Kahan's compensated summation algorithm in
125  * which a second variable is used to accumulate round-off errors and fold
126  * them into later iterations.
127  */
128 static REAL8 sum_squares(REAL8 *start, int length)
129 {
130 
131  REAL8 sum = 0.0;
132  REAL8 e = 0.0;
133  REAL8 *end = start + length - 1;
134 
135  /* Note: don't try to simplify this loop, the statements must be
136  * done like this to induce the C compiler to perform the
137  * arithmetic in the correct order. */
138  for(; start < end; start++, end--) {
139  REAL8 temp = sum;
140  /* what we want to add */
141  REAL8 x = *start * *start + *end * *end + e;
142  /* add */
143  sum += x;
144  /* negative of what was actually added */
145  e = temp - sum;
146  /* what didn't get added, add next time */
147  e += x;
148  }
149 
150  if(start == end)
151  /* length is odd, get middle sample */
152  sum += *start * *start + e;
153 
154  return sum;
155 }
156 
157 
158 static REAL8 sum_samples(REAL8 *start, int length)
159 {
160 
161  REAL8 sum = 0.0;
162  REAL8 e = 0.0;
163  REAL8 *end = start + length - 1;
164 
165  /* Note: don't try to simplify this loop, the statements must be
166  * done like this to induce the C compiler to perform the
167  * arithmetic in the correct order. */
168  for(; start < end; start++, end--) {
169  REAL8 temp = sum;
170  /* what we want to add */
171  REAL8 x = *start + *end + e;
172  /* add */
173  sum += x;
174  /* negative of what was actually added */
175  e = temp - sum;
176  /* what didn't get added, add next time */
177  e += x;
178  }
179 
180  if(start == end)
181  /* length is odd, get middle sample */
182  sum += *start + e;
183 
184  return sum;
185 }
186 
187 
188 /*
189  * ============================================================================
190  *
191  * Public Utilities
192  *
193  * ============================================================================
194  */
195 
196 
197 /**
198  * Constructs a new REAL8Window from a REAL8Sequence. The window "owns"
199  * the sequence, when the window is destroyed the sequence will be
200  * destroyed with it. If this function fails, the sequence is destroyed.
201  * The return value is the address of the newly allocated REAL8Window or
202  * NULL on failure.
203  */
205 {
206  REAL8Window *new;
207 
208  new = XLALMalloc(sizeof(*new));
209  if(!new) {
210  XLALDestroyREAL8Sequence(sequence);
212  }
213 
214  new->data = sequence;
215  new->sumofsquares = sum_squares(new->data->data, new->data->length);
216  new->sum = sum_samples(new->data->data, new->data->length);
217 
218  return new;
219 }
220 
221 
222 /**
223  * Single-precision version of XLALCreateREAL8WindowFromSequence().
224  */
226 {
227  /* a double-precision copy of the data is used from which to
228  * compute the window's metadata. this provides for more accurate
229  * results, but mostly means I don't have to write single-precision
230  * versions of the summing loops */
231  REAL8Sequence *workspace;
232  REAL4Window *new;
233  UINT4 i;
234 
235  workspace = XLALCreateREAL8Sequence(sequence->length);
236  new = XLALMalloc(sizeof(*new));
237  if(!workspace || !new) {
238  XLALDestroyREAL4Sequence(sequence);
239  XLALDestroyREAL8Sequence(workspace);
240  XLALFree(new);
242  }
243 
244  for(i = 0; i < workspace->length; i++)
245  workspace->data[i] = sequence->data[i];
246 
247  new->data = sequence;
248  new->sumofsquares = sum_squares(workspace->data, workspace->length);
249  new->sum = sum_samples(workspace->data, workspace->length);
250 
251  XLALDestroyREAL8Sequence(workspace);
252 
253  return new;
254 }
255 
256 
257 /**
258  * Multiply a REAL8Sequence in-place by a REAL8Window with a normalization
259  * that preserves the variance of a zero-mean stationary Gaussian random
260  * process. If the window's length is N samples and its sum-of-squares is
261  * S, then the input sequence is multiplied by the window * \f$\sqrt{N / S}\f$.
262  * Returns the address of the REAL8Sequence or NULL on failure.
263  */
265 {
266  unsigned i;
267  double norm = sqrt(window->data->length / window->sumofsquares);
268 
269  if(window->sumofsquares <= 0)
271  if(sequence->length != window->data->length)
273 
274  for(i = 0; i < window->data->length; i++)
275  sequence->data[i] *= window->data->data[i] * norm;
276 
277  return sequence;
278 }
279 
280 
281 /**
282  * Double-precision complex version of XLALUnitaryWindowREAL8Sequence().
283  */
285 {
286  unsigned i;
287  double norm = sqrt(window->data->length / window->sumofsquares);
288 
289  if(window->sumofsquares <= 0)
291  if(sequence->length != window->data->length)
293 
294  for(i = 0; i < window->data->length; i++)
295  sequence->data[i] *= window->data->data[i] * norm;
296 
297  return sequence;
298 }
299 
300 
301 /**
302  * Single-precision version of XLALUnitaryWindowREAL8Sequence().
303  */
305 {
306  unsigned i;
307  float norm = sqrt(window->data->length / window->sumofsquares);
308 
309  if(window->sumofsquares <= 0)
311  if(sequence->length != window->data->length)
313 
314  for(i = 0; i < window->data->length; i++)
315  sequence->data[i] *= window->data->data[i] * norm;
316 
317  return sequence;
318 }
319 
320 
321 /**
322  * Single-precision complex version of XLALUnitaryWindowREAL8Sequence().
323  */
325 {
326  unsigned i;
327  double norm = sqrt(window->data->length / window->sumofsquares);
328 
329  if(window->sumofsquares <= 0)
331  if(sequence->length != window->data->length)
333 
334  for(i = 0; i < window->data->length; i++)
335  sequence->data[i] *= window->data->data[i] * norm;
336 
337  return sequence;
338 }
339 
340 
341 /*
342  * ============================================================================
343  *
344  * REAL8Window
345  *
346  * ============================================================================
347  */
348 
349 
351 {
352  REAL8Sequence *sequence;
353  UINT4 i;
354 
355  sequence = XLALCreateREAL8Sequence(length);
356  if(!sequence)
358 
359  /* flat, box-car, top-hat, rectangle, whatever */
360  for(i = 0; i < length; i++)
361  sequence->data[i] = 1;
362 
363  return XLALCreateREAL8WindowFromSequence(sequence);
364 }
365 
366 
368 {
369  REAL8Sequence *sequence;
370  UINT4 i;
371 
372  sequence = XLALCreateREAL8Sequence(length);
373  if(!sequence)
375 
376  /* cos^2, zero at both end points, 1 in the middle */
377  for(i = 0; i < (length + 1) / 2; i++)
378  sequence->data[i] = sequence->data[length - 1 - i] = pow(sin(LAL_PI_2 * (Y(length, i) + 1)), 2);
379 
380  return XLALCreateREAL8WindowFromSequence(sequence);
381 }
382 
383 
385 {
386  REAL8Sequence *sequence;
387  UINT4 i;
388 
389  sequence = XLALCreateREAL8Sequence(length);
390  if(!sequence)
392 
393  /* downward-opening parabola, zero at both end points, 1 in the
394  * middle */
395  for(i = 0; i < (length + 1) / 2; i++)
396  sequence->data[i] = sequence->data[length - 1 - i] = 1 - pow(Y(length, i), 2.0);
397 
398  return XLALCreateREAL8WindowFromSequence(sequence);
399 }
400 
401 
403 {
404  REAL8Sequence *sequence;
405  UINT4 i;
406 
407  sequence = XLALCreateREAL8Sequence(length);
408  if(!sequence)
410 
411  /* downward-opening triangle, zero at both end points (non-zero end
412  * points is a different window called the "triangle" window), 1 in
413  * the middle */
414  for(i = 0; i < (length + 1) / 2; i++)
415  sequence->data[i] = sequence->data[length - 1 - i] = 1 + Y(length, i);
416 
417  return XLALCreateREAL8WindowFromSequence(sequence);
418 }
419 
420 
422 {
423  REAL8Sequence *sequence;
424  UINT4 i;
425 
426  sequence = XLALCreateREAL8Sequence(length);
427  if(!sequence)
429 
430  /* ?? Copied from LAL Software Description */
431  for(i = 0; i < (length + 1) / 4; i++)
432  sequence->data[i] = sequence->data[length - 1 - i] = 2 * pow(1 + Y(length, i), 3);
433  for(; i < (length + 1) / 2; i++) {
434  double y = Y(length, i);
435  sequence->data[i] = sequence->data[length - 1 - i] = 1 - 6 * y * y * (1 + y);
436  }
437 
438  return XLALCreateREAL8WindowFromSequence(sequence);
439 }
440 
441 
443 {
444  REAL8Sequence *sequence;
445  UINT4 i;
446 
447  sequence = XLALCreateREAL8Sequence(length);
448  if(!sequence)
450 
451  /* ?? Copied from LAL Software Description */
452  for(i = 0; i < (length + 1) / 2; i++) {
453  double y = Y(length, i);
454  sequence->data[i] = sequence->data[length - 1 - i] = (1 + y) * cos(LAL_PI * y) - sin(LAL_PI * y) / LAL_PI;
455  }
456 
457  return XLALCreateREAL8WindowFromSequence(sequence);
458 }
459 
460 
462 {
463  REAL8Sequence *sequence;
464  UINT4 i;
465 
466  sequence = XLALCreateREAL8Sequence(length);
467  if(!sequence)
469 
470  /* cos^2, like Hann window, but with a bias of 0.08 */
471  for(i = 0; i < (length + 1) / 2; i++)
472  sequence->data[i] = sequence->data[length - 1 - i] = 0.08 + 0.92 * pow(cos(LAL_PI_2 * Y(length, i)), 2);
473 
474  return XLALCreateREAL8WindowFromSequence(sequence);
475 }
476 
477 
479 {
480  REAL8Sequence *sequence;
481  REAL8 I0beta=0;
482  UINT4 i;
483 
484  if(beta < 0)
486 
487  sequence = XLALCreateREAL8Sequence(length);
488  if(!sequence)
490 
491  /* pre-compute I0(beta) */
492  if(beta < 705)
493  I0beta = gsl_sf_bessel_I0(beta);
494 
495  /* I0(beta sqrt(1 - y^2)) / I0(beta)
496  *
497  * note that in many places the window is defined with pi
498  * multiplying beta in the numerator and denominator, but not here.
499  * beta=0 --> top-hat window.
500  *
501  * The asymptotic forms for large beta are derived from the
502  * asymptotic form of I0(x) which is
503  *
504  * I0(x) --> exp(x) / sqrt(2 pi x)
505  *
506  * Although beta may be large, beta sqrt(1 - y^2) can be small
507  * (when y ~= +/- 1), so there is a need for two asymptotic forms:
508  * one for large beta alone, and one for large beta sqrt(1 - y^2).
509  *
510  * When beta alone is large,
511  *
512  * w(y) = I0(beta sqrt(1 - y^2)) sqrt(2 pi beta) / exp(beta)
513  *
514  * and when beta sqrt(1 - y^2) is large,
515  *
516  * w(y) = exp(-beta * (1 - sqrt(1 - y^2))) / sqrt(1 - y^2)
517  *
518  * As a function of beta, the asymptotic approximation and the
519  * "exact" form are found to disagree by about 20% in the y = +/- 1
520  * bins near the edge of the "exact" form's domain of validity. To
521  * smooth this out, a linear transition to the asymptotic form
522  * occurs between beta = 695 and beta = 705. */
523 
524  for(i = 0; i < (length + 1) / 2; i++) {
525  double y = Y(length, i);
526  double x = sqrt(1 - y * y);
527  double w1=0, w2=0;
528 
529  if(beta < 705)
530  w1 = gsl_sf_bessel_I0(beta * x) / I0beta;
531  if(beta >= 695) {
532  /* FIXME: should an interpolation be done across
533  * the transition from small beta x to large beta
534  * x? */
535  /* Note: the inf * 0 when beta = inf and y = +/- 1
536  * needs to be hard-coded */
537  if(beta * x < 700)
538  w2 = y == 0 ? 1 : gsl_sf_bessel_I0(beta * x) * sqrt(LAL_2_PI * beta) / exp(beta);
539  else
540  /* Note: when beta = inf, the inf * 0 in
541  * the y = 0 sample must be hard-coded,
542  * which we do by simply testing for y = 0.
543  * And when beta = inf and x = 0 (y = +/-
544  * 1), the conditional goes onto this
545  * branch, and results in a 0/0 which we
546  * have to hard-code */
547  w2 = y == 0 ? 1 : x == 0 ? 0 : exp(-beta * (1 - x)) / sqrt(x);
548  }
549 
550  if(beta < 695)
551  sequence->data[i] = sequence->data[length - 1 - i] = w1;
552  else if(beta < 705) {
553  double r = (beta - 695) / (705 - 695);
554  sequence->data[i] = sequence->data[length - 1 - i] = (1 - r) * w1 + r * w2;
555  } else
556  sequence->data[i] = sequence->data[length - 1 - i] = w2;
557  }
558 
559  return XLALCreateREAL8WindowFromSequence(sequence);
560 }
561 
562 
564 {
565  REAL8Sequence *sequence;
566  UINT4 i;
567 
568  if(beta < 0)
570 
571  sequence = XLALCreateREAL8Sequence(length);
572  if(!sequence)
574 
575  /* ?? Copied from LAL Software Description */
576  for(i = 0; i < (length + 1) / 2; i++) {
577  double y = Y(length, i);
578  /* NOTE: divide-by-zero in y^2 / (1 - y^2) when i = 0
579  * seems to work out OK. It's well-defined algebraically,
580  * but I'm surprised the FPU doesn't complain. The 0/0
581  * when beta = i = 0 has to be hard-coded, as does the inf
582  * * 0 when beta = inf and y = 0 (which is done by just
583  * checking for y = 0). The fabs() is there because Macs,
584  * with optimizations turned on, incorrectly state that
585  * 1-y^2 = -0 when y = 1, which converts the argument of
586  * exp() from -inf to +inf, and causes the window to
587  * evaluate to +inf instead of 0 at the end points. See
588  * also the -0 at the end points of the Welch window on
589  * Macs. */
590  sequence->data[i] = sequence->data[length - 1 - i] = (beta == 0 && y == -1) || y == 0 ? 1 : exp(-beta * y * y / fabs(1 - y * y));
591  }
592 
593  return XLALCreateREAL8WindowFromSequence(sequence);
594 }
595 
596 
598 {
599  REAL8Sequence *sequence;
600  UINT4 transition_length = round(beta * length);
601  UINT4 i;
602 
603  if(beta < 0 || beta > 1)
605 
606  sequence = XLALCreateREAL8Sequence(length);
607  if(!sequence)
609 
610  /* 1.0 and flat in the middle, cos^2 transition at each end, zero
611  * at end points, 0.0 <= beta <= 1.0 sets what fraction of the
612  * window is transition (0 --> rectangle window, 1 --> Hann window)
613  * */
614  for(i = 0; i < (transition_length + 1) / 2; i++)
615  sequence->data[i] = sequence->data[length - 1 - i] = pow(cos(LAL_PI_2 * Y(transition_length, i)), 2);
616  for(; i < (length + 1) / 2; i++)
617  sequence->data[i] = sequence->data[length - 1 - i] = 1;
618 
619  return XLALCreateREAL8WindowFromSequence(sequence);
620 }
621 
622 
624 {
625  REAL8Sequence *sequence;
626  UINT4 i;
627 
628  if(beta < 0)
630 
631  sequence = XLALCreateREAL8Sequence(length);
632  if(!sequence)
634 
635  /* pre-compute -1/2 beta^2 */
636  beta = -0.5 * beta * beta;
637 
638  /* exp(-1/2 beta^2 y^2) */
639  for(i = 0; i < (length + 1) / 2; i++) {
640  double y = Y(length, i);
641  /* Note: we have to hard-code the 0 * inf when y = 0 and
642  * beta = inf, which we do by simply checking for y = 0 */
643  sequence->data[i] = sequence->data[length - 1 - i] = y == 0 ? 1 : exp(y * y * beta);
644  }
645 
646  return XLALCreateREAL8WindowFromSequence(sequence);
647 }
648 
649 
651 {
652  REAL8Sequence *sequence = XLALCreateREAL8Sequence(length);
653  UINT4 i;
654 
655  if(!sequence)
657 
658  /* sin(pi y) / (pi y) */
659  for(i = 0; i < length; i++) {
660  double pi_y = LAL_PI * Y(length, i);
661  sequence->data[i] = pi_y != 0. ? sin(pi_y) / pi_y : 1.0;
662  }
663 
664  return XLALCreateREAL8WindowFromSequence(sequence);
665 }
666 
667 
669 {
670  if(window)
672  XLALFree(window);
673 }
674 
675 
676 /*
677  * ============================================================================
678  *
679  * REAL4Window
680  *
681  * ============================================================================
682  */
683 
684 
686 {
688 }
689 
690 
692 {
694 }
695 
696 
698 {
700 }
701 
702 
704 {
706 }
707 
708 
710 {
712 }
713 
714 
716 {
718 }
719 
720 
722 {
724 }
725 
726 
728 {
730 }
731 
732 
734 {
736 }
737 
738 
740 {
742 }
743 
744 
746 {
748 }
749 
750 
752 {
754 }
755 
756 
758 {
759  if(window)
761  XLALFree(window);
762 }
763 
764 
765 /*
766  * ============================================================================
767  *
768  * Get Windows by Name
769  *
770  * ============================================================================
771  */
772 
773 
774 typedef enum tagLALWindowType
775  {
790 
791 const struct {
792  const char *const name; /**< window name */
793  const BOOLEAN hasBeta; /**< does this window need a 'beta' parameter? */
795 
796  [LAL_WINDOWTYPE_RECTANGULAR] = { "rectangular", 0 },
797  [LAL_WINDOWTYPE_HANN] = { "hann", 0 },
798  [LAL_WINDOWTYPE_WELCH] = { "welch", 0 },
799  [LAL_WINDOWTYPE_BARTLETT] = { "bartlett", 0 },
800  [LAL_WINDOWTYPE_PARZEN] = { "parzen", 0 },
801  [LAL_WINDOWTYPE_PAPOULIS] = { "papoulis", 0 },
802  [LAL_WINDOWTYPE_HAMMING] = { "hamming", 1 },
803  [LAL_WINDOWTYPE_KAISER] = { "kaiser", 1 },
804  [LAL_WINDOWTYPE_CREIGHTON] = { "creighton", 1 },
805  [LAL_WINDOWTYPE_TUKEY] = { "tukey", 1 },
806  [LAL_WINDOWTYPE_GAUSS] = { "gauss", 1 },
807  [LAL_WINDOWTYPE_LANCZOS] = { "lanczos", 0 },
808 };
809 
810 /**
811  * Parse window-name string (case-insensitive) into an internal
812  * window-type index (>=0, returned), and also check if the user-input 'beta'
813  * is valid for given window. Window-types that don't take a beta
814  * input parameter need to have beta==0.
815  *
816  * Returns XLAL_FAILURE=-1 on error
817  */
818 static int
819 XLALParseWindowNameAndCheckBeta ( const char *windowName, //< [in] window-name to parse
820  REAL8 beta //< [in] beta user-input, checked for validity
821  )
822 {
823  XLAL_CHECK ( windowName != NULL, XLAL_EINVAL );
824 
825  // convert input window-name into lower-case first
826  char windowNameLC [ strlen(windowName) + 1 ];
827  strcpy ( windowNameLC, windowName );
828  XLALStringToLowerCase ( windowNameLC );
829 
830  for ( UINT4 i = 0; i < LAL_WINDOWTYPE_LAST; i ++ )
831  {
832  if ( strcmp ( windowNameLC, AllowedWindows[i].name ) == 0 )
833  {
834  XLAL_CHECK ( AllowedWindows[i].hasBeta || (beta == 0 ), XLAL_EINVAL, "Invalid non-zero input beta=%g for window '%s'\n", beta, windowName );
835  return i;
836  }
837  } // for i < LAL_WINDOWTYPE_LAST
838 
839  // we only come here if no window-name matched
840  XLALPrintError ("Invalid Window-name '%s', allowed are (case-insensitive):\n[%s", windowName, AllowedWindows[0].name );
841  for ( UINT4 j = 1; j < LAL_WINDOWTYPE_LAST; j++ ) {
842  XLALPrintError (", %s", AllowedWindows[j].name );
843  }
844  XLALPrintError ("]\n");
845 
847 
848 } // XLALParseWindowNameAndCheckBeta()
849 
850 /**
851  * Check whether a named window-function exists and whether it requires a parameter
852  */
853 int
854 XLALCheckNamedWindow ( const char *windowName, const BOOLEAN haveBeta )
855 {
856 
857  int wintype = XLALParseWindowNameAndCheckBeta ( windowName, 0 );
858  XLAL_CHECK ( wintype >= 0, XLAL_EFUNC );
859 
860  if ( AllowedWindows[wintype].hasBeta ^ haveBeta ) {
862  "Inconsistent Window-option: '%s' requires parameter = %s, but user supplied parameter = %s\n",
863  AllowedWindows[wintype].name,
864  AllowedWindows[wintype].hasBeta ? "yes" : "no",
865  haveBeta ? "yes" : "no" );
866  }
867 
868  return XLAL_SUCCESS;
869 
870 } // XLALCheckNamedWindow()
871 
872 /**
873  * Generic window-function wrapper, allowing to select a window by its name.
874  * windowBeta must be set to '0' for windows without parameter.
875  */
876 REAL8Window *
877 XLALCreateNamedREAL8Window ( const char *windowName, REAL8 beta, UINT4 length )
878 {
879  XLAL_CHECK_NULL ( length > 0, XLAL_EINVAL );
880 
881  int wintype;
882  XLAL_CHECK_NULL ( (wintype = XLALParseWindowNameAndCheckBeta ( windowName, beta )) >= 0, XLAL_EFUNC );
883 
884  REAL8Window *win = NULL;
885  switch ( wintype )
886  {
888  win = XLALCreateRectangularREAL8Window ( length );
889  break;
890  case LAL_WINDOWTYPE_HANN:
891  win = XLALCreateHannREAL8Window ( length );
892  break;
894  win = XLALCreateWelchREAL8Window ( length );
895  break;
897  win = XLALCreateBartlettREAL8Window ( length );
898  break;
900  win = XLALCreateParzenREAL8Window ( length );
901  break;
903  win = XLALCreatePapoulisREAL8Window ( length );
904  break;
906  win = XLALCreateHammingREAL8Window ( length );
907  break;
909  win = XLALCreateKaiserREAL8Window ( length, beta );
910  break;
912  win = XLALCreateCreightonREAL8Window ( length, beta );
913  break;
915  win = XLALCreateTukeyREAL8Window ( length, beta );
916  break;
918  win = XLALCreateGaussREAL8Window ( length, beta );
919  break;
921  win = XLALCreateLanczosREAL8Window ( length );
922  break;
923  default:
924  XLAL_ERROR_NULL ( XLAL_EERR, "Internal ERROR: Invalid window-type '%d', must be within [0, %d]\n", wintype, LAL_WINDOWTYPE_LAST - 1 );
925  break;
926  } // switch(wintype)
927 
928  XLAL_CHECK_NULL (win != NULL, XLAL_EFUNC );
929 
930  return win;
931 
932 } /* XLALCreateNamedREAL8Window() */
933 
934 
935 REAL4Window *
936 XLALCreateNamedREAL4Window ( const char *windowName, REAL8 beta, UINT4 length )
937 {
938  return XLALREAL4Window_from_REAL8Window ( XLALCreateNamedREAL8Window ( windowName, beta, length ) );
939 }
static REAL8 sum_samples(REAL8 *start, int length)
Definition: Window.c:158
const BOOLEAN hasBeta
does this window need a 'beta' parameter?
Definition: Window.c:793
static double Y(int length, int i)
Maps the length of a window and the offset within the window to the "y" co-ordinate of the LAL docume...
Definition: Window.c:109
LALWindowType
Definition: Window.c:775
@ LAL_WINDOWTYPE_CREIGHTON
Definition: Window.c:784
@ LAL_WINDOWTYPE_WELCH
Definition: Window.c:778
@ LAL_WINDOWTYPE_LAST
Definition: Window.c:788
@ LAL_WINDOWTYPE_HAMMING
Definition: Window.c:782
@ LAL_WINDOWTYPE_KAISER
Definition: Window.c:783
@ LAL_WINDOWTYPE_LANCZOS
Definition: Window.c:787
@ LAL_WINDOWTYPE_PAPOULIS
Definition: Window.c:781
@ LAL_WINDOWTYPE_BARTLETT
Definition: Window.c:779
@ LAL_WINDOWTYPE_RECTANGULAR
Definition: Window.c:776
@ LAL_WINDOWTYPE_GAUSS
Definition: Window.c:786
@ LAL_WINDOWTYPE_PARZEN
Definition: Window.c:780
@ LAL_WINDOWTYPE_TUKEY
Definition: Window.c:785
@ LAL_WINDOWTYPE_HANN
Definition: Window.c:777
static int XLALParseWindowNameAndCheckBeta(const char *windowName, REAL8 beta)
Parse window-name string (case-insensitive) into an internal window-type index (>=0,...
Definition: Window.c:819
static REAL8 sum_squares(REAL8 *start, int length)
Computes the sum of squares, and sum, of the samples in a window function.
Definition: Window.c:128
const struct @16 AllowedWindows[LAL_WINDOWTYPE_LAST]
static REAL4Window * XLALREAL4Window_from_REAL8Window(REAL8Window *orig)
Constructs a REAL4Window from a REAL8Window by quantizing the double-precision data to single-precisi...
Definition: Window.c:58
const char *const name
window name
Definition: Window.c:792
int XLALPrintError(const char *fmt,...)
Definition: XLALError.c:68
#define LAL_PI_2
pi/2
Definition: LALConstants.h:181
#define LAL_2_PI
2/pi is Buffon's constant
Definition: LALConstants.h:184
#define LAL_PI
Archimedes's constant, pi.
Definition: LALConstants.h:179
unsigned char BOOLEAN
Boolean logical type, see Headers LAL(Atomic)Datatypes.h for more details.
double REAL8
Double precision real floating-point number (8 bytes).
uint32_t UINT4
Four-byte unsigned integer.
float REAL4
Single precision real floating-point number (4 bytes).
#define XLALMalloc(n)
Definition: LALMalloc.h:44
#define XLALFree(p)
Definition: LALMalloc.h:47
int XLALStringToLowerCase(char *string)
Turn a string in-place into lowercase without using locale-dependent functions.
Definition: LALString.c:153
static const INT4 r
Definition: Random.c:82
void XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
void XLALDestroyREAL4Sequence(REAL4Sequence *sequence)
REAL4Sequence * XLALCreateREAL4Sequence(size_t length)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
REAL8Window * XLALCreateWelchREAL8Window(UINT4 length)
Definition: Window.c:384
REAL4Window * XLALCreateTukeyREAL4Window(UINT4 length, REAL4 beta)
Definition: Window.c:739
REAL4Window * XLALCreateGaussREAL4Window(UINT4 length, REAL4 beta)
Definition: Window.c:745
REAL4Window * XLALCreateBartlettREAL4Window(UINT4 length)
Definition: Window.c:703
REAL4Window * XLALCreateRectangularREAL4Window(UINT4 length)
Definition: Window.c:685
REAL4Window * XLALCreateLanczosREAL4Window(UINT4 length)
Definition: Window.c:751
COMPLEX16Sequence * XLALUnitaryWindowCOMPLEX16Sequence(COMPLEX16Sequence *sequence, const REAL8Window *window)
Double-precision complex version of XLALUnitaryWindowREAL8Sequence().
Definition: Window.c:284
REAL4Window * XLALCreateKaiserREAL4Window(UINT4 length, REAL4 beta)
Definition: Window.c:727
REAL4Window * XLALCreateNamedREAL4Window(const char *windowName, REAL8 beta, UINT4 length)
Definition: Window.c:936
REAL8Window * XLALCreateNamedREAL8Window(const char *windowName, REAL8 beta, UINT4 length)
Generic window-function wrapper, allowing to select a window by its name.
Definition: Window.c:877
REAL8Window * XLALCreateRectangularREAL8Window(UINT4 length)
Definition: Window.c:350
REAL4Window * XLALCreateParzenREAL4Window(UINT4 length)
Definition: Window.c:709
REAL4Window * XLALCreateHannREAL4Window(UINT4 length)
Definition: Window.c:691
REAL4Window * XLALCreatePapoulisREAL4Window(UINT4 length)
Definition: Window.c:715
REAL4Window * XLALCreateHammingREAL4Window(UINT4 length)
Definition: Window.c:721
REAL4Window * XLALCreateCreightonREAL4Window(UINT4 length, REAL4 beta)
Definition: Window.c:733
REAL8Window * XLALCreateLanczosREAL8Window(UINT4 length)
Definition: Window.c:650
void XLALDestroyREAL8Window(REAL8Window *window)
Definition: Window.c:668
REAL8Window * XLALCreatePapoulisREAL8Window(UINT4 length)
Definition: Window.c:442
REAL8Window * XLALCreateHannREAL8Window(UINT4 length)
Definition: Window.c:367
COMPLEX8Sequence * XLALUnitaryWindowCOMPLEX8Sequence(COMPLEX8Sequence *sequence, const REAL4Window *window)
Single-precision complex version of XLALUnitaryWindowREAL8Sequence().
Definition: Window.c:324
REAL8Window * XLALCreateCreightonREAL8Window(UINT4 length, REAL8 beta)
Definition: Window.c:563
REAL4Sequence * XLALUnitaryWindowREAL4Sequence(REAL4Sequence *sequence, const REAL4Window *window)
Single-precision version of XLALUnitaryWindowREAL8Sequence().
Definition: Window.c:304
REAL8Sequence * XLALUnitaryWindowREAL8Sequence(REAL8Sequence *sequence, const REAL8Window *window)
Multiply a REAL8Sequence in-place by a REAL8Window with a normalization that preserves the variance o...
Definition: Window.c:264
int XLALCheckNamedWindow(const char *windowName, const BOOLEAN haveBeta)
Check whether a named window-function exists and whether it requires a parameter.
Definition: Window.c:854
REAL8Window * XLALCreateGaussREAL8Window(UINT4 length, REAL8 beta)
Definition: Window.c:623
void XLALDestroyREAL4Window(REAL4Window *window)
Definition: Window.c:757
REAL4Window * XLALCreateWelchREAL4Window(UINT4 length)
Definition: Window.c:697
REAL8Window * XLALCreateKaiserREAL8Window(UINT4 length, REAL8 beta)
Definition: Window.c:478
REAL8Window * XLALCreateBartlettREAL8Window(UINT4 length)
Definition: Window.c:402
REAL8Window * XLALCreateHammingREAL8Window(UINT4 length)
Definition: Window.c:461
REAL8Window * XLALCreateTukeyREAL8Window(UINT4 length, REAL8 beta)
Definition: Window.c:597
REAL4Window * XLALCreateREAL4WindowFromSequence(REAL4Sequence *sequence)
Single-precision version of XLALCreateREAL8WindowFromSequence().
Definition: Window.c:225
REAL8Window * XLALCreateREAL8WindowFromSequence(REAL8Sequence *sequence)
Constructs a new REAL8Window from a REAL8Sequence.
Definition: Window.c:204
REAL8Window * XLALCreateParzenREAL8Window(UINT4 length)
Definition: Window.c:421
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
Definition: XLALError.h:713
#define XLAL_ERROR(...)
Macro to invoke a failure from a XLAL routine returning an integer.
Definition: XLALError.h:700
#define XLAL_CHECK(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns an integ...
Definition: XLALError.h:810
#define XLAL_CHECK_NULL(assertion,...)
Macro to test an assertion and invoke a failure if it is not true in a function that returns a pointe...
Definition: XLALError.h:825
@ XLAL_EBADLEN
Inconsistent or invalid length.
Definition: XLALError.h:419
@ XLAL_SUCCESS
Success return value (not an error number)
Definition: XLALError.h:401
@ XLAL_ERANGE
Output range error.
Definition: XLALError.h:411
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_EERR
Internal error.
Definition: XLALError.h:443
@ XLAL_EDOM
Input domain error.
Definition: XLALError.h:410
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409
Vector of type COMPLEX16, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:172
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:176
COMPLEX16 * data
Pointer to the data array.
Definition: LALDatatypes.h:177
Vector of type COMPLEX8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:163
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:167
COMPLEX8 * data
Pointer to the data array.
Definition: LALDatatypes.h:168
Vector of type REAL4, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:145
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:150
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:149
Structure for storing REAL4 window function data, providing storage for a sequence of samples as well...
Definition: Window.h:243
REAL4Sequence * data
The window function samples.
Definition: Window.h:244
REAL8 sumofsquares
The sum of the squares of the window function samples.
Definition: Window.h:245
Vector of type REAL8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:154
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:159
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:158
Structure for storing REAL8 window function data, providing storage for a sequence of samples as well...
Definition: Window.h:254
REAL8Sequence * data
The window function samples.
Definition: Window.h:255
REAL8 sumofsquares
The sum of the squares of the window function samples.
Definition: Window.h:256
REAL8 sum
The sum of the window function samples.
Definition: Window.h:257