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