Pakman
ABCSMCControllerStatic.cc
1 #include <memory>
2 #include <fstream>
3 #include <string>
4 #include <random>
5 
6 #include "core/common.h"
7 #include "core/utils.h"
8 #include "core/LongOptions.h"
9 #include "core/Arguments.h"
10 #include "interface/input.h"
11 
12 #include "ABCSMCController.h"
13 
15 {
16  return
17 R"(* Help message for 'smc' controller *
18 
19 Description:
20  The ABC sequential Monte Carlo (SMC) method evolves a population of
21  parameters through multiple generations to an approximate posterior
22  distribution, with epsilon decreasing at each generation. The generations
23  are numbered starting from 0.
24 
25  The sequence of epsilon values is given by the comma-separated list
26  'epsilons'. The number of values in 'epsilons' determines the number of
27  generations.
28 
29  The first generation of candidate parameters is obtained from the stdout of
30  'prior_sampler'.
31 
32  In subsequent generations, candidate parameters are sampled by perturbing a
33  parameter from the previous generation with 'perturber'. 'perturber' accepts
34  two lines as its input; the first line contains the current generation 't'
35  and the second line contains the parameter to be perturbed.
36 
37  The parameter to be perturbed is sampled from the previous generation with
38  weights that are calculated using 'prior_pdf' and 'perturbation_pdf'.
39  'prior_pdf' accepts a parameter on its stdin and returns the corresponding
40  prior probability density on its stdout.
41 
42  'perturbation_pdf' accepts at least two lines on its stdin, containing the
43  current generation 't' and the perturbed parameter, respectively. This is
44  then followed by an arbitrary number of parameters, each on a separate line.
45  For every parameter from the third line onwards, 'perturbation_pdf' outputs
46  on its stdout the corresponding probability density for reaching the
47  perturbed parameter by perturbing the given parameter.
48 
49  For every candidate parameter, 'simulator' is invoked and given two lines as
50  its input; the first line contains the current epsilon value and the second
51  line contains the candidate parameter.
52 
53  The output of 'simulator' indicates whether the parameter was accepted or
54  rejected; an output of '0', 'reject' or 'rejected' means that the parameter
55  was rejected and an output of '1', 'accept' or 'accepted' means that the
56  parameter was accepted.
57 
58  Upon completion, the controller outputs the parameter names, followed by
59  newline-separated list of accepted parameters.
60 
61 Required arguments:
62  -N, --population-size=NUM NUM is the parameter population size
63  -E, --epsilons=EPS EPS is comma-separated list of tolerances
64  that are passed to simulator
65  -P, --parameter-names=NAMES NAMES is comma-separated list of
66  parameter names
67  -S, --simulator=CMD CMD is simulator command
68  -R, --prior-sampler=CMD CMD is prior_sampler command
69  -T, --perturber=CMD CMD is perturber command
70  -I, --prior-pdf=CMD CMD is prior_pdf command
71  -U, --perturbation-pdf=CMD CMD is perturbation_pdf command
72 
73 ABC SMC controller options:
74  -s, --seed=SEED SEED is the seed for the pseudo random number
75  generator that is used to sample from the
76  parameter population (by default, the seed is
77  derived from the system clock).
78 )";
79 }
80 
82  LongOptions& lopts)
83 {
84  lopts.add({"population-size", required_argument, nullptr, 'N'});
85  lopts.add({"epsilons", required_argument, nullptr, 'E'});
86  lopts.add({"parameter-names", required_argument, nullptr, 'P'});
87  lopts.add({"simulator", required_argument, nullptr, 'S'});
88  lopts.add({"prior-sampler", required_argument, nullptr, 'R'});
89  lopts.add({"perturber", required_argument, nullptr, 'T'});
90  lopts.add({"prior-pdf", required_argument, nullptr, 'I'});
91  lopts.add({"perturbation-pdf", required_argument, nullptr, 'U'});
92  lopts.add({"seed", required_argument, nullptr, 's'});
93 }
94 
96 {
97  Input input_obj;
98 
99  // Parse command-line options
100  input_obj = Input::makeInput(args);
101 
102  // Make ABCSMCController
103  return new ABCSMCController(input_obj);
104 }
105 
106 // Construct Input from Arguments object
108  const Arguments& args)
109 {
110  // Initialize input
111  Input input_obj;
112 
113  // Process optional arguments
114  if (args.isOptionalArgumentSet("seed"))
115  {
116  input_obj.seed =
118  }
119 
120  try
121  {
122  input_obj.population_size =
123  parse_integer(args.optionalArgument("population-size"));
124 
125  input_obj.epsilons = parse_epsilons(args.optionalArgument("epsilons"));
126 
127  input_obj.parameter_names =
128  parse_parameter_names(args.optionalArgument("parameter-names"));
129 
130  input_obj.simulator =
131  parse_command(args.optionalArgument("simulator"));
132 
133  input_obj.prior_sampler =
134  parse_command(args.optionalArgument("prior-sampler"));
135 
136  input_obj.perturber =
137  parse_command(args.optionalArgument("perturber"));
138 
139  input_obj.prior_pdf =
140  parse_command(args.optionalArgument("prior-pdf"));
141 
142  input_obj.perturbation_pdf =
143  parse_command(args.optionalArgument("perturbation-pdf"));
144  }
145  catch (const std::out_of_range& e)
146  {
147  std::string error_msg;
148  error_msg += "Out of range: ";
149  error_msg += e.what();
150  error_msg += '\n';
151  error_msg += "One or more arguments missing or incorrect, try '";
152  error_msg += g_program_name;
153  error_msg += " smc --help' for more info";
154  throw std::runtime_error(error_msg);
155  }
156  catch (const std::invalid_argument& e)
157  {
158  std::string error_msg;
159  error_msg += " Invalid argument: ";
160  error_msg += e.what();
161  error_msg += '\n';
162  error_msg += "One or more arguments missing or incorrect, try '";
163  error_msg += g_program_name;
164  error_msg += " smc --help' for more info";
165  throw std::runtime_error(error_msg);
166  }
167 
168  return input_obj;
169 }
static ABCSMCController * makeController(const Arguments &args)
Command parse_command(const std::string &raw_input)
Definition: input.cc:19
const char * g_program_name
Definition: main.cc:22
ABCSMCController(const Input &input_obj)
std::vector< ParameterName > parameter_names
static void addLongOptions(LongOptions &lopts)
std::vector< ParameterName > parse_parameter_names(const std::string &raw_input)
Definition: input.cc:42
std::vector< Epsilon > parse_epsilons(const std::string &raw_input)
Definition: input.cc:29
unsigned long parse_unsigned_long_integer(const std::string &raw_input)
Definition: input.cc:14
std::vector< Epsilon > epsilons
static Input makeInput(const Arguments &args)
int parse_integer(const std::string &raw_input)
Definition: input.cc:9
bool isOptionalArgumentSet(const std::string &option_name) const
Definition: Arguments.cc:38
static std::string help()
void add(struct option long_opt)
Definition: LongOptions.cc:20
std::string optionalArgument(const std::string &option_name) const
Definition: Arguments.cc:45