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