<NME> svmdataset.h
<BEF> /** @file svmdataset.h
 ** @brief SVM Dataset
 ** @author Daniele Perrone
 ** @author Andrea Vedaldi
 **/

/*
Copyright (C) 2012 Daniele Perrone.
Copyright (C) 2013 Andrea Vedaldi.
All rights reserved.

This file is part of the VLFeat library and is made available under
the terms of the BSD license (see the COPYING file).
*/

#ifndef VL_SVMDATASET_H
#define VL_SVMDATASET_H

#include "generic.h"
#include "homkermap.h"

struct VlSvm_ ;

/** @typedef VlSvmDataset
 ** @brief SVM dataset object
 **
 ** This objects contain a training set to be used in combination with
 ** the SVM solver object ::VlSvm. Its main purpose is to implement
 ** the two basic operations inner product (::VlSvmInnerProductFunction)
 ** and accumulation (::VlSvmAccumulateFunction).
 **
 ** See @ref svm and @ref svm-advanced for further information.
 **/

#ifndef __DOXYGEN__
struct VlSvmDataset_ ;
typedef struct VlSvmDataset_ VlSvmDataset ;
#else
typedef OPAQUE VlSvmDataset ;
#endif

/** @name SVM callbacks
 ** @{ */
typedef void (*VlSvmDiagnosticFunction) (struct VlSvm_ *svm, void *data) ;
typedef double (*VlSvmLossFunction) (double inner, double label) ;
typedef double (*VlSvmDcaUpdateFunction) (double alpha, double inner, double norm2, double label) ;
typedef double (*VlSvmInnerProductFunction)(const void *data, vl_uindex element, double *model) ;
typedef void (*VlSvmAccumulateFunction) (const void *data, vl_uindex element, double *model, double multiplier) ;


VL_EXPORT
VlSvmDataset* vl_svmdataset_new (void * data, vl_size dimension) ; 

VL_EXPORT
void vl_svmdataset_set_map (VlSvmDataset * data, void * map,VlSvmFeatureMap mapFunc, vl_size order) ;
VL_EXPORT void vl_svmdataset_delete (VlSvmDataset * dataset) ;
/** @} */

/** @name Set parameters
 ** @{
 **/
VL_EXPORT void vl_svmdataset_set_homogeneous_kernel_map (VlSvmDataset * self,
                                                         VlHomogeneousKernelMap * hom) ;
/** @} */

/** @name Get data and parameters
 ** @{
 **/
VL_EXPORT void* vl_svmdataset_get_data (VlSvmDataset const *self) ;
VL_EXPORT vl_size vl_svmdataset_get_num_data (VlSvmDataset const *self) ;
VL_EXPORT vl_size vl_svmdataset_get_dimension (VlSvmDataset const *self) ;
VL_EXPORT void* vl_svmdataset_get_map (VlSvmDataset const *self) ;
VL_EXPORT vl_size vl_svmdataset_get_mapDim (VlSvmDataset const *self) ;
VL_EXPORT VlSvmAccumulateFunction vl_svmdataset_get_accumulate_function (VlSvmDataset const *self) ;
VL_EXPORT VlSvmInnerProductFunction vl_svmdataset_get_inner_product_function (VlSvmDataset const * self) ;
VL_EXPORT VlHomogeneousKernelMap * vl_svmdataset_get_homogeneous_kernel_map (VlSvmDataset const * self) ;
/** @} */

/* VL_SVMDATASET_H */
#endif



<MSG> design fixes

