SVM_linear.cpp

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

SHOGUN Machine Learning Toolbox - Documentation