LAL  7.1.7.1-2d066e5
BilinearTransform.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton, Teviet Creighton
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #include <complex.h>
21 #include <lal/LALStdlib.h>
22 #include <lal/AVFactories.h>
23 #include <lal/VectorOps.h>
24 #include <lal/Sort.h>
25 #include <math.h>
26 #include <lal/ZPGFilter.h>
27 
28 #ifdef __GNUC__
29 #define UNUSED __attribute__ ((unused))
30 #else
31 #define UNUSED
32 #endif
33 
34 /**
35  * \addtogroup BilinearTransform_c
36  * \author Creighton, T. D.
37  *
38  * \brief Transforms the complex frequency coordinate of a ZPG filter.
39  *
40  * ### Description ###
41  *
42  * These functions perform an in-place bilinear transformation on an
43  * object <tt>*filter</tt> of type <tt><datatype>ZPGFilter</tt>, transforming
44  * from \f$w\f$ to \f$z=(1+iw)/(1-iw)\f$. Care is taken to ensure that zeros and
45  * poles at \f$w=\infty\f$ are correctly transformed to \f$z=-1\f$, and zeros and
46  * poles at \f$w=-i\f$ are correctly transformed to \f$z=\infty\f$. In addition
47  * to simply relocating the zeros and poles, residual factors are also
48  * incorporated into the gain of the filter (i.e.\ the leading
49  * coefficient of the rational function).
50  *
51  * ### Algorithm ###
52  *
53  * The vectors <tt>filter->zeros</tt> and <tt>filter->poles</tt> only record
54  * those zeros and poles that have finite value. If one includes the
55  * point \f$\infty\f$ on the complex plane, then a rational function always
56  * has the same number of zeros and poles: a number \c num that is
57  * the larger of <tt>z->zeros->length</tt> or <tt>z->poles->length</tt>. If
58  * one or the other vector has a smaller length, then after the
59  * transformation that vector will receive additional elements, with a
60  * complex value of \f$z=-1\f$, to bring its length up to \c num.
61  * However, each vector will then \e lose those elements that
62  * previously had values \f$w=-i\f$, (which are sent to \f$z=\infty\f$,) thus
63  * possibly decreasing the length of the vector. These routines handle
64  * this by simply allocating a new vector for the transformed data, and
65  * freeing the old vector after the transformation.
66  *
67  * When transforming a zero \f$w_k\f$ on the complex plane, one makes use of
68  * the identity:
69  * \f[
70  * (w - w_k) = -(w_k + i)\times\frac{z-z_k}{z+1} \; ,
71  * \f]
72  * and similarly, when transforming a pole at \f$w_k\f$,
73  * \f[
74  * (w - w_k)^{-1} = -(w_k + i)^{-1}\times\frac{z+1}{z-z_k} \; ,
75  * \f]
76  * where \f$z=(1+iw)/(1-iw)\f$ and \f$z_k=(1+iw_k)/(1-iw_k)\f$. If there are an
77  * equal number of poles and zeros being transformed, then the factors of
78  * \f$z+1\f$ will cancel; otherwise, the remaining factors correspond to the
79  * zeros or poles at \f$z=-1\f$ brought in from \f$w=\infty\f$. The factor
80  * \f$(z-z_k)\f$ represents the new position of the transformed zero or pole.
81  * The important factor to note, though, is the factor \f$-(w_k+i)^{\pm1}\f$.
82  * This factor represents the change in the gain <tt>filter->gain</tt>.
83  * When \f$w_k=-i\f$, the transformation is slightly different:
84  * \f[
85  * (w + i) = \frac{2i}{z+1} \; ;
86  * \f]
87  * thus the gain correction factor is \f$2i\f$ (rather than 0) in this case.
88  *
89  * The algorithm in this module computes and stores all the gain
90  * correction factors before applying them to the gain. The correction
91  * factors are sorted in order of absolute magnitude, and are multiplied
92  * together in small- and large-magnitude pairs. In this way one reduces
93  * the risk of overrunning the floating-point dynamical range during
94  * intermediate calculations.
95  *
96  * As a similar precaution, the routines in this module use the algorithm
97  * discussed in the \c VectorOps package whenever they perform
98  * complex division, to avoid intermediate results that may be the
99  * product of two large numbers. When transforming \f$z=(1+iw)/(1-iw)\f$,
100  * these routines also test for special cases (such as \f$w\f$ purely
101  * imaginary) that have qualitatively significant results (\f$z\f$ purely
102  * real), so that one doesn't end up with, for instance, an imaginary
103  * part of \f$10^{-12}\f$ instead of 0.
104  */
105 /** @{ */
106 
107 /*
108  * WARNING: NOT A PROPER COMPARE FUNCTION
109  * this returns -1 if abs(a)<abs(b), otherwise it returns 1 (don't check equal)
110  * also: don't worry about possible overflow
111  */
112 static int CompareCOMPLEX8Abs( void UNUSED *p, const void *a, const void *b )
113 {
114  REAL8 ar = crealf(*(const COMPLEX8 *)a);
115  REAL8 ai = cimagf(*(const COMPLEX8 *)a);
116  REAL8 br = crealf(*(const COMPLEX8 *)b);
117  REAL8 bi = cimagf(*(const COMPLEX8 *)b);
118  if ( (ar*ar+ai*ai) < (br*br+bi*bi) )
119  return -1;
120  return 1;
121 }
122 
123 /*
124  * WARNING: NOT A PROPER COMPARE FUNCTION
125  * this returns -1 if abs(a)<abs(b), otherwise it returns 1 (don't check equal)
126  * also: don't worry about possible overflow
127  */
128 static int CompareCOMPLEX16Abs( void UNUSED *p, const void *a, const void *b )
129 {
130  REAL8 ar = creal(*(const COMPLEX16 *)a);
131  REAL8 ai = cimag(*(const COMPLEX16 *)a);
132  REAL8 br = creal(*(const COMPLEX16 *)b);
133  REAL8 bi = cimag(*(const COMPLEX16 *)b);
134  if ( (ar*ar+ai*ai) < (br*br+bi*bi) )
135  return -1;
136  return 1;
137 }
138 
139 /** \see See \ref BilinearTransform_c for documentation */
141 {
142  INT4 i; /* A counter. */
143  INT4 j; /* Another counter. */
144  INT4 num; /* The total number of zeros or poles. */
145  INT4 numZeros; /* The number of finite zeros. */
146  INT4 numPoles; /* The number of finite poles. */
147  COMPLEX8 *a; /* A zero or pole in the w plane. */
148  COMPLEX8 *b; /* A zero or pole in the z plane. */
149  COMPLEX8 *g; /* A gain correction factor. */
150  COMPLEX8Vector *z=NULL; /* Vector of zeros or poles in z plane. */
151  COMPLEX8Vector *gain=NULL; /* Vector of gain correction factors. */
152  COMPLEX8Vector null; /* A vector of zero length. */
153  INT4Vector *idx=NULL; /* Index array for sorting absGain. */
154 
155  /* Make sure the filter pointer is non-null. */
156  if ( ! filter )
158 
159  /* If the filter->zeros or filter->poles pointers is null, this
160  means that there are no zeros or no poles. For simplicity, we
161  set the pointer to point to a vector of zero length. */
162  null.length=0;
163  null.data=NULL;
164  if(!filter->zeros)
165  filter->zeros=&null;
166  if(!filter->poles)
167  filter->poles=&null;
168 
169  /* Check that the vector lengths are non-negative, and, if positive,
170  that the vector data pointer is non-null. */
171  numZeros=filter->zeros->length;
172  if (numZeros<0)
174  if(numZeros>0)
175  if (!filter->zeros->data)
177  numPoles=filter->poles->length;
178  if (numPoles<0)
180  if(numPoles>0)
181  if (!filter->poles->data)
183 
184  /* Compute the total number of zeros and poles in the w-plane,
185  including those at w=infinity. */
186  num = (numZeros>numPoles) ? numZeros : numPoles;
187  numZeros=numPoles=num;
188 
189  /* If there are neither zeros nor poles, then there is nothing to
190  transform. (The <0 case should never occur if the ASSERT()
191  macros have done their job, but is included for extra safety.) */
192  if(num<=0){
193  filter->zeros=NULL;
194  filter->poles=NULL;
195  return 0;
196  }
197 
198  /* Compute the revised number of zeros and poles in the z-plane,
199  excluding those at z=infinity (w=-i). */
200  for(i=0,a=filter->zeros->data;i<(INT4)filter->zeros->length;i++,a++)
201  if((crealf(*a)==0.0)&&(cimagf(*a)==-1.0))
202  numZeros--;
203  for(i=0,a=filter->poles->data;i<(INT4)filter->poles->length;i++,a++)
204  if((crealf(*a)==0.0)&&(cimagf(*a)==-1.0))
205  numPoles--;
206 
207  /* Create the vector of gain correction factors. */
208  /* Create the new vector of zeros. */
209  gain=XLALCreateCOMPLEX8Vector(filter->zeros->length+filter->poles->length);
210  z=XLALCreateCOMPLEX8Vector(numZeros);
211  if (!gain||!z)
212  {
216  }
217  g=gain->data;
218  b=z->data;
219 
220  /* Transform existing zeros from w to z, except for those at w=-i,
221  which are mapped to z=infinity. At the same time, compute the
222  gain correction factors. */
223  for(i=0,j=0,a=filter->zeros->data;i<(INT4)filter->zeros->length;
224  i++,a++,g++){
225  REAL4 ar=crealf(*a);
226  REAL4 ai=cimagf(*a);
227  if(ar==0.0){
228  if(ai==-1.0){
229  /* w=-i is mapped to z=infinity. */
230  *g=2.0*I;
231  }else{
232  /* w=i*y is mapped to z=(1-y)/(1+y). */
233  *b=(1.0-ai)/(1.0+ai);
234  *g=-(1.0+ai)*I;
235  b++;
236  j++;
237  }
238  }else if(fabs(1.0+ai)>fabs(ar)){
239  REAL8 ratio = -ar/(1.0+ai);
240  REAL8 denom = 1.0+ai - ratio*ar;
241 
242  *b = (1.0-ai + ratio*ar)/denom;
243  *b += I*(ar - ratio*(1.0-ai))/denom;
244  *g = -ar;
245  *g += -(1.0+ai)*I;
246  b++;
247  j++;
248  }else{
249  REAL8 ratio = -(1.0+ai)/ar;
250  REAL8 denom = -ar + ratio*(1.0+ai);
251 
252  *b = ((1.0-ai)*ratio + ar)/denom;
253  *b += I*(ar*ratio - 1.0+ai)/denom;
254  *g = -ar;
255  *g = -(1.0+ai)*I;
256  b++;
257  j++;
258  }
259  }
260  /* Transform any remaining zeros at w=infinity to z=-1. */
261  for(;j<numZeros;b++,j++){
262  *b = -1.0;
263  }
264  /* Replace the old filter zeros with the new ones. */
265  if(filter->zeros->length>0)
267  filter->zeros=z;
268  z=NULL;
269 
270  /* Create the new vector of poles. */
271  z=XLALCreateCOMPLEX8Vector(numPoles);
272  if (!gain||!z)
273  {
276  }
277  b=z->data;
278  /* Transform existing poles from w to z, except for those at w=-i,
279  which are mapped to z=infinity. At the same time, compute the
280  gain correction factors. */
281  for(i=0,j=0,a=filter->poles->data;i<(INT4)filter->poles->length;
282  i++,a++,g++){
283  REAL4 ar=crealf(*a);
284  REAL4 ai=cimagf(*a);
285  if(ar==0.0){
286  if(ai==-1.0){
287  /* w=-i is mapped to z=infinity. */
288  *g=-0.5*I;
289  }else{
290  /* w=i*y is mapped to z=(1-y)/(1+y). */
291  *b=(1.0-ai)/(1.0+ai);
292  *g=I*1.0/(1.0+ai);
293  b++;
294  j++;
295  }
296  }else if(fabs(1.0+ai)>fabs(ar)){
297  REAL8 ratio = -ar/(1.0+ai);
298  REAL8 denom = 1.0+ai - ratio*ar;
299 
300  *b = (1.0-ai + ratio*ar)/denom;
301  *b += I*(ar - ratio*(1.0-ai))/denom;
302  *g = ratio/denom;
303  *g += I*1.0/denom;
304  b++;
305  j++;
306  }else{
307  REAL8 ratio = -(1.0+ai)/ar;
308  REAL8 denom = -ar + ratio*(1.0+ai);
309 
310  *b = ((1.0-ai)*ratio + ar)/denom;
311  *b += I*(ar*ratio - 1.0+ai)/denom;
312  *g = ratio/denom;
313  *g += I*1.0/denom;
314  b++;
315  j++;
316  }
317  }
318  /* Transform any remaining poles at w=infinity to z=-1. */
319  for(;j<numPoles;b++,j++){
320  *b = -1.0;
321  }
322  /* Replace the old filter poles with the new ones. */
323  if(filter->poles->length>0)
325  filter->poles=z;
326  z=NULL;
327 
328  /* To avoid numerical overflow when applying the gain correction
329  factors, we should multiply alternately by large and small
330  factors. Create an idx vector that indexes the magnitudes
331  from small to large. */
332  idx=XLALCreateINT4Vector(gain->length);
333  if(!idx||XLALHeapIndex(idx->data,gain->data,gain->length,sizeof(*gain->data),NULL,CompareCOMPLEX8Abs)<0)
334  {
338  }
339 
340  /* Now multiply the gain alternately by small and large correction
341  factors. */
342  for(i=0,j=gain->length-1;i<j;i++,j--){
343  /* Multiply the small and largest factors together. */
344  /* Multiply the gain by the combined factor. */
345  filter->gain *= gain->data[idx->data[i]] * gain->data[idx->data[j]];
346  }
347  if(i==j){
348  /* Multiply by the remaining odd factor. */
349  filter->gain *= gain->data[idx->data[i]];
350  }
351 
352  /* Free remaining temporary vectors, and exit. */
355  return 0;
356 }
357 
358 /** \see See \ref BilinearTransform_c for documentation */
360 {
361  INT4 i; /* A counter. */
362  INT4 j; /* Another counter. */
363  INT4 num; /* The total number of zeros or poles. */
364  INT4 numZeros; /* The number of finite zeros. */
365  INT4 numPoles; /* The number of finite poles. */
366  COMPLEX16 *a; /* A zero or pole in the w plane. */
367  COMPLEX16 *b; /* A zero or pole in the z plane. */
368  COMPLEX16 *g; /* A gain correction factor. */
369  COMPLEX16Vector *z=NULL; /* Vector of zeros or poles in z plane. */
370  COMPLEX16Vector *gain=NULL; /* Vector of gain correction factors. */
371  COMPLEX16Vector null; /* A vector of zero length. */
372  INT4Vector *idx=NULL; /* Index array for sorting absGain. */
373 
374  /* Make sure the filter pointer is non-null. */
375  if ( ! filter )
377 
378  /* If the filter->zeros or filter->poles pointers is null, this
379  means that there are no zeros or no poles. For simplicity, we
380  set the pointer to point to a vector of zero length. */
381  null.length=0;
382  null.data=NULL;
383  if(!filter->zeros)
384  filter->zeros=&null;
385  if(!filter->poles)
386  filter->poles=&null;
387 
388  /* Check that the vector lengths are non-negative, and, if positive,
389  that the vector data pointer is non-null. */
390  numZeros=filter->zeros->length;
391  if (numZeros<0)
393  if(numZeros>0)
394  if (!filter->zeros->data)
396  numPoles=filter->poles->length;
397  if (numPoles<0)
399  if(numPoles>0)
400  if (!filter->poles->data)
402 
403  /* Compute the total number of zeros and poles in the w-plane,
404  including those at w=infinity. */
405  num = (numZeros>numPoles) ? numZeros : numPoles;
406  numZeros=numPoles=num;
407 
408  /* If there are neither zeros nor poles, then there is nothing to
409  transform. (The <0 case should never occur if the ASSERT()
410  macros have done their job, but is included for extra safety.) */
411  if(num<=0){
412  filter->zeros=NULL;
413  filter->poles=NULL;
414  return 0;
415  }
416 
417  /* Compute the revised number of zeros and poles in the z-plane,
418  excluding those at z=infinity (w=-i). */
419  for(i=0,a=filter->zeros->data;i<(INT4)filter->zeros->length;i++,a++)
420  if((creal(*a)==0.0)&&(cimag(*a)==-1.0))
421  numZeros--;
422  for(i=0,a=filter->poles->data;i<(INT4)filter->poles->length;i++,a++)
423  if((creal(*a)==0.0)&&(cimag(*a)==-1.0))
424  numPoles--;
425 
426  /* Create the vector of gain correction factors. */
427  /* Create the new vector of zeros. */
428  gain=XLALCreateCOMPLEX16Vector(filter->zeros->length+filter->poles->length);
429  z=XLALCreateCOMPLEX16Vector(numZeros);
430  if (!gain||!z)
431  {
435  }
436  g=gain->data;
437  b=z->data;
438 
439  /* Transform existing zeros from w to z, except for those at w=-i,
440  which are mapped to z=infinity. At the same time, compute the
441  gain correction factors. */
442  for(i=0,j=0,a=filter->zeros->data;i<(INT4)filter->zeros->length;
443  i++,a++,g++){
444  REAL8 ar=creal(*a);
445  REAL8 ai=cimag(*a);
446  if(ar==0.0){
447  if(ai==-1.0){
448  /* w=-i is mapped to z=infinity. */
449  *g=2.0*I;
450  }else{
451  /* w=i*y is mapped to z=(1-y)/(1+y). */
452  *b=(1.0-ai)/(1.0+ai);
453  *g=-(1.0+ai)*I;
454  b++;
455  j++;
456  }
457  }else if(fabs(1.0+ai)>fabs(ar)){
458  REAL8 ratio = -ar/(1.0+ai);
459  REAL8 denom = 1.0+ai - ratio*ar;
460 
461  *b = (1.0-ai + ratio*ar)/denom;
462  *b += I*(ar - ratio*(1.0-ai))/denom;
463  *g = -ar;
464  *g += -(1.0+ai)*I;
465  b++;
466  j++;
467  }else{
468  REAL8 ratio = -(1.0+ai)/ar;
469  REAL8 denom = -ar + ratio*(1.0+ai);
470 
471  *b = ((1.0-ai)*ratio + ar)/denom;
472  *b += I*(ar*ratio - 1.0+ai)/denom;
473  *g = -ar;
474  *g += -(1.0+ai)*I;
475  b++;
476  j++;
477  }
478  }
479  /* Transform any remaining zeros at w=infinity to z=-1. */
480  for(;j<numZeros;b++,j++){
481  *b = -1.0;
482  }
483  /* Replace the old filter zeros with the new ones. */
484  if(filter->zeros->length>0)
486  filter->zeros=z;
487  z=NULL;
488 
489  /* Create the new vector of poles. */
490  z=XLALCreateCOMPLEX16Vector(numPoles);
491  if (!gain||!z)
492  {
495  }
496  b=z->data;
497  /* Transform existing poles from w to z, except for those at w=-i,
498  which are mapped to z=infinity. At the same time, compute the
499  gain correction factors. */
500  for(i=0,j=0,a=filter->poles->data;i<(INT4)filter->poles->length;
501  i++,a++,g++){
502  REAL8 ar=creal(*a);
503  REAL8 ai=cimag(*a);
504  if(ar==0.0){
505  if(ai==-1.0){
506  /* w=-i is mapped to z=infinity. */
507  *g=-0.5*I;
508  }else{
509  /* w=i*y is mapped to z=(1-y)/(1+y). */
510  *b=(1.0-ai)/(1.0+ai);
511  *g=I*1.0/(1.0+ai);
512  b++;
513  j++;
514  }
515  }else if(fabs(1.0+ai)>fabs(ar)){
516  REAL8 ratio = -ar/(1.0+ai);
517  REAL8 denom = 1.0+ai - ratio*ar;
518 
519  *b = (1.0-ai + ratio*ar)/denom;
520  *b += I*(ar - ratio*(1.0-ai))/denom;
521  *g = ratio/denom;
522  *g += I*1.0/denom;
523  b++;
524  j++;
525  }else{
526  REAL8 ratio = -(1.0+ai)/ar;
527  REAL8 denom = -ar + ratio*(1.0+ai);
528 
529  *b = ((1.0-ai)*ratio + ar)/denom;
530  *b += I*(ar*ratio - 1.0+ai)/denom;
531  *g = ratio/denom;
532  *g += I*1.0/denom;
533  b++;
534  j++;
535  }
536  }
537  /* Transform any remaining poles at w=infinity to z=-1. */
538  for(;j<numPoles;b++,j++){
539  *b = -1.0;
540  }
541  /* Replace the old filter poles with the new ones. */
542  if(filter->poles->length>0)
544  filter->poles=z;
545  z=NULL;
546 
547  /* To avoid numerical overflow when applying the gain correction
548  factors, we should multiply alternately by large and small
549  factors. Create an idx vector that indexes the magnitudes
550  from small to large. */
551  idx=XLALCreateINT4Vector(gain->length);
552  if(!idx||XLALHeapIndex(idx->data,gain->data,gain->length,sizeof(*gain->data),NULL,CompareCOMPLEX16Abs)<0)
553  {
557  }
558 
559  /* Now multiply the gain alternately by small and large correction
560  factors. */
561  for(i=0,j=gain->length-1;i<j;i++,j--){
562  /* Multiply the small and largest factors together. */
563  /* Multiply the gain by the combined factor. */
564  filter->gain *= gain->data[idx->data[i]] * gain->data[idx->data[j]];
565  }
566  if(i==j){
567  /* Multiply by the remaining odd factor. */
568  filter->gain *= gain->data[idx->data[i]];
569  }
570 
571  /* Free remaining temporary vectors, and exit. */
574  return 0;
575 }
576 
577 
578 /**
579  * Deprecated.
580  * \deprecated Use XLALWToZCOMPLEX8ZPGFilter() instead
581  */
582 void
584  COMPLEX8ZPGFilter *filter )
585 {
586  INITSTATUS(stat);
587 
588  if(XLALWToZCOMPLEX8ZPGFilter(filter)<0)
589  {
590  int code=xlalErrno;
591  XLALClearErrno();
592  switch(code){
593  case XLAL_EFAULT:
595  case XLAL_EINVAL:
597  default:
598  ABORTXLAL(stat);
599  }
600  }
601 
602  RETURN(stat);
603 }
604 
605 
606 /**
607  * Deprecated.
608  * \deprecated Use XLALWToZCOMPLEX16ZPGFilter() instead
609  */
610 void
612  COMPLEX16ZPGFilter *filter )
613 {
614  INITSTATUS(stat);
615 
616  if(XLALWToZCOMPLEX16ZPGFilter(filter)<0)
617  {
618  int code=xlalErrno;
619  XLALClearErrno();
620  switch(code){
621  case XLAL_EFAULT:
623  case XLAL_EINVAL:
625  default:
626  ABORTXLAL(stat);
627  }
628  }
629 
630  RETURN(stat);
631 }
632 /** @} */
#define ZPGFILTERH_EBAD
Bad filter parameters.
Definition: ZPGFilter.h:106
int XLALWToZCOMPLEX16ZPGFilter(COMPLEX16ZPGFilter *filter)
#define xlalErrno
Modifiable lvalue containing the XLAL error number.
Definition: XLALError.h:572
void XLALDestroyINT4Vector(INT4Vector *vector)
COMPLEX8Vector * zeros
Definition: LALDatatypes.h:924
void XLALDestroyCOMPLEX16Vector(COMPLEX16Vector *vector)
int XLALWToZCOMPLEX8ZPGFilter(COMPLEX8ZPGFilter *filter)
#define XLAL_ERROR(...)
Macro to invoke a failure from a XLAL routine returning an integer.
Definition: XLALError.h:701
float complex COMPLEX8
Single-precision floating-point complex number (8 bytes total)
See DATATYPE-ZPGFilter types for details.
Definition: LALDatatypes.h:930
#define ZPGFILTERH_ENUL
Unexpected null pointer in arguments.
Definition: ZPGFilter.h:103
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:176
See DATATYPE-ZPGFilter types for details.
Definition: LALDatatypes.h:921
static const INT4 a
Definition: Random.c:79
float REAL4
Single precision real floating-point number (4 bytes).
Vector of type COMPLEX16, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:172
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
COMPLEX8Vector * XLALCreateCOMPLEX8Vector(UINT4 length)
void LALWToZCOMPLEX8ZPGFilter(LALStatus *stat, COMPLEX8ZPGFilter *filter)
Deprecated.
#define RETURN(statusptr)
#define INITSTATUS(statusptr)
int XLALClearErrno(void)
Clears the XLAL error number, returns the old value.
Definition: XLALError.c:363
int XLALHeapIndex(INT4 *indx, void *base, UINT4 nobj, UINT4 size, void *params, int(*compar)(void *, const void *, const void *))
Definition: HeapSort.c:98
Invalid pointer.
Definition: XLALError.h:409
COMPLEX16Vector * zeros
Definition: LALDatatypes.h:933
void LALWToZCOMPLEX16ZPGFilter(LALStatus *stat, COMPLEX16ZPGFilter *filter)
Deprecated.
double REAL8
Double precision real floating-point number (8 bytes).
#define ABORT(statusptr, code, mesg)
COMPLEX16 * data
Pointer to the data array.
Definition: LALDatatypes.h:177
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
Vector of type INT4, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:109
INT4 * data
Pointer to the data array.
Definition: LALDatatypes.h:114
COMPLEX16Vector * poles
Definition: LALDatatypes.h:934
double complex COMPLEX16
Double-precision floating-point complex number (16 bytes total)
COMPLEX8Vector * poles
Definition: LALDatatypes.h:925
static int CompareCOMPLEX16Abs(void UNUSED *p, const void *a, const void *b)
#define ZPGFILTERH_MSGEBAD
Definition: ZPGFilter.h:113
#define ABORTXLAL(sp)
COMPLEX16Vector * XLALCreateCOMPLEX16Vector(UINT4 length)
#define ZPGFILTERH_MSGENUL
Definition: ZPGFilter.h:110
int32_t INT4
Four-byte signed integer.
void XLALDestroyCOMPLEX8Vector(COMPLEX8Vector *vector)
static int CompareCOMPLEX8Abs(void UNUSED *p, const void *a, const void *b)
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:463
Invalid argument.
Definition: XLALError.h:410
COMPLEX8 * data
Pointer to the data array.
Definition: LALDatatypes.h:168
INT4Vector * XLALCreateINT4Vector(UINT4 length)