diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | model/ranksvm.cpp | 2 | ||||
| -rw-r--r-- | model/ranksvmtn.cpp | 19 | ||||
| -rw-r--r-- | tools/dataProvider.h | 73 | 
4 files changed, 70 insertions, 26 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c579851..4ae8e51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES ( "/usr/include/eigen3" )  # Use Random Library for Random Number Generation -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fopenmp")  FIND_PACKAGE( Boost COMPONENTS program_options REQUIRED )  INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR}) diff --git a/model/ranksvm.cpp b/model/ranksvm.cpp index a468729..acc2f4e 100644 --- a/model/ranksvm.cpp +++ b/model/ranksvm.cpp @@ -15,7 +15,7 @@ int maxiter = 1; // max iteration count  double prec=1e-10; // precision  // conjugate gradient  double cg_prec=1e-3; // precision -int cg_maxiter = 500; +int cg_maxiter = 1000;  int ls_maxiter = 20;  // line search  double line_prec=1e-10; // precision diff --git a/model/ranksvmtn.cpp b/model/ranksvmtn.cpp index 7f292f5..ba2d5a3 100644 --- a/model/ranksvmtn.cpp +++ b/model/ranksvmtn.cpp @@ -9,23 +9,26 @@ using namespace Eigen;  void cal_Dw(RidList &D,const VectorXd &w, VectorXd &Dw)  {      int n = D.getSize(); -    #pragma omp parallel for +    // static chunk size of 1 to interleave the iterations +    #pragma omp parallel for schedule(static,1)      for (int i=0;i<n;++i) -        Dw(i) = D.getVec(i).dot(w); +        Dw(i) = D.getVecDot(i,w);  }  void cal_Dtw(RidList &D,const VectorXd &w, VectorXd &Dw)  {      int n = D.getSize(); -    #pragma omp parallel +    int fsize = D.getfSize(); +    #pragma omp parallel shared(D,Dw)      {          VectorXd Dw_private = VectorXd::Zero(D.getfSize());          #pragma omp for nowait          for (int i=0;i<n;++i) -            Dw_private = Dw_private + D.getVec(i)*w(i); +            D.addVecw(i,w(i),Dw_private);          #pragma omp critical          { -            Dw=Dw+Dw_private; +            for (int i=0;i<fsize;++i) +                Dw(i) = Dw(i) + Dw_private(i);          }      }  } @@ -55,8 +58,10 @@ int cal_Hs(RidList &D,const vector<int> &rank,const VectorXd &corr,const VectorX              else                  g+=Ds[rank[i+j]];      } -    VectorXd tmp = alpha.cwiseProduct(Ds)-gamma; -    VectorXd res = VectorXd::Zero(D.getSize()); +    VectorXd tmp(n); +    for (int i=0;i<n;++i) +        tmp(i) = alpha(i)*Ds(i)-gamma(i); +    VectorXd res = VectorXd::Zero(D.getfSize());      cal_Dtw(D,tmp,res);      Hs = s + C*res;      return 0; diff --git a/tools/dataProvider.h b/tools/dataProvider.h index 348d15c..4dc9c41 100644 --- a/tools/dataProvider.h +++ b/tools/dataProvider.h @@ -4,6 +4,7 @@  #include<Eigen/Dense>  #include "../tools/easylogging++.h"  #include<vector> +#include<math.h>  // TODO decide how to construct training data  // One possible way for training data: @@ -93,8 +94,8 @@ public:      }      inline std::string getQid(int x)      { -        int a,b,n=getqSize(); -        a=x/n; +        int a,b,q=getqSize(); +        a=x/q;          return getU(a)->qid;      }      inline int getqSize() @@ -112,25 +113,63 @@ public:          return getuSize()*getqSize();      }      inline Eigen::VectorXd getVec(int x){ -        int a,b,n=getqSize(); -        a=x/n; -        b=x%n; -        Eigen::VectorXd vec; +        int a,b,q=getqSize(); +        a=x/q; +        b=x%q; +        Eigen::VectorXd *id,*oth; +        id = &(uniq[a]->feature);          if (single) -            return (uniq[a]->feature-other[b]->feature).cwiseAbs(); -        if (b<a) -            vec=uniq[a]->feature-uniq[b]->feature; +            oth = &(other[b]->feature); +        else if (b<a) +            oth = &(uniq[b]->feature); +        else if (b<uniq.size()-1) +            oth = &(uniq[b+1]->feature);          else -        if (b<uniq.size()-1) -            vec=uniq[a]->feature-uniq[b+1]->feature; -        else -            vec=uniq[a]->feature-other[b-uniq.size()+1]->feature; -        return vec.cwiseAbs(); +            oth = &(other[b-uniq.size()+1]->feature); +        return (*id-*oth).cwiseAbs();      }; +    inline double getVecDot(int x,const Eigen::VectorXd &w) +    { +        int a,b,q=getqSize(); +        a=x/q; +        b=x%q; +        double res = 0; +        Eigen::VectorXd *id,*oth; +        id = &(uniq[a]->feature); +        if (single) +            oth = &(other[b]->feature); +        else if (b<a) +            oth = &(uniq[b]->feature); +        else if (b<uniq.size()-1) +            oth = &(uniq[b+1]->feature); +        else +            oth = &(other[b-uniq.size()+1]->feature); +        for (int i=0;i<n;++i) +            res += fabs((*id)[i] - (*oth)[i])*w[i]; +        return res; +    } +    inline void addVecw(int x,double w,Eigen::VectorXd &X) +    { +        int a,b,q=getqSize(); +        a=x/q; +        b=x%q; +        Eigen::VectorXd *id,*oth; +        id = &(uniq[a]->feature); +        if (single) +            oth = &(other[b]->feature); +        else if (b<a) +            oth = &(uniq[b]->feature); +        else if (b<uniq.size()-1) +            oth = &(uniq[b+1]->feature); +        else +            oth = &(other[b-uniq.size()+1]->feature); +        for (int i=0;i<n;++i) +            X[i] += fabs((*id)[i] - (*oth)[i])*w; +    }      inline double getL(int x){ -        int a,b,n=getqSize(); -        a=x/n; -        b=x%n; +        int a,b,q=getqSize(); +        a=x/q; +        b=x%q;          if (single)          {              if (std::fabs(other[b]->rank - a) < 1e-5)  | 
