source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/vlutil/toolbox/binsum.mex.c

Last change on this file was 37, checked in by (none), 14 years ago

Added original make3d

File size: 5.0 KB
Line 
1/** file:        binsum.mex.c
2 ** author:      Andrea Vedaldi
3 ** description: MEX implementation of binsum.m
4 **/
5
6/* AUTORIGHTS
7Copyright (C) 2006 Andrea Vedaldi
8     
9This file is part of VLUtil.
10
11VLUtil is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2, or (at your option)
14any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software Foundation,
23Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24*/
25
26#include"mexutils.c"
27
28/** @brief Driver.
29 **
30 ** @param nount number of output arguments.
31 ** @param out output arguments.
32 ** @param nin number of input arguments.
33 ** @param in input arguments.
34 **/
35void 
36mexFunction(int nout, mxArray *out[], 
37            int nin, const mxArray *in[])
38{
39  enum { IN_H, IN_X, IN_B, IN_DIM } ;
40  int KH, KX, KB, j ;
41  const double *H_pt, *X_pt, *B_pt ;
42  const double *X_end ;
43  double *R_pt ;
44 
45  if( nin < 3 ) {
46    mexErrMsgTxt("At least three arguments required") ;
47  } else if( nin > 4 ) {
48    mexErrMsgTxt("At most four arguments") ;
49  } else if (nout > 1) {
50    mexErrMsgTxt("At most one output argument") ;
51  }
52 
53  if(! uIsReal(in[IN_H]) ||
54     ! uIsReal(in[IN_X]) ||
55     ! uIsReal(in[IN_B]) )
56    mexErrMsgTxt("Illegal arguments") ;
57 
58  KH = mxGetNumberOfElements(in[IN_H]) ;
59  KX = mxGetNumberOfElements(in[IN_X]) ;
60  KB = mxGetNumberOfElements(in[IN_B]) ;
61
62  H_pt = mxGetPr(in[IN_H]) ;
63  X_pt = mxGetPr(in[IN_X]) ;
64  B_pt = mxGetPr(in[IN_B]) ;
65
66  X_end = X_pt + KX ;
67 
68  out[0] = mxDuplicateArray(in[IN_H]) ;
69  R_pt   = mxGetPr(out[0]) ;
70 
71  if( KX != KB ) {
72    mexErrMsgTxt("X and B must have the same number of elements") ;
73  }
74 
75  /* All dimensions mode ------------------------------------------- */
76  if( nin == 3 ) {
77
78    while( X_pt < X_end ) { 
79      j = (int)(*B_pt++) - 1;
80      if(j < 0 || j >= KH)
81        mexErrMsgTxt("Index out ouf bounds") ;
82      R_pt[j] += *X_pt++ ;
83    }
84  }
85
86  /* One dimension mode -------------------------------------------- */
87  else { 
88    int k ;   
89    unsigned int d  = (unsigned int)*mxGetPr(in[IN_DIM]) - 1 ;
90   
91    unsigned int HD = mxGetNumberOfDimensions(in[IN_H]) ;
92    unsigned int XD = mxGetNumberOfDimensions(in[IN_X]) ;
93    unsigned int BD = mxGetNumberOfDimensions(in[IN_B]) ;
94
95    int const* Hdims = mxGetDimensions(in[IN_H]) ;
96    int const* Xdims = mxGetDimensions(in[IN_X]) ;
97    int const* Bdims = mxGetDimensions(in[IN_B]) ;
98
99    const double* X_brk ;
100    const double* X_nbrk ;
101
102    unsigned int srd ;
103
104    /* We need to check a few more details about the matrices */
105    if( d >= HD ) {
106      mexErrMsgTxt("DIM out of bound") ;
107    }
108
109    /* Here either B,X have the same number of dimensions of H, or B,X
110       have exactly one dimension less and DIM=end.  The latter is a
111       special case due to the fact that MATLAB deletes singleton
112       dimensions at the ends of array, so it would be impossible to
113       operate with DIM=end and size(B,end)=1, which is a logically
114       acceptable case. */
115       
116    if( HD != XD || HD != BD ) {
117      if( !( d == HD-1 && XD == BD && XD == HD-1) ) { 
118        mexErrMsgTxt("H, X and B must have the same number of dimensions") ;
119      }
120    }
121   
122    /* This will contain the stride required to go from one element of
123     * the histogram to the next. This crossess all dimensions < d. */
124
125    srd = 1 ;
126
127    for(k = 0 ; k < XD ; ++k) {
128      if( Xdims[k] != Bdims[k] ) {
129        mexErrMsgTxt("X and B have incompatible dimensions") ;
130      }
131      if( k != d && (Xdims[k] != Hdims[k]) ) {
132        mexErrMsgTxt("H, X and B have incompatible dimensions") ;
133      }
134      if( k < d ) {
135        srd = srd * Xdims[k] ;
136      }
137    }
138
139    /* We scan all data points in X. We partition the dimensions in
140     * (a) the ones < d and (b) the ones > d. We detect the times in
141     * which X_pt crossess (a) or (b) by the dynamic bounds X_brk and
142     * X_nbrk respectively.
143     *
144     * For case (a) we need to re-position R_pt back to the
145     * beginning. For case (b) we need also to move R_pt to the next
146     * slice. */
147
148    KH     = Hdims[d] ;
149    X_brk  = X_pt + srd ;
150    X_nbrk = X_pt + srd * Xdims[d] ; 
151
152    while( X_pt < X_end ) {
153     
154      j = (int)(*B_pt) - 1;
155      if(j < 0 || j >= KH) {
156        char str [256] ;
157        snprintf(str, 256, 
158                 "Index out of bounds "
159                 "(B(%d)=%d)",
160                 B_pt-mxGetPr(in[IN_B]),j) ;
161        mexErrMsgTxt(str) ;
162      }
163      R_pt[j * srd] += *X_pt ;
164
165      /* next element */
166      X_pt++ ;
167      B_pt++ ;
168      R_pt++ ;
169     
170      if( X_pt == X_brk ) {
171        X_brk += srd ;
172        R_pt  -= srd ;
173        if( X_pt == X_nbrk ) {
174          X_nbrk += srd * Xdims[d] ;
175          R_pt   += srd * Hdims[d] ;
176        }
177      }
178    }
179  }
180}
Note: See TracBrowser for help on using the repository browser.