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); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mxArray *srcmat; int ndim, eltsize; mwSize *dimsize; const mwSize *dims; int ndimdest; mwSize *destdims, *destdimsize; char *src, *dest; mwSize *rep; int i,nrep; int extra_rep = 1; int empty; double *outp, *inp; mwSize m,n,numel; if(nrhs < 2) mexErrMsgTxt("Usage: repmat(A, [M N ...])"); srcmat = prhs[0]; if(0) { /* testing code, please ignore */ /* plhs[0] = mxCreateNumericArrayE(ndim, dims, mxGetClassID(srcmat), mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); */ m = mxGetM(srcmat); n = mxGetN(srcmat); plhs[0] = mxCreateDoubleMatrixE(m, n, mxREAL); outp = mxGetPr(plhs[0]); inp = mxGetPr(srcmat); numel = mxGetNumberOfElements(srcmat); memcpy(outp, inp, numel*sizeof(double)); /* plhs[0] = mxCreateNumericMatrixE(dims[0], dims[1], mxGetClassID(srcmat), mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); plhs[0] = mxCreateNumericMatrix(0, 0, mxGetClassID(srcmat), mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); */ return; } if(!mxIsNumeric(srcmat) || mxIsSparse(srcmat) || mxIsCell(srcmat) || mxIsStruct(srcmat)) { /* call Matlab's repmat */ mexCallMATLAB(nlhs,plhs,nrhs,(mxArray**)prhs,"xrepmat");return; /* mexErrMsgTxt("Sorry, can't handle sparse matrices yet."); */ } ndim = mxGetNumberOfDimensions(srcmat); dims = mxGetDimensions(srcmat); eltsize = mxGetElementSize(srcmat); /* compute dimension sizes */ dimsize = (mwSize*)mxCalloc(ndim, sizeof(mwSize)); 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) { /* prhs[1] is a vector of reps */ nrep = mxGetN(prhs[1]); if(nrep > ndimdest) ndimdest = nrep; rep = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize)); for(i=0;i<nrep;i++) { double repv = mxGetPr(prhs[1])[i]; rep[i] = (mwSize)repv; } #if ALWAYS_2D if(nrep == 1) { /* special behavior */ nrep = 2; rep[1] = rep[0]; } #endif } else { /* concatenate all prhs's */ int ri=0; nrep = 0; for(i=0;i<nrhs-1;i++) { nrep += mxGetNumberOfElements(prhs[i+1]); } if(nrep > ndimdest) ndimdest = nrep; rep = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize)); for(i=0;i<nrhs-1;i++) { double *p = mxGetPr(prhs[i+1]); int j, sz = mxGetNumberOfElements(prhs[i+1]); for(j=0;j<sz;j++) rep[ri++] = (mwSize)p[j]; } } for(i=nrep;i<ndimdest;i++) rep[i] = 1; /* compute output size */ destdims = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize)); 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 = (mwSize*)mxCalloc(ndim, sizeof(mwSize)); 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] = mxCreateNumericArrayE(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); } }