Mercurial > hg > smallbox
view Problems/private/im2colstep.c @ 61:42fcbcfca132
(none)
author | idamnjanovic |
---|---|
date | Tue, 15 Mar 2011 12:21:31 +0000 |
parents | 51b76c31c93d |
children |
line wrap: on
line source
/************************************************************************** * * File name: im2colstep.c * * Ron Rubinstein * Computer Science Department * Technion, Haifa 32000 Israel * ronrubin@cs * * Last Updated: 31.8.2009 * *************************************************************************/ #include "mex.h" #include <string.h> /* Input Arguments */ #define X_IN prhs[0] #define SZ_IN prhs[1] #define S_IN prhs[2] /* Output Arguments */ #define B_OUT plhs[0] void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) { double *x, *b, *s; mwSize sz[3], stepsize[3], n[3], ndims; mwIndex i, j, k, l, m, blocknum; /* Check for proper number of arguments */ if (nrhs < 2 || nrhs > 3) { mexErrMsgTxt("Invalid number of input arguments."); } else if (nlhs > 1) { mexErrMsgTxt("Too many output arguments."); } /* Check the the input dimensions */ ndims = mxGetNumberOfDimensions(X_IN); if (!mxIsDouble(X_IN) || mxIsComplex(X_IN) || ndims>3) { mexErrMsgTxt("X should be a 2-D or 3-D double matrix."); } if (!mxIsDouble(SZ_IN) || mxIsComplex(SZ_IN) || mxGetNumberOfDimensions(SZ_IN)>2 || mxGetM(SZ_IN)*mxGetN(SZ_IN)!=ndims) { mexErrMsgTxt("Invalid block size."); } if (nrhs == 3) { if (!mxIsDouble(S_IN) || mxIsComplex(S_IN) || mxGetNumberOfDimensions(S_IN)>2 || mxGetM(S_IN)*mxGetN(S_IN)!=ndims) { mexErrMsgTxt("Invalid step size."); } } /* Get parameters */ s = mxGetPr(SZ_IN); if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { mexErrMsgTxt("Invalid block size."); } sz[0] = (mwSize)(s[0] + 0.01); sz[1] = (mwSize)(s[1] + 0.01); sz[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; if (nrhs == 3) { s = mxGetPr(S_IN); if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { mexErrMsgTxt("Invalid step size."); } stepsize[0] = (mwSize)(s[0] + 0.01); stepsize[1] = (mwSize)(s[1] + 0.01); stepsize[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; } else { stepsize[0] = stepsize[1] = stepsize[2] = 1; } n[0] = (mxGetDimensions(X_IN))[0]; n[1] = (mxGetDimensions(X_IN))[1]; n[2] = ndims==3 ? (mxGetDimensions(X_IN))[2] : 1; if (n[0]<sz[0] || n[1]<sz[1] || (ndims==3 && n[2]<sz[2])) { mexErrMsgTxt("Block size too large."); } /* Create a matrix for the return argument */ B_OUT = mxCreateDoubleMatrix(sz[0]*sz[1]*sz[2], ((n[0]-sz[0])/stepsize[0]+1)*((n[1]-sz[1])/stepsize[1]+1)*((n[2]-sz[2])/stepsize[2]+1), mxREAL); /* Assign pointers */ x = mxGetPr(X_IN); b = mxGetPr(B_OUT); /* Do the actual computation */ blocknum = 0; /* iterate over all blocks */ for (k=0; k<=n[2]-sz[2]; k+=stepsize[2]) { for (j=0; j<=n[1]-sz[1]; j+=stepsize[1]) { for (i=0; i<=n[0]-sz[0]; i+=stepsize[0]) { /* copy single block */ for (m=0; m<sz[2]; m++) { for (l=0; l<sz[1]; l++) { memcpy(b + blocknum*sz[0]*sz[1]*sz[2] + m*sz[0]*sz[1] + l*sz[0], x+(k+m)*n[0]*n[1]+(j+l)*n[0]+i, sz[0]*sizeof(double)); } } blocknum++; } } } return; }