Explorar o código

towards quantization for raw version -- unstable

Alexander Freytag %!s(int64=9) %!d(string=hai) anos
pai
achega
4af16179a4

+ 135 - 10
GMHIKernelRaw.cpp

@@ -16,13 +16,17 @@ using namespace NICE;
 using namespace std;
 using namespace std;
 
 
 
 
-GMHIKernelRaw::GMHIKernelRaw( const std::vector< const NICE::SparseVector *> &_examples, const double _d_noise )
+GMHIKernelRaw::GMHIKernelRaw( const std::vector< const NICE::SparseVector *> &_examples,
+                              const double _d_noise
+                              const NICE::Quantization * _q
+                            )
 {
 {
     this->examples_raw = NULL;
     this->examples_raw = NULL;
     this->nnz_per_dimension = NULL;
     this->nnz_per_dimension = NULL;
     this->table_A = NULL;
     this->table_A = NULL;
     this->table_B = NULL;
     this->table_B = NULL;
     this->d_noise = _d_noise;
     this->d_noise = _d_noise;
+    this->q       = _q;
 
 
     initData(_examples);
     initData(_examples);
 }
 }
@@ -59,7 +63,6 @@ void GMHIKernelRaw::cleanupData()
         delete [] this->table_B;
         delete [] this->table_B;
         this->table_B = NULL;
         this->table_B = NULL;
     }
     }
-
 }
 }
 
 
 void GMHIKernelRaw::initData ( const std::vector< const NICE::SparseVector *> &_examples )
 void GMHIKernelRaw::initData ( const std::vector< const NICE::SparseVector *> &_examples )
@@ -131,11 +134,19 @@ void GMHIKernelRaw::initData ( const std::vector< const NICE::SparseVector *> &_
     }
     }
 
 
     // pre-allocate the A and B matrices
     // pre-allocate the A and B matrices
-    this->table_A = allocateTable();
-    this->table_B = allocateTable();
+    this->table_A = allocateTableAorB();
+    this->table_B = allocateTableAorB();
+
+    // Quantization for classification?
+    if ( this->q != NULL )
+    {
+      // (1) if yes, setup the parameters of the quantization object
+      this->q->computeParametersFromData ( this );
+      this->table_T = allocateTableT();
+    }
 }
 }
 
 
-double **GMHIKernelRaw::allocateTable() const
+double **GMHIKernelRaw::allocateTableAorB() const
 {
 {
     double **table;
     double **table;
     table = new double *[this->num_dimension];
     table = new double *[this->num_dimension];
@@ -151,7 +162,14 @@ double **GMHIKernelRaw::allocateTable() const
     return table;
     return table;
 }
 }
 
 
-void GMHIKernelRaw::copyTable(double **src, double **dst) const
+double **GMHIKernelRaw::allocateTableT() const
+{
+    double **table;
+    table = new double *[this->num_dimension * this->q->getNumberOfBins()];
+    return table;
+}
+
+void GMHIKernelRaw::copyTableAorB(double **src, double **dst) const
 {
 {
     for (uint i = 0; i < this->num_dimension; i++)
     for (uint i = 0; i < this->num_dimension; i++)
     {
     {
@@ -165,8 +183,52 @@ void GMHIKernelRaw::copyTable(double **src, double **dst) const
     }
     }
 }
 }
 
 
