inline void interp1_helper_nearest(const Mat<eT>& XG, const Mat<eT>& YG, const Mat<eT>& XI, Mat<eT>& YI, const eT extrap_val) { arma_extra_debug_sigprint(); const eT XG_min = XG.min(); const eT XG_max = XG.max(); YI.copy_size(XI); const eT* XG_mem = XG.memptr(); const eT* YG_mem = YG.memptr(); const eT* XI_mem = XI.memptr(); eT* YI_mem = YI.memptr(); const uword NG = XG.n_elem; const uword NI = XI.n_elem; uword best_j = 0; for(uword i=0; i<NI; ++i) { eT best_err = Datum<eT>::inf; const eT XI_val = XI_mem[i]; if((XI_val < XG_min) || (XI_val > XG_max)) { YI_mem[i] = extrap_val; } else { // XG and XI are guaranteed to be sorted in ascending manner, // so start searching XG from last known optimum position for(uword j=best_j; j<NG; ++j) { const eT tmp = XG_mem[j] - XI_val; const eT err = (tmp >= eT(0)) ? tmp : -tmp; if(err >= best_err) { // error is going up, so we have found the optimum position break; } else { best_err = err; best_j = j; // remember the optimum position } } YI_mem[i] = YG_mem[best_j]; } } }
void parse_matrices(string file, Mat<double> & M, Mat<double> & P0, Mat<double> & P1, Mat<int> & C, int nrows) { ifstream ifs; ifs.open(file.c_str()); if(!ifs.good()) { cerr << "Error: couldn't open " << file << endl; exit(1); } string str; vector<string> tokens; int m=-1,i=0; int P0reducedcols=0; int P1reducedcols=0; while(true) { bool spacer=false; do { if(!ifs.eof()) { getline(ifs,str); } else { str=""; } str=str.substr(0, str.find_first_of("#")); tokens.clear(); tokenise(str, tokens, " "); if(tokens.size() < 1) spacer=true; } while(!ifs.eof() && tokens.size() < 1); if(str.size()==0 && ifs.eof()) break; if(spacer) { m++; i=0; } if(m==-1) m=0; if(m==0) M.resize(nrows,tokens.size()); if(m==1) C.resize(nrows,tokens.size()); if(m==2) P0.resize(nrows,tokens.size()); if(m==3) P1.resize(nrows,tokens.size()); if(i >= nrows) { cerr << "Error: number of rows of matrices greater than number of samples.\n"; exit(1); } for(int t=0; t < tokens.size(); t++) { if(m==0) M(i,t) = atof(tokens[t].c_str()); if(m==1) C(i,t) = atoi(tokens[t].c_str()); if(m==2) { for(int j=0; j < nrows; j++) { if(i > max(C.col(0))) { cerr << "Error: more distinct rows of P than classes for model 0 (" << i << " > " << max(C.col(0)) << ").\n"; exit(1); } if(C(j,0)==i) { P0(j,t)= atof(tokens[t].c_str()); } } P0reducedcols = max(P0reducedcols, i); } if(m==3) { for(int j=0; j < nrows; j++) { if(i > max(C.col(1))) { cerr << "Error: more distinct rows of P than classes for model 1 (" << i << " > " << max(C.col(1)) << ").\n"; exit(1); } if(C(j,1)==i) { P1(j,t)= atof(tokens[t].c_str()); } } P1reducedcols = max(P1reducedcols, i); } } i++; } if(C.min() != 0) { cerr << "Error: need at least one class in each model labelled 0." << endl; exit(1); } if(max(C.col(0)) != P0reducedcols) { cerr << "Error: number of classes does not correspond to number of disinct rows of P for model 0.\n"; exit(1); } if(max(C.col(1)) != P1reducedcols) { cerr << "Error: number of classes does not correspond to number of disinct rows of P for model 1.\n"; exit(1); } }
inline void interp1_helper_linear(const Mat<eT>& XG, const Mat<eT>& YG, const Mat<eT>& XI, Mat<eT>& YI, const eT extrap_val) { arma_extra_debug_sigprint(); const eT XG_min = XG.min(); const eT XG_max = XG.max(); YI.copy_size(XI); const eT* XG_mem = XG.memptr(); const eT* YG_mem = YG.memptr(); const eT* XI_mem = XI.memptr(); eT* YI_mem = YI.memptr(); const uword NG = XG.n_elem; const uword NI = XI.n_elem; uword a_best_j = 0; uword b_best_j = 0; for(uword i=0; i<NI; ++i) { const eT XI_val = XI_mem[i]; if((XI_val < XG_min) || (XI_val > XG_max)) { YI_mem[i] = extrap_val; } else { // XG and XI are guaranteed to be sorted in ascending manner, // so start searching XG from last known optimum position eT a_best_err = Datum<eT>::inf; eT b_best_err = Datum<eT>::inf; for(uword j=a_best_j; j<NG; ++j) { const eT tmp = XG_mem[j] - XI_val; const eT err = (tmp >= eT(0)) ? tmp : -tmp; if(err >= a_best_err) { break; } else { a_best_err = err; a_best_j = j; } } if( (XG_mem[a_best_j] - XI_val) <= eT(0) ) { // a_best_j is to the left of the interpolated position b_best_j = ( (a_best_j+1) < NG) ? (a_best_j+1) : a_best_j; } else { // a_best_j is to the right of the interpolated position b_best_j = (a_best_j >= 1) ? (a_best_j-1) : a_best_j; } b_best_err = std::abs( XG_mem[b_best_j] - XI_val ); if(a_best_j > b_best_j) { std::swap(a_best_j, b_best_j ); std::swap(a_best_err, b_best_err); } const eT weight = (a_best_err > eT(0)) ? (a_best_err / (a_best_err + b_best_err)) : eT(0); YI_mem[i] = (eT(1) - weight)*YG_mem[a_best_j] + (weight)*YG_mem[b_best_j]; } } }