<DFF> @@ -49,7 +49,7 @@ typedef struct _VlSvmDataset {
 
 
 VL_EXPORT
-VlSvmDataset* vl_svmdataset_new (void * data, vl_size dimension) ; 
+VlSvmDataset* vl_svmdataset_new (void * data, vl_size dimension) ;
 
 VL_EXPORT
 void vl_svmdataset_set_map (VlSvmDataset * data, void * map,VlSvmFeatureMap mapFunc, vl_size order) ;

{'commit': 'diff --git a/toolbox/misc/vl_pegasos.c b/toolbox/misc/vl_pegasos.c\nindex 6f3de36..9da66b1 100644\n--- a/toolbox/misc/vl_pegasos.c\n+++ b/toolbox/misc/vl_pegasos.c\n@@ -26,152 +26,151 @@ the terms of the BSD license (see the COPYING file).\n \n #include "kdtree.h"\n \n-/* Diagnostics */\n-enum {model=0,\n-      dimension,\n-      iterationsSoFar,\n+/* Info */\n+enum {dimension,\n+      iterations,\n       maxIterations,\n-      regularizer,\n+      epsilon,\n+      lambda,\n       biasMultiplier,\n-      preConditioner,\n+      biasLearningRate,\n+      energyFrequency,\n       elapsedTime,\n       energy,\n       regularizerTerm,\n-      lossPoss,\n+      lossPos,\n       lossNeg,\n       hardLossPos,\n       hardLossNeg};\n \n-void setValue(mxArray* array, double value)\n+static\n+void setDoubleValue(mxArray* array, double value)\n {\n   double* temp = (double*) mxGetData(array) ;\n   *temp = value ;\n }\n \n-mxArray * createOutputStruct(VlSvm* svm)\n+static\n+void setUintValue(mxArray* array, double value)\n {\n-  mwSize dims[] = {1 , 1} ;\n-\n-  const char* names [8] = {"model","dimension","iterationsSoFar","maxIterations","regularizer","biasMultiplier","preConditioner","elapsedTime"} ;\n-  mxArray* output = mxCreateStructArray(1, dims,\n-\t\t\t\t       8, names);\n-\n-  vl_size extDimension = svm->dimension + (svm->biasMultiplier != 0) ;\n-\n-  mxArray * model = mxCreateNumericMatrix(extDimension, 1,mxDOUBLE_CLASS, mxREAL) ;\n-\n-  memcpy(mxGetData(model),svm->model,extDimension*sizeof(double)) ;\n+  vl_uint32 * temp = (vl_uint32*) mxGetData(array) ;\n+  *temp = value ;\n+}\n \n-  mxArray * dimension = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n-  setValue(dimension,svm->dimension) ;\n \n+static\n+mxArray * createInfoStruct(VlSvmPegasos* svm)\n+{\n+  mwSize dims[] = {1 , 1} ;\n \n-  mxArray * iterationsSoFar = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+  const char* names [15] = {"dimension", "iterations", "maxIterations",\n+                           "epsilon", "lambda", "biasMultiplier",\n+                           "biasLearningRate", "energyFrequency", "elapsedTime",\n+                           "energy", "regularizerTerm", "lossPos",\n+                           "lossNeg", "hardLossPos", "hardLossNeg"} ;\n \n-  setValue(iterationsSoFar,svm->iterationsSoFar) ;\n+  mxArray* output = mxCreateStructArray(1, dims, 15, names);\n \n+  mxArray * dimension = mxCreateNumericMatrix(1, 1,mxUINT32_CLASS, mxREAL) ;\n+  setUintValue(dimension,svm->dimension) ;\n \n-  mxArray * maxIterations = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+  mxArray * iterations = mxCreateNumericMatrix(1, 1,mxUINT32_CLASS, mxREAL) ;\n+  setUintValue(iterations,svm->iterations) ;\n \n-  setValue(maxIterations,svm->maxIterations) ;\n+  mxArray * maxIterations = mxCreateNumericMatrix(1, 1,mxUINT32_CLASS, mxREAL) ;\n+  setUintValue(maxIterations,svm->maxIterations) ;\n \n-  mxArray * regularizer = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+  mxArray * epsilon = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+  setDoubleValue(epsilon,svm->epsilon) ;\n \n-  setValue(regularizer,svm->regularizer) ;\n+  mxArray * lambda = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+  setDoubleValue(lambda,svm->lambda) ;\n \n   mxArray * biasMultiplier = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+  setDoubleValue(biasMultiplier,svm->biasMultiplier) ;\n \n-  setValue(maxIterations,svm->maxIterations) ;\n+  mxArray * biasLearningRate = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+  setDoubleValue(biasLearningRate,svm->biasLearningRate) ;\n \n-  mxArray * preConditioner = mxCreateNumericMatrix(extDimension, 1,mxDOUBLE_CLASS, mxREAL) ;\n-  if (svm->preConditioner)\n-    memcpy(mxGetData(preConditioner),svm->preConditioner,extDimension*sizeof(double)) ;\n+  mxArray * energyFrequency = mxCreateNumericMatrix(1, 1,mxUINT32_CLASS, mxREAL) ;\n+  setUintValue(energyFrequency,svm->energyFrequency) ;\n \n   mxArray * elapsedTime = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+  setDoubleValue(elapsedTime,svm->elapsedTime) ;\n \n-  setValue(elapsedTime,svm->elapsedTime) ;\n \n-  mxSetField(output, 0, "model", model) ;\n   mxSetField(output, 0, "dimension", dimension) ;\n-  mxSetField(output, 0, "iterationsSoFar", iterationsSoFar) ;\n+  mxSetField(output, 0, "iterationsSoFar", iteration) ;\n   mxSetField(output, 0, "maxIterations", maxIterations) ;\n-  mxSetField(output, 0, "regularizer", regularizer) ;\n+  mxSetField(output, 0, "epsilon", maxIterations) ;\n+  mxSetField(output, 0, "lambda", lambda) ;\n   mxSetField(output, 0, "biasMultiplier", biasMultiplier) ;\n-  mxSetField(output, 0, "preConditioner", preConditioner) ;\n+  mxSetField(output, 0, "biasLearningRate", biasLearningRate) ;\n+  mxSetField(output, 0, "energyFrequency", energyFrequency) ;\n   mxSetField(output, 0, "elapsedTime", elapsedTime) ;\n \n-  return output ;\n-}\n-\n-mxArray * createDiagnosticsStruct(VlSvm* svm, VlSvmStatus* status)\n-{\n-  mxArray * output = createOutputStruct(svm) ;\n-\n-  mxAddField (output,"energy") ;\n-  mxAddField (output,"regularizerTerm") ;\n-  mxAddField (output,"lossPos") ;\n-  mxAddField (output,"lossNeg") ;\n-  mxAddField (output,"hardLossPos") ;\n-  mxAddField (output,"hardLossNeg") ;\n-\n \n-  mxArray * energy = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n-\n-  setValue(energy,status->energy) ;\n-\n-  mxArray * regularizerTerm = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n-\n-  setValue(regularizerTerm,status->regularizer) ;\n+  if (svm->objective)\n+    {\n+      mxArray * energy = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      setDoubleValue(energy,svm->objective->energy) ;\n \n-  mxArray * lossPos = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      mxArray * regularizerTerm = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      setDoubleValue(regularizerTerm,svm->objective->regularizer) ;\n \n-  setValue(lossPos,status->lossPos) ;\n+      mxArray * lossPos = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      setDoubleValue(lossPos,svm->objective->lossPos) ;\n \n-  mxArray * lossNeg = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      mxArray * lossNeg = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      setDoubleValue(lossNeg,svm->objective->lossNeg) ;\n \n-  setValue(lossNeg,status->lossNeg) ;\n+      mxArray * hardLossPos = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      setDoubleValue(hardLossPos,svm->objective->hardLossPos) ;\n \n-  mxArray * hardLossPos = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      mxArray * hardLossNeg = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+      setDoubleValue(hardLossNeg,svm->objective->hardLossNeg) ;\n \n-  setValue(hardLossPos,status->hardLossPos) ;\n+      mxSetField(output, 0, "energy", energy) ;\n+      mxSetField(output, 0, "regularizerTerm", regularizerTerm) ;\n+      mxSetField(output, 0, "lossPos", lossPos) ;\n+      mxSetField(output, 0, "lossNeg", lossNeg) ;\n+      mxSetField(output, 0, "hardLossPos", hardLossPos) ;\n+      mxSetField(output, 0, "hardLossNeg", hardLossNeg) ;\n \n-  mxArray * hardLossNeg = mxCreateNumericMatrix(1, 1,mxDOUBLE_CLASS, mxREAL) ;\n+    }\n \n-  setValue(hardLossNeg,status->hardLossNeg) ;\n+  return output ;\n+}\n \n \n-  mxSetField(output, 0, "energy", energy) ;\n-  mxSetField(output, 0, "regularizerTerm", regularizerTerm) ;\n-  mxSetField(output, 0, "lossPos", lossPos) ;\n-  mxSetField(output, 0, "lossNeg", lossNeg) ;\n-  mxSetField(output, 0, "hardLossPos", hardLossPos) ;\n-  mxSetField(output, 0, "hardLossNeg", hardLossNeg) ;\n \n-  return output ;\n-}\n \n+typedef struct _DiagnosticsDispatcher {\n+  mxArray* diagnosticsHandle ;\n+  mxArray * callerRef ;\n+  int verbose ;\n+} DiagnosticsDispatcher ;\n \n-mxArray* diagnosticsHandle = NULL ;\n-int            verbose = 0 ;\n \n-void diagnosticsDispatcher(VlSvm* svm, VlSvmStatus *status)\n+void diagnosticsDispatcher(DiagnosticsDispatcher * self, VlSvmPegasos* svm)\n {\n   if (diagnosticsHandle)\n     {\n-      mxArray *lhs,*rhs[2];\n+      mxArray *lhs,*rhs[3];\n \n-      rhs[0] = diagnosticsHandle ;\n-      rhs[1] =  createDiagnosticsStruct(svm,status) ;\n+      rhs[0] = self->diagnosticsHandle ;\n+      rhs[1] = self->callerRef ;\n+      rhs[2] =  createDiagnosticsStruct(svm) ;\n \n       if( mxIsClass( rhs[0] , "function_handle"))\n-\tmexCallMATLAB(0,&lhs,2,rhs,"feval");\n+\tmexCallMATLAB(0,&lhs,3,rhs,"feval");\n \n-      if (verbose)\n+      if (self->verbose)\n \t{\n \t  mexPrintf("vl_pegasos: Iteration = %d\\n",svm->iterationsSoFar) ;\n \t  mexPrintf("vl_pegasos: elapsed time = %f\\n",svm->elapsedTime) ;\n \n-\t  mexPrintf("vl_pegasos: energy = %f\\n",status->energy) ;\n+\t  mexPrintf("vl_pegasos: energy = %f\\n",svm->objective->energy) ;\n \t}\n     }\n \n@@ -183,29 +182,27 @@ void diagnosticsDispatcher(VlSvm* svm, VlSvmStatus *status)\n enum {\n   opt_verbose, opt_bias_multiplier, opt_num_iterations,\n   opt_starting_iteration, opt_starting_model, opt_permutation,\n-  opt_preconditioner, opt_diagnostics, opt_diagnostics_freq, opt_block_sparse, opt_homkermap, opt_KCHI2, opt_KL1, opt_KJS, opt_KINTERS, opt_gamma, opt_period, opt_window,opt_order\n+  opt_bias_learningrate, opt_diagnostics, opt_diagnostics_freq, opt_block_sparse, opt_homkermap, opt_KCHI2, opt_KL1, opt_KJS, opt_KINTERS, opt_gamma, opt_period, opt_window\n } ;\n \n /* options */\n vlmxOption  options [] = {\n   {"Verbose",           0,   opt_verbose             },\n-  {"BlockSparse",       0,   opt_block_sparse        },\n   {"BiasMultiplier",    1,   opt_bias_multiplier     },\n   {"NumIterations",     1,   opt_num_iterations      },\n   {"StartingIteration", 1,   opt_starting_iteration  },\n   {"StartingModel",     1,   opt_starting_model      },\n   {"Permutation",       1,   opt_permutation         },\n-  {"Preconditioner",    1,   opt_preconditioner      },\n+  {"BiasLearningRate",    1,   opt_bias_learningrate     },\n   {"DiagnosticsFunction",       1,   opt_diagnostics         },\n   {"DiagnosticsFreq",   1, opt_diagnostics_freq      },\n-  {"homkermap",         0,   opt_homkermap           },\n+  {"homkermap",         1,   opt_homkermap           },\n   {"kl1",               0,   opt_KL1                 },\n   {"kchi2",             0,   opt_KCHI2               },\n   {"kjs",               0,   opt_KJS                 },\n   {"kinters",           0,   opt_KINTERS             },\n   {"order",             1,   opt_order               },\n   {"gamma",             1,   opt_gamma               },\n-  {"period",            1,   opt_period              },\n   {"window",            1,   opt_window              },\n   {0,                   0,   0                       }\n } ;\n@@ -222,29 +219,19 @@ mexFunction(int nout, mxArray *out[],\n   enum {OUT_MODEL = 0} ;\n \n \n+  int            verbose = 0 ;\n   int            opt ;\n   int            next = IN_END ;\n   mxArray const *optarg ;\n \n   mxArray *inputModel = NULL;\n \n-  VlSvm* svm ;\n+  VlSvmPegasos* svm ;\n \n-  vl_size preconditionerDimension = 0 ;\n   vl_size dataDimension ;\n \n   vl_uint32* matlabPermutation ;\n \n-  svm = (VlSvm*) vl_malloc(sizeof(VlSvm)) ;\n-\n-  svm->biasMultiplier = 0 ;\n-  svm->preConditioner = NULL ;\n-\n-  svm->maxIterations = 0 ;\n-  svm->iterationsSoFar = 0 ;\n-\n-  svm->elapsedTime = 0 ;\n-\n   void * data ;\n   mxClassID dataClass ;\n   vl_type dataType ;\n@@ -301,14 +288,42 @@ mexFunction(int nout, mxArray *out[],\n   }\n \n \n+  data = mxGetData (IN(DATA)) ;\n+\n+  dataDimension = mxGetM(IN(DATA)) ;\n+  numSamples = mxGetN(IN(DATA)) ;\n+\n+  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {\n+    if  (opt == opt_homkermap)\n+      {\n+        homkermap = VL_TRUE ;\n+        if (! vlmxIsPlainScalar(optarg))\n+          {\n+            vlmxError(vlmxErrInvalidArgument, "N is not a scalar.") ;\n+          }\n+        n = *mxGetPr(optarg) ;\n+        if (n < 0)\n+          {\n+            vlmxError(vlmxErrInvalidArgument, "N is negative.") ;\n+          }\n+\n+      }\n+  }\n+\n+\n+\n+  if (! vlmxIsVector(IN(LABELS), numSamples)) {\n+    vlmxError(vlmxErrInvalidArgument, "LABELS is not a vector of dimension compatible with DATA.") ;\n+  }\n+\n+\n \n   switch (dataClass) {\n   case mxSINGLE_CLASS : dataType = VL_TYPE_FLOAT ; break ;\n   case mxDOUBLE_CLASS : dataType = VL_TYPE_DOUBLE ; break ;\n-  case mxUINT32_CLASS : dataType = VL_TYPE_UINT32; break ;\n   default:\n     vlmxError(vlmxErrInvalidArgument,\n-              "DATA must be either SINGLE or DOUBLE or Block Sparse UINT32.") ;\n+              "DATA must be either SINGLE or DOUBLE.") ;\n   }\n \n   if (mxGetClassID(IN(LABELS)) != mxINT8_CLASS) {\n@@ -319,7 +334,8 @@ mexFunction(int nout, mxArray *out[],\n   if (! vlmxIsPlainScalar(IN(LAMBDA))) {\n     vlmxError(vlmxErrInvalidArgument, "LAMBDA is not a plain scalar.") ;\n   }\n-  svm->regularizer = *mxGetPr(IN(LAMBDA)) ;\n+\n+  svm = vl_svmpegasos_new ((2*n + 1)*dataDimension,*mxGetPr(IN(LAMBDA)) ;\n \n   while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {\n     switch (opt) {\n@@ -327,7 +343,7 @@ mexFunction(int nout, mxArray *out[],\n       if (!vlmxIsPlainScalar(optarg)) {\n \tvlmxError(vlmxErrInvalidArgument, "BIASMULTIPLIER is not a plain scalar.") ;\n       }\n-      svm->biasMultiplier = *mxGetPr(optarg) ;\n+      vl_svmpegasos_set_bias_multiplier(svm, *mxGetPr(optarg)) ;\n       break ;\n \n     case opt_num_iterations :\n@@ -337,7 +353,7 @@ mexFunction(int nout, mxArray *out[],\n       if (*mxGetPr(optarg) < 0) {\n \tvlmxError(vlmxErrInvalidArgument, "NUMITERATIONS is negative.") ;\n       }\n-      svm->maxIterations = (vl_size) *mxGetPr(optarg) ;\n+      vl_svmpegasos_set_maxiterations(svm, (vl_size) *mxGetPr(optarg)) ;\n       break ;\n \n     case opt_starting_iteration :\n@@ -347,7 +363,7 @@ mexFunction(int nout, mxArray *out[],\n       if (*mxGetPr(optarg) < 1) {\n \tvlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is smaller than 1.") ;\n       }\n-      svm->iterationsSoFar = (vl_size) *mxGetPr(optarg) ;\n+      vl_svmpegasos_set_iterations(svm, (vl_size) *mxGetPr(optarg)) ;\n       break ;\n \n     case opt_starting_model :\n@@ -369,19 +385,29 @@ mexFunction(int nout, mxArray *out[],\n       permutationSize = mxGetNumberOfElements(optarg) ;\n       permutation = mxMalloc(sizeof(vl_uint32) * permutationSize) ;\n       matlabPermutation = mxGetData(optarg) ;\n+      {\n+        /* adjust indexing */\n+        vl_uindex k ;\n+        for (k = 0 ; k < permutationSize ; ++k) {\n+          permutation[k] = matlabPermutation[k] - 1 ;\n+          if (permutation[k] >= numSamples) {\n+            vlmxError(vlmxErrInconsistentData,\n+                      "Permutation indexes out of bounds: PERMUTATION(%d) = %d > %d = number of data samples.",\n+                      k + 1, permutation[k] + 1, numSamples) ;\n+          }\n+        }\n+      }\n+      vl_svmpegasos_set_permutation(svm,permutation,permutationSize) ;\n       break ;\n \n-    case opt_preconditioner :\n-      if (!vlmxIsVector(optarg, -1) ||\n-\t  mxIsComplex(optarg) ||\n-\t  !mxIsNumeric(optarg)) {\n-\tvlmxError(vlmxErrInvalidArgument, "PRECONDITIONER is not a real vector.") ;\n-      }\n+    case opt_bias_learningrate :\n+      if (!vlmxIsPlainScalar(optarg)) {\n+\tvlmxError(vlmxErrInvalidArgument, "BIASLEARNINGRATE is not a plain scalar.") ;\n+\n       if (mxGetClassID(optarg) != mxDOUBLE_CLASS) {\n-\tvlmxError(vlmxErrInvalidArgument, "PRECODNITIONER storage class must be double.") ;\n+\tvlmxError(vlmxErrInvalidArgument, "BIASLEARNINGRATE must be double.") ;\n       }\n-      svm->preConditioner = (double*) mxGetData(optarg) ;\n-      preconditionerDimension = mxGetNumberOfElements(optarg) ;\n+      vl_svmpegasos_set_bias_learningrate(svm, (double)*mxGetPr(optarg)) ;\n       break ;\n     case opt_diagnostics :\n \n@@ -390,25 +416,16 @@ mexFunction(int nout, mxArray *out[],\n       }\n       diagnosticsHandle = (mxArray*)(optarg) ;\n       break ;\n-    case opt_diagnostics_freq :\n+    case opt_energy_freq :\n       if (!vlmxIsPlainScalar(optarg)) {\n-\tvlmxError(vlmxErrInvalidArgument, "DIAGNOSTICSFREQ is not a plain scalar.") ;\n+\tvlmxError(vlmxErrInvalidArgument, "ENERGYFREQ is not a plain scalar.") ;\n       }\n-      diagnosticsFrequency = *mxGetPr(optarg) ;\n+      vl_svmpegasos_set_energy_frequency (svm, (vl_size)*mxGetPr(optarg)) ;\n \n       break ;\n     case opt_verbose :\n       ++ verbose ;\n       break ;\n-    case opt_block_sparse :\n-      if (dataType != VL_TYPE_UINT32)\n-\tvlmxError(vlmxErrInvalidArgument, "Invalid Block Sparse Array.") ;\n-\n-      blockSparse = VL_TRUE ;\n-      break;\n-    case opt_homkermap:\n-      homkermap = VL_TRUE ;\n-      break ;\n     case opt_KINTERS:\n     case opt_KL1:\n       kernelType = VlHomogeneousKernelIntersection ;\n@@ -427,18 +444,6 @@ mexFunction(int nout, mxArray *out[],\n       if (period <= 0) {\n \tvlmxError(vlmxErrInvalidArgument, "PERIOD is not positive.") ;\n       }\n-      break ;\n-    case opt_order:\n-      if (! vlmxIsPlainScalar(optarg))\n-\t{\n-\t  vlmxError(vlmxErrInvalidArgument, "N is not a scalar.") ;\n-\t}\n-      n = *mxGetPr(optarg) ;\n-      if (n < 0)\n-\t{\n-\t  vlmxError(vlmxErrInvalidArgument, "N is negative.") ;\n-\t}\n-\n       break ;\n     case opt_gamma:\n       if (! vlmxIsPlainScalar(optarg)){\n@@ -468,44 +473,9 @@ mexFunction(int nout, mxArray *out[],\n   }\n \n \n-  data = mxGetData (IN(DATA)) ;\n-  if (!blockSparse)\n-    {\n-      dataDimension = mxGetM(IN(DATA)) ;\n-      numSamples = mxGetN(IN(DATA)) ;\n-    }\n-  else\n-    {\n-      VlBlockSparseMatrixHeader * bsMatrix = (VlBlockSparseMatrixHeader *) data ;\n-\n-      numSamples = bsMatrix->numColumns ;\n-\n-      VlBlockSparseArrayHeader * bsArray = vl_bsmatrix_get_column(bsMatrix,0) ;\n-\n-      dataDimension = vl_bsarray_length(bsArray) ;\n-\n-    }\n-\n-  svm->dimension = (2*n + 1)*dataDimension;\n \n-  if (! vlmxIsVector(IN(LABELS), numSamples)) {\n-    vlmxError(vlmxErrInvalidArgument, "LABELS is not a vector of dimension compatible with DATA.") ;\n-  }\n \n \n-  if (permutation)\n-    {\n-      /* adjust indexing */\n-      vl_uindex k ;\n-      for (k = 0 ; k < permutationSize ; ++k) {\n-\tpermutation[k] = matlabPermutation[k] - 1 ;\n-\tif (permutation[k] >= numSamples) {\n-\t  vlmxError(vlmxErrInconsistentData,\n-\t\t    "Permutation indexes out of bounds: PERMUTATION(%d) = %d > %d = number of data samples.",\n-\t\t    k + 1, permutation[k] + 1, numSamples) ;\n-\t}\n-      }\n-    }\n \n   if (svm->preConditioner && preconditionerDimension != (svm->dimension + (svm->biasMultiplier > 0))) {\n     vlmxError(vlmxErrInvalidArgument, "PRECONDITIONER has incompatible dimension.") ;\n@@ -560,7 +530,7 @@ mexFunction(int nout, mxArray *out[],\n    * -------------------------------------------------------------- */\n \n   if (diagnosticsHandle)\n-    vl_pegasos_train_binary_svm_diagnostics(svm,data,dataDimension,\n+    vl_pegasos_train s(svm,data,dataDimension,\n \t\t\t\t\t    numSamples,\n \t\t\t\t\t    (vl_int8 const *)mxGetData(IN(LABELS)),\n \t\t\t\t\t    innerProduct,\ndiff --git a/vl/pegasos.c b/vl/pegasos.c\nindex e66fd7f..0ed5c41 100644\n--- a/vl/pegasos.c\n+++ b/vl/pegasos.c\n@@ -272,7 +272,7 @@ vl_svm_compute_diagnostics(VlSvmPegasos *svm,\n \n \n VL_EXPORT\n-VlSvmPegasosSolver* vl_svmpegasos_new (vl_size dimension,\n+VlSvmPegasos* vl_svmpegasos_new (vl_size dimension,\n                                        double lambda)\n {\n   VlSvmPegasos  * svm ;\n@@ -283,7 +283,7 @@ VlSvmPegasosSolver* vl_svmpegasos_new (vl_size dimension,\n \n   svm->objective = (VlSvmObjective*) vl_malloc(sizeof(VlSvmObjective)) ;\n \n-  \n+\n   svm->maxIterations = (vl_size) 10 / (lambda + 1) ;\n \n   assert(lambda > 0.0) ;\n@@ -297,9 +297,11 @@ VlSvmPegasosSolver* vl_svmpegasos_new (vl_size dimension,\n \n   svm->biasLearningRate = 1 ;\n \n-  svm->energyCheckFrequency = 100 ;\n+  svm->energyFrequency = 100 ;\n+\n+  svm->randomGenerator = NULL ;\n \n-  svm->randomGenerator = NULL ; \n+  return svm ;\n }\n \n VL_EXPORT\n@@ -311,9 +313,6 @@ void vl_pegasos_delete (VlSvmPegasos * svm)\n   if (svm->objective)\n     vl_free(svm->objective) ;\n \n-  if (svm->preConditioner)\n-    vl_free(svm->preConditioner) ;\n-\n   if (svm->permutation)\n     vl_free(svm->permutation) ;\n \n@@ -337,7 +336,7 @@ vl_svmpegasos_train(VlSvmPegasos * svm,\n   vl_tic() ;\n   vl_uindex iteration0 ;\n \n-  double energy ;\n+  double energy = 0;\n \n   vl_size i ;\n \n@@ -369,16 +368,16 @@ vl_svmpegasos_train(VlSvmPegasos * svm,\n    the margin, only scale needs to be updated.\n    */\n \n-  for ( ++(svm->iterationsSoFar) ;\n-       svm->iterationsSoFar <  svm->maxIterations ;\n-       ++ svm->iterationsSoFar)\n+  for ( ++(svm->iterations) ;\n+       svm->iterations <  svm->maxIterations ;\n+       ++ svm->iterations)\n     {\n       /* pick a sample  */\n       vl_uindex k ;\n       if (svm->permutation == NULL) {\n-\tk = vl_rand_uindex(randomGenerator, numSamples) ;\n+\tk = vl_rand_uindex(svm->randomGenerator, numSamples) ;\n       } else {\n-\tk = svm->permutation[svm->iterationsSoFar % svm->permutationSize] ;\n+\tk = svm->permutation[svm->iterations % svm->permutationSize] ;\n \tassert(k < numSamples) ;\n       }\n \n@@ -386,21 +385,21 @@ vl_svmpegasos_train(VlSvmPegasos * svm,\n       y = labels[k] ;\n \n       /* compute learning rate */\n-      learningRate = 1.0 / ((svm->iterationsSoFar + iteration0) * lambda) ;\n+      learningRate = 1.0 / ((svm->iterations + iteration0) * lambda) ;\n \n       /* regularizer step ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */\n-      if (svm->iterationsSoFar % regularizationPeriod == 0) {\n+      if (svm->iterations % regularizationPeriod == 0) {\n \tdouble eta =  learningRate * regularizationPeriod * lambda ;\n \n \n-\t\n+\n         for (i = 0 ; i < svm->dimension  ; ++i)\n           {\n             svm->model[i] -= eta * svm->model[i] ;\n           }\n         if (svm->biasMultiplier)\n           svm->bias -= eta * svm->biasLearningRate * svm->bias ;\n-\t  \n+\n \n       }\n \n@@ -425,7 +424,7 @@ vl_svmpegasos_train(VlSvmPegasos * svm,\n \n       }\n \n-      if (svm->iterationsSoFar % svm->energyCheckFrequency == 0)\n+      if (svm->iterations % svm->energyFrequency == 0)\n \t{\n \t  svm->elapsedTime += vl_toc() ;\n           if(validation)\n@@ -448,6 +447,7 @@ vl_svmpegasos_train(VlSvmPegasos * svm,\n           if(svm->epsilon > 0 && abs(energy - svm->objective->energy) < svm->epsilon)\n             break ;\n \n+          energy = svm->objective->energy ;\n \t  vl_tic() ;\n \t}\n \ndiff --git a/vl/pegasos.h b/vl/pegasos.h\nindex a74036f..1da30ea 100644\n--- a/vl/pegasos.h\n+++ b/vl/pegasos.h\n@@ -28,7 +28,7 @@ typedef struct _VlSvmObjective {\n /** @brief Pegasos Svm Solver  */\n typedef struct _VlSvmPegasos {\n   double *  model ;\n-  double bias ; \n+  double bias ;\n   vl_size dimension ;\n   vl_size iterations ;\n   vl_size maxIterations ;\n@@ -39,7 +39,7 @@ typedef struct _VlSvmPegasos {\n   vl_size energyFrequency ;\n   double  biasLearningRate ;\n   VlSvmObjective*  objective ;\n-  VlRand* randomGenerator ; \n+  VlRand* randomGenerator ;\n   vl_uint32 * permutation ;\n   vl_size permutationSize ;\n } VlSvmPegasos ;\n@@ -73,7 +73,7 @@ void vl_svmpegasos_train (VlSvmPegasos * svm,\n  ** @{\n  **/\n VL_INLINE double* vl_svmpegasos_get_model             (VlSvmPegasos const *self) ;\n-VL_INLINE double* vl_svmpegasos_get_bias              (VlSvmPegasos const *self) ;\n+VL_INLINE double  vl_svmpegasos_get_bias              (VlSvmPegasos const *self) ;\n VL_INLINE vl_size vl_svmpegasos_get_dimension         (VlSvmPegasos const *self) ;\n VL_INLINE vl_size vl_svmpegasos_get_iterations        (VlSvmPegasos const *self) ;\n VL_INLINE vl_size vl_svmpegasos_get_maxiterations     (VlSvmPegasos const *self) ;\n@@ -93,13 +93,14 @@ VL_INLINE vl_size vl_svmpegasos_get_permutation_size  (VlSvmPegasos const *self)\n  ** @{\n  **/\n VL_INLINE void vl_svmpegasos_set_maxiterations   (VlSvmPegasos *self, vl_size i) ;\n+VL_INLINE void vl_svmpegasos_set_iterations      (VlSvmPegasos *self, vl_size i) ;\n VL_INLINE void vl_svmpegasos_set_epsilon         (VlSvmPegasos *self, double e) ;\n VL_INLINE void vl_svmpegasos_set_lambda          (VlSvmPegasos *self, double l) ;\n VL_INLINE void vl_svmpegasos_set_bias_multiplier (VlSvmPegasos *self, double b) ;\n VL_INLINE void vl_svmpegasos_set_energy_frequency(VlSvmPegasos *self, vl_size e) ;\n VL_INLINE void vl_svmpegasos_set_bias_learningrate (VlSvmPegasos *self, double  blr) ;\n-VL_INLINE void vl_svmpegasos_set_random_generator(VlSvmPegasos const *self, VlRand * r) ;\n-VL_INLINE void vl_svmpegasos_set_permutation     (VlSvmPegasos const *self, vl_uint32 p,\n+VL_INLINE void vl_svmpegasos_set_random_generator(VlSvmPegasos *self, VlRand * r) ;\n+VL_INLINE void vl_svmpegasos_set_permutation     (VlSvmPegasos *self, vl_uint32* p,\n                                                   vl_size psize) ;\n /** @} */\n \n@@ -113,10 +114,10 @@ VL_INLINE void vl_svmpegasos_set_permutation     (VlSvmPegasos const *self, vl_u\n  ** @return pointer to model.\n  **/\n \n-VL_INLINE double* \n+VL_INLINE double*\n vl_svmpegasos_get_model (VlSvmPegasos const *self)\n {\n-  return self->model ; \n+  return self->model ;\n }\n \n /** ------------------------------------------------------------------\n@@ -125,10 +126,10 @@ vl_svmpegasos_get_model (VlSvmPegasos const *self)\n  ** @return bias value.\n  **/\n \n-VL_INLINE double \n+VL_INLINE double\n vl_svmpegasos_get_bias (VlSvmPegasos const *self)\n {\n-  return self->bias ; \n+  return self->bias ;\n }\n \n /** ------------------------------------------------------------------\n@@ -140,7 +141,7 @@ vl_svmpegasos_get_bias (VlSvmPegasos const *self)\n VL_INLINE vl_size\n vl_svmpegasos_get_dimension (VlSvmPegasos const *self)\n {\n-  return self->dimension ; \n+  return self->dimension ;\n }\n \n /** ------------------------------------------------------------------\n@@ -152,7 +153,7 @@ vl_svmpegasos_get_dimension (VlSvmPegasos const *self)\n VL_INLINE vl_size\n vl_svmpegasos_get_iterations (VlSvmPegasos const *self)\n {\n-  return self->iterations ; \n+  return self->iterations ;\n }\n \n /** ------------------------------------------------------------------\n@@ -164,7 +165,7 @@ vl_svmpegasos_get_iterations (VlSvmPegasos const *self)\n VL_INLINE vl_size\n vl_svmpegasos_get_maxiterations (VlSvmPegasos const *self)\n {\n-  return self->maxIterations ; \n+  return self->maxIterations ;\n }\n \n /** ------------------------------------------------------------------\n@@ -176,7 +177,7 @@ vl_svmpegasos_get_maxiterations (VlSvmPegasos const *self)\n VL_INLINE double\n vl_svmpegasos_get_epsilon (VlSvmPegasos const *self)\n {\n-  return self->epsilon ; \n+  return self->epsilon ;\n }\n \n /** ------------------------------------------------------------------\n@@ -188,7 +189,7 @@ vl_svmpegasos_get_epsilon (VlSvmPegasos const *self)\n VL_INLINE double\n vl_svmpegasos_get_lambda (VlSvmPegasos const *self)\n {\n-  return self->lambda ; \n+  return self->lambda ;\n }\n \n /** ------------------------------------------------------------------\n@@ -200,7 +201,7 @@ vl_svmpegasos_get_lambda (VlSvmPegasos const *self)\n VL_INLINE double\n vl_svmpegasos_get_bias_multiplier (VlSvmPegasos const *self)\n {\n-  return self->biasMultiplier ; \n+  return self->biasMultiplier ;\n }\n \n /** ------------------------------------------------------------------\n@@ -212,11 +213,11 @@ vl_svmpegasos_get_bias_multiplier (VlSvmPegasos const *self)\n VL_INLINE double\n vl_svmpegasos_get_elapsed_time (VlSvmPegasos const *self)\n {\n-  return self->elapsedTime ; \n+  return self->elapsedTime ;\n }\n \n /** ------------------------------------------------------------------\n- ** @brief Get how frequent the full energy is computed. \n+ ** @brief Get how frequent the full energy is computed.\n  ** @param self Pegasos Svm Solver.\n  ** @return energy computation frequency.\n  **/\n@@ -224,7 +225,7 @@ vl_svmpegasos_get_elapsed_time (VlSvmPegasos const *self)\n VL_INLINE vl_size\n vl_svmpegasos_get_energy_frequency (VlSvmPegasos const *self)\n {\n-  return self->energyFrequency ; \n+  return self->energyFrequency ;\n }\n \n /** ------------------------------------------------------------------\n@@ -236,7 +237,7 @@ vl_svmpegasos_get_energy_frequency (VlSvmPegasos const *self)\n VL_INLINE double\n vl_svmpegasos_get_bias_learningrate (VlSvmPegasos const *self)\n {\n-  return self->biasLearningRate ; \n+  return self->biasLearningRate ;\n }\n \n /** ------------------------------------------------------------------\n@@ -245,10 +246,10 @@ vl_svmpegasos_get_bias_learningrate (VlSvmPegasos const *self)\n  ** @return objective energy.\n  **/\n \n-VL_INLINE double*\n+VL_INLINE VlSvmObjective*\n vl_svmpegasos_get_objective (VlSvmPegasos const *self)\n {\n-  return self->objective ; \n+  return self->objective ;\n }\n \n /** ------------------------------------------------------------------\n@@ -260,7 +261,7 @@ vl_svmpegasos_get_objective (VlSvmPegasos const *self)\n VL_INLINE VlRand*\n vl_svmpegasos_get_random_generator (VlSvmPegasos const *self)\n {\n-  return self->randomGenerator ; \n+  return self->randomGenerator ;\n }\n \n /** ------------------------------------------------------------------\n@@ -272,7 +273,7 @@ vl_svmpegasos_get_random_generator (VlSvmPegasos const *self)\n VL_INLINE vl_uint32*\n vl_svmpegasos_get_permutation (VlSvmPegasos const *self)\n {\n-  return self->permutation ; \n+  return self->permutation ;\n }\n \n /** ------------------------------------------------------------------\n@@ -282,9 +283,9 @@ vl_svmpegasos_get_permutation (VlSvmPegasos const *self)\n  **/\n \n VL_INLINE vl_size\n-vl_svmpegasos_get_permutation (VlSvmPegasos const *self)\n+vl_svmpegasos_get_permutationsize (VlSvmPegasos const *self)\n {\n-  return self->permutationSize ; \n+  return self->permutationSize ;\n }\n \n /** ------------------------------------------------------------------\n@@ -296,7 +297,19 @@ vl_svmpegasos_get_permutation (VlSvmPegasos const *self)\n VL_INLINE void\n vl_svmpegasos_set_maxiterations (VlSvmPegasos *self, vl_size i)\n {\n-  self->maxIterations = maxIterations ; \n+  self->maxIterations = i ;\n+}\n+\n+/** ------------------------------------------------------------------\n+ ** @brief Set pegasos performed iterations.\n+ ** @param self Pegasos Svm Solver.\n+ ** @param i pegasos performed iterations.\n+ **/\n+\n+VL_INLINE void\n+vl_svmpegasos_set_iterations (VlSvmPegasos *self, vl_size i)\n+{\n+  self->iterations = i ;\n }\n \n /** ------------------------------------------------------------------\n@@ -306,9 +319,9 @@ vl_svmpegasos_set_maxiterations (VlSvmPegasos *self, vl_size i)\n  **/\n \n VL_INLINE void\n-vl_svmpegasos_set_epsilon (VlSvmPegasos *self, vl_size e)\n+vl_svmpegasos_set_epsilon (VlSvmPegasos *self, double e)\n {\n-  self->epsilon = epsilon ; \n+  self->epsilon = e ;\n }\n \n /** ------------------------------------------------------------------\n@@ -318,9 +331,9 @@ vl_svmpegasos_set_epsilon (VlSvmPegasos *self, vl_size e)\n  **/\n \n VL_INLINE void\n-vl_svmpegasos_set_lambda (VlSvmPegasos *self, vl_size l)\n+vl_svmpegasos_set_lambda (VlSvmPegasos *self, double l)\n {\n-  self->lambda = lambda ; \n+  self->lambda = l ;\n }\n \n /** ------------------------------------------------------------------\n@@ -330,9 +343,9 @@ vl_svmpegasos_set_lambda (VlSvmPegasos *self, vl_size l)\n  **/\n \n VL_INLINE void\n-vl_svmpegasos_set_bias_multiplier (VlSvmPegasos *self, vl_size b)\n+vl_svmpegasos_set_bias_multiplier (VlSvmPegasos *self, double b)\n {\n-  self->biasMultiplier = biasMultiplier ; \n+  self->biasMultiplier = b ;\n }\n \n /** ------------------------------------------------------------------\n@@ -344,7 +357,7 @@ vl_svmpegasos_set_bias_multiplier (VlSvmPegasos *self, vl_size b)\n VL_INLINE void\n vl_svmpegasos_set_energy_frequency (VlSvmPegasos *self, vl_size e)\n {\n-  self->energyFrequency = energyFrequency ; \n+  self->energyFrequency = e ;\n }\n \n /** ------------------------------------------------------------------\n@@ -354,9 +367,9 @@ vl_svmpegasos_set_energy_frequency (VlSvmPegasos *self, vl_size e)\n  **/\n \n VL_INLINE void\n-vl_svmpegasos_set_bias_learningrate (VlSvmPegasos *self, vl_size blr)\n+vl_svmpegasos_set_bias_learningrate (VlSvmPegasos *self, double blr)\n {\n-  self->biasLearningrate = blr ; \n+  self->biasLearningRate = blr ;\n }\n \n /** ------------------------------------------------------------------\n@@ -366,9 +379,9 @@ vl_svmpegasos_set_bias_learningrate (VlSvmPegasos *self, vl_size blr)\n  **/\n \n VL_INLINE void\n-vl_svmpegasos_set_random_generator(VlSvmPegasos const *self, VlRand * r)\n+vl_svmpegasos_set_random_generator(VlSvmPegasos *self, VlRand * r)\n {\n-  self->randomGenerator = r ; \n+  self->randomGenerator = r ;\n }\n \n /** ------------------------------------------------------------------\n@@ -379,11 +392,11 @@ vl_svmpegasos_set_random_generator(VlSvmPegasos const *self, VlRand * r)\n  **/\n \n VL_INLINE void\n-vl_svmpegasos_set_permutation(VlSvmPegasos const *self, vl_uint32 p,\n+vl_svmpegasos_set_permutation(VlSvmPegasos *self, vl_uint32* p,\n                                    vl_size psize)\n {\n   self->permutation = p ;\n-  self->permutationSize = psize ; \n+  self->permutationSize = psize ;\n }\n \n /* VL_PEGASOS_H */\ndiff --git a/vl/svmdataset.c b/vl/svmdataset.c\nindex fbf4dec..810ceba 100644\n--- a/vl/svmdataset.c\n+++ b/vl/svmdataset.c\n@@ -8,7 +8,7 @@ Copyright Statement\n */\n #ifndef VL_SVM_INVARIANTS\n \n-#include "svm_dataset.h"\n+#include "svmdataset.h"\n #include <string.h>\n #include <math.h>\n \n@@ -32,7 +32,6 @@ void vl_svmdataset_set_map (VlSvmDataset * data, void * map, VlSvmFeatureMap map\n   data->mapFunc = mapFunc ;\n   data->order = order ;\n \n-  return data ;\n }\n \n VL_EXPORT\n@@ -46,11 +45,11 @@ void vl_svmdataset_delete (VlSvmDataset * dataset)\n \n #define FLT VL_TYPE_FLOAT\n #define VL_SVM_INVARIANTS\n-#include "svm_dataset.c"\n+#include "svmdataset.c"\n \n #define FLT VL_TYPE_DOUBLE\n #define VL_SVM_INVARIANTS\n-#include "svm_dataset.c"\n+#include "svmdataset.c"\n \n /* VL_SVM_INVARIANTS */\n \n@@ -66,30 +65,30 @@ VL_XCAT(vl_svm_innnerproduct_,SFX) (const void* data, const vl_uindex element,\n   T* tData ;\n   double res = 0 ;\n \n+  VlSvmDataset* sdata = (VlSvmDataset*) data ;\n \n+  tData  = (T*) sdata->data ;\n \n-  tData  = (T*) data->data ;\n-\n-  if (data->mapFunc)\n+  if (sdata->mapFunc)\n     {\n \n-      double temp[data->order] ;\n+      double temp[sdata->order] ;\n \n-      for (i = 0; i < data->dimension; i++)\n+      for (i = 0; i < sdata->dimension; i++)\n \t{\n-\t  data->mapFunc(data->map,temp,1,tData[element*data->dimension + i]);\n+\t  sdata->mapFunc(sdata->map,temp,1,tData[element*sdata->dimension + i]);\n \n-\t  for (j = 0; j < data->order; j++)\n+\t  for (j = 0; j < sdata->order; j++)\n \t    {\n-\t      res += model[i*data->order + j]*temp[j] ;\n+\t      res += model[i*sdata->order + j]*temp[j] ;\n \t    }\n \t}\n     }\n   else\n     {\n-      for (i = 0; i < data->dimension; i++)\n+      for (i = 0; i < sdata->dimension; i++)\n \t{\n-\t  res += model[i]*(double)(tData[element*data->dimension + i]) ;\n+\t  res += model[i]*(double)(tData[element*sdata->dimension + i]) ;\n \t}\n     }\n \n@@ -106,28 +105,31 @@ VL_XCAT(vl_svm_accumulator_,SFX)(const void* data,\n   vl_size i,j ;\n   T* tData ;\n \n-  tData  = (T*) data->data ;\n \n-  if (data->mapFunc)\n+  VlSvmDataset* sdata = (VlSvmDataset*) data ;\n+\n+  tData  = (T*) sdata->data ;\n+\n+  if (sdata->mapFunc)\n     {\n \n-      double temp[data->order] ;\n+      double temp[sdata->order] ;\n+\n \n-      \n-      for (i = 0; i < data->dimension; i++)\n+      for (i = 0; i < sdata->dimension; i++)\n         {\n-          data->mapFunc(data->map,temp,1,tData[element*data->dimension + i]) ;\n-          for (j = 0; j < data->order; j++)\n+          sdata->mapFunc(sdata->map,temp,1,tData[element*sdata->dimension + i]) ;\n+          for (j = 0; j < sdata->order; j++)\n             {\n-              model[i*data->order + j] += multiplier * temp[j] ;\n+              model[i*sdata->order + j] += multiplier * temp[j] ;\n             }\n         }\n     }\n   else\n     {\n-      for (i = 0; i < data->dimension; i++)\n+      for (i = 0; i < sdata->dimension; i++)\n         {\n-          model[i] += multiplier * tData[element*data->dimension + i] ;\n+          model[i] += multiplier * tData[element*sdata->dimension + i] ;\n         }\n     }\n \ndiff --git a/vl/svmdataset.h b/vl/svmdataset.h\nindex 6c500de..42a67d4 100644\n--- a/vl/svmdataset.h\n+++ b/vl/svmdataset.h\n@@ -49,7 +49,7 @@ typedef struct _VlSvmDataset {\n \n \n VL_EXPORT\n-VlSvmDataset* vl_svmdataset_new (void * data, vl_size dimension) ; \n+VlSvmDataset* vl_svmdataset_new (void * data, vl_size dimension) ;\n \n VL_EXPORT\n void vl_svmdataset_set_map (VlSvmDataset * data, void * map,VlSvmFeatureMap mapFunc, vl_size order) ;\n', 'commit_subject': 'design fixes', 'repo_name': 'vlfeat/vlfeat', 'committer': {'name': 'Andrea Vedaldi', 'email': '412674b6eaeb392cf6309bc8344c997e51457723@gmail.com', 'time_sec': '1347553465', 'tz_offset': '60', 'date': {'seconds': '1347553465'}}, 'commit_tree': 'cc2880e5224ad755d7201c1772b1f9963274c33e', 'commit_message': 'design fixes\n', 'language_name': 'Matlab', 'license': 'bsd-2-clause', 'hunks': '@@ -49,7 +49,7 @@ typedef struct _VlSvmDataset {\n \n \n VL_EXPORT\n-VlSvmDataset* vl_svmdataset_new (void * data, vl_size dimension) ; \n+VlSvmDataset* vl_svmdataset_new (void * data, vl_size dimension) ;\n \n VL_EXPORT\n void vl_svmdataset_set_map (VlSvmDataset * data, void * map,VlSvmFeatureMap mapFunc, vl_size order) ;\n', 'addition_count': 1, 'deletion_count': 1, 'src_file': 'a/vl/svmdataset.h', 'tgt_file': 'b/vl/svmdataset.h', 'file_extension': '.h', 'before_file': '/** @file svmdataset.h\n ** @brief SVM Dataset\n ** @author Daniele Perrone\n ** @author Andrea Vedaldi\n **/\n\n/*\nCopyright (C) 2012 Daniele Perrone.\nCopyright (C) 2013 Andrea Vedaldi.\nAll rights reserved.\n\nThis file is part of the VLFeat library and is made available under\nthe terms of the BSD license (see the COPYING file).\n*/\n\n#ifndef VL_SVMDATASET_H\n#define VL_SVMDATASET_H\n\n#include "generic.h"\n#include "homkermap.h"\n\nstruct VlSvm_ ;\n\n/** @typedef VlSvmDataset\n ** @brief SVM dataset object\n **\n ** This objects contain a training set to be used in combination with\n ** the SVM solver object ::VlSvm. Its main purpose is to implement\n ** the two basic operations inner product (::VlSvmInnerProductFunction)\n ** and accumulation (::VlSvmAccumulateFunction).\n **\n ** See @ref svm and @ref svm-advanced for further information.\n **/\n\n#ifndef __DOXYGEN__\nstruct VlSvmDataset_ ;\ntypedef struct VlSvmDataset_ VlSvmDataset ;\n#else\ntypedef OPAQUE VlSvmDataset ;\n#endif\n\n/** @name SVM callbacks\n ** @{ */\ntypedef void (*VlSvmDiagnosticFunction) (struct VlSvm_ *svm, void *data) ;\ntypedef double (*VlSvmLossFunction) (double inner, double label) ;\ntypedef double (*VlSvmDcaUpdateFunction) (double alpha, double inner, double norm2, double label) ;\ntypedef double (*VlSvmInnerProductFunction)(const void *data, vl_uindex element, double *model) ;\ntypedef void (*VlSvmAccumulateFunction) (const void *data, vl_uindex element, double *model, double multiplier) ;\n\n\nVL_EXPORT\nVlSvmDataset* vl_svmdataset_new (void * data, vl_size dimension) ; \n\nVL_EXPORT\nvoid vl_svmdataset_set_map (VlSvmDataset * data, void * map,VlSvmFeatureMap mapFunc, vl_size order) ;\nVL_EXPORT void vl_svmdataset_delete (VlSvmDataset * dataset) ;\n/** @} */\n\n/** @name Set parameters\n ** @{\n **/\nVL_EXPORT void vl_svmdataset_set_homogeneous_kernel_map (VlSvmDataset * self,\n                                                         VlHomogeneousKernelMap * hom) ;\n/** @} */\n\n/** @name Get data and parameters\n ** @{\n **/\nVL_EXPORT void* vl_svmdataset_get_data (VlSvmDataset const *self) ;\nVL_EXPORT vl_size vl_svmdataset_get_num_data (VlSvmDataset const *self) ;\nVL_EXPORT vl_size vl_svmdataset_get_dimension (VlSvmDataset const *self) ;\nVL_EXPORT void* vl_svmdataset_get_map (VlSvmDataset const *self) ;\nVL_EXPORT vl_size vl_svmdataset_get_mapDim (VlSvmDataset const *self) ;\nVL_EXPORT VlSvmAccumulateFunction vl_svmdataset_get_accumulate_function (VlSvmDataset const *self) ;\nVL_EXPORT VlSvmInnerProductFunction vl_svmdataset_get_inner_product_function (VlSvmDataset const * self) ;\nVL_EXPORT VlHomogeneousKernelMap * vl_svmdataset_get_homogeneous_kernel_map (VlSvmDataset const * self) ;\n/** @} */\n\n/* VL_SVMDATASET_H */\n#endif\n\n\n', 'message': 'design fixes\n', 'author_name': 'Andrea Vedaldi', 'lang': 'h'}