46 ErrorCBL(
"the stretch move parameter must be >1!",
"m_set_gz",
"Sampler.cpp");
52 gzz.push_back(1./sqrt(zzz));
64 for (
int i=0; i<m_nwalkers; i++) {
65 vector<double> pp = start[i];
66 m_function_chain[0][i] = m_function(pp);
78 #pragma omp parallel for schedule(dynamic)
79 for (
int i=0; i<m_nwalkers; i++) {
80 vector<double> pp = start[i];
81 m_function_chain[0][i] = m_function(pp);
93 m_npar_free = npar_free;
95 m_nwalkers = nwalkers;
96 m_chain_size = chain_size;
98 m_chains.erase(m_chains.begin(), m_chains.end());
99 m_chains.resize(m_chain_size, vector<vector<double>>(m_nwalkers, vector<double>(m_npar,0)));
101 m_acceptance.erase(m_acceptance.begin(), m_acceptance.end());
102 m_acceptance.resize(m_nwalkers, 0.);
104 m_function_chain.erase(m_function_chain.begin(), m_function_chain.end());
105 m_function_chain.resize(m_chain_size, vector<double>(m_nwalkers, 0.));
114 m_function =
function;
115 m_use_python =
false;
135 set_chain(m_npar, m_npar_free, chain_size, nwalkers);
137 function<void(
int,
int,
const vector<double>,
const double)> write_func;
140 write_func = [&] (
const int nc,
const int nw,
const vector<double> parameters,
const double func)
141 {(void)nc; (void)nw; (void)parameters; (void)func;};
144 fout.open(outputFile.c_str());
145 write_func = [&] (
const int nc,
const int nw,
const vector<double> parameters,
const double func)
147 fout << nc <<
" " << nw <<
" ";
148 for (
int p=0; p<m_npar; p++)
149 fout << parameters[p] <<
" ";
150 fout << func << endl;
157 const int chain_seed = seeds();
158 const int MH_seed = seeds();
159 const int gz_seed = seeds();
161 coutCBL <<
"Starting seed = " << seed << endl;
162 coutCBL <<
"Seed for random walker choice = " << chain_seed << endl;
163 coutCBL <<
"Seed for Metropolis-Hastings algorithm = " << MH_seed << endl;
164 coutCBL <<
"Seed for random extraction from g(z) = " << gz_seed << endl;
168 auto gz = m_set_gz(gz_seed, aa);
171 m_initialize_chains(start);
173 for (
int n=1; n<m_chain_size; n++) {
174 for (
int i=0; i<m_nwalkers; i++)
180 vector<double> parameters_i;
181 vector<double> parameters_k;
183 parameters_i = m_chains[n-1][i];
184 parameters_k = m_chains[n-1][kk];
186 vector<double> parameters(m_npar, 0);
189 double gen_z = gz->operator()();
191 gen_z = gz->operator()();
192 for (
int p=0; p<m_npar; p++)
193 parameters[p] = parameters_k[p] + gen_z*(parameters_i[p]-parameters_k[p]);
194 proposed_function_chains = m_function(parameters);
196 parameters_i = parameters;
198 double ratio = min(1.,pow(gen_z, m_npar_free-1)*exp(proposed_function_chains-m_function_chain[n-1][i]));
200 if (MH_random() <ratio) {
201 m_function_chain[n][i] = proposed_function_chains;
202 m_chains[n][i] = parameters_i;
203 m_acceptance[i] += 1./m_chain_size;
206 m_function_chain[n][i] = m_function_chain[n-1][i];
207 m_chains[n][i] = m_chains[n-1][i];
210 write_func(n, i, m_chains[n][i], m_function_chain[n][i]);
213 const int progress = int(
double((n+1)*m_nwalkers)/(m_nwalkers*m_chain_size)*100);
214 coutCBL << progress <<
"% \r"; cout.flush();
227 set_chain(m_npar, m_npar_free, chain_size, nwalkers);
233 vector<double> chains_weights(m_nwalkers,1);
235 const int chain_seed1 = seeds();
236 const int chain_seed2 = seeds();
237 const int MH_seed = seeds();
238 const int gz_seed = seeds();
240 coutCBL <<
"Starting seed = " << seed << endl;
241 coutCBL <<
"Seed for random walker choice, first half = " << chain_seed1 << endl;
242 coutCBL <<
"Seed for random walker choice, second half = " << chain_seed2 << endl;
243 coutCBL <<
"Seed for Metropolis-Hastings algorithm = " << MH_seed << endl;
244 coutCBL <<
"Seed for random extraction from g(z) = " << gz_seed << endl;
246 int half = m_nwalkers/2;
250 vector<random::UniformRandomNumbers_Int> chains_sample = {chains_second_half, chains_first_half};
254 auto gz = m_set_gz(gz_seed, aa);
257 m_initialize_chains_parallel(start);
261 for (
int n=1; n<m_chain_size; n++) {
262 for (
int ss=0; ss<2; ss++) {
263 #pragma omp parallel for schedule(dynamic)
264 for (
int ii=0; ii<half; ii++)
268 int kk = int(chains_sample[ss]());;
270 vector<double> parameters_i= m_chains[n-1][i];
271 vector<double> parameters_k = m_chains[nn][kk];;
273 vector<double> parameters(m_npar, 0);
276 double gen_z = gz->operator()();
278 gen_z = gz->operator()();
279 for (
int p=0; p<m_npar; p++)
280 parameters[p] = parameters_k[p] + gen_z*(parameters_i[p]-parameters_k[p]);
281 proposed_function_chains = m_function(parameters);
283 parameters_i = parameters;
285 double ratio = min(1., pow(gen_z, m_npar_free-1)*exp(proposed_function_chains-m_function_chain[n-1][i]));
287 if (MH_random()<ratio) {
288 m_function_chain[n][i] = proposed_function_chains;
289 m_chains[n][i] = parameters_i;
290 m_acceptance[i] += 1./m_chain_size;
293 m_function_chain[n][i] = m_function_chain[n-1][i];
294 m_chains[n][i] = m_chains[n-1][i];
300 const int progress = int(
double((n+1)*m_nwalkers)/(m_nwalkers*m_chain_size)*100);
301 coutCBL << progress <<
"% \r"; cout.flush();
314 (void)chain_size; (void)nwalkers; (void)start; (void)seed; (void)aa;
315 cbl::ErrorCBL(
"",
"m_sample_stretch_move_parallel_py",
"Sampler.cpp", glob::ExitCode::_workInProgress_);
399 ErrorCBL(
"the number of walkers must be an even integer!",
"sample_stretch_move_parallel",
"Sampler.cpp");
402 m_sample_stretch_move_parallel_py(chain_size, nwalkers, start, seed, aa);
404 m_sample_stretch_move_parallel_cpp(chain_size, nwalkers, start, seed, aa);
413 chains.resize(m_npar);
414 function.erase(
function.begin(),
function.end());
415 acceptance.erase(acceptance.begin(), acceptance.end());
417 for (
int i=start; i<m_chain_size; i+=thin) {
418 for (
int j=0; j<m_nwalkers; j++) {
419 function.push_back(m_function_chain[i][j]);
420 acceptance.push_back(m_acceptance[j]);
421 for (
int k=0; k<m_npar; k++)
422 chains[k].push_back(m_chains[i][j][k]);
433 string file_out = dir_output+file;
434 ofstream fout(file_out.c_str());
437 for (
int i=start;i<m_chain_size; i+=thin) {
438 for (
int j=0; j<m_nwalkers; j++) {
439 fout << i*m_nwalkers+j <<
" ";
440 for (
int k=0; k<m_npar; k++)
441 fout << m_chains[i][j][k] <<
" ";
442 fout << m_function_chain[i][j] <<
" " << m_acceptance[j] << endl;
445 fout.clear(); fout.close();
#define coutCBL
CBL print message.
The class DistributionRandomNumbers.
void write_chain(const std::string dir_output, const std::string file, const int start, const int thin)
write the chains in an output file
void sample_stretch_move(const int chain_size, const int nwalkers, const std::vector< std::vector< double >> start, const int seed=4241, const double aa=2, const std::string outputFile=cbl::par::defaultString)
sample the input function using the stretch-move algorithm on n-dimensional parameter space
void m_sample_stretch_move_parallel_cpp(const int chain_size, const int nwalkers, const std::vector< std::vector< double >> start, const int seed=4241, const double aa=2)
sample the input function using the stretch-move algorithm on n-dimensional parameter space....
void get_chain_function_acceptance(std::vector< std::vector< double >> &chains, std::vector< double > &function, std::vector< double > &acceptance, const int start=0, const int thin=1)
get the chain values and the function
void set_chain(const int npar, const int npar_free, const int chain_size, const int nwalkers)
function to set the chains
void set_function(const std::function< double(std::vector< double > &)> function)
set the function
void sample_stretch_move_parallel(const int chain_size, const int nwalkers, const std::vector< std::vector< double >> start, const int seed=4241, const double aa=2)
sample the input function using the stretch-move algorithm on n-dimensional parameter space - paralle...
std::shared_ptr< random::DistributionRandomNumbers > m_set_gz(const int seed, const double aa=2)
return the random generator for the stretch-move
void m_initialize_chains_parallel(const std::vector< std::vector< double >> start)
initialize chains
void m_initialize_chains(const std::vector< std::vector< double >> start)
initialize chains
void m_sample_stretch_move_parallel_py(const int chain_size, const int nwalkers, const std::vector< std::vector< double >> start, const int seed=4241, const double aa=2)
sample the input function using the stretch-move algorithm on n-dimensional parameter space - paralle...
static const std::string defaultString
default std::string value
static const double defaultDouble
default double value
The global namespace of the CosmoBolognaLib
std::vector< T > linear_bin_vector(const size_t nn, const T min, const T max)
fill a std::vector with linearly spaced values
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib