void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) { DOUBLE *sig,*wcp,*tmp; mxArray *temp; unsigned int m,n; int nr,nc,nn,J; /* Check for proper number of arguments */ if (nrhs != 1) { mexErrMsgTxt("dct_ii requires one input argument."); } else if (nlhs != 1) { mexErrMsgTxt("dct_ii requires one output argument."); } /* Check the dimensions of signal. signal can be n X 1 or 1 X n. */ /* future enhancement -- vectorize, do each column of matrix */ m = mxGetM(Sig_IN); n = mxGetN(Sig_IN); if(m == 1){ nr = (int) n; nc = 1; } else { nr = (int) m; nc = (int) n; } J = 0; for( nn = 1; nn < nr; nn *= 2 ) J ++; if( nn != nr){ mexErrMsgTxt("dct_ii requires dyadic length"); } /* Create a matrix for the return argument */ DCT_OUT = mxCreateDoubleMatrix(m, n, mxREAL); temp = mxCreateDoubleMatrix(4*n,1,mxREAL); /* Assign pointers to the various parameters */ wcp = mxGetPr(DCT_OUT); sig = mxGetPr(Sig_IN); tmp = mxGetPr(temp); copydouble(sig,tmp,nr); /* Do the actual computations in a subroutine */ dct(&tmp[0],&tmp[nr],J,&tmp[2*nr]); copydouble(tmp,wcp,nr); mxDestroyArray(temp); }
/** * @brief Perform forward DWT (periodic boundaries) on 3D data. * * @param sig Signal to be transformed. * @param res Decomposed signal. */ void dpwt3 (const Matrix <T> & sig, Matrix <T> & res) { // assign signal to result matrix res = sig; # pragma omp parallel default (shared), num_threads (_num_threads) { T * wcplo, * wcphi, * templo, * temphi, * tmp; size_t stride; int sl1 = _sl1, sl2 = _sl2, sl3 = _sl3; const int t_num = omp_get_thread_num (); // loop over levels of DWT for (int j = (_max_level-1); j >= _min_level; --j) { // update stride stride = sl1 * t_num; // update thread's temporary memory address tmp = & _temp [stride]; # pragma omp for schedule (OMP_SCHEDULE) // loop over lines along first dimension ('columns') of image for (int c2_loc = 0; c2_loc < sl2 * sl3; c2_loc++) { int c2_glob = (c2_loc / sl2) * _sl1 * _sl2 + (c2_loc % sl2) * _sl1; // access to lowpass part of DWT wcplo = & res [c2_glob /** _sl1*/]; // access to highpass part of DWT wcphi = & res [c2_glob /** _sl1*/ + sl1 / 2]; // copy part of image to _temp memory copydouble (wcplo, tmp, sl1); // apply low pass filter on current line and write to result matrix downlo (tmp, sl1, wcplo); // apply high pass filter on current line and write to result matrix downhi (tmp, sl1, wcphi); } // loop over lines along first dimension // update stride stride = 2 * sl2 * t_num; // update thread's temporary memory address tmp = & _temp [stride]; templo = & _temp [ sl2 + stride]; temphi = & _temp [1.5 * sl2 + stride]; # pragma omp for schedule (OMP_SCHEDULE) // loop over lines along second dimension ('rows') of image for (int c1_loc = 0; c1_loc < sl1 * sl3; c1_loc++) { int c1_glob = (c1_loc / sl1) * _sl1 * _sl2; // copy c1-th line of image to temp_mem unpackdouble (& res [c1_glob], sl2, _sl1, c1_loc % sl1, tmp); // apply low pass filter on current line and write to _temp mem downlo (tmp, sl2, templo); // apply high pass filter on current line and write to _temp mem downhi (tmp, sl2, temphi); // write temp lowpass result to result matrix packdouble (templo, sl2 / 2, _sl1, c1_loc % sl1, & res [c1_glob]); // write temp highpass result to result matrix packdouble (temphi, sl2 / 2, _sl1, c1_loc % sl1, & res [c1_glob + sl2 / 2 * _sl1]); } // loop over lines along second dimension // update stride stride = 2 * sl3 * t_num; // update thread's temporary memory address tmp = & _temp [stride]; templo = & _temp [ sl3 + stride]; temphi = & _temp [1.5 * sl3 + stride]; # pragma omp for schedule (OMP_SCHEDULE) // loop over lines along third dimension ('third') of image for (int c1_loc = 0; c1_loc < sl1 * sl2; c1_loc++) { int c1_glob = (c1_loc % sl1) + (c1_loc / sl1) * _sl1; // copy c2-th line of image to temp_mem unpackdouble (& res [c1_glob], sl3, _ld12, 0, tmp); // apply low pass filter on current line and write to _temp mem downlo (tmp, sl3, templo); // apply high pass filter on current line and write to _temp mem downhi (tmp, sl3, temphi); // write temp lowpass result to result matrix packdouble (templo, sl3 / 2, _ld12, 0, & res [c1_glob]); // write temp highpass result to result matrix packdouble (temphi, sl3 / 2, _ld12, 0, & res [c1_glob + sl3 / 2 * _ld12]); } // loop over lines along third dimension // reduce dimensions for next level sl1 /= 2; sl2 /= 2; sl3 /= 2; } // loop over levels of DWT } // omp parallel }
/** * @brief Perform inverse DWT (periodic boundaries) on 3D data. * * @param wc Wavelet presentation of 3D data. * @param img Reconstructed signal. */ void idpwt3 (const Matrix <T> & wc, Matrix <T> & img) { // assign dwt to result image img = wc; # pragma omp parallel default (shared) num_threads (_num_threads) { T * wcplo, * wcphi, * templo, * temphi, * temptop, * tmp; size_t stride; int sl1 = _sl1_scale, sl2 = _sl2_scale, sl3 = _sl3_scale; const int t_num = omp_get_thread_num (); // loop over levels of backwards DWT for (int j = _min_level; j < _max_level; j++) { // update stride stride = 6 * sl3 * t_num; tmp = & _temp [stride]; templo = & _temp [2 * sl3 + stride]; temphi = & _temp [3 * sl3 + stride]; temptop = & _temp [4 * sl3 + stride]; # pragma omp for schedule (OMP_SCHEDULE) // loop over lines along third dimension ('third') of result image for (int c1_loc = 0; c1_loc < 2 * sl1 * 2 * sl2; c1_loc++) { int c1_glob = (c1_loc % (2 * sl1)) + (c1_loc / (2 * sl1)) * _sl1; // copy lowpass part of current line to temporary memory unpackdouble (& img [c1_glob], sl3, _ld12, 0, templo); // copy highpass part of current line to temporary memory unpackdouble (& img [c1_glob + sl3 * _ld12], sl3, _ld12, 0, temphi); // perform lowpass reconstruction uplo (templo, sl3, tmp); // perform highpass reconstruction uphi (temphi, sl3, temptop); // fusion of reconstruction parts adddouble (tmp, temptop, sl3 * 2, tmp); // write back reconstructed line packdouble (tmp, sl3 * 2, _ld12, 0, & img [c1_glob]); } // loop over lines along third dimension of result image // update stride stride = 6 * sl2 * t_num; tmp = & _temp [stride]; templo = & _temp [2 * sl2 + stride]; temphi = & _temp [3 * sl2 + stride]; temptop = & _temp [4 * sl2 + stride]; # pragma omp for schedule (OMP_SCHEDULE) // loop over lines along second dimension ('rows') of result image for (int c1_loc = 0; c1_loc < 2 * sl1 * 2 * sl3; c1_loc++) { int c1_glob = (c1_loc / (2 * sl1)) * _sl1 * _sl2; // copy lowpass part of current line to temporary memory unpackdouble (& img [c1_glob], sl2, _sl1, c1_loc % (2 * sl1), templo); // copy highpass part of current line to temporary memory unpackdouble (& img [c1_glob + sl2 * _sl1], sl2, _sl1, c1_loc % (2 * sl1), temphi); // perform lowpass reconstruction uplo (templo, sl2, tmp); // perform highpass reconstruction uphi (temphi, sl2, temptop); // fusion of reconstruction parts adddouble (tmp, temptop, sl2 * 2, tmp); // write back reconstructed line packdouble (tmp, sl2 * 2, _sl1, c1_loc % (2 * sl1), & img [c1_glob]); } // loop over lines along second dimension of result image // update stride stride = 5 * sl1 * t_num; tmp = & _temp [stride]; templo = & _temp [ sl1 + stride]; temphi = & _temp [3 * sl1 + stride]; # pragma omp for schedule (OMP_SCHEDULE) // loop over lines along first dimension ('columns') of result image for (int c2_loc = 0; c2_loc < 2 * sl2 * 2 * sl3; c2_loc++) { int c2_glob = (c2_loc / (2 * sl2)) * _sl2 * _sl1 + (c2_loc % (2 * sl2)) * _sl1; // assign address of current line's lowpass part wcplo = & img [c2_glob]; // assign address of current line's highpass part wcphi = & img [c2_glob + sl1]; // copy lowpass part to temporary memory copydouble (wcplo, tmp, sl1); // perform lowpass reconstruction uplo (wcplo, sl1, templo); // perform highpass reconstruction uphi (wcphi, sl1, temphi); // combine reconstructed parts and write back to current line adddouble (templo, temphi, sl1 * 2, wcplo); } // loop over lines along first dimension ('columns') of result image // update current row / column size sl2 *= 2; sl1 *= 2; sl3 *= 2; } // loop over levels of backwards DWT } // omp parallel }
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) { DOUBLE *hpf,*lpf; DOUBLE *sig,*wcp,*wcp1,*wcp2; /* unsigned int m,n; */ int nr,nc,nn,mm,kk,J,lenfil,dee; mxArray *temp, *hpfmat, *WP_OUT1, *WP_OUT2; /* Check for proper number of arguments */ if (nrhs != 3) { mexErrMsgTxt("rec_wp_decomp1 requires three input arguments."); } else if (nlhs != 1) { mexErrMsgTxt("rec_wp_decomp1 requires one output argument."); } /* Check the dimensions of signal. signal can be n X 1 or 1 X n. */ nr = mxGetM(Sig_IN); nc = mxGetN(Sig_IN); J = 0; for( nn = 1; nn < nc; nn *= 2 ) J ++; if( nn != nc){ mexErrMsgTxt("rec_wp_decomp1 requires dyadic length"); } J = 0; for( nn = 1; nn < nr; nn *= 2 ) J ++; if( nn != nr){ mexErrMsgTxt("rec_wp_decomp1 requires dyadic length"); } WP_OUT = mxCreateDoubleMatrix(nr, nc, mxREAL); sig = mxGetPr(Sig_IN); wcp = mxGetPr(WP_OUT); lenfil = (int) (mxGetM(LPF_IN) * mxGetN(LPF_IN)); /* should check this */ lpf = mxGetPr(LPF_IN); hpfmat = mxCreateDoubleMatrix((unsigned int) lenfil, 1, mxREAL); hpf = mxGetPr(hpfmat); mirrorfilt(lpf,hpf,lenfil); for( kk = 0; kk < mxGetN(LLL_IN); kk++) { dee = floor ((mxGetPr(LLL_IN))[kk] + .5); /* should check whether this is in range */ /* Create a matrix for the return argument */ if( dee > J ){ mexErrMsgTxt("rec_wp_decomp1 requires D < log_2(n)"); } if( dee < 0){ mexErrMsgTxt("rec_wp_decomp1 requires D >= 0"); } nn = dee+1; for( mm = nc/2; mm < nc; mm++){ WP_OUT1 = mxCreateDoubleMatrix(nr, nn, mxREAL); WP_OUT2 = mxCreateDoubleMatrix(nr, 1, mxREAL); temp = mxCreateDoubleMatrix(nr, 6, mxREAL); /* Assign pointers to the various parameters */ wcp1 = mxGetPr(WP_OUT1); wcp2 = mxGetPr(WP_OUT2); copydouble(&sig[mm*nr],wcp2,nr); /* Do the actual computations in a subroutine */ wpd(wcp2,nr,dee,hpf,lpf,lenfil,wcp1,mxGetPr(temp)); copydouble(&wcp1[0],&wcp[mm*nr],nr); mxDestroyArray(temp); } nc = nc/2; } mxDestroyArray(hpfmat); }