comparison util/ksvd utils/im2colstep.c @ 70:c3eca463202d

(none)
author idamnjanovic
date Wed, 16 Mar 2011 14:16:57 +0000
parents
children
comparison
equal deleted inserted replaced
69:5f1f436057ca 70:c3eca463202d
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 }