comparison wavelet.cpp @ 1:6422640a802f

first upload
author Wen X <xue.wen@elec.qmul.ac.uk>
date Tue, 05 Oct 2010 10:45:57 +0100
parents
children fc19d45615d1
comparison
equal deleted inserted replaced
0:9b9f21935f24 1:6422640a802f
1 //---------------------------------------------------------------------------
2
3 #include <math.h>
4 #include <mem.h>
5 #include "wavelet.h"
6 #include "matrix.h"
7
8 //---------------------------------------------------------------------------
9 /*
10 function csqrt: real implementation of complex square root z=sqrt(x)
11
12 In: xr and xi: real and imaginary parts of x
13 Out: zr and zi: real and imaginary parts of z=sqrt(x)
14
15 No return value.
16 */
17 void csqrt(double& zr, double& zi, double xr, double xi)
18 {
19 if (xi==0)
20 if (xr>=0) zr=sqrt(xr), zi=0;
21 else zi=sqrt(-xr), zr=0;
22 else
23 {
24 double xm=sqrt(xr*xr+xi*xi);
25 double ri=sqrt((xm-xr)/2);
26 zr=xi/2/ri;
27 zi=ri;
28 }
29 }//csqrt
30
31 /*
32 function Daubechies: calculates the Daubechies filter of a given order p
33
34 In: filter order p
35 Out: h[2p]: the 2p FIR coefficients
36
37 No reutrn value. The calculated filters are minimum phase, which means the energy concentrates at the
38 beginning. This is usually used for reconstruction. On the contrary, for wavelet analysis the filter
39 is mirrored.
40 */
41 void Daubechies(int p, double* h)
42 {
43 //initialize h(z)
44 double r01=pow(2, -p-p+1.5);
45
46 h[0]=1;
47 for (int i=1; i<=p; i++)
48 {
49 h[i]=h[i-1]*(p+1-i)/i;
50 }
51
52 //construct polynomial p
53 double *P=new double[p], *rp=new double[p], *ip=new double[p];
54
55 P[p-1]=1;
56 double r02=1;
57 for (int i=p-1; i>0; i--)
58 {
59 double rate=(i+1-1.0)/(p-2.0+i+1);
60 P[i-1]=P[i]*rate;
61 r02/=rate;
62 }
63 Roots(p-1, P, rp, ip);
64 for (int i=0; i<p-1; i++)
65 {
66 //current length of h is p+1+i, h[0:p+i]
67 if (i<p-2 && rp[i]==rp[i+1] && ip[i]==-ip[i+1])
68 {
69 double ar=rp[i], ai=ip[i];
70 double bkr=-2*ar+1, bki=-2*ai, ckr=4*(ar*ar-ai*ai-ar), cki=4*(2*ar*ai-ai), dlr, dli;
71 csqrt(dlr, dli, ckr, cki);
72 double akr=bkr+dlr, aki=bki+dli;
73 if (akr*akr+aki*aki>1) akr=bkr-dlr, aki=bki-dli;
74 double ak1=-2*akr, ak2=akr*akr+aki*aki;
75 h[p+2+i]=ak2*h[p+i];
76 h[p+1+i]=ak2*h[p-1+i]+ak1*h[p+i];
77 for (int j=p+i; j>1; j--) h[j]=h[j]+ak1*h[j-1]+ak2*h[j-2];
78 h[1]=h[1]+ak1*h[0];
79 r02/=ak2;
80 i++;
81 }
82 else //real root of P
83 {
84 double ak, bk=-(2*rp[i]-1), delk=4*rp[i]*(rp[i]-1);
85 if (bk>0) ak=bk-sqrt(delk);
86 else ak=bk+sqrt(delk);
87 r02/=ak;
88 h[p+1+i]=-ak*h[p+i];
89 for (int j=p+i; j>0; j--) h[j]=h[j]-ak*h[j-1];
90 }
91 }
92 delete[] P; delete[] rp; delete[] ip;
93 r01=r01*sqrt(r02);
94 for (int i=0; i<p*2; i++) h[i]*=r01;
95 }//Daubechies
96
97 /*
98 Periodic wavelet decomposition and reconstruction routines
99
100 The wavelet transform of an N-point sequence is arranged in "interleaved" format
101 as another N-point sequance. Level 1 details are found at N/2 points 1, 3, 5, ...,
102 N-1; level 2 details are found at N/4 points 2, 6, ..., N-2; level 3 details are
103 found at N/8 points 4, 12, ..., N-4; etc.
104 */
105
106 /*
107 function dwtpqmf: in this implementation h and g are the same as reconstruction qmf filters. In fact
108 the actual filters used are their mirrors and filter origin are aligned to the ends of the real
109 filters, which turn out to be the starts of h and g.
110
111 The inverse transform is idwtp(), the same as inversing dwtp().
112
113 In: in[Count]: waveform data
114 h[M], g[M]: quadratic mirror filter pair
115 N: maximal time resolution
116 Count=kN, N=2^lN being the reciprocal of the most detailed frequency scale, i.e.
117 N=1 for no transforming at all, N=2 for dividing into approx. and detail,
118 N=4 for dividing into approx+detail(approx+detial), etc.
119 Count*2/N=2k gives the smallest length to be convolved with h and g.
120 Out: out[N], the wavelet transform, arranged in interleaved format.
121
122 Returns maximal atom length (should equal N).
123 */
124 int dwtpqmf(double* in, int Count, int N, double* h, double* g, int M, double* out)
125 {
126 double* tmp=new double[Count];
127 double *tmpa=tmp, *tmpla=in;
128 int C=Count, L=0, n=1;
129
130 A:
131 {
132 //C: signal length at current layer
133 //L: layer index, 0 being most detailed
134 //n: atom length on current layer, equals 2^L.
135 //C*n=(C<<L)=Count
136 double* tmpd=&tmpa[C/2];
137 for (int i=0; i<C; i+=2)
138 {
139 int i2=i/2;
140 tmpa[i2]=tmpla[i]*h[0];
141 tmpd[i2]=tmpla[i]*g[0];
142 for (int j=1; j<M; j++)
143 {
144 if (i+j<C)
145 {
146 tmpa[i2]+=tmpla[i+j]*h[j];
147 tmpd[i2]+=tmpla[i+j]*g[j];
148 }
149 else
150 {
151 tmpa[i2]+=tmpla[i+j-C]*h[j];
152 tmpd[i2]+=tmpla[i+j-C]*g[j];
153 }
154 }
155 }
156 for (int i=0; i*2+1<C; i++) out[(2*i+1)<<L]=tmpd[i];
157 for (int i=0; i*2<C; i++) out[i<<(L+1)]=tmpa[i];
158 n*=2;
159 if (n<N)
160 {
161 tmpla=tmpa;
162 tmpa=tmpd;
163 L++;
164 C/=2;
165 goto A;
166 }
167 }
168 delete[] tmp;
169 return n;
170 }//dwtpqmf
171
172 /*
173 function dwtp: in this implementation h and g can be different from mirrored reconstruction filters,
174 i.e. the biorthogonal transform. h[0] and g[0] are aligned at the ends of the filters, i.e. h[-M+1:0],
175 g[-M+1:0].
176
177 In: in[Count]: waveform data
178 h[-M+1:0], g[-M+1:0]: quadratic mirror filter pair
179 N: maximal time resolution
180 Out: out[N], the wavelet transform, arranged in interleaved format.
181
182 Returns maximal atom length (should equal N).
183 */
184 int dwtp(double* in, int Count, int N, double* h, double* g, int M, double* out)
185 {
186 double* tmp=new double[Count];
187 double *tmpa=tmp, *tmpla=in;
188 int C=Count, L=0, n=1;
189
190 A:
191 {
192 double* tmpd=&tmpa[C/2];
193 for (int i=0; i<C; i+=2)
194 {
195 int i2=i/2;
196 tmpa[i2]=tmpla[i]*h[0];
197 tmpd[i2]=tmpla[i]*g[0];
198 for (int j=-1; j>-M; j--)
199 {
200 if (i-j<C)
201 {
202 tmpa[i2]+=tmpla[i-j]*h[j];
203 tmpd[i2]+=tmpla[i-j]*g[j];
204 }
205 else
206 {
207 tmpa[i2]+=tmpla[i-j-C]*h[j];
208 tmpd[i2]+=tmpla[i-j-C]*g[j];
209 }
210 }
211 }
212 for (int i=0; i*2+1<C; i++) out[(2*i+1)<<L]=tmpd[i];
213 for (int i=0; i*2<C; i++) out[i<<(L+1)]=tmpa[i];
214 n*=2;
215 if (n<N)
216 {
217 tmpla=tmpa;
218 tmpa=tmpd;
219 L++;
220 C/=2;
221 goto A;
222 }
223 }
224 delete[] tmp;
225 return n;
226 }//dwtp
227
228 /*
229 function dwtp: in this implementation h and g can be different size. h[0] and g[0] are aligned at the
230 ends of the filters, i.e. h[-Mh+1:0], g[-Mg+1:0].
231
232 In: in[Count]: waveform data
233 h[-Mh+1:0], g[-Mg+1:0]: quadratic mirror filter pair
234 N: maximal time resolution
235 Out: out[N], the wavelet transform, arranged in interleaved format.
236
237 Returns maximal atom length (should equal N).
238 */
239 int dwtp(double* in, int Count, int N, double* h, int Mh, double* g, int Mg, double* out)
240 {
241 double* tmp=new double[Count];
242 double *tmpa=tmp, *tmpla=in;
243 int C=Count, L=0, n=1;
244
245 A:
246 {
247 double* tmpd=&tmpa[C/2];
248 for (int i=0; i<C; i+=2)
249 {
250 int i2=i/2;
251 tmpa[i2]=tmpla[i]*h[0];
252 tmpd[i2]=tmpla[i]*g[0];
253 for (int j=-1; j>-Mh; j--)
254 {
255 if (i-j<C)
256 {
257 tmpa[i2]+=tmpla[i-j]*h[j];
258 }
259 else
260 {
261 tmpa[i2]+=tmpla[i-j-C]*h[j];
262 }
263 }
264 for (int j=-1; j>-Mg; j--)
265 {
266 if (i-j<C)
267 {
268 tmpd[i2]+=tmpla[i-j]*g[j];
269 }
270 else
271 {
272 tmpd[i2]+=tmpla[i-j-C]*g[j];
273 }
274 }
275 }
276 for (int i=0; i*2+1<C; i++) out[(2*i+1)<<L]=tmpd[i];
277 for (int i=0; i*2<C; i++) out[i<<(L+1)]=tmpa[i];
278 n*=2;
279 if (n<N)
280 {
281 tmpla=tmpa;
282 tmpa=tmpd;
283 L++;
284 C/=2;
285 goto A;
286 }
287 }
288 delete[] tmp;
289 return n;
290 }//dwtp
291
292 /*
293 function dwtp: in this implementation h and g can be arbitrarily located: h from $sh to $eh, g from
294 $sg to $eg.
295
296 In: in[Count]: waveform data
297 h[sh:eh-1], g[sg:eg-1]: quadratic mirror filter pair
298 N: maximal time resolution
299 Out: out[N], the wavelet transform, arranged in interleaved format.
300
301 Returns maximal atom length (should equal N).
302 */
303 int dwtp(double* in, int Count, int N, double* h, int sh, int eh, double* g, int sg, int eg, double* out)
304 {
305 double* tmp=new double[Count];
306 double *tmpa=tmp, *tmpla=in;
307 int C=Count, L=0, n=1;
308
309 A:
310 {
311 double* tmpd=&tmpa[C/2];
312 for (int i=0; i<C; i+=2)
313 {
314 int i2=i/2;
315 tmpa[i2]=0;//tmpla[i]*h[0];
316 tmpd[i2]=0;//tmpla[i]*g[0];
317 for (int j=sh; j<=eh; j++)
318 {
319 int ind=i-j;
320 if (ind>=C) tmpa[i2]+=tmpla[ind-C]*h[j];
321 else if (ind<0) tmpa[i2]+=tmpla[ind+C]*h[j];
322 else tmpa[i2]+=tmpla[ind]*h[j];
323 }
324 for (int j=sg; j<=eg; j++)
325 {
326 int ind=i-j;
327 if (ind>=C) tmpd[i2]+=tmpla[i-j-C]*g[j];
328 else if (ind<0) tmpd[i2]+=tmpla[i-j+C]*g[j];
329 else tmpd[i2]+=tmpla[i-j]*g[j];
330 }
331 }
332 for (int i=0; i*2+1<C; i++) out[(2*i+1)<<L]=tmpd[i];
333 for (int i=0; i*2<C; i++) out[i<<(L+1)]=tmpa[i];
334 n*=2;
335 if (n<N)
336 {
337 tmpla=tmpa;
338 tmpa=tmpd;
339 L++;
340 C/=2;
341 goto A;
342 }
343 }
344 delete[] tmp;
345 return n;
346 }//dwtp
347
348 /*
349 function idwtp: periodic wavelet reconstruction by qmf
350
351 In: in[Count]: wavelet transform in interleaved format
352 h[M], g[M]: quadratic mirror filter pair
353 N: maximal time resolution
354 Out: out[N], waveform data (detail level 0).
355
356 No return value.
357 */
358 void idwtp(double* in, int Count, int N, double* h, double* g, int M, double* out)
359 {
360 double* tmp=new double[Count];
361 memcpy(out, in, sizeof(double)*Count);
362 int n=N, C=Count/N, L=log2(N)-1;
363 while (n>1)
364 {
365 memset(tmp, 0, sizeof(double)*C*2);
366 //2k<<L being the approx, (2k+1)<<L being the detail
367 for (int i=0; i<C; i++)
368 {
369 for (int j=0; j<M; j++)
370 {
371 if (i*2+j<C*2)
372 {
373 tmp[i*2+j]+=out[(2*i)<<L]*h[j]+out[(2*i+1)<<L]*g[j];
374 }
375 else
376 {
377 tmp[i*2+j-C*2]+=out[(2*i)<<L]*h[j]+out[(2*i+1)<<L]*g[j];
378 }
379 }
380 }
381 for (int i=0; i<C*2; i++) out[i<<L]=tmp[i];
382 n/=2;
383 C*=2;
384 L--;
385 }
386 delete[] tmp;
387 }//idwtp
388
389 /*
390 function idwtp: in which h and g can have different length.
391
392 In: in[Count]: wavelet transform in interleaved format
393 h[Mh], g[Mg]: quadratic mirror filter pair
394 N: maximal time resolution
395 Out: out[N], waveform data (detail level 0).
396
397 No return value.
398 */
399 void idwtp(double* in, int Count, int N, double* h, int Mh, double* g, int Mg, double* out)
400 {
401 double* tmp=new double[Count];
402 memcpy(out, in, sizeof(double)*Count);
403 int n=N, C=Count/N, L=log2(N)-1;
404 while (n>1)
405 {
406 memset(tmp, 0, sizeof(double)*C*2);
407 //2k<<L being the approx, (2k+1)<<L being the detail
408 for (int i=0; i<C; i++)
409 {
410 for (int j=0; j<Mh; j++)
411 {
412 int ind=i*2+j+(Mg-Mh)/2;
413 if (ind>=C*2)
414 {
415 tmp[ind-C*2]+=out[(2*i)<<L]*h[j];
416 }
417 else if (ind<0)
418 {
419 tmp[ind+C*2]+=out[(2*i)<<L]*h[j];
420 }
421 else
422 {
423 tmp[ind]+=out[(2*i)<<L]*h[j];
424 }
425 }
426 }
427 for (int i=0; i<C; i++)
428 {
429 for (int j=0; j<Mg; j++)
430 {
431 int ind=i*2+j+(Mh-Mg)/2;
432 if (ind>=C*2)
433 {
434 tmp[ind-C*2]+=out[(2*i+1)<<L]*g[j];
435 }
436 else if (ind<0)
437 {
438 tmp[ind+C*2]+=out[(2*i+1)<<L]*g[j];
439 }
440 else
441 {
442 tmp[ind]+=out[(2*i+1)<<L]*g[j];
443 }
444 }
445 }
446 for (int i=0; i<C*2; i++) out[i<<L]=tmp[i];
447 n/=2;
448 C*=2;
449 L--;
450 }
451 delete[] tmp;
452 }//idwtp
453
454 /*
455 function idwtp: in which h and g can be arbitrarily located: h from $sh to $eh, g from $sg to $eg
456
457 In: in[Count]: wavelet transform in interleaved format
458 h[sh:eh-1], g[sg:eg-1]: quadratic mirror filter pair
459 N: maximal time resolution
460 Out: out[N], waveform data (detail level 0).
461
462 No return value.
463 */
464 void idwtp(double* in, int Count, int N, double* h, int sh, int eh, double* g, int sg, int eg, double* out)
465 {
466 double* tmp=new double[Count];
467 memcpy(out, in, sizeof(double)*Count);
468 int n=N, C=Count/N, L=log2(N)-1;
469 while (n>1)
470 {
471 memset(tmp, 0, sizeof(double)*C*2);
472 //2k<<L being the approx, (2k+1)<<L being the detail
473 for (int i=0; i<C; i++)
474 {
475 for (int j=sh; j<=eh; j++)
476 {
477 int ind=i*2+j;
478 if (ind>=C*2) tmp[ind-C*2]+=out[(2*i)<<L]*h[j];
479 else if (ind<0) tmp[ind+C*2]+=out[(2*i)<<L]*h[j];
480 else tmp[ind]+=out[(2*i)<<L]*h[j];
481 }
482 }
483 for (int i=0; i<C; i++)
484 {
485 for (int j=sg; j<=eg; j++)
486 {
487 int ind=i*2+j;
488 if (ind>=C*2) tmp[ind-C*2]+=out[(2*i+1)<<L]*g[j];
489 else if (ind<0) tmp[ind+C*2]+=out[(2*i+1)<<L]*g[j];
490 else tmp[ind]+=out[(2*i+1)<<L]*g[j];
491 }
492 }
493 for (int i=0; i<C*2; i++) out[i<<L]=tmp[i];
494 n/=2;
495 C*=2;
496 L--;
497 }
498 delete[] tmp;
499 }//idwtp
500
501 //---------------------------------------------------------------------------
502
503 /*
504 Spline biorthogonal wavelet routines.
505
506 Further reading: "Calculation of biorthogonal spline wavelets.pdf"
507 */
508
509 //function Cmb: combination number C(n, k) (n>=k>=0)
510 int Cmb(int n, int k)
511 {
512 if (k>n/2) k=n-k;
513 int c=1;
514 for (int i=1; i<=k; i++) c=c*(n+1-i)/i;
515 return c;
516 }
517
518 /*
519 function splinewl: computes spline biorthogonal wavelet filters. This version of splinewl calcualtes
520 the positive-time half of h and hm coefficients only.
521
522 p1 and p2 must have the same parity. If p1 is even, p1 coefficients will be returned in h1; if p1 is
523 odd, p1-1 coefficients will be returned in h1.
524
525 Actual length of h is p1+1, of hm is p1+2p2-1. only a half of each is kept.
526 p even: h[0:p1/2] <- [p1/2:p1], hm[0:p1/2+p2-1] <- [p1/2+p2-1:p1+2p2-2]
527 p odd: h[0:(p1-1)/2] <- [(p1+1)/2:p1], hm[0:(p1-3)/2+p2] <- [(p1-1)/2+p2:p1+2p2-2]
528 i.e. h[0:hp1] <- [p1-hp1:p1], hm[0:hp1+p2-1] <- [p1-hp1-1+p2:p1+2p2-2]
529
530 In: p1, p2: specify vanishing moments of h and hm
531 Out: h[] and hm[] as specified above.
532
533 No return value.
534 */
535 void splinewl(int p1, int p2, double* h, double* hm)
536 {
537 int hp1=p1/2, hp2=p2/2;
538 int q=(p1+p2)/2;
539 h[hp1]=sqrt(2.0)*pow(2, -p1);
540 // h1[hp1]=1;
541 for (int i=1, j=hp1-1; i<=hp1; i++, j--)
542 {
543 h[j]=h[j+1]*(p1+1-i)/i;
544 }
545
546 double *_hh1=new double[p2+1], *_hh2=new double[2*q];
547 double *hh1=&_hh1[p2-hp2], *hh2=&_hh2[q];
548
549 hh1[hp2]=sqrt(2.0)*pow(2, -p2);
550 for (int i=1, j=hp2-1; i<=hp2; i++, j--)
551 {
552 hh1[j]=hh1[j+1]*(p2+1-i)/i;
553 }
554 if (p2%2) //p2 is odd
555 {
556 for (int i=0; i<=hp2; i++) hh1[-i-1]=hh1[i];
557 }
558 else //p2 even
559 {
560 for (int i=1; i<=hp2; i++) hh1[-i]=hh1[i];
561 }
562
563 memset(_hh2, 0, sizeof(double)*2*q);
564 for (int n=1-q; n<=q-1; n++)
565 {
566 int k=abs(n);
567 int CC1=Cmb(q-1+k, k), CC2=Cmb(2*k, k-n); //CC=1.0*C(q-1+k, k)*C(2*k, k-n)
568 for (; k<=q-1; k++)
569 {
570 hh2[n]=hh2[n]+1.0*CC1*CC2*pow(0.25, k);
571 CC1=CC1*(q+k)/(k+1);
572 CC2=CC2*(2*k+1)*(2*k+2)/((k+1-n)*(k+1+n));
573 }
574 hh2[n]*=pow(-1, n);
575 }
576
577 //hh1[hp2-p2:hp2], hh2[1-q:q-1]
578 //h2=conv(hh1, hh2), but the positive half only
579 memset(hm, 0, sizeof(double)*(hp1+p2));
580 for (int i=hp2-p2; i<=hp2; i++)
581 for (int j=1-q; j<=q-1; j++)
582 {
583 if (i+j>=0 && i+j<hp1+p2)
584 hm[i+j]+=hh1[i]*hh2[j];
585 }
586
587 delete[] _hh1;
588 delete[] _hh2;
589 }//splinewl
590
591
592 /*
593 function splinewl: calculates the analysis and reconstruction filter pairs of spline biorthogonal
594 wavelet (h, g) and (hm, gm). h has the size p1+1, hm has the size p1+2p2-1.
595
596 If p1+1 is odd, then all four filters are symmetric; if not, then h and hm are symmetric, while g and
597 gm are anti-symmetric.
598
599 The concatenation of filters h with hm (or g with gm) introduces a time shift of p1+p2-1, which is the
600 return value multiplied by -1.
601
602 If normmode==1, the results are normalized so that ||h||^2=||g||^2=1;
603 if normmode==2, the results are normalized so that ||hm||^2=||gm||^2=1,
604 if normmode==3, the results are normalized so that ||h||^2==||g||^2=||hm||^2=||gm||^2.
605
606 If a *points* buffer is specified, the function returns the starting and ending
607 positions (inclusive) of h, hm, g, and gm, in the order of (hs, he, hms, hme,
608 gs, ge, gms, gme), as ps[0]~ps[7].
609
610 In: p1 and p2, specify vanishing moments of h and hm, respectively.
611 normmode: mode for normalization
612 Out: h[p1+1], g[p1+1], hm[p1+2p2-1], gm[p1+2p2-1], points[8] (optional)
613
614 Returns -p1-p2+1.
615 */
616 int splinewl(int p1, int p2, double* h, double* hm, double* g, double* gm, int normmode, int* points)
617 {
618 int lf=p1+1, lb=p1+2*p2-1;
619 int hlf=lf/2, hlb=lb/2;
620
621 double *h1=&h[hlf], *h2=&hm[hlb];
622 int hp1=p1/2, hp2=p2/2;
623 int q=(p1+p2)/2;
624 h1[hp1]=sqrt(2.0)*pow(2, -p1);
625 // h1[hp1]=2*pow(2, -p1);
626 for (int i=1, j=hp1-1; i<=hp1; i++, j--) h1[j]=h1[j+1]*(p1+1-i)/i;
627
628 double *_hh1=new double[p2+1+2*q];
629 double *_hh2=&_hh1[p2+1];
630 double *hh1=&_hh1[p2-hp2], *hh2=&_hh2[q];
631 hh1[hp2]=sqrt(2.0)*pow(2, -p2);
632 // hh1[hp2]=pow(2, -p2);
633 for (int i=1, j=hp2-1; i<=hp2; i++, j--) hh1[j]=hh1[j+1]*(p2+1-i)/i;
634 if (p2%2) for (int i=0; i<=hp2; i++) hh1[-i-1]=hh1[i];
635 else for (int i=1; i<=hp2; i++) hh1[-i]=hh1[i];
636 memset(_hh2, 0, sizeof(double)*2*q);
637 for (int n=1-q; n<=q-1; n++)
638 {
639 int k=abs(n);
640 int CC1=Cmb(q-1+k, k), CC2=Cmb(2*k, k-n); //CC=1.0*C(q-1+k, k)*C(2*k, k-n)
641 for (int k=abs(n); k<=q-1; k++)
642 {
643 hh2[n]=hh2[n]+1.0*CC1*CC2*pow(0.25, k);
644 CC1=CC1*(q+k)/(k+1);
645 CC2=CC2*(2*k+1)*(2*k+2)/((k+1-n)*(k+1+n));
646 }
647 hh2[n]*=pow(-1, n);
648 }
649 //hh1[hp2-p2:hp2], hh2[1-q:q-1]
650 //h2=conv(hh1, hh2), but the positive half only
651 memset(h2, 0, sizeof(double)*(hp1+p2));
652 for (int i=hp2-p2; i<=hp2; i++) for (int j=1-q; j<=q-1; j++)
653 if (i+j>=0 && i+j<hp1+p2) h2[i+j]+=hh1[i]*hh2[j];
654 delete[] _hh1;
655
656 int hs, he, hms, hme, gs, ge, gms, gme;
657 if (lf%2)
658 {
659 hs=-hlf, he=hlf, hms=-hlb, hme=hlb;
660 gs=-hlb+1, ge=hlb+1, gms=-hlf-1, gme=hlf-1;
661 }
662 else
663 {
664 hs=-hlf, he=hlf-1, hms=-hlb+1, hme=hlb;
665 gs=-hlb, ge=hlb-1, gms=-hlf+1, gme=hlf;
666 }
667
668 if (lf%2)
669 {
670 for (int i=1; i<=hlf; i++) h1[-i]=h1[i];
671 for (int i=1; i<=hlb; i++) h2[-i]=h2[i];
672 double* _g=&g[hlb-1], *_gm=&gm[hlf+1];
673 for (int i=gs; i<=ge; i++) _g[i]=(i%2)?h2[1-i]:-h2[1-i];
674 for (int i=gms; i<=gme; i++) _gm[i]=(i%2)?h1[-1-i]:-h1[-1-i];
675 }
676 else
677 {
678 for (int i=0; i<hlf; i++) h1[-i-1]=h1[i];
679 for (int i=0; i<hlb; i++) h2[-i-1]=h2[i];
680 h2=&h2[-1];
681 double *_g=&g[hlb], *_gm=&gm[hlf-1];
682 for (int i=gs; i<=ge; i++) _g[i]=(i%2)?-h2[-i]:h2[-i];
683 for (int i=gms; i<=gme; i++) _gm[i]=(i%2)?-h1[-i]:h1[-i];
684 }
685
686 if (normmode)
687 {
688 double sumh=0; for (int i=0; i<=he-hs; i++) sumh+=h[i]*h[i];
689 double sumhm=0; for (int i=0; i<=hme-hms; i++) sumhm+=hm[i]*hm[i];
690 if (normmode==1)
691 {
692 double rr=sqrt(sumh);
693 for (int i=0; i<=hme-hms; i++) hm[i]*=rr;
694 rr=1.0/rr;
695 for (int i=0; i<=he-hs; i++) h[i]*=rr;
696 rr=sqrt(sumhm);
697 for (int i=0; i<=gme-gms; i++) gm[i]*=rr;
698 rr=1.0/rr;
699 for (int i=0; i<=ge-gs; i++) g[i]*=rr;
700 }
701 else if (normmode==2)
702 {
703 double rr=sqrt(sumh);
704 for (int i=0; i<=ge-gs; i++) g[i]*=rr;
705 rr=1.0/rr;
706 for (int i=0; i<=gme-gms; i++) gm[i]*=rr;
707 rr=sqrt(sumhm);
708 for (int i=0; i<=he-hs; i++) h[i]*=rr;
709 rr=1.0/rr;
710 for (int i=0; i<=hme-hms; i++) hm[i]*=rr;
711 }
712 else if (normmode==3)
713 {
714 double rr=pow(sumh/sumhm, 0.25);
715 for (int i=0; i<=hme-hms; i++) hm[i]*=rr;
716 for (int i=0; i<=ge-gs; i++) g[i]*=rr;
717 rr=1.0/rr;
718 for (int i=0; i<=he-hs; i++) h[i]*=rr;
719 for (int i=0; i<=gme-gms; i++) gm[i]*=rr;
720 }
721 }
722
723 if (points)
724 {
725 points[0]=hs, points[1]=he, points[2]=hms, points[3]=hme;
726 points[4]=gs, points[5]=ge, points[6]=gms, points[7]=gme;
727 }
728 return -p1-p2+1;
729 }//splinewl
730
731 //---------------------------------------------------------------------------
732 /*
733 function wavpacqmf: calculate pseudo local cosine transforms using wavelet packet
734
735 In: data[Count], Count=fr*WID, waveform data
736 WID: largest scale, equals 2^ORDER
737 wid: smallest scale, euqals 2^order
738 h[M], g[M]: quadratic mirror filter pair, fr>2*M
739 Out: spec[0][fr][WID], spec[1][2*fr][WID/2], ..., spec[ORDER-order-1][FR][wid]
740
741 No return value.
742 */
743 void wavpacqmf(double*** spec, double* data, int Count, int WID, int wid, int M, double* h, double* g)
744 {
745 int fr=Count/WID, ORDER=log2(WID), order=log2(wid);
746 double* _data1=new double[Count*2];
747 double *data1=_data1, *data2=&_data1[Count];
748 //the qmf always filters data1 and puts the results to data2
749 memcpy(data1, data, sizeof(double)*Count);
750 int l=0, C=fr*WID, FR=1;
751 double *ldata, *ldataa, *ldatad;
752 while (l<ORDER)
753 {
754 //qmf
755 for (int f=0; f<FR; f++)
756 {
757 ldata=&data1[f*C];
758 if (f%2==0)
759 ldataa=&data2[f*C], ldatad=&data2[f*C+C/2];
760 else
761 ldatad=&data2[f*C], ldataa=&data2[f*C+C/2];
762
763 memset(&data2[f*C], 0, sizeof(double)*C);
764 for (int i=0; i<C; i+=2)
765 {
766 int i2=i/2;
767 ldataa[i2]=ldata[i]*h[0];
768 ldatad[i2]=ldata[i]*g[0];
769 for (int j=1; j<M; j++)
770 {
771 if (i+j<C)
772 {
773 ldataa[i2]+=ldata[i+j]*h[j];
774 ldatad[i2]+=ldata[i+j]*g[j];
775 }
776 else
777 {
778 ldataa[i2]+=ldata[i+j-C]*h[j];
779 ldatad[i2]+=ldata[i+j-C]*g[j];
780 }
781 }
782 }
783 }
784 double *tmp=data2; data2=data1; data1=tmp;
785 l++;
786 C=(C>>1);
787 FR=(FR<<1);
788 if (l>=order)
789 {
790 for (int f=0; f<FR; f++)
791 for(int i=0; i<C; i++)
792 spec[ORDER-l][i][f]=data1[f*C+i];
793 }
794 }
795
796 delete[] _data1;
797 }//wavpacqmf
798
799 /*
800 function iwavpacqmf: inverse transform of wavpacqmf
801
802 In: spec[Fr][Wid], Fr>M*2
803 h[M], g[M], quadratic mirror filter pair
804 Out: data[Fr*Wid]
805
806 No return value.
807 */
808 void iwavpacqmf(double* data, double** spec, int Fr, int Wid, int M, double* h, double* g)
809 {
810 int Count=Fr*Wid, Order=log2(Wid);
811 double* _data1=new double[Count];
812 double *data1, *data2, *ldata, *ldataa, *ldatad;
813 if (Order%2) data1=_data1, data2=data;
814 else data1=data, data2=_data1;
815 //data pass to buffer
816 for (int i=0, t=0; i<Wid; i++)
817 for (int j=0; j<Fr; j++)
818 data1[t++]=spec[j][i];
819
820 int l=Order;
821 int C=Fr;
822 int K=Wid/2;
823 while (l>0)
824 {
825 memset(data2, 0, sizeof(double)*Count);
826 for (int k=0; k<K; k++)
827 {
828 if (k%2==0) ldataa=&data1[2*k*C], ldatad=&data1[(2*k+1)*C];
829 else ldatad=&data1[2*k*C], ldataa=&data1[(2*k+1)*C];
830 ldata=&data2[2*k*C];
831 //qmf
832 for (int i=0; i<C; i++)
833 {
834 for (int j=0; j<M; j++)
835 {
836 if (i*2+j<C*2)
837 {
838 ldata[i*2+j]+=ldataa[i]*h[j]+ldatad[i]*g[j];
839 }
840 else
841 {
842 ldata[i*2+j-C*2]+=ldataa[i]*h[j]+ldatad[i]*g[j];
843 }
844 }
845 }
846 }
847
848 double *tmp=data2; data2=data1; data1=tmp;
849 l--;
850 C=(C<<1);
851 K=(K>>1);
852 }
853 delete[] _data1;
854 }//iwavpacqmf
855
856 /*
857 function wavpac: calculate pseudo local cosine transforms using wavelet packet,
858
859 In: data[Count], Count=fr*WID, waveform data
860 WID: largest scale, equals 2^ORDER
861 wid: smallest scale, euqals 2^order
862 h[hs:he-1], g[gs:ge-1]: filter pair
863 Out: spec[0][fr][WID], spec[1][2*fr][WID/2], ..., spec[ORDER-order-1][FR][wid]
864
865 No return value.
866 */
867 void wavpac(double*** spec, double* data, int Count, int WID, int wid, double* h, int hs, int he, double* g, int gs, int ge)
868 {
869 int fr=Count/WID, ORDER=log2(WID), order=log2(wid);
870 double* _data1=new double[Count*2];
871 double *data1=_data1, *data2=&_data1[Count];
872 //the qmf always filters data1 and puts the results to data2
873 memcpy(data1, data, sizeof(double)*Count);
874 int l=0, C=fr*WID, FR=1;
875 double *ldata, *ldataa, *ldatad;
876 while (l<ORDER)
877 {
878 //qmf
879 for (int f=0; f<FR; f++)
880 {
881 ldata=&data1[f*C];
882 if (f%2==0)
883 ldataa=&data2[f*C], ldatad=&data2[f*C+C/2];
884 else
885 ldatad=&data2[f*C], ldataa=&data2[f*C+C/2];
886
887 memset(&data2[f*C], 0, sizeof(double)*C);
888 for (int i=0; i<C; i+=2)
889 {
890 int i2=i/2;
891 ldataa[i2]=0;//ldata[i]*h[0];
892 ldatad[i2]=0;//ldata[i]*g[0];
893 for (int j=hs; j<=he; j++)
894 {
895 int ind=i-j;
896 if (ind>=C)
897 {
898 ldataa[i2]+=ldata[ind-C]*h[j];
899 }
900 else if (ind<0)
901 {
902 ldataa[i2]+=ldata[ind+C]*h[j];
903 }
904 else
905 {
906 ldataa[i2]+=ldata[ind]*h[j];
907 }
908 }
909 for (int j=gs; j<=ge; j++)
910 {
911 int ind=i-j;
912 if (ind>=C)
913 {
914 ldatad[i2]+=ldata[ind-C]*g[j];
915 }
916 else if (ind<0)
917 {
918 ldatad[i2]+=ldata[ind+C]*g[j];
919 }
920 else
921 {
922 ldatad[i2]+=ldata[ind]*g[j];
923 }
924 }
925 }
926 }
927 double *tmp=data2; data2=data1; data1=tmp;
928 l++;
929 C=(C>>1);
930 FR=(FR<<1);
931 if (l>=order)
932 {
933 for (int f=0; f<FR; f++)
934 for(int i=0; i<C; i++)
935 spec[ORDER-l][i][f]=data1[f*C+i];
936 }
937 }
938
939 delete[] _data1;
940 }//wavpac
941
942 /*
943 function iwavpac: inverse transform of wavpac
944
945 In: spec[Fr][Wid]
946 h[hs:he-1], g[gs:ge-1], reconstruction filter pair
947 Out: data[Fr*Wid]
948
949 No return value.
950 */
951 void iwavpac(double* data, double** spec, int Fr, int Wid, double* h, int hs, int he, double* g, int gs, int ge)
952 {
953 int Count=Fr*Wid, Order=log2(Wid);
954 double* _data1=new double[Count];
955 double *data1, *data2, *ldata, *ldataa, *ldatad;
956 if (Order%2) data1=_data1, data2=data;
957 else data1=data, data2=_data1;
958 //data pass to buffer
959 for (int i=0, t=0; i<Wid; i++)
960 for (int j=0; j<Fr; j++)
961 data1[t++]=spec[j][i];
962
963 int l=Order;
964 int C=Fr;
965 int K=Wid/2;
966 while (l>0)
967 {
968 memset(data2, 0, sizeof(double)*Count);
969 for (int k=0; k<K; k++)
970 {
971 if (k%2==0) ldataa=&data1[2*k*C], ldatad=&data1[(2*k+1)*C];
972 else ldatad=&data1[2*k*C], ldataa=&data1[(2*k+1)*C];
973 ldata=&data2[2*k*C];
974 //qmf
975 for (int i=0; i<C; i++)
976 {
977 for (int j=hs; j<=he; j++)
978 {
979 int ind=i*2+j;
980 if (ind>=C*2)
981 {
982 ldata[ind-C*2]+=ldataa[i]*h[j];
983 }
984 else if (ind<0)
985 {
986 ldata[ind+C*2]+=ldataa[i]*h[j];
987 }
988 else
989 {
990 ldata[ind]+=ldataa[i]*h[j];
991 }
992 }
993 for (int j=gs; j<=ge; j++)
994 {
995 int ind=i*2+j;
996 if (ind>=C*2)
997 {
998 ldata[ind-C*2]+=ldatad[i]*g[j];
999 }
1000 else if (ind<0)
1001 {
1002 ldata[ind+C*2]+=ldatad[i]*g[j];
1003 }
1004 else
1005 {
1006 ldata[ind]+=ldatad[i]*g[j];
1007 }
1008 }
1009 }
1010 }
1011
1012 double *tmp=data2; data2=data1; data1=tmp;
1013 l--;
1014 C=(C<<1);
1015 K=(K>>1);
1016 }
1017 delete[] _data1;
1018 }//iwavpac