yat/classifier/SVM.cc

Code
Comments
Other
Rev Date Author Line
30 16 Jan 04 peter 1 // $Id$
30 16 Jan 04 peter 2
675 10 Oct 06 jari 3 /*
2119 12 Dec 09 peter 4   Copyright (C) 2004, 2005 Jari Häkkinen, Peter Johansson
2119 12 Dec 09 peter 5   Copyright (C) 2006 Jari Häkkinen, Peter Johansson, Markus Ringnér
4359 23 Aug 23 peter 6   Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson
4359 23 Aug 23 peter 7   Copyright (C) 2009, 2010, 2012 Peter Johansson
295 29 Apr 05 peter 8
1437 25 Aug 08 peter 9   This file is part of the yat library, http://dev.thep.lu.se/yat
295 29 Apr 05 peter 10
675 10 Oct 06 jari 11   The yat library is free software; you can redistribute it and/or
675 10 Oct 06 jari 12   modify it under the terms of the GNU General Public License as
1486 09 Sep 08 jari 13   published by the Free Software Foundation; either version 3 of the
675 10 Oct 06 jari 14   License, or (at your option) any later version.
675 10 Oct 06 jari 15
675 10 Oct 06 jari 16   The yat library is distributed in the hope that it will be useful,
675 10 Oct 06 jari 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
675 10 Oct 06 jari 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
675 10 Oct 06 jari 19   General Public License for more details.
675 10 Oct 06 jari 20
675 10 Oct 06 jari 21   You should have received a copy of the GNU General Public License
1487 10 Sep 08 jari 22   along with yat. If not, see <http://www.gnu.org/licenses/>.
675 10 Oct 06 jari 23 */
675 10 Oct 06 jari 24
2881 18 Nov 12 peter 25 #include <config.h>
2881 18 Nov 12 peter 26
680 11 Oct 06 jari 27 #include "SVM.h"
1102 18 Feb 08 peter 28 #include "KernelLookup.h"
747 11 Feb 07 peter 29 #include "Target.h"
2210 05 Mar 10 peter 30 #include "yat/utility/Exception.h"
1121 22 Feb 08 peter 31 #include "yat/utility/Matrix.h"
1120 21 Feb 08 peter 32 #include "yat/utility/Vector.h"
675 10 Oct 06 jari 33
323 26 May 05 peter 34 #include <algorithm>
463 16 Dec 05 peter 35 #include <cassert>
569 23 Mar 06 peter 36 #include <cctype>
55 11 Mar 04 jari 37 #include <cmath>
323 26 May 05 peter 38 #include <limits>
1049 07 Feb 08 peter 39 #include <sstream>
1100 18 Feb 08 peter 40 #include <string>
47 02 Mar 04 peter 41 #include <utility>
61 17 Apr 04 peter 42 #include <vector>
30 16 Jan 04 peter 43
42 26 Feb 04 jari 44 namespace theplu {
680 11 Oct 06 jari 45 namespace yat {
4200 19 Aug 22 peter 46 namespace classifier {
30 16 Jan 04 peter 47
1100 18 Feb 08 peter 48   SVM::SVM(void)
1100 18 Feb 08 peter 49     : bias_(0),
491 04 Jan 06 peter 50       C_inverse_(0),
1100 18 Feb 08 peter 51       kernel_(NULL),
569 23 Mar 06 peter 52       margin_(0),
568 22 Mar 06 peter 53       max_epochs_(100000),
1100 18 Feb 08 peter 54       tolerance_(0.00000001),
1100 18 Feb 08 peter 55       trained_(false)
68 28 Apr 04 peter 56   {
68 28 Apr 04 peter 57   }
30 16 Jan 04 peter 58
1100 18 Feb 08 peter 59
1108 19 Feb 08 peter 60   SVM::SVM(const SVM& other)
1177 27 Feb 08 peter 61     : bias_(other.bias_), C_inverse_(other.C_inverse_),  kernel_(other.kernel_),
1108 19 Feb 08 peter 62       margin_(0), max_epochs_(other.max_epochs_), tolerance_(other.tolerance_),
1108 19 Feb 08 peter 63       trained_(other.trained_)
1108 19 Feb 08 peter 64   {
1108 19 Feb 08 peter 65   }
1108 19 Feb 08 peter 66
1108 19 Feb 08 peter 67
547 06 Mar 06 peter 68   SVM::~SVM()
547 06 Mar 06 peter 69   {
547 06 Mar 06 peter 70   }
547 06 Mar 06 peter 71
1100 18 Feb 08 peter 72
1120 21 Feb 08 peter 73   const utility::Vector& SVM::alpha(void) const
720 26 Dec 06 jari 74   {
720 26 Dec 06 jari 75     return alpha_;
720 26 Dec 06 jari 76   }
547 06 Mar 06 peter 77
1100 18 Feb 08 peter 78
720 26 Dec 06 jari 79   double SVM::C(void) const
720 26 Dec 06 jari 80   {
720 26 Dec 06 jari 81     return 1.0/C_inverse_;
720 26 Dec 06 jari 82   }
720 26 Dec 06 jari 83
1100 18 Feb 08 peter 84
569 23 Mar 06 peter 85   void SVM::calculate_margin(void)
569 23 Mar 06 peter 86   {
569 23 Mar 06 peter 87     margin_ = 0;
569 23 Mar 06 peter 88     for(size_t i = 0; i<alpha_.size(); ++i){
569 23 Mar 06 peter 89       margin_ += alpha_(i)*target(i)*kernel_mod(i,i)*alpha_(i)*target(i);
569 23 Mar 06 peter 90       for(size_t j = i+1; j<alpha_.size(); ++j)
569 23 Mar 06 peter 91         margin_ += 2*alpha_(i)*target(i)*kernel_mod(i,j)*alpha_(j)*target(j);
569 23 Mar 06 peter 92     }
2103 06 Nov 09 peter 93     margin_ = std::sqrt(margin_);
569 23 Mar 06 peter 94   }
569 23 Mar 06 peter 95
1100 18 Feb 08 peter 96
1102 18 Feb 08 peter 97   /*
722 27 Dec 06 markus 98   const DataLookup2D& SVM::data(void) const
722 27 Dec 06 markus 99   {
722 27 Dec 06 markus 100     return *kernel_;
722 27 Dec 06 markus 101    }
1102 18 Feb 08 peter 102   */
722 27 Dec 06 markus 103
722 27 Dec 06 markus 104
720 26 Dec 06 jari 105   double SVM::kernel_mod(const size_t i, const size_t j) const
720 26 Dec 06 jari 106   {
1100 18 Feb 08 peter 107     assert(kernel_);
1100 18 Feb 08 peter 108     assert(i<kernel_->rows());
1100 18 Feb 08 peter 109     assert(i<kernel_->columns());
720 26 Dec 06 jari 110     return i!=j ? (*kernel_)(i,j) : (*kernel_)(i,j) + C_inverse_;
720 26 Dec 06 jari 111   }
569 23 Mar 06 peter 112
1100 18 Feb 08 peter 113
1100 18 Feb 08 peter 114   SVM* SVM::make_classifier(void) const
493 09 Jan 06 peter 115   {
1175 27 Feb 08 peter 116     SVM* svm = new SVM(*this);
1175 27 Feb 08 peter 117     svm->trained_ = false;
1175 27 Feb 08 peter 118     return svm;
493 09 Jan 06 peter 119   }
493 09 Jan 06 peter 120
1100 18 Feb 08 peter 121
1863 13 Mar 09 peter 122   unsigned long int SVM::max_epochs(void) const
720 26 Dec 06 jari 123   {
720 26 Dec 06 jari 124     return max_epochs_;
720 26 Dec 06 jari 125   }
720 26 Dec 06 jari 126
964 10 Oct 07 peter 127
1863 13 Mar 09 peter 128   void SVM::max_epochs(unsigned long int n)
964 10 Oct 07 peter 129   {
964 10 Oct 07 peter 130     max_epochs_=n;
964 10 Oct 07 peter 131   }
964 10 Oct 07 peter 132
964 10 Oct 07 peter 133
1120 21 Feb 08 peter 134   const utility::Vector& SVM::output(void) const
720 26 Dec 06 jari 135   {
720 26 Dec 06 jari 136     return output_;
720 26 Dec 06 jari 137   }
720 26 Dec 06 jari 138
1121 22 Feb 08 peter 139   void SVM::predict(const KernelLookup& input, utility::Matrix& prediction) const
523 23 Feb 06 peter 140   {
1102 18 Feb 08 peter 141     assert(input.rows()==alpha_.size());
1102 18 Feb 08 peter 142     prediction.resize(2,input.columns(),0);
1102 18 Feb 08 peter 143     for (size_t i = 0; i<input.columns(); i++){
1102 18 Feb 08 peter 144       for (size_t j = 0; j<input.rows(); j++){
1102 18 Feb 08 peter 145         prediction(0,i) += target(j)*alpha_(j)*input(j,i);
1102 18 Feb 08 peter 146         assert(target(j));
559 11 Mar 06 peter 147       }
1102 18 Feb 08 peter 148       prediction(0,i) = margin_ * (prediction(0,i) + bias_);
523 23 Feb 06 peter 149     }
4200 19 Aug 22 peter 150
1102 18 Feb 08 peter 151     for (size_t i = 0; i<prediction.columns(); i++)
1102 18 Feb 08 peter 152       prediction(1,i) = -prediction(0,i);
523 23 Feb 06 peter 153   }
523 23 Feb 06 peter 154
1200 05 Mar 08 peter 155   /*
539 05 Mar 06 peter 156   double SVM::predict(const DataLookup1D& x) const
523 23 Feb 06 peter 157   {
523 23 Feb 06 peter 158     double y=0;
539 05 Mar 06 peter 159     for (size_t i=0; i<alpha_.size(); i++)
539 05 Mar 06 peter 160       y += alpha_(i)*target_(i)*kernel_->element(x,i);
523 23 Feb 06 peter 161
569 23 Mar 06 peter 162     return margin_*(y+bias_);
523 23 Feb 06 peter 163   }
523 23 Feb 06 peter 164
628 05 Sep 06 peter 165   double SVM::predict(const DataLookupWeighted1D& x) const
542 05 Mar 06 peter 166   {
542 05 Mar 06 peter 167     double y=0;
542 05 Mar 06 peter 168     for (size_t i=0; i<alpha_.size(); i++)
628 05 Sep 06 peter 169       y += alpha_(i)*target_(i)*kernel_->element(x,i);
542 05 Mar 06 peter 170
569 23 Mar 06 peter 171     return margin_*(y+bias_);
542 05 Mar 06 peter 172   }
1200 05 Mar 08 peter 173   */
542 05 Mar 06 peter 174
720 26 Dec 06 jari 175   int SVM::target(size_t i) const
720 26 Dec 06 jari 176   {
1100 18 Feb 08 peter 177     assert(i<target_.size());
720 26 Dec 06 jari 178     return target_.binary(i) ? 1 : -1;
720 26 Dec 06 jari 179   }
720 26 Dec 06 jari 180
4200 19 Aug 22 peter 181   void SVM::train(const KernelLookup& kernel, const Target& targ)
114 15 Jul 04 peter 182   {
1859 08 Mar 09 peter 183     trained_ = false;
1100 18 Feb 08 peter 184     kernel_ = new KernelLookup(kernel);
1100 18 Feb 08 peter 185     target_ = targ;
4200 19 Aug 22 peter 186
1120 21 Feb 08 peter 187     alpha_ = utility::Vector(targ.size(), 0.0);
1120 21 Feb 08 peter 188     output_ = utility::Vector(targ.size(), 0.0);
323 26 May 05 peter 189     // initializing variables for optimization
523 23 Feb 06 peter 190     assert(target_.size()==kernel_->rows());
323 26 May 05 peter 191     assert(target_.size()==alpha_.size());
167 23 Sep 04 peter 192
323 26 May 05 peter 193     sample_.init(alpha_,tolerance_);
1120 21 Feb 08 peter 194     utility::Vector   E(target_.size(),0);
323 26 May 05 peter 195     for (size_t i=0; i<E.size(); i++) {
4200 19 Aug 22 peter 196       for (size_t j=0; j<E.size(); j++)
509 18 Feb 06 peter 197         E(i) += kernel_mod(i,j)*target(j)*alpha_(j);
559 11 Mar 06 peter 198       E(i)-=target(i);
162 21 Sep 04 peter 199     }
323 26 May 05 peter 200     assert(target_.size()==E.size());
568 22 Mar 06 peter 201     assert(target_.size()==sample_.size());
114 15 Jul 04 peter 202
162 21 Sep 04 peter 203     unsigned long int epochs = 0;
162 21 Sep 04 peter 204     double alpha_new2;
162 21 Sep 04 peter 205     double alpha_new1;
162 21 Sep 04 peter 206     double u;
162 21 Sep 04 peter 207     double v;
323 26 May 05 peter 208
162 21 Sep 04 peter 209     // Training loop
323 26 May 05 peter 210     while(choose(E)) {
4200 19 Aug 22 peter 211       bounds(u,v);
4200 19 Aug 22 peter 212       double k = ( kernel_mod(sample_.value_first(), sample_.value_first()) +
4200 19 Aug 22 peter 213                    kernel_mod(sample_.value_second(), sample_.value_second()) -
323 26 May 05 peter 214                    2*kernel_mod(sample_.value_first(), sample_.value_second()));
4200 19 Aug 22 peter 215
323 26 May 05 peter 216       double alpha_old1=alpha_(sample_.value_first());
323 26 May 05 peter 217       double alpha_old2=alpha_(sample_.value_second());
4200 19 Aug 22 peter 218       alpha_new2 = ( alpha_(sample_.value_second()) +
509 18 Feb 06 peter 219                      target(sample_.value_second())*
323 26 May 05 peter 220                      ( E(sample_.value_first())-E(sample_.value_second()) )/k );
4200 19 Aug 22 peter 221
162 21 Sep 04 peter 222       if (alpha_new2 > v)
162 21 Sep 04 peter 223         alpha_new2 = v;
162 21 Sep 04 peter 224       else if (alpha_new2<u)
162 21 Sep 04 peter 225         alpha_new2 = u;
4200 19 Aug 22 peter 226
323 26 May 05 peter 227       // Updating the alphas
323 26 May 05 peter 228       // if alpha is 'zero' make the sample a non-support vector
323 26 May 05 peter 229       if (alpha_new2 < tolerance_){
323 26 May 05 peter 230         sample_.nsv_second();
323 26 May 05 peter 231       }
323 26 May 05 peter 232       else{
323 26 May 05 peter 233         sample_.sv_second();
323 26 May 05 peter 234       }
4200 19 Aug 22 peter 235
4200 19 Aug 22 peter 236
4200 19 Aug 22 peter 237       alpha_new1 = (alpha_(sample_.value_first()) +
4200 19 Aug 22 peter 238                     (target(sample_.value_first()) *
4200 19 Aug 22 peter 239                      target(sample_.value_second()) *
323 26 May 05 peter 240                      (alpha_(sample_.value_second()) - alpha_new2) ));
4200 19 Aug 22 peter 241
323 26 May 05 peter 242       // if alpha is 'zero' make the sample a non-support vector
162 21 Sep 04 peter 243       if (alpha_new1 < tolerance_){
323 26 May 05 peter 244         sample_.nsv_first();
162 21 Sep 04 peter 245       }
323 26 May 05 peter 246       else
323 26 May 05 peter 247         sample_.sv_first();
4200 19 Aug 22 peter 248
323 26 May 05 peter 249       alpha_(sample_.value_first()) = alpha_new1;
323 26 May 05 peter 250       alpha_(sample_.value_second()) = alpha_new2;
4200 19 Aug 22 peter 251
323 26 May 05 peter 252       // update E vector
323 26 May 05 peter 253       // Peter, perhaps one should only update SVs, but what happens in choose?
323 26 May 05 peter 254       for (size_t i=0; i<E.size(); i++) {
323 26 May 05 peter 255         E(i)+=( kernel_mod(i,sample_.value_first())*
509 18 Feb 06 peter 256                 target(sample_.value_first()) *
323 26 May 05 peter 257                 (alpha_new1-alpha_old1) );
323 26 May 05 peter 258         E(i)+=( kernel_mod(i,sample_.value_second())*
509 18 Feb 06 peter 259                 target(sample_.value_second()) *
323 26 May 05 peter 260                 (alpha_new2-alpha_old2) );
323 26 May 05 peter 261       }
4200 19 Aug 22 peter 262
4200 19 Aug 22 peter 263       epochs++;
520 22 Feb 06 peter 264       if (epochs>max_epochs_){
2210 05 Mar 10 peter 265         throw utility::runtime_error("SVM: maximal number of epochs reached.");
520 22 Feb 06 peter 266       }
323 26 May 05 peter 267     }
569 23 Mar 06 peter 268     calculate_margin();
1049 07 Feb 08 peter 269     calculate_bias();
1049 07 Feb 08 peter 270     trained_ = true;
323 26 May 05 peter 271   }
323 26 May 05 peter 272
323 26 May 05 peter 273
1120 21 Feb 08 peter 274   bool SVM::choose(const theplu::yat::utility::Vector& E)
323 26 May 05 peter 275   {
323 26 May 05 peter 276     // First check for violation among SVs
323 26 May 05 peter 277     // E should be the same for all SVs
323 26 May 05 peter 278     // Choose that pair having largest violation/difference.
323 26 May 05 peter 279     sample_.update_second(0);
323 26 May 05 peter 280     sample_.update_first(0);
323 26 May 05 peter 281     if (sample_.nof_sv()>1){
514 20 Feb 06 peter 282
323 26 May 05 peter 283       double max = E(sample_(0));
323 26 May 05 peter 284       double min = max;
4200 19 Aug 22 peter 285       for (size_t i=1; i<sample_.nof_sv(); i++){
323 26 May 05 peter 286         assert(alpha_(sample_(i))>tolerance_);
323 26 May 05 peter 287         if (E(sample_(i)) > max){
323 26 May 05 peter 288           max = E(sample_(i));
323 26 May 05 peter 289           sample_.update_second(i);
323 26 May 05 peter 290         }
323 26 May 05 peter 291         else if (E(sample_(i))<min){
323 26 May 05 peter 292           min = E(sample_(i));
323 26 May 05 peter 293           sample_.update_first(i);
323 26 May 05 peter 294         }
162 21 Sep 04 peter 295       }
323 26 May 05 peter 296       assert(alpha_(sample_.value_first())>tolerance_);
323 26 May 05 peter 297       assert(alpha_(sample_.value_second())>tolerance_);
323 26 May 05 peter 298
323 26 May 05 peter 299       if (E(sample_.value_second()) - E(sample_.value_first()) > 2*tolerance_){
323 26 May 05 peter 300         return true;
323 26 May 05 peter 301       }
4200 19 Aug 22 peter 302
323 26 May 05 peter 303       // If no violation check among non-support vectors
323 26 May 05 peter 304       sample_.shuffle();
568 22 Mar 06 peter 305       for (size_t i=sample_.nof_sv(); i<sample_.size();i++){
514 20 Feb 06 peter 306         if (target_.binary(sample_(i))){
323 26 May 05 peter 307           if(E(sample_(i)) < E(sample_.value_first()) - 2*tolerance_){
323 26 May 05 peter 308             sample_.update_second(i);
323 26 May 05 peter 309             return true;
323 26 May 05 peter 310           }
323 26 May 05 peter 311         }
323 26 May 05 peter 312         else{
323 26 May 05 peter 313           if(E(sample_(i)) > E(sample_.value_second()) + 2*tolerance_){
323 26 May 05 peter 314             sample_.update_first(i);
323 26 May 05 peter 315             return true;
323 26 May 05 peter 316           }
323 26 May 05 peter 317         }
323 26 May 05 peter 318       }
68 28 Apr 04 peter 319     }
37 13 Feb 04 peter 320
323 26 May 05 peter 321     // if no support vectors - special case
323 26 May 05 peter 322     else{
559 11 Mar 06 peter 323       // to avoid getting stuck we shuffle
559 11 Mar 06 peter 324       sample_.shuffle();
568 22 Mar 06 peter 325       for (size_t i=0; i<sample_.size(); i++) {
568 22 Mar 06 peter 326         if (target(sample_(i))==1){
568 22 Mar 06 peter 327           for (size_t j=0; j<sample_.size(); j++) {
4200 19 Aug 22 peter 328             if ( target(sample_(j))==-1 &&
323 26 May 05 peter 329                  E(sample_(i)) < E(sample_(j))+2*tolerance_ ){
323 26 May 05 peter 330               sample_.update_first(i);
323 26 May 05 peter 331               sample_.update_second(j);
323 26 May 05 peter 332               return true;
323 26 May 05 peter 333             }
323 26 May 05 peter 334           }
323 26 May 05 peter 335         }
323 26 May 05 peter 336       }
323 26 May 05 peter 337     }
4200 19 Aug 22 peter 338
323 26 May 05 peter 339     // If there is no violation then we should stop training
323 26 May 05 peter 340     return false;
323 26 May 05 peter 341
114 15 Jul 04 peter 342   }
4200 19 Aug 22 peter 343
4200 19 Aug 22 peter 344
323 26 May 05 peter 345   void SVM::bounds( double& u, double& v) const
323 26 May 05 peter 346   {
509 18 Feb 06 peter 347     if (target(sample_.value_first())!=target(sample_.value_second())) {
323 26 May 05 peter 348       if (alpha_(sample_.value_second()) > alpha_(sample_.value_first())) {
323 26 May 05 peter 349         v = std::numeric_limits<double>::max();
323 26 May 05 peter 350         u = alpha_(sample_.value_second()) - alpha_(sample_.value_first());
323 26 May 05 peter 351       }
323 26 May 05 peter 352       else {
4200 19 Aug 22 peter 353         v = (std::numeric_limits<double>::max() -
4200 19 Aug 22 peter 354              alpha_(sample_.value_first()) +
323 26 May 05 peter 355              alpha_(sample_.value_second()));
323 26 May 05 peter 356         u = 0;
323 26 May 05 peter 357       }
323 26 May 05 peter 358     }
4200 19 Aug 22 peter 359     else {
4200 19 Aug 22 peter 360       if (alpha_(sample_.value_second()) + alpha_(sample_.value_first()) >
323 26 May 05 peter 361            std::numeric_limits<double>::max()) {
4200 19 Aug 22 peter 362         u = (alpha_(sample_.value_second()) + alpha_(sample_.value_first()) -
323 26 May 05 peter 363               std::numeric_limits<double>::max());
4200 19 Aug 22 peter 364         v =  std::numeric_limits<double>::max();
323 26 May 05 peter 365       }
323 26 May 05 peter 366       else {
323 26 May 05 peter 367         u = 0;
323 26 May 05 peter 368         v = alpha_(sample_.value_first()) + alpha_(sample_.value_second());
323 26 May 05 peter 369       }
323 26 May 05 peter 370     }
323 26 May 05 peter 371   }
4200 19 Aug 22 peter 372
1049 07 Feb 08 peter 373   void SVM::calculate_bias(void)
323 26 May 05 peter 374   {
47 02 Mar 04 peter 375
323 26 May 05 peter 376     // calculating output without bias
323 26 May 05 peter 377     for (size_t i=0; i<output_.size(); i++) {
323 26 May 05 peter 378       output_(i)=0;
4200 19 Aug 22 peter 379       for (size_t j=0; j<output_.size(); j++)
523 23 Feb 06 peter 380         output_(i)+=alpha_(j)*target(j) * (*kernel_)(i,j);
323 26 May 05 peter 381     }
323 26 May 05 peter 382
323 26 May 05 peter 383     if (!sample_.nof_sv()){
1049 07 Feb 08 peter 384       std::stringstream ss;
4200 19 Aug 22 peter 385       ss << "yat::classifier::SVM::train() error: "
4200 19 Aug 22 peter 386          << "Cannot calculate bias because there is no support vector";
2210 05 Mar 10 peter 387       throw utility::runtime_error(ss.str());
323 26 May 05 peter 388     }
323 26 May 05 peter 389
323 26 May 05 peter 390     // For samples with alpha>0, we have: target*output=1-alpha/C
323 26 May 05 peter 391     bias_=0;
4200 19 Aug 22 peter 392     for (size_t i=0; i<sample_.nof_sv(); i++)
4200 19 Aug 22 peter 393       bias_+= ( target(sample_(i)) * (1-alpha_(sample_(i))*C_inverse_) -
323 26 May 05 peter 394                 output_(sample_(i)) );
323 26 May 05 peter 395     bias_=bias_/sample_.nof_sv();
4200 19 Aug 22 peter 396     for (size_t i=0; i<output_.size(); i++)
323 26 May 05 peter 397       output_(i) += bias_;
323 26 May 05 peter 398   }
323 26 May 05 peter 399
571 06 Apr 06 peter 400   void SVM::set_C(const double C)
571 06 Apr 06 peter 401   {
571 06 Apr 06 peter 402     C_inverse_ = 1/C;
571 06 Apr 06 peter 403   }
571 06 Apr 06 peter 404
4200 19 Aug 22 peter 405
1859 08 Mar 09 peter 406   void SVM::reset(void)
1859 08 Mar 09 peter 407   {
1859 08 Mar 09 peter 408     trained_ = false;
1859 08 Mar 09 peter 409   }
1859 08 Mar 09 peter 410
1859 08 Mar 09 peter 411
1859 08 Mar 09 peter 412   bool SVM::trained(void) const
1859 08 Mar 09 peter 413   {
1859 08 Mar 09 peter 414     return trained_;
1859 08 Mar 09 peter 415   }
1859 08 Mar 09 peter 416
680 11 Oct 06 jari 417 }}} // of namespace classifier, yat, and theplu