1// -------------------------------------------------------------------------
2// SWT - Scilab wavelet toolbox
3// Copyright (C) 2010-2014  Holger Nahrstaedt
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18//-------------------------------------------------------------------------
19//
20//  <-- NO CHECK ERROR OUTPUT -->
21// filter Test
22// biorfilt
23function y = rot90 (x, k)
24 [nargout,nargin]=argn(0);
25  if (nargin == 1 | nargin == 2)
26    if (nargin < 2)
27      k = 1;
28    end
29    if (ndims (x) > 2)
30      error ("rot90: Only works with 2-D arrays");
31    end
32    if (imag (k) ~= 0 | fix (k) ~= k)
33      error ("rot90: k must be an integer");
34    end
35    k = modulo (k, 4);
36    if (k < 0)
37      k = k + 4;
38    end
39    if (k == 0)
40      y = x;
41    elseif (k == 1)
42      y = flipud (x.');
43    elseif (k == 2)
44      y = flipud (fliplr (x));
45    elseif (k == 3)
46      y = (flipud (x)).';
47    else
48      error ("rot90: internal error!");
49    end
50  else
51    error("wrong usage!");
52  end
53endfunction
54function b=flipud(a)
55b=a($:-1:1,:);
56endfunction
57function b=fliplr(a)
58b=a(:,$:-1:1)
59endfunction
60function [h_0,h_1] = daubcqf(N,TYPE)
61//    [h_0,h_1] = daubcqf(N,TYPE);
62//
63//    Function computes the Daubechies' scaling and wavelet filters
64//    (normalized to sqrt(2)).
65//
66//    Input:
67//       N    : Length of filter (must be even)
68//       TYPE : Optional parameter that distinguishes the minimum phase,
69//              maximum phase and mid-phase solutions ('min', 'max', or
70//              'mid'). If no argument is specified, the minimum phase
71//              solution is used.
72//
73//    Output:
74//       h_0 : Minimal phase Daubechies' scaling filter
75//       h_1 : Minimal phase Daubechies' wavelet filter
76//
77//    Example:
78//       N = 4;
79//       TYPE = 'min';
80//       [h_0,h_1] = daubcqf(N,TYPE)
81//       h_0 = 0.4830 0.8365 0.2241 -0.1294
82//       h_1 = 0.1294 0.2241 -0.8365 0.4830
83//
84//    Reference: "Orthonormal Bases of Compactly Supported Wavelets",
85//                CPAM, Oct.89
86//
87//File Name: daubcqf.m
88//Last Modification Date: 01/02/96	15:12:57
89//Current Version: daubcqf.m	2.4
90//File Creation Date: 10/10/88
91//Author: Ramesh Gopinath  <ramesh@dsp.rice.edu>
92//
93//Copyright (c) 2000 RICE UNIVERSITY. All rights reserved.
94//Created by Ramesh Gopinath, Department of ECE, Rice University.
95//
96//This software is distributed and licensed to you on a non-exclusive
97//basis, free-of-charge. Redistribution and use in source and binary forms,
98//with or without modification, are permitted provided that the following
99//conditions are met:
100//
101//1. Redistribution of source code must retain the above copyright notice,
102//   this list of conditions and the following disclaimer.
103//2. Redistribution in binary form must reproduce the above copyright notice,
104//   this list of conditions and the following disclaimer in the
105//   documentation and/or other materials provided with the distribution.
106//3. All advertising materials mentioning features or use of this software
107//   must display the following acknowledgment: This product includes
108//   software developed by Rice University, Houston, Texas and its contributors.
109//4. Neither the name of the University nor the names of its contributors
110//   may be used to endorse or promote products derived from this software
111//   without specific prior written permission.
112//
113//THIS SOFTWARE IS PROVIDED BY WILLIAM MARSH RICE UNIVERSITY, HOUSTON, TEXAS,
114//AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
115//BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
116//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RICE UNIVERSITY
117//OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
118//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
119//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
120//OR BUSINESS INTERRUPTIONS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
121//WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
122//OTHERWISE), PRODUCT LIABILITY, OR OTHERWISE ARISING IN ANY WAY OUT OF THE
123//USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124//
125//For information on commercial licenses, contact Rice University's Office of
126//Technology Transfer at techtran@rice.edu or (713) 348-6173
127[nargout,nargin]=argn(0);
128if(nargin < 2),
129  TYPE = 'min';
130end;
131if(modulo(N,2) ~= 0),
132  error('No Daubechies filter exists for ODD length');
133end;
134K = N/2;
135a = 1;
136p = 1;
137q = 1;
138h_0 = [1 1];
139for j  = 1:K-1,
140  a = -a * 0.25 * (j + K - 1)/j;
141  h_0 = [0 h_0] + [h_0 0];
142  p = [0 -p] + [p 0];
143  p = [0 -p] + [p 0];
144  q = [0 q 0] + a*p;
145end;
146q = mtlb_sort(roots(q));
147qt = q(1:K-1);
148if TYPE=='mid',
149  if modulo(K,2)==1,
150    qt = q([1:4:N-2 2:4:N-2]);
151  else
152    qt = q([1 4:4:K-1 5:4:K-1 N-3:-4:K N-4:-4:K]);
153  end;
154end;
155w = real(poly(qt,'s'));
156w=coeff(w);
157w=w($:-1:1)
158// h_0 = conv(h_0,real(poly(qt)));
159h_0 = conv(h_0,w);
160h_0 = sqrt(2)*h_0/sum(h_0); 	//Normalize to sqrt(2);
161if(TYPE=='max'),
162  h_0 = fliplr(h_0);
163end;
164if(abs(sum(h_0 .^ 2))-1 > 1e-4)
165  error('Numerically unstable for this value of N.');
166end;
167h_1 = rot90(h_0,2);
168h_1(1:2:N)=-h_1(1:2:N);
169endfunction
170function w = dbaux(N)
171lon = 2*N-1;
172sup = [-N+1:N];
173a = zeros(1,N);
174for k = 1:N
175    nok  = sup(sup ~= k);
176    a(k) = prod(0.5-nok)/prod(k-nok);
177end
178P = zeros(1,lon);
179P(1:2:lon) = a;
180if N==1 then
181  P = [P,1,P];
182else
183  P = [wrev(P),1,P];
184end;
185//if nargout>1
186    R = roots(P);
187    [s,K] = mtlb_sort(abs(R+1));
188    R = R(K(lon+2:2*lon));
189    [s,K] = mtlb_sort(abs(R));
190    R = R(K);
191//end
192w = real(poly([R(abs(R)<1);-ones(N,1)],'s'));
193w=coeff(w);
194w=w($:-1:1)/sum(w);
195endfunction
196// db1
197N=1;
198w = dbaux(N);
199w2=dbwavf("db"+sprintf("%d",N));
200w2=w2/sqrt(2);
201assert_checkalmostequal ( w , w2 , %eps, %eps*10 );
202// db2
203N=2;
204w = dbaux(N);
205w2=dbwavf("db"+sprintf("%d",N));
206w2=w2/sqrt(2);
207assert_checkalmostequal ( w , w2 , %eps, %eps*10 );
208// db3
209N=3;
210w = dbaux(N);
211w2=dbwavf("db"+sprintf("%d",N));
212w2=w2/sqrt(2);
213assert_checkalmostequal ( w , w2 , %eps, %eps*10 );
214// db4
215N=4;
216w = dbaux(N);
217w2=dbwavf("db"+sprintf("%d",N));
218w2=w2/sqrt(2);
219assert_checkalmostequal ( w , w2 , %eps, %eps*10 );
220// db5
221N=5;
222w = dbaux(N);
223w2=dbwavf("db"+sprintf("%d",N));
224w2=w2/sqrt(2);
225assert_checkalmostequal ( w , w2 , %eps, %eps*10 );
226// db6
227N=6;
228w = dbaux(N);
229w2=dbwavf("db"+sprintf("%d",N));
230w2=w2/sqrt(2);
231assert_checkalmostequal ( w , w2 , %eps, %eps*10 );
232// db7
233N=7;
234w = dbaux(N);
235w2=dbwavf("db"+sprintf("%d",N));
236w2=w2/sqrt(2);
237assert_checkalmostequal ( w , w2 , %eps, %eps*10 );
238// db8
239N=8;
240w = dbaux(N);
241w2=dbwavf("db"+sprintf("%d",N));
242w2=w2/sqrt(2);
243assert_checkalmostequal ( w , w2 , %eps, %eps*10 );
244// db9
245N=9;
246w = dbaux(N);
247w2=dbwavf("db"+sprintf("%d",N));
248w2=w2/sqrt(2);
249assert_checkalmostequal ( w , w2 , %eps, %eps*100 );
250// db10
251N=10;
252w = dbaux(N);
253w2=dbwavf("db"+sprintf("%d",N));
254w2=w2/sqrt(2);
255assert_checkalmostequal ( w , w2 , %eps, %eps*100 );
256// db11
257N=11;
258w = dbaux(N);
259w2=dbwavf("db"+sprintf("%d",N));
260w2=w2/sqrt(2);
261assert_checkalmostequal ( w , w2 , %eps, %eps*1000 );
262// db12
263N=12;
264w = dbaux(N);
265w2=dbwavf("db"+sprintf("%d",N));
266w2=w2/sqrt(2);
267assert_checkalmostequal ( w , w2 , %eps, %eps*1000 );
268// db13
269N=13;
270w = dbaux(N);
271w2=dbwavf("db"+sprintf("%d",N));;
272w2=w2/sqrt(2);
273assert_checkalmostequal ( w , w2 , %eps, %eps*1000 );
274// db14
275N=14;
276w = dbaux(N);
277w2=dbwavf("db"+sprintf("%d",N));;
278w2=w2/sqrt(2);
279assert_checkalmostequal ( w , w2 , %eps, %eps*1000 );
280// db15
281N=15;
282w = dbaux(N);
283w2=dbwavf("db"+sprintf("%d",N));
284w2=w2/sqrt(2);
285assert_checkalmostequal ( w , w2 , %eps, %eps*1000 );
286// db16
287N=16;
288w = dbaux(N);
289w2=dbwavf("db"+sprintf("%d",N));
290w2=w2/sqrt(2);
291assert_checkalmostequal ( w , w2 , %eps, %eps*10000 );
292// db17
293N=17;
294w = dbaux(N);
295w2=dbwavf("db"+sprintf("%d",N));
296w2=w2/sqrt(2);
297assert_checkalmostequal ( w , w2 , %eps, %eps*10000 );
298// db18
299N=18;
300w = dbaux(N);
301w2=dbwavf("db"+sprintf("%d",N));
302w2=w2/sqrt(2);
303assert_checkalmostequal ( w , w2 , %eps, %eps*10000 );
304// db20
305for N=19:36
306  w = dbaux(N);
307  w2=dbwavf("db"+sprintf("%d",N));
308  w2=w2/sqrt(2);
309  assert_checkalmostequal ( w , w2 , %eps, 1e-6 );
310end;
311// db20
312for N=1:36
313  w=dbwavf("db"+sprintf("%d",N));
314  assert_checkalmostequal ( sum(w)-sqrt(2),0 , %eps, %eps*10 );
315end;
316//    - sumEven = sum_k^{N-1} h_{2k} = 1/sqrt(2);
317//    - sumOdd  = sum_k^{N-1} h_{2k+1} = 1/sqrt(2);
318//    - For each integer m = 0, 1, ..., N-1:
319//         sum_{k=2m}^{2N-1+2m} h_{k} h_{k-2m}
320//         = 1 if m=0,
321//         = 0 otherwise.
322// db2- 36
323for N=1:29
324  w=dbwavf("db"+sprintf("%d",N));
325  assert_checkalmostequal(sum(w(1:2:$)),1. /sqrt(2),%eps,%eps);
326  assert_checkalmostequal(sum(w(2:2:$)),1. /sqrt(2),%eps,%eps);
327  m=0;
328  assert_checkalmostequal(sum(w(2*m+1:(2*N+2*m)).*w(1:2*N)),1,%eps,%eps);
329  for m = 1:N-2
330    assert_checkalmostequal(sum(w(2*m+1:(2*N)).*w(1:2*(N)-2*m)),0,%eps,%eps);
331  end;
332 end;
333 for N=30:36
334  w=dbwavf("db"+sprintf("%d",N));
335  assert_checkalmostequal(sum(w(1:2:$)),1. /sqrt(2),%eps,%eps*10);
336  assert_checkalmostequal(sum(w(2:2:$)),1. /sqrt(2),%eps,%eps*10);
337  m=0;
338  assert_checkalmostequal(sum(w(2*m+1:(2*N+2*m)).*w(1:2*N)),1,%eps,%eps);
339  for m = 1:N-2
340    assert_checkalmostequal(sum(w(2*m+1:(2*N)).*w(1:2*(N)-2*m)),0,%eps,%eps);
341  end;
342 end;
343