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