|
a |
|
b/util/im2colstep.c |
|
|
1 |
/************************************************************************** |
|
|
2 |
* |
|
|
3 |
* File name: im2colstep.c |
|
|
4 |
* |
|
|
5 |
* Ron Rubinstein |
|
|
6 |
* Computer Science Department |
|
|
7 |
* Technion, Haifa 32000 Israel |
|
|
8 |
* ronrubin@cs |
|
|
9 |
* |
|
|
10 |
* Last Updated: 31.8.2009 |
|
|
11 |
* |
|
|
12 |
*************************************************************************/ |
|
|
13 |
|
|
|
14 |
|
|
|
15 |
#include "mex.h" |
|
|
16 |
#include <string.h> |
|
|
17 |
|
|
|
18 |
|
|
|
19 |
/* Input Arguments */ |
|
|
20 |
|
|
|
21 |
#define X_IN prhs[0] |
|
|
22 |
#define SZ_IN prhs[1] |
|
|
23 |
#define S_IN prhs[2] |
|
|
24 |
|
|
|
25 |
|
|
|
26 |
/* Output Arguments */ |
|
|
27 |
|
|
|
28 |
#define B_OUT plhs[0] |
|
|
29 |
|
|
|
30 |
|
|
|
31 |
void mexFunction(int nlhs, mxArray *plhs[], |
|
|
32 |
int nrhs, const mxArray*prhs[]) |
|
|
33 |
|
|
|
34 |
{ |
|
|
35 |
double *x, *b, *s; |
|
|
36 |
mwSize sz[3], stepsize[3], n[3], ndims; |
|
|
37 |
mwIndex i, j, k, l, m, blocknum; |
|
|
38 |
|
|
|
39 |
|
|
|
40 |
/* Check for proper number of arguments */ |
|
|
41 |
|
|
|
42 |
if (nrhs < 2 || nrhs > 3) { |
|
|
43 |
mexErrMsgTxt("Invalid number of input arguments."); |
|
|
44 |
} else if (nlhs > 1) { |
|
|
45 |
mexErrMsgTxt("Too many output arguments."); |
|
|
46 |
} |
|
|
47 |
|
|
|
48 |
|
|
|
49 |
/* Check the the input dimensions */ |
|
|
50 |
|
|
|
51 |
ndims = mxGetNumberOfDimensions(X_IN); |
|
|
52 |
|
|
|
53 |
if (!mxIsDouble(X_IN) || mxIsComplex(X_IN) || ndims>3) { |
|
|
54 |
mexErrMsgTxt("X should be a 2-D or 3-D double matrix."); |
|
|
55 |
} |
|
|
56 |
if (!mxIsDouble(SZ_IN) || mxIsComplex(SZ_IN) || mxGetNumberOfDimensions(SZ_IN)>2 || mxGetM(SZ_IN)*mxGetN(SZ_IN)!=ndims) { |
|
|
57 |
mexErrMsgTxt("Invalid block size."); |
|
|
58 |
} |
|
|
59 |
if (nrhs == 3) { |
|
|
60 |
if (!mxIsDouble(S_IN) || mxIsComplex(S_IN) || mxGetNumberOfDimensions(S_IN)>2 || mxGetM(S_IN)*mxGetN(S_IN)!=ndims) { |
|
|
61 |
mexErrMsgTxt("Invalid step size."); |
|
|
62 |
} |
|
|
63 |
} |
|
|
64 |
|
|
|
65 |
|
|
|
66 |
/* Get parameters */ |
|
|
67 |
|
|
|
68 |
s = mxGetPr(SZ_IN); |
|
|
69 |
if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { |
|
|
70 |
mexErrMsgTxt("Invalid block size."); |
|
|
71 |
} |
|
|
72 |
sz[0] = (mwSize)(s[0] + 0.01); |
|
|
73 |
sz[1] = (mwSize)(s[1] + 0.01); |
|
|
74 |
sz[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; |
|
|
75 |
|
|
|
76 |
if (nrhs == 3) { |
|
|
77 |
s = mxGetPr(S_IN); |
|
|
78 |
if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) { |
|
|
79 |
mexErrMsgTxt("Invalid step size."); |
|
|
80 |
} |
|
|
81 |
stepsize[0] = (mwSize)(s[0] + 0.01); |
|
|
82 |
stepsize[1] = (mwSize)(s[1] + 0.01); |
|
|
83 |
stepsize[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1; |
|
|
84 |
} |
|
|
85 |
else { |
|
|
86 |
stepsize[0] = stepsize[1] = stepsize[2] = 1; |
|
|
87 |
} |
|
|
88 |
|
|
|
89 |
n[0] = (mxGetDimensions(X_IN))[0]; |
|
|
90 |
n[1] = (mxGetDimensions(X_IN))[1]; |
|
|
91 |
n[2] = ndims==3 ? (mxGetDimensions(X_IN))[2] : 1; |
|
|
92 |
|
|
|
93 |
if (n[0]<sz[0] || n[1]<sz[1] || (ndims==3 && n[2]<sz[2])) { |
|
|
94 |
mexErrMsgTxt("Block size too large."); |
|
|
95 |
} |
|
|
96 |
|
|
|
97 |
|
|
|
98 |
/* Create a matrix for the return argument */ |
|
|
99 |
|
|
|
100 |
B_OUT = mxCreateDoubleMatrix(sz[0]*sz[1]*sz[2], ((n[0]-sz[0])/stepsize[0]+1)*((n[1]-sz[1])/stepsize[1]+1)*((n[2]-sz[2])/stepsize[2]+1), mxREAL); |
|
|
101 |
|
|
|
102 |
|
|
|
103 |
/* Assign pointers */ |
|
|
104 |
|
|
|
105 |
x = mxGetPr(X_IN); |
|
|
106 |
b = mxGetPr(B_OUT); |
|
|
107 |
|
|
|
108 |
|
|
|
109 |
/* Do the actual computation */ |
|
|
110 |
|
|
|
111 |
blocknum = 0; |
|
|
112 |
|
|
|
113 |
/* iterate over all blocks */ |
|
|
114 |
for (k=0; k<=n[2]-sz[2]; k+=stepsize[2]) { |
|
|
115 |
for (j=0; j<=n[1]-sz[1]; j+=stepsize[1]) { |
|
|
116 |
for (i=0; i<=n[0]-sz[0]; i+=stepsize[0]) { |
|
|
117 |
|
|
|
118 |
/* copy single block */ |
|
|
119 |
for (m=0; m<sz[2]; m++) { |
|
|
120 |
for (l=0; l<sz[1]; l++) { |
|
|
121 |
memcpy(b + blocknum*sz[0]*sz[1]*sz[2] + m*sz[0]*sz[1] + l*sz[0], x+(k+m)*n[0]*n[1]+(j+l)*n[0]+i, sz[0]*sizeof(double)); |
|
|
122 |
} |
|
|
123 |
} |
|
|
124 |
blocknum++; |
|
|
125 |
|
|
|
126 |
} |
|
|
127 |
} |
|
|
128 |
} |
|
|
129 |
|
|
|
130 |
return; |
|
|
131 |
} |