Mercurial > hg > camir-aes2014
diff toolboxes/FullBNT-1.0.7/KPMtools/repmatC.c @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/FullBNT-1.0.7/KPMtools/repmatC.c Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,149 @@ +/* +mex -c mexutil.c +mex repmat.c mexutil.obj +to check for warnings: +gcc -Wall -I/cygdrive/c/MATLAB6p1/extern/include -c repmat.c +*/ +#include "mexutil.h" +#include <string.h> + +/* repeat a block of memory rep times */ +void memrep(char *dest, size_t chunk, int rep) +{ +#if 0 + /* slow way */ + int i; + char *p = dest; + for(i=1;i<rep;i++) { + p += chunk; + memcpy(p, dest, chunk); + } +#else + /* fast way */ + if(rep == 1) return; + memcpy(dest + chunk, dest, chunk); + if(rep & 1) { + dest += chunk; + memcpy(dest + chunk, dest, chunk); + } + /* now repeat using a block twice as big */ + memrep(dest, chunk<<1, rep>>1); +#endif +} + +void repmat(char *dest, const char *src, int ndim, int *destdimsize, + int *dimsize, const int *dims, int *rep) +{ + int d = ndim-1; + int i, chunk; + /* copy the first repetition into dest */ + if(d == 0) { + chunk = dimsize[0]; + memcpy(dest,src,chunk); + } + else { + /* recursively repeat each slice of src */ + for(i=0;i<dims[d];i++) { + repmat(dest + i*destdimsize[d-1], src + i*dimsize[d-1], + ndim-1, destdimsize, dimsize, dims, rep); + } + chunk = destdimsize[d-1]*dims[d]; + } + /* copy the result rep-1 times */ + memrep(dest,chunk,rep[d]); +} + +void mexFunction(int nlhs, mxArray *plhs[], + int nrhs, const mxArray *prhs[]) +{ + const mxArray *srcmat; + int ndim, *dimsize, eltsize; + const int *dims; + int ndimdest, *destdims, *destdimsize; + char *src, *dest; + int *rep; + int i,nrep; + int extra_rep = 1; + int empty; + + if(nrhs < 2) mexErrMsgTxt("Usage: xrepmat(A, [N M ...])"); + srcmat = prhs[0]; + if(mxIsSparse(srcmat)) { + mexErrMsgTxt("Sorry, can't handle sparse matrices yet."); + } + if(mxIsCell(srcmat)) { + mexErrMsgTxt("Sorry, can't handle cell arrays yet."); + } + ndim = mxGetNumberOfDimensions(srcmat); + dims = mxGetDimensions(srcmat); + eltsize = mxGetElementSize(srcmat); + + /* compute dimension sizes */ + dimsize = mxCalloc(ndim, sizeof(int)); + dimsize[0] = eltsize*dims[0]; + for(i=1;i<ndim;i++) dimsize[i] = dimsize[i-1]*dims[i]; + + /* determine repetition vector */ + ndimdest = ndim; + if(nrhs == 2) { + nrep = mxGetN(prhs[1]); + if(nrep > ndimdest) ndimdest = nrep; + rep = mxCalloc(ndimdest, sizeof(int)); + for(i=0;i<nrep;i++) { + double repv = mxGetPr(prhs[1])[i]; + rep[i] = (int)repv; + } + if(nrep == 1) { + /* special behavior */ + nrep = 2; + rep[1] = rep[0]; + } + } + else { + nrep = nrhs-1; + if(nrep > ndimdest) ndimdest = nrep; + rep = mxCalloc(ndimdest, sizeof(int)); + for(i=0;i<nrep;i++) { + rep[i] = (int)*mxGetPr(prhs[i+1]); + } + } + for(i=nrep;i<ndimdest;i++) rep[i] = 1; + + /* compute output size */ + destdims = mxCalloc(ndimdest, sizeof(int)); + for(i=0;i<ndim;i++) destdims[i] = dims[i]*rep[i]; + for(;i<ndimdest;i++) { + destdims[i] = rep[i]; + extra_rep *= rep[i]; + } + destdimsize = mxCalloc(ndim, sizeof(int)); + destdimsize[0] = eltsize*destdims[0]; + for(i=1;i<ndim;i++) destdimsize[i] = destdimsize[i-1]*destdims[i]; + + + /* for speed, array should be uninitialized */ + plhs[0] = mxCreateNumericArray(ndimdest, destdims, mxGetClassID(srcmat), + mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); + + /* if any rep[i] == 0, output should be empty array. + Added by KPM 11/13/02. + */ + empty = 0; + for (i=0; i < nrep; i++) { + if (rep[i]==0) + empty = 1; + } + if (empty) + return; + + src = (char*)mxGetData(srcmat); + dest = (char*)mxGetData(plhs[0]); + repmat(dest,src,ndim,destdimsize,dimsize,dims,rep); + if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep); + if(mxIsComplex(srcmat)) { + src = (char*)mxGetPi(srcmat); + dest = (char*)mxGetPi(plhs[0]); + repmat(dest,src,ndim,destdimsize,dimsize,dims,rep); + if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep); + } +}