SVM_linear.cpp

Go to the documentation of this file.
00001 #include "lib/config.h"
00002 
00003 #ifdef HAVE_LAPACK
00004 #include <math.h>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <stdarg.h>
00009 
00010 #include "classifier/svm/SVM_linear.h"
00011 #include "classifier/svm/Tron.h"
00012 
00013 l2_lr_fun::l2_lr_fun(const problem *p, double Cp, double Cn)
00014 : function()
00015 {
00016     int i;
00017     int l=p->l;
00018     int *y=p->y;
00019 
00020     this->prob = p;
00021 
00022     z = new double[l];
00023     D = new double[l];
00024     C = new double[l];
00025 
00026     for (i=0; i<l; i++)
00027     {
00028         if (y[i] == 1)
00029             C[i] = Cp;
00030         else
00031             C[i] = Cn;
00032     }
00033 }
00034 
00035 l2_lr_fun::~l2_lr_fun()
00036 {
00037     delete[] z;
00038     delete[] D;
00039     delete[] C;
00040 }
00041 
00042 
00043 double l2_lr_fun::fun(double *w)
00044 {
00045     int i;
00046     double f=0;
00047     int *y=prob->y;
00048     int l=prob->l;
00049     int n=prob->n;
00050 
00051     Xv(w, z);
00052     for(i=0;i<l;i++)
00053     {
00054             double yz = y[i]*z[i];
00055         if (yz >= 0)
00056                 f += C[i]*log(1 + exp(-yz));
00057         else
00058                 f += C[i]*(-yz+log(1 + exp(yz)));
00059     }
00060     f = 2*f;
00061     for(i=0;i<n;i++)
00062         f += w[i]*w[i];
00063     f /= 2.0;
00064 
00065     return(f);
00066 }
00067 
00068 void l2_lr_fun::grad(double *w, double *g)
00069 {
00070     int i;
00071     int *y=prob->y;
00072     int l=prob->l;
00073     int n=prob->n;
00074 
00075     for(i=0;i<l;i++)
00076     {
00077         z[i] = 1/(1 + exp(-y[i]*z[i]));
00078         D[i] = z[i]*(1-z[i]);
00079         z[i] = C[i]*(z[i]-1)*y[i];
00080     }
00081     XTv(z, g);
00082 
00083     for(i=0;i<n;i++)
00084         g[i] = w[i] + g[i];
00085 }
00086 
00087 int l2_lr_fun::get_nr_variable(void)
00088 {
00089     return prob->n;
00090 }
00091 
00092 void l2_lr_fun::Hv(double *s, double *Hs)
00093 {
00094     int i;
00095     int l=prob->l;
00096     int n=prob->n;
00097     double *wa = new double[l];
00098 
00099     Xv(s, wa);
00100     for(i=0;i<l;i++)
00101         wa[i] = C[i]*D[i]*wa[i];
00102 
00103     XTv(wa, Hs);
00104     for(i=0;i<n;i++)
00105         Hs[i] = s[i] + Hs[i];
00106     delete[] wa;
00107 }
00108 
00109 void l2_lr_fun::Xv(double *v, double *res_Xv)
00110 {
00111     int l=prob->l;
00112     int n=prob->n;
00113 
00114     if (prob->use_bias)
00115         n--;
00116 
00117     for (int i=0;i<l;i++)
00118     {
00119         res_Xv[i]=prob->x->dense_dot(1.0, i, v, n, 0);
00120 
00121         if (prob->use_bias)
00122             res_Xv[i]+=v[n];
00123     }
00124 }
00125 
00126 void l2_lr_fun::XTv(double *v, double *res_XTv)
00127 {
00128     int l=prob->l;
00129     int n=prob->n;
00130 
00131     if (prob->use_bias)
00132         n--;
00133 
00134     memset(res_XTv, 0, sizeof(double)*prob->n);
00135 
00136     for (int i=0;i<l;i++)
00137     {
00138         prob->x->add_to_dense_vec(v[i], i, res_XTv, n);
00139 
00140         if (prob->use_bias)
00141             res_XTv[n]+=v[i];
00142     }
00143 }
00144 
00145 l2loss_svm_fun::l2loss_svm_fun(const problem *p, double Cp, double Cn)
00146 : function()
00147 {
00148     int i;
00149     int l=p->l;
00150     int *y=p->y;
00151 
00152     this->prob = p;
00153 
00154     z = new double[l];
00155     D = new double[l];
00156     C = new double[l];
00157     I = new int[l];
00158 
00159     for (i=0; i<l; i++)
00160     {
00161         if (y[i] == 1)
00162             C[i] = Cp;
00163         else
00164             C[i] = Cn;
00165     }
00166 }
00167 
00168 l2loss_svm_fun::~l2loss_svm_fun()
00169 {
00170     delete[] z;
00171     delete[] D;
00172     delete[] C;
00173     delete[] I;
00174 }
00175 
00176 double l2loss_svm_fun::fun(double *w)
00177 {
00178     int i;
00179     double f=0;
00180     int *y=prob->y;
00181     int l=prob->l;
00182     int n=prob->n;
00183 
00184     Xv(w, z);
00185     for(i=0;i<l;i++)
00186     {
00187             z[i] = y[i]*z[i];
00188         double d = z[i]-1;
00189         if (d < 0)
00190             f += C[i]*d*d;
00191     }
00192     f = 2*f;
00193     for(i=0;i<n;i++)
00194         f += w[i]*w[i];
00195     f /= 2.0;
00196 
00197     return(f);
00198 }
00199 
00200 void l2loss_svm_fun::grad(double *w, double *g)
00201 {
00202     int i;
00203     int *y=prob->y;
00204     int l=prob->l;
00205     int n=prob->n;
00206 
00207     sizeI = 0;
00208     for (i=0;i<l;i++)
00209         if (z[i] < 1)
00210         {
00211             z[sizeI] = C[i]*y[i]*(z[i]-1);
00212             I[sizeI] = i;
00213             sizeI++;
00214         }
00215     subXTv(z, g);
00216 
00217     for(i=0;i<n;i++)
00218         g[i] = w[i] + 2*g[i];
00219 }
00220 
00221 int l2loss_svm_fun::get_nr_variable(void)
00222 {
00223     return prob->n;
00224 }
00225 
00226 void l2loss_svm_fun::Hv(double *s, double *Hs)
00227 {
00228     int i;
00229     int l=prob->l;
00230     int n=prob->n;
00231     double *wa = new double[l];
00232 
00233     subXv(s, wa);
00234     for(i=0;i<sizeI;i++)
00235         wa[i] = C[I[i]]*wa[i];
00236 
00237     subXTv(wa, Hs);
00238     for(i=0;i<n;i++)
00239         Hs[i] = s[i] + 2*Hs[i];
00240     delete[] wa;
00241 }
00242 
00243 void l2loss_svm_fun::Xv(double *v, double *res_Xv)
00244 {
00245     int l=prob->l;
00246     int n=prob->n;
00247 
00248     if (prob->use_bias)
00249         n--;
00250 
00251     for(int i=0;i<l;i++)
00252     {
00253         res_Xv[i]=prob->x->dense_dot(1.0, i, v, n, 0);
00254 
00255         if (prob->use_bias)
00256             res_Xv[i]+=v[n];
00257     }
00258 }
00259 
00260 void l2loss_svm_fun::subXv(double *v, double *res_Xv)
00261 {
00262     int n=prob->n;
00263 
00264     if (prob->use_bias)
00265         n--;
00266 
00267     for(int i=0;i<sizeI;i++)
00268     {
00269         res_Xv[i]=prob->x->dense_dot(1.0, I[i], v, n, 0);
00270 
00271         if (prob->use_bias)
00272             res_Xv[i]+=v[n];
00273     }
00274 }
00275 
00276 void l2loss_svm_fun::subXTv(double *v, double *XTv)
00277 {
00278     int n=prob->n;
00279 
00280     if (prob->use_bias)
00281         n--;
00282 
00283     memset(XTv, 0, sizeof(double)*prob->n);
00284     for(int i=0;i<sizeI;i++)
00285     {
00286         prob->x->add_to_dense_vec(v[i], I[i], XTv, n);
00287         
00288         if (prob->use_bias)
00289             XTv[n]+=v[i];
00290     }
00291 }
00292 
00293 #endif //HAVE_LAPACK

SHOGUN Machine Learning Toolbox - Documentation