comparison Problems/private/col2imstep.c @ 15:51b76c31c93d

(none)
author idamnjanovic
date Thu, 25 Mar 2010 14:05:27 +0000
parents
children
comparison
equal deleted inserted replaced
14:a0571bf2ff54 15:51b76c31c93d
1 /**************************************************************************
2 *
3 * File name: col2imstep.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
17
18 /* Input Arguments */
19
20 #define B_IN prhs[0]
21 #define N_IN prhs[1]
22 #define SZ_IN prhs[2]
23 #define S_IN prhs[3]
24
25
26 /* Output Arguments */
27
28 #define X_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, t, blocknum;
38
39
40 /* Check for proper number of arguments */
41
42 if (nrhs < 3 || nrhs > 4) {
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 if (!mxIsDouble(B_IN) || mxIsComplex(B_IN) || mxGetNumberOfDimensions(B_IN)>2) {
52 mexErrMsgTxt("B should be a double matrix.");
53 }
54 if (!mxIsDouble(N_IN) || mxIsComplex(N_IN) || mxGetNumberOfDimensions(N_IN)>2) {
55 mexErrMsgTxt("Invalid output matrix size.");
56 }
57 ndims = mxGetM(N_IN)*mxGetN(N_IN);
58 if (ndims<2 || ndims>3) {
59 mexErrMsgTxt("Output matrix can only be 2-D or 3-D.");
60 }
61 if (!mxIsDouble(SZ_IN) || mxIsComplex(SZ_IN) || mxGetNumberOfDimensions(SZ_IN)>2 || mxGetM(SZ_IN)*mxGetN(SZ_IN)!=ndims) {
62 mexErrMsgTxt("Invalid block size.");
63 }
64 if (nrhs == 4) {
65 if (!mxIsDouble(S_IN) || mxIsComplex(S_IN) || mxGetNumberOfDimensions(S_IN)>2 || mxGetM(S_IN)*mxGetN(S_IN)!=ndims) {
66 mexErrMsgTxt("Invalid step size.");
67 }
68 }
69
70
71 /* Get parameters */
72
73 s = mxGetPr(N_IN);
74 if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) {
75 mexErrMsgTxt("Invalid output matrix size.");
76 }
77 n[0] = (mwSize)(s[0] + 0.01);
78 n[1] = (mwSize)(s[1] + 0.01);
79 n[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1;
80
81 s = mxGetPr(SZ_IN);
82 if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) {
83 mexErrMsgTxt("Invalid block size.");
84 }
85 sz[0] = (mwSize)(s[0] + 0.01);
86 sz[1] = (mwSize)(s[1] + 0.01);
87 sz[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1;
88
89 if (nrhs == 4) {
90 s = mxGetPr(S_IN);
91 if (s[0]<1 || s[1]<1 || (ndims==3 && s[2]<1)) {
92 mexErrMsgTxt("Invalid step size.");
93 }
94 stepsize[0] = (mwSize)(s[0] + 0.01);
95 stepsize[1] = (mwSize)(s[1] + 0.01);
96 stepsize[2] = ndims==3 ? (mwSize)(s[2] + 0.01) : 1;
97 }
98 else {
99 stepsize[0] = stepsize[1] = stepsize[2] = 1;
100 }
101
102 if (n[0]<sz[0] || n[1]<sz[1] || (ndims==3 && n[2]<sz[2])) {
103 mexErrMsgTxt("Block size too large.");
104 }
105
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)) {
107 mexErrMsgTxt("Invalid number of columns in B. Please use IM2COLSTEP to compute B.");
108 }
109
110
111 /* Create a matrix for the return argument */
112
113 X_OUT = mxCreateNumericArray(ndims, n, mxDOUBLE_CLASS, mxREAL);
114
115
116 /* Assign pointers */
117
118 b = mxGetPr(B_IN);
119 x = mxGetPr(X_OUT);
120
121
122 /* Do the actual computation */
123
124 blocknum = 0;
125
126 /* iterate over all blocks */
127 for (k=0; k<=n[2]-sz[2]; k+=stepsize[2]) {
128 for (j=0; j<=n[1]-sz[1]; j+=stepsize[1]) {
129 for (i=0; i<=n[0]-sz[0]; i+=stepsize[0]) {
130
131 /* add single block */
132 for (m=0; m<sz[2]; m++) {
133 for (l=0; l<sz[1]; l++) {
134 for (t=0; t<sz[0]; t++) {
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];
136 }
137 }
138 }
139 blocknum++;
140
141 }
142 }
143 }
144
145 return;
146 }