Go to the documentation of this file.00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <mexutils.h>
00015
00016 #include <stdlib.h>
00017
00020 #define greater(a,b) ((a) > (b)+threshold)
00021
00022 void
00023 mexFunction(int nout, mxArray *out[],
00024 int nin, const mxArray *in[])
00025 {
00026 int M, N ;
00027 const double* F_pt ;
00028 int ndims ;
00029 int pdims = -1 ;
00030 int* offsets ;
00031 int* midx ;
00032 int* neighbors ;
00033 int nneighbors ;
00034 int* dims ;
00035 enum {F=0,THRESHOLD,P} ;
00036 enum {MAXIMA=0} ;
00037 double threshold = - mxGetInf() ;
00038
00039
00040
00041
00042
00043 if (nin < 1) {
00044 mexErrMsgTxt("At least one input argument is required.");
00045 } else if (nin > 3) {
00046 mexErrMsgTxt("At most three arguments are allowed.") ;
00047 } else if (nout > 1) {
00048 mexErrMsgTxt("Too many output arguments");
00049 }
00050
00051
00052 if (!mxIsDouble(in[F]) || mxIsComplex(in[F])) {
00053 mexErrMsgTxt("Input must be real matrix.");
00054 }
00055
00056 if(nin > 1) {
00057 if(!vlmxIsPlainScalar(in[THRESHOLD])) {
00058 mexErrMsgTxt("THRESHOLD must be a real scalar.") ;
00059 }
00060 threshold = *mxGetPr(in[THRESHOLD]) ;
00061 }
00062
00063 if(nin > 2) {
00064 if(!vlmxIsPlainScalar(in[P]))
00065 mexErrMsgTxt("P must be a non-negative integer") ;
00066 pdims = (int) *mxGetPr(in[P]) ;
00067 if(pdims < 0)
00068 mexErrMsgTxt("P must be a non-negative integer") ;
00069 }
00070
00071 ndims = mxGetNumberOfDimensions(in[F]) ;
00072 {
00073
00074
00075
00076 int d ;
00077 mwSize const * const_dims = mxGetDimensions(in[F]) ;
00078 dims = mxMalloc(sizeof(int)*ndims) ;
00079 for(d=0 ; d < ndims ; ++d) dims[d] = const_dims[d] ;
00080 }
00081 M = dims[0] ;
00082 N = dims[1] ;
00083 F_pt = mxGetPr(in[F]) ;
00084
00085
00086
00087
00088
00089
00090
00091
00092 if((ndims == 2) && (pdims < 0) && (M == 1 || N == 1)) {
00093 pdims = 1 ;
00094 M = (M>N)?M:N ;
00095 N = 1 ;
00096 dims[0]=M ;
00097 dims[1]=N ;
00098 }
00099
00100
00101 if(pdims < 0)
00102 pdims = ndims ;
00103
00104 if(pdims > ndims) {
00105 mxFree(dims) ;
00106 mexErrMsgTxt("P must not be greater than the number of dimensions") ;
00107 }
00108
00109
00110
00111
00112 {
00113 int maxima_size = M*N ;
00114 int* maxima_start = mxMalloc(sizeof(int) * maxima_size) ;
00115 int* maxima_iterator = maxima_start ;
00116 int* maxima_end = maxima_start + maxima_size ;
00117 int i,h,o ;
00118 const double* pt = F_pt ;
00119
00120
00121 offsets = mxMalloc(sizeof(int) * ndims) ;
00122 offsets[0] = 1 ;
00123 for(h = 1 ; h < ndims ; ++h)
00124 offsets[h] = offsets[h-1]*dims[h-1] ;
00125
00126
00127 midx = mxMalloc(sizeof(int) * ndims) ;
00128 for(h = 0 ; h < ndims ; ++h)
00129 midx[h] = 1 ;
00130
00131
00132 nneighbors = 1 ;
00133 o=0 ;
00134 for(h = 0 ; h < pdims ; ++h) {
00135 nneighbors *= 3 ;
00136 midx[h] = -1 ;
00137 o -= offsets[h] ;
00138 }
00139 nneighbors -= 1 ;
00140 neighbors = mxMalloc(sizeof(int) * nneighbors) ;
00141 i = 0 ;
00142
00143 while(VL_TRUE) {
00144 if(o != 0 )
00145 neighbors[i++] = o ;
00146 h = 0 ;
00147 while( o += offsets[h], (++midx[h]) > 1 ) {
00148 o -= 3*offsets[h] ;
00149 midx[h] = -1 ;
00150 if(++h >= pdims)
00151 goto stop ;
00152 }
00153 }
00154 stop: ;
00155
00156
00157 for(h = 0 ; h < pdims ; ++h) {
00158 midx[h] = 1 ;
00159 pt += offsets[h] ;
00160 }
00161 for(h = pdims ; h < ndims ; ++h) {
00162 midx[h] = 0 ;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 for(h=0 ; h < pdims ; ++h)
00175 if(dims[h] < 3) goto end ;
00176
00177 while(VL_TRUE) {
00178 double v ;
00179 bool is_greater;
00180
00181
00182 h = 0 ;
00183 while((midx[h]) >= dims[h] - 1) {
00184 pt += 2*offsets[h] ;
00185 midx[h] = 1 ;
00186 if(++h >= pdims)
00187 goto next_layer ;
00188 ++midx[h] ;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 v = *pt ;
00199 is_greater = (v >= threshold) ;
00200 i = 0 ;
00201 while(is_greater && i < nneighbors)
00202 is_greater &= v > *(pt + neighbors[i++]) ;
00203
00204
00205 if(is_greater) {
00206
00207 if(maxima_iterator == maxima_end) {
00208 maxima_size += M*N ;
00209 maxima_start = mxRealloc(maxima_start,
00210 maxima_size*sizeof(int)) ;
00211 maxima_end = maxima_start + maxima_size ;
00212 maxima_iterator = maxima_end - M*N ;
00213 }
00214
00215 *maxima_iterator++ = pt - F_pt + 1 ;
00216 }
00217
00218
00219 pt += 1 ;
00220 ++midx[0] ;
00221 continue ;
00222
00223 next_layer: ;
00224 if( h >= ndims )
00225 goto end ;
00226
00227 while((++midx[h]) >= dims[h]) {
00228 midx[h] = 0 ;
00229 if(++h >= ndims)
00230 goto end ;
00231 }
00232 }
00233 end:;
00234
00235 {
00236 double* M_pt ;
00237 out[MAXIMA] = mxCreateDoubleMatrix
00238 (1, maxima_iterator-maxima_start, mxREAL) ;
00239 maxima_end = maxima_iterator ;
00240 maxima_iterator = maxima_start ;
00241 M_pt = mxGetPr(out[MAXIMA]) ;
00242 while(maxima_iterator != maxima_end) {
00243 *M_pt++ = *maxima_iterator++ ;
00244 }
00245 }
00246
00247
00248 mxFree(offsets) ;
00249 mxFree(neighbors) ;
00250 mxFree(midx) ;
00251 mxFree(maxima_start) ;
00252 }
00253 mxFree(dims) ;
00254 }