comparison util/Rice Wavelet Toolbox/mirdwt.c @ 78:f69ae88b8be5

added Rice Wavelet Toolbox with my modification, so it can be compiled on newer systems.
author Ivan Damnjanovic lnx <ivan.damnjanovic@eecs.qmul.ac.uk>
date Fri, 25 Mar 2011 15:27:33 +0000
parents
children
comparison
equal deleted inserted replaced
76:d052ec5b742f 78:f69ae88b8be5
1 /*
2 File Name: mirdwt.c
3 Last Modification Date: %G% %U%
4 Current Version: %M% %I%
5 File Creation Date: Wed Oct 12 08:44:43 1994
6 Author: Markus Lang <lang@jazz.rice.edu>
7
8 Copyright: All software, documentation, and related files in this distribution
9 are Copyright (c) 1994 Rice University
10
11 Permission is granted for use and non-profit distribution providing that this
12 notice be clearly maintained. The right to distribute any portion for profit
13 or as part of any commercial product is specifically reserved for the author.
14
15 Change History: Fixed code such that the result has the same dimension as the
16 input for 1D problems. Also, added some standard error checking.
17 Jan Erik Odegard <odegard@ece.rice.edu> Wed Jun 14 1995
18
19 */
20
21 #include <math.h>
22 /*#include <malloc.h>*/
23 #include <stdio.h>
24 #include "mex.h"
25 #include "matrix.h"
26 #if !defined(_WIN32) && !defined(_WIN64)
27 #include <inttypes.h>
28 #endif
29 #define max(A,B) (A > B ? A : B)
30 #define min(A,B) (A < B ? A : B)
31 #define even(x) ((x & 1) ? 0 : 1)
32 #define isint(x) ((x - floor(x)) > 0.0 ? 0 : 1)
33
34
35 void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
36
37 {
38 double *x, *h, *yl, *yh, *Lf, *Lr;
39 intptr_t m, n, mh, nh, h_col, h_row, lh, L, i, po2, j;
40 double mtest, ntest;
41
42 /* check for correct # of input variables */
43 if (nrhs>4){
44 mexErrMsgTxt("There are at most 4 input parameters allowed!");
45 return;
46 }
47 if (nrhs<3){
48 mexErrMsgTxt("There are at least 3 input parameters required!");
49 return;
50 }
51 yl = mxGetPr(prhs[0]);
52 n = mxGetN(prhs[0]);
53 m = mxGetM(prhs[0]);
54 yh = mxGetPr(prhs[1]);
55 nh = mxGetN(prhs[1]);
56 mh = mxGetM(prhs[1]);
57 h = mxGetPr(prhs[2]);
58 h_col = mxGetN(prhs[2]);
59 h_row = mxGetM(prhs[2]);
60 if (h_col>h_row)
61 lh = h_col;
62 else
63 lh = h_row;
64 if (nrhs == 4){
65 L = (intptr_t) *mxGetPr(prhs[3]);
66 if (L < 0)
67 mexErrMsgTxt("The number of levels, L, must be a non-negative integer");
68 }
69 else /* Estimate L */ {
70 i=n;j=0;
71 while (even(i)){
72 i=(i>>1);
73 j++;
74 }
75 L=m;i=0;
76 while (even(L)){
77 L=(L>>1);
78 i++;
79 }
80 if(min(m,n) == 1)
81 L = max(i,j);
82 else
83 L = min(i,j);
84 if (L==0){
85 mexErrMsgTxt("Maximum number of levels is zero; no decomposition can be performed!");
86 return;
87 }
88 }
89 /* check for consistency of rows and columns of yl, yh */
90 if (min(m,n) > 1){
91 if((m != mh) | (3*n*L != nh)){
92 mexErrMsgTxt("Dimensions of first two input matrices not consistent!");
93 return;
94 }
95 }
96 else{
97 if((m != mh) | (n*L != nh)){
98 mexErrMsgTxt("Dimensions of first two input vectors not consistent!");{
99 return;
100 }
101 }
102 }
103 /* Check the ROW dimension of input */
104 if(m > 1){
105 mtest = (double) m/pow(2.0, (double) L);
106 if (!isint(mtest))
107 mexErrMsgTxt("The matrix row dimension must be of size m*2^(L)");
108 }
109 /* Check the COLUMN dimension of input */
110 if(n > 1){
111 ntest = (double) n/pow(2.0, (double) L);
112 if (!isint(ntest))
113 mexErrMsgTxt("The matrix column dimension must be of size n*2^(L)");
114 }
115 plhs[0] = mxCreateDoubleMatrix(m,n,mxREAL);
116 x = mxGetPr(plhs[0]);
117 plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
118 Lr = mxGetPr(plhs[1]);
119 *Lr = L;
120 MIRDWT(x, m, n, h, lh, L, yl, yh);
121 }
122 #define mat(a, i, j) (*(a + (m*(j)+i))) /* macro for matrix indices */
123
124 #ifdef __STDC__
125 MIRDWT(double *x, intptr_t m, intptr_t n, double *h, intptr_t lh, intptr_t L,
126 double *yl, double *yh)
127 #else
128 MIRDWT(x, m, n, h, lh, L, yl, yh)
129 double *x, *h, *yl, *yh;
130 intptr_t m, n, lh, L;
131 #endif
132 {
133 double *g0, *g1, *ydummyll, *ydummylh, *ydummyhl;
134 double *ydummyhh, *xdummyl , *xdummyh, *xh;
135 intptr_t i, j;
136 intptr_t actual_L, actual_m, actual_n, c_o_a, ir, n_c, n_cb, n_c_o, lhm1;
137 intptr_t ic, n_r, n_rb, n_r_o, c_o_a_p2n, sample_f;
138 xh = (double *)(intptr_t)mxCalloc(m*n,sizeof(double));
139 xdummyl = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double));
140 xdummyh = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double));
141 ydummyll = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double));
142 ydummylh = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double));
143 ydummyhl = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double));
144 ydummyhh = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double));
145 g0 = (double *)(intptr_t)mxCalloc(lh,sizeof(double));
146 g1 = (double *)(intptr_t)mxCalloc(lh,sizeof(double));
147
148 if (n==1){
149 n = m;
150 m = 1;
151 }
152 /* analysis lowpass and highpass */
153 for (i=0; i<lh; i++){
154 g0[i] = h[i]/2;
155 g1[i] = h[lh-i-1]/2;
156 }
157 for (i=1; i<=lh; i+=2)
158 g1[i] = -g1[i];
159
160 lhm1 = lh - 1;
161 /* 2^L */
162 sample_f = 1;
163 for (i=1; i<L; i++)
164 sample_f = sample_f*2;
165 actual_m = m/sample_f;
166 actual_n = n/sample_f;
167 /* restore yl in x */
168 for (i=0;i<m*n;i++)
169 x[i] = yl[i];
170
171 /* main loop */
172 for (actual_L=L; actual_L >= 1; actual_L--){
173 /* actual (level dependent) column offset */
174 if (m==1)
175 c_o_a = n*(actual_L-1);
176 else
177 c_o_a = 3*n*(actual_L-1);
178 c_o_a_p2n = c_o_a + 2*n;
179
180 /* go by columns in case of a 2D signal*/
181 if (m>1){
182 n_rb = m/actual_m; /* # of row blocks per column */
183 for (ic=0; ic<n; ic++){ /* loop over column */
184 for (n_r=0; n_r<n_rb; n_r++){ /* loop within one column */
185 /* store in dummy variables */
186 ir = -sample_f + n_r;
187 for (i=0; i<actual_m; i++){
188 ir = ir + sample_f;
189 ydummyll[i+lhm1] = mat(x, ir, ic);
190 ydummylh[i+lhm1] = mat(yh, ir, c_o_a+ic);
191 ydummyhl[i+lhm1] = mat(yh, ir,c_o_a+n+ic);
192 ydummyhh[i+lhm1] = mat(yh, ir, c_o_a_p2n+ic);
193 }
194 /* perform filtering and adding: first LL/LH, then HL/HH */
195 bpconv(xdummyl, actual_m, g0, g1, lh, ydummyll, ydummylh);
196 bpconv(xdummyh, actual_m, g0, g1, lh, ydummyhl, ydummyhh);
197 /* store dummy variables in matrices */
198 ir = -sample_f + n_r;
199 for (i=0; i<actual_m; i++){
200 ir = ir + sample_f;
201 mat(x, ir, ic) = xdummyl[i];
202 mat(xh, ir, ic) = xdummyh[i];
203 }
204 }
205 }
206 }
207
208 /* go by rows */
209 n_cb = n/actual_n; /* # of column blocks per row */
210 for (ir=0; ir<m; ir++){ /* loop over rows */
211 for (n_c=0; n_c<n_cb; n_c++){ /* loop within one row */
212 /* store in dummy variable */
213 ic = -sample_f + n_c;
214 for (i=0; i<actual_n; i++){
215 ic = ic + sample_f;
216 ydummyll[i+lhm1] = mat(x, ir, ic);
217 if (m>1)
218 ydummyhh[i+lhm1] = mat(xh, ir, ic);
219 else
220 ydummyhh[i+lhm1] = mat(yh, ir, c_o_a+ic);
221 }
222 /* perform filtering lowpass/highpass */
223 bpconv(xdummyl, actual_n, g0, g1, lh, ydummyll, ydummyhh);
224 /* restore dummy variables in matrices */
225 ic = -sample_f + n_c;
226 for (i=0; i<actual_n; i++){
227 ic = ic + sample_f;
228 mat(x, ir, ic) = xdummyl[i];
229 }
230 }
231 }
232 sample_f = sample_f/2;
233 actual_m = actual_m*2;
234 actual_n = actual_n*2;
235 }
236 }
237
238 #ifdef __STDC__
239 bpconv(double *x_out, intptr_t lx, double *g0, double *g1, intptr_t lh,
240 double *x_inl, double *x_inh)
241 #else
242 bpconv(x_out, lx, g0, g1, lh, x_inl, x_inh)
243 double *x_inl, *x_inh, *g0, *g1, *x_out;
244 intptr_t lx, lh;
245 #endif
246 {
247 intptr_t i, j;
248 double x0;
249
250 for (i=lh-2; i > -1; i--){
251 x_inl[i] = x_inl[lx+i];
252 x_inh[i] = x_inh[lx+i];
253 }
254 for (i=0; i<lx; i++){
255 x0 = 0;
256 for (j=0; j<lh; j++)
257 x0 = x0 + x_inl[j+i]*g0[lh-1-j] +
258 x_inh[j+i]*g1[lh-1-j];
259 x_out[i] = x0;
260 }
261 }