structmatrix soverrelaxation(structmatrix *A, structmatrix *b){ const unsigned int MAXITER=100; const double TOL=1e-6; double *xp=calloc(A->nrows,sizeof(double));//init guess 0s double *x= calloc(A->nrows,sizeof(double));// structmatrix XP=creatematrix(xp ,A->nrows,1//solns in col vector ,endt(MATDOUBLE),rowmjr); structmatrix X=creatematrix(x ,A->nrows,1//solns in col vector ,endt(MATDOUBLE),rowmjr); fpidx idxA= getidxingfunc( A); fpidx idxb= getidxingfunc( b); fpidx idxX= getidxingfunc(&X); fpidx idxXP=getidxingfunc(&XP); #define Xv(ri,ci) *(double*) idxX( &ri,&ci,&X) #define XPv(ri,ci) *(double*) idxXP(&ri,&ci,&XP) #define Av(ri,ci) *(double*) idxA( &ri,&ci, A) #define bv(ri,ci) *(double*) idxb( &ri,&ci, b) unsigned int zero=0; double omega=.5;//b/w 0 and 2 unsigned int k=0; while(k<MAXITER){ unsigned ri; for(ri=0;ri<A->nrows;ri++){ double newsumsoln=0;unsigned int sumi=0; for(sumi=0;(sumi<(ri));sumi++)//tricky iter {newsumsoln=newsumsoln-Av(ri,sumi)*Xv(sumi,zero);} double oldsumsoln=0; for(sumi=ri+1;(sumi<A->nrows);sumi++) {oldsumsoln=oldsumsoln-Av(ri,sumi)*XPv(sumi,zero);} Xv(ri,zero)=(1/Av(ri,ri))*(newsumsoln+oldsumsoln+bv(ri,zero))*omega +(1-omega)*XPv(ri,zero); } double normofdiff=0; for(ri=0;ri<X.nrows;ri++){ normofdiff+=pow((Xv(ri,zero)-XPv(ri,zero)),2);} normofdiff=pow(normofdiff,.5); if(normofdiff<TOL){printf("converged in %d iterations\n",k+1);return X;} for(ri=0;ri<X.nrows;ri++){XPv(ri,zero)=Xv(ri,zero);} k++; } free(XP.data); return X; #undef Xv #undef XPv #undef Av #undef bv }
double l2r_l2_ranksvm_fun::fun(double *w) { int q,i,j; double f = 0; int l = prob->l; int w_size = get_nr_variable(); selectiontree *T; Xv(w,z); for (q=0;q<nr_query;q++) { int *perm_q = &perm[start[q]]; id_and_value *order_perm_q = order_perm[q]; for (i=0;i<count[q];i++) { order_perm_q[i].id = perm_q[i]; order_perm_q[i].value = z[perm_q[i]]; } qsort(order_perm_q, count[q], sizeof(id_and_value), compare_values); T = new selectiontree(nr_class[q]); j = 0; for (i=0;i<count[q];i++) { while (j<count[q] && (1 - order_perm_q[j].value + order_perm_q[i].value>0)) { T->insert_node(int_y[order_perm_q[j].id], order_perm_q[j].value); j++; } T->larger(int_y[order_perm_q[i].id], &l_plus[order_perm_q[i].id], &alpha_plus[order_perm_q[i].id]); } delete T; j = count[q] - 1; T = new selectiontree(nr_class[q]); for (i=count[q]-1;i>=0;i--) { while (j>=0 && (1 - order_perm_q[i].value + order_perm_q[j].value>0)) { T->insert_node(int_y[order_perm_q[j].id], order_perm_q[j].value); j--; } T->smaller(int_y[order_perm_q[i].id], &l_minus[order_perm_q[i].id], &alpha_minus[order_perm_q[i].id]); } delete T; } for(i=0;i<w_size;i++) f += w[i] * w[i]; f /= 2.0; for(i=0;i<l;i++) f += C * (z[i] * ((l_plus[i] + l_minus[i]) * z[i] - alpha_minus[i] - alpha_plus[i] - 2 * (l_minus[i] - l_plus[i])) + l_minus[i]); return(f); }
void init_env(t_env *e) { int i; struct rlimit rlp; X(-1, getrlimit(RLIMIT_NOFILE, &rlp), "getrlimit"); e->maxfd = rlp.rlim_cur; e->fds = (t_fd*)Xv(NULL, malloc(sizeof(*e->fds) * e->maxfd), "malloc"); i = 0; while (i < e->maxfd) { clean_fd(&e->fds[i]); i++; } }
void l2_lr_fun::Hv(double *s, double *Hs) { int i; int l=prob->l; int n=prob->n; double *wa = new double[l]; Xv(s, wa); for(i=0;i<l;i++) wa[i] = C[i]*D[i]*wa[i]; XTv(wa, Hs); for(i=0;i<n;i++) Hs[i] = s[i] + Hs[i]; delete[] wa; }
void l2r_lr_fun::Hv(double *s, double *Hs) { int i; int l=prob->l; int w_size=get_nr_variable(); double *wa = new double[l]; Xv(s, wa); for(i=0;i<l;i++) wa[i] = C[i]*D[i]*wa[i]; XTv(wa, Hs); for(i=0;i<w_size;i++) Hs[i] = s[i] + Hs[i]; delete[] wa; }
void l2r_l2_ranksvm_fun::Hv(double *s, double *Hs) { int q,i,j; int w_size = get_nr_variable(); int l = prob->l; double *wa = new double[l]; selectiontree *T; double* alpha_plus_minus; alpha_plus_minus = new double[l]; Xv(s, wa); for (q=0;q<nr_query;q++) { id_and_value *order_perm_q = order_perm[q]; T = new selectiontree(nr_class[q]); j = 0; for (i=0;i<count[q];i++) { while (j<count[q] && (1 - order_perm_q[j].value + order_perm_q[i].value>0)) { T->insert_node(int_y[order_perm_q[j].id],wa[order_perm_q[j].id]); j++; } alpha_plus_minus[order_perm_q[i].id] = T->xv_larger(int_y[order_perm_q[i].id]); } delete T; j = count[q] - 1; T = new selectiontree(nr_class[q]); for (i=count[q]-1;i>=0;i--) { while (j>=0 && (1 - order_perm_q[i].value + order_perm_q[j].value>0)) { T->insert_node(int_y[order_perm_q[j].id], wa[order_perm_q[j].id]); j--; } alpha_plus_minus[order_perm_q[i].id] += T->xv_smaller(int_y[order_perm_q[i].id]); } delete T; } for (i=0;i<l;i++) wa[i] = wa[i] * (l_plus[i] + l_minus[i]) - alpha_plus_minus[i]; delete[] alpha_plus_minus; XTv(wa, Hs); delete[] wa; for(i=0;i<w_size;i++) Hs[i] = s[i] + 2 * C * Hs[i]; }
void selection_rank_fun::Hv(double *s, double *Hs) { int i,j,k; int w_size=get_nr_variable(); int l=prob->l; double *wa = new double[l]; selectiontree *T; double* alpha_plus_minus; alpha_plus_minus = new double[l]; Xv(s, wa); for (i=0;i<nr_subset;i++) { T=new selectiontree(nr_class[i]); k=0; for (j=0;j<count[i];j++) { while (k<count[i]&&(1-pi[i][j].value+pi[i][k].value>0)) { T->insert_node(int_y[pi[i][k].id],wa[pi[i][k].id]); k++; } alpha_plus_minus[pi[i][j].id]=T->vector_sum_smaller(int_y[pi[i][j].id]); } delete T; k=count[i]-1; T = new selectiontree(nr_class[i]); for (j=count[i]-1;j>=0;j--) { while (k>=0&&(1+pi[i][j].value-pi[i][k].value>0)) { T->insert_node(int_y[pi[i][k].id],wa[pi[i][k].id]); k--; } alpha_plus_minus[pi[i][j].id]+=T->vector_sum_larger(int_y[pi[i][j].id]); } delete T; } for (i=0;i<l;i++) wa[i]=wa[i]*((double)l_plus[i]+(double)l_minus[i])-alpha_plus_minus[i]; delete[] alpha_plus_minus; XTv(wa, Hs); delete[] wa; for(i=0;i<w_size;i++) Hs[i] = s[i] + 2*C*Hs[i]; }
double l2loss_svm_fun::fun(double *w) { int i; double f=0; int *y=prob->y; int l=prob->l; int n=prob->n; Xv(w, z); for(i=0;i<l;i++) { z[i] = y[i]*z[i]; double d = 1-z[i]; if (d > 0) f += C[i]*d*d; } f = 2*f; for(i=0;i<n;i++) f += w[i]*w[i]; f /= 2.0; return(f); }
double l2r_l2_svc_fun::fun(double *w) { int i; double f=0; int *y=prob->y; int l=prob->l; int w_size=get_nr_variable(); Xv(w, z); for(i=0;i<l;i++) { z[i] = y[i]*z[i]; double d = 1-z[i]; if (d > 0) f += C[i]*d*d; } f = 2*f; for(i=0;i<w_size;i++) f += w[i]*w[i]; f /= 2.0; return(f); }
double l2_lr_fun::fun(double *w) { int i; double f=0; int *y=prob->y; int l=prob->l; int n=prob->n; Xv(w, z); for(i=0;i<l;i++) { double yz = y[i]*z[i]; if (yz >= 0) f += C[i]*log(1 + exp(-yz)); else f += C[i]*(-yz+log(1 + exp(yz))); } f = 2*f; for(i=0;i<n;i++) f += w[i]*w[i]; f /= 2.0; return(f); }
double l2r_lr_fun::fun(double *w) { int i; double f=0; int *y=prob->y; int l=prob->l; int w_size=get_nr_variable(); Xv(w, z); for(i=0;i<l;i++) { double yz = y[i]*z[i]; if (yz >= 0) f += C[i]*log(1 + exp(-yz)); else f += C[i]*(-yz+log(1 + exp(yz))); } f = 2*f; for(i=0;i<w_size;i++) f += w[i]*w[i]; f /= 2.0; return(f); }
double selection_rank_fun::fun(double *w, long int *num_data) { int i,j,k; double f=0.0; int l=prob->l; int w_size=get_nr_variable(); selectiontree *T; Xv(w,z); *num_data += l; for (i=0;i<nr_subset;i++) { for (j=0;j<count[i];j++) { pi[i][j].id = perm[j+start[i]]; pi[i][j].value = z[perm[j+start[i]]]; } qsort(pi[i], count[i], sizeof(id_and_value), compare_id_and_value); T=new selectiontree(nr_class[i]); k=0; for (j=0;j<count[i];j++) { while (k<count[i]&&(1-pi[i][j].value+pi[i][k].value>0)) { T->insert_node(int_y[pi[i][k].id],pi[i][k].value); k++; } T->count_smaller(int_y[pi[i][j].id],&l_minus[pi[i][j].id], &alpha_minus[pi[i][j].id]); } delete T; k=count[i]-1; T = new selectiontree(nr_class[i]); for (j=count[i]-1;j>=0;j--) { while (k>=0&&(1+pi[i][j].value-pi[i][k].value>0)) { T->insert_node(int_y[pi[i][k].id],pi[i][k].value); k--; } T->count_larger(int_y[pi[i][j].id],&l_plus[pi[i][j].id], &alpha_plus[pi[i][j].id]); } delete T; } long long nSV = 0; for (i=0;i<l;i++) nSV += l_plus[i]; //info("nSV = %ld\n",nSV); for(i=0;i<w_size;i++) { f += w[i]*w[i]; } f /= 2.0; for(i=0;i<l;i++) { f += C*(z[i]*((l_plus[i]+l_minus[i])*z[i]-alpha_minus[i]-alpha_plus[i]-2*(l_minus[i]-l_plus[i]))+l_minus[i]); } return (f); }
void selection_rank_fun::Hv(double *s, double *Hs) { int i,j,k; int w_size=get_nr_variable(); int l=prob->l; double *wa = new double[l]; selectiontree *T; double* alpha_plus_minus; alpha_plus_minus = new double[l]; double begin, end; begin = omp_get_wtime(); Xv(s, wa); end = omp_get_wtime(); Xviter++; Xvtime += end-begin; begin = omp_get_wtime(); #pragma omp parallel for default(shared) private(i, j, k, T) for (i=0;i<nr_subset;i++) { T=new selectiontree(nr_class[i]);// nr_class[i]is the i-th query's number of different label k=0; for (j=0;j<count[i];j++) { while (k<count[i]&&(1-pi[i][j].value+pi[i][k].value>0)) { T->insert_node(int_y[pi[i][k].id],wa[pi[i][k].id]); k++; } alpha_plus_minus[pi[i][j].id]=T->vector_sum_smaller(int_y[pi[i][j].id]); } delete T; k=count[i]-1; T = new selectiontree(nr_class[i]); for (j=count[i]-1;j>=0;j--) { while (k>=0&&(1+pi[i][j].value-pi[i][k].value>0)) { T->insert_node(int_y[pi[i][k].id],wa[pi[i][k].id]); k--; } alpha_plus_minus[pi[i][j].id]+=T->vector_sum_larger(int_y[pi[i][j].id]); } delete T; } end = omp_get_wtime(); AViter++; AVtime += end-begin; #pragma omp parallel for default(shared) private(i) for (i=0;i<l;i++) wa[i]=wa[i]*((double)l_plus[i]+(double)l_minus[i])-alpha_plus_minus[i]; delete[] alpha_plus_minus; begin = omp_get_wtime(); XTv(wa, Hs); end = omp_get_wtime(); XTviter++; XTvtime += end-begin; delete[] wa; #pragma omp parallel for default(shared) private(i) for(i=0;i<w_size;i++) Hs[i] = s[i] + 2*C*Hs[i]; }
double selection_rank_fun::fun(double *w) { int i,j,k; double f = 0.0; int l=prob->l; int w_size=get_nr_variable(); selectiontree *T; double begin,end; begin = omp_get_wtime(); Xv(w,z); end = omp_get_wtime(); Xviter++; Xvtime += end-begin; begin = omp_get_wtime(); #pragma omp parallel for default(shared) private(i, j, k, T) //construct the OST for (i=0;i<nr_subset;i++) { for (j=0;j<count[i];j++) { pi[i][j].id = perm[j+start[i]]; pi[i][j].value = z[perm[j+start[i]]]; } qsort(pi[i], count[i], sizeof(id_and_value), compare_id_and_value); T=new selectiontree(nr_class[i]); k=0; for (j=0;j<count[i];j++) { while (k<count[i]&&(1-pi[i][j].value+pi[i][k].value>0)) { T->insert_node(int_y[pi[i][k].id],pi[i][k].value); k++; } T->count_smaller(int_y[pi[i][j].id],&l_minus[pi[i][j].id], &alpha_minus[pi[i][j].id]); } delete T; k=count[i]-1; T = new selectiontree(nr_class[i]); for (j=count[i]-1;j>=0;j--) { while (k>=0&&(1+pi[i][j].value-pi[i][k].value>0)) { T->insert_node(int_y[pi[i][k].id],pi[i][k].value); k--; } T->count_larger(int_y[pi[i][j].id],&l_plus[pi[i][j].id], &alpha_plus[pi[i][j].id]); } delete T; } end = omp_get_wtime(); AViter++; AVtime += end-begin; long long nSV = 0; #pragma omp parallel for default(shared) reduction(+:nSV) private(i) for (i=0;i<l;i++) nSV += l_plus[i]; //info("nSV = %ld\n",nSV); for(i=0;i<w_size;i++) { f += w[i]*w[i]; } f /= 2.0; #pragma omp parallel for default(shared) private(i) reduction(+:f) for(i=0;i<l;i++) { f += C*(z[i]*((l_plus[i]+l_minus[i])*z[i]-alpha_minus[i]-alpha_plus[i]-2.0*(l_minus[i]-l_plus[i]))+l_minus[i]); } return (f); }
//todo put convergence into one function structmatrix conjugategradient(structmatrix *A,structmatrix *b){ const unsigned int MAXITER=100; const MATDOUBLE TOL=1e-6; MATDOUBLE *xp=calloc(A->nrows,sizeof(MATDOUBLE));//init guess 0s MATDOUBLE *x= malloc(A->nrows*sizeof(MATDOUBLE));// structmatrix XP=creatematrix(xp ,A->nrows,1//solns in col vector ,endt(MATDOUBLE),rowmjr); structmatrix X=creatematrix(x ,A->nrows,1//solns in col vector ,endt(MATDOUBLE),rowmjr); structmatrix rP=copymatrix(b); //previous error structmatrix pP=copymatrix(b); //CG vec structmatrix r=creatematrix(malloc(sizeof(MATDOUBLE)*rP.nrows) ,rP.nrows,1 ,endt(MATDOUBLE),rowmjr); structmatrix p=creatematrix(malloc(sizeof(MATDOUBLE)*pP.nrows) ,pP.nrows,1 ,endt(MATDOUBLE),rowmjr); fpidx idxA= getidxingfunc( A); fpidx idxb= getidxingfunc( b); fpidx idxX= getidxingfunc(&X); fpidx idxXP=getidxingfunc(&XP); fpidx idxrP=getidxingfunc(&rP); fpidx idxpP=getidxingfunc(&pP); fpidx idxr =getidxingfunc(&r ); fpidx idxp =getidxingfunc(&p ); #define Xv(ri,ci) *(double*) idxX( &ri,&ci,&X) #define XPv(ri,ci) *(double*) idxXP(&ri,&ci,&XP) #define Av(ri,ci) *(double*) idxA( &ri,&ci, A) #define bv(ri,ci) *(double*) idxb( &ri,&ci, b) #define rPv(ri,ci) *(double*) idxrP( &ri,&ci, &rP) #define pPv(ri,ci) *(double*) idxb( &ri,&ci, &pP) #define rv(ri,ci) *(double*) idxA( &ri,&ci, &r) #define pv(ri,ci) *(double*) idxb( &ri,&ci, &p) //result definition #define ApPv(ri,ci) *(double*) idxApP(&ri,&ci,&ApP) unsigned int zero=0; unsigned int k=0; while(k<MAXITER){ double alpha, beta;//scalars to compute in each interatin structmatrix rPT=(vecT(&rP)),pPT=vecT(&pP); structmatrix rPTrP=matrixmatrixmuldbl(&rPT,&rP);//1x1 structmatrix ApP=matrixmatrixmuldbl(A,&pP);// vec nrows fpidx idxApP =getidxingfunc(&ApP); double alphan=*(double*) rPTrP.data; double alphad=*(double*) (matrixmatrixmuldbl(&pPT,&ApP)).data; alpha=alphan/alphad;//alpha new unsigned int ri; for(ri=0;ri<XP.nrows;ri++){ Xv(ri,zero)=XPv(ri,zero)+alpha*pPv(ri,zero); //new x approx soln rv(ri,zero)=rPv(ri,zero)-alpha*ApPv(ri,zero);//new r error } structmatrix rT=vecT(&r); structmatrix rTr=matrixmatrixmuldbl(&rT,&r); beta=(*(double*) rTr.data)/(*(double*) rPTrP.data); //scalar/scalar for(ri=0;ri<p.nrows;ri++){ pv(ri,zero)=rv(ri,zero)+beta*pPv(ri,zero); } double normofr=0; for(ri=0;ri<X.nrows;ri++){normofr+=pow(rv(ri,zero),2);} normofr=pow(normofr,.5); if(normofr<TOL){printf("converged\n in %d iterations\n",k+1);return X;} //previous=current for(ri=0;ri<X.nrows;ri++){ XPv(ri,zero)=Xv(ri,zero); pPv(ri,zero)=pv(ri,zero); rPv(ri,zero)=rv(ri,zero); } /* todo does not work if i add these free statements does the memory get freed with each loop? i thought it would not!*/ /* free(rPT.data); free(rPTrP.data); free(ApP.data); free(rT.data); free(rTr.data); */ k++;} free(XP.data); free(rP.data); free(pP.data); free(r.data); free(p.data); return X; #undef Xv #undef XPv #undef Av #undef bv #undef rPv #undef pPv #undef rv #undef pv #undef ApPv }