Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALInspiral 5.0.3.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALInspiralIIR.c
Go to the documentation of this file.
1/*
2
3 This code relates to Infinite Impulse Response filters that correspond to an
4 inspiral waveform. The idea is that a sum a set of delayed first order IIR
5 filters with one feedback coefficient (a1) and one feedforward (b0)
6 coefficient that will approximate the correlation of the input data and the
7 inspiral waveform.
8
9 I.E the total impulse response is approximately a time reversed inspiral
10 waveform.
11
12 To generate the IIR set of a1's, b0's and delays, you need to provide a
13 amplitude and phase time series.
14
15 Created by Shaun Hooper 2010-05-28
16
17*/
18
19#include <lal/LALInspiral.h>
20#include <math.h>
21
23{
24 REAL8 xabs = fabs(creal(z));
25 REAL8 yabs = fabs(cimag(z));
26 REAL8 max, u;
27 if (xabs >= yabs)
28 {
29 max = xabs;
30 u = yabs / xabs;
31 }
32 else
33 {
34 max = yabs;
35 u = xabs / yabs;
36 }
37 return log(max) + 0.5 * log1p(u * u);
38}
39
40int XLALInspiralGenerateIIRSet(REAL8Vector *amp, REAL8Vector *phase, double epsilon, double alpha, double beta, double padding, COMPLEX16Vector **a1, COMPLEX16Vector **b0, INT4Vector **delay)
41{
42 int j = amp->length-1, jstep, jstepThird, k;
43 int nfilters = 0, decimationFactor = 1;
44 double phase_tdot, phase_ddot, phase_dot;
45
46 //printf("This is confirming that the LALInspiralIIR.c code has been successfully modified");
47 /* FIXME: Add error checking for lengths of amp and phase */
48 if (amp->length != phase->length)
50
53 *delay = XLALCreateINT4Vector(0);
54
55 //printf("This is the modified code\n");
56
57 while (j > 3 ) {
58 //int prej = j;
59 /* Reset j so that the delay will be an integar number of decimated rate */
60 //j = amp->length-1 - (int) floor((amp->length-1-j)/(double) decimationFactor + 0.5)*decimationFactor;
61
62 /* Get second derivative term */
63 phase_ddot = (phase->data[j-2] - 2.0 * phase->data[j-1] + phase->data[j]) / (2.0 * LAL_PI);
64 phase_tdot = (phase->data[j-3] - 3.0 * phase->data[j-2] + 3.0 * phase->data[j-1] - phase->data[j]) / (2.0*LAL_PI);
65 phase_ddot = fabs(phase_ddot);
66 phase_tdot = fabs(phase_tdot);
67
68 if (phase_ddot < 0 || phase_ddot > 8*epsilon){
69 j = j - 1;
70 continue;
71 }
72
73 jstep = (int) fabs(floor(sqrt(2.0 * epsilon / fabs(phase_ddot))+0.5));
74 jstepThird = (int) fabs(floor(pow(6.0 * epsilon / fabs(phase_tdot),1./3)+0.5));
75 jstep = abs(jstep);
76 jstepThird = abs(jstepThird);
77
78 //jstepThird integer overflow??
79 if(jstep > jstepThird && jstepThird >0){
80 jstep = jstepThird;
81 }
82 if(jstep == 0){
83 jstep = 1;
84 }
85 k = (int ) floor((double ) j - alpha * (double ) jstep + 0.5);
86 if (k < 1){
87 jstep = j;
88 k = (int ) floor((double ) j - alpha * (double ) jstep + 0.5);
89 }
90 //printf("jstep: %d jstepThird: %d k: %d j:%d \n ", jstep, jstepThird, k, j);
91
92
93 if(k == 0){
94 k = 1;
95 }
96
97
98 if (k <= 2) break;
99 nfilters++;
100
101 if (k > (int) amp->length-3) {
102 phase_dot = (11.0/6.0*phase->data[k] - 3.0*phase->data[k-1] + 1.5*phase->data[k-2] - 1.0/3.0*phase->data[k-3]);
103 }
104 else {
105 phase_dot = (-phase->data[k+2] + 8 * (phase->data[k+1] - phase->data[k-1]) + phase->data[k-2]) / 12.0; // Five-point stencil first derivative of phase
106 }
107 //fprintf(stderr, "%3.0d, %6.0d, %3.0d, %11.2f, %11.8f\n",nfilters, amp->length-1-j, decimationFactor, ((double) (amp->length-1-j))/((double) decimationFactor), phase_dot/(2.0*LAL_PI)*2048.0);
108 decimationFactor = ((int ) pow(2.0,-ceil(log(2.0*padding*phase_dot/(2.0*LAL_PI))/log(2.0))));
109 if (decimationFactor < 1 ) decimationFactor = 1;
110
111 //fprintf(stderr, "filter = %d, prej = %d, j = %d, k=%d, jstep = %d, decimation rate = %d, nFreq = %e, phase[k] = %e\n", nfilters, prej, j, k, jstep, decimationFactor, phase_dot/(2.0*LAL_PI), phase->data[k]);
112 /* FIXME: Should think about being smarter about allocating memory for these (linked list??) */
113 *a1 = XLALResizeCOMPLEX16Vector(*a1, nfilters);
114 *b0 = XLALResizeCOMPLEX16Vector(*b0, nfilters);
115 *delay = XLALResizeINT4Vector(*delay, nfilters);
116
117 /* Record a1, b0 and delay */
118 (*a1)->data[nfilters-1] = cpolar((double) exp(-beta / ((double) jstep)), -phase_dot);
119 (*b0)->data[nfilters-1] = cpolar(amp->data[k], phase->data[k] + phase_dot * ((double) (j - k)) );
120 (*delay)->data[nfilters-1] = amp->length - 1 - j;
121
122
123
124 /* Calculate the next data point step */
125 j -= jstep;
126
127 }
128
129 return 0;
130}
131
132
134{
135 int length, numFilters;
136 complex double y;
137 complex double *a1_last;
138 complex double *a1f = (complex double *) a1->data;
139 complex double *b0f = (complex double *) b0->data;
140 int *delayf = delay->data;
141
142 if(a1->length != b0->length || a1->length != delay->length)
144
145 memset(response->data, 0, sizeof(complex double) * response->length);
146
147 numFilters = a1->length;
148 for (a1_last = a1f + numFilters; a1f < a1_last; a1f++)
149 {
150 y = *b0f / *a1f;
151 length = (int) (logf(1e-13))/(logf(cabs(*a1f)));// + *delayf;
152 //length = (int) (logf((1e-13)/cabs(*b0f)))/(logf(cabs(*a1f)));// + *delayf;
153 int maxlength = response->length - *delayf;
154 if (length > maxlength)
155 length = maxlength;
156
157 complex double *response_data = (complex double *) &response->data[*delayf];
158 complex double *response_data_last;
159
160 for (response_data_last = response_data + length; response_data < response_data_last; response_data++ )
161 {
162 y *= *a1f;
163 *response_data += y;
164 }
165 b0f++;
166 delayf++;
167 }
168 return 0;
169}
170
172{
173 double loga1, arga1, pf;
174 COMPLEX16 scl, ft, ftconj;
175
176 /* FIXME: Check if a1, b0, delay exist */
177
178 loga1 = clogabs(a1);
179 arga1 = carg(a1);
180 pf = 2.0 * LAL_PI * ((double ) j) / ((double ) jmax);
181 scl = cpolar(0.5, - pf * ((double ) (jmax - delay)));
182
183 ft = b0 / crect(-loga1, -arga1 - pf);
184 ftconj = conj(b0) / crect(-loga1, arga1 - pf);
185
186 *hfcos = scl * (ft + ftconj);
187 *hfsin = scl * (ft - ftconj);
188
189 return 0;
190}
191
193{
194 UINT4 k, j;
195 COMPLEX16 hA;
196 COMPLEX16 hfcos = 0.0;
197 COMPLEX16 hfsin = 0.0;
198
199 *ip = 0.0;
200
201 for (j = 0; j < psd->length; j++)
202 {
203 hA = 0.0;
204 for (k = 0; k < a1->length; k++)
205 {
206 XLALInspiralGenerateIIRSetFourierTransform(j, 2 * psd->length, a1->data[k], b0->data[k], delay->data[k], &hfcos, &hfsin);
207 hA = hA + hfcos;
208 }
209 *ip += cabs(hA) * cabs(hA) / (psd->data[j] * ((double ) psd->length)) * 1.0;
210 }
211
212 return 0;
213}
int XLALInspiralGenerateIIRSetFourierTransform(int j, int jmax, COMPLEX16 a1, COMPLEX16 b0, INT4 delay, COMPLEX16 *hfcos, COMPLEX16 *hfsin)
int XLALInspiralCalculateIIRSetInnerProduct(COMPLEX16Vector *a1, COMPLEX16Vector *b0, INT4Vector *delay, REAL8Vector *psd, double *ip)
static REAL8 clogabs(COMPLEX16 z)
int XLALInspiralGenerateIIRSet(REAL8Vector *amp, REAL8Vector *phase, double epsilon, double alpha, double beta, double padding, COMPLEX16Vector **a1, COMPLEX16Vector **b0, INT4Vector **delay)
int XLALInspiralIIRSetResponse(COMPLEX16Vector *a1, COMPLEX16Vector *b0, INT4Vector *delay, COMPLEX16Vector *response)
const double b0
double e
const double pf
const double u
#define LAL_PI
#define crect(re, im)
#define cpolar(r, th)
double complex COMPLEX16
double REAL8
uint32_t UINT4
int32_t INT4
INT4Vector * XLALResizeINT4Vector(INT4Vector *vector, UINT4 length)
INT4Vector * XLALCreateINT4Vector(UINT4 length)
COMPLEX16Vector * XLALCreateCOMPLEX16Vector(UINT4 length)
COMPLEX16Vector * XLALResizeCOMPLEX16Vector(COMPLEX16Vector *vector, UINT4 length)
#define XLAL_ERROR(...)
XLAL_EBADLEN
XLAL_EINVAL
list y
double alpha
COMPLEX16 * data
INT4 * data
UINT4 length
REAL8 * data