// // Created by joe on 4/12/15. // #include "rankaccu.h" using namespace std; const double offset = 1; void ranksort(int l,int r,vector<int> &rank,const vector<double> &ref1,const vector<double> &ref2) { int i=l,j=r,k; double mid1=ref1[rank[(l+r)>>1]],mid2=ref2[rank[(l+r)>>1]]; while (i<=j) { while (ref1[rank[i]]>mid1 || (ref1[rank[i]]==mid1 && ref2[rank[i]]>mid2)) ++i; while (ref1[rank[j]]<mid1 || (ref1[rank[j]]==mid1 && ref2[rank[j]]<mid2)) --j; if (i<=j) { k=rank[i]; rank[i]=rank[j]; rank[j]=k; ++i; --j; } } if (j>l) ranksort(l,j,rank,ref1,ref2); if (i<r) ranksort(i,r,rank,ref1,ref2); } void rankmerge(int l,int r,vector<int> &C,vector<int> &rank,const vector<double> &ref1,const vector<double> &ref2) { if (l==r) return; int i=l,j=((l+r)>>1)+1; rankmerge(i,j-1,C,rank,ref1,ref2); rankmerge(j,r,C,rank,ref1,ref2); vector<int> stage_r((unsigned long)r-l+1),stage_c((unsigned long)r-l+1); int cnt=0; int k=0; while (i<=((l+r)>>1) && j<=r) { if (ref1[rank[i]]>ref1[rank[j]] || (ref1[rank[i]]==ref1[rank[j]] && ref2[rank[i]]>ref2[rank[j]])) { stage_c[k] = C[i]; stage_r[k++] = rank[i++]; ++cnt; } else{ stage_c[k] = C[j]+cnt; stage_r[k++] = rank[j++]; } } while (i<=((l+r)>>1)) { stage_c[k] = C[i]; stage_r[k++] = rank[i++]; } while (j<=r) { stage_c[k] = C[j]+cnt; stage_r[k++] = rank[j++]; } for (i=l;i<=r;++i) { C[i]=stage_c[i-l]; rank[i]=stage_r[i-l]; } } void rank_accu(RidList &D,const vector<double> pred) { unsigned long n = D.getSize(); vector<int> orig_rank(n),pred_rank(n),C(n); vector<double> orig(n); int i,j; for (i=0;i<D.getSize();++i) { orig_rank[i]=i; pred_rank[i]=i; orig[i]=D.getL(i); } double accu_nDCG=0; double accu_AP=0; for (j=0; j<D.getSize();j+=D.getqSize()) { i=j+D.getqSize()-1; double Y=0,Z=0; double AP=0; ranksort(j,i,orig_rank,orig,pred); ranksort(j,i,pred_rank,pred,orig); for (int k = j;k<=i;++k) { Z += (pow(2,offset+orig[orig_rank[k]]) - 1)/log2(2+k-j); Y += (pow(2,offset+orig[pred_rank[k]]) - 1)/log2(2+k-j); } accu_nDCG+=Y/Z; rankmerge(j,i,C,orig_rank,pred,orig); for (int k = j+1;k<=i;++k) AP += ((double)C[k])/(k-j); AP=AP*2/(i-j)-1; accu_AP+=AP; LOG(INFO)<<"qid:"<<D.getQid(j)<<"; nDCG:"<<Y/Z<<"; AP:"<< AP; } LOG(INFO)<<"over "<< D.getuSize()<< " queries. "<<"Average nDGC: "<< accu_nDCG/D.getuSize()<< " Average AP: "<<accu_AP/D.getuSize(); } void rank_CMC(RidList &D,const std::vector<double> pred,CMC & cmc) { unsigned long n = D.getSize(); vector<int> pred_rank(n); vector<double> orig(n); int i,j; for (i=0;i<D.getSize();++i) { pred_rank[i]=i; orig[i]=D.getL(i); } for (j=0; j<D.getSize();j+=D.getqSize()) { i=j+D.getqSize()-1; ranksort(j,i,pred_rank,pred,orig); for (int k=j;k<=i;++k) if (orig[pred_rank[k]]>0) { LOG(INFO)<<"qid:"<<D.getQid(j)<<"; pred:"<<pred[k]<<"; rank:"<< k-j; cmc.addEntry(k-j); break; // account only for the first match; } LOG(INFO)<<"top: "<< D.getO(pred_rank[j]%D.getqSize())->qid <<" "<<D.getO(pred_rank[j+1]%D.getqSize())->qid <<" "<<D.getO(pred_rank[j+2]%D.getqSize())->qid <<" "<<D.getO(pred_rank[j+3]%D.getqSize())->qid <<" "<<D.getO(pred_rank[j+4]%D.getqSize())->qid <<" "<< D.getO(pred_rank[j+5]%D.getqSize())->qid <<" "<<D.getO(pred_rank[j+6]%D.getqSize())->qid <<" "<<D.getO(pred_rank[j+7]%D.getqSize())->qid <<" "<<D.getO(pred_rank[j+8]%D.getqSize())->qid <<" "<<D.getO(pred_rank[j+9]%D.getqSize())->qid; } } void rank_pair(RidList &D,const vector<double> pred,vector<double> &pair) { int n =D.getSize(),q=D.getqSize(); pair.clear(); for (int i=0;i<n;i+=q) { int corr=0; for (int j=0;j<q;++j) if (D.getL(i+j)>0) { corr = j; break; } for (int j=0;j<q;++j) if (j!=corr) pair.push_back(pred[i+corr]-pred[i+j]); } }