Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include<mexutils.h>
00016
00017 #include<stdio.h>
00018 #include<stdlib.h>
00019 #include<math.h>
00020 #include<string.h>
00021 #include<assert.h>
00022
00023 #include <vl/generic.h>
00024
00025
00029 void
00030 mexFunction (int nout, mxArray * out[], int nin, const mxArray * in[])
00031 {
00032 enum {IN_PARENTS = 0, IN_DATA, IN_OPT} ;
00033 enum {OUT_TREE} ;
00034
00035 vl_uint32 const *parents ;
00036 vl_uint32 *tree ;
00037 double const *data ;
00038
00039 int nnull = 0 ;
00040 int histmode = 0 ;
00041
00042 vl_uint32 i, P, N ;
00043
00044
00045
00046
00047
00048 if ((nin < 2) || (nin > 3)) {
00049 mexErrMsgTxt ("Two or three arguments required.") ;
00050 }
00051
00052 if (nout > 1) {
00053 mexErrMsgTxt ("Too many output arguments.") ;
00054 }
00055
00056 if (!vlmxIsMatrix(in[IN_DATA], -1, -1)) {
00057 mexErrMsgTxt ("DATA must be a matrix of DOUBLE");
00058 }
00059
00060 if (!vlmxIsVector(in[IN_PARENTS], -1)) {
00061 mexErrMsgTxt ("PARENTS must be a vector") ;
00062 }
00063
00064 if (mxGetClassID(in[IN_PARENTS]) != mxUINT32_CLASS) {
00065 mexErrMsgTxt ("PARENTS must be UINT32") ;
00066 }
00067
00068 N = mxGetNumberOfElements (in[IN_DATA]) ;
00069 data = mxGetPr (in[IN_DATA]) ;
00070
00071 P = mxGetNumberOfElements (in[IN_PARENTS]) ;
00072 parents = mxGetData (in[IN_PARENTS]) ;
00073
00074 if (nin > 2) {
00075 enum {buflen = 32} ;
00076 char buf [buflen] ;
00077 if (!vlmxIsString(in[IN_OPT], -1)) {
00078 mexErrMsgTxt("OPT must be a string") ;
00079 }
00080 mxGetString(in[IN_OPT], buf, buflen) ;
00081 buf [buflen - 1] = 0 ;
00082 if (!vlmxCompareStringsI("hist", buf)) {
00083 mexErrMsgTxt("OPT must be equal to 'hist'") ;
00084 }
00085 histmode = 1 ;
00086 }
00087
00088 out[OUT_TREE] = mxCreateNumericMatrix(1, P,mxUINT32_CLASS, mxREAL) ;
00089 tree = mxGetData (out[OUT_TREE]) ;
00090
00091
00092
00093
00094
00095 {
00096 char buf [1024] ;
00097 vl_uint32 max_node = 0 ;
00098 vl_uint32 min_node = 0 ;
00099 vl_uint32 last_leaf = 0 ;
00100
00101
00102
00103 for (i = 0 ; i < P ; ++i) {
00104 vl_uint32 node = parents [i] ;
00105
00106 if ((node != 0) & (node != 1)) {
00107 max_node = VL_MAX (node, max_node) ;
00108 min_node = VL_MIN (node, min_node) ;
00109 }
00110
00111
00112 if (node > P) {
00113 snprintf(buf, sizeof(buf),
00114 "Out of bounds link PARENTS[%d] = %u > %u", i, node, P) ;
00115 mexErrMsgTxt (buf) ;
00116 }
00117
00118
00119 if ((node != 0) & (node != 1) & (node < i)) {
00120 snprintf(buf, sizeof(buf),
00121 "Backward link PARENTS[%d] = %u < %d", i, node, i) ;
00122 mexErrMsgTxt (buf) ;
00123 }
00124 if (node == 0) ++ nnull ;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134 last_leaf = min_node - 1 ;
00135
00136
00137
00138 for (i = 0 ; i < N ; ++i) {
00139
00140 vl_uint32 x = data [i] ;
00141
00142 if (histmode) {
00143
00144 x = i ;
00145 }
00146
00147 if ((x < 1) | (x > last_leaf)) {
00148 if (histmode) {
00149 snprintf(buf, sizeof(buf),
00150 "DATA length exceeds number of AIB leaves") ;
00151 } else {
00152 snprintf(buf, sizeof(buf),
00153 "DATA [%u] = %u is not a leaf", i, x) ;
00154 }
00155 mexErrMsgTxt (buf) ;
00156 }
00157
00158 while (VL_TRUE) {
00159 vl_uint32 x_ = parents [x -1] ;
00160
00161 ++ tree [x - 1] ;
00162 if ((x_ == x) | (x_ == 0) | (x_ == 1)) break ;
00163 x = x_ ;
00164 }
00165 }
00166 }
00167 }