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