annotate util/Rice Wavelet Toolbox/mirdwt.c @ 162:88578ec2f94a danieleb

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