annotate _FullBNT/KPMtools/repmatC.c @ 9:4ea6619cb3f5 tip

removed log files
author matthiasm
date Fri, 11 Apr 2014 15:55:11 +0100
parents b5b38998ef3b
children
rev   line source
matthiasm@8 1 /*
matthiasm@8 2 mex -c mexutil.c
matthiasm@8 3 mex repmat.c mexutil.obj
matthiasm@8 4 to check for warnings:
matthiasm@8 5 gcc -Wall -I/cygdrive/c/MATLAB6p1/extern/include -c repmat.c
matthiasm@8 6 */
matthiasm@8 7 #include "mexutil.h"
matthiasm@8 8 #include <string.h>
matthiasm@8 9
matthiasm@8 10 /* repeat a block of memory rep times */
matthiasm@8 11 void memrep(char *dest, size_t chunk, int rep)
matthiasm@8 12 {
matthiasm@8 13 #if 0
matthiasm@8 14 /* slow way */
matthiasm@8 15 int i;
matthiasm@8 16 char *p = dest;
matthiasm@8 17 for(i=1;i<rep;i++) {
matthiasm@8 18 p += chunk;
matthiasm@8 19 memcpy(p, dest, chunk);
matthiasm@8 20 }
matthiasm@8 21 #else
matthiasm@8 22 /* fast way */
matthiasm@8 23 if(rep == 1) return;
matthiasm@8 24 memcpy(dest + chunk, dest, chunk);
matthiasm@8 25 if(rep & 1) {
matthiasm@8 26 dest += chunk;
matthiasm@8 27 memcpy(dest + chunk, dest, chunk);
matthiasm@8 28 }
matthiasm@8 29 /* now repeat using a block twice as big */
matthiasm@8 30 memrep(dest, chunk<<1, rep>>1);
matthiasm@8 31 #endif
matthiasm@8 32 }
matthiasm@8 33
matthiasm@8 34 void repmat(char *dest, const char *src, int ndim, int *destdimsize,
matthiasm@8 35 int *dimsize, const int *dims, int *rep)
matthiasm@8 36 {
matthiasm@8 37 int d = ndim-1;
matthiasm@8 38 int i, chunk;
matthiasm@8 39 /* copy the first repetition into dest */
matthiasm@8 40 if(d == 0) {
matthiasm@8 41 chunk = dimsize[0];
matthiasm@8 42 memcpy(dest,src,chunk);
matthiasm@8 43 }
matthiasm@8 44 else {
matthiasm@8 45 /* recursively repeat each slice of src */
matthiasm@8 46 for(i=0;i<dims[d];i++) {
matthiasm@8 47 repmat(dest + i*destdimsize[d-1], src + i*dimsize[d-1],
matthiasm@8 48 ndim-1, destdimsize, dimsize, dims, rep);
matthiasm@8 49 }
matthiasm@8 50 chunk = destdimsize[d-1]*dims[d];
matthiasm@8 51 }
matthiasm@8 52 /* copy the result rep-1 times */
matthiasm@8 53 memrep(dest,chunk,rep[d]);
matthiasm@8 54 }
matthiasm@8 55
matthiasm@8 56 void mexFunction(int nlhs, mxArray *plhs[],
matthiasm@8 57 int nrhs, const mxArray *prhs[])
matthiasm@8 58 {
matthiasm@8 59 const mxArray *srcmat;
matthiasm@8 60 int ndim, *dimsize, eltsize;
matthiasm@8 61 const int *dims;
matthiasm@8 62 int ndimdest, *destdims, *destdimsize;
matthiasm@8 63 char *src, *dest;
matthiasm@8 64 int *rep;
matthiasm@8 65 int i,nrep;
matthiasm@8 66 int extra_rep = 1;
matthiasm@8 67 int empty;
matthiasm@8 68
matthiasm@8 69 if(nrhs < 2) mexErrMsgTxt("Usage: xrepmat(A, [N M ...])");
matthiasm@8 70 srcmat = prhs[0];
matthiasm@8 71 if(mxIsSparse(srcmat)) {
matthiasm@8 72 mexErrMsgTxt("Sorry, can't handle sparse matrices yet.");
matthiasm@8 73 }
matthiasm@8 74 if(mxIsCell(srcmat)) {
matthiasm@8 75 mexErrMsgTxt("Sorry, can't handle cell arrays yet.");
matthiasm@8 76 }
matthiasm@8 77 ndim = mxGetNumberOfDimensions(srcmat);
matthiasm@8 78 dims = mxGetDimensions(srcmat);
matthiasm@8 79 eltsize = mxGetElementSize(srcmat);
matthiasm@8 80
matthiasm@8 81 /* compute dimension sizes */
matthiasm@8 82 dimsize = mxCalloc(ndim, sizeof(int));
matthiasm@8 83 dimsize[0] = eltsize*dims[0];
matthiasm@8 84 for(i=1;i<ndim;i++) dimsize[i] = dimsize[i-1]*dims[i];
matthiasm@8 85
matthiasm@8 86 /* determine repetition vector */
matthiasm@8 87 ndimdest = ndim;
matthiasm@8 88 if(nrhs == 2) {
matthiasm@8 89 nrep = mxGetN(prhs[1]);
matthiasm@8 90 if(nrep > ndimdest) ndimdest = nrep;
matthiasm@8 91 rep = mxCalloc(ndimdest, sizeof(int));
matthiasm@8 92 for(i=0;i<nrep;i++) {
matthiasm@8 93 double repv = mxGetPr(prhs[1])[i];
matthiasm@8 94 rep[i] = (int)repv;
matthiasm@8 95 }
matthiasm@8 96 if(nrep == 1) {
matthiasm@8 97 /* special behavior */
matthiasm@8 98 nrep = 2;
matthiasm@8 99 rep[1] = rep[0];
matthiasm@8 100 }
matthiasm@8 101 }
matthiasm@8 102 else {
matthiasm@8 103 nrep = nrhs-1;
matthiasm@8 104 if(nrep > ndimdest) ndimdest = nrep;
matthiasm@8 105 rep = mxCalloc(ndimdest, sizeof(int));
matthiasm@8 106 for(i=0;i<nrep;i++) {
matthiasm@8 107 rep[i] = (int)*mxGetPr(prhs[i+1]);
matthiasm@8 108 }
matthiasm@8 109 }
matthiasm@8 110 for(i=nrep;i<ndimdest;i++) rep[i] = 1;
matthiasm@8 111
matthiasm@8 112 /* compute output size */
matthiasm@8 113 destdims = mxCalloc(ndimdest, sizeof(int));
matthiasm@8 114 for(i=0;i<ndim;i++) destdims[i] = dims[i]*rep[i];
matthiasm@8 115 for(;i<ndimdest;i++) {
matthiasm@8 116 destdims[i] = rep[i];
matthiasm@8 117 extra_rep *= rep[i];
matthiasm@8 118 }
matthiasm@8 119 destdimsize = mxCalloc(ndim, sizeof(int));
matthiasm@8 120 destdimsize[0] = eltsize*destdims[0];
matthiasm@8 121 for(i=1;i<ndim;i++) destdimsize[i] = destdimsize[i-1]*destdims[i];
matthiasm@8 122
matthiasm@8 123
matthiasm@8 124 /* for speed, array should be uninitialized */
matthiasm@8 125 plhs[0] = mxCreateNumericArray(ndimdest, destdims, mxGetClassID(srcmat),
matthiasm@8 126 mxIsComplex(srcmat)?mxCOMPLEX:mxREAL);
matthiasm@8 127
matthiasm@8 128 /* if any rep[i] == 0, output should be empty array.
matthiasm@8 129 Added by KPM 11/13/02.
matthiasm@8 130 */
matthiasm@8 131 empty = 0;
matthiasm@8 132 for (i=0; i < nrep; i++) {
matthiasm@8 133 if (rep[i]==0)
matthiasm@8 134 empty = 1;
matthiasm@8 135 }
matthiasm@8 136 if (empty)
matthiasm@8 137 return;
matthiasm@8 138
matthiasm@8 139 src = (char*)mxGetData(srcmat);
matthiasm@8 140 dest = (char*)mxGetData(plhs[0]);
matthiasm@8 141 repmat(dest,src,ndim,destdimsize,dimsize,dims,rep);
matthiasm@8 142 if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep);
matthiasm@8 143 if(mxIsComplex(srcmat)) {
matthiasm@8 144 src = (char*)mxGetPi(srcmat);
matthiasm@8 145 dest = (char*)mxGetPi(plhs[0]);
matthiasm@8 146 repmat(dest,src,ndim,destdimsize,dimsize,dims,rep);
matthiasm@8 147 if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep);
matthiasm@8 148 }
matthiasm@8 149 }