annotate toolboxes/FullBNT-1.0.7/KPMtools/repmatC.c @ 0:cc4b1211e677 tip

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