Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00150 #include "vlad.h"
00151 #include "mathop.h"
00152 #include <stdio.h>
00153 #include <stdlib.h>
00154 #include <string.h>
00155
00156 #if defined(_OPENMP)
00157 #include <omp.h>
00158 #endif
00159
00160
00161 #ifdef VL_VLAD_INSTANTIATING
00162
00163 static void
00164 VL_XCAT(_vl_vlad_encode_, SFX)
00165 (TYPE * enc,
00166 TYPE const * means, vl_size dimension, vl_size numClusters,
00167 TYPE const * data, vl_size numData,
00168 TYPE const * assignments,
00169 int flags)
00170 {
00171 vl_uindex dim ;
00172 vl_index i_cl, i_d ;
00173
00174 memset(enc, 0, sizeof(TYPE) * dimension * numClusters) ;
00175
00176 #if defined(_OPENMP)
00177 #pragma omp parallel for default(shared) private(i_cl,i_d,dim) num_threads(vl_get_max_threads())
00178 #endif
00179 for (i_cl = 0; i_cl < (signed)numClusters; i_cl++) {
00180 double clusterMass = 0 ;
00181 for (i_d = 0; i_d < (signed)numData; i_d++) {
00182 if (assignments[i_d*numClusters + i_cl] > 0) {
00183 double q = assignments[i_d*numClusters+i_cl] ;
00184 clusterMass += q ;
00185 for(dim = 0; dim < dimension; dim++) {
00186 enc [i_cl * dimension + dim] += q * data [i_d * dimension + dim] ;
00187 }
00188 }
00189 }
00190
00191 if (clusterMass > 0) {
00192 if (flags & VL_VLAD_FLAG_NORMALIZE_MASS) {
00193 for(dim = 0; dim < dimension; dim++) {
00194 enc[i_cl*dimension + dim] /= clusterMass ;
00195 enc[i_cl*dimension + dim] -= means[i_cl*dimension+dim];
00196 }
00197 } else {
00198 for(dim = 0; dim < dimension; dim++) {
00199 enc[i_cl*dimension + dim] -= clusterMass * means[i_cl*dimension+dim];
00200 }
00201 }
00202 }
00203
00204 if (flags & VL_VLAD_FLAG_SQUARE_ROOT) {
00205 for(dim = 0; dim < dimension; dim++) {
00206 TYPE z = enc[i_cl*dimension + dim] ;
00207 if (z >= 0) {
00208 enc[i_cl*dimension + dim] = VL_XCAT(vl_sqrt_, SFX)(z) ;
00209 } else {
00210 enc[i_cl*dimension + dim] = - VL_XCAT(vl_sqrt_, SFX)(- z) ;
00211 }
00212 }
00213 }
00214
00215 if (flags & VL_VLAD_FLAG_NORMALIZE_COMPONENTS) {
00216 TYPE n = 0 ;
00217 dim = 0 ;
00218 for(dim = 0; dim < dimension; dim++) {
00219 TYPE z = enc[i_cl*dimension + dim] ;
00220 n += z * z ;
00221 }
00222 n = VL_XCAT(vl_sqrt_, SFX)(n) ;
00223 n = VL_MAX(n, 1e-12) ;
00224 for(dim = 0; dim < dimension; dim++) {
00225 enc[i_cl*dimension + dim] /= n ;
00226 }
00227 }
00228 }
00229
00230 if (! (flags & VL_VLAD_FLAG_UNNORMALIZED)) {
00231 TYPE n = 0 ;
00232 for(dim = 0 ; dim < dimension * numClusters ; dim++) {
00233 TYPE z = enc [dim] ;
00234 n += z * z ;
00235 }
00236 n = VL_XCAT(vl_sqrt_, SFX)(n) ;
00237 n = VL_MAX(n, 1e-12) ;
00238 for(dim = 0 ; dim < dimension * numClusters ; dim++) {
00239 enc[dim] /= n ;
00240 }
00241 }
00242 }
00243
00244
00245 #else
00246
00247 #ifndef __DOXYGEN__
00248 #define FLT VL_TYPE_FLOAT
00249 #define TYPE float
00250 #define SFX f
00251 #define VL_VLAD_INSTANTIATING
00252 #include "vlad.c"
00253
00254 #define FLT VL_TYPE_DOUBLE
00255 #define TYPE double
00256 #define SFX d
00257 #define VL_VLAD_INSTANTIATING
00258 #include "vlad.c"
00259 #endif
00260
00261
00262 #endif
00263
00264
00265 #ifndef VL_VLAD_INSTANTIATING
00266
00292 void
00293 vl_vlad_encode (void * enc, vl_type dataType,
00294 void const * means, vl_size dimension, vl_size numClusters,
00295 void const * data, vl_size numData,
00296 void const * assignments,
00297 int flags)
00298 {
00299 switch(dataType) {
00300 case VL_TYPE_FLOAT:
00301 _vl_vlad_encode_f ((float *) enc,
00302 (float const *) means, dimension, numClusters,
00303 (float const *) data, numData,
00304 (float const *) assignments, flags) ;
00305 break;
00306 case VL_TYPE_DOUBLE:
00307 _vl_vlad_encode_d ((double *) enc,
00308 (double const *) means, dimension, numClusters,
00309 (double const *) data, numData,
00310 (double const *) assignments, flags) ;
00311 break;
00312 default:
00313 abort();
00314 }
00315 }
00316
00317
00318 #endif
00319
00320 #undef SFX
00321 #undef TYPE
00322 #undef FLT
00323 #undef VL_VLAD_INSTANTIATING