iRoCS Toolbox  1.1.0
Kernel_SCALE.hh
Go to the documentation of this file.
1 /**************************************************************************
2  *
3  * Copyright (C) 2004-2015 Olaf Ronneberger, Florian Pigorsch, Jörg Mechnich,
4  * Thorsten Falk
5  *
6  * Image Analysis Lab, University of Freiburg, Germany
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  **************************************************************************/
23 
24 /**************************************************************************
25 ** Title: kernel wrapper that scales the features
26 ** $RCSfile$
27 ** $Revision: 4820 $$Name$
28 ** $Date: 2011-11-08 10:57:01 +0100 (Tue, 08 Nov 2011) $
29 ** Copyright: GPL $Author: tschmidt $
30 ** Description:
31 **
32 **
33 **
34 **-------------------------------------------------------------------------
35 **
36 ** $Log$
37 ** Revision 1.10 2005/07/19 13:03:59 haasdonk
38 ** removed redundant cout-messages, erroneous filename and added a new function
39 ** for computing a training-kernel matrix in BasicSVMAdapter*
40 **
41 ** Revision 1.9 2005/06/24 07:23:55 fehr
42 ** removed static for thread-safety
43 **
44 ** Revision 1.8 2005/06/06 21:23:31 haasdonk
45 ** added updateCache() with two FV-lists, required for classification with precomputed kernel-matrices
46 **
47 ** Revision 1.7 2005/03/29 17:56:53 ronneber
48 ** - added clearCache()
49 **
50 ** Revision 1.6 2005/02/11 09:26:53 ronneber
51 ** - fixed stupid bug in k_function() when chache is no up to date
52 **
53 ** Revision 1.5 2004/10/11 17:04:55 ronneber
54 ** added missing include
55 **
56 ** Revision 1.4 2004/09/13 10:12:08 ronneber
57 ** - corrected some typos in svt_check Macros
58 **
59 ** Revision 1.3 2004/09/13 10:04:04 ronneber
60 ** - documentation update
61 **
62 ** Revision 1.2 2004/09/08 14:30:22 ronneber
63 ** - adapted to new ParamInfo class
64 **
65 ** Revision 1.1 2004/09/03 07:11:20 ronneber
66 ** inisital revison
67 **
68 **
69 **
70 **************************************************************************/
71 
72 #ifndef KERNEL_SCALE_HH
73 #define KERNEL_SCALE_HH
74 
75 #ifdef HAVE_CONFIG_H
76 #include <config.hh>
77 #endif
78 
79 // std includes
80 #include <map>
81 #include <set>
82 #include <string>
83 #include <vector>
84 
85 // libsvmtl includes
86 #include "svm_defines.hh"
87 #include "SVMError.hh"
88 #include "ProgressReporter.hh"
89 
90 // requirements of template parameters
97 
98 namespace svt
99 {
100 
101  /*-----------------------------------------------------------------------
102  * Error classes for Kernel_SCALE
103  *-----------------------------------------------------------------------*/
104  class UnknownScaleAlgorithm : public SVMError {};
106 
107  /*======================================================================*/
130  /*======================================================================*/
131  template< typename KERNEL>
133  {
136 
137  public:
139  :_cacheIsUpToDate(false)
140  {}
141 
142 
143  Kernel_SCALE( const KERNEL& kernel)
144  : _kernel(kernel),
145  _cacheIsUpToDate(false)
146  {}
147 
148  /*======================================================================*/
155  /*======================================================================*/
156  void setAlgorithm( const std::string& algorithm)
157  {
158  _algorithm = algorithm;
159  }
160 
161  /*======================================================================*/
167  /*======================================================================*/
168  const std::string& algorithm() const
169  {
170  return _algorithm;
171  }
172 
173  /*======================================================================*/
190  /*======================================================================*/
191  template< typename ForwardIter, typename Accessor>
192  void calcScaleAndOffset( const ForwardIter& fvBegin,
193  const ForwardIter& fvEnd,
194  Accessor accessor) const;
195 
196 
197  /*======================================================================*/
207  /*======================================================================*/
208  template< typename FV_IN, typename FV_OUT>
209  void scaleSingleFV( const FV_IN& fvIn, FV_OUT& fvOut) const
210  {
211  for( unsigned int i = 0; i < fvIn.size(); ++i)
212  {
213  fvOut[i] = (fvIn[i] + _offset[i]) * _scaleFactor[i];
214  }
215  }
216 
217 
218  /*======================================================================*/
239  /*======================================================================*/
240  template< typename ForwardIter, typename Accessor>
241  void updateCache( const ForwardIter& fvBegin,
242  const ForwardIter& fvEnd,
243  Accessor accessor,
244  ProgressReporter* pr = 0) const;
245 
246  // new updateCache-Syntax:
247  template< typename ForwardIter1, typename Accessor1,
248  typename ForwardIter2, typename Accessor2 >
249  void updateCache( const ForwardIter1& /*fvBegin1*/,
250  const ForwardIter1& /*fvEnd1*/,
251  Accessor1 /*accessor1*/,
252  const ForwardIter2& /*fvBegin2*/,
253  const ForwardIter2& /*fvEnd2*/,
254  Accessor2 /*accessor2*/,
255  ProgressReporter* /*pr*/ = NULL) const
256  {
257  // nothing to be done or can be implemented later
258  }
259 
260  void clearCache() const
261  {
262  _scaledFVsByUID.clear();
263  _cacheIsUpToDate = false;
264 
265  /*--------------------------------------------------------------
266  * clear cache of underlying kernel
267  *--------------------------------------------------------------*/
268  _kernel.clearCache();
269  }
270 
271 
272 
273  /*======================================================================*/
287  /*======================================================================*/
288  template< typename FV>
289  double k_function( const FV& x, const FV& y) const
290  {
293  if( _cacheIsUpToDate == false)
294  {
295  if( x.size() != nComponents() || y.size() != nComponents())
296  {
298  err << "number of scale factors (" << nComponents()
299  << ") and number of feature vectors components ("
300  << x.size() << ") don't match. "
301  "Maybe you forgot to specify the scale_algorithm?";
302 
303  throw err;
304  }
305 
306  BasicFV xScaled;
307  BasicFV yScaled;
308  xScaled.resize( x.size());
309  yScaled.resize( y.size());
310  scaleSingleFV( x, xScaled);
311  scaleSingleFV( y, yScaled);
312  xScaled.setUniqueID( x.uniqueID());
313  yScaled.setUniqueID( y.uniqueID());
314  return _kernel.k_function( xScaled, yScaled);
315  }
316 
317  unsigned int xUid = x.uniqueID();
318  unsigned int yUid = y.uniqueID();
319 
320  SVM_ASSERT( xUid < _scaledFVsByUID.size());
321  SVM_ASSERT( yUid < _scaledFVsByUID.size());
322 
323  return _kernel.k_function( _scaledFVsByUID[xUid],
324  _scaledFVsByUID[yUid]);
325  }
326 
327 
328  /*======================================================================*/
334  /*======================================================================*/
335  unsigned int nComponents() const
336  {
337  return static_cast<unsigned int>(_scaleFactor.size());
338  }
339 
340 
341 
342  /*======================================================================*/
348  /*======================================================================*/
349  double scaleFactor( unsigned int index) const
350  {
351  return _scaleFactor[ index];
352  }
353 
354 
355  /*======================================================================*/
361  /*======================================================================*/
362  double offset( unsigned int index) const
363  {
364  return _offset[ index];
365  }
366 
367  template<typename STDATA>
368  void loadParameters( STDATA& stData)
369  {
371  if( stData.valueExists( "scale_factor"))
372  {
373  _scaleFactor.resize( stData.getArraySize( "scale_factor"));
374  stData.getArray( "scale_factor", _scaleFactor.begin(),
375  static_cast<int>(_scaleFactor.size()));
376  _offset.resize( stData.getArraySize( "scale_offset"));
377  stData.getArray( "scale_offset", _offset.begin(),
378  static_cast<int>(_offset.size()));
379  if( _scaleFactor.size() != _offset.size())
380  {
381  LoadError err;
382  err << "sizes of 'scale_factor' array ("
383  << _scaleFactor.size() << ") and 'scale_offset' "
384  "array (" << _offset.size() << ") mismatch.";
385  throw err;
386  }
387  }
388  stData.getValue( "scale_algorithm", _algorithm);
389  _kernel.loadParameters( stData);
390  }
391 
392  /*======================================================================*/
406  /*======================================================================*/
407  template<typename STDATA>
408  void saveParameters( STDATA& stData) const
409  {
411  _kernel.saveParameters( stData);
412  if( _algorithm != "")
413  {
414  stData.setValue( "scale_used_algorithm", _algorithm);
415  }
416  if( _scaleFactor.size() != 0)
417  {
418  stData.setArray( "scale_factor", _scaleFactor.begin(),
419  _scaleFactor.size());
420  stData.setArray( "scale_offset", _offset.begin(),
421  _offset.size());
422  }
423 
424 
425  }
426 
427  static std::string name()
428  {
429  return std::string( "scaled_") + KERNEL::name();
430  }
431 
432  static std::string description()
433  {
434  return std::string( "scaled feature vectors passed to ") + KERNEL::description();
435  }
436 
437  /*======================================================================*/
446  /*======================================================================*/
447  static void getParamInfos( std::vector<ParamInfo>& p)
448  {
449  KERNEL::getParamInfos( p);
450  p.push_back(
451  ParamInfo( "scale_algorithm", "sa"));
452  p.back().addAlternative( "minmax",
453  "scale each feature that min becomes -1 "
454  "and max becomes +1");
455  p.back().addAlternative( "stddev",
456  "scale each feature that mean becomes 0 "
457  "and standard deviation becomes 1");
458  p.push_back(
459  ParamInfo( "scale_factor", "sf", "array",
460  "array containing scale factors for each "
461  "feature -- usually you don't want to specify "
462  "this manually"));
463  p.push_back(
464  ParamInfo( "scale_offset", "so", "array",
465  "array containing offsets for each feature "
466  "-- usually you don't want to specify this "
467  "manually"));
468  }
469 
470  private:
471  KERNEL _kernel;
472  std::string _algorithm;
473  mutable std::vector<double> _offset;
474  mutable std::vector<double> _scaleFactor;
475  mutable bool _cacheIsUpToDate;
476  mutable std::vector<BasicFV> _scaledFVsByUID;
477 
478  };
479 
480 }
481 
482 #include "Kernel_SCALE.icc"
483 
484 #endif
void saveParameters(STDATA &stData) const
save scale_factor and scale_offset.
#define CHECK_MEMBER_TEMPLATE(c)
unsigned int nComponents() const
number of components (features) in scale factor and offset
#define CHECK_CLASS_TEMPLATE3(c)
const std::string & algorithm() const
return selected algorithm (default is "")
#define SVM_ASSERT(condition)
Definition: SVMError.hh:176
void loadParameters(STDATA &stData)
void setAlgorithm(const std::string &algorithm)
set algorithm for data scaling
void clearCache() const
double offset(unsigned int index) const
return offset for the nth component of the feature vector
void scaleSingleFV(const FV_IN &fvIn, FV_OUT &fvOut) const
scale single feature vector with internal offset and scale factor.
#define CHECK_CLASS_TEMPLATE2(c)
void resize(size_type newSize)
Definition: BasicFV.hh:267
void updateCache(const ForwardIter1 &, const ForwardIter1 &, Accessor1, const ForwardIter2 &, const ForwardIter2 &, Accessor2, ProgressReporter *=NULL) const
Ensure that TESTCLASS provides a loadParameters() and saveParamters() method.
The SVMError class is the parent class for all errors that are thrown by the LIBSVMTL.
Definition: SVMError.hh:90
void setUniqueID(unsigned int uid)
Definition: BasicFV.hh:199
Kernel_SCALE(const KERNEL &kernel)
double k_function(const FV &x, const FV &y) const
kernel function.
static void getParamInfos(std::vector< ParamInfo > &p)
get information about the parameters, that are used in loadParameters() and saveParameters().
The Kernel_SCALE class provides a wrapper for other kernel classes , that scales the feature vectors...
static std::string name()
double scaleFactor(unsigned int index) const
return scale factor for the nth component of the feature vector
#define CHECK_MEMBER_TEMPLATE_2PARAM(c1, c2)
static std::string description()
The ParamInfo class contains informations about one parameter like key, help text, guiHints etc.
Definition: ParamInfo.hh:82