double gen_real() { return real_dist(gen); }
void generate (SNPMatrix& A, std::vector<double>& y, const snp_int_t& num_rhs, SNPSet& true_snps) { typedef typename SNPSet::value_type snp_type; /* psuedo-random generator engine for various phases in this function */ boost::random::mt19937 prng; prng.seed (int_params[RAND_SEED_INDEX]); /* parameters that we will refer to over and over again */ snp_int_t M = int_params[M_INDEX]; /* not making it const for BLAS */ snp_int_t N = int_params[N_INDEX]; /* not making it const for BLAS */ const double cutoff_for_0 = dbl_params[CUTOFF_FOR_0_INDEX]; const double cutoff_for_1 = dbl_params[CUTOFF_FOR_1_INDEX]; double signal_strength = dbl_params[SIGNAL_STRENGTH_INDEX]; /*************************************************************************/ /* generate epistatic and marginal SNPs */ const snp_int_t num_mar_snps = floor (dbl_params [PERCENT_MAR_INDEX] * static_cast<double>(int_params [NUM_TRUE_SNPS_INDEX])); const snp_int_t num_epi_snps = int_params [NUM_TRUE_SNPS_INDEX]-num_mar_snps; /* initialize a uniform random number generator in the range [0,N) */ boost::uniform_int<snp_int_t> int_dist(0, (N-1)); for (snp_int_t i=0;i<num_mar_snps;++i) true_snps.insert(snp_type(int_dist(prng))); /* generate some epistatic snp pairs */ generate_epistatic_t<snp_type, boost::uniform_int<snp_int_t>, boost::random::mt19937> gen_epistatic (int_dist,prng); for (snp_int_t i=0; i<num_epi_snps; ++i) { snp_type epi_snp = gen_epistatic(); while (true_snps.end()!=true_snps.find(epi_snp)) epi_snp=gen_epistatic(); true_snps.insert(epi_snp); } /*************************************************************************/ /* generate A */ boost::uniform_real<double> real_dist (0.0 /*lb*/, 1.0 /*ub*/); for (snp_int_t col=0; col<N; ++col) for (snp_int_t row=0; row<M; ++row) { const double next_rnd = real_dist(prng); const unsigned char next_snp = ((cutoff_for_0>next_rnd)? 0: ((cutoff_for_0<=next_rnd && cutoff_for_1>next_rnd)) ? 1:2); A.set (row,col,next_snp); } /*************************************************************************/ /* generate y */ boost::normal_distribution<double> nrml_dist (0.0/*mean*/, 1.0/*sigma*/); std::vector<double> multiplier (M); int truncated_M=static_cast<int> (M); /* Initialize y to zero for good measure */ y.resize (M*num_rhs, 0.0); /* Marginal: Set the right positions of x to be signal strength */ typename SNPSet::iterator first = true_snps.begin (); while (first != true_snps.end()) { /* Generate the column based on a linear model */ if (first->marginal()) A.interact (first->first(), multiplier.begin()); else A.interact (first->first(), first->second(), multiplier.begin()); daxpy_ (&truncated_M, &signal_strength, &(multiplier[0]), &ONE_STEP, &(y[0]), &ONE_STEP); ++first; } /* Copy this "y" into all the other "y"'s */ double* y_src = &(y[0]); for (snp_int_t i=1; i<num_rhs; ++i) { double* y_dst = y_src + (i*truncated_M); dcopy_ (&truncated_M, y_src, &ONE_STEP, y_dst, &ONE_STEP); } /* Now, for each "y", add a different gaussian noise */ for (size_t i=0; i<y.size(); ++i) y[i]+=nrml_dist(prng); }