/******************************************************* * zconv2D_OS.c - Written by Jason Laska * * Inputs: x - A 2D signal * h - 2D filter * m - upsample matrix of type: * Mk^(l) = 2*D0^(l-2)*R3^Sl(k) * Sl(k) = 2*floor(k/2) - 2^(l-2) + 1 * where D0 is a diagonal matrix and R3 * is a rotation matrix * * Outputs: y - 2D result of convolution with filter * upsampled by a parallelogram matrix. * * Usage: y = zconv2D_O(x,h,m); * * Notes: This function does not actually upsample the filter, * it computes the convolution as if the filter had been * upsampled. This is the ultimate optimized version. * Further optimized for separable (diagonal) upsampling matrices. * * This is a MEX-FILE for matlab * /********************************************************/ #include "mex.h" #include //Constants for matlab interfacing #define OUT plhs[0] #define SIGNAL prhs[0] //flip and shift #define FILTER prhs[1] //stationary #define MMATRIX prhs[2] //MACRO for converting positions to linear #define LINPOS(row,col,collen) (row*collen)+col void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /*Declarations*/ double *FArray,*SArray,*outArray,*M; int SColLength,SRowLength,FColLength,FRowLength,NewFColLength,NewFRowLength; int n1,n2,l1,l2,SkipX,SkipY,SkipP; double sum; int indexx,indexy,outindexx,outindexy,mn1,mn2,mn2save; int M0,M1,M2,M3; int Start1,End1,Start2,End2; /*Get the input sizes*/ SColLength = mxGetM(SIGNAL); SRowLength = mxGetN(SIGNAL); FColLength = mxGetM(FILTER); FRowLength = mxGetN(FILTER); /*Get The Data*/ FArray = mxGetPr(FILTER); SArray = mxGetPr(SIGNAL); M = mxGetPr(MMATRIX); M0 = (int)M[0]; M1 = (int)M[1]; M2 = (int)M[2]; M3 = (int)M[3]; /*Calculate New Magical Lengths*/ NewFRowLength = ((M[0]-1)*(FRowLength-1))+(M[2])*(FColLength-1) + FRowLength - 1; NewFColLength = ((M[3]-1)*(FColLength-1))+((M[1])*(FRowLength-1)) + FColLength - 1; /*Make output size and Allocate out vector*/ OUT = mxCreateDoubleMatrix(SColLength, SRowLength, mxREAL); outArray = mxGetPr(OUT); /*outArray is new vector*/ /*Initialize*/ sum = 0; Start1 = NewFRowLength/2; End1 = SRowLength+NewFRowLength/2; Start2 = NewFColLength/2; End2 = SColLength+NewFColLength/2; mn1 = Start1%SRowLength; mn2 = mn2save = Start2%SColLength; /*Compute!*/ for(n1=0; n1 (SRowLength-1)) // indexx -= SRowLength;*/ indexy -= M3; if(indexy < 0) indexy += SColLength; } outindexx -= M0; if(outindexx < 0) outindexx += SRowLength; /*outindexy -= M1; //if(outindexy < 0) // outindexy += SColLength; //if(outindexy > (SColLength-1)) // outindexy -= SColLength;*/ } outArray[LINPOS(n1,n2,SColLength)] = sum; sum = 0; mn2++; if(mn2 > (SColLength-1)) mn2 -= SColLength; } mn2 = mn2save; mn1++; if(mn1 > (SRowLength-1)) mn1 -= SRowLength; } return; }