Sfoglia il codice sorgente

bugfix and cleanup

Erik Rodner 9 anni fa
parent
commit
89b710e6da
3 ha cambiato i file con 90 aggiunte e 77 eliminazioni
  1. 71 71
      FastMinKernel.cpp
  2. 5 4
      GMHIKernelRaw.cpp
  3. 14 2
      tests/TestFastHIK.cpp

+ 71 - 71
FastMinKernel.cpp

@@ -195,8 +195,6 @@ void FastMinKernel::hik_prepare_alpha_multiplications(const NICE::Vector & _alph
     _B[i].resize( numNonZero  );
   }
 
-  //  for more information see hik_prepare_alpha_multiplications
-
   for (uint dim = 0; dim < this->ui_d; dim++)
   {
     double alpha_sum(0.0);
@@ -230,7 +228,7 @@ void FastMinKernel::hik_prepare_alpha_multiplications(const NICE::Vector & _alph
 double *FastMinKernel::hik_prepare_alpha_multiplications_fast(const NICE::VVector & _A,
                                                               const NICE::VVector & _B,
                                                               const Quantization * _q,
-                                                              const ParameterizedFunction *_pf 
+                                                              const ParameterizedFunction *_pf
                                                              ) const
 {
   //NOTE keep in mind: for doing this, we already have precomputed A and B using hik_prepare_alpha_multiplications!
@@ -242,7 +240,7 @@ double *FastMinKernel::hik_prepare_alpha_multiplications_fast(const NICE::VVecto
   double * prototypes   = new double [ hmax * this->ui_d ];
   double * p_prototypes = prototypes;
 
-  for (uint dim = 0; dim < this->ui_d; dim++)  
+  for (uint dim = 0; dim < this->ui_d; dim++)
   {
     for ( uint i = 0 ; i < hmax ; i++ )
     {
@@ -253,11 +251,11 @@ double *FastMinKernel::hik_prepare_alpha_multiplications_fast(const NICE::VVecto
       {
         *p_prototypes = _q->getPrototype( i, dim );
       }
-      
+
       p_prototypes++;
     }
-  } 
-  
+  }
+
   // creating the lookup table as pure C, which might be beneficial
   // for fast evaluation
   double *Tlookup = new double [ hmax * this->ui_d ];
@@ -281,7 +279,7 @@ double *FastMinKernel::hik_prepare_alpha_multiplications_fast(const NICE::VVecto
     uint index = 0;
     // we use the quantization of the original features! the transformed feature were
     // already used to calculate A and B, this of course assumes monotonic functions!!!
-    uint qBin = _q->quantize ( i->first, dim ); 
+    uint qBin = _q->quantize ( i->first, dim );
 
     // the next loop is linear in max(hmax, n)
     // REMARK: this could be changed to hmax*log(n), when
@@ -331,9 +329,9 @@ double *FastMinKernel::hik_prepare_alpha_multiplications_fast(const NICE::VVecto
   return Tlookup;
 }
 
-double *FastMinKernel::hikPrepareLookupTable(const NICE::Vector & _alpha, 
-                                             const Quantization * _q, 
-                                             const ParameterizedFunction *_pf 
+double *FastMinKernel::hikPrepareLookupTable(const NICE::Vector & _alpha,
+                                             const Quantization * _q,
+                                             const ParameterizedFunction *_pf
                                             ) const
 {
   // number of quantization bins
@@ -343,7 +341,7 @@ double *FastMinKernel::hikPrepareLookupTable(const NICE::Vector & _alpha,
   double * prototypes   = new double [ hmax * this->ui_d ];
   double * p_prototypes = prototypes;
 
-  for (uint dim = 0; dim < this->ui_d; dim++)  
+  for (uint dim = 0; dim < this->ui_d; dim++)
   {
     for ( uint i = 0 ; i < hmax ; i++ )
     {
@@ -354,7 +352,7 @@ double *FastMinKernel::hikPrepareLookupTable(const NICE::Vector & _alpha,
       {
         *p_prototypes = _q->getPrototype( i, dim );
       }
-      
+
       p_prototypes++;
     }
   }
@@ -388,8 +386,8 @@ double *FastMinKernel::hikPrepareLookupTable(const NICE::Vector & _alpha,
     uint index = 0;
 
     // we use the quantization of the original features! Nevetheless, the resulting lookupTable is computed using the transformed ones
-    uint qBin = _q->quantize ( i->first, dim ); 
-    
+    uint qBin = _q->quantize ( i->first, dim );
+
     double alpha_sum(0.0);
     double alpha_times_x_sum(0.0);
     double alpha_sum_prev(0.0);
@@ -447,12 +445,12 @@ double *FastMinKernel::hikPrepareLookupTable(const NICE::Vector & _alpha,
 }
 
 
-void FastMinKernel::hikUpdateLookupTable(double * _T, 
-                                         const double & _alphaNew, 
-                                         const double & _alphaOld, 
-                                         const uint & _idx, 
-                                         const Quantization * _q, 
-                                         const ParameterizedFunction *_pf 
+void FastMinKernel::hikUpdateLookupTable(double * _T,
+                                         const double & _alphaNew,
+                                         const double & _alphaOld,
+                                         const uint & _idx,
+                                         const Quantization * _q,
+                                         const ParameterizedFunction *_pf
                                         ) const
 {
 
@@ -469,7 +467,7 @@ void FastMinKernel::hikUpdateLookupTable(double * _T,
   double * prototypes   = new double [ hmax * this->ui_d ];
   double * p_prototypes = prototypes;
 
-  for (uint dim = 0; dim < this->ui_d; dim++)  
+  for (uint dim = 0; dim < this->ui_d; dim++)
   {
     for ( uint i = 0 ; i < hmax ; i++ )
     {
@@ -480,11 +478,11 @@ void FastMinKernel::hikUpdateLookupTable(double * _T,
       {
         *p_prototypes = _q->getPrototype( i, dim );
       }
-      
+
       p_prototypes++;
     }
   }
-  
+
   double diffOfAlpha(_alphaNew - _alphaOld);
 
   // loop through all dimensions
@@ -501,7 +499,7 @@ void FastMinKernel::hikUpdateLookupTable(double * _T,
     {
         double fval;
         uint q_bin = _q->quantize( x_i, dim );
-        
+
         if ( q_bin > j )
           fval = prototypes[ dim*hmax + j ];
         else
@@ -583,9 +581,9 @@ void FastMinKernel::hik_kernel_multiply(const NICE::VVector & _A,
   }
 }
 
-void FastMinKernel::hik_kernel_multiply_fast(const double *_Tlookup, 
-                                             const Quantization * _q, 
-                                             const NICE::Vector & _alpha, 
+void FastMinKernel::hik_kernel_multiply_fast(const double *_Tlookup,
+                                             const Quantization * _q,
+                                             const NICE::Vector & _alpha,
                                              NICE::Vector & _beta) const
 {
   _beta.resize( this->ui_n );
@@ -760,9 +758,9 @@ void FastMinKernel::hik_kernel_sum(const NICE::VVector & _A,
   }
 }
 
-void FastMinKernel::hik_kernel_sum_fast(const double *_Tlookup, 
-                                        const Quantization * _q, 
-                                        const NICE::Vector & _xstar, 
+void FastMinKernel::hik_kernel_sum_fast(const double *_Tlookup,
+                                        const Quantization * _q,
+                                        const NICE::Vector & _xstar,
                                         double & _beta
                                        ) const
 {
@@ -778,14 +776,14 @@ void FastMinKernel::hik_kernel_sum_fast(const double *_Tlookup,
   {
     double v = _xstar[dim];
     uint qBin = _q->quantize( v, dim );
-    
+
     _beta += _Tlookup[dim*_q->getNumberOfBins() + qBin];
   }
 }
 
-void FastMinKernel::hik_kernel_sum_fast(const double *_Tlookup, 
-                                        const Quantization * _q, 
-                                        const NICE::SparseVector & _xstar, 
+void FastMinKernel::hik_kernel_sum_fast(const double *_Tlookup,
+                                        const Quantization * _q,
+                                        const NICE::SparseVector & _xstar,
                                         double & _beta
                                        ) const
 {
@@ -799,19 +797,19 @@ void FastMinKernel::hik_kernel_sum_fast(const double *_Tlookup,
     uint dim = i->first;
     double v = i->second;
     uint qBin = _q->quantize( v, dim );
-    
+
     _beta += _Tlookup[dim*_q->getNumberOfBins() + qBin];
   }
 }
 
 double *FastMinKernel::solveLin(const NICE::Vector & _y,
                                 NICE::Vector & _alpha,
-                                const Quantization * _q, 
-                                const ParameterizedFunction *_pf, 
-                                const bool & _useRandomSubsets, 
-                                uint _maxIterations, 
-                                const uint & _sizeOfRandomSubset, 
-                                double _minDelta, 
+                                const Quantization * _q,
+                                const ParameterizedFunction *_pf,
+                                const bool & _useRandomSubsets,
+                                uint _maxIterations,
+                                const uint & _sizeOfRandomSubset,
+                                double _minDelta,
                                 bool _timeAnalysis
                                ) const
 {
@@ -826,7 +824,7 @@ double *FastMinKernel::solveLin(const NICE::Vector & _y,
 
   // number of quantization bins
   uint hmax = _q->getNumberOfBins();
-  
+
   NICE::Vector diagonalElements(_y.size(),0.0);
   this->X_sorted.hikDiagonalElements(diagonalElements);
   diagonalElements += this->d_noise;
@@ -867,11 +865,13 @@ double *FastMinKernel::solveLin(const NICE::Vector & _y,
 
     if (sizeOfRandomSubset <= 0)
       sizeOfRandomSubset = _y.size();
+    if (sizeOfRandomSubset > _y.size())
+      sizeOfRandomSubset = _y.size();
 
     for ( iter = 1; iter <= _maxIterations; iter++ )
     {
       NICE::Vector perm;
-      this->randomPermutation( perm, indices, _sizeOfRandomSubset );
+      this->randomPermutation( perm, indices, sizeOfRandomSubset );
 
       if ( _timeAnalysis )
       {
@@ -890,7 +890,7 @@ double *FastMinKernel::solveLin(const NICE::Vector & _y,
 
       for ( uint i = 0; i < sizeOfRandomSubset; i++)
       {
-
+        cerr << i << " " << sizeOfRandomSubset << " " << perm.size() << " " << _y.size() << " " << _alpha.size() << endl;
         pseudoResidual(perm[i]) = -_y(perm[i]) + (this->d_noise * _alpha(perm[i]));
         for (uint j = 0; j < this->ui_d; j++)
         {
@@ -1151,8 +1151,8 @@ void FastMinKernel::hikPrepareKVNApproximation(NICE::VVector & _A) const
   }
 }
 
-double * FastMinKernel::hikPrepareKVNApproximationFast(NICE::VVector & _A, 
-                                                       const Quantization * _q, 
+double * FastMinKernel::hikPrepareKVNApproximationFast(NICE::VVector & _A,
+                                                       const Quantization * _q,
                                                        const ParameterizedFunction *_pf ) const
 {
   //NOTE keep in mind: for doing this, we already have precomputed A using hikPrepareSquaredKernelVector!
@@ -1163,8 +1163,8 @@ double * FastMinKernel::hikPrepareKVNApproximationFast(NICE::VVector & _A,
   // store (transformed) prototypes
   double *prototypes = new double [ hmax * this->ui_d ];
   double * p_prototypes = prototypes;
-  
-  for (uint dim = 0; dim < this->ui_d; dim++)  
+
+  for (uint dim = 0; dim < this->ui_d; dim++)
   {
     for ( uint i = 0 ; i < hmax ; i++ )
     {
@@ -1175,7 +1175,7 @@ double * FastMinKernel::hikPrepareKVNApproximationFast(NICE::VVector & _A,
       {
         *p_prototypes = _q->getPrototype( i, dim );
       }
-      
+
       p_prototypes++;
     }
   }
@@ -1201,7 +1201,7 @@ double * FastMinKernel::hikPrepareKVNApproximationFast(NICE::VVector & _A,
     uint index = 0;
     // we use the quantization of the original features! the transformed feature were
     // already used to calculate A and B, this of course assumes monotonic functions!!!
-    uint qBin = _q->quantize ( i->first, dim ); 
+    uint qBin = _q->quantize ( i->first, dim );
 
     // the next loop is linear in max(hmax, n)
     // REMARK: this could be changed to hmax*log(n), when
@@ -1238,7 +1238,7 @@ double * FastMinKernel::hikPrepareKVNApproximationFast(NICE::VVector & _A,
           t = _A[dim][index];
         } else {
           // standard case
-          t =  _A[dim][index-1] + pow( fval, 2 ) * (this->ui_n-nrZeroIndices-(index) );          
+          t =  _A[dim][index-1] + pow( fval, 2 ) * (this->ui_n-nrZeroIndices-(index) );
         }
       }
 
@@ -1252,7 +1252,7 @@ double * FastMinKernel::hikPrepareKVNApproximationFast(NICE::VVector & _A,
 }
 
 double* FastMinKernel::hikPrepareLookupTableForKVNApproximation(const Quantization * _q,
-                                                                const ParameterizedFunction *_pf 
+                                                                const ParameterizedFunction *_pf
                                                                ) const
 {
   // number of quantization bins
@@ -1262,7 +1262,7 @@ double* FastMinKernel::hikPrepareLookupTableForKVNApproximation(const Quantizati
   double *prototypes = new double [ hmax * this->ui_d ];
   double * p_prototypes = prototypes;
 
-  for (uint dim = 0; dim < this->ui_d; dim++)  
+  for (uint dim = 0; dim < this->ui_d; dim++)
   {
     for ( uint i = 0 ; i < hmax ; i++ )
     {
@@ -1273,10 +1273,10 @@ double* FastMinKernel::hikPrepareLookupTableForKVNApproximation(const Quantizati
       {
         *p_prototypes = _q->getPrototype( i, dim );
       }
-      
+
       p_prototypes++;
     }
-  }    
+  }
 
   // creating the lookup table as pure C, which might be beneficial
   // for fast evaluation
@@ -1298,7 +1298,7 @@ double* FastMinKernel::hikPrepareLookupTableForKVNApproximation(const Quantizati
     uint index = 0;
 
     // we use the quantization of the original features! Nevetheless, the resulting lookupTable is computed using the transformed ones
-    uint qBin = _q->quantize ( i->first, dim ); 
+    uint qBin = _q->quantize ( i->first, dim );
 
     double sum(0.0);
 
@@ -1409,9 +1409,9 @@ void FastMinKernel::hikComputeKVNApproximation(const NICE::VVector & _A,
   }
 }
 
-void FastMinKernel::hikComputeKVNApproximationFast(const double *_Tlookup, 
-                                                   const Quantization * _q, 
-                                                   const NICE::SparseVector & _xstar, 
+void FastMinKernel::hikComputeKVNApproximationFast(const double *_Tlookup,
+                                                   const Quantization * _q,
+                                                   const NICE::SparseVector & _xstar,
                                                    double & _norm
                                                   ) const
 {
@@ -1421,12 +1421,12 @@ void FastMinKernel::hikComputeKVNApproximationFast(const double *_Tlookup,
   {
     uint dim = i->first;
     double v = i->second;
-    // we do not need a parameterized function here, since the quantizer works on the original feature values. 
-    // nonetheless, the lookup table was created using the parameterized function    
+    // we do not need a parameterized function here, since the quantizer works on the original feature values.
+    // nonetheless, the lookup table was created using the parameterized function
     uint qBin = _q->quantize( v, dim );
-    
+
     _norm += _Tlookup[dim*_q->getNumberOfBins() + qBin];
-  }  
+  }
 }
 
 void FastMinKernel::hikComputeKernelVector ( const NICE::SparseVector& _xstar,
@@ -1552,9 +1552,9 @@ void FastMinKernel::hikComputeKVNApproximation(const NICE::VVector & _A,
   }
 }
 
-void FastMinKernel::hikComputeKVNApproximationFast(const double *_Tlookup, 
-                                                   const Quantization * _q, 
-                                                   const NICE::Vector & _xstar, 
+void FastMinKernel::hikComputeKVNApproximationFast(const double *_Tlookup,
+                                                   const Quantization * _q,
+                                                   const NICE::Vector & _xstar,
                                                    double & _norm
                                                   ) const
 {
@@ -1564,12 +1564,12 @@ void FastMinKernel::hikComputeKVNApproximationFast(const double *_Tlookup,
   for ( NICE::Vector::const_iterator i = _xstar.begin(); i != _xstar.end(); i++, dim++ )
   {
     double v = *i;
-    // we do not need a parameterized function here, since the quantizer works on the original feature values. 
-    // nonetheless, the lookup table was created using the parameterized function    
+    // we do not need a parameterized function here, since the quantizer works on the original feature values.
+    // nonetheless, the lookup table was created using the parameterized function
     uint qBin = _q->quantize( v, dim );
-    
+
     _norm += _Tlookup[dim*_q->getNumberOfBins() + qBin];
-  }  
+  }
 }
 
 

+ 5 - 4
GMHIKernelRaw.cpp

@@ -100,6 +100,8 @@ void GMHIKernelRaw::initData ( const std::vector< const NICE::SparseVector *> &_
         }
     }
 
+    delete [] examples_raw_increment;
+
     // sort along each dimension
     for (uint d = 0; d < this->num_dimension; d++)
     {
@@ -180,7 +182,6 @@ void GMHIKernelRaw::multiply (NICE::Vector & _y, const NICE::Vector & _x) const
 
       alpha_sum += _x[index];
       this->table_B[dim][cntNonzeroFeat] = alpha_sum;
-      cntNonzeroFeat++;
     }
   }
 
@@ -204,10 +205,10 @@ void GMHIKernelRaw::multiply (NICE::Vector & _y, const NICE::Vector & _x) const
       uint inversePosition = cntNonzeroFeat;
       double fval = training_values_in_dim->value;
 
-      double firstPart( this->table_A[dim][inversePosition] );
-      double secondPart( this->table_B[dim][this->num_examples-1-nz] - this->table_B[dim][inversePosition]);
+      double firstPart = this->table_A[dim][inversePosition];
+      double secondPart = this->table_B[dim][nnz-1] - this->table_B[dim][inversePosition];
 
-      _y[cntNonzeroFeat] += firstPart + fval * secondPart;
+      _y[feat] += firstPart + fval * secondPart;
     }
   }
 

+ 14 - 2
tests/TestFastHIK.cpp

@@ -24,8 +24,8 @@ const bool b_debug = true;
 const bool verbose = true;
 const bool verboseStartEnd = true;
 const bool solveLinWithoutRand = false;
-const uint n = 500;//1500;//1500;//10;
-const uint d = 200;//200;//2;
+const uint n = 10;//1500;//1500;//10;
+const uint d = 3;//200;//2;
 const uint numBins = 11;//1001;//1001;
 const uint solveLinMaxIterations = 1000;
 const double sparse_prob = 0.6;
@@ -115,6 +115,12 @@ void TestFastHIK::testKernelMultiplication()
       }
   }
 
+  if ( b_debug ) {
+    cerr << "data matrix: " << endl;
+    printMatrix ( dataMatrix );
+    cerr << endl;
+  }
+
   double noise = 1.0;
   NICE::Timer t;
   t.start();
@@ -217,6 +223,7 @@ void TestFastHIK::testKernelMultiplication()
   NICE::Matrix gK ( ghikSlow.computeKernelMatrix(dataMatrix_transposed, noise) );
   ParameterizedFunction *pf = new PFAbsExp( 1.2 );
   fmk.applyFunctionToFeatureMatrix( pf );
+
 //   pf->applyFunctionToFeatureMatrix ( fmk.featureMatrix() );
 
   Vector galpha;
@@ -227,6 +234,8 @@ void TestFastHIK::testKernelMultiplication()
   CPPUNIT_ASSERT_DOUBLES_EQUAL((galpha-galpha_slow).normL1(), 0.0, 1e-8);
   if (verboseStartEnd)
     std::cerr << "================== TestFastHIK::testKernelMultiplication done ===================== " << std::endl;
+
+  delete pf;
 }
 
 void TestFastHIK::testKernelMultiplicationFast()
@@ -273,6 +282,7 @@ void TestFastHIK::testKernelMultiplicationFast()
   ParameterizedFunction *pf = new PFAbsExp ( 1.0 );
   GMHIKernel gmkFast ( &fmk, pf, q );
 
+
 //   pf.applyFunctionToFeatureMatrix ( fmk.featureMatrix() );
 
   Vector alpha;
@@ -329,6 +339,8 @@ void TestFastHIK::testKernelMultiplicationFast()
   CPPUNIT_ASSERT_DOUBLES_EQUAL((galphaFast-galpha_slow).normL1(), 0.0, 1e-8);
   if (verboseStartEnd)
     std::cerr << "================== TestFastHIK::testKernelMultiplicationFast done ===================== " << std::endl;
+
+  delete pf;
 }