Mercurial > hg > camir-aes2014
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 } |