Pakman
protocols.cc
1 #include <string>
2 #include <vector>
3 #include <sstream>
4 #include <stdexcept>
5 
6 #include "system/system_call.h"
7 
8 #include "protocols.h"
9 
10 // simulator protocol
12  const Epsilon& epsilon,
13  const Parameter& parameter)
14 {
15  std::string input_string;
16  input_string += epsilon.str();
17  input_string += '\n';
18  input_string += parameter.str();
19  input_string += '\n';
20 
21  return input_string;
22 }
23 
24 bool parse_simulator_output(const std::string& simulator_output)
25 {
26  // Extract line
27  std::string line;
28  std::istringstream sstrm(simulator_output);
29  std::getline(sstrm, line);
30 
31  // Ensure that end of input has been reached
32  if (sstrm.eof() || (sstrm.peek() != EOF))
33  {
34  std::string error_msg;
35  error_msg += "Simulator output must contain exactly one "
36  "newline-terminated line, given output: ";
37  error_msg += simulator_output;
38  throw std::runtime_error(error_msg);
39  }
40 
41  // Parse line
42  if (line.compare("1") == 0)
43  return true;
44  else if (line.compare("accept") == 0)
45  return true;
46  else if (line.compare("accepted") == 0)
47  return true;
48  if (line.compare("0") == 0)
49  return false;
50  else if (line.compare("reject") == 0)
51  return false;
52  else if (line.compare("rejected") == 0)
53  return false;
54  // Invalid simulator output
55  else
56  {
57  std::string error_msg;
58  error_msg += "Cannot parse output of simulator: ";
59  error_msg += simulator_output;
60  throw std::runtime_error(error_msg);
61  }
62 }
63 
64 // prior_sampler protocol
65 Parameter parse_prior_sampler_output(const std::string& prior_sampler_output)
66 {
67  // Extract line
68  std::string line;
69  std::istringstream sstrm(prior_sampler_output);
70  std::getline(sstrm, line);
71 
72  // Ensure that end of input has been reached
73  if (sstrm.eof() || (sstrm.peek() != EOF))
74  {
75  std::string error_msg;
76  error_msg += "Prior_sampler output must contain exactly one "
77  "newline-terminated line, given output: ";
78  error_msg += prior_sampler_output;
79  throw std::runtime_error(error_msg);
80  }
81 
82  // Parse line
83  try
84  {
85  return line;
86  }
87  catch (const std::runtime_error& e)
88  {
89  std::string error_msg;
90  error_msg += e.what();
91  error_msg += '\n';
92  error_msg += "Cannot parse output of prior_sampler: ";
93  error_msg += prior_sampler_output;
94  throw std::runtime_error(error_msg);
95  }
96 }
97 
98 // perturber protocol
99 std::string format_perturber_input(int t, const Parameter& parameter)
100 {
101  std::string input_string;
102  input_string += std::to_string(t);
103  input_string += '\n';
104  input_string += parameter.str();
105  input_string += '\n';
106 
107  return input_string;
108 }
109 
110 Parameter parse_perturber_output(const std::string& perturber_output)
111 {
112  try
113  {
114  return perturber_output;
115  }
116  catch (const std::runtime_error& e)
117  {
118  std::string error_msg;
119  error_msg += e.what();
120  error_msg += '\n';
121  error_msg += "Cannot parse output of perturber: ";
122  error_msg += perturber_output;
123  throw std::runtime_error(error_msg);
124  }
125 }
126 
127 // prior_pdf protocol
128 std::string format_prior_pdf_input(const Parameter& parameter)
129 {
130  std::string input_string;
131  input_string += parameter.str();
132  input_string += '\n';
133 
134  return input_string;
135 }
136 
137 double parse_prior_pdf_output(const std::string& prior_pdf_output)
138 {
139  // Extract line
140  std::string line;
141  std::istringstream sstrm(prior_pdf_output);
142  std::getline(sstrm, line);
143 
144  // Ensure that end of input has been reached
145  if (sstrm.eof() || (sstrm.peek() != EOF))
146  {
147  std::string error_msg;
148  error_msg += "Prior_pdf output must contain exactly one "
149  "newline-terminated line, given output: ";
150  error_msg += prior_pdf_output;
151  throw std::runtime_error(error_msg);
152  }
153 
154  // Parse line as double-precision floating point
155  try
156  {
157  return std::stod(line);
158  }
159  catch (const std::invalid_argument& e)
160  {
161  std::string error_msg;
162  error_msg += "Invalid argument: ";
163  error_msg += e.what();
164  error_msg += '\n';
165  error_msg += "Cannot parse output of prior_pdf: ";
166  error_msg += prior_pdf_output;
167  throw std::runtime_error(error_msg);
168  }
169  catch (const std::out_of_range& e)
170  {
171  std::string error_msg;
172  error_msg += "Out of range: ";
173  error_msg += e.what();
174  error_msg += '\n';
175  error_msg += "Cannot parse output of prior_pdf: ";
176  error_msg += prior_pdf_output;
177  throw std::runtime_error(error_msg);
178  }
179 }
180 
181 // perturbation_pdf protocol
183  int t,
184  const Parameter& perturbed_parameter,
185  const std::vector<Parameter>& parameter_population)
186 {
187  std::string input_string;
188  input_string += std::to_string(t);
189  input_string += '\n';
190  input_string += perturbed_parameter.str();
191  input_string += '\n';
192 
193  for (const Parameter& parameter : parameter_population)
194  {
195  input_string += parameter.str();
196  input_string += '\n';
197  }
198 
199  return input_string;
200 }
201 
202 std::vector<double> parse_perturbation_pdf_output(
203  const std::string& perturbation_pdf_output)
204 {
205  // Ensure that output ends with newline. Cannot check for too many lines
206  // because the number of lines is unspecified
207  if (perturbation_pdf_output.back() != '\n')
208  {
209  std::string error_msg;
210  error_msg += "Perturbation_pdf output must end with newline, "
211  "given output: ";
212  error_msg += perturbation_pdf_output;
213  throw std::runtime_error(error_msg);
214  }
215 
216  // Initialize sstrm and vector
217  std::istringstream sstrm(perturbation_pdf_output);
218  std::string line;
219  std::vector<double> perturbation_pdf_vector;
220 
221  // Parse lines as double-precision floating point
222  try
223  {
224  while (std::getline(sstrm, line))
225  perturbation_pdf_vector.push_back(std::stod(line));
226  }
227  catch (const std::invalid_argument& e)
228  {
229  std::string error_msg;
230  error_msg += "Invalid argument: ";
231  error_msg += e.what();
232  error_msg += '\n';
233  error_msg += "Cannot parse output of perturbation_pdf: ";
234  error_msg += perturbation_pdf_output;
235  throw std::runtime_error(error_msg);
236  }
237  catch (const std::out_of_range& e)
238  {
239  std::string error_msg;
240  error_msg += "Out of range: ";
241  error_msg += e.what();
242  error_msg += '\n';
243  error_msg += "Cannot parse output of perturbation_pdf: ";
244  error_msg += perturbation_pdf_output;
245  throw std::runtime_error(error_msg);
246  }
247 
248  // Return vector
249  return perturbation_pdf_vector;
250 }
251 
252 // generator protocol
253 std::vector<Parameter> parse_generator_output(
254  const std::string& generator_output)
255 {
256  // Ensure that output ends with newline. Cannot check for too many lines
257  // because the number of lines is unspecified
258  if (generator_output.back() != '\n')
259  {
260  std::string error_msg;
261  error_msg += "Generator output must end with newline, "
262  "given output: ";
263  error_msg += generator_output;
264  throw std::runtime_error(error_msg);
265  }
266 
267  // Initialize sstrm and vector
268  std::istringstream sstrm(generator_output);
269  std::string line;
270  std::vector<Parameter> generator_vector;
271 
272  // Parse lines as double-precision floating point
273  try
274  {
275  while (std::getline(sstrm, line))
276  generator_vector.push_back(std::move(line));
277  }
278  catch (const std::runtime_error& e)
279  {
280  std::string error_msg;
281  error_msg += e.what();
282  error_msg += '\n';
283  error_msg += "Cannot parse output of generator: ";
284  error_msg += generator_output;
285  throw std::runtime_error(error_msg);
286  }
287 
288  // Return vector
289  return generator_vector;
290 }
291 
292 
293 // Call prior_sampler to sample from prior
294 Parameter sample_from_prior(const Command& prior_sampler)
295 {
296  std::string prior_sampler_output = system_call(prior_sampler);
297  return parse_prior_sampler_output(prior_sampler_output);
298 }
299 
300 // Call perturber to perturb parameter
302  source_parameter)
303 {
304  std::string perturber_input = format_perturber_input(t,
305  source_parameter);
306  std::string perturber_output = system_call(perturber, perturber_input);
307  return parse_perturber_output(perturber_output);
308 }
309 
310 // Call prior_pdf to get prior pdf of parameter
311 double get_prior_pdf(const Command& prior_pdf, Parameter parameter)
312 {
313  std::string prior_pdf_input = format_prior_pdf_input(parameter);
314  std::string prior_pdf_output = system_call(prior_pdf, prior_pdf_input);
315  return parse_prior_pdf_output(prior_pdf_output);
316 }
317 
318 // Call perturbation_pdf to get perturbation pdf of parameters
319 std::vector<double> get_perturbation_pdf(const Command& perturbation_pdf,
320  int t, const Parameter& perturbed_parameter,
321  const std::vector<Parameter>& parameter_population)
322 {
323  std::string perturbation_pdf_input = format_perturbation_pdf_input(t,
324  perturbed_parameter, parameter_population);
325  std::string perturbation_pdf_output = system_call(perturbation_pdf,
326  perturbation_pdf_input);
327  return parse_perturbation_pdf_output(perturbation_pdf_output);
328 }
std::string format_perturbation_pdf_input(int t, const Parameter &perturbed_parameter, const std::vector< Parameter > &parameter_population)
Definition: protocols.cc:182
const std::string & str() const
Definition: LineString.cc:45
std::string format_simulator_input(const Epsilon &epsilon, const Parameter &parameter)
Definition: protocols.cc:11
std::string format_perturber_input(int t, const Parameter &source_parameter)
Definition: protocols.cc:99
std::vector< double > get_perturbation_pdf(const Command &perturbation_pdf, int t, const Parameter &perturbed_parameter, const std::vector< Parameter > &parameter_population)
Definition: protocols.cc:319
Parameter parse_perturber_output(const std::string &perturber_output)
Definition: protocols.cc:110
Parameter sample_from_prior(const Command &prior_sampler)
Definition: protocols.cc:294
double parse_prior_pdf_output(const std::string &prior_pdf_output)
Definition: protocols.cc:137
std::string format_prior_pdf_input(const Parameter &parameter)
Definition: protocols.cc:128
Parameter perturb_parameter(const Command &perturber, int t, Parameter source_parameter)
Definition: protocols.cc:301
Parameter parse_prior_sampler_output(const std::string &prior_sampler_output)
Definition: protocols.cc:65
double get_prior_pdf(const Command &prior_pdf, Parameter parameter)
Definition: protocols.cc:311
std::vector< Parameter > parse_generator_output(const std::string &generator_output)
Definition: protocols.cc:253
bool parse_simulator_output(const std::string &simulator_output)
Definition: protocols.cc:24
std::vector< double > parse_perturbation_pdf_output(const std::string &perturbation_pdf_output)
Definition: protocols.cc:202