SVECTOR* add_dual_list_ns_r(SVECTOR *a, SVECTOR *b, double min_non_zero) /* computes the linear combination of the two SVECTOR lists weighted by the factor of each SVECTOR */ { SVECTOR *f,*sum; for(f=a;f->next;f=f->next); /* find end of first vector list */ f->next=b; /* temporarily append the two vector lists */ sum=add_list_ns_r(a,min_non_zero); f->next=NULL; /* undo append */ return(sum); }
double add_constraint_to_constraint_cache(CCACHE *ccache, MODEL *svmModel, int exnum, SVECTOR *fydelta, double rhs, double gainthresh, int maxconst, double *rt_cachesum) /* add new constraint fydelta*w>rhs for example exnum to cache, if it is more violated (by gainthresh) than the currently most violated constraint in cache. if this grows the number of cached constraints for this example beyond maxconst, then the least recently used constraint is deleted. the function assumes that update_constraint_cache_for_model has been run. */ { double viol,viol_gain,viol_gain_trunc; double dist_ydelta; DOC *doc_fydelta; SVECTOR *fydelta_new; CCACHEELEM *celem; int cnum; double rt2=0; /* compute violation of new constraint */ doc_fydelta=create_example(1,0,1,1,fydelta); dist_ydelta=classify_example(svmModel,doc_fydelta); free_example(doc_fydelta,0); viol=rhs-dist_ydelta; viol_gain=viol-ccache->constlist[exnum]->viol; viol_gain_trunc=viol-MAX(ccache->constlist[exnum]->viol,0); ccache->avg_viol_gain[exnum]=viol_gain; /* check if violation of new constraint is larger than that of the best cache element */ if(viol_gain > gainthresh) { fydelta_new=fydelta; if(struct_verbosity>=2) rt2=get_runtime(); if(svmModel->kernel_parm.kernel_type == LINEAR_KERNEL) { if(COMPACT_CACHED_VECTORS == 1) { /* eval sum for linear */ fydelta_new=add_list_sort_ss_r(fydelta,COMPACT_ROUNDING_THRESH); free_svector(fydelta); } else if(COMPACT_CACHED_VECTORS == 2) { fydelta_new=add_list_ss_r(fydelta,COMPACT_ROUNDING_THRESH); free_svector(fydelta); } else if(COMPACT_CACHED_VECTORS == 3) { fydelta_new=add_list_ns_r(fydelta,COMPACT_ROUNDING_THRESH); free_svector(fydelta); } } if(struct_verbosity>=2) (*rt_cachesum)+=MAX(get_runtime()-rt2,0); celem=ccache->constlist[exnum]; ccache->constlist[exnum]=(CCACHEELEM *)my_malloc(sizeof(CCACHEELEM)); ccache->constlist[exnum]->next=celem; ccache->constlist[exnum]->fydelta=fydelta_new; ccache->constlist[exnum]->rhs=rhs; ccache->constlist[exnum]->viol=viol; ccache->changed[exnum]+=2; /* remove last constraint in list, if list is longer than maxconst */ cnum=2; for(celem=ccache->constlist[exnum];celem && celem->next && celem->next->next;celem=celem->next) cnum++; if(cnum>maxconst) { free_svector(celem->next->fydelta); free(celem->next); celem->next=NULL; } } else { free_svector(fydelta); } return(viol_gain_trunc); }
SVECTOR* add_list_ns(SVECTOR *a) { return(add_list_ns_r(a,0)); }