iRoCS Toolbox  1.1.0
Solver.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: Optimizer / Solver
26 ** $RCSfile$
27 ** $Revision: 476 $$Name$
28 ** $Date: 2004-08-26 10:36:59 +0200 (Thu, 26 Aug 2004) $
29 ** Copyright: LGPL $Author: ronneber $
30 ** Description:
31 **
32 **
33 **
34 **-------------------------------------------------------------------------
35 **
36 ** $Log$
37 ** Revision 1.1 2004/08/26 08:36:59 ronneber
38 ** initital import
39 **
40 ** Revision 1.4 2003/05/19 11:20:56 ronneber
41 ** - moved SolutionInfo struct to own class
42 **
43 ** Revision 1.3 2002/05/08 15:03:23 ronneber
44 ** - calculate_rho now writes its results to the passed SolutionInfo
45 ** struct (to get rid of the errornous private copy of si in SolverNu)
46 **
47 ** Revision 1.2 2002/05/08 10:36:11 ronneber
48 ** - added some debugging stuff
49 **
50 ** Revision 1.1 2002/03/26 12:44:02 ronneber
51 ** restructured for autoconf
52 **
53 ** Revision 1.5 2002/03/13 13:58:52 pigorsch
54 ** * put sources in Solver.icc
55 ** * added comments
56 **
57 ** Revision 1.4 2002/03/11 17:15:47 mechnich
58 ** modified some expressions to increase standard conformity (for compilation under Win32)
59 **
60 ** Revision 1.3 2002/01/31 10:55:30 pigorsch
61 ** * made some functions virtual
62 **
63 ** Revision 1.2 2001/12/17 13:18:30 pigorsch
64 ** *** empty log message ***
65 **
66 ** Revision 1.1 2001/12/11 11:03:00 pigorsch
67 ** Initial Revision
68 **
69 **
70 **
71 **************************************************************************/
72 
73 #ifndef SOLVER_HH
74 #define SOLVER_HH
75 
76 #ifdef HAVE_CONFIG_H
77 #include <config.hh>
78 #endif
79 
80 #include <algorithm>
81 #include <vector>
82 #include <iostream>
83 #include <cmath>
84 
85 #include "svm_defines.hh"
86 #include "SolutionInfo.hh"
87 #include "Kernel.hh"
88 #include "ProgressReporter.hh"
89 
90 
91 namespace svt
92 {
93  // Generalized SMO+SVMlight algorithm
94  // Solves:
95  //
96  // min 0.5(\alpha^T Q \alpha) + b^T \alpha
97  //
98  // y^T \alpha = \delta
99  // y_i = +1 or -1
100  // 0 <= alpha_i <= Cp for y_i = 1
101  // 0 <= alpha_i <= Cn for y_i = -1
102  //
103  // Given:
104  //
105  // Q, b, y, Cp, Cn, and an initial feasible point \alpha
106  // l is the size of vectors and matrices
107  // eps is the stopping criterion
108  //
109  // solution will be put in \alpha, objective value will be put in obj
110  //
111  template< typename FV, typename KF>
112  class Solver
113  {
114  public:
115  Solver() {};
116  virtual ~Solver() {};
117 
118  private:
119  // forbid copying
120  Solver( const Solver<FV,KF>& orig) {}
121  void operator=( const Solver<FV,KF>& orig) {}
122  public:
123 
124 
125  void Solve(int l, const Kernel<FV,KF>& Q, const double *b_,
126  const schar *y_,
127  double *alpha_, double Cp, double Cn, double eps,
128  SolutionInfo* si, int shrinking,
129  ProgressReporter* progressReporter);
130 
131  protected:
134  double *G; // gradient of objective function
136  char *alpha_status; // LOWER_BOUND, UPPER_BOUND, FREE
137  double *alpha;
138  const Kernel<FV,KF>* Q;
139  double eps;
140  double Cp,Cn;
141  double *b;
143  double *G_bar; // gradient, if we treat free variables as 0
144  int l;
145  bool unshrinked; // XXX
146 
147  double get_C(int i)
148  {
149  return (y[i] > 0)? Cp : Cn;
150  }
152  {
153  if(alpha[i] >= get_C(i))
154  alpha_status[i] = UPPER_BOUND;
155  else if(alpha[i] <= 0)
156  alpha_status[i] = LOWER_BOUND;
157  else alpha_status[i] = FREE;
158  }
159  bool is_upper_bound(int i) { return alpha_status[i] == UPPER_BOUND; }
160  bool is_lower_bound(int i) { return alpha_status[i] == LOWER_BOUND; }
161  bool is_free(int i) { return alpha_status[i] == FREE; }
162  void swap_index(int i, int j);
163  void reconstruct_gradient();
164  virtual int select_working_set(int &i, int &j);
165  virtual double calculate_rho();
166  virtual void do_shrinking();
167  };
168 
169 }
170 #include "Solver.icc"
171 
172 #endif
173 
174 
175 
176 
177 
178 // old libsvmtl code
179  //
180  //
181  // /*====================================================================*/
182  // /*!
183  // * (description)
184  // *
185  // * \param
186  // */
187  // /*====================================================================*/
188  // void
189  // Solve(
190  // int l,
191  // KQ* Q,
192  // const std::vector<double>& b_,
193  // const std::vector<signed char>& y_,
194  // std::vector<double>& alpha_,
195  // double Cp,
196  // double Cn,
197  // double eps,
198  // SolutionInfo& si,
199  // bool shrinking);
200  //
201  // protected:
202  // /*====================================================================*/
203  // /*!
204  // * (description)
205  // *
206  // * \param
207  // *
208  // * \return
209  // */
210  // /*====================================================================*/
211  // double
212  // get_C(int i) const;
213  //
214  //
215  // /*====================================================================*/
216  // /*!
217  // * (description)
218  // *
219  // * \param
220  // */
221  // /*====================================================================*/
222  // void
223  // update_alpha_status(int i);
224  //
225  //
226  // /*====================================================================*/
227  // /*!
228  // * (description)
229  // *
230  // * \param
231  // *
232  // * \return
233  // */
234  // /*====================================================================*/
235  // bool
236  // is_upper_bound(int i) const;
237  //
238  //
239  // /*====================================================================*/
240  // /*!
241  // * (description)
242  // *
243  // * \param
244  // *
245  // * \return
246  // */
247  // /*====================================================================*/
248  // bool
249  // is_lower_bound(int i) const;
250  //
251  //
252  // /*====================================================================*/
253  // /*!
254  // * (description)
255  // *
256  // * \param
257  // *
258  // * \return
259  // */
260  // /*====================================================================*/
261  // bool
262  // is_free(int i) const;
263  //
264  //
265  // /*====================================================================*/
266  // /*!
267  // * (description)
268  // *
269  // * \param
270  // */
271  // /*====================================================================*/
272  // void
273  // swap_index(
274  // int i,
275  // int j);
276  //
277  //
278  // /*====================================================================*/
279  // /*!
280  // * (description)
281  // */
282  // /*====================================================================*/
283  // void
284  // reconstruct_gradient();
285  //
286  //
287  // /*====================================================================*/
288  // /*!
289  // * (description)
290  // *
291  // * \param
292  // *
293  // * \return
294  // */
295  // /*====================================================================*/
296  // virtual
297  // int
298  // select_working_set(
299  // int &out_i,
300  // int &out_j) const;
301  //
302  //
303  // /*====================================================================*/
304  // /*!
305  // * (description)
306  // *
307  // * \return
308  // */
309  // /*====================================================================*/
310  // virtual
311  // void
312  // calculate_rho( SolutionInfo& si);
313  //
314  //
315  // /*====================================================================*/
316  // /*!
317  // * (description)
318  // *
319  // * \param
320  // */
321  // /*====================================================================*/
322  // virtual
323  // void
324  // do_shrinking();
325  //
326  //
327  // int active_size;
328  // std::vector<signed char> y;
329  // double* G; // gradient of objective function
330  // enum { LOWER_BOUND, UPPER_BOUND, FREE };
331  // char* alpha_status; // LOWER_BOUND, UPPER_BOUND, FREE
332  // std::vector<double> alpha;
333  // KQ* p_Q;
334  // double eps;
335  // double Cp,Cn;
336  // std::vector<double> b;
337  // int* active_set;
338  // double* G_bar; // gradient, if we treat free variables as 0
339  // int l;
340  // bool unshrinked; // XXX
341  //
342  // template< typename T>
343  // void print_array( T p, int len)
344  // {
345  // cout << "( ";
346  // for( int i = 0; i < len; ++i)
347  // {
348  // cout << double(p[i]) << " ";
349  // }
350  // cout << ")\n";
351  // }
352  //
353  // void print_internals()
354  // {
355  // cout << "active_size = " << active_size << endl;
356  // cout << "y = "; print_array( y, active_size);
357  // cout << "G = "; print_array( G, active_size);
358  // cout << "alpha_status= "; print_array( alpha_status, active_size);
359  // cout << "alpha = "; print_array( alpha, active_size);
360  // cout << "eps = " << eps << endl;
361  // cout << "Cp = " << Cp << endl;
362  // cout << "Cn = " << Cn << endl;
363  // cout << "b = "; print_array( b, active_size);
364  // cout << "active_set = "; print_array( active_set, active_size);
365  // cout << "G_bar = "; print_array( G_bar, active_size);
366  // cout << "l = " << l << endl;
367  // cout << "unshrinked = " << unshrinked << endl;
368  // }
369  //
370  // };
371  //
372  // #include "Solver.icc"
373  //
374  // }
375  //
376  // #endif
double * alpha
Definition: Solver.hh:137
virtual ~Solver()
Definition: Solver.hh:116
virtual int select_working_set(int &i, int &j)
virtual void do_shrinking()
bool is_free(int i)
Definition: Solver.hh:161
void reconstruct_gradient()
signed char schar
Definition: svm_defines.hh:67
void Solve(int l, const Kernel< FV, KF > &Q, const double *b_, const schar *y_, double *alpha_, double Cp, double Cn, double eps, SolutionInfo *si, int shrinking, ProgressReporter *progressReporter)
bool is_upper_bound(int i)
Definition: Solver.hh:159
void update_alpha_status(int i)
Definition: Solver.hh:151
double * G_bar
Definition: Solver.hh:143
double Cp
Definition: Solver.hh:140
int * active_set
Definition: Solver.hh:142
bool is_lower_bound(int i)
Definition: Solver.hh:160
double get_C(int i)
Definition: Solver.hh:147
double Cn
Definition: Solver.hh:140
int active_size
Definition: Solver.hh:132
double * b
Definition: Solver.hh:141
bool unshrinked
Definition: Solver.hh:145
double * G
Definition: Solver.hh:134
double eps
Definition: Solver.hh:139
virtual double calculate_rho()
void swap_index(int i, int j)
char * alpha_status
Definition: Solver.hh:136
const Kernel< FV, KF > * Q
Definition: Solver.hh:138
schar * y
Definition: Solver.hh:133