00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <shogun/lib/config.h>
00012
00013 #ifdef USE_SVMLIGHT
00014
00015 #include <shogun/io/SGIO.h>
00016 #include <shogun/mathematics/lapack.h>
00017 #include <shogun/lib/Signal.h>
00018 #include <shogun/mathematics/Math.h>
00019 #include <shogun/regression/svr/SVRLight.h>
00020 #include <shogun/machine/KernelMachine.h>
00021 #include <shogun/kernel/CombinedKernel.h>
00022
00023 #include <unistd.h>
00024
00025 #ifdef USE_CPLEX
00026 extern "C" {
00027 #include <ilcplex/cplex.h>
00028 }
00029 #endif
00030
00031 #include <shogun/base/Parallel.h>
00032
00033 #ifdef HAVE_PTHREAD
00034 #include <pthread.h>
00035 #endif
00036
00037 using namespace shogun;
00038
00039 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00040 struct S_THREAD_PARAM
00041 {
00042 float64_t* lin;
00043 int32_t start, end;
00044 int32_t* active2dnum;
00045 int32_t* docs;
00046 CKernel* kernel;
00047 int32_t num_vectors;
00048 };
00049 #endif // DOXYGEN_SHOULD_SKIP_THIS
00050
00051 CSVRLight::CSVRLight(float64_t C, float64_t eps, CKernel* k, CLabels* lab)
00052 : CSVMLight(C, k, lab)
00053 {
00054 set_tube_epsilon(eps);
00055 }
00056
00057 CSVRLight::CSVRLight()
00058 : CSVMLight()
00059 {
00060 }
00061
00062 bool CSVRLight::train_machine(CFeatures* data)
00063 {
00064
00065 verbosity=1;
00066 init_margin=0.15;
00067 init_iter=500;
00068 precision_violations=0;
00069 opt_precision=DEF_PRECISION;
00070
00071 strcpy (learn_parm->predfile, "");
00072 learn_parm->biased_hyperplane=1;
00073 learn_parm->sharedslack=0;
00074 learn_parm->remove_inconsistent=0;
00075 learn_parm->skip_final_opt_check=1;
00076 learn_parm->svm_maxqpsize=get_qpsize();
00077 learn_parm->svm_newvarsinqp=learn_parm->svm_maxqpsize-1;
00078 learn_parm->maxiter=100000;
00079 learn_parm->svm_iter_to_shrink=100;
00080 learn_parm->svm_c=get_C1();
00081 learn_parm->transduction_posratio=0.33;
00082 learn_parm->svm_costratio=get_C2()/get_C1();
00083 learn_parm->svm_costratio_unlab=1.0;
00084 learn_parm->svm_unlabbound=1E-5;
00085 learn_parm->epsilon_crit=epsilon;
00086 learn_parm->epsilon_a=1E-15;
00087 learn_parm->compute_loo=0;
00088 learn_parm->rho=1.0;
00089 learn_parm->xa_depth=0;
00090
00091 if (!kernel)
00092 {
00093 SG_ERROR( "SVR_light can not proceed without kernel!\n");
00094 return false ;
00095 }
00096
00097 if (!labels)
00098 {
00099 SG_ERROR( "SVR_light can not proceed without labels!\n");
00100 return false;
00101 }
00102
00103 if (data)
00104 {
00105 if (labels->get_num_labels() != data->get_num_vectors())
00106 SG_ERROR("Number of training vectors does not match number of labels\n");
00107 kernel->init(data, data);
00108 }
00109
00110 if (kernel->has_property(KP_LINADD) && get_linadd_enabled())
00111 kernel->clear_normal();
00112
00113
00114 SG_DEBUG( "qpsize = %i\n", learn_parm->svm_maxqpsize) ;
00115 SG_DEBUG( "epsilon = %1.1e\n", learn_parm->epsilon_crit) ;
00116 SG_DEBUG( "kernel->has_property(KP_LINADD) = %i\n", kernel->has_property(KP_LINADD)) ;
00117 SG_DEBUG( "kernel->has_property(KP_KERNCOMBINATION) = %i\n", kernel->has_property(KP_KERNCOMBINATION)) ;
00118 SG_DEBUG( "get_linadd_enabled() = %i\n", get_linadd_enabled()) ;
00119 SG_DEBUG( "kernel->get_num_subkernels() = %i\n", kernel->get_num_subkernels()) ;
00120
00121 use_kernel_cache = !((kernel->get_kernel_type() == K_CUSTOM) ||
00122 (get_linadd_enabled() && kernel->has_property(KP_LINADD)));
00123
00124 SG_DEBUG( "use_kernel_cache = %i\n", use_kernel_cache) ;
00125
00126
00127 svr_learn();
00128
00129
00130 create_new_model(model->sv_num-1);
00131 set_bias(-model->b);
00132 for (int32_t i=0; i<model->sv_num-1; i++)
00133 {
00134 set_alpha(i, model->alpha[i+1]);
00135 set_support_vector(i, model->supvec[i+1]);
00136 }
00137
00138 if (kernel->has_property(KP_LINADD) && get_linadd_enabled())
00139 kernel->clear_normal() ;
00140
00141 return true ;
00142 }
00143
00144 void CSVRLight::svr_learn()
00145 {
00146 int32_t *inconsistent, i, j;
00147 int32_t upsupvecnum;
00148 float64_t maxdiff, *lin, *c, *a;
00149 int32_t iterations;
00150 float64_t *xi_fullset;
00151 float64_t *a_fullset;
00152 TIMING timing_profile;
00153 SHRINK_STATE shrink_state;
00154 int32_t* label;
00155 int32_t* docs;
00156
00157 ASSERT(labels);
00158 int32_t totdoc=labels->get_num_labels();
00159 num_vectors=totdoc;
00160
00161
00162 docs=SG_MALLOC(int32_t, 2*totdoc);
00163 label=SG_MALLOC(int32_t, 2*totdoc);
00164 c = SG_MALLOC(float64_t, 2*totdoc);
00165
00166 for(i=0;i<totdoc;i++) {
00167 docs[i]=i;
00168 j=2*totdoc-1-i;
00169 label[i]=+1;
00170 c[i]=labels->get_label(i);
00171 docs[j]=j;
00172 label[j]=-1;
00173 c[j]=labels->get_label(i);
00174 }
00175 totdoc*=2;
00176
00177
00178 kernel->resize_kernel_cache( kernel->get_cache_size(), true);
00179
00180 if (kernel->get_kernel_type() == K_COMBINED)
00181 {
00182 CCombinedKernel* k = (CCombinedKernel*) kernel;
00183 CKernel* kn = k->get_first_kernel();
00184
00185 while (kn)
00186 {
00187 kn->resize_kernel_cache( kernel->get_cache_size(), true);
00188 SG_UNREF(kn);
00189 kn = k->get_next_kernel();
00190 }
00191 }
00192
00193 timing_profile.time_kernel=0;
00194 timing_profile.time_opti=0;
00195 timing_profile.time_shrink=0;
00196 timing_profile.time_update=0;
00197 timing_profile.time_model=0;
00198 timing_profile.time_check=0;
00199 timing_profile.time_select=0;
00200
00201 SG_FREE(W);
00202 W=NULL;
00203
00204 if (kernel->has_property(KP_KERNCOMBINATION) && callback)
00205 {
00206 W = SG_MALLOC(float64_t, totdoc*kernel->get_num_subkernels());
00207 for (i=0; i<totdoc*kernel->get_num_subkernels(); i++)
00208 W[i]=0;
00209 }
00210
00211
00212 if((learn_parm->svm_newvarsinqp < 2)
00213 || (learn_parm->svm_newvarsinqp > learn_parm->svm_maxqpsize)) {
00214 learn_parm->svm_newvarsinqp=learn_parm->svm_maxqpsize;
00215 }
00216
00217 init_shrink_state(&shrink_state,totdoc,(int32_t)MAXSHRINK);
00218
00219 inconsistent = SG_MALLOC(int32_t, totdoc);
00220 a = SG_MALLOC(float64_t, totdoc);
00221 a_fullset = SG_MALLOC(float64_t, totdoc);
00222 xi_fullset = SG_MALLOC(float64_t, totdoc);
00223 lin = SG_MALLOC(float64_t, totdoc);
00224 learn_parm->svm_cost = SG_MALLOC(float64_t, totdoc);
00225 if (m_linear_term.vlen>0)
00226 learn_parm->eps=get_linear_term_array();
00227 else
00228 {
00229 learn_parm->eps=SG_MALLOC(float64_t, totdoc);
00230 CMath::fill_vector(learn_parm->eps, totdoc, tube_epsilon);
00231 }
00232
00233 SG_FREE(model->supvec);
00234 SG_FREE(model->alpha);
00235 SG_FREE(model->index);
00236 model->supvec = SG_MALLOC(int32_t, totdoc+2);
00237 model->alpha = SG_MALLOC(float64_t, totdoc+2);
00238 model->index = SG_MALLOC(int32_t, totdoc+2);
00239
00240 model->at_upper_bound=0;
00241 model->b=0;
00242 model->supvec[0]=0;
00243 model->alpha[0]=0;
00244 model->totdoc=totdoc;
00245
00246 model->kernel=kernel;
00247
00248 model->sv_num=1;
00249 model->loo_error=-1;
00250 model->loo_recall=-1;
00251 model->loo_precision=-1;
00252 model->xa_error=-1;
00253 model->xa_recall=-1;
00254 model->xa_precision=-1;
00255
00256 for(i=0;i<totdoc;i++) {
00257 inconsistent[i]=0;
00258 a[i]=0;
00259 lin[i]=0;
00260
00261 if(label[i] > 0) {
00262 learn_parm->svm_cost[i]=learn_parm->svm_c*learn_parm->svm_costratio*
00263 fabs((float64_t)label[i]);
00264 }
00265 else if(label[i] < 0) {
00266 learn_parm->svm_cost[i]=learn_parm->svm_c*fabs((float64_t)label[i]);
00267 }
00268 else
00269 ASSERT(false);
00270 }
00271
00272 if(verbosity==1) {
00273 SG_DEBUG( "Optimizing...\n");
00274 }
00275
00276
00277 SG_DEBUG( "num_train: %d\n", totdoc);
00278 iterations=optimize_to_convergence(docs,label,totdoc,
00279 &shrink_state,inconsistent,a,lin,
00280 c,&timing_profile,
00281 &maxdiff,(int32_t)-1,
00282 (int32_t)1);
00283
00284
00285 if(verbosity>=1) {
00286 SG_DONE();
00287 SG_INFO("(%ld iterations)\n",iterations);
00288 SG_INFO( "Optimization finished (maxdiff=%.8f).\n",maxdiff);
00289 SG_INFO( "obj = %.16f, rho = %.16f\n",get_objective(),model->b);
00290
00291 upsupvecnum=0;
00292
00293 SG_DEBUG( "num sv: %d\n", model->sv_num);
00294 for(i=1;i<model->sv_num;i++)
00295 {
00296 if(fabs(model->alpha[i]) >=
00297 (learn_parm->svm_cost[model->supvec[i]]-
00298 learn_parm->epsilon_a))
00299 upsupvecnum++;
00300 }
00301 SG_INFO( "Number of SV: %ld (including %ld at upper bound)\n",
00302 model->sv_num-1,upsupvecnum);
00303 }
00304
00305
00306
00307 for(i=1;i<model->sv_num;i++) {
00308 j=model->supvec[i];
00309 if(j >= (totdoc/2)) {
00310 j=totdoc-j-1;
00311 }
00312 model->supvec[i]=j;
00313 }
00314
00315 shrink_state_cleanup(&shrink_state);
00316 SG_FREE(label);
00317 SG_FREE(inconsistent);
00318 SG_FREE(c);
00319 SG_FREE(a);
00320 SG_FREE(a_fullset);
00321 SG_FREE(xi_fullset);
00322 SG_FREE(lin);
00323 SG_FREE(learn_parm->svm_cost);
00324 SG_FREE(docs);
00325 }
00326
00327 float64_t CSVRLight::compute_objective_function(
00328 float64_t *a, float64_t *lin, float64_t *c, float64_t* eps, int32_t *label,
00329 int32_t totdoc)
00330 {
00331
00332 float64_t criterion=0;
00333
00334 for(int32_t i=0;i<totdoc;i++)
00335 criterion+=(eps[i]-(float64_t)label[i]*c[i])*a[i]+0.5*a[i]*label[i]*lin[i];
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 return(criterion);
00349 }
00350
00351 void* CSVRLight::update_linear_component_linadd_helper(void *params_)
00352 {
00353 S_THREAD_PARAM * params = (S_THREAD_PARAM*) params_ ;
00354
00355 int32_t jj=0, j=0 ;
00356
00357 for(jj=params->start;(jj<params->end) && (j=params->active2dnum[jj])>=0;jj++)
00358 params->lin[j]+=params->kernel->compute_optimized(CSVRLight::regression_fix_index2(params->docs[j], params->num_vectors));
00359
00360 return NULL ;
00361 }
00362
00363
00364 void CSVRLight::update_linear_component(
00365 int32_t* docs, int32_t* label, int32_t *active2dnum, float64_t *a,
00366 float64_t *a_old, int32_t *working2dnum, int32_t totdoc, float64_t *lin,
00367 float64_t *aicache, float64_t* c)
00368
00369
00370
00371
00372 {
00373 register int32_t i=0,ii=0,j=0,jj=0;
00374
00375 if (kernel->has_property(KP_LINADD) && get_linadd_enabled())
00376 {
00377 if (callback)
00378 {
00379 update_linear_component_mkl_linadd(docs, label, active2dnum, a, a_old, working2dnum,
00380 totdoc, lin, aicache, c) ;
00381 }
00382 else
00383 {
00384 kernel->clear_normal();
00385
00386 int32_t num_working=0;
00387 for(ii=0;(i=working2dnum[ii])>=0;ii++) {
00388 if(a[i] != a_old[i]) {
00389 kernel->add_to_normal(regression_fix_index(docs[i]), (a[i]-a_old[i])*(float64_t)label[i]);
00390 num_working++;
00391 }
00392 }
00393
00394 if (num_working>0)
00395 {
00396 if (parallel->get_num_threads() < 2)
00397 {
00398 for(jj=0;(j=active2dnum[jj])>=0;jj++) {
00399 lin[j]+=kernel->compute_optimized(regression_fix_index(docs[j]));
00400 }
00401 }
00402 #ifdef HAVE_PTHREAD
00403 else
00404 {
00405 int32_t num_elem = 0 ;
00406 for(jj=0;(j=active2dnum[jj])>=0;jj++) num_elem++ ;
00407
00408 pthread_t* threads = SG_MALLOC(pthread_t, parallel->get_num_threads()-1);
00409 S_THREAD_PARAM* params = SG_MALLOC(S_THREAD_PARAM, parallel->get_num_threads()-1);
00410 int32_t start = 0 ;
00411 int32_t step = num_elem/parallel->get_num_threads() ;
00412 int32_t end = step ;
00413
00414 for (int32_t t=0; t<parallel->get_num_threads()-1; t++)
00415 {
00416 params[t].kernel = kernel ;
00417 params[t].lin = lin ;
00418 params[t].docs = docs ;
00419 params[t].active2dnum=active2dnum ;
00420 params[t].start = start ;
00421 params[t].end = end ;
00422 params[t].num_vectors=num_vectors ;
00423
00424 start=end ;
00425 end+=step ;
00426 pthread_create(&threads[t], NULL, update_linear_component_linadd_helper, (void*)¶ms[t]) ;
00427 }
00428
00429 for(jj=params[parallel->get_num_threads()-2].end;(j=active2dnum[jj])>=0;jj++) {
00430 lin[j]+=kernel->compute_optimized(regression_fix_index(docs[j]));
00431 }
00432 void* ret;
00433 for (int32_t t=0; t<parallel->get_num_threads()-1; t++)
00434 pthread_join(threads[t], &ret) ;
00435
00436 SG_FREE(params);
00437 SG_FREE(threads);
00438 }
00439 #endif
00440 }
00441 }
00442 }
00443 else
00444 {
00445 if (callback)
00446 {
00447 update_linear_component_mkl(docs, label, active2dnum,
00448 a, a_old, working2dnum, totdoc, lin, aicache, c) ;
00449 }
00450 else {
00451 for(jj=0;(i=working2dnum[jj])>=0;jj++) {
00452 if(a[i] != a_old[i]) {
00453 kernel->get_kernel_row(i,active2dnum,aicache);
00454 for(ii=0;(j=active2dnum[ii])>=0;ii++)
00455 lin[j]+=(a[i]-a_old[i])*aicache[j]*(float64_t)label[i];
00456 }
00457 }
00458 }
00459 }
00460 }
00461
00462 void CSVRLight::update_linear_component_mkl(
00463 int32_t* docs, int32_t* label, int32_t *active2dnum, float64_t *a,
00464 float64_t *a_old, int32_t *working2dnum, int32_t totdoc, float64_t *lin,
00465 float64_t *aicache, float64_t* c)
00466 {
00467 int32_t num = totdoc;
00468 int32_t num_weights = -1;
00469 int32_t num_kernels = kernel->get_num_subkernels() ;
00470 const float64_t* old_beta = kernel->get_subkernel_weights(num_weights);
00471
00472 ASSERT(num_weights==num_kernels);
00473
00474 if ((kernel->get_kernel_type()==K_COMBINED) &&
00475 (!((CCombinedKernel*)kernel)->get_append_subkernel_weights()))
00476 {
00477 CCombinedKernel* k = (CCombinedKernel*) kernel;
00478 CKernel* kn = k->get_first_kernel() ;
00479 int32_t n = 0, i, j ;
00480
00481 while (kn!=NULL)
00482 {
00483 for(i=0;i<num;i++)
00484 {
00485 if(a[i] != a_old[i])
00486 {
00487 kn->get_kernel_row(i,NULL,aicache, true);
00488 for(j=0;j<num;j++)
00489 W[j*num_kernels+n]+=(a[i]-a_old[i])*aicache[regression_fix_index(j)]*(float64_t)label[i];
00490 }
00491 }
00492 SG_UNREF(kn);
00493 kn = k->get_next_kernel();
00494 n++ ;
00495 }
00496 }
00497 else
00498 {
00499 float64_t* w_backup = SG_MALLOC(float64_t, num_kernels);
00500 float64_t* w1 = SG_MALLOC(float64_t, num_kernels);
00501
00502
00503 for (int32_t i=0; i<num_kernels; i++)
00504 {
00505 w_backup[i] = old_beta[i] ;
00506 w1[i]=0.0 ;
00507 }
00508 for (int32_t n=0; n<num_kernels; n++)
00509 {
00510 w1[n]=1.0 ;
00511 kernel->set_subkernel_weights(w1, num_weights) ;
00512
00513 for(int32_t i=0;i<num;i++)
00514 {
00515 if(a[i] != a_old[i])
00516 {
00517 for(int32_t j=0;j<num;j++)
00518 W[j*num_kernels+n]+=(a[i]-a_old[i])*compute_kernel(i,j)*(float64_t)label[i];
00519 }
00520 }
00521 w1[n]=0.0 ;
00522 }
00523
00524
00525 kernel->set_subkernel_weights(w_backup,num_weights) ;
00526
00527 SG_FREE(w_backup);
00528 SG_FREE(w1);
00529 }
00530
00531 call_mkl_callback(a, label, lin, c, totdoc);
00532 }
00533
00534
00535 void CSVRLight::update_linear_component_mkl_linadd(
00536 int32_t* docs, int32_t* label, int32_t *active2dnum, float64_t *a,
00537 float64_t *a_old, int32_t *working2dnum, int32_t totdoc, float64_t *lin,
00538 float64_t *aicache, float64_t* c)
00539 {
00540
00541
00542 int32_t num = totdoc;
00543 int32_t num_weights = -1;
00544 int32_t num_kernels = kernel->get_num_subkernels() ;
00545 const float64_t* old_beta = kernel->get_subkernel_weights(num_weights);
00546
00547 ASSERT(num_weights==num_kernels);
00548
00549 float64_t* w_backup=SG_MALLOC(float64_t, num_kernels);
00550 float64_t* w1=SG_MALLOC(float64_t, num_kernels);
00551
00552
00553 for (int32_t i=0; i<num_kernels; i++)
00554 {
00555 w_backup[i] = old_beta[i] ;
00556 w1[i]=1.0 ;
00557 }
00558
00559 kernel->set_subkernel_weights(w1, num_weights) ;
00560
00561
00562 kernel->clear_normal();
00563 for(int32_t ii=0, i=0;(i=working2dnum[ii])>=0;ii++) {
00564 if(a[i] != a_old[i]) {
00565 kernel->add_to_normal(regression_fix_index(docs[i]), (a[i]-a_old[i])*(float64_t)label[i]);
00566 }
00567 }
00568
00569
00570 for (int32_t i=0; i<num; i++)
00571 kernel->compute_by_subkernel(i,&W[i*num_kernels]) ;
00572
00573
00574 kernel->set_subkernel_weights(w_backup,num_weights) ;
00575
00576 SG_FREE(w_backup);
00577 SG_FREE(w1);
00578
00579 call_mkl_callback(a, label, lin, c, totdoc);
00580 }
00581
00582 void CSVRLight::call_mkl_callback(float64_t* a, int32_t* label, float64_t* lin, float64_t* c, int32_t totdoc)
00583 {
00584 int32_t num = totdoc;
00585 int32_t num_kernels = kernel->get_num_subkernels() ;
00586 int nk = (int) num_kernels;
00587 float64_t sumalpha = 0;
00588 float64_t* sumw=SG_MALLOC(float64_t, num_kernels);
00589
00590 for (int32_t i=0; i<num; i++)
00591 sumalpha-=a[i]*(learn_parm->eps[i]-label[i]*c[i]);
00592
00593 #ifdef HAVE_LAPACK
00594 double* alphay = SG_MALLOC(double, num);
00595 for (int32_t i=0; i<num; i++)
00596 alphay[i]=a[i]*label[i];
00597
00598 for (int32_t i=0; i<num_kernels; i++)
00599 sumw[i]=0;
00600
00601 cblas_dgemv(CblasColMajor, CblasNoTrans, nk, (int) num, 0.5, (double*) W,
00602 nk, (double*) alphay, 1, 1.0, (double*) sumw, 1);
00603
00604 SG_FREE(alphay);
00605 #else
00606 for (int32_t d=0; d<num_kernels; d++)
00607 {
00608 sumw[d]=0;
00609 for(int32_t i=0; i<num; i++)
00610 sumw[d] += 0.5*a[i]*label[i]*W[i*num_kernels+d];
00611 }
00612 #endif
00613
00614 if (callback)
00615 mkl_converged=callback(mkl, sumw, sumalpha);
00616
00617 const float64_t* new_beta = kernel->get_subkernel_weights(num_kernels);
00618
00619
00620 #ifdef HAVE_LAPACK
00621 cblas_dgemv(CblasColMajor, CblasTrans, nk, (int) num, 1.0, (double*) W,
00622 nk, (double*) new_beta, 1, 0.0, (double*) lin, 1);
00623 #else
00624 for(int32_t i=0; i<num; i++)
00625 lin[i]=0 ;
00626 for (int32_t d=0; d<num_kernels; d++)
00627 if (new_beta[d]!=0)
00628 for(int32_t i=0; i<num; i++)
00629 lin[i] += new_beta[d]*W[i*num_kernels+d] ;
00630 #endif
00631
00632
00633 SG_FREE(sumw);
00634 }
00635
00636
00637 void CSVRLight::reactivate_inactive_examples(
00638 int32_t* label, float64_t *a, SHRINK_STATE *shrink_state, float64_t *lin,
00639 float64_t *c, int32_t totdoc, int32_t iteration, int32_t *inconsistent,
00640 int32_t* docs, float64_t *aicache, float64_t *maxdiff)
00641
00642
00643
00644 {
00645 register int32_t i=0,j,ii=0,jj,t,*changed2dnum,*inactive2dnum;
00646 int32_t *changed,*inactive;
00647 register float64_t *a_old,dist;
00648 float64_t ex_c,target;
00649
00650 if (kernel->has_property(KP_LINADD) && get_linadd_enabled()) {
00651 a_old=shrink_state->last_a;
00652
00653 kernel->clear_normal();
00654 int32_t num_modified=0;
00655 for(i=0;i<totdoc;i++) {
00656 if(a[i] != a_old[i]) {
00657 kernel->add_to_normal(regression_fix_index(docs[i]), ((a[i]-a_old[i])*(float64_t)label[i]));
00658 a_old[i]=a[i];
00659 num_modified++;
00660 }
00661 }
00662
00663 if (num_modified>0)
00664 {
00665 for(i=0;i<totdoc;i++) {
00666 if(!shrink_state->active[i]) {
00667 lin[i]=shrink_state->last_lin[i]+kernel->compute_optimized(regression_fix_index(docs[i]));
00668 }
00669 shrink_state->last_lin[i]=lin[i];
00670 }
00671 }
00672 }
00673 else
00674 {
00675 changed=SG_MALLOC(int32_t, totdoc);
00676 changed2dnum=SG_MALLOC(int32_t, totdoc+11);
00677 inactive=SG_MALLOC(int32_t, totdoc);
00678 inactive2dnum=SG_MALLOC(int32_t, totdoc+11);
00679 for(t=shrink_state->deactnum-1;(t>=0) && shrink_state->a_history[t];t--) {
00680 if(verbosity>=2) {
00681 SG_INFO( "%ld..",t);
00682 }
00683 a_old=shrink_state->a_history[t];
00684 for(i=0;i<totdoc;i++) {
00685 inactive[i]=((!shrink_state->active[i])
00686 && (shrink_state->inactive_since[i] == t));
00687 changed[i]= (a[i] != a_old[i]);
00688 }
00689 compute_index(inactive,totdoc,inactive2dnum);
00690 compute_index(changed,totdoc,changed2dnum);
00691
00692 for(ii=0;(i=changed2dnum[ii])>=0;ii++) {
00693 CKernelMachine::kernel->get_kernel_row(i,inactive2dnum,aicache);
00694 for(jj=0;(j=inactive2dnum[jj])>=0;jj++)
00695 lin[j]+=(a[i]-a_old[i])*aicache[j]*(float64_t)label[i];
00696 }
00697 }
00698 SG_FREE(changed);
00699 SG_FREE(changed2dnum);
00700 SG_FREE(inactive);
00701 SG_FREE(inactive2dnum);
00702 }
00703
00704 (*maxdiff)=0;
00705 for(i=0;i<totdoc;i++) {
00706 shrink_state->inactive_since[i]=shrink_state->deactnum-1;
00707 if(!inconsistent[i]) {
00708 dist=(lin[i]-model->b)*(float64_t)label[i];
00709 target=-(learn_parm->eps[i]-(float64_t)label[i]*c[i]);
00710 ex_c=learn_parm->svm_cost[i]-learn_parm->epsilon_a;
00711 if((a[i]>learn_parm->epsilon_a) && (dist > target)) {
00712 if((dist-target)>(*maxdiff))
00713 (*maxdiff)=dist-target;
00714 }
00715 else if((a[i]<ex_c) && (dist < target)) {
00716 if((target-dist)>(*maxdiff))
00717 (*maxdiff)=target-dist;
00718 }
00719 if((a[i]>(0+learn_parm->epsilon_a))
00720 && (a[i]<ex_c)) {
00721 shrink_state->active[i]=1;
00722 }
00723 else if((a[i]<=(0+learn_parm->epsilon_a)) && (dist < (target+learn_parm->epsilon_shrink))) {
00724 shrink_state->active[i]=1;
00725 }
00726 else if((a[i]>=ex_c)
00727 && (dist > (target-learn_parm->epsilon_shrink))) {
00728 shrink_state->active[i]=1;
00729 }
00730 else if(learn_parm->sharedslack) {
00731 shrink_state->active[i]=1;
00732 }
00733 }
00734 }
00735 if (use_kernel_cache) {
00736 for(i=0;i<totdoc;i++) {
00737 (shrink_state->a_history[shrink_state->deactnum-1])[i]=a[i];
00738 }
00739 for(t=shrink_state->deactnum-2;(t>=0) && shrink_state->a_history[t];t--) {
00740 SG_FREE(shrink_state->a_history[t]);
00741 shrink_state->a_history[t]=0;
00742 }
00743 }
00744 }
00745 #endif //USE_SVMLIGHT