ivan@78: /* ivan@78: File Name: midwt.c ivan@78: Last Modification Date: 06/14/95 12:55:58 ivan@78: Current Version: midwt.c 1.4 ivan@78: File Creation Date: Wed Oct 12 08:44:43 1994 ivan@78: Author: Markus Lang ivan@78: ivan@78: Copyright: All software, documentation, and related files in this distribution ivan@78: are Copyright (c) 1994 Rice University ivan@78: ivan@78: Permission is granted for use and non-profit distribution providing that this ivan@78: notice be clearly maintained. The right to distribute any portion for profit ivan@78: or as part of any commercial product is specifically reserved for the author. ivan@78: ivan@78: Change History: Fixed code such that the result has the same dimension as the ivan@78: input for 1D problems. Also, added some standard error checking. ivan@78: Jan Erik Odegard Wed Jun 14 1995 ivan@78: ivan@78: */ ivan@78: #include ivan@78: /*#include */ ivan@78: #include ivan@78: #include "mex.h" ivan@78: #include "matrix.h" ivan@78: #if !defined(_WIN32) && !defined(_WIN64) ivan@78: #include ivan@78: #endif ivan@78: #define max(A,B) (A > B ? A : B) ivan@78: #define min(A,B) (A < B ? A : B) ivan@78: #define even(x) ((x & 1) ? 0 : 1) ivan@78: #define isint(x) ((x - floor(x)) > 0.0 ? 0 : 1) ivan@78: ivan@78: ivan@78: ivan@78: void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) ivan@78: ivan@78: { ivan@78: double *x, *h, *y, *Lf, *Lr; ivan@78: intptr_t m, n, h_col, h_row, lh, L, i, po2, j; ivan@78: double mtest, ntest; ivan@78: ivan@78: /* check for correct # of input variables */ ivan@78: if (nrhs>3){ ivan@78: mexErrMsgTxt("There are at most 3 input parameters allowed!"); ivan@78: return; ivan@78: } ivan@78: if (nrhs<2){ ivan@78: mexErrMsgTxt("There are at least 2 input parameters required!"); ivan@78: return; ivan@78: } ivan@78: y = mxGetPr(prhs[0]); ivan@78: n = mxGetN(prhs[0]); ivan@78: m = mxGetM(prhs[0]); ivan@78: h = mxGetPr(prhs[1]); ivan@78: h_col = mxGetN(prhs[1]); ivan@78: h_row = mxGetM(prhs[1]); ivan@78: if (h_col>h_row) ivan@78: lh = h_col; ivan@78: else ivan@78: lh = h_row; ivan@78: if (nrhs == 3){ ivan@78: L = (intptr_t) *mxGetPr(prhs[2]); ivan@78: if (L < 0) ivan@78: mexErrMsgTxt("The number of levels, L, must be a non-negative integer"); ivan@78: } ivan@78: else /* Estimate L */ { ivan@78: i=n;j=0; ivan@78: while (even(i)){ ivan@78: i=(i>>1); ivan@78: j++; ivan@78: } ivan@78: L=m;i=0; ivan@78: while (even(L)){ ivan@78: L=(L>>1); ivan@78: i++; ivan@78: } ivan@78: if(min(m,n) == 1) ivan@78: L = max(i,j); ivan@78: else ivan@78: L = min(i,j); ivan@78: if (L==0){ ivan@78: mexErrMsgTxt("Maximum number of levels is zero; no decomposition can be performed!"); ivan@78: return; ivan@78: } ivan@78: } ivan@78: /* Check the ROW dimension of input */ ivan@78: if(m > 1){ ivan@78: mtest = (double) m/pow(2.0, (double) L); ivan@78: if (!isint(mtest)) ivan@78: mexErrMsgTxt("The matrix row dimension must be of size m*2^(L)"); ivan@78: } ivan@78: /* Check the COLUMN dimension of input */ ivan@78: if(n > 1){ ivan@78: ntest = (double) n/pow(2.0, (double) L); ivan@78: if (!isint(ntest)) ivan@78: mexErrMsgTxt("The matrix column dimension must be of size n*2^(L)"); ivan@78: } ivan@78: plhs[0] = mxCreateDoubleMatrix(m,n,mxREAL); ivan@78: x = mxGetPr(plhs[0]); ivan@78: plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL); ivan@78: Lr = mxGetPr(plhs[1]); ivan@78: *Lr = L; ivan@78: MIDWT(x, m, n, h, lh, L, y); ivan@78: } ivan@78: ivan@78: #define mat(a, i, j) (*(a + (m*(j)+i))) /* macro for matrix indices */ ivan@78: ivan@78: ivan@78: #ifdef __STDC__ ivan@78: MIDWT(double *x, intptr_t m, intptr_t n, double *h, intptr_t lh, intptr_t L, double *y) ivan@78: #else ivan@78: MIDWT(x, m, n, h, lh, L, y) ivan@78: double *x, *h, *y; ivan@78: intptr_t m, n, lh, L; ivan@78: #endif ivan@78: { ivan@78: double *g0, *g1, *ydummyl, *ydummyh, *xdummy; ivan@78: intptr_t i, j; ivan@78: intptr_t actual_L, actual_m, actual_n, r_o_a, c_o_a, ir, ic, lhm1, lhhm1, sample_f; ivan@78: xdummy = (double *)mxCalloc(max(m,n),sizeof(double)); ivan@78: ydummyl = (double *)mxCalloc(max(m,n)+lh/2-1,sizeof(double)); ivan@78: ydummyh = (double *)(intptr_t)mxCalloc(max(m,n)+lh/2-1,sizeof(double)); ivan@78: g0 = (double *)(intptr_t)mxCalloc(lh,sizeof(double)); ivan@78: g1 = (double *)(intptr_t)mxCalloc(lh,sizeof(double)); ivan@78: ivan@78: if (n==1){ ivan@78: n = m; ivan@78: m = 1; ivan@78: } ivan@78: /* synthesis lowpass and highpass */ ivan@78: for (i=0; i1) ivan@78: actual_m = m/sample_f; ivan@78: else ivan@78: actual_m = 1; ivan@78: actual_n = n/sample_f; ivan@78: ivan@78: for (i=0; i<(m*n); i++) ivan@78: x[i] = y[i]; ivan@78: ivan@78: /* main loop */ ivan@78: for (actual_L=L; actual_L >= 1; actual_L--){ ivan@78: r_o_a = actual_m/2; ivan@78: c_o_a = actual_n/2; ivan@78: ivan@78: /* go by columns in case of a 2D signal*/ ivan@78: if (m>1){ ivan@78: for (ic=0; ic -1; i--){ ivan@78: x_inl[i] = x_inl[lx+i]; ivan@78: x_inh[i] = x_inh[lx+i]; ivan@78: } ivan@78: ind = 0; ivan@78: for (i=0; i<(lx); i++){ ivan@78: x0 = 0; ivan@78: x1 = 0; ivan@78: tj = -2; ivan@78: for (j=0; j<=lhhm1; j++){ ivan@78: tj+=2; ivan@78: x0 = x0 + x_inl[i+j]*g0[lhm1-1-tj] + x_inh[i+j]*g1[lhm1-1-tj] ; ivan@78: x1 = x1 + x_inl[i+j]*g0[lhm1-tj] + x_inh[i+j]*g1[lhm1-tj] ; ivan@78: } ivan@78: x_out[ind++] = x0; ivan@78: x_out[ind++] = x1; ivan@78: } ivan@78: }