SVECTOR* shift_s(SVECTOR *a, long shift) /* shifts the feature numbers by shift positions */ { SVECTOR *vec; register WORD *sum,*sumi; register WORD *ai; long veclength; ai=a->words; veclength=0; while (ai->wnum) { veclength++; ai++; } veclength++; sum=(WORD *)my_malloc(sizeof(WORD)*veclength); sumi=sum; ai=a->words; while (ai->wnum) { (*sumi)=(*ai); sumi->wnum+=shift; ai++; sumi++; } sumi->wnum=0; vec=create_svector_shallow(sum,a->userdefined,a->factor); return(vec); }
SVECTOR* smult_s(SVECTOR *a, double factor) /* scale sparse vector a by factor */ { SVECTOR *vec; register WORD *sum,*sumi; register WORD *ai; long veclength; ai=a->words; veclength=0; while (ai->wnum) { veclength++; ai++; } veclength++; sum=(WORD *)my_malloc(sizeof(WORD)*veclength); sumi=sum; ai=a->words; while (ai->wnum) { (*sumi)=(*ai); sumi->weight*=factor; if(sumi->weight != 0) sumi++; ai++; } sumi->wnum=0; vec=create_svector_shallow(sum,a->userdefined,1.0); return(vec); }
SVECTOR *copy_svector_shallow(SVECTOR *vec) /* unlike 'copy_svector' this does not copy words and userdefined */ { SVECTOR *newvec=NULL; if(vec) { newvec=create_svector_shallow(vec->words,vec->userdefined,vec->factor); newvec->next=copy_svector_shallow(vec->next); } return(newvec); }
SVECTOR* add_list_sort_ss_r(SVECTOR *a, double min_non_zero) /* Like add_list_sort_ss(SVECTOR *a), but rounds values smaller than min_non_zero to zero. */ { SVECTOR *sum,*f; WORD empty[2],*ai,*concat,*concati,*concat_read,*concat_write; long length,i; double weight; if(a){ /* count number or entries over all vectors */ length=0; for(f=a;f;f=f->next) { ai=f->words; while (ai->wnum) { length++; ai++; } } /* write all entries into one long array and sort by feature number */ concat=(WORD *)my_malloc(sizeof(WORD)*(length+1)); concati=concat; for(f=a;f;f=f->next) { ai=f->words; while (ai->wnum) { (*concati)=(*ai); concati->weight*=f->factor; concati++; ai++; } } qsort(concat,length,sizeof(WORD),compareup_word); concat_read=concat+1; concat_write=concat; for(i=0;(i<length-1) && (concat_write->wnum != concat_read->wnum);i++) { concat_write++; concat_read++; } weight=concat_write->weight; for(i=i;(i<length-1);i++) { if(concat_write->wnum == concat_read->wnum) { weight+=(double)concat_read->weight; concat_read++; } else { if((weight > min_non_zero) || (weight < -min_non_zero)) { concat_write->weight=weight; concat_write++; } (*concat_write)=(*concat_read); weight=concat_write->weight; concat_read++; } } if((length>0) && ((weight > min_non_zero) || (weight < -min_non_zero))) { concat_write->weight=weight; concat_write++; } concat_write->wnum=0; if(1) { /* this wastes some memory, but saves malloc'ing */ sum=create_svector_shallow(concat,NULL,1.0); } else { /* this is more memory efficient */ sum=create_svector(concat,NULL,1.0); free(concat); } } else { empty[0].wnum=0; sum=create_svector(empty,NULL,1.0); } return(sum); }
SVECTOR* multadd_ss_r(SVECTOR *a,SVECTOR *b,double fa, double fb, double min_non_zero) /* compute fa*a+fb*b of two sparse vectors */ /* Note: SVECTOR lists are not followed, but only the first SVECTOR is used */ { SVECTOR *vec; register WORD *sum,*sumi; register WORD *ai,*bj; long veclength; double weight; ai=a->words; bj=b->words; veclength=0; while (ai->wnum && bj->wnum) { if(ai->wnum > bj->wnum) { veclength++; bj++; } else if (ai->wnum < bj->wnum) { veclength++; ai++; } else { veclength++; ai++; bj++; } } while (bj->wnum) { veclength++; bj++; } while (ai->wnum) { veclength++; ai++; } veclength++; sum=(WORD *)my_malloc(sizeof(WORD)*veclength); sumi=sum; ai=a->words; bj=b->words; while (ai->wnum && bj->wnum) { if(ai->wnum > bj->wnum) { (*sumi)=(*bj); sumi->weight*=fb; sumi++; bj++; } else if (ai->wnum < bj->wnum) { (*sumi)=(*ai); sumi->weight*=fa; sumi++; ai++; } else { weight=fa*(double)ai->weight+fb*(double)bj->weight; if((weight<-min_non_zero) || (weight>min_non_zero)) { sumi->wnum=ai->wnum; sumi->weight=weight; sumi++; } ai++; bj++; } } while (bj->wnum) { (*sumi)=(*bj); sumi->weight*=fb; sumi++; bj++; } while (ai->wnum) { (*sumi)=(*ai); sumi->weight*=fa; sumi++; ai++; } sumi->wnum=0; if(1) { /* potentially this wastes some memory, but saves malloc'ing */ vec=create_svector_shallow(sum,NULL,1.0); } else { /* this is more memory efficient */ vec=create_svector(sum,NULL,1.0); free(sum); } return(vec); }