+void GMHIKernelRaw::copyTableC(double **src, double **dst) const
+{
+    for (uint i = 0; i < this->num_dimension; i++)
+    {
+        for (uint j = 0; j < this->q->getNumberOfBins(); j++)
+        {
+            //FIXME can we speed this up using pointer increments?
+            dst[i][j] = src[i][j];
+        }
+    }
+}
+
 void GMHIKernelRaw::updateTables ( const NICE::Vector _x ) const
 void GMHIKernelRaw::updateTables ( const NICE::Vector _x ) const
 {
 {
+    // pre-computions if quantization is activated
+    double * prototypes;
+    double * p_prototypes;
+
+    // store prototypes
+    if ( this->q != NULL)
+    {
+        // number of quantization bins
+        uint hmax = _q->getNumberOfBins();
+
+
+        double * prototypes   = new double [ hmax * this->ui_d ];
+        double * p_prototypes = prototypes;
+
+        for (uint dim = 0; dim < this->ui_d; dim++)
+        {
+          for ( uint i = 0 ; i < hmax ; i++ )
+          {
+            if ( _pf != NULL )
+            {
+              *p_prototypes = _pf->f ( dim, _q->getPrototype( i, dim ) );
+            } else
+            {
+              *p_prototypes = _q->getPrototype( i, dim );
+            }
+
+            p_prototypes++;
+          }
+        }
+    }
+
+    // start the actual computations of A, B, and optionally T
     for (uint dim = 0; dim < this->num_dimension; dim++)
     for (uint dim = 0; dim < this->num_dimension; dim++)
     {
     {
       double alpha_sum = 0.0;
       double alpha_sum = 0.0;
@@ -248,15 +310,22 @@ uint GMHIKernelRaw::cols () const
 
 
 double **GMHIKernelRaw::getTableA() const
 double **GMHIKernelRaw::getTableA() const
 {
 {
-    double **t = allocateTable();
-    copyTable(this->table_A, t);
+    double **t = allocateTableAorB();
+    copyTableAorB(this->table_A, t);
     return t;
     return t;
 }
 }
 
 
 double **GMHIKernelRaw::getTableB() const
 double **GMHIKernelRaw::getTableB() const
 {
 {
-    double **t = allocateTable();
-    copyTable(this->table_B, t);
+    double **t = allocateTableAorB();
+    copyTableAorB(this->table_B, t);
+    return t;
+}
+
+double **GMHIKernelRaw::getTableT() const
+{
+    double **t = allocateTableT();
+    copyTableT(this->table_T, t);
     return t;
     return t;
 }
 }
 
 
@@ -269,7 +338,63 @@ uint *GMHIKernelRaw::getNNZPerDimension() const
 }
 }
 
 
 
 
+uint NICE::GMHIKernelRaw::getNumberOfDimensions() const
+{
+    return this->num_dimension;
+}
+
 void NICE::GMHIKernelRaw::getDiagonalElements( NICE::Vector & _diagonalElements) const
 void NICE::GMHIKernelRaw::getDiagonalElements( NICE::Vector & _diagonalElements) const
 {
 {
     _diagonalElements = this->diagonalElements;
     _diagonalElements = this->diagonalElements;
 }
 }
+
+double NICE::GMHIKernelRaw::getLargestValue ( ) const
+{
+  double vmax (0.0);
+  double vtmp (0.0);
+
+  uint tmpIdx ( 0 );
+  // compare largest elements of all dimensions
+  for (uint d = 0; d < this->num_dimension; d++)
+  {
+      uint nnz = this->nnz_per_dimension[d];
+
+      if ( nnz > 1 )
+      {
+          tmpIdx = tmpIdx + nnz;
+          vtmp   = this->examples_raw[tmpIdx];
+          if ( vtmp > vmax )
+          {
+            vmax = vtmp;
+          }
+      }
+  }
+
+  return vmax;
+}
+
+
+NICE::Vector NICE::GMHIKernelRaw::getLargestValuePerDimension ( ) const
+{
+  NICE::Vector vmax ( this->get_d() );
+
+  NICE::Vector::iterator vmaxIt = vmax.begin();
+
+  uint tmpIdx ( 0 );
+  for (uint d = 0; d < this->num_dimension; d++, vmaxIt++)
+  {
+      uint nnz = this->nnz_per_dimension[d];
+
+      if ( nnz > 1 )
+      {
+          tmpIdx  = tmpIdx + nnz;
+          *vmaxIt = this->examples_raw[tmpIdx];
+      }
+      else
+      {
+          *vmaxIt = 0.0;
+      }
+  }
+
+  return vmax;
+}

+ 45 - 4
GMHIKernelRaw.h

@@ -11,6 +11,8 @@
 
 
 #include <core/algebra/GenericMatrix.h>
 #include <core/algebra/GenericMatrix.h>
 
 
+#include "quantization/Quantization.h"
+
 namespace NICE {
 namespace NICE {
 
 
  /**
  /**
@@ -38,6 +40,7 @@ class GMHIKernelRaw : public GenericMatrix
     sparseVectorElement **examples_raw;
     sparseVectorElement **examples_raw;
     double **table_A;
     double **table_A;
     double **table_B;
     double **table_B;
+    double **table_T;
 
 
     NICE::Vector diagonalElements;
     NICE::Vector diagonalElements;
 
 
@@ -46,18 +49,48 @@ class GMHIKernelRaw : public GenericMatrix
     uint num_examples;
     uint num_examples;
     double d_noise;
     double d_noise;
 
 
+    /** object performing feature quantization */
+    NICE::Quantization *q;
+
+
+
+    /////////////////////////
+    /////////////////////////
+    //  PROTECTED METHODS  //
+    /////////////////////////
+    /////////////////////////
+
     void initData ( const std::vector< const NICE::SparseVector *> & examples );
     void initData ( const std::vector< const NICE::SparseVector *> & examples );
     void cleanupData ();
     void cleanupData ();
-    double **allocateTable() const;
-    void copyTable(double **src, double **dst) const;
+
+    double **allocateTableAorB() const;
+    double **allocateTableT() const
+
+    void copyTableAorB(double **src, double **dst) const;
+    void copyTableT(double **src, double **dst) const;
+
+
+    double * computeTableT ( const NICE::Vector & _alpha
+                           );
+
+    /////////////////////////
+    /////////////////////////
+    //    PUBLIC METHODS   //
+    /////////////////////////
+    /////////////////////////
 
 
   public:
   public:
 
 
     /** simple constructor */
     /** simple constructor */
-    GMHIKernelRaw( const std::vector< const NICE::SparseVector *> & examples, const double d_noise = 0.1 );
+    GMHIKernelRaw( const std::vector< const NICE::SparseVector *> & examples,
+                   const double d_noise = 0.1,
+                   const NICE::Quantization * _q = NULL
+                 );
 
 
     /** multiply with a vector: A*x = y; this is not really const anymore!! */
     /** multiply with a vector: A*x = y; this is not really const anymore!! */
-    virtual void multiply (NICE::Vector & y, const NICE::Vector & x) const;
+    virtual void multiply ( NICE::Vector & y,
+                            const NICE::Vector & x
+                          ) const;
 
 
     /** get the number of rows in A */
     /** get the number of rows in A */
     virtual uint rows () const;
     virtual uint rows () const;
@@ -67,7 +100,10 @@ class GMHIKernelRaw : public GenericMatrix
 
 
     double **getTableA() const;
     double **getTableA() const;
     double **getTableB() const;
     double **getTableB() const;
+    double **getTableT() const;
+
     uint *getNNZPerDimension() const;
     uint *getNNZPerDimension() const;
+    uint getNumberOfDimensions() const;
 
 
     /** simple destructor */
     /** simple destructor */
     virtual ~GMHIKernelRaw();
     virtual ~GMHIKernelRaw();
@@ -78,6 +114,11 @@ class GMHIKernelRaw : public GenericMatrix
     /** get the diagonal elements of the current matrix */
     /** get the diagonal elements of the current matrix */
     void getDiagonalElements ( NICE::Vector & _diagonalElements ) const;
     void getDiagonalElements ( NICE::Vector & _diagonalElements ) const;
 
 
+
+    double getLargestValue ( ) const;
+
+    NICE::Vector getLargestValuePerDimension ( ) const;
+
 };
 };
 
 
 }
 }

+ 120 - 5
GPHIKRawClassifier.cpp

@@ -17,8 +17,13 @@
 #include <core/algebra/EigValues.h>
 #include <core/algebra/EigValues.h>
 
 
 // gp-hik-core includes
 // gp-hik-core includes
-#include "GPHIKRawClassifier.h"
-#include "GMHIKernelRaw.h"
+#include "gp-hik-core/GPHIKRawClassifier.h"
+#include "gp-hik-core/GMHIKernelRaw.h"
+
+//
+#include "gp-hik-core/quantization/Quantization1DAequiDist0To1.h"
+#include "gp-hik-core/quantization/Quantization1DAequiDist0ToMax.h"
+#include "gp-hik-core/quantization/QuantizationNDAequiDist0ToMax.h"
 
 
 using namespace std;
 using namespace std;
 using namespace NICE;
 using namespace NICE;
@@ -30,6 +35,64 @@ using namespace NICE;
 /////////////////////////////////////////////////////
 /////////////////////////////////////////////////////
 
 
 
 
+double * GPHIKRawClassifier::computeTableT ( const NICE::Vector & _alpha
+                                           )
+{
+    if (this->q == NULL )
+    {
+        return NULL;
+    }
+
+    //
+    // number of quantization bins
+    uint hmax = _q->getNumberOfBins();
+
+    // store (transformed) prototypes
+    double * prototypes   = new double [ hmax * this->num_dimension ];
+    double * p_prototypes = prototypes;
+
+    for (uint dim = 0; dim < this->num_dimension; dim++)
+    {
+      for ( uint i = 0 ; i < hmax ; i++ )
+      {
+        if ( _pf != NULL )
+        {
+          *p_prototypes = _pf->f ( dim, _q->getPrototype( i, dim ) );
+        } else
+        {
+          *p_prototypes = _q->getPrototype( i, dim );
+        }
+
+        p_prototypes++;
+      }
+    }
+
+    //allocate memory for the LUT
+    double *Tlookup = new double [ hmax * this->num_dimension ];
+
+    // loop through all dimensions
+    for (uint dim = 0; dim < this->ui_d; dim++)
+    {
+        if ( nnz_per_dimension[dim] == 0 )
+            continue;
+
+        double alphaSumTotalInDim(0.0);
+        double alphaTimesXSumTotalInDim(0.0);
+
+        for ( SortedVectorSparse<double>::const_elementpointer i = nonzeroElements.begin(); i != nonzeroElements.end(); i++ )
+        {
+          alphaSumTotalInDim += _alpha[i->second.first];
+          alphaTimesXSumTotalInDim += _alpha[i->second.first] * i->second.second;
+        }
+    }
+
+    //don't waste memory
+    delete [] prototypes;
+
+    return Tlookup;
+
+}
+
 
 
 /////////////////////////////////////////////////////
 /////////////////////////////////////////////////////
 /////////////////////////////////////////////////////
 /////////////////////////////////////////////////////
@@ -129,6 +192,46 @@ void GPHIKRawClassifier::initFromConfig(const Config *_conf,
       std::cerr << "   ils_min_residual " << ils_min_residual << std::endl;
       std::cerr << "   ils_min_residual " << ils_min_residual << std::endl;
       std::cerr << "   ils_verbose " << ils_verbose << std::endl;
       std::cerr << "   ils_verbose " << ils_verbose << std::endl;
   }
   }
+
+  //quantization during classification?
+  bool useQuantization = _conf->gB ( _confSection, "use_quantization", false );
+
+  if ( this->b_verbose )
+  {
+    std::cerr << "_confSection: " << _confSection << std::endl;
+    std::cerr << "use_quantization: " << useQuantization << std::endl;
+  }
+
+  if ( _conf->gB ( _confSection, "use_quantization", false ) )
+  {
+    int numBins = _conf->gI ( _confSection, "num_bins", 100 );
+    if ( this->b_verbose )
+      std::cerr << "FMKGPHyperparameterOptimization: quantization initialized with " << numBins << " bins." << std::endl;
+
+
+    std::string s_quantType = _conf->gS( _confSection, "s_quantType", "1d-aequi-0-1" );
+
+    if ( s_quantType == "1d-aequi-0-1" )
+    {
+      this->q = new NICE::Quantization1DAequiDist0To1 ( numBins );
+    }
+    else if ( s_quantType == "1d-aequi-0-max" )
+    {
+      this->q = new NICE::Quantization1DAequiDist0ToMax ( numBins );
+    }
+    else if ( s_quantType == "nd-aequi-0-max" )
+    {
+      this->q = new NICE::QuantizationNDAequiDist0ToMax ( numBins );
+    }
+    else
+    {
+      fthrow(Exception, "Quantization type is unknown " << s_quantType);
+    }
+  }
+  else
+  {
+    this->q = NULL;
+  }
 }
 }
 
 
 ///////////////////// ///////////////////// /////////////////////
 ///////////////////// ///////////////////// /////////////////////
@@ -320,13 +423,16 @@ void GPHIKRawClassifier::train ( const std::vector< const NICE::SparseVector *>
   precomputedB.clear();
   precomputedB.clear();
   precomputedT.clear();
   precomputedT.clear();
 
 
+
   // sort examples in each dimension and "transpose" the feature matrix
   // sort examples in each dimension and "transpose" the feature matrix
   // set up the GenericMatrix interface
   // set up the GenericMatrix interface
   if (gm != NULL)
   if (gm != NULL)
     delete gm;
     delete gm;
 
 
-  gm = new GMHIKernelRaw ( _examples, this->d_noise );
-  nnz_per_dimension = gm->getNNZPerDimension();
+  gm = new GMHIKernelRaw ( _examples, this->d_noise, this->q );
+  this->nnz_per_dimension = gm->getNNZPerDimension();
+  this->num_dimension     = gm->getNumberOfDimensions();
+
 
 
   // compute largest eigenvalue of our kernel matrix
   // compute largest eigenvalue of our kernel matrix
   // note: this guy is shared among all categories,
   // note: this guy is shared among all categories,
@@ -383,6 +489,16 @@ void GPHIKRawClassifier::train ( const std::vector< const NICE::SparseVector *>
 
 
     precomputedA.insert ( pair<uint, PrecomputedType> ( classno, A ) );
     precomputedA.insert ( pair<uint, PrecomputedType> ( classno, A ) );
     precomputedB.insert ( pair<uint, PrecomputedType> ( classno, B ) );
     precomputedB.insert ( pair<uint, PrecomputedType> ( classno, B ) );
+
+    // Quantization for classification?
+    if ( this->q != NULL )
+    {
+      // (2) then compute the corresponding look-up table T
+        double **B = gm->getTableT();
+
+      double *T = this->computeTableT ( alpha );
+      precomputedT.insert( pair<uint, PrecomputedType> ( classno, T ) );
+    }
   }
   }
 
 
 
 
@@ -390,7 +506,6 @@ void GPHIKRawClassifier::train ( const std::vector< const NICE::SparseVector *>
   if ( this->b_verbose )
   if ( this->b_verbose )
     std::cerr << "Time used for setting up the fmk object: " << t.getLast() << std::endl;
     std::cerr << "Time used for setting up the fmk object: " << t.getLast() << std::endl;
 
 
-
   //indicate that we finished training successfully
   //indicate that we finished training successfully
   this->b_isTrained = true;
   this->b_isTrained = true;
 
 

+ 10 - 3
GPHIKRawClassifier.h

@@ -25,12 +25,12 @@
 namespace NICE {
 namespace NICE {
 
 
  /**
  /**
- * @class GPHIKClassifier
+ * @class GPHIKRawClassifier
  * @brief ...
  * @brief ...
- * @author Erik Rodner
+ * @author Erik Rodner, Alexander Freytag
  */
  */
 
 
-class GPHIKRawClassifier //: public NICE::Persistent
+class GPHIKRawClassifier
 {
 {
 
 
   protected:
   protected:
@@ -83,6 +83,7 @@ class GPHIKRawClassifier //: public NICE::Persistent
 
 
     uint *nnz_per_dimension;
     uint *nnz_per_dimension;
     uint num_examples;
     uint num_examples;
+    uint num_dimension;
 
 
     double f_tolerance;
     double f_tolerance;
 
 
@@ -96,6 +97,12 @@ class GPHIKRawClassifier //: public NICE::Persistent
     /////////////////////////
     /////////////////////////
 
 
 
 
+    /////////////////////////
+    /////////////////////////
+    //    PUBLIC METHODS   //
+    /////////////////////////
+    /////////////////////////
+
   public:
   public:
 
 
     /**
     /**

+ 3 - 1
quantization/Quantization.h

@@ -15,6 +15,7 @@
 
 
 // gp-hik-core includes
 // gp-hik-core includes
 #include "gp-hik-core/FeatureMatrixT.h"
 #include "gp-hik-core/FeatureMatrixT.h"
+#include "gp-hik-core/GMHIKernelRaw.h"
 
 
 namespace NICE {
 namespace NICE {
   
   
@@ -97,7 +98,8 @@ class Quantization  : public NICE::Persistent
                         
                         
                         
                         
   //FIXME should the argument _fm be templated?
   //FIXME should the argument _fm be templated?
-  virtual void computeParametersFromData ( const NICE::FeatureMatrix *  _fm ) = 0;                        
+  virtual void computeParametersFromData ( const NICE::FeatureMatrix *  _fm ) = 0;
+  virtual void computeParametersFromData ( const NICE::GMHIKernelRaw *  _gm ) = 0;
   
   
   ///////////////////// INTERFACE PERSISTENT /////////////////////
   ///////////////////// INTERFACE PERSISTENT /////////////////////
   // interface specific methods for store and restore
   // interface specific methods for store and restore

+ 5 - 0
quantization/Quantization1DAequiDist0To1.cpp

@@ -56,6 +56,11 @@ void Quantization1DAequiDist0To1::computeParametersFromData ( const NICE::Featur
 {
 {
   // nothing to do here...
   // nothing to do here...
 }
 }
+
+void Quantization1DAequiDist0To1::computeParametersFromData ( const NICE::GMHIKernelRaw *  _gm )
+{
+  // nothing to do here...
+}
 // ---------------------- STORE AND RESTORE FUNCTIONS ----------------------
 // ---------------------- STORE AND RESTORE FUNCTIONS ----------------------
 
 
 void Quantization1DAequiDist0To1::restore ( std::istream & _is, 
 void Quantization1DAequiDist0To1::restore ( std::istream & _is, 

+ 2 - 1
quantization/Quantization1DAequiDist0To1.h

@@ -77,7 +77,8 @@ class Quantization1DAequiDist0To1  : public NICE::Quantization
                           const uint & _dim = 0
                           const uint & _dim = 0
                         ) const;
                         ) const;
                         
                         
-  virtual void computeParametersFromData ( const NICE::FeatureMatrix *  _fm ) ;                        
+  virtual void computeParametersFromData ( const NICE::FeatureMatrix *  _fm ) ;
+  virtual void computeParametersFromData ( const NICE::GMHIKernelRaw *  _gm ) ;
   
   
   ///////////////////// INTERFACE PERSISTENT /////////////////////
   ///////////////////// INTERFACE PERSISTENT /////////////////////
   // interface specific methods for store and restore
   // interface specific methods for store and restore

+ 7 - 0
quantization/Quantization1DAequiDist0ToMax.cpp

@@ -64,6 +64,13 @@ void Quantization1DAequiDist0ToMax::computeParametersFromData ( const NICE::Feat
       this->v_upperBounds.resize ( 1 );
       this->v_upperBounds.resize ( 1 );
       this->v_upperBounds ( 0 ) = vmax;
       this->v_upperBounds ( 0 ) = vmax;
 }
 }
+
+void Quantization1DAequiDist0ToMax::computeParametersFromData ( const NICE::GMHIKernelRaw *  _gm )
+{
+      double vmax = ( _gm->getLargestValue( ) );
+      this->v_upperBounds.resize ( 1 );
+      this->v_upperBounds ( 0 ) = vmax;
+}
 // ---------------------- STORE AND RESTORE FUNCTIONS ----------------------
 // ---------------------- STORE AND RESTORE FUNCTIONS ----------------------
 
 
 void Quantization1DAequiDist0ToMax::restore ( std::istream & _is, 
 void Quantization1DAequiDist0ToMax::restore ( std::istream & _is, 

+ 1 - 0
quantization/Quantization1DAequiDist0ToMax.h

@@ -79,6 +79,7 @@ class Quantization1DAequiDist0ToMax  : public NICE::Quantization
                         
                         
                         
                         
   virtual void computeParametersFromData ( const NICE::FeatureMatrix *  _fm ) ;
   virtual void computeParametersFromData ( const NICE::FeatureMatrix *  _fm ) ;
+  virtual void computeParametersFromData ( const NICE::GMHIKernelRaw *  _gm ) ;
   
   
   ///////////////////// INTERFACE PERSISTENT /////////////////////
   ///////////////////// INTERFACE PERSISTENT /////////////////////
   // interface specific methods for store and restore
   // interface specific methods for store and restore

+ 8 - 0
quantization/QuantizationNDAequiDist0ToMax.cpp

@@ -60,6 +60,14 @@ void QuantizationNDAequiDist0ToMax::computeParametersFromData ( const NICE::Feat
   this->v_upperBounds = _fm->getLargestValuePerDimension( d_quantile );  
   this->v_upperBounds = _fm->getLargestValuePerDimension( d_quantile );  
 }
 }
 
 
+void QuantizationNDAequiDist0ToMax::computeParametersFromData ( const NICE::GMHIKernelRaw *  _gm )
+{
+  // 100% quantile...
+  double d_quantile ( 1.00 );
+  this->v_upperBounds = _gm->getLargestValuePerDimension( d_quantile );
+}
+
+
 // ---------------------- STORE AND RESTORE FUNCTIONS ----------------------
 // ---------------------- STORE AND RESTORE FUNCTIONS ----------------------
 
 
 void QuantizationNDAequiDist0ToMax::restore ( std::istream & _is, 
 void QuantizationNDAequiDist0ToMax::restore ( std::istream & _is, 

+ 1 - 0
quantization/QuantizationNDAequiDist0ToMax.h

@@ -79,6 +79,7 @@ class QuantizationNDAequiDist0ToMax  : public NICE::Quantization
                         
                         
                         
                         
   virtual void computeParametersFromData ( const NICE::FeatureMatrix *  _fm ) ;
   virtual void computeParametersFromData ( const NICE::FeatureMatrix *  _fm ) ;
+  virtual void computeParametersFromData ( const NICE::GMHIKernelRaw *  _gm ) ;
                           
                           
   ///////////////////// INTERFACE PERSISTENT /////////////////////
   ///////////////////// INTERFACE PERSISTENT /////////////////////
   // interface specific methods for store and restore
   // interface specific methods for store and restore