32 #include <boost/numeric/ublas/vector.hpp> 38 #include <o2scl/rng_gsl.h> 39 #include <o2scl/uniform_grid.h> 40 #include <o2scl/table3d.h> 41 #include <o2scl/hdf_file.h> 42 #include <o2scl/hdf_io.h> 43 #include <o2scl/exception.h> 44 #include <o2scl/prob_dens_func.h> 45 #include <o2scl/cholesky.h> 46 #include <o2scl/vector.h> 47 #include <o2scl/multi_funct.h> 48 #include <o2scl/mcmc.h> 51 #include <o2scl/cli_readline.h> 53 #include <o2scl/cli.h> 65 template<
class func_t,
class fill_t,
class data_t,
109 unsigned long int seed=time(0);
121 virtual int mcmc(
size_t np, vec_t &init,
122 vec_t &low, vec_t &high, func_t &func,
171 int initial_point_type;
172 static const int fp_unspecified=-1;
173 static const int fp_last=-2;
174 static const int fp_best=-3;
205 if (first_file_update==
false) {
207 first_file_update=
true;
212 hf.
set_szt(
"n_chains",chain_index+1);
215 std::string ch_name=
"markov_chain"+
o2scl::szttos(chain_index);
216 hdf_output(hf,*this->
tab,ch_name);
225 virtual int add_line(
const ubvector &pars,
double weight,
226 size_t ix,
bool new_meas, data_t &dat,
232 scr_out <<
" " << weight <<
" " << ix <<
" " << new_meas << std::endl;
236 (pars,weight,ix,new_meas,dat,fill);
238 bool files_updated=
false;
239 if (((
int)this->
tab->get_nlines())==max_chain_size) {
240 scr_out <<
"Writing files and starting new chain." << std::endl;
243 this->
tab->clear_data();
251 if (this->max_iters>0 &&
253 if (files_updated==
false) {
257 std::cout <<
"mcmc: Stopping because n_accept+n_reject, " 259 <<
", is equal to max_iters." << std::endl;
269 if (elapsed>max_time) {
270 if (files_updated==
false) {
274 std::cout <<
"mcmc: Stopping because elapsed > max_time." 291 std::cout <<
"Start mcmc_mpi::mcmc_init()." << std::endl;
297 mpi_start_time=MPI_Wtime();
299 mpi_start_time=time(0);
304 if (this->file_opened==
false) {
306 this->scr_out.open((this->prefix+
"_"+
308 this->scr_out.setf(std::ios::scientific);
309 this->file_opened=
true;
310 this->scr_out <<
"Opened main file in command 'mcmc'." << std::endl;
314 if (file_update_iters<1) {
315 this->scr_out <<
"Parameter 'file_update_iters' less " 316 <<
"than 1. Set equal to 1." << std::endl;
320 if (max_chain_size<1) {
321 O2SCL_ERR(
"Parameter 'max_chain_size' must be larger than 1.",
327 if (this->mpi_nprocs>1 && this->mpi_rank>0) {
328 MPI_Recv(&buffer,1,MPI_INT,this->mpi_rank-1,tag,MPI_COMM_WORLD,
333 if (initial_point_file.length()>0) {
335 if (initial_point_type==fp_last) {
338 this->scr_out <<
"Reading last point from file '" << initial_point_file
339 <<
"'." << std::endl;
341 hf.
open(initial_point_file);
344 size_t file_n_chains;
345 hf.
get_szt(
"n_chains",file_n_chains);
346 std::string chain_name=std::string(
"markov_chain")+
354 std::string pname=((std::string)
"param_")+this->
col_names[i];
355 this->
current[0][i]=file_tab.
get(pname,last_line);
356 this->scr_out <<
"Parameter named " 358 << this->
current[0][i] << std::endl;
362 this->scr_out << std::endl;
365 }
else if (initial_point_type==fp_best) {
369 hf.
open(initial_point_file);
370 hf.
getd_vec(
"best_point",best_point);
372 this->scr_out <<
"Reading best point from file '" << initial_point_file
373 <<
"'." << std::endl;
375 this->
current[0][i]=best_point[i];
376 this->scr_out <<
"Parameter " << i <<
" : " 377 << this->
current[0][i] << std::endl;
379 this->scr_out <<
"Best weight: " 380 << best_point[
n_params] << std::endl;
381 this->scr_out << std::endl;
386 this->scr_out <<
"Reading " 387 << initial_point_type <<
"th point from file '" 388 << initial_point_file
389 <<
"'." << std::endl;
391 hf.
open(initial_point_file);
394 size_t file_n_chains, row=initial_point_type;
395 hf.
get_szt(
"n_chains",file_n_chains);
398 for(
size_t k=0;k<file_n_chains;k++) {
399 std::string chain_name=std::string(
"markov_chain")+
o2scl::szttos(k);
408 this->scr_out <<
"Couldn't find point " << initial_point_type
409 <<
" in file. Using last point." << std::endl;
415 std::string pname=((std::string)
"param_")+this->
col_names[i];
417 this->scr_out <<
"Parameter named " 419 << this->
current[0][i] << std::endl;
423 this->scr_out << std::endl;
427 }
else if (initial_point.size()>0) {
429 this->scr_out <<
"First point from command-line." << std::endl;
431 this->
current[0][i]=initial_point[i];
432 this->scr_out << this->
current[0][i] << std::endl;
434 this->scr_out << std::endl;
438 this->scr_out <<
"First point from default." << std::endl;
443 if (this->mpi_nprocs>1 && this->mpi_rank<this->mpi_nprocs-1) {
444 MPI_Send(&buffer,1,MPI_INT,this->mpi_rank+1,tag,MPI_COMM_WORLD);
448 this->scr_out <<
"First point: ";
452 std::cout <<
"End mcmc_mpi::mcmc_init()." << std::endl;
461 if (this->file_opened==
false) {
463 this->scr_out.open((this->prefix+
"_"+
465 this->scr_out.setf(std::ios::scientific);
466 this->file_opened=
true;
467 this->scr_out <<
"Opened main file in function 'best_point()'." 470 this->scr_out <<
"Best: ";
472 this->scr_out <<
" " << w_best << std::endl;
482 hf.
set_szt(
"n_params",n_params);
483 hf.
setd(
"max_time",this->max_time);
487 hf.
seti(
"max_iters",this->max_iters);
488 hf.
seti(
"file_update_iters",file_update_iters);
489 hf.
seti(
"output_meas",this->output_meas);
490 hf.
seti(
"initial_point_type",initial_point_type);
491 hf.
sets(
"initial_point_file",initial_point_file);
493 hf.
set_szt(
"n_chains",chain_index+1);
501 #ifdef O2SCL_NEVER_DEFINED 504 virtual int hastings(std::vector<std::string> &sv,
509 if (file_opened==
false) {
511 scr_out.open((prefix+
"_"+
o2scl::itos(mpi_rank)+
"_scr").c_str());
512 scr_out.setf(ios::scientific);
514 scr_out <<
"Opened main file in command 'hastings'." << endl;
518 cout <<
"No arguments given to 'hastings'." << endl;
522 if (model_type.length()==0) {
523 cout <<
"No model selected in 'hastings'." << endl;
529 if (mpi_nprocs>1 && mpi_rank>0) {
530 MPI_Recv(&buffer,1,MPI_INT,mpi_rank-1,tag,MPI_COMM_WORLD,
536 std::string fname=sv[1];
537 scr_out <<
"Opening file " << fname <<
" for hastings." << endl;
543 scr_out <<
"Done opening file " << fname <<
" for hastings." << endl;
546 if (mpi_nprocs>1 && mpi_rank<mpi_nprocs-1) {
547 MPI_Send(&buffer,1,MPI_INT,mpi_rank+1,tag,MPI_COMM_WORLD);
555 double max_mwgt=file_tab.
max(
"mwgt");
556 if (debug) scr_out <<
"lines: " << file_tab.
get_nlines() << endl;
559 if (debug) scr_out <<
"lines: " << file_tab.
get_nlines() << endl;
562 size_t nv=n_params+n_sources;
564 scr_out << n_params <<
" parameters and " << n_sources <<
" sources." 571 string str_i=((string)
"param_")+
data_arr[0].modp->param_name(i);
575 for(
size_t i=0;i<n_sources;i++) {
576 string str_i=((string)
"Mns_")+source_names[i];
582 ubmatrix covar(nv,nv);
584 string str_i=((string)
"param_")+
data_arr[0].modp->param_name(i);
586 string str_j=((string)
"param_")+
data_arr[0].modp->param_name(j);
588 file_tab[str_i],file_tab[str_j],
591 scr_out <<
"Covar: " << i <<
" " << j <<
" " 592 << covar(i,j) << endl;
594 covar(j,i)=covar(i,j);
596 for(
size_t j=0;j<n_sources;j++) {
597 string str_j=((string)
"Mns_")+source_names[j];
599 file_tab[str_i],file_tab[str_j],
602 scr_out <<
"Covar: " << i <<
" " << j+n_params <<
" " 603 << covar(i,j+n_params) << endl;
605 covar(j+n_params,i)=covar(i,j+n_params);
608 for(
size_t i=0;i<n_sources;i++) {
609 string str_i=((string)
"Mns_")+source_names[i];
610 for(
size_t j=i;j<n_sources;j++) {
611 string str_j=((string)
"Mns_")+source_names[j];
612 covar(i+n_params,j+n_params)=
614 file_tab[str_i],file_tab[str_j],
617 scr_out <<
"Covar: " << i+n_params <<
" " << j+n_params <<
" " 618 << covar(i+n_params,j+n_params) << endl;
620 covar(j+n_params,i+n_params)=covar(i+n_params,j+n_params);
629 hg_covar_inv=hg_chol;
630 o2scl_linalg::cholesky_invert<ubmatrix>(nv,hg_covar_inv);
633 for(
size_t i=0;i<nv;i++) {
634 for(
size_t j=0;j<nv;j++) {
635 if (i<j) hg_chol(i,j)=0.0;
645 for(
size_t i=0;i<file_tab.
get_nlines();i+=step) {
646 ubvector e(n_params,n_sources);
648 string str_j=((string)
"param_")+
data_arr[0].modp->param_name(j);
649 e.params[j]=file_tab.
get(str_j,i);
651 for(
size_t j=0;j<n_sources;j++) {
652 string str_j=((string)
"Mns_")+source_names[j];
653 e.mass[j]=file_tab.
get(str_j,i);
655 double wgt=file_tab.
get(
"mult",i)*file_tab.
get(
"weight",i);
656 double rat=wgt/approx_like(e);
657 renorm+=wgt*wgt/approx_like(e);
659 scr_out << wgt <<
" " << approx_like(e) <<
" " << rat << endl;
663 renorm/=((double)wgt_sum);
666 scr_out <<
"New normalization: " << hg_norm << endl;
671 for(
size_t i=0;i<file_tab.
get_nlines();i+=step) {
672 ubvector e(n_params,n_sources);
674 string str_j=((string)
"param_")+
data_arr[0].modp->param_name(j);
675 e.params[j]=file_tab.
get(str_j,i);
677 for(
size_t j=0;j<n_sources;j++) {
678 string str_j=((string)
"Mns_")+source_names[j];
679 e.mass[j]=file_tab.
get(str_j,i);
681 double wgt=file_tab.
get(
"mult",i)*file_tab.
get(
"weight",i);
682 double rat=wgt/approx_like(e);
684 scr_out << wgt <<
" " << approx_like(e) <<
" " << rat << endl;
700 std::cout <<
"No arguments given to 'initial-point'." << std::endl;
704 if (sv[1]==((std::string)
"values")) {
706 initial_point.resize(sv.size()-1);
707 for(
size_t i=2;i<sv.size();i++) {
710 initial_point_type=fp_unspecified;
712 }
else if (sv[1]==((std::string)
"prefix")) {
714 initial_point_type=fp_last;
715 initial_point_file=sv[2]+((std::string)
"_")+
718 }
else if (sv[1]==((std::string)
"last")) {
719 initial_point_type=fp_last;
720 initial_point_file=sv[2];
721 }
else if (sv[1]==((std::string)
"best")) {
722 initial_point_type=fp_best;
723 initial_point_file=sv[2];
724 }
else if (sv[1]==((std::string)
"N")) {
726 initial_point_file=sv[3];
751 first_file_update=
false;
753 initial_point_file=
"";
754 initial_point_type=fp_unspecified;
756 file_update_iters=40;
757 max_chain_size=10000;
772 template<
class func_t,
class fill_t,
class data_t,
782 #ifdef O2SCL_READLINE 814 parent_t::first_update(hf);
815 hf.
sets_vec(
"cl_args",this->cl_args);
822 virtual void run(
int argc,
char *argv[]) {
831 MPI_Comm_rank(MPI_COMM_WORLD,&this->
mpi_rank);
832 MPI_Comm_size(MPI_COMM_WORLD,&this->
mpi_nprocs);
836 for(
int i=0;i<argc;i++) {
837 this->cl_args.push_back(argv[i]);
862 static const size_t nopt=1;
864 {
'i',
"initial-point",
"Set the starting point in the parameter space",
866 ((std::string)
"Mode can be one of 'best', 'last', 'N', or ")+
867 "'values'. If mode is 'best', then it uses the point with the "+
868 "largest weight and the second argument specifies the file. If "+
869 "mode is 'last' then it uses the last point and the second "+
870 "argument specifies the file. If mode is 'N' then it uses the Nth "+
871 "point, the second argument specifies the value of N and the third "+
872 "argument specifies the file. If mode is 'values', then the "+
873 "remaining arguments specify all the parameter values. On the "+
874 "command-line, enclose negative values in quotes and parentheses, "+
875 "i.e. \"(-1.00)\" to ensure they do not get confused with other "+
878 o2scl::cli::comm_option_both}
890 p_file_update_iters.
help=((std::string)
"Number of MCMC successes ")+
891 "between file upates (default 40, minimum value 1).";
892 this->cl.
par_list.insert(std::make_pair(
"file_update_iters",
893 &p_file_update_iters));
896 p_max_chain_size.
help=((std::string)
"Maximum Markov chain size ")+
898 this->cl.
par_list.insert(std::make_pair(
"max_chain_size",
902 p_max_time.
help=((std::string)
"Maximum run time in seconds ")+
903 "(default 86400 sec or 1 day).";
904 this->cl.
par_list.insert(std::make_pair(
"max_time",&p_max_time));
907 p_max_iters.
help=((std::string)
"If non-zero, limit the number of ")+
908 "iterations to be less than the specified number (default zero).";
909 this->cl.
par_list.insert(std::make_pair(
"max_iters",&p_max_iters));
912 p_prefix.
help=
"Output file prefix (default 'mcmc\').";
913 this->cl.
par_list.insert(std::make_pair(
"prefix",&p_prefix));
916 p_output_meas.
help=((std::string)
"If true, output next point ")+
917 "to the '_scr' file before calling TOV solver (default true).";
918 this->cl.
par_list.insert(std::make_pair(
"output_meas",&p_output_meas));
921 p_step_fac.
help=((std::string)
"MCMC step factor. The step size for ")+
922 "each variable is taken as the difference between the high and low "+
923 "limits divided by this factor (default 10.0). This factor can "+
924 "be increased if the acceptance rate is too small, but care must "+
925 "be taken, e.g. if the conditional probability is multimodal. If "+
926 "this step size is smaller than 1.0, it is reset to 1.0 .";
927 this->cl.
par_list.insert(std::make_pair(
"step_fac",&p_step_fac));
930 p_n_warm_up.
help=((std::string)
"Minimum number of warm up iterations ")+
932 this->cl.
par_list.insert(std::make_pair(
"n_warm_up",&p_n_warm_up));
935 p_verbose.
help=((std::string)
"Verbosity parameter ")+
937 this->cl.
par_list.insert(std::make_pair(
"verbose",&p_verbose));
940 p_max_bad_steps.
help=((std::string)
"Maximum number of bad steps ")+
942 this->cl.
par_list.insert(std::make_pair(
"max_bad_steps",&p_max_bad_steps));
945 p_n_walk.
help=((std::string)
"Number of walkers ")+
947 this->cl.
par_list.insert(std::make_pair(
"n_walk",&p_n_walk));
950 p_user_seed.
help=((std::string)
"Seed for multiplier for random ")+
951 "number generator. If zero is given (the default), then mcmc() "+
952 "uses time(0) to generate a random seed.";
953 this->cl.
par_list.insert(std::make_pair(
"user_seed",&p_user_seed));
956 p_aff_inv.
help=((std::string)
"If true, then use affine-invariant ")+
957 "sampling (default false).";
958 this->cl.
par_list.insert(std::make_pair(
"aff_inv",&p_aff_inv));
std::shared_ptr< o2scl::table_units<> > tab
Main data table for Markov chain.
virtual int mcmc(size_t np, vec_t &init, vec_t &low, vec_t &high, func_t &func, fill_t &fill)
Perform an MCMC simulation.
virtual int add_line(const vec_t &pars, double log_weight, size_t walker_ix, bool new_meas, data_t &dat, fill_t &fill)
A measurement function which adds the point to the table.
An extension to o2scl::cli which uses readline.
Error handler to throw C++ exceptions.
std::vector< std::string > col_names
Column names.
double max(std::string scol) const
Return column maximum. Makes no assumptions about ordering .
std::ofstream scr_out
The screen output file.
double get(std::string scol, size_t row) const
Get value from row row of column named col. .
int getd_vec(std::string name, std::vector< double > &v)
Get vector dataset and place data in v.
int setd_vec_copy(std::string name, const vec_t &v)
Set vector dataset named name with v.
Double parameter for o2scl::cli.
virtual void update_files()
Update files with current table.
double wvector_mean(size_t n, const vec_t &data, const vec2_t &weights)
Compute the mean of weighted data.
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
std::string prefix
Prefix for output filenames.
int set_szt_vec(std::string name, const std::vector< size_t > &v)
Set vector dataset named name with v.
size_t get_nlines() const
Return the number of lines.
virtual void setup_cli()
Set up the 'cli' object.
err_hnd_type * err_hnd
The global error handler pointer.
std::vector< vec_t > current
Current points in parameter space.
double step_fac
Stepsize factor (default 10.0)
void close()
Close the file.
Integer parameter for o2scl::cli.
void set_szt(std::string name, size_t u)
Set an unsigned integer named name to value u.
void setd(std::string name, double d)
Set a double named name to value d.
size_t n_walk
Number of walkers for affine-invariant MC or 1 otherwise (default 1)
String parameter for o2scl::cli.
void set_seed(unsigned long int s)
Set the seed.
size_t n_reject
The number of Metropolis steps which were rejected.
int verbose
Output control (default 0)
virtual int mcmc(size_t nparams, vec_t &init, vec_t &low, vec_t &high, func_t &func, fill_t &fill)
Perform an MCMC simulation.
virtual int mcmc_init()
User-defined initialization function.
A generic MCMC simulation class.
invalid argument supplied by user
o2scl::err_hnd_cpp error_handler
Error handler for each thread.
bool first_file_update
If true, then first_update() has been called.
virtual void best_point(ubvector &best, double w_best)
Output the best point so far.
vec_t high_copy
A copy of the upper limits for HDF5 output.
int mpi_rank
The MPI processor rank.
void seti(std::string name, int i)
Set an integer named name to value i.
int run_auto(int argc, char *argv[], int debug=0)
Automatically parse arguments to main and call interactive mode if required.
int get_szt(std::string name, size_t &u)
Get an unsigned integer named name.
std::string prompt
The prompt (default "> ")
size_t max_iters
Maximum number of iterations (default 0)
ubvector initial_point
If true, output MC accepts and rejects (default true)
size_t chain_index
Number of complete Markov chain segments.
static const int mcmc_done
Integer to indicate completion.
Configurable command-line interface.
int mpi_nprocs
The MPI number of processors.
size_t n_accept
The number of Metropolis steps which were accepted.
int max_chain_size
Maximum size of Markov chain (default 10000)
std::string help
Help description.
void sets(std::string name, std::string s)
Set a string named name to value s.
int stoi(std::string s, bool err_on_fail=true)
Convert a string to an integer.
MCMC with MPI and HDF5 table I/O.
virtual void first_update(o2scl_hdf::hdf_file &hf)
Initial write to HDF5 file.
double wvector_covariance(size_t n, const vec_t &data1, const vec2_t &data2, const vec3_t &weights)
The weighted covariance of two vectors.
void open_or_create(std::string fname)
Open a file named fname or create if it doesn't already exist.
size_t n_warm_up
Number of warm up steps (successful steps not iterations) (default 0)
A generic MCMC simulation class writing data to a o2scl::table_units object.
double max_time
Time in seconds (default is 86400 seconds or 1 day)
std::vector< data_t > data_arr
Data array.
virtual int add_line(const ubvector &pars, double weight, size_t ix, bool new_meas, data_t &dat, fill_t &fill)
Add a measurement to the table.
vec_t low_copy
A copy of the lower limits for HDF5 output.
Member function pointer for o2scl::cli command function.
int set_initial_point(std::vector< std::string > &sv, bool itive_com)
Set the first point.
void cholesky_decomp(const size_t M, mat_t &A)
Compute the in-place Cholesky decomposition of a symmetric positive-definite square matrix...
int user_seed
If non-zero, use as the seed for the random number generator (default 0)
bool aff_inv
If true, use affine-invariant Monte Carlo.
String parameter for o2scl::cli.
size_t max_bad_steps
Maximum number of failed steps when generating initial points with affine-invariant sampling (default...
std::string * str
Parameter.
std::map< std::string, parameter *, std::less< std::string > > par_list
Parameter list.
double mpi_start_time
The MPI starting time.
bool output_meas
Output each measurement.
MCMC class with a command-line interface.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
virtual void add_constant(std::string name, double val)
Add a constant, or if the constant already exists, change its value.
int set_comm_option_vec(size_t list_size, vec_t &option_list)
Add a vector containing new commands/options.
Integer parameter for o2scl::cli.
std::vector< std::string > cl_args
The arguments sent to the command-line.
void vector_out(std::ostream &os, size_t n, const vec_t &v, bool endline=false)
Output the first n elements of a vector to a stream, os.
void delete_rows(std::string func)
Delete all rows where func evaluates to a number greater than 0.5 .
virtual void set_seed()
Default method for setting the random seed.
std::vector< size_t > ret_value_counts
Return value counters.
Data table table class with units.
Command for interactive mode in o2scl::cli.
size_t n_params
The number of parameters.
int file_update_iters
The number of MCMC successes between file updates (default 40)
virtual void run(int argc, char *argv[])
Main wrapper for parsing command-line arguments.
void function_column(std::string function, std::string scol)
Make a column from the function specified in function and add it to the table.
std::string initial_point_file
The file containing the initial point.
Store data in an O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$sc...
int sets_vec(std::string name, std::vector< std::string > &s)
Set a vector of strings named name.
o2scl::cli cl
Command-line interface.
bool file_opened
If true, scr_out has been opened.
int open(std::string fname, bool write_access=false, bool err_on_fail=true)
Open a file named fname.
mcmc_mpi()
Create an MCMC object with model m.
std::string itos(int x)
Convert an integer to a string.
double function_to_double(std::string s, bool err_on_fail=true)
Convert a formula to a double.
std::string szttos(size_t x)
Convert a size_t to a string.
void hdf_input(hdf_file &hf, o2scl::table< vec_t > &t, std::string name)
Input a o2scl::table object from a hdf_file.
virtual void first_update(o2scl_hdf::hdf_file &hf)
Initial write to HDF5 file.
rng_gsl rg
Random number generator.
virtual int mcmc_init()
MCMC initialization function.