WDSVMOcas.cpp

Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 2007-2008 Vojtech Franc
00008  * Written (W) 2007-2009 Soeren Sonnenburg
00009  * Copyright (C) 2007-2009 Fraunhofer Institute FIRST and Max-Planck-Society
00010  */
00011 
00012 #include <shogun/features/Labels.h>
00013 #include <shogun/mathematics/Math.h>
00014 #include <shogun/lib/DynamicArray.h>
00015 #include <shogun/lib/Time.h>
00016 #include <shogun/base/Parallel.h>
00017 #include <shogun/machine/Machine.h>
00018 #include <shogun/classifier/svm/libocas.h>
00019 #include <shogun/classifier/svm/WDSVMOcas.h>
00020 #include <shogun/features/StringFeatures.h>
00021 #include <shogun/features/Alphabet.h>
00022 #include <shogun/features/Labels.h>
00023 
00024 using namespace shogun;
00025 
00026 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00027 struct wdocas_thread_params_output
00028 {
00029     float32_t* out;
00030     int32_t* val;
00031     float64_t* output;
00032     CWDSVMOcas* wdocas;
00033     int32_t start;
00034     int32_t end;
00035 };
00036 
00037 struct wdocas_thread_params_add
00038 {
00039     CWDSVMOcas* wdocas;
00040     float32_t* new_a;
00041     uint32_t* new_cut;
00042     int32_t start;
00043     int32_t end;
00044     uint32_t cut_length;
00045 };
00046 #endif // DOXYGEN_SHOULD_SKIP_THIS
00047 
00048 CWDSVMOcas::CWDSVMOcas()
00049 : CMachine(), use_bias(false), bufsize(3000), C1(1), C2(1),
00050     epsilon(1e-3), method(SVM_OCAS)
00051 {
00052     SG_UNSTABLE("CWDSVMOcas::CWDSVMOcas()", "\n");
00053 
00054     w=NULL;
00055     old_w=NULL;
00056     features=NULL;
00057     degree=6;
00058     from_degree=40;
00059     wd_weights=NULL;
00060     w_offsets=NULL;
00061     normalization_const=1.0;
00062 }
00063 
00064 CWDSVMOcas::CWDSVMOcas(E_SVM_TYPE type)
00065 : CMachine(), use_bias(false), bufsize(3000), C1(1), C2(1),
00066     epsilon(1e-3), method(type)
00067 {
00068     w=NULL;
00069     old_w=NULL;
00070     features=NULL;
00071     degree=6;
00072     from_degree=40;
00073     wd_weights=NULL;
00074     w_offsets=NULL;
00075     normalization_const=1.0;
00076 }
00077 
00078 CWDSVMOcas::CWDSVMOcas(
00079     float64_t C, int32_t d, int32_t from_d, CStringFeatures<uint8_t>* traindat,
00080     CLabels* trainlab)
00081 : CMachine(), use_bias(false), bufsize(3000), C1(C), C2(C), epsilon(1e-3),
00082     degree(d), from_degree(from_d)
00083 {
00084     w=NULL;
00085     old_w=NULL;
00086     method=SVM_OCAS;
00087     features=traindat;
00088     set_labels(trainlab);
00089     wd_weights=NULL;
00090     w_offsets=NULL;
00091     normalization_const=1.0;
00092 }
00093 
00094 
00095 CWDSVMOcas::~CWDSVMOcas()
00096 {
00097 }
00098 
00099 CLabels* CWDSVMOcas::apply()
00100 {
00101     set_wd_weights();
00102     set_normalization_const();
00103 
00104     if (features)
00105     {
00106         int32_t num=features->get_num_vectors();
00107         ASSERT(num>0);
00108 
00109         CLabels* output=new CLabels(num);
00110         SG_REF(output);
00111 
00112         for (int32_t i=0; i<num; i++)
00113             output->set_label(i, apply(i));
00114 
00115         return output;
00116     }
00117 
00118     return NULL;
00119 }
00120 
00121 CLabels* CWDSVMOcas::apply(CFeatures* data)
00122 {
00123     if (!data)
00124         SG_ERROR("No features specified\n");
00125 
00126     if (data->get_feature_class() != C_STRING ||
00127             data->get_feature_type() != F_BYTE)
00128     {
00129         SG_ERROR("Features not of class string type byte\n");
00130     }
00131 
00132     set_features((CStringFeatures<uint8_t>*) data);
00133     return apply();
00134 }
00135 
00136 int32_t CWDSVMOcas::set_wd_weights()
00137 {
00138     ASSERT(degree>0 && degree<=8);
00139     SG_FREE(wd_weights);
00140     wd_weights=SG_MALLOC(float32_t, degree);
00141     SG_FREE(w_offsets);
00142     w_offsets=SG_MALLOC(int32_t, degree);
00143     int32_t w_dim_single_c=0;
00144 
00145     for (int32_t i=0; i<degree; i++)
00146     {
00147         w_offsets[i]=CMath::pow(alphabet_size, i+1);
00148         wd_weights[i]=sqrt(2.0*(from_degree-i)/(from_degree*(from_degree+1)));
00149         w_dim_single_c+=w_offsets[i];
00150     }
00151     return w_dim_single_c;
00152 }
00153 
00154 bool CWDSVMOcas::train_machine(CFeatures* data)
00155 {
00156     SG_INFO("C=%f, epsilon=%f, bufsize=%d\n", get_C1(), get_epsilon(), bufsize);
00157 
00158     ASSERT(labels);
00159     if (data)
00160     {
00161         if (data->get_feature_class() != C_STRING ||
00162                 data->get_feature_type() != F_BYTE)
00163         {
00164             SG_ERROR("Features not of class string type byte\n");
00165         }
00166         set_features((CStringFeatures<uint8_t>*) data);
00167     }
00168 
00169     ASSERT(get_features());
00170     ASSERT(labels->is_two_class_labeling());
00171     CAlphabet* alphabet=get_features()->get_alphabet();
00172     ASSERT(alphabet && alphabet->get_alphabet()==RAWDNA);
00173 
00174     alphabet_size=alphabet->get_num_symbols();
00175     string_length=features->get_num_vectors();
00176     SGVector<float64_t> labvec=labels->get_labels();
00177     lab=labvec.vector;
00178 
00179     w_dim_single_char=set_wd_weights();
00180     //CMath::display_vector(wd_weights, degree, "wd_weights");
00181     SG_DEBUG("w_dim_single_char=%d\n", w_dim_single_char);
00182     w_dim=string_length*w_dim_single_char;
00183     SG_DEBUG("cutting plane has %d dims\n", w_dim);
00184     num_vec=get_features()->get_max_vector_length();
00185 
00186     set_normalization_const();
00187     SG_INFO("num_vec: %d num_lab: %d\n", num_vec, labvec.vlen);
00188     ASSERT(num_vec==labvec.vlen);
00189     ASSERT(num_vec>0);
00190 
00191     SG_FREE(w);
00192     w=SG_MALLOC(float32_t, w_dim);
00193     memset(w, 0, w_dim*sizeof(float32_t));
00194 
00195     SG_FREE(old_w);
00196     old_w=SG_MALLOC(float32_t, w_dim);
00197     memset(old_w, 0, w_dim*sizeof(float32_t));
00198     bias=0;
00199     old_bias=0;
00200 
00201     cuts=SG_MALLOC(float32_t*, bufsize);
00202     memset(cuts, 0, sizeof(*cuts)*bufsize);
00203     cp_bias=SG_MALLOC(float64_t, bufsize);
00204     memset(cp_bias, 0, sizeof(float64_t)*bufsize);
00205 
00207     /*float64_t* tmp = SG_MALLOC(float64_t, num_vec);
00208     float64_t start=CTime::get_curtime();
00209     CMath::random_vector(w, w_dim, (float32_t) 0, (float32_t) 1000);
00210     compute_output(tmp, this);
00211     start=CTime::get_curtime()-start;
00212     SG_PRINT("timing:%f\n", start);
00213     SG_FREE(tmp);
00214     exit(1);*/
00216     float64_t TolAbs=0;
00217     float64_t QPBound=0;
00218     uint8_t Method=0;
00219     if (method == SVM_OCAS)
00220         Method = 1;
00221     ocas_return_value_T result = svm_ocas_solver( get_C1(), num_vec, get_epsilon(),
00222             TolAbs, QPBound, get_max_train_time(), bufsize, Method,
00223             &CWDSVMOcas::compute_W,
00224             &CWDSVMOcas::update_W,
00225             &CWDSVMOcas::add_new_cut,
00226             &CWDSVMOcas::compute_output,
00227             &CWDSVMOcas::sort,
00228             &CWDSVMOcas::print,
00229             this);
00230 
00231     SG_INFO("Ocas Converged after %d iterations\n"
00232             "==================================\n"
00233             "timing statistics:\n"
00234             "output_time: %f s\n"
00235             "sort_time: %f s\n"
00236             "add_time: %f s\n"
00237             "w_time: %f s\n"
00238             "solver_time %f s\n"
00239             "ocas_time %f s\n\n", result.nIter, result.output_time, result.sort_time,
00240             result.add_time, result.w_time, result.qp_solver_time, result.ocas_time);
00241 
00242     for (int32_t i=bufsize-1; i>=0; i--)
00243         SG_FREE(cuts[i]);
00244     SG_FREE(cuts);
00245 
00246     lab=NULL;
00247     labvec.free_vector();
00248 
00249     SG_UNREF(alphabet);
00250 
00251     return true;
00252 }
00253 
00254 /*----------------------------------------------------------------------------------
00255   sq_norm_W = sparse_update_W( t ) does the following:
00256 
00257   W = oldW*(1-t) + t*W;
00258   sq_norm_W = W'*W;
00259 
00260   ---------------------------------------------------------------------------------*/
00261 float64_t CWDSVMOcas::update_W( float64_t t, void* ptr )
00262 {
00263   float64_t sq_norm_W = 0;         
00264   CWDSVMOcas* o = (CWDSVMOcas*) ptr;
00265   uint32_t nDim = (uint32_t) o->w_dim;
00266   float32_t* W=o->w;
00267   float32_t* oldW=o->old_w;
00268   float64_t bias=o->bias;
00269   float64_t old_bias=bias;
00270 
00271   for(uint32_t j=0; j <nDim; j++)
00272   {
00273       W[j] = oldW[j]*(1-t) + t*W[j];
00274       sq_norm_W += W[j]*W[j];
00275   }          
00276 
00277   bias=old_bias*(1-t) + t*bias;
00278   sq_norm_W += CMath::sq(bias);
00279 
00280   o->bias=bias;
00281   o->old_bias=old_bias;
00282 
00283   return( sq_norm_W );
00284 }
00285 
00286 /*----------------------------------------------------------------------------------
00287   sparse_add_new_cut( new_col_H, new_cut, cut_length, nSel ) does the following:
00288 
00289     new_a = sum(data_X(:,find(new_cut ~=0 )),2);
00290     new_col_H = [sparse_A(:,1:nSel)'*new_a ; new_a'*new_a];
00291     sparse_A(:,nSel+1) = new_a;
00292 
00293   ---------------------------------------------------------------------------------*/
00294 void* CWDSVMOcas::add_new_cut_helper( void* ptr)
00295 {
00296     wdocas_thread_params_add* p = (wdocas_thread_params_add*) ptr;
00297     CWDSVMOcas* o = p->wdocas;
00298     int32_t start = p->start;
00299     int32_t end = p->end;
00300     int32_t string_length = o->string_length;
00301     //uint32_t nDim=(uint32_t) o->w_dim;
00302     uint32_t cut_length=p->cut_length;
00303     uint32_t* new_cut=p->new_cut;
00304     int32_t* w_offsets = o->w_offsets;
00305     float64_t* y = o->lab;
00306     int32_t alphabet_size = o->alphabet_size;
00307     float32_t* wd_weights = o->wd_weights;
00308     int32_t degree = o->degree;
00309     CStringFeatures<uint8_t>* f = o->features;
00310     float64_t normalization_const = o->normalization_const;
00311 
00312     // temporary vector
00313     float32_t* new_a = p->new_a;
00314     //float32_t* new_a = SG_MALLOC(float32_t, nDim);
00315     //memset(new_a, 0, sizeof(float32_t)*nDim);
00316 
00317     int32_t* val=SG_MALLOC(int32_t, cut_length);
00318     for (int32_t j=start; j<end; j++)
00319     {
00320         int32_t offs=o->w_dim_single_char*j;
00321         memset(val,0,sizeof(int32_t)*cut_length);
00322         int32_t lim=CMath::min(degree, string_length-j);
00323         int32_t len;
00324 
00325         for (int32_t k=0; k<lim; k++)
00326         {
00327             bool free_vec;
00328             uint8_t* vec = f->get_feature_vector(j+k, len, free_vec);
00329             float32_t wd = wd_weights[k]/normalization_const;
00330 
00331             for(uint32_t i=0; i < cut_length; i++) 
00332             {
00333                 val[i]=val[i]*alphabet_size + vec[new_cut[i]];
00334                 new_a[offs+val[i]]+=wd * y[new_cut[i]];
00335             }
00336             offs+=w_offsets[k];
00337             f->free_feature_vector(vec, j+k, free_vec);
00338         }
00339     }
00340 
00341     //p->new_a=new_a;
00342     SG_FREE(val);
00343     return NULL;
00344 }
00345 
00346 int CWDSVMOcas::add_new_cut(
00347     float64_t *new_col_H, uint32_t *new_cut, uint32_t cut_length,
00348     uint32_t nSel, void* ptr)
00349 {
00350     CWDSVMOcas* o = (CWDSVMOcas*) ptr;
00351     int32_t string_length = o->string_length;
00352     uint32_t nDim=(uint32_t) o->w_dim;
00353     float32_t** cuts=o->cuts;
00354     float64_t* c_bias = o->cp_bias;
00355 
00356     uint32_t i;
00357     wdocas_thread_params_add* params_add=SG_MALLOC(wdocas_thread_params_add, o->parallel->get_num_threads());
00358     pthread_t* threads=SG_MALLOC(pthread_t, o->parallel->get_num_threads());
00359     float32_t* new_a=SG_MALLOC(float32_t, nDim);
00360     memset(new_a, 0, sizeof(float32_t)*nDim);
00361 
00362     int32_t t;
00363     int32_t nthreads=o->parallel->get_num_threads()-1;
00364     int32_t step= string_length/o->parallel->get_num_threads();
00365 
00366     if (step<1)
00367     {
00368         nthreads=string_length-1;
00369         step=1;
00370     }
00371 
00372     for (t=0; t<nthreads; t++)
00373     {
00374         params_add[t].wdocas=o;
00375         //params_add[t].new_a=NULL;
00376         params_add[t].new_a=new_a;
00377         params_add[t].new_cut=new_cut;
00378         params_add[t].start = step*t;
00379         params_add[t].end = step*(t+1);
00380         params_add[t].cut_length = cut_length;
00381 
00382         if (pthread_create(&threads[t], NULL, &CWDSVMOcas::add_new_cut_helper, (void*)&params_add[t]) != 0)
00383         {
00384             nthreads=t;
00385             SG_SWARNING("thread creation failed\n");
00386             break;
00387         }
00388     }
00389 
00390     params_add[t].wdocas=o;
00391     //params_add[t].new_a=NULL;
00392     params_add[t].new_a=new_a;
00393     params_add[t].new_cut=new_cut;
00394     params_add[t].start = step*t;
00395     params_add[t].end = string_length;
00396     params_add[t].cut_length = cut_length;
00397     add_new_cut_helper(&params_add[t]);
00398     //float32_t* new_a=params_add[t].new_a;
00399 
00400     for (t=0; t<nthreads; t++)
00401     {
00402         if (pthread_join(threads[t], NULL) != 0)
00403             SG_SWARNING( "pthread_join failed\n");
00404 
00405         //float32_t* a=params_add[t].new_a;
00406         //for (i=0; i<nDim; i++)
00407         //  new_a[i]+=a[i];
00408         //SG_FREE(a);
00409     }
00410 
00411     for(i=0; i < cut_length; i++) 
00412     {
00413         if (o->use_bias)
00414             c_bias[nSel]+=o->lab[new_cut[i]];
00415     }
00416 
00417     // insert new_a into the last column of sparse_A
00418     for(i=0; i < nSel; i++)
00419         new_col_H[i] = CMath::dot(new_a, cuts[i], nDim) + c_bias[nSel]*c_bias[i];
00420     new_col_H[nSel] = CMath::dot(new_a, new_a, nDim) + CMath::sq(c_bias[nSel]);
00421 
00422     cuts[nSel]=new_a;
00423     //CMath::display_vector(new_col_H, nSel+1, "new_col_H");
00424     //CMath::display_vector(cuts[nSel], nDim, "cut[nSel]");
00425     //
00426     SG_FREE(threads);
00427     SG_FREE(params_add);
00428 
00429     return 0;
00430 }
00431 
00432 int CWDSVMOcas::sort( float64_t* vals, float64_t* data, uint32_t size)
00433 {
00434     CMath::qsort_index(vals, data, size);
00435     return 0;
00436 }
00437 
00438 /*----------------------------------------------------------------------
00439   sparse_compute_output( output ) does the follwing:
00440 
00441   output = data_X'*W;
00442   ----------------------------------------------------------------------*/
00443 void* CWDSVMOcas::compute_output_helper(void* ptr)
00444 {
00445     wdocas_thread_params_output* p = (wdocas_thread_params_output*) ptr;
00446     CWDSVMOcas* o = p->wdocas;
00447     int32_t start = p->start;
00448     int32_t end = p->end;
00449     float32_t* out = p->out;
00450     float64_t* output = p->output;
00451     int32_t* val = p->val;
00452 
00453     CStringFeatures<uint8_t>* f=o->get_features();
00454 
00455     int32_t degree = o->degree;
00456     int32_t string_length = o->string_length;
00457     int32_t alphabet_size = o->alphabet_size;
00458     int32_t* w_offsets = o->w_offsets;
00459     float32_t* wd_weights = o->wd_weights;
00460     float32_t* w= o->w;
00461 
00462     float64_t* y = o->lab;
00463     float64_t normalization_const = o->normalization_const;
00464 
00465 
00466     for (int32_t j=0; j<string_length; j++)
00467     {
00468         int32_t offs=o->w_dim_single_char*j;
00469         for (int32_t i=start ; i<end; i++)
00470             val[i]=0;
00471 
00472         int32_t lim=CMath::min(degree, string_length-j);
00473         int32_t len;
00474 
00475         for (int32_t k=0; k<lim; k++)
00476         {
00477             bool free_vec;
00478             uint8_t* vec=f->get_feature_vector(j+k, len, free_vec);
00479             float32_t wd = wd_weights[k];
00480 
00481             for (int32_t i=start; i<end; i++) // quite fast 1.9s
00482             {
00483                 val[i]=val[i]*alphabet_size + vec[i];
00484                 out[i]+=wd*w[offs+val[i]];
00485             }
00486 
00487             /*for (int32_t i=0; i<nData/4; i++) // slowest 2s
00488             {
00489                 uint32_t x=((uint32_t*) vec)[i];
00490                 int32_t ii=4*i;
00491                 val[ii]=val[ii]*alphabet_size + (x&255);
00492                 val[ii+1]=val[ii+1]*alphabet_size + ((x>>8)&255);
00493                 val[ii+2]=val[ii+2]*alphabet_size + ((x>>16)&255);
00494                 val[ii+3]=val[ii+3]*alphabet_size + (x>>24);
00495                 out[ii]+=wd*w[offs+val[ii]];
00496                 out[ii+1]+=wd*w[offs+val[ii+1]];
00497                 out[ii+2]+=wd*w[offs+val[ii+2]];
00498                 out[ii+3]+=wd*w[offs+val[ii+3]];
00499             }*/
00500 
00501             /*for (int32_t i=0; i<nData>>3; i++) // fastest on 64bit: 1.5s
00502             {
00503                 uint64_t x=((uint64_t*) vec)[i];
00504                 int32_t ii=i<<3;
00505                 val[ii]=val[ii]*alphabet_size + (x&255);
00506                 val[ii+1]=val[ii+1]*alphabet_size + ((x>>8)&255);
00507                 val[ii+2]=val[ii+2]*alphabet_size + ((x>>16)&255);
00508                 val[ii+3]=val[ii+3]*alphabet_size + ((x>>24)&255);
00509                 val[ii+4]=val[ii+4]*alphabet_size + ((x>>32)&255);
00510                 val[ii+5]=val[ii+5]*alphabet_size + ((x>>40)&255);
00511                 val[ii+6]=val[ii+6]*alphabet_size + ((x>>48)&255);
00512                 val[ii+7]=val[ii+7]*alphabet_size + (x>>56);
00513                 out[ii]+=wd*w[offs+val[ii]];
00514                 out[ii+1]+=wd*w[offs+val[ii+1]];
00515                 out[ii+2]+=wd*w[offs+val[ii+2]];
00516                 out[ii+3]+=wd*w[offs+val[ii+3]];
00517                 out[ii+4]+=wd*w[offs+val[ii+4]];
00518                 out[ii+5]+=wd*w[offs+val[ii+5]];
00519                 out[ii+6]+=wd*w[offs+val[ii+6]];
00520                 out[ii+7]+=wd*w[offs+val[ii+7]];
00521             }*/
00522             offs+=w_offsets[k];
00523             f->free_feature_vector(vec, j+k, free_vec);
00524         }
00525     }
00526 
00527     for (int32_t i=start; i<end; i++)
00528         output[i]=y[i]*o->bias + out[i]*y[i]/normalization_const;
00529 
00530     //CMath::display_vector(o->w, o->w_dim, "w");
00531     //CMath::display_vector(output, nData, "out");
00532     return NULL;
00533 }
00534 
00535 int CWDSVMOcas::compute_output( float64_t *output, void* ptr )
00536 {
00537     CWDSVMOcas* o = (CWDSVMOcas*) ptr;
00538     int32_t nData=o->num_vec;
00539     wdocas_thread_params_output* params_output=SG_MALLOC(wdocas_thread_params_output, o->parallel->get_num_threads());
00540     pthread_t* threads = SG_MALLOC(pthread_t, o->parallel->get_num_threads());
00541 
00542     float32_t* out=SG_MALLOC(float32_t, nData);
00543     int32_t* val=SG_MALLOC(int32_t, nData);
00544     memset(out, 0, sizeof(float32_t)*nData);
00545 
00546     int32_t t;
00547     int32_t nthreads=o->parallel->get_num_threads()-1;
00548     int32_t step= nData/o->parallel->get_num_threads();
00549 
00550     if (step<1)
00551     {
00552         nthreads=nData-1;
00553         step=1;
00554     }
00555 
00556     for (t=0; t<nthreads; t++)
00557     {
00558         params_output[t].wdocas=o;
00559         params_output[t].output=output;
00560         params_output[t].out=out;
00561         params_output[t].val=val;
00562         params_output[t].start = step*t;
00563         params_output[t].end = step*(t+1);
00564 
00565         //SG_SPRINT("t=%d start=%d end=%d output=%p\n", t, params_output[t].start, params_output[t].end, params_output[t].output);
00566         if (pthread_create(&threads[t], NULL, &CWDSVMOcas::compute_output_helper, (void*)&params_output[t]) != 0)
00567         {
00568             nthreads=t;
00569             SG_SWARNING("thread creation failed\n");
00570             break;
00571         }
00572     }
00573 
00574     params_output[t].wdocas=o;
00575     params_output[t].output=output;
00576     params_output[t].out=out;
00577     params_output[t].val=val;
00578     params_output[t].start = step*t;
00579     params_output[t].end = nData;
00580     compute_output_helper(&params_output[t]);
00581     //SG_SPRINT("t=%d start=%d end=%d output=%p\n", t, params_output[t].start, params_output[t].end, params_output[t].output);
00582 
00583     for (t=0; t<nthreads; t++)
00584     {
00585         if (pthread_join(threads[t], NULL) != 0)
00586             SG_SWARNING( "pthread_join failed\n");
00587     }
00588     SG_FREE(threads);
00589     SG_FREE(params_output);
00590     SG_FREE(val);
00591     SG_FREE(out);
00592     return 0;
00593 }
00594 /*----------------------------------------------------------------------
00595   sq_norm_W = compute_W( alpha, nSel ) does the following:
00596 
00597   oldW = W;
00598   W = sparse_A(:,1:nSel)'*alpha;
00599   sq_norm_W = W'*W;
00600   dp_WoldW = W'*oldW';
00601 
00602   ----------------------------------------------------------------------*/
00603 void CWDSVMOcas::compute_W(
00604     float64_t *sq_norm_W, float64_t *dp_WoldW, float64_t *alpha, uint32_t nSel,
00605     void* ptr)
00606 {
00607     CWDSVMOcas* o = (CWDSVMOcas*) ptr;
00608     uint32_t nDim= (uint32_t) o->w_dim;
00609     CMath::swap(o->w, o->old_w);
00610     float32_t* W=o->w;
00611     float32_t* oldW=o->old_w;
00612     float32_t** cuts=o->cuts;
00613     memset(W, 0, sizeof(float32_t)*nDim);
00614     float64_t* c_bias = o->cp_bias;
00615     float64_t old_bias=o->bias;
00616     float64_t bias=0;
00617 
00618     for (uint32_t i=0; i<nSel; i++)
00619     {
00620         if (alpha[i] > 0)
00621             CMath::vec1_plus_scalar_times_vec2(W, (float32_t) alpha[i], cuts[i], nDim);
00622 
00623         bias += c_bias[i]*alpha[i];
00624     }
00625 
00626     *sq_norm_W = CMath::dot(W,W, nDim) +CMath::sq(bias);
00627     *dp_WoldW = CMath::dot(W,oldW, nDim) + bias*old_bias;;
00628     //SG_PRINT("nSel=%d sq_norm_W=%f dp_WoldW=%f\n", nSel, *sq_norm_W, *dp_WoldW);
00629 
00630     o->bias = bias;
00631     o->old_bias = old_bias;
00632 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation