int RandFourierMap(int nKernelType, const fvec& x, const std::vector<fvec> &W, const fvec &b, fvec &result) { int nErrCode = 0; if(W.empty() || b.empty()) { return 1; } int nKernelRank = W[0].size(); switch(nKernelType) { case RAND_KERNEL_RBF: for(int rank_idx = 0; rank_idx < nKernelRank; ++rank_idx) { float sum = 0.0; for(int dim_idx = 0; dim_idx < x.size(); ++dim_idx) { sum += W[dim_idx][rank_idx] * x[dim_idx]; } result.push_back(sqrt(2.0 / nKernelRank) * cos(sum + b[rank_idx])); } break; default: nErrCode = 1; } return nErrCode; }
int RandFourierFactorize(int nKernelType, int nKernelRank, float fGamma, const std::vector<fvec>& X, std::vector<fvec> &G, std::vector<fvec> &W, fvec &b) { int nErrCode = 0; int m = X.size(); if(m == 0) { return nErrCode; } int dim = X[0].size(); G.clear(); W.clear(); b.clear(); //generate random features dlib::rand r; std::ostringstream seed; seed << (unsigned int) time(0); r.set_seed(seed.str()); switch(nKernelType) { case RAND_KERNEL_RBF: for(int ind = 0; ind < dim; ++ind) { fvec tmp_vec; for(int rank_idx = 0; rank_idx < nKernelRank; ++rank_idx) { tmp_vec.push_back(r.get_random_gaussian() * fGamma); } W.push_back(tmp_vec); } for(int ind = 0; ind < nKernelRank; ++ind) { b.push_back(r.get_random_float() * 2.0 * PI); } for(int ind = 0; ind < m; ++ind) { fvec tmp_vec; RandFourierMap(nKernelType, X[ind], W, b, tmp_vec); G.push_back(tmp_vec); } break; default: //unknown kernel type //printf("unknown type\n"); nErrCode = 1; break; }; return nErrCode; }
void search2(fvec &stat, ivec &sel_id, int &marg_id, const fvec &S, const fmat &Sigma, const int &mc){ int ns = S.size(); //find best marginal SNP int id = -1; double max_stat = -1.0; for(int j = 0; j < ns; ++j){ double s = S[j] * S[j] / Sigma[j][j]; if(s > max_stat){ max_stat = s; id = j; } } stat = fvec(1, max_stat); assert(id >= 0 && id < ns); sel_id = ivec(1, id); marg_id = id; if(ns == 1){ return; } //find best pair int id1 = -1; int id2 = -1; max_stat = -1.0; for(int j = 0; j < ns; ++j){ for(int k = j + 1; k < ns; ++k){ double a = Sigma[j][j]; double b = Sigma[j][k]; double d = Sigma[k][k]; double stat = (d * S[j] * S[j] - 2 * b * S[j] * S[k] + a * S[k] * S[k]) / (a * d - b * b); if(stat > max_stat){ max_stat = stat; id1 = j; id2 = k; } } } stat.push_back(max_stat); assert(id1 >= 0 && id1 < ns); assert(id2 >= 0 && id2 < ns); sel_id = ivec(1, id1); sel_id.push_back(id2); if(ns == 2){ return; } dmat inv_Sigma22(mc + 1, dvec(mc + 1, .0)); double a = Sigma[id1][id1]; double b = Sigma[id1][id2]; double d = Sigma[id2][id2]; double e = a * d - b * b; inv_Sigma22[0][0] = d / e; inv_Sigma22[0][1] = -b / e; inv_Sigma22[1][0] = inv_Sigma22[0][1]; inv_Sigma22[1][1] = a / e; dvec S2(mc + 1, .0); S2[0] = S[id1]; S2[1] = S[id2]; vector<bool> used(ns, false); used[id1] = true; used[id2] = true; double w = max_stat; for(int j = 2; j <= mc; ++j){//j is the number of SNPs being selected dvec v(j, .0); // v = (Sigma22)^-1 S2 for(int i = 0; i < j; ++i){ v[i] = .0; for(int k = 0; k < j; ++k){ v[i] += inv_Sigma22[i][k] * S2[k]; } } max_stat = -1.0; double max_qf2 = -1.0; id = -1; for(int k = 0; k < ns; ++k){ if(used[k]){ continue; } double S1 = S[k]; double qf1 = .0; //qf1 = sigma12 (Sigma22)^-1 S2 double qf2 = .0; //qf2 = sigma12 (Sigma22)^-1 sigma21 for(int l = 0; l < j; ++l){ qf1 += Sigma[k][sel_id[l]] * v[l]; double tmp = .0; // tmp = the l-th column of sigma12 (Sigma22)^-1 for(int t = 0; t < j; ++t){ tmp += Sigma[k][sel_id[t]] * inv_Sigma22[t][l]; } qf2 += tmp * Sigma[sel_id[l]][k]; } double stat = w + (S1 * S1 - 2.0 * S1 * qf1 + qf1 * qf1)/(Sigma[k][k] - qf2); if(stat > max_stat){ max_stat = stat; id = k; max_qf2 = qf2; } } w = max_stat; stat.push_back(max_stat); sel_id.push_back(id); used[id] = true; S2[j] = S[id]; inv_Sigma22[j][j] = 1.0 / (Sigma[id][id] - max_qf2); dvec tmp(j, .0); for(int l = 0; l < j; ++l){ inv_Sigma22[j][l] = .0; for(int t = 0; t < j; ++t){ inv_Sigma22[j][l] += Sigma[id][sel_id[t]] * inv_Sigma22[t][l]; } inv_Sigma22[j][l] *= -inv_Sigma22[j][j]; inv_Sigma22[l][j] = inv_Sigma22[j][l]; } for(int l = 0; l < j; ++l){ for(int t = 0; t < j; ++t){ inv_Sigma22[l][t] += inv_Sigma22[l][j] * inv_Sigma22[t][j] / inv_Sigma22[j][j]; } } } }