From 2343d1a31fee4bbefa1e08c2374d100def8512e1 Mon Sep 17 00:00:00 2001 From: gvegayon Date: Fri, 22 Nov 2024 00:15:47 +0000 Subject: [PATCH] deploy: d7e04a4a5d232d254b21511690bb0caabc1e1d84 --- agent-meat-virus-sampling_8hpp_source.html | 6 +- class_l_f_m_c_m_c-members.html | 4 +- class_l_f_m_c_m_c.html | 12 +- class_model_s_e_i_r.html | 4 +- class_model_s_e_i_r_d.html | 4 +- classepiworld_1_1_l_f_m_c_m_c-members.html | 4 +- classepiworld_1_1_l_f_m_c_m_c.html | 12 +- classepiworld_1_1_model.html | 2 +- ...iworld_1_1epimodels_1_1_model_s_e_i_r.html | 4 +- ...orld_1_1epimodels_1_1_model_s_e_i_r_d.html | 4 +- diffnet_8hpp_source.html | 8 +- dir_02538684322ef550c75c27a53acd1367.html | 79 + epiworld_8hpp_source.html | 34266 ++++++++-------- include_2epiworld_2epiworld_8hpp_source.html | 4 +- init-functions_8hpp_source.html | 4 +- latex/agent-meat-state_8hpp__dep__incl.pdf | Bin 7058 -> 7058 bytes latex/agent-meat-state_8hpp__incl.pdf | Bin 6750 -> 6750 bytes latex/class_l_f_m_c_m_c.tex | 10 +- latex/class_model__coll__graph.pdf | Bin 6018 -> 6018 bytes latex/class_model_diff_net__coll__graph.pdf | Bin 8626 -> 8626 bytes .../class_model_diff_net__inherit__graph.pdf | Bin 8626 -> 8626 bytes latex/class_model_s_e_i_r__coll__graph.pdf | Bin 6233 -> 6233 bytes latex/class_model_s_e_i_r__inherit__graph.pdf | Bin 6233 -> 6233 bytes ...ass_model_s_e_i_r_c_o_n_n__coll__graph.pdf | Bin 7086 -> 7086 bytes ..._model_s_e_i_r_c_o_n_n__inherit__graph.pdf | Bin 7086 -> 7086 bytes latex/class_model_s_e_i_r_d__coll__graph.pdf | Bin 6317 -> 6317 bytes .../class_model_s_e_i_r_d__inherit__graph.pdf | Bin 6317 -> 6317 bytes ...s_model_s_e_i_r_d_c_o_n_n__coll__graph.pdf | Bin 7074 -> 7074 bytes ...odel_s_e_i_r_d_c_o_n_n__inherit__graph.pdf | Bin 7074 -> 7074 bytes ...lass_model_s_e_i_r_mixing__coll__graph.pdf | Bin 7147 -> 7147 bytes ...s_model_s_e_i_r_mixing__inherit__graph.pdf | Bin 7147 -> 7147 bytes latex/class_model_s_i_r__coll__graph.pdf | Bin 6141 -> 6141 bytes latex/class_model_s_i_r__inherit__graph.pdf | Bin 6141 -> 6141 bytes ...class_model_s_i_r_c_o_n_n__coll__graph.pdf | Bin 7075 -> 7075 bytes ...ss_model_s_i_r_c_o_n_n__inherit__graph.pdf | Bin 7075 -> 7075 bytes latex/class_model_s_i_r_d__coll__graph.pdf | Bin 6237 -> 6237 bytes latex/class_model_s_i_r_d__inherit__graph.pdf | Bin 6237 -> 6237 bytes ...ass_model_s_i_r_d_c_o_n_n__coll__graph.pdf | Bin 7076 -> 7076 bytes ..._model_s_i_r_d_c_o_n_n__inherit__graph.pdf | Bin 7076 -> 7076 bytes .../class_model_s_i_r_logit__coll__graph.pdf | Bin 7083 -> 7083 bytes ...lass_model_s_i_r_logit__inherit__graph.pdf | Bin 7083 -> 7083 bytes .../class_model_s_i_r_mixing__coll__graph.pdf | Bin 7147 -> 7147 bytes ...ass_model_s_i_r_mixing__inherit__graph.pdf | Bin 7147 -> 7147 bytes latex/class_model_s_i_s__coll__graph.pdf | Bin 5949 -> 5949 bytes latex/class_model_s_i_s__inherit__graph.pdf | Bin 5949 -> 5949 bytes latex/class_model_s_i_s_d__coll__graph.pdf | Bin 6046 -> 6046 bytes latex/class_model_s_i_s_d__inherit__graph.pdf | Bin 6046 -> 6046 bytes latex/class_model_s_u_r_v__coll__graph.pdf | Bin 6805 -> 6805 bytes latex/class_model_s_u_r_v__inherit__graph.pdf | Bin 6805 -> 6805 bytes latex/classepiworld_1_1_l_f_m_c_m_c.tex | 10 +- .../classepiworld_1_1_model__coll__graph.pdf | Bin 6333 -> 6333 bytes ...models_1_1_model_diff_net__coll__graph.pdf | Bin 9014 -> 9014 bytes ...els_1_1_model_diff_net__inherit__graph.pdf | Bin 9014 -> 9014 bytes ...imodels_1_1_model_s_e_i_r__coll__graph.pdf | Bin 6611 -> 6611 bytes ...dels_1_1_model_s_e_i_r__inherit__graph.pdf | Bin 6611 -> 6611 bytes ...1_1_model_s_e_i_r_c_o_n_n__coll__graph.pdf | Bin 7446 -> 7446 bytes ..._model_s_e_i_r_c_o_n_n__inherit__graph.pdf | Bin 7446 -> 7446 bytes ...odels_1_1_model_s_e_i_r_d__coll__graph.pdf | Bin 6710 -> 6710 bytes ...ls_1_1_model_s_e_i_r_d__inherit__graph.pdf | Bin 6710 -> 6710 bytes ...1_model_s_e_i_r_d_c_o_n_n__coll__graph.pdf | Bin 7462 -> 7462 bytes ...odel_s_e_i_r_d_c_o_n_n__inherit__graph.pdf | Bin 7462 -> 7462 bytes ..._1_1_model_s_e_i_r_mixing__coll__graph.pdf | Bin 7501 -> 7501 bytes ...1_model_s_e_i_r_mixing__inherit__graph.pdf | Bin 7501 -> 7501 bytes ...epimodels_1_1_model_s_i_r__coll__graph.pdf | Bin 6521 -> 6521 bytes ...models_1_1_model_s_i_r__inherit__graph.pdf | Bin 6521 -> 6521 bytes ...s_1_1_model_s_i_r_c_o_n_n__coll__graph.pdf | Bin 7443 -> 7443 bytes ..._1_model_s_i_r_c_o_n_n__inherit__graph.pdf | Bin 7443 -> 7443 bytes ...imodels_1_1_model_s_i_r_d__coll__graph.pdf | Bin 6619 -> 6619 bytes ...dels_1_1_model_s_i_r_d__inherit__graph.pdf | Bin 6619 -> 6619 bytes ...1_1_model_s_i_r_d_c_o_n_n__coll__graph.pdf | Bin 7461 -> 7461 bytes ..._model_s_i_r_d_c_o_n_n__inherit__graph.pdf | Bin 7461 -> 7461 bytes ...els_1_1_model_s_i_r_logit__coll__graph.pdf | Bin 7447 -> 7447 bytes ..._1_1_model_s_i_r_logit__inherit__graph.pdf | Bin 7447 -> 7447 bytes ...ls_1_1_model_s_i_r_mixing__coll__graph.pdf | Bin 7503 -> 7503 bytes ...1_1_model_s_i_r_mixing__inherit__graph.pdf | Bin 7503 -> 7503 bytes ...epimodels_1_1_model_s_i_s__coll__graph.pdf | Bin 6324 -> 6324 bytes ...models_1_1_model_s_i_s__inherit__graph.pdf | Bin 6324 -> 6324 bytes ...imodels_1_1_model_s_i_s_d__coll__graph.pdf | Bin 6416 -> 6416 bytes ...dels_1_1_model_s_i_s_d__inherit__graph.pdf | Bin 6416 -> 6416 bytes ...imodels_1_1_model_s_u_r_v__coll__graph.pdf | Bin 7173 -> 7173 bytes ...dels_1_1_model_s_u_r_v__inherit__graph.pdf | Bin 7173 -> 7173 bytes latex/md__r_e_a_d_m_e_old.tex | 12 +- latex/md_paper_mixing.tex | 4 +- latex/namespaceepiworld_1_1sampler.tex | 12 +- latex/namespacesampler.tex | 12 +- latex/refman.aux | 24 +- latex/refman.log | 146 +- latex/refman.pdf | Bin 1106313 -> 1106768 bytes latex/struct_event__coll__graph.pdf | Bin 7191 -> 7191 bytes lfmcmc-bones_8hpp_source.html | 24 +- lfmcmc-meat-print_8hpp_source.html | 415 +- lfmcmc-meat_8hpp_source.html | 553 +- md__r_e_a_d_m_e_old.html | 12 +- md_paper_mixing.html | 4 +- misc_8hpp_source.html | 2 +- model-meat_8hpp_source.html | 2 +- namespaceepiworld_1_1sampler.html | 12 +- namespacesampler.html | 12 +- seir_8hpp_source.html | 6 +- seirconnected_8hpp_source.html | 8 +- seird_8hpp_source.html | 10 +- seirdconnected_8hpp_source.html | 10 +- seirmixing_8hpp_source.html | 8 +- sir_8hpp_source.html | 4 +- sirconnected_8hpp_source.html | 8 +- sird_8hpp_source.html | 4 +- sirdconnected_8hpp_source.html | 10 +- sirlogit_8hpp_source.html | 6 +- sirmixing_8hpp_source.html | 8 +- sis_8hpp_source.html | 4 +- sisd_8hpp_source.html | 4 +- surveillance_8hpp_source.html | 8 +- tests_8hpp_source.html | 6 +- 113 files changed, 17977 insertions(+), 17810 deletions(-) create mode 100644 dir_02538684322ef550c75c27a53acd1367.html diff --git a/agent-meat-virus-sampling_8hpp_source.html b/agent-meat-virus-sampling_8hpp_source.html index 96d01f21a..e70b2af93 100644 --- a/agent-meat-virus-sampling_8hpp_source.html +++ b/agent-meat-virus-sampling_8hpp_source.html @@ -75,7 +75,7 @@
3 
8 namespace sampler {
9 
-
23 template<typename TSeq>
+
23 template<typename TSeq = EPI_DEFAULT_TSEQ>
24 inline std::function<void(Agent<TSeq>*,Model<TSeq>*)> make_update_susceptible(
25  std::vector< epiworld_fast_uint > exclude = {}
26  )
@@ -221,7 +221,7 @@
166 
167 }
168 
-
182 template<typename TSeq = int>
+
182 template<typename TSeq = EPI_DEFAULT_TSEQ>
183 inline std::function<Virus<TSeq>*(Agent<TSeq>*,Model<TSeq>*)> make_sample_virus_neighbors(
184  std::vector< epiworld_fast_uint > exclude = {}
185 )
@@ -373,7 +373,7 @@
331 
332 }
333 
-
350 template<typename TSeq = int>
+
350 template<typename TSeq = EPI_DEFAULT_TSEQ>
351 inline Virus<TSeq> * sample_virus_single(Agent<TSeq> * p, Model<TSeq> * m)
352 {
353 
diff --git a/class_l_f_m_c_m_c-members.html b/class_l_f_m_c_m_c-members.html index 5b66a9571..176b60034 100644 --- a/class_l_f_m_c_m_c-members.html +++ b/class_l_f_m_c_m_c-members.html @@ -69,6 +69,8 @@

This is the complete list of members for LFMCMC< TData >, including all inherited members.

+ + @@ -87,7 +89,7 @@ - + diff --git a/class_l_f_m_c_m_c.html b/class_l_f_m_c_m_c.html index ac29a65d8..1569f26f3 100644 --- a/class_l_f_m_c_m_c.html +++ b/class_l_f_m_c_m_c.html @@ -137,6 +137,12 @@ + + + + @@ -149,9 +155,9 @@ - - + +
get_accepted_params() (defined in LFMCMC< TData >)LFMCMC< TData >inline
get_accepted_stats() (defined in LFMCMC< TData >)LFMCMC< TData >inline
get_drawn_prob() (defined in LFMCMC< TData >)LFMCMC< TData >inline
get_epsilon() const (defined in LFMCMC< TData >)LFMCMC< TData >inline
get_n_parameters() const (defined in LFMCMC< TData >)LFMCMC< TData >inline
get_stats_mean() (defined in LFMCMC< TData >)LFMCMC< TData >inline
LFMCMC() (defined in LFMCMC< TData >)LFMCMC< TData >inline
LFMCMC(const TData &observed_data_) (defined in LFMCMC< TData >)LFMCMC< TData >inline
print() (defined in LFMCMC< TData >)LFMCMC< TData >inline
print(size_t burnin=0u) const (defined in LFMCMC< TData >)LFMCMC< TData >inline
rgamma() (defined in LFMCMC< TData >)LFMCMC< TData >inline
rgamma(epiworld_double alpha, epiworld_double beta) (defined in LFMCMC< TData >)LFMCMC< TData >inline
rnorm() (defined in LFMCMC< TData >)LFMCMC< TData >inline
std::vector< TData > * get_sampled_data ()
 
+const std::vector< epiworld_double > & get_accepted_params ()
 
+const std::vector< epiworld_double > & get_accepted_stats ()
 
void set_par_names (std::vector< std::string > names)
 
std::vector< epiworld_double > get_stats_mean ()
 
-void print ()
 
+void print (size_t burnin=0u) const
 
Random number generation
Parameters
diff --git a/class_model_s_e_i_r.html b/class_model_s_e_i_r.html index d8f00c212..8ca9112be 100644 --- a/class_model_s_e_i_r.html +++ b/class_model_s_e_i_r.html @@ -788,8 +788,8 @@

return;
}
Template for a Susceptible-Exposed-Infected-Removed (SEIR) model.
Definition: seir.hpp:16
-
Agent (agents)
Definition: epiworld.hpp:13643
-
Core class of epiworld.
Definition: epiworld.hpp:6296
+
Agent (agents)
Definition: epiworld.hpp:13673
+
Core class of epiworld.
Definition: epiworld.hpp:6326
diff --git a/class_model_s_e_i_r_d.html b/class_model_s_e_i_r_d.html index 8e14c7ad1..21060c737 100644 --- a/class_model_s_e_i_r_d.html +++ b/class_model_s_e_i_r_d.html @@ -892,8 +892,8 @@

return;
}
Template for a Susceptible-Exposed-Infected-Removed-Deceased (SEIRD) model.
Definition: seird.hpp:9
-
Agent (agents)
Definition: epiworld.hpp:13643
-
Core class of epiworld.
Definition: epiworld.hpp:6296
+
Agent (agents)
Definition: epiworld.hpp:13673
+
Core class of epiworld.
Definition: epiworld.hpp:6326
diff --git a/classepiworld_1_1_l_f_m_c_m_c-members.html b/classepiworld_1_1_l_f_m_c_m_c-members.html index 315d375f7..e22c917a0 100644 --- a/classepiworld_1_1_l_f_m_c_m_c-members.html +++ b/classepiworld_1_1_l_f_m_c_m_c-members.html @@ -73,6 +73,8 @@

This is the complete list of members for epiworld::LFMCMC< TData >, including all inherited members.

+ + @@ -91,7 +93,7 @@ - + diff --git a/classepiworld_1_1_l_f_m_c_m_c.html b/classepiworld_1_1_l_f_m_c_m_c.html index d90fd7a2e..1b957077f 100644 --- a/classepiworld_1_1_l_f_m_c_m_c.html +++ b/classepiworld_1_1_l_f_m_c_m_c.html @@ -141,6 +141,12 @@ + + + + @@ -153,9 +159,9 @@ - - + +
get_accepted_params() (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
get_accepted_stats() (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
get_drawn_prob() (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
get_epsilon() const (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
get_n_parameters() const (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
get_stats_mean() (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
LFMCMC() (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
LFMCMC(const TData &observed_data_) (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
print() (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
print(size_t burnin=0u) const (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
rgamma() (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
rgamma(epiworld_double alpha, epiworld_double beta) (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
rnorm() (defined in epiworld::LFMCMC< TData >)epiworld::LFMCMC< TData >inline
std::vector< TData > * get_sampled_data ()
 
+const std::vector< epiworld_double > & get_accepted_params ()
 
+const std::vector< epiworld_double > & get_accepted_stats ()
 
void set_par_names (std::vector< std::string > names)
 
std::vector< epiworld_double > get_stats_mean ()
 
-void print ()
 
+void print (size_t burnin=0u) const
 
Random number generation
Parameters
diff --git a/classepiworld_1_1_model.html b/classepiworld_1_1_model.html index 06dbad3c5..a00742beb 100644 --- a/classepiworld_1_1_model.html +++ b/classepiworld_1_1_model.html @@ -494,7 +494,7 @@
[name of parameter 1]: [value in double]
[name of parameter 2]: [value in double]
...
-
std::string name
Name of the model.
Definition: epiworld.hpp:6303
+
std::string name
Name of the model.
Definition: epiworld.hpp:6333

The only condition for parameter names is that these do not include a colon.

Parameters
diff --git a/classepiworld_1_1epimodels_1_1_model_s_e_i_r.html b/classepiworld_1_1epimodels_1_1_model_s_e_i_r.html index 39967b041..9924e13ba 100644 --- a/classepiworld_1_1epimodels_1_1_model_s_e_i_r.html +++ b/classepiworld_1_1epimodels_1_1_model_s_e_i_r.html @@ -792,8 +792,8 @@

return;
}
Template for a Susceptible-Exposed-Infected-Removed (SEIR) model.
Definition: seir.hpp:16
-
Agent (agents)
Definition: epiworld.hpp:13643
-
Core class of epiworld.
Definition: epiworld.hpp:6296
+
Agent (agents)
Definition: epiworld.hpp:13673
+
Core class of epiworld.
Definition: epiworld.hpp:6326
diff --git a/classepiworld_1_1epimodels_1_1_model_s_e_i_r_d.html b/classepiworld_1_1epimodels_1_1_model_s_e_i_r_d.html index a82c3e8fd..60e9c8fdc 100644 --- a/classepiworld_1_1epimodels_1_1_model_s_e_i_r_d.html +++ b/classepiworld_1_1epimodels_1_1_model_s_e_i_r_d.html @@ -896,8 +896,8 @@

return;
}
Template for a Susceptible-Exposed-Infected-Removed-Deceased (SEIRD) model.
Definition: seird.hpp:9
-
Agent (agents)
Definition: epiworld.hpp:13643
-
Core class of epiworld.
Definition: epiworld.hpp:6296
+
Agent (agents)
Definition: epiworld.hpp:13673
+
Core class of epiworld.
Definition: epiworld.hpp:6326
diff --git a/diffnet_8hpp_source.html b/diffnet_8hpp_source.html index 5aa168215..b300fdfe4 100644 --- a/diffnet_8hpp_source.html +++ b/diffnet_8hpp_source.html @@ -273,10 +273,10 @@
210 #endif
Agent (agents)
Definition: agent-bones.hpp:66
Template for a Network Diffusion Model.
Definition: diffnet.hpp:15
-
Agent (agents)
Definition: epiworld.hpp:13643
-
Core class of epiworld.
Definition: epiworld.hpp:6296
-
size_t get_n_viruses() const
Number of viruses in the model.
Definition: epiworld.hpp:8598
-
Virus.
Definition: epiworld.hpp:10105
+
Agent (agents)
Definition: epiworld.hpp:13673
+
Core class of epiworld.
Definition: epiworld.hpp:6326
+
size_t get_n_viruses() const
Number of viruses in the model.
Definition: epiworld.hpp:8628
+
Virus.
Definition: epiworld.hpp:10135

+ + + + + +
+
epiworld +  0.0-1 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
14-community-hosp Directory Reference
+
+
+
+ + + + diff --git a/epiworld_8hpp_source.html b/epiworld_8hpp_source.html index 509e257bb..bc767680d 100644 --- a/epiworld_8hpp_source.html +++ b/epiworld_8hpp_source.html @@ -86,8 +86,8 @@
18 
19 /* Versioning */
20 #define EPIWORLD_VERSION_MAJOR 0
-
21 #define EPIWORLD_VERSION_MINOR 4
-
22 #define EPIWORLD_VERSION_PATCH 3
+
21 #define EPIWORLD_VERSION_MINOR 5
+
22 #define EPIWORLD_VERSION_PATCH 0
23 
24 static const int epiworld_version_major = EPIWORLD_VERSION_MAJOR;
25 static const int epiworld_version_minor = EPIWORLD_VERSION_MINOR;
@@ -556,7 +556,7 @@
582  return false;
583 }
584 
-
598 template<typename TSeq, typename TDbl>
+
598 template<typename TSeq = EPI_DEFAULT_TSEQ, typename TDbl = epiworld_double >
599 inline int roulette(
600  const std::vector< TDbl > & probs,
601  Model<TSeq> * m
@@ -1075,7 +1075,7 @@
1239  epiworld_double * last_elapsed,
1240  std::string * unit_abbr,
1241  bool print
-
1242  );
+
1242  ) const;
1243 
1244  void chrono_start();
1245  void chrono_end();
@@ -1126,9697 +1126,9697 @@
1297  const std::vector< epiworld_double > & get_drawn_prob() {return drawn_prob;};
1298  std::vector< TData > * get_sampled_data() {return sampled_data;};
1299 
-
1300  void set_par_names(std::vector< std::string > names);
-
1301  void set_stats_names(std::vector< std::string > names);
+
1300  const std::vector< epiworld_double > & get_accepted_params() {return accepted_params;};
+
1301  const std::vector< epiworld_double > & get_accepted_stats() {return accepted_stats;};
1302 
-
1303  std::vector< epiworld_double > get_params_mean();
-
1304  std::vector< epiworld_double > get_stats_mean();
-
1305 
-
1306  void print() ;
-
1307 
-
1308 };
+
1303 
+
1304  void set_par_names(std::vector< std::string > names);
+
1305  void set_stats_names(std::vector< std::string > names);
+
1306 
+
1307  std::vector< epiworld_double > get_params_mean();
+
1308  std::vector< epiworld_double > get_stats_mean();
1309 
-
1310 #endif
-
1311 /*//////////////////////////////////////////////////////////////////////////////
+
1310  void print(size_t burnin = 0u) const;
+
1311 
+
1312 };
1313 
-
1314  End of -include/epiworld//math/lfmcmc/lfmcmc-bones.hpp-
-
1315 
-
1318 
+
1314 #endif
+
1315 /*//////////////////////////////////////////////////////////////////////////////
+
1317 
+
1318  End of -include/epiworld//math/lfmcmc/lfmcmc-bones.hpp-
1319 
-
1320 /*//////////////////////////////////////////////////////////////////////////////
1322 
-
1323  Start of -include/epiworld//math/lfmcmc/lfmcmc-meat.hpp-
-
1324 
-
1327 
+
1323 
+
1324 /*//////////////////////////////////////////////////////////////////////////////
+
1326 
+
1327  Start of -include/epiworld//math/lfmcmc/lfmcmc-meat.hpp-
1328 
-
1329 #ifndef EPIWORLD_LFMCMC_MEAT_HPP
-
1330 #define EPIWORLD_LFMCMC_MEAT_HPP
1331 
-
1332 /*//////////////////////////////////////////////////////////////////////////////
-
1334 
-
1335  Start of -include/epiworld//math//lfmcmc/lfmcmc-bones.hpp-
-
1336 
-
1339 
+
1332 
+
1333 #ifndef EPIWORLD_LFMCMC_MEAT_HPP
+
1334 #define EPIWORLD_LFMCMC_MEAT_HPP
+
1335 
+
1336 /*//////////////////////////////////////////////////////////////////////////////
+
1338 
+
1339  Start of -include/epiworld//math//lfmcmc/lfmcmc-bones.hpp-
1340 
-
1341 #ifndef EPIWORLD_LFMCMC_BONES_HPP
-
1342 #define EPIWORLD_LFMCMC_BONES_HPP
1343 
-
1344 #ifndef epiworld_double
-
1345  #define epiworld_double float
-
1346 #endif
+
1344 
+
1345 #ifndef EPIWORLD_LFMCMC_BONES_HPP
+
1346 #define EPIWORLD_LFMCMC_BONES_HPP
1347 
-
1348 
-
1349 template<typename TData>
-
1350 class LFMCMC;
+
1348 #ifndef epiworld_double
+
1349  #define epiworld_double float
+
1350 #endif
1351 
-
1352 template<typename TData>
-
1353 using LFMCMCSimFun = std::function<TData(const std::vector< epiworld_double >&,LFMCMC<TData>*)>;
-
1354 
-
1355 template<typename TData>
-
1356 using LFMCMCSummaryFun = std::function<void(std::vector< epiworld_double >&,const TData&,LFMCMC<TData>*)>;
-
1357 
-
1358 template<typename TData>
-
1359 using LFMCMCProposalFun = std::function<void(std::vector< epiworld_double >&,const std::vector< epiworld_double >&,LFMCMC<TData>*)>;
-
1360 
-
1361 template<typename TData>
-
1362 using LFMCMCKernelFun = std::function<epiworld_double(const std::vector< epiworld_double >&,const std::vector< epiworld_double >&,epiworld_double,LFMCMC<TData>*)>;
-
1363 
-
1371 template<typename TData>
-
1372 inline void proposal_fun_normal(
-
1373  std::vector< epiworld_double >& params_now,
-
1374  const std::vector< epiworld_double >& params_prev,
-
1375  LFMCMC<TData>* m
-
1376 );
-
1377 
-
1390 template<typename TData>
-
1391 inline LFMCMCProposalFun<TData> make_proposal_norm_reflective(
-
1392  epiworld_double scale,
-
1393  epiworld_double lb = std::numeric_limits<epiworld_double>::min(),
-
1394  epiworld_double ub = std::numeric_limits<epiworld_double>::max()
-
1395 );
-
1396 
-
1408 template<typename TData>
-
1409 inline void proposal_fun_unif(
-
1410  std::vector< epiworld_double >& params_now,
-
1411  const std::vector< epiworld_double >& params_prev,
-
1412  LFMCMC<TData>* m
-
1413 );
-
1414 
-
1425 template<typename TData>
-
1426 inline epiworld_double kernel_fun_uniform(
-
1427  const std::vector< epiworld_double >& stats_now,
-
1428  const std::vector< epiworld_double >& stats_obs,
-
1429  epiworld_double epsilon,
-
1430  LFMCMC<TData>* m
-
1431 );
-
1432 
-
1441 template<typename TData>
-
1442 inline epiworld_double kernel_fun_gaussian(
-
1443  const std::vector< epiworld_double >& stats_now,
-
1444  const std::vector< epiworld_double >& stats_obs,
-
1445  epiworld_double epsilon,
-
1446  LFMCMC<TData>* m
-
1447 );
-
1448 
-
1454 template<typename TData>
-
1455 class LFMCMC {
-
1456 private:
-
1457 
-
1458  // Random number sampling
-
1459  std::shared_ptr< std::mt19937 > engine = nullptr;
-
1460 
-
1461  std::shared_ptr< std::uniform_real_distribution<> > runifd =
-
1462  std::make_shared< std::uniform_real_distribution<> >(0.0, 1.0);
-
1463 
-
1464  std::shared_ptr< std::normal_distribution<> > rnormd =
-
1465  std::make_shared< std::normal_distribution<> >(0.0);
-
1466 
-
1467  std::shared_ptr< std::gamma_distribution<> > rgammad =
-
1468  std::make_shared< std::gamma_distribution<> >();
-
1469 
-
1470  // Process data
-
1471  TData observed_data;
-
1472 
-
1473  // Information about the size of the problem
-
1474  size_t n_samples;
-
1475  size_t n_statistics;
-
1476  size_t n_parameters;
-
1477 
-
1478  epiworld_double epsilon;
-
1479 
-
1480  std::vector< epiworld_double > params_now;
-
1481  std::vector< epiworld_double > params_prev;
-
1482  std::vector< epiworld_double > params_init;
+
1352 
+
1353 template<typename TData>
+
1354 class LFMCMC;
+
1355 
+
1356 template<typename TData>
+
1357 using LFMCMCSimFun = std::function<TData(const std::vector< epiworld_double >&,LFMCMC<TData>*)>;
+
1358 
+
1359 template<typename TData>
+
1360 using LFMCMCSummaryFun = std::function<void(std::vector< epiworld_double >&,const TData&,LFMCMC<TData>*)>;
+
1361 
+
1362 template<typename TData>
+
1363 using LFMCMCProposalFun = std::function<void(std::vector< epiworld_double >&,const std::vector< epiworld_double >&,LFMCMC<TData>*)>;
+
1364 
+
1365 template<typename TData>
+
1366 using LFMCMCKernelFun = std::function<epiworld_double(const std::vector< epiworld_double >&,const std::vector< epiworld_double >&,epiworld_double,LFMCMC<TData>*)>;
+
1367 
+
1375 template<typename TData>
+
1376 inline void proposal_fun_normal(
+
1377  std::vector< epiworld_double >& params_now,
+
1378  const std::vector< epiworld_double >& params_prev,
+
1379  LFMCMC<TData>* m
+
1380 );
+
1381 
+
1394 template<typename TData>
+
1395 inline LFMCMCProposalFun<TData> make_proposal_norm_reflective(
+
1396  epiworld_double scale,
+
1397  epiworld_double lb = std::numeric_limits<epiworld_double>::min(),
+
1398  epiworld_double ub = std::numeric_limits<epiworld_double>::max()
+
1399 );
+
1400 
+
1412 template<typename TData>
+
1413 inline void proposal_fun_unif(
+
1414  std::vector< epiworld_double >& params_now,
+
1415  const std::vector< epiworld_double >& params_prev,
+
1416  LFMCMC<TData>* m
+
1417 );
+
1418 
+
1429 template<typename TData>
+
1430 inline epiworld_double kernel_fun_uniform(
+
1431  const std::vector< epiworld_double >& stats_now,
+
1432  const std::vector< epiworld_double >& stats_obs,
+
1433  epiworld_double epsilon,
+
1434  LFMCMC<TData>* m
+
1435 );
+
1436 
+
1445 template<typename TData>
+
1446 inline epiworld_double kernel_fun_gaussian(
+
1447  const std::vector< epiworld_double >& stats_now,
+
1448  const std::vector< epiworld_double >& stats_obs,
+
1449  epiworld_double epsilon,
+
1450  LFMCMC<TData>* m
+
1451 );
+
1452 
+
1458 template<typename TData>
+
1459 class LFMCMC {
+
1460 private:
+
1461 
+
1462  // Random number sampling
+
1463  std::shared_ptr< std::mt19937 > engine = nullptr;
+
1464 
+
1465  std::shared_ptr< std::uniform_real_distribution<> > runifd =
+
1466  std::make_shared< std::uniform_real_distribution<> >(0.0, 1.0);
+
1467 
+
1468  std::shared_ptr< std::normal_distribution<> > rnormd =
+
1469  std::make_shared< std::normal_distribution<> >(0.0);
+
1470 
+
1471  std::shared_ptr< std::gamma_distribution<> > rgammad =
+
1472  std::make_shared< std::gamma_distribution<> >();
+
1473 
+
1474  // Process data
+
1475  TData observed_data;
+
1476 
+
1477  // Information about the size of the problem
+
1478  size_t n_samples;
+
1479  size_t n_statistics;
+
1480  size_t n_parameters;
+
1481 
+
1482  epiworld_double epsilon;
1483 
-
1484  std::vector< epiworld_double > observed_stats; ///< Observed statistics
-
1485 
-
1486  std::vector< epiworld_double > sampled_params; ///< Sampled Parameters
-
1487  std::vector< epiworld_double > sampled_stats; ///< Sampled statistics
-
1488  std::vector< epiworld_double > sampled_stats_prob; ///< Sampled statistics
-
1489  std::vector< bool > sampled_accepted; ///< Indicator of accepted statistics
-
1490 
-
1491  std::vector< epiworld_double > accepted_params; ///< Posterior distribution (accepted samples)
-
1492  std::vector< epiworld_double > accepted_stats; ///< Posterior distribution (accepted samples)
-
1493  std::vector< epiworld_double > accepted_params_prob; ///< Posterior probability
+
1484  std::vector< epiworld_double > params_now;
+
1485  std::vector< epiworld_double > params_prev;
+
1486  std::vector< epiworld_double > params_init;
+
1487 
+
1488  std::vector< epiworld_double > observed_stats; ///< Observed statistics
+
1489 
+
1490  std::vector< epiworld_double > sampled_params; ///< Sampled Parameters
+
1491  std::vector< epiworld_double > sampled_stats; ///< Sampled statistics
+
1492  std::vector< epiworld_double > sampled_stats_prob; ///< Sampled statistics
+
1493  std::vector< bool > sampled_accepted; ///< Indicator of accepted statistics
1494 
-
1495  std::vector< epiworld_double > drawn_prob; ///< Drawn probabilities (runif())
-
1496  std::vector< TData > * sampled_data = nullptr;
-
1497 
-
1498  // Functions
-
1499  LFMCMCSimFun<TData> simulation_fun;
-
1500  LFMCMCSummaryFun<TData> summary_fun;
-
1501  LFMCMCProposalFun<TData> proposal_fun = proposal_fun_normal<TData>;
-
1502  LFMCMCKernelFun<TData> kernel_fun = kernel_fun_uniform<TData>;
-
1503 
-
1504  // Misc
-
1505  std::vector< std::string > names_parameters;
-
1506  std::vector< std::string > names_statistics;
+
1495  std::vector< epiworld_double > accepted_params; ///< Posterior distribution (accepted samples)
+
1496  std::vector< epiworld_double > accepted_stats; ///< Posterior distribution (accepted samples)
+
1497  std::vector< epiworld_double > accepted_params_prob; ///< Posterior probability
+
1498 
+
1499  std::vector< epiworld_double > drawn_prob; ///< Drawn probabilities (runif())
+
1500  std::vector< TData > * sampled_data = nullptr;
+
1501 
+
1502  // Functions
+
1503  LFMCMCSimFun<TData> simulation_fun;
+
1504  LFMCMCSummaryFun<TData> summary_fun;
+
1505  LFMCMCProposalFun<TData> proposal_fun = proposal_fun_normal<TData>;
+
1506  LFMCMCKernelFun<TData> kernel_fun = kernel_fun_uniform<TData>;
1507 
-
1508  std::chrono::time_point<std::chrono::steady_clock> time_start;
-
1509  std::chrono::time_point<std::chrono::steady_clock> time_end;
-
1510 
-
1511  // std::chrono::milliseconds
-
1512  std::chrono::duration<epiworld_double,std::micro> time_elapsed =
-
1513  std::chrono::duration<epiworld_double,std::micro>::zero();
+
1508  // Misc
+
1509  std::vector< std::string > names_parameters;
+
1510  std::vector< std::string > names_statistics;
+
1511 
+
1512  std::chrono::time_point<std::chrono::steady_clock> time_start;
+
1513  std::chrono::time_point<std::chrono::steady_clock> time_end;
1514 
-
1515  inline void get_elapsed(
-
1516  std::string unit,
-
1517  epiworld_double * last_elapsed,
-
1518  std::string * unit_abbr,
-
1519  bool print
-
1520  );
-
1521 
-
1522  void chrono_start();
-
1523  void chrono_end();
-
1524 
-
1525 public:
-
1526 
-
1527  void run(
-
1528  std::vector< epiworld_double > param_init,
-
1529  size_t n_samples_,
-
1530  epiworld_double epsilon_,
-
1531  int seed = -1
-
1532  );
-
1533 
-
1534  LFMCMC() {};
-
1535  LFMCMC(const TData & observed_data_) : observed_data(observed_data_) {};
-
1536  ~LFMCMC() {};
+
1515  // std::chrono::milliseconds
+
1516  std::chrono::duration<epiworld_double,std::micro> time_elapsed =
+
1517  std::chrono::duration<epiworld_double,std::micro>::zero();
+
1518 
+
1519  inline void get_elapsed(
+
1520  std::string unit,
+
1521  epiworld_double * last_elapsed,
+
1522  std::string * unit_abbr,
+
1523  bool print
+
1524  ) const;
+
1525 
+
1526  void chrono_start();
+
1527  void chrono_end();
+
1528 
+
1529 public:
+
1530 
+
1531  void run(
+
1532  std::vector< epiworld_double > param_init,
+
1533  size_t n_samples_,
+
1534  epiworld_double epsilon_,
+
1535  int seed = -1
+
1536  );
1537 
-
1538  void set_observed_data(const TData & observed_data_) {observed_data = observed_data_;};
-
1539  void set_proposal_fun(LFMCMCProposalFun<TData> fun);
-
1540  void set_simulation_fun(LFMCMCSimFun<TData> fun);
-
1541  void set_summary_fun(LFMCMCSummaryFun<TData> fun);
-
1542  void set_kernel_fun(LFMCMCKernelFun<TData> fun);
-
1543 
-
1550  void set_rand_engine(std::shared_ptr< std::mt19937 > & eng);
-
1551  std::shared_ptr< std::mt19937 > & get_rand_endgine();
-
1552  void seed(epiworld_fast_uint s);
-
1553  void set_rand_gamma(epiworld_double alpha, epiworld_double beta);
-
1554  epiworld_double runif();
-
1555  epiworld_double rnorm();
-
1556  epiworld_double rgamma();
-
1557  epiworld_double runif(epiworld_double lb, epiworld_double ub);
-
1558  epiworld_double rnorm(epiworld_double mean, epiworld_double sd);
-
1559  epiworld_double rgamma(epiworld_double alpha, epiworld_double beta);
-
1561 
-
1562  // Accessing parameters of the function
-
1563  size_t get_n_samples() const {return n_samples;};
-
1564  size_t get_n_statistics() const {return n_statistics;};
-
1565  size_t get_n_parameters() const {return n_parameters;};
-
1566  epiworld_double get_epsilon() const {return epsilon;};
-
1567 
-
1568  const std::vector< epiworld_double > & get_params_now() {return params_now;};
-
1569  const std::vector< epiworld_double > & get_params_prev() {return params_prev;};
-
1570  const std::vector< epiworld_double > & get_params_init() {return params_init;};
-
1571  const std::vector< epiworld_double > & get_statistics_obs() {return observed_stats;};
-
1572  const std::vector< epiworld_double > & get_statistics_hist() {return sampled_stats;};
-
1573  const std::vector< bool > & get_statistics_accepted() {return sampled_accepted;};
-
1574  const std::vector< epiworld_double > & get_posterior_lf_prob() {return accepted_params_prob;};
-
1575  const std::vector< epiworld_double > & get_drawn_prob() {return drawn_prob;};
-
1576  std::vector< TData > * get_sampled_data() {return sampled_data;};
-
1577 
-
1578  void set_par_names(std::vector< std::string > names);
-
1579  void set_stats_names(std::vector< std::string > names);
-
1580 
-
1581  std::vector< epiworld_double > get_params_mean();
-
1582  std::vector< epiworld_double > get_stats_mean();
-
1583 
-
1584  void print() ;
+
1538  LFMCMC() {};
+
1539  LFMCMC(const TData & observed_data_) : observed_data(observed_data_) {};
+
1540  ~LFMCMC() {};
+
1541 
+
1542  void set_observed_data(const TData & observed_data_) {observed_data = observed_data_;};
+
1543  void set_proposal_fun(LFMCMCProposalFun<TData> fun);
+
1544  void set_simulation_fun(LFMCMCSimFun<TData> fun);
+
1545  void set_summary_fun(LFMCMCSummaryFun<TData> fun);
+
1546  void set_kernel_fun(LFMCMCKernelFun<TData> fun);
+
1547 
+
1554  void set_rand_engine(std::shared_ptr< std::mt19937 > & eng);
+
1555  std::shared_ptr< std::mt19937 > & get_rand_endgine();
+
1556  void seed(epiworld_fast_uint s);
+
1557  void set_rand_gamma(epiworld_double alpha, epiworld_double beta);
+
1558  epiworld_double runif();
+
1559  epiworld_double rnorm();
+
1560  epiworld_double rgamma();
+
1561  epiworld_double runif(epiworld_double lb, epiworld_double ub);
+
1562  epiworld_double rnorm(epiworld_double mean, epiworld_double sd);
+
1563  epiworld_double rgamma(epiworld_double alpha, epiworld_double beta);
+
1565 
+
1566  // Accessing parameters of the function
+
1567  size_t get_n_samples() const {return n_samples;};
+
1568  size_t get_n_statistics() const {return n_statistics;};
+
1569  size_t get_n_parameters() const {return n_parameters;};
+
1570  epiworld_double get_epsilon() const {return epsilon;};
+
1571 
+
1572  const std::vector< epiworld_double > & get_params_now() {return params_now;};
+
1573  const std::vector< epiworld_double > & get_params_prev() {return params_prev;};
+
1574  const std::vector< epiworld_double > & get_params_init() {return params_init;};
+
1575  const std::vector< epiworld_double > & get_statistics_obs() {return observed_stats;};
+
1576  const std::vector< epiworld_double > & get_statistics_hist() {return sampled_stats;};
+
1577  const std::vector< bool > & get_statistics_accepted() {return sampled_accepted;};
+
1578  const std::vector< epiworld_double > & get_posterior_lf_prob() {return accepted_params_prob;};
+
1579  const std::vector< epiworld_double > & get_drawn_prob() {return drawn_prob;};
+
1580  std::vector< TData > * get_sampled_data() {return sampled_data;};
+
1581 
+
1582  const std::vector< epiworld_double > & get_accepted_params() {return accepted_params;};
+
1583  const std::vector< epiworld_double > & get_accepted_stats() {return accepted_stats;};
+
1584 
1585 
-
1586 };
-
1587 
-
1588 #endif
-
1589 /*//////////////////////////////////////////////////////////////////////////////
+
1586  void set_par_names(std::vector< std::string > names);
+
1587  void set_stats_names(std::vector< std::string > names);
+
1588 
+
1589  std::vector< epiworld_double > get_params_mean();
+
1590  std::vector< epiworld_double > get_stats_mean();
1591 
-
1592  End of -include/epiworld//math//lfmcmc/lfmcmc-bones.hpp-
+
1592  void print(size_t burnin = 0u) const;
1593 
-
1596 
-
1597 
-
1598 
-
1606 template<typename TData>
-
1607 inline void proposal_fun_normal(
-
1608  std::vector< epiworld_double >& params_now,
-
1609  const std::vector< epiworld_double >& params_prev,
-
1610  LFMCMC<TData>* m
-
1611 ) {
-
1612 
-
1613  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
-
1614  params_now[p] = params_prev[p] + m->rnorm();
-
1615 
-
1616  return;
-
1617 }
-
1618 
-
1631 template<typename TData>
-
1632 inline LFMCMCProposalFun<TData> make_proposal_norm_reflective(
-
1633  epiworld_double scale,
-
1634  epiworld_double lb,
-
1635  epiworld_double ub
-
1636 ) {
-
1637 
-
1638  LFMCMCProposalFun<TData> fun =
-
1639  [scale,lb,ub](
-
1640  std::vector< epiworld_double >& params_now,
-
1641  const std::vector< epiworld_double >& params_prev,
-
1642  LFMCMC<TData>* m
-
1643  ) {
-
1644 
-
1645  // Making the proposal
-
1646  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
-
1647  params_now[p] = params_prev[p] + m->rnorm() * scale;
-
1648 
-
1649  // Checking boundaries
-
1650  epiworld_double d = ub - lb;
-
1651  int odd;
-
1652  epiworld_double d_above, d_below;
-
1653  for (auto & p : params_now)
-
1654  {
-
1655 
-
1656  // Correcting if parameter goes above the upper bound
-
1657  if (p > ub)
-
1658  {
-
1659  d_above = p - ub;
-
1660  odd = static_cast<int>(std::floor(d_above / d)) % 2;
-
1661  d_above = d_above - std::floor(d_above / d) * d;
-
1662 
-
1663  p = (lb + d_above) * odd +
-
1664  (ub - d_above) * (1 - odd);
-
1665 
-
1666  // Correcting if parameter goes below upper bound
-
1667  } else if (p < lb)
-
1668  {
-
1669  d_below = lb - p;
-
1670  int odd = static_cast<int>(std::floor(d_below / d)) % 2;
-
1671  d_below = d_below - std::floor(d_below / d) * d;
-
1672 
-
1673  p = (ub - d_below) * odd +
-
1674  (lb + d_below) * (1 - odd);
-
1675  }
-
1676 
-
1677  }
-
1678 
-
1679  #ifdef EPI_DEBUG
-
1680  for (auto & p : params_now)
-
1681  if (p < lb || p > ub)
-
1682  throw std::range_error("The parameter is out of bounds.");
-
1683  #endif
+
1594 };
+
1595 
+
1596 #endif
+
1597 /*//////////////////////////////////////////////////////////////////////////////
+
1599 
+
1600  End of -include/epiworld//math//lfmcmc/lfmcmc-bones.hpp-
+
1601 
+
1604 
+
1605 
+
1606 
+
1614 template<typename TData>
+
1615 inline void proposal_fun_normal(
+
1616  std::vector< epiworld_double >& params_now,
+
1617  const std::vector< epiworld_double >& params_prev,
+
1618  LFMCMC<TData>* m
+
1619 ) {
+
1620 
+
1621  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
+
1622  params_now[p] = params_prev[p] + m->rnorm();
+
1623 
+
1624  return;
+
1625 }
+
1626 
+
1639 template<typename TData>
+
1640 inline LFMCMCProposalFun<TData> make_proposal_norm_reflective(
+
1641  epiworld_double scale,
+
1642  epiworld_double lb,
+
1643  epiworld_double ub
+
1644 ) {
+
1645 
+
1646  LFMCMCProposalFun<TData> fun =
+
1647  [scale,lb,ub](
+
1648  std::vector< epiworld_double >& params_now,
+
1649  const std::vector< epiworld_double >& params_prev,
+
1650  LFMCMC<TData>* m
+
1651  ) {
+
1652 
+
1653  // Making the proposal
+
1654  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
+
1655  params_now[p] = params_prev[p] + m->rnorm() * scale;
+
1656 
+
1657  // Checking boundaries
+
1658  epiworld_double d = ub - lb;
+
1659  int odd;
+
1660  epiworld_double d_above, d_below;
+
1661  for (auto & p : params_now)
+
1662  {
+
1663 
+
1664  // Correcting if parameter goes above the upper bound
+
1665  if (p > ub)
+
1666  {
+
1667  d_above = p - ub;
+
1668  odd = static_cast<int>(std::floor(d_above / d)) % 2;
+
1669  d_above = d_above - std::floor(d_above / d) * d;
+
1670 
+
1671  p = (lb + d_above) * odd +
+
1672  (ub - d_above) * (1 - odd);
+
1673 
+
1674  // Correcting if parameter goes below upper bound
+
1675  } else if (p < lb)
+
1676  {
+
1677  d_below = lb - p;
+
1678  int odd = static_cast<int>(std::floor(d_below / d)) % 2;
+
1679  d_below = d_below - std::floor(d_below / d) * d;
+
1680 
+
1681  p = (ub - d_below) * odd +
+
1682  (lb + d_below) * (1 - odd);
+
1683  }
1684 
-
1685 
-
1686  return;
-
1687 
-
1688  };
-
1689 
-
1690  return fun;
-
1691 }
+
1685  }
+
1686 
+
1687  #ifdef EPI_DEBUG
+
1688  for (auto & p : params_now)
+
1689  if (p < lb || p > ub)
+
1690  throw std::range_error("The parameter is out of bounds.");
+
1691  #endif
1692 
-
1704 template<typename TData>
-
1705 inline void proposal_fun_unif(
-
1706  std::vector< epiworld_double >& params_now,
-
1707  const std::vector< epiworld_double >& params_prev,
-
1708  LFMCMC<TData>* m
-
1709 ) {
-
1710 
-
1711  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
-
1712  params_now[p] = (params_prev[p] + m->runif(-1.0, 1.0));
-
1713 
-
1714  return;
-
1715 }
-
1716 
-
1727 template<typename TData>
-
1728 inline epiworld_double kernel_fun_uniform(
-
1729  const std::vector< epiworld_double >& stats_now,
-
1730  const std::vector< epiworld_double >& stats_obs,
-
1731  epiworld_double epsilon,
-
1732  LFMCMC<TData>* m
-
1733 ) {
-
1734 
-
1735  epiworld_double ans = 0.0;
-
1736  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
-
1737  ans += std::pow(stats_obs[p] - stats_now[p], 2.0);
-
1738 
-
1739  return std::sqrt(ans) < epsilon ? 1.0 : 0.0;
-
1740 
-
1741 }
+
1693 
+
1694  return;
+
1695 
+
1696  };
+
1697 
+
1698  return fun;
+
1699 }
+
1700 
+
1712 template<typename TData>
+
1713 inline void proposal_fun_unif(
+
1714  std::vector< epiworld_double >& params_now,
+
1715  const std::vector< epiworld_double >& params_prev,
+
1716  LFMCMC<TData>* m
+
1717 ) {
+
1718 
+
1719  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
+
1720  params_now[p] = (params_prev[p] + m->runif(-1.0, 1.0));
+
1721 
+
1722  return;
+
1723 }
+
1724 
+
1735 template<typename TData>
+
1736 inline epiworld_double kernel_fun_uniform(
+
1737  const std::vector< epiworld_double >& stats_now,
+
1738  const std::vector< epiworld_double >& stats_obs,
+
1739  epiworld_double epsilon,
+
1740  LFMCMC<TData>* m
+
1741 ) {
1742 
-
1743 #define sqrt2pi() 2.5066282746310002416
-
1744 
-
1753 template<typename TData>
-
1754 inline epiworld_double kernel_fun_gaussian(
-
1755  const std::vector< epiworld_double >& stats_now,
-
1756  const std::vector< epiworld_double >& stats_obs,
-
1757  epiworld_double epsilon,
-
1758  LFMCMC<TData>* m
-
1759 ) {
-
1760 
-
1761  epiworld_double ans = 0.0;
-
1762  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
-
1763  ans += std::pow(stats_obs[p] - stats_now[p], 2.0);
-
1764 
-
1765  return std::exp(
-
1766  -.5 * (ans/std::pow(1 + std::pow(epsilon, 2.0)/3.0, 2.0))
-
1767  ) / sqrt2pi() ;
+
1743  epiworld_double ans = 0.0;
+
1744  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
+
1745  ans += std::pow(stats_obs[p] - stats_now[p], 2.0);
+
1746 
+
1747  return std::sqrt(ans) < epsilon ? 1.0 : 0.0;
+
1748 
+
1749 }
+
1750 
+
1751 #define sqrt2pi() 2.5066282746310002416
+
1752 
+
1761 template<typename TData>
+
1762 inline epiworld_double kernel_fun_gaussian(
+
1763  const std::vector< epiworld_double >& stats_now,
+
1764  const std::vector< epiworld_double >& stats_obs,
+
1765  epiworld_double epsilon,
+
1766  LFMCMC<TData>* m
+
1767 ) {
1768 
-
1769 }
-
1770 
-
1771 
-
1772 template<typename TData>
-
1773 inline void LFMCMC<TData>::set_proposal_fun(LFMCMCProposalFun<TData> fun)
-
1774 {
-
1775  proposal_fun = fun;
-
1776 }
-
1777 
-
1778 template<typename TData>
-
1779 inline void LFMCMC<TData>::set_simulation_fun(LFMCMCSimFun<TData> fun)
-
1780 {
-
1781  simulation_fun = fun;
-
1782 }
-
1783 
-
1784 template<typename TData>
-
1785 inline void LFMCMC<TData>::set_summary_fun(LFMCMCSummaryFun<TData> fun)
-
1786 {
-
1787  summary_fun = fun;
-
1788 }
-
1789 
-
1790 template<typename TData>
-
1791 inline void LFMCMC<TData>::set_kernel_fun(LFMCMCKernelFun<TData> fun)
-
1792 {
-
1793  kernel_fun = fun;
-
1794 }
-
1795 
-
1796 
-
1797 template<typename TData>
-
1798 inline void LFMCMC<TData>::run(
-
1799  std::vector< epiworld_double > params_init_,
-
1800  size_t n_samples_,
-
1801  epiworld_double epsilon_,
-
1802  int seed
-
1803  )
-
1804 {
-
1805 
-
1806  // Starting timing
-
1807  chrono_start();
-
1808 
-
1809  // Setting the baseline parameters of the model
-
1810  n_samples = n_samples_;
-
1811  epsilon = epsilon_;
-
1812  params_init = params_init_;
-
1813  n_parameters = params_init_.size();
-
1814 
-
1815  if (seed >= 0)
-
1816  this->seed(seed);
-
1817 
-
1818  params_now.resize(n_parameters);
-
1819  params_prev.resize(n_parameters);
-
1820 
-
1821  if (sampled_data != nullptr)
-
1822  sampled_data->resize(n_samples);
-
1823 
-
1824  params_prev = params_init;
-
1825  params_now = params_init;
-
1826 
-
1827  // Computing the baseline sufficient statistics
-
1828  summary_fun(observed_stats, observed_data, this);
-
1829  n_statistics = observed_stats.size();
-
1830 
-
1831  // Reserving size
-
1832  drawn_prob.resize(n_samples);
-
1833  sampled_accepted.resize(n_samples, false);
-
1834  sampled_stats.resize(n_samples * n_statistics);
-
1835  sampled_stats_prob.resize(n_samples);
-
1836 
-
1837  accepted_params.resize(n_samples * n_parameters);
-
1838  accepted_stats.resize(n_samples * n_statistics);
-
1839  accepted_params_prob.resize(n_samples);
-
1840 
-
1841  TData data_i = simulation_fun(params_init, this);
-
1842 
-
1843  std::vector< epiworld_double > proposed_stats_i;
-
1844  summary_fun(proposed_stats_i, data_i, this);
-
1845  accepted_params_prob[0u] = kernel_fun(proposed_stats_i, observed_stats, epsilon, this);
-
1846 
-
1847  // Recording statistics
-
1848  for (size_t i = 0u; i < n_statistics; ++i)
-
1849  sampled_stats[i] = proposed_stats_i[i];
+
1769  epiworld_double ans = 0.0;
+
1770  for (size_t p = 0u; p < m->get_n_parameters(); ++p)
+
1771  ans += std::pow(stats_obs[p] - stats_now[p], 2.0);
+
1772 
+
1773  return std::exp(
+
1774  -.5 * (ans/std::pow(1 + std::pow(epsilon, 2.0)/3.0, 2.0))
+
1775  ) / sqrt2pi() ;
+
1776 
+
1777 }
+
1778 
+
1779 
+
1780 template<typename TData>
+
1781 inline void LFMCMC<TData>::set_proposal_fun(LFMCMCProposalFun<TData> fun)
+
1782 {
+
1783  proposal_fun = fun;
+
1784 }
+
1785 
+
1786 template<typename TData>
+
1787 inline void LFMCMC<TData>::set_simulation_fun(LFMCMCSimFun<TData> fun)
+
1788 {
+
1789  simulation_fun = fun;
+
1790 }
+
1791 
+
1792 template<typename TData>
+
1793 inline void LFMCMC<TData>::set_summary_fun(LFMCMCSummaryFun<TData> fun)
+
1794 {
+
1795  summary_fun = fun;
+
1796 }
+
1797 
+
1798 template<typename TData>
+
1799 inline void LFMCMC<TData>::set_kernel_fun(LFMCMCKernelFun<TData> fun)
+
1800 {
+
1801  kernel_fun = fun;
+
1802 }
+
1803 
+
1804 
+
1805 template<typename TData>
+
1806 inline void LFMCMC<TData>::run(
+
1807  std::vector< epiworld_double > params_init_,
+
1808  size_t n_samples_,
+
1809  epiworld_double epsilon_,
+
1810  int seed
+
1811  )
+
1812 {
+
1813 
+
1814  // Starting timing
+
1815  chrono_start();
+
1816 
+
1817  // Setting the baseline parameters of the model
+
1818  n_samples = n_samples_;
+
1819  epsilon = epsilon_;
+
1820  params_init = params_init_;
+
1821  n_parameters = params_init_.size();
+
1822 
+
1823  if (seed >= 0)
+
1824  this->seed(seed);
+
1825 
+
1826  params_now.resize(n_parameters);
+
1827  params_prev.resize(n_parameters);
+
1828 
+
1829  if (sampled_data != nullptr)
+
1830  sampled_data->resize(n_samples);
+
1831 
+
1832  params_prev = params_init;
+
1833  params_now = params_init;
+
1834 
+
1835  // Computing the baseline sufficient statistics
+
1836  summary_fun(observed_stats, observed_data, this);
+
1837  n_statistics = observed_stats.size();
+
1838 
+
1839  // Reserving size
+
1840  drawn_prob.resize(n_samples);
+
1841  sampled_accepted.resize(n_samples, false);
+
1842  sampled_stats.resize(n_samples * n_statistics);
+
1843  sampled_stats_prob.resize(n_samples);
+
1844 
+
1845  accepted_params.resize(n_samples * n_parameters);
+
1846  accepted_stats.resize(n_samples * n_statistics);
+
1847  accepted_params_prob.resize(n_samples);
+
1848 
+
1849  TData data_i = simulation_fun(params_init, this);
1850 
-
1851  for (size_t k = 0u; k < n_statistics; ++k)
-
1852  accepted_params[k] = proposed_stats_i[k];
-
1853 
-
1854  for (size_t i = 1u; i < n_samples; ++i)
-
1855  {
-
1856  // Step 1: Generate a proposal and store it in params_now
-
1857  proposal_fun(params_now, params_prev, this);
-
1858 
-
1859  // Step 2: Using params_now, simulate data
-
1860  TData data_i = simulation_fun(params_now, this);
-
1861 
-
1862  // Are we storing the data?
-
1863  if (sampled_data != nullptr)
-
1864  sampled_data->operator[](i) = data_i;
-
1865 
-
1866  // Step 3: Generate the summary statistics of the data
-
1867  summary_fun(proposed_stats_i, data_i, this);
+
1851  std::vector< epiworld_double > proposed_stats_i;
+
1852  summary_fun(proposed_stats_i, data_i, this);
+
1853  accepted_params_prob[0u] = kernel_fun(
+
1854  proposed_stats_i, observed_stats, epsilon, this
+
1855  );
+
1856 
+
1857  // Recording statistics
+
1858  for (size_t i = 0u; i < n_statistics; ++i)
+
1859  sampled_stats[i] = proposed_stats_i[i];
+
1860 
+
1861  for (size_t k = 0u; k < n_parameters; ++k)
+
1862  accepted_params[k] = params_init[k];
+
1863 
+
1864  for (size_t i = 1u; i < n_samples; ++i)
+
1865  {
+
1866  // Step 1: Generate a proposal and store it in params_now
+
1867  proposal_fun(params_now, params_prev, this);
1868 
-
1869  // Step 4: Compute the hastings ratio using the kernel function
-
1870  epiworld_double hr = kernel_fun(proposed_stats_i, observed_stats, epsilon, this);
-
1871  sampled_stats_prob[i] = hr;
-
1872 
-
1873  // Storing data
-
1874  for (size_t k = 0u; k < n_statistics; ++k)
-
1875  sampled_stats[i * n_statistics + k] = proposed_stats_i[k];
-
1876 
-
1877  // Running Hastings ratio
-
1878  epiworld_double r = runif();
-
1879  drawn_prob[i] = r;
-
1880 
-
1881  // Step 5: Update if likely
-
1882  if (r < std::min(static_cast<epiworld_double>(1.0), hr / accepted_params_prob[i - 1u]))
-
1883  {
-
1884  accepted_params_prob[i] = hr;
-
1885  sampled_accepted[i] = true;
-
1886 
-
1887  for (size_t k = 0u; k < n_statistics; ++k)
-
1888  accepted_stats[i * n_statistics + k] =
-
1889  proposed_stats_i[k];
-
1890 
-
1891  params_prev = params_now;
-
1892 
-
1893  } else
-
1894  {
-
1895 
-
1896  for (size_t k = 0u; k < n_statistics; ++k)
-
1897  accepted_stats[i * n_statistics + k] =
-
1898  accepted_stats[(i - 1) * n_statistics + k];
-
1899 
-
1900  accepted_params_prob[i] = accepted_params_prob[i - 1u];
-
1901  }
-
1902 
+
1869  // Step 2: Using params_now, simulate data
+
1870  TData data_i = simulation_fun(params_now, this);
+
1871 
+
1872  // Are we storing the data?
+
1873  if (sampled_data != nullptr)
+
1874  sampled_data->operator[](i) = data_i;
+
1875 
+
1876  // Step 3: Generate the summary statistics of the data
+
1877  summary_fun(proposed_stats_i, data_i, this);
+
1878 
+
1879  // Step 4: Compute the hastings ratio using the kernel function
+
1880  epiworld_double hr = kernel_fun(
+
1881  proposed_stats_i, observed_stats, epsilon, this
+
1882  );
+
1883 
+
1884  sampled_stats_prob[i] = hr;
+
1885 
+
1886  // Storing data
+
1887  for (size_t k = 0u; k < n_statistics; ++k)
+
1888  sampled_stats[i * n_statistics + k] = proposed_stats_i[k];
+
1889 
+
1890  // Running Hastings ratio
+
1891  epiworld_double r = runif();
+
1892  drawn_prob[i] = r;
+
1893 
+
1894  // Step 5: Update if likely
+
1895  if (r < std::min(static_cast<epiworld_double>(1.0), hr / accepted_params_prob[i - 1u]))
+
1896  {
+
1897  accepted_params_prob[i] = hr;
+
1898  sampled_accepted[i] = true;
+
1899 
+
1900  for (size_t k = 0u; k < n_statistics; ++k)
+
1901  accepted_stats[i * n_statistics + k] =
+
1902  proposed_stats_i[k];
1903 
-
1904  for (size_t k = 0u; k < n_parameters; ++k)
-
1905  accepted_params[i * n_parameters + k] = params_prev[k];
-
1906 
-
1907  }
+
1904  params_prev = params_now;
+
1905 
+
1906  } else
+
1907  {
1908 
-
1909  // End timing
-
1910  chrono_end();
-
1911 
-
1912 }
-
1913 
-
1914 
-
1915 template<typename TData>
-
1916 inline epiworld_double LFMCMC<TData>::runif()
-
1917 {
-
1918  return runifd->operator()(*engine);
-
1919 }
-
1920 
-
1921 template<typename TData>
-
1922 inline epiworld_double LFMCMC<TData>::runif(
-
1923  epiworld_double lb,
-
1924  epiworld_double ub
-
1925 )
-
1926 {
-
1927  return runifd->operator()(*engine) * (ub - lb) + lb;
-
1928 }
-
1929 
-
1930 template<typename TData>
-
1931 inline epiworld_double LFMCMC<TData>::rnorm()
-
1932 {
-
1933  return rnormd->operator()(*engine);
-
1934 }
-
1935 
-
1936 template<typename TData>
-
1937 inline epiworld_double LFMCMC<TData>::rnorm(
-
1938  epiworld_double mean,
-
1939  epiworld_double sd
-
1940  )
-
1941 {
-
1942  return (rnormd->operator()(*engine)) * sd + mean;
-
1943 }
-
1944 
-
1945 template<typename TData>
-
1946 inline epiworld_double LFMCMC<TData>::rgamma()
-
1947 {
-
1948  return rgammad->operator()(*engine);
-
1949 }
-
1950 
-
1951 template<typename TData>
-
1952 inline epiworld_double LFMCMC<TData>::rgamma(
-
1953  epiworld_double alpha,
-
1954  epiworld_double beta
-
1955  )
-
1956 {
+
1909  for (size_t k = 0u; k < n_statistics; ++k)
+
1910  accepted_stats[i * n_statistics + k] =
+
1911  accepted_stats[(i - 1) * n_statistics + k];
+
1912 
+
1913  accepted_params_prob[i] = accepted_params_prob[i - 1u];
+
1914  }
+
1915 
+
1916 
+
1917  for (size_t k = 0u; k < n_parameters; ++k)
+
1918  accepted_params[i * n_parameters + k] = params_prev[k];
+
1919 
+
1920  }
+
1921 
+
1922  // End timing
+
1923  chrono_end();
+
1924 
+
1925 }
+
1926 
+
1927 
+
1928 template<typename TData>
+
1929 inline epiworld_double LFMCMC<TData>::runif()
+
1930 {
+
1931  return runifd->operator()(*engine);
+
1932 }
+
1933 
+
1934 template<typename TData>
+
1935 inline epiworld_double LFMCMC<TData>::runif(
+
1936  epiworld_double lb,
+
1937  epiworld_double ub
+
1938 )
+
1939 {
+
1940  return runifd->operator()(*engine) * (ub - lb) + lb;
+
1941 }
+
1942 
+
1943 template<typename TData>
+
1944 inline epiworld_double LFMCMC<TData>::rnorm()
+
1945 {
+
1946  return rnormd->operator()(*engine);
+
1947 }
+
1948 
+
1949 template<typename TData>
+
1950 inline epiworld_double LFMCMC<TData>::rnorm(
+
1951  epiworld_double mean,
+
1952  epiworld_double sd
+
1953  )
+
1954 {
+
1955  return (rnormd->operator()(*engine)) * sd + mean;
+
1956 }
1957 
-
1958  auto old_param = rgammad->param();
-
1959 
-
1960  rgammad->param(std::gamma_distribution<>::param_type(alpha, beta));
-
1961 
-
1962  epiworld_double ans = rgammad->operator()(*engine);
+
1958 template<typename TData>
+
1959 inline epiworld_double LFMCMC<TData>::rgamma()
+
1960 {
+
1961  return rgammad->operator()(*engine);
+
1962 }
1963 
-
1964  rgammad->param(old_param);
-
1965 
-
1966  return ans;
-
1967 
-
1968 }
-
1969 
-
1970 template<typename TData>
-
1971 inline void LFMCMC<TData>::seed(epiworld_fast_uint s) {
+
1964 template<typename TData>
+
1965 inline epiworld_double LFMCMC<TData>::rgamma(
+
1966  epiworld_double alpha,
+
1967  epiworld_double beta
+
1968  )
+
1969 {
+
1970 
+
1971  auto old_param = rgammad->param();
1972 
-
1973  this->engine->seed(s);
+
1973  rgammad->param(std::gamma_distribution<>::param_type(alpha, beta));
1974 
-
1975 }
+
1975  epiworld_double ans = rgammad->operator()(*engine);
1976 
-
1977 template<typename TData>
-
1978 inline void LFMCMC<TData>::set_rand_engine(std::shared_ptr< std::mt19937 > & eng)
-
1979 {
-
1980  engine = eng;
+
1977  rgammad->param(old_param);
+
1978 
+
1979  return ans;
+
1980 
1981 }
1982 
1983 template<typename TData>
-
1984 inline void LFMCMC<TData>::set_rand_gamma(epiworld_double alpha, epiworld_double beta)
-
1985 {
-
1986  rgammad = std::make_shared<std::gamma_distribution<>>(alpha,beta);
-
1987 }
-
1988 
-
1989 template<typename TData>
-
1990 inline std::shared_ptr< std::mt19937 > & LFMCMC<TData>::get_rand_endgine()
-
1991 {
-
1992  return engine;
-
1993 }
-
1994 
-
1995 // Step 1: Simulate data
-
1996 
-
1997 // Step 2: Compute the sufficient statistics
-
1998 
-
1999 // Step 3: Compute the hastings-ratio
-
2000 
-
2001 // Step 4: Accept/reject, and go back to step 1
-
2002 
-
2003 #define DURCAST(tunit,txtunit) {\
-
2004  elapsed = std::chrono::duration_cast<std::chrono:: tunit>(\
-
2005  time_end - time_start).count(); \
-
2006  abbr_unit = txtunit;}
+
1984 inline void LFMCMC<TData>::seed(epiworld_fast_uint s) {
+
1985 
+
1986  this->engine->seed(s);
+
1987 
+
1988 }
+
1989 
+
1990 template<typename TData>
+
1991 inline void LFMCMC<TData>::set_rand_engine(std::shared_ptr< std::mt19937 > & eng)
+
1992 {
+
1993  engine = eng;
+
1994 }
+
1995 
+
1996 template<typename TData>
+
1997 inline void LFMCMC<TData>::set_rand_gamma(epiworld_double alpha, epiworld_double beta)
+
1998 {
+
1999  rgammad = std::make_shared<std::gamma_distribution<>>(alpha,beta);
+
2000 }
+
2001 
+
2002 template<typename TData>
+
2003 inline std::shared_ptr< std::mt19937 > & LFMCMC<TData>::get_rand_endgine()
+
2004 {
+
2005  return engine;
+
2006 }
2007 
-
2008 template<typename TData>
-
2009 inline void LFMCMC<TData>::get_elapsed(
-
2010  std::string unit,
-
2011  epiworld_double * last_elapsed,
-
2012  std::string * unit_abbr,
-
2013  bool print
-
2014 ) {
+
2008 // Step 1: Simulate data
+
2009 
+
2010 // Step 2: Compute the sufficient statistics
+
2011 
+
2012 // Step 3: Compute the hastings-ratio
+
2013 
+
2014 // Step 4: Accept/reject, and go back to step 1
2015 
-
2016  // Preparing the result
-
2017  epiworld_double elapsed;
-
2018  std::string abbr_unit;
-
2019 
-
2020  // Figuring out the length
-
2021  if (unit == "auto")
-
2022  {
-
2023 
-
2024  size_t tlength = std::to_string(
-
2025  static_cast<int>(floor(time_elapsed.count()))
-
2026  ).length();
-
2027 
-
2028  if (tlength <= 1)
-
2029  unit = "nanoseconds";
-
2030  else if (tlength <= 3)
-
2031  unit = "microseconds";
-
2032  else if (tlength <= 6)
-
2033  unit = "milliseconds";
-
2034  else if (tlength <= 8)
-
2035  unit = "seconds";
-
2036  else if (tlength <= 9)
-
2037  unit = "minutes";
-
2038  else
-
2039  unit = "hours";
-
2040 
-
2041  }
-
2042 
-
2043  if (unit == "nanoseconds") DURCAST(nanoseconds,"ns")
-
2044  else if (unit == "microseconds") DURCAST(microseconds,"\xC2\xB5s")
-
2045  else if (unit == "milliseconds") DURCAST(milliseconds,"ms")
-
2046  else if (unit == "seconds") DURCAST(seconds,"s")
-
2047  else if (unit == "minutes") DURCAST(minutes,"m")
-
2048  else if (unit == "hours") DURCAST(hours,"h")
-
2049  else
-
2050  throw std::range_error("The time unit " + unit + " is not supported.");
-
2051 
-
2052 
-
2053  if (last_elapsed != nullptr)
-
2054  *last_elapsed = elapsed;
-
2055  if (unit_abbr != nullptr)
-
2056  *unit_abbr = abbr_unit;
-
2057 
-
2058  if (!print)
-
2059  return;
-
2060 
-
2061  printf_epiworld("Elapsed time : %.2f%s.\n", elapsed, abbr_unit.c_str());
-
2062 }
-
2063 
-
2064 #undef DURCAST
+
2016 #define DURCAST(tunit,txtunit) {\
+
2017  elapsed = std::chrono::duration_cast<std::chrono:: tunit>(\
+
2018  time_end - time_start).count(); \
+
2019  abbr_unit = txtunit;}
+
2020 
+
2021 template<typename TData>
+
2022 inline void LFMCMC<TData>::get_elapsed(
+
2023  std::string unit,
+
2024  epiworld_double * last_elapsed,
+
2025  std::string * unit_abbr,
+
2026  bool print
+
2027 ) const {
+
2028 
+
2029  // Preparing the result
+
2030  epiworld_double elapsed;
+
2031  std::string abbr_unit;
+
2032 
+
2033  // Figuring out the length
+
2034  if (unit == "auto")
+
2035  {
+
2036 
+
2037  size_t tlength = std::to_string(
+
2038  static_cast<int>(floor(time_elapsed.count()))
+
2039  ).length();
+
2040 
+
2041  if (tlength <= 1)
+
2042  unit = "nanoseconds";
+
2043  else if (tlength <= 3)
+
2044  unit = "microseconds";
+
2045  else if (tlength <= 6)
+
2046  unit = "milliseconds";
+
2047  else if (tlength <= 8)
+
2048  unit = "seconds";
+
2049  else if (tlength <= 9)
+
2050  unit = "minutes";
+
2051  else
+
2052  unit = "hours";
+
2053 
+
2054  }
+
2055 
+
2056  if (unit == "nanoseconds") DURCAST(nanoseconds,"ns")
+
2057  else if (unit == "microseconds") DURCAST(microseconds,"\xC2\xB5s")
+
2058  else if (unit == "milliseconds") DURCAST(milliseconds,"ms")
+
2059  else if (unit == "seconds") DURCAST(seconds,"s")
+
2060  else if (unit == "minutes") DURCAST(minutes,"m")
+
2061  else if (unit == "hours") DURCAST(hours,"h")
+
2062  else
+
2063  throw std::range_error("The time unit " + unit + " is not supported.");
+
2064 
2065 
-
2066 /*//////////////////////////////////////////////////////////////////////////////
-
2068 
-
2069  Start of -include/epiworld//math//lfmcmc/lfmcmc-meat-print.hpp-
+
2066  if (last_elapsed != nullptr)
+
2067  *last_elapsed = elapsed;
+
2068  if (unit_abbr != nullptr)
+
2069  *unit_abbr = abbr_unit;
2070 
+
2071  if (!print)
+
2072  return;
2073 
-
2074 
-
2075 #ifndef LFMCMC_MEAT_PRINT_HPP
-
2076 #define LFMCMC_MEAT_PRINT_HPP
-
2077 
-
2078 template<typename TData>
-
2079 inline void LFMCMC<TData>::print()
-
2080 {
-
2081  std::vector< epiworld_double > summ_params(n_parameters * 3, 0.0);
-
2082  std::vector< epiworld_double > summ_stats(n_statistics * 3, 0.0);
+
2074  printf_epiworld("Elapsed time : %.2f%s.\n", elapsed, abbr_unit.c_str());
+
2075 }
+
2076 
+
2077 #undef DURCAST
+
2078 
+
2079 /*//////////////////////////////////////////////////////////////////////////////
+
2081 
+
2082  Start of -include/epiworld//math//lfmcmc/lfmcmc-meat-print.hpp-
2083 
-
2084  for (size_t k = 0u; k < n_parameters; ++k)
-
2085  {
2086 
-
2087  // Retrieving the relevant parameter
-
2088  std::vector< epiworld_double > par_i(n_samples);
-
2089  for (size_t i = 0u; i < n_samples; ++i)
-
2090  {
-
2091  par_i[i] = accepted_params[i * n_parameters + k];
-
2092  summ_params[k * 3] += par_i[i]/n_samples;
-
2093  }
+
2087 
+
2088 #ifndef LFMCMC_MEAT_PRINT_HPP
+
2089 #define LFMCMC_MEAT_PRINT_HPP
+
2090 
+
2091 template<typename TData>
+
2092 inline void LFMCMC<TData>::print(size_t burnin) const
+
2093 {
2094 
-
2095  // Computing the 95% Credible interval
-
2096  std::sort(par_i.begin(), par_i.end());
+
2095  std::vector< epiworld_double > summ_params(n_parameters * 3, 0.0);
+
2096  std::vector< epiworld_double > summ_stats(n_statistics * 3, 0.0);
2097 
-
2098  summ_params[k * 3 + 1u] =
-
2099  par_i[std::floor(.025 * static_cast<epiworld_double>(n_samples))];
-
2100  summ_params[k * 3 + 2u] =
-
2101  par_i[std::floor(.975 * static_cast<epiworld_double>(n_samples))];
-
2102 
-
2103  }
-
2104 
-
2105  for (size_t k = 0u; k < n_statistics; ++k)
-
2106  {
+
2098  size_t n_samples_print = n_samples;
+
2099  if (burnin > 0)
+
2100  {
+
2101  if (burnin >= n_samples)
+
2102  throw std::length_error(
+
2103  "The burnin is greater than the number of samples."
+
2104  );
+
2105 
+
2106  n_samples_print = n_samples - burnin;
2107 
-
2108  // Retrieving the relevant parameter
-
2109  std::vector< epiworld_double > stat_k(n_samples);
-
2110  for (size_t i = 0u; i < n_samples; ++i)
-
2111  {
-
2112  stat_k[i] = accepted_stats[i * n_statistics + k];
-
2113  summ_stats[k * 3] += stat_k[i]/n_samples;
-
2114  }
-
2115 
-
2116  // Computing the 95% Credible interval
-
2117  std::sort(stat_k.begin(), stat_k.end());
-
2118 
-
2119  summ_stats[k * 3 + 1u] =
-
2120  stat_k[std::floor(.025 * static_cast<epiworld_double>(n_samples))];
-
2121  summ_stats[k * 3 + 2u] =
-
2122  stat_k[std::floor(.975 * static_cast<epiworld_double>(n_samples))];
-
2123 
-
2124  }
-
2125 
-
2126  printf_epiworld("___________________________________________\n\n");
-
2127  printf_epiworld("LIKELIHOOD-FREE MARKOV CHAIN MONTE CARLO\n\n");
-
2128 
-
2129  printf_epiworld("N Samples : %zu\n", n_samples);
-
2130 
-
2131  std::string abbr;
-
2132  epiworld_double elapsed;
-
2133  get_elapsed("auto", &elapsed, &abbr, false);
-
2134  printf_epiworld("Elapsed t : %.2f%s\n\n", elapsed, abbr.c_str());
-
2135 
-
2137  // PARAMETERS
-
2139  printf_epiworld("Parameters:\n");
-
2140 
-
2141  // Figuring out format
-
2142  std::string fmt_params;
-
2143 
-
2144  int nchar_par_num = 0;
-
2145  for (auto & n : summ_params)
-
2146  {
-
2147 
-
2148  int tmp_nchar = std::floor(std::log10(std::abs(n)));
-
2149  if (nchar_par_num < tmp_nchar)
-
2150  nchar_par_num = tmp_nchar;
-
2151  }
-
2152  nchar_par_num += 5; // 1 for neg padd, 2 for decimals, 1 the decimal point, and one b/c log(<10) < 1.
-
2153  std::string charlen = std::to_string(nchar_par_num);
-
2154 
-
2155  if (names_parameters.size() != 0u)
-
2156  {
-
2157  int nchar_par = 0;
-
2158  for (auto & n : names_parameters)
-
2159  {
-
2160  int tmp_nchar = n.length();
-
2161  if (nchar_par < tmp_nchar)
-
2162  nchar_par = tmp_nchar;
-
2163  }
-
2164 
-
2165  fmt_params = std::string(" -%-") +
-
2166  std::to_string(nchar_par) +
-
2167  std::string("s : % ") + charlen +
-
2168  std::string(".2f [% ") + charlen +
-
2169  std::string(".2f, % ") + charlen +
-
2170  std::string(".2f] (initial : % ") +
-
2171  charlen + std::string(".2f)\n");
-
2172 
-
2173  for (size_t k = 0u; k < n_parameters; ++k)
-
2174  {
-
2175  printf_epiworld(
-
2176  fmt_params.c_str(),
-
2177  names_parameters[k].c_str(),
-
2178  summ_params[k * 3],
-
2179  summ_params[k * 3 + 1u],
-
2180  summ_params[k * 3 + 2u],
-
2181  params_init[k]
-
2182  );
-
2183  }
+
2108  }
+
2109 
+
2110  epiworld_double n_samples_dbl = static_cast< epiworld_double >(
+
2111  n_samples_print
+
2112  );
+
2113 
+
2114  for (size_t k = 0u; k < n_parameters; ++k)
+
2115  {
+
2116 
+
2117  // Retrieving the relevant parameter
+
2118  std::vector< epiworld_double > par_i(n_samples_print);
+
2119  for (size_t i = burnin; i < n_samples; ++i)
+
2120  {
+
2121  par_i[i] = accepted_params[i * n_parameters + k];
+
2122  summ_params[k * 3] += par_i[i]/n_samples_dbl;
+
2123  }
+
2124 
+
2125  // Computing the 95% Credible interval
+
2126  std::sort(par_i.begin(), par_i.end());
+
2127 
+
2128  summ_params[k * 3 + 1u] =
+
2129  par_i[std::floor(.025 * n_samples_dbl)];
+
2130  summ_params[k * 3 + 2u] =
+
2131  par_i[std::floor(.975 * n_samples_dbl)];
+
2132 
+
2133  }
+
2134 
+
2135  for (size_t k = 0u; k < n_statistics; ++k)
+
2136  {
+
2137 
+
2138  // Retrieving the relevant parameter
+
2139  std::vector< epiworld_double > stat_k(n_samples_print);
+
2140  for (size_t i = burnin; i < n_samples; ++i)
+
2141  {
+
2142  stat_k[i] = accepted_stats[i * n_statistics + k];
+
2143  summ_stats[k * 3] += stat_k[i]/n_samples_dbl;
+
2144  }
+
2145 
+
2146  // Computing the 95% Credible interval
+
2147  std::sort(stat_k.begin(), stat_k.end());
+
2148 
+
2149  summ_stats[k * 3 + 1u] =
+
2150  stat_k[std::floor(.025 * n_samples_dbl)];
+
2151  summ_stats[k * 3 + 2u] =
+
2152  stat_k[std::floor(.975 * n_samples_dbl)];
+
2153 
+
2154  }
+
2155 
+
2156  printf_epiworld("___________________________________________\n\n");
+
2157  printf_epiworld("LIKELIHOOD-FREE MARKOV CHAIN MONTE CARLO\n\n");
+
2158 
+
2159  printf_epiworld("N Samples : %zu\n", n_samples);
+
2160 
+
2161  std::string abbr;
+
2162  epiworld_double elapsed;
+
2163  get_elapsed("auto", &elapsed, &abbr, false);
+
2164  printf_epiworld("Elapsed t : %.2f%s\n\n", elapsed, abbr.c_str());
+
2165 
+
2167  // PARAMETERS
+
2169  printf_epiworld("Parameters:\n");
+
2170 
+
2171  // Figuring out format
+
2172  std::string fmt_params;
+
2173 
+
2174  int nchar_par_num = 0;
+
2175  for (auto & n : summ_params)
+
2176  {
+
2177 
+
2178  int tmp_nchar = std::floor(std::log10(std::abs(n)));
+
2179  if (nchar_par_num < tmp_nchar)
+
2180  nchar_par_num = tmp_nchar;
+
2181  }
+
2182  nchar_par_num += 5; // 1 for neg padd, 2 for decimals, 1 the decimal point, and one b/c log(<10) < 1.
+
2183  std::string charlen = std::to_string(nchar_par_num);
2184 
-
2185 
-
2186  } else {
-
2187 
-
2188  fmt_params = std::string(" [%-2ld]: % ") + charlen +
-
2189  std::string(".2f [% ") + charlen +
-
2190  std::string(".2f, % ") + charlen +
-
2191  std::string(".2f] (initial : % ") + charlen +
-
2192  std::string(".2f)\n");
-
2193 
-
2194  for (size_t k = 0u; k < n_parameters; ++k)
-
2195  {
-
2196 
-
2197  printf_epiworld(
-
2198  fmt_params.c_str(),
-
2199  k,
-
2200  summ_params[k * 3],
-
2201  summ_params[k * 3 + 1u],
-
2202  summ_params[k * 3 + 2u],
-
2203  params_init[k]
-
2204  );
-
2205  }
-
2206 
-
2207  }
-
2208 
-
2210  // Statistics
-
2212  printf_epiworld("\nStatistics:\n");
-
2213  int nchar = 0;
-
2214  for (auto & s : summ_stats)
-
2215  {
-
2216  int tmp_nchar = std::floor(std::log10(std::abs(s)));
-
2217  if (nchar < tmp_nchar)
-
2218  nchar = tmp_nchar;
-
2219  }
-
2220 
-
2221  nchar += 5; // See above
-
2222 
-
2223  std::string nchar_char = std::to_string(nchar);
-
2224 
-
2225  // Figuring out format
-
2226  std::string fmt_stats;
-
2227  if (names_statistics.size() != 0u)
-
2228  {
-
2229  int nchar_stats = 0;
-
2230  for (auto & n : names_statistics)
-
2231  {
-
2232  int tmp_nchar = n.length();
-
2233  if (nchar_stats < tmp_nchar)
-
2234  nchar_stats = tmp_nchar;
+
2185  if (names_parameters.size() != 0u)
+
2186  {
+
2187  int nchar_par = 0;
+
2188  for (auto & n : names_parameters)
+
2189  {
+
2190  int tmp_nchar = n.length();
+
2191  if (nchar_par < tmp_nchar)
+
2192  nchar_par = tmp_nchar;
+
2193  }
+
2194 
+
2195  fmt_params = std::string(" -%-") +
+
2196  std::to_string(nchar_par) +
+
2197  std::string("s : % ") + charlen +
+
2198  std::string(".2f [% ") + charlen +
+
2199  std::string(".2f, % ") + charlen +
+
2200  std::string(".2f] (initial : % ") +
+
2201  charlen + std::string(".2f)\n");
+
2202 
+
2203  for (size_t k = 0u; k < n_parameters; ++k)
+
2204  {
+
2205  printf_epiworld(
+
2206  fmt_params.c_str(),
+
2207  names_parameters[k].c_str(),
+
2208  summ_params[k * 3],
+
2209  summ_params[k * 3 + 1u],
+
2210  summ_params[k * 3 + 2u],
+
2211  params_init[k]
+
2212  );
+
2213  }
+
2214 
+
2215 
+
2216  } else {
+
2217 
+
2218  fmt_params = std::string(" [%-2ld]: % ") + charlen +
+
2219  std::string(".2f [% ") + charlen +
+
2220  std::string(".2f, % ") + charlen +
+
2221  std::string(".2f] (initial : % ") + charlen +
+
2222  std::string(".2f)\n");
+
2223 
+
2224  for (size_t k = 0u; k < n_parameters; ++k)
+
2225  {
+
2226 
+
2227  printf_epiworld(
+
2228  fmt_params.c_str(),
+
2229  k,
+
2230  summ_params[k * 3],
+
2231  summ_params[k * 3 + 1u],
+
2232  summ_params[k * 3 + 2u],
+
2233  params_init[k]
+
2234  );
2235  }
2236 
-
2237  fmt_stats = std::string(" -%-") +
-
2238  std::to_string(nchar_stats) +
-
2239  std::string("s : % ") + nchar_char +
-
2240  std::string(".2f [% ") + nchar_char +
-
2241  std::string(".2f, % ") + nchar_char +
-
2242  std::string(".2f] (Observed: % ") + nchar_char +
-
2243  std::string(".2f)\n");
-
2244 
-
2245  for (size_t k = 0u; k < n_statistics; ++k)
-
2246  {
-
2247  printf_epiworld(
-
2248  fmt_stats.c_str(),
-
2249  names_statistics[k].c_str(),
-
2250  summ_stats[k * 3],
-
2251  summ_stats[k * 3 + 1u],
-
2252  summ_stats[k * 3 + 2u],
-
2253  observed_stats[k]
-
2254  );
-
2255  }
-
2256 
-
2257 
-
2258  } else {
-
2259 
-
2260  fmt_stats = std::string(" [%-2ld] : % ") +
-
2261  nchar_char +
-
2262  std::string(".2f [% ") + nchar_char +
-
2263  std::string(".2f, % ") + nchar_char +
-
2264  std::string(".2f] (Observed: % ") + nchar_char +
-
2265  std::string(".2f)\n");
+
2237  }
+
2238 
+
2240  // Statistics
+
2242  printf_epiworld("\nStatistics:\n");
+
2243  int nchar = 0;
+
2244  for (auto & s : summ_stats)
+
2245  {
+
2246  int tmp_nchar = std::floor(std::log10(std::abs(s)));
+
2247  if (nchar < tmp_nchar)
+
2248  nchar = tmp_nchar;
+
2249  }
+
2250 
+
2251  nchar += 5; // See above
+
2252 
+
2253  std::string nchar_char = std::to_string(nchar);
+
2254 
+
2255  // Figuring out format
+
2256  std::string fmt_stats;
+
2257  if (names_statistics.size() != 0u)
+
2258  {
+
2259  int nchar_stats = 0;
+
2260  for (auto & n : names_statistics)
+
2261  {
+
2262  int tmp_nchar = n.length();
+
2263  if (nchar_stats < tmp_nchar)
+
2264  nchar_stats = tmp_nchar;
+
2265  }
2266 
-
2267  for (size_t k = 0u; k < n_statistics; ++k)
-
2268  {
-
2269  printf_epiworld(
-
2270  fmt_stats.c_str(),
-
2271  k,
-
2272  summ_stats[k * 3],
-
2273  summ_stats[k * 3 + 1u],
-
2274  summ_stats[k * 3 + 2u],
-
2275  observed_stats[k]
-
2276  );
-
2277  }
-
2278 
-
2279  }
-
2280 
-
2281  printf_epiworld("___________________________________________\n\n");
-
2282 }
-
2283 
-
2284 #endif
-
2285 /*//////////////////////////////////////////////////////////////////////////////
-
2287 
-
2288  End of -include/epiworld//math//lfmcmc/lfmcmc-meat-print.hpp-
+
2267  fmt_stats = std::string(" -%-") +
+
2268  std::to_string(nchar_stats) +
+
2269  std::string("s : % ") + nchar_char +
+
2270  std::string(".2f [% ") + nchar_char +
+
2271  std::string(".2f, % ") + nchar_char +
+
2272  std::string(".2f] (Observed: % ") + nchar_char +
+
2273  std::string(".2f)\n");
+
2274 
+
2275  for (size_t k = 0u; k < n_statistics; ++k)
+
2276  {
+
2277  printf_epiworld(
+
2278  fmt_stats.c_str(),
+
2279  names_statistics[k].c_str(),
+
2280  summ_stats[k * 3],
+
2281  summ_stats[k * 3 + 1u],
+
2282  summ_stats[k * 3 + 2u],
+
2283  observed_stats[k]
+
2284  );
+
2285  }
+
2286 
+
2287 
+
2288  } else {
2289 
-
2292 
-
2293 
-
2294 
-
2295 template<typename TData>
-
2296 inline void LFMCMC<TData>::chrono_start() {
-
2297  time_start = std::chrono::steady_clock::now();
-
2298 }
-
2299 
-
2300 template<typename TData>
-
2301 inline void LFMCMC<TData>::chrono_end() {
-
2302  time_end = std::chrono::steady_clock::now();
-
2303  time_elapsed += (time_end - time_start);
-
2304 }
-
2305 
-
2306 template<typename TData>
-
2307 inline void LFMCMC<TData>::set_par_names(std::vector< std::string > names)
-
2308 {
-
2309 
-
2310  if (names.size() != n_parameters)
-
2311  throw std::length_error("The number of names to add differs from the number of parameters in the model.");
-
2312 
-
2313  names_parameters = names;
-
2314 
-
2315 }
-
2316 template<typename TData>
-
2317 inline void LFMCMC<TData>::set_stats_names(std::vector< std::string > names)
-
2318 {
+
2290  fmt_stats = std::string(" [%-2ld] : % ") +
+
2291  nchar_char +
+
2292  std::string(".2f [% ") + nchar_char +
+
2293  std::string(".2f, % ") + nchar_char +
+
2294  std::string(".2f] (Observed: % ") + nchar_char +
+
2295  std::string(".2f)\n");
+
2296 
+
2297  for (size_t k = 0u; k < n_statistics; ++k)
+
2298  {
+
2299  printf_epiworld(
+
2300  fmt_stats.c_str(),
+
2301  k,
+
2302  summ_stats[k * 3],
+
2303  summ_stats[k * 3 + 1u],
+
2304  summ_stats[k * 3 + 2u],
+
2305  observed_stats[k]
+
2306  );
+
2307  }
+
2308 
+
2309  }
+
2310 
+
2311  printf_epiworld("___________________________________________\n\n");
+
2312 }
+
2313 
+
2314 #endif
+
2315 /*//////////////////////////////////////////////////////////////////////////////
+
2317 
+
2318  End of -include/epiworld//math//lfmcmc/lfmcmc-meat-print.hpp-
2319 
-
2320  if (names.size() != n_statistics)
-
2321  throw std::length_error("The number of names to add differs from the number of statistics in the model.");
2322 
-
2323  names_statistics = names;
+
2323 
2324 
-
2325 }
-
2326 
-
2327 template<typename TData>
-
2328 inline std::vector< epiworld_double > LFMCMC<TData>::get_params_mean()
-
2329 {
-
2330  std::vector< epiworld_double > res(this->n_parameters, 0.0);
-
2331 
-
2332  for (size_t k = 0u; k < n_parameters; ++k)
-
2333  {
-
2334  for (size_t i = 0u; i < n_samples; ++i)
-
2335  res[k] += (this->accepted_params[k + n_parameters * i])/
-
2336  static_cast< epiworld_double >(n_samples);
-
2337  }
-
2338 
-
2339  return res;
-
2340 
-
2341 }
+
2325 template<typename TData>
+
2326 inline void LFMCMC<TData>::chrono_start() {
+
2327  time_start = std::chrono::steady_clock::now();
+
2328 }
+
2329 
+
2330 template<typename TData>
+
2331 inline void LFMCMC<TData>::chrono_end() {
+
2332  time_end = std::chrono::steady_clock::now();
+
2333  time_elapsed += (time_end - time_start);
+
2334 }
+
2335 
+
2336 template<typename TData>
+
2337 inline void LFMCMC<TData>::set_par_names(std::vector< std::string > names)
+
2338 {
+
2339 
+
2340  if (names.size() != n_parameters)
+
2341  throw std::length_error("The number of names to add differs from the number of parameters in the model.");
2342 
-
2343 template<typename TData>
-
2344 inline std::vector< epiworld_double > LFMCMC<TData>::get_stats_mean()
-
2345 {
-
2346  std::vector< epiworld_double > res(this->n_statistics, 0.0);
-
2347 
-
2348  for (size_t k = 0u; k < n_statistics; ++k)
-
2349  {
-
2350  for (size_t i = 0u; i < n_samples; ++i)
-
2351  res[k] += (this->accepted_stats[k + n_statistics * i])/
-
2352  static_cast< epiworld_double >(n_samples);
-
2353  }
+
2343  names_parameters = names;
+
2344 
+
2345 }
+
2346 template<typename TData>
+
2347 inline void LFMCMC<TData>::set_stats_names(std::vector< std::string > names)
+
2348 {
+
2349 
+
2350  if (names.size() != n_statistics)
+
2351  throw std::length_error("The number of names to add differs from the number of statistics in the model.");
+
2352 
+
2353  names_statistics = names;
2354 
-
2355  return res;
+
2355 }
2356 
-
2357 }
-
2358 
-
2359 #endif
-
2360 /*//////////////////////////////////////////////////////////////////////////////
-
2362 
-
2363  End of -include/epiworld//math/lfmcmc/lfmcmc-meat.hpp-
-
2364 
-
2367 
+
2357 template<typename TData>
+
2358 inline std::vector< epiworld_double > LFMCMC<TData>::get_params_mean()
+
2359 {
+
2360  std::vector< epiworld_double > res(this->n_parameters, 0.0);
+
2361 
+
2362  for (size_t k = 0u; k < n_parameters; ++k)
+
2363  {
+
2364  for (size_t i = 0u; i < n_samples; ++i)
+
2365  res[k] += (this->accepted_params[k + n_parameters * i])/
+
2366  static_cast< epiworld_double >(n_samples);
+
2367  }
2368 
-
2369 
-
2370 #endif
-
2371 /*//////////////////////////////////////////////////////////////////////////////
-
2373 
-
2374  End of -include/epiworld/math/lfmcmc.hpp-
-
2375 
-
2378 
-
2379 
-
2380 
-
2381 /*//////////////////////////////////////////////////////////////////////////////
-
2383 
-
2384  Start of -include/epiworld/userdata-bones.hpp-
-
2385 
+
2369  return res;
+
2370 
+
2371 }
+
2372 
+
2373 template<typename TData>
+
2374 inline std::vector< epiworld_double > LFMCMC<TData>::get_stats_mean()
+
2375 {
+
2376  std::vector< epiworld_double > res(this->n_statistics, 0.0);
+
2377 
+
2378  for (size_t k = 0u; k < n_statistics; ++k)
+
2379  {
+
2380  for (size_t i = 0u; i < n_samples; ++i)
+
2381  res[k] += (this->accepted_stats[k + n_statistics * i])/
+
2382  static_cast< epiworld_double >(n_samples);
+
2383  }
+
2384 
+
2385  return res;
+
2386 
+
2387 }
2388 
-
2389 
-
2390 #ifndef EPIWORLD_USERDATA_BONES_HPP
-
2391 #define EPIWORLD_USERDATA_BONES_HPP
+
2389 #endif
+
2390 /*//////////////////////////////////////////////////////////////////////////////
2392 
-
2393 template<typename TSeq>
-
2394 class Model;
-
2395 
-
2396 template<typename TSeq>
-
2397 class DataBase;
+
2393  End of -include/epiworld//math/lfmcmc/lfmcmc-meat.hpp-
+
2394 
+
2397 
2398 
-
2404 template<typename TSeq>
-
2405 class UserData
-
2406 {
-
2407  friend class Model<TSeq>;
-
2408  friend class DataBase<TSeq>;
+
2399 
+
2400 #endif
+
2401 /*//////////////////////////////////////////////////////////////////////////////
+
2403 
+
2404  End of -include/epiworld/math/lfmcmc.hpp-
+
2405 
+
2408 
2409 
-
2410 private:
-
2411  Model<TSeq> * model;
-
2412 
-
2413  std::vector< std::string > data_names;
-
2414  std::vector< int > data_dates;
-
2415  std::vector< epiworld_double > data_data;
-
2416 
-
2417  epiworld_fast_uint k = 0u;
-
2418  epiworld_fast_uint n = 0u;
+
2410 
+
2411 /*//////////////////////////////////////////////////////////////////////////////
+
2413 
+
2414  Start of -include/epiworld/userdata-bones.hpp-
+
2415 
+
2418 
2419 
-
2420  int last_day = -1;
-
2421 
-
2422 public:
-
2423 
-
2424  UserData() = delete;
-
2425  UserData(Model<TSeq> & m) : model(&m) {};
-
2426  UserData(Model<TSeq> * m) : model(m) {};
-
2427 
-
2434  UserData(std::vector< std::string > names);
-
2435 
-
2443  void add(std::vector<epiworld_double> x);
-
2444  void add(
-
2445  epiworld_fast_uint j,
-
2446  epiworld_double x
-
2447  );
+
2420 #ifndef EPIWORLD_USERDATA_BONES_HPP
+
2421 #define EPIWORLD_USERDATA_BONES_HPP
+
2422 
+
2423 template<typename TSeq>
+
2424 class Model;
+
2425 
+
2426 template<typename TSeq>
+
2427 class DataBase;
+
2428 
+
2434 template<typename TSeq>
+
2435 class UserData
+
2436 {
+
2437  friend class Model<TSeq>;
+
2438  friend class DataBase<TSeq>;
+
2439 
+
2440 private:
+
2441  Model<TSeq> * model;
+
2442 
+
2443  std::vector< std::string > data_names;
+
2444  std::vector< int > data_dates;
+
2445  std::vector< epiworld_double > data_data;
+
2446 
+
2447  epiworld_fast_uint k = 0u;
+
2448  epiworld_fast_uint n = 0u;
2449 
-
2458  epiworld_double & operator()(
-
2459  epiworld_fast_uint i,
-
2460  epiworld_fast_uint j
-
2461  );
-
2462 
-
2463  epiworld_double & operator()(
-
2464  epiworld_fast_uint i,
-
2465  std::string name
-
2466  );
-
2468 
-
2469  std::vector< std::string > & get_names();
-
2470 
-
2471  std::vector< int > & get_dates();
-
2472 
-
2473  std::vector< epiworld_double > & get_data();
-
2474 
-
2475  void get_all(
-
2476  std::vector< std::string > * names = nullptr,
-
2477  std::vector< int > * date = nullptr,
-
2478  std::vector< epiworld_double > * data = nullptr
-
2479  );
-
2480 
-
2481  epiworld_fast_uint nrow() const;
-
2482  epiworld_fast_uint ncol() const;
-
2483 
-
2484  void write(std::string fn);
-
2485  void print() const;
-
2486 
-
2487 };
-
2488 
-
2489 #endif
-
2490 /*//////////////////////////////////////////////////////////////////////////////
+
2450  int last_day = -1;
+
2451 
+
2452 public:
+
2453 
+
2454  UserData() = delete;
+
2455  UserData(Model<TSeq> & m) : model(&m) {};
+
2456  UserData(Model<TSeq> * m) : model(m) {};
+
2457 
+
2464  UserData(std::vector< std::string > names);
+
2465 
+
2473  void add(std::vector<epiworld_double> x);
+
2474  void add(
+
2475  epiworld_fast_uint j,
+
2476  epiworld_double x
+
2477  );
+
2479 
+
2488  epiworld_double & operator()(
+
2489  epiworld_fast_uint i,
+
2490  epiworld_fast_uint j
+
2491  );
2492 
-
2493  End of -include/epiworld/userdata-bones.hpp-
-
2494 
-
2497 
+
2493  epiworld_double & operator()(
+
2494  epiworld_fast_uint i,
+
2495  std::string name
+
2496  );
2498 
-
2499 /*//////////////////////////////////////////////////////////////////////////////
-
2501 
-
2502  Start of -include/epiworld/userdata-meat.hpp-
-
2503 
-
2506 
-
2507 
-
2508 #ifndef EPIWORLD_USERDATA_MEAT_HPP
-
2509 #define EPIWORLD_USERDATA_MEAT_HPP
+
2499  std::vector< std::string > & get_names();
+
2500 
+
2501  std::vector< int > & get_dates();
+
2502 
+
2503  std::vector< epiworld_double > & get_data();
+
2504 
+
2505  void get_all(
+
2506  std::vector< std::string > * names = nullptr,
+
2507  std::vector< int > * date = nullptr,
+
2508  std::vector< epiworld_double > * data = nullptr
+
2509  );
2510 
-
2511 template<typename TSeq>
-
2512 class UserData;
+
2511  epiworld_fast_uint nrow() const;
+
2512  epiworld_fast_uint ncol() const;
2513 
-
2514 template<typename TSeq>
-
2515 inline UserData<TSeq>::UserData(std::vector< std::string > names)
-
2516 {
-
2517 
-
2518  k = names.size();
-
2519  data_names = names;
-
2520 
-
2521 }
+
2514  void write(std::string fn);
+
2515  void print() const;
+
2516 
+
2517 };
+
2518 
+
2519 #endif
+
2520 /*//////////////////////////////////////////////////////////////////////////////
2522 
-
2523 template<typename TSeq>
-
2524 inline void UserData<TSeq>::add(std::vector<epiworld_double> x)
-
2525 {
-
2526 
-
2527  if (x.size() != k)
-
2528  throw std::out_of_range(
-
2529  "The size of -x-, " + std::to_string(x.size()) + ", does not match " +
-
2530  "the number of elements registered (" + std::to_string(k));
+
2523  End of -include/epiworld/userdata-bones.hpp-
+
2524 
+
2527 
+
2528 
+
2529 /*//////////////////////////////////////////////////////////////////////////////
2531 
-
2532  for (auto & i : x)
-
2533  data_data.push_back(i);
-
2534 
-
2535  data_dates.push_back(model->today());
+
2532  Start of -include/epiworld/userdata-meat.hpp-
+
2533 
2536 
-
2537  n++;
-
2538  last_day = model->today();
-
2539 
-
2540 }
-
2541 
-
2542 template<typename TSeq>
-
2543 inline void UserData<TSeq>::add(epiworld_fast_uint j, epiworld_double x)
-
2544 {
-
2545 
-
2546  // Starting with a new day?
-
2547  if (static_cast<int>(model->today()) != last_day)
-
2548  {
-
2549 
-
2550  std::vector< epiworld_double > tmp(k, 0.0);
-
2551 
-
2552  tmp[j] = x;
-
2553 
-
2554  add(tmp);
-
2555 
-
2556  }
-
2557  else
-
2558  {
-
2559 
-
2560  this->operator()(n - 1, j) = x;
+
2537 
+
2538 #ifndef EPIWORLD_USERDATA_MEAT_HPP
+
2539 #define EPIWORLD_USERDATA_MEAT_HPP
+
2540 
+
2541 template<typename TSeq>
+
2542 class UserData;
+
2543 
+
2544 template<typename TSeq>
+
2545 inline UserData<TSeq>::UserData(std::vector< std::string > names)
+
2546 {
+
2547 
+
2548  k = names.size();
+
2549  data_names = names;
+
2550 
+
2551 }
+
2552 
+
2553 template<typename TSeq>
+
2554 inline void UserData<TSeq>::add(std::vector<epiworld_double> x)
+
2555 {
+
2556 
+
2557  if (x.size() != k)
+
2558  throw std::out_of_range(
+
2559  "The size of -x-, " + std::to_string(x.size()) + ", does not match " +
+
2560  "the number of elements registered (" + std::to_string(k));
2561 
-
2562  }
-
2563 
-
2564 }
-
2565 
-
2566 template<typename TSeq>
-
2567 inline std::vector< std::string > & UserData<TSeq>::get_names()
-
2568 {
-
2569  return data_names;
+
2562  for (auto & i : x)
+
2563  data_data.push_back(i);
+
2564 
+
2565  data_dates.push_back(model->today());
+
2566 
+
2567  n++;
+
2568  last_day = model->today();
+
2569 
2570 }
2571 
2572 template<typename TSeq>
-
2573 inline std::vector< int > & UserData<TSeq>::get_dates()
+
2573 inline void UserData<TSeq>::add(epiworld_fast_uint j, epiworld_double x)
2574 {
-
2575  return data_dates;
-
2576 }
-
2577 
-
2578 template<typename TSeq>
-
2579 inline std::vector< epiworld_double > & UserData<TSeq>::get_data()
-
2580 {
-
2581  return data_data;
-
2582 }
+
2575 
+
2576  // Starting with a new day?
+
2577  if (static_cast<int>(model->today()) != last_day)
+
2578  {
+
2579 
+
2580  std::vector< epiworld_double > tmp(k, 0.0);
+
2581 
+
2582  tmp[j] = x;
2583 
-
2584 template<typename TSeq>
-
2585 inline void UserData<TSeq>::get_all(
-
2586  std::vector< std::string > * names,
-
2587  std::vector< int > * date,
-
2588  std::vector< epiworld_double > * data
-
2589 )
-
2590 {
-
2591 
-
2592  if (names != nullptr)
-
2593  names = &this->data_names;
-
2594 
-
2595  if (date != nullptr)
-
2596  date = &this->data_dates;
-
2597 
-
2598  if (data != nullptr)
-
2599  data = &this->data_data;
-
2600 
-
2601 }
-
2602 
-
2603 template<typename TSeq>
-
2604 inline epiworld_double & UserData<TSeq>::operator()(
-
2605  epiworld_fast_uint i,
-
2606  epiworld_fast_uint j
-
2607 )
-
2608 {
-
2609 
-
2610  if (j >= k)
-
2611  throw std::out_of_range("j cannot be greater than k - 1.");
-
2612 
-
2613  if (i >= n)
-
2614  throw std::out_of_range("j cannot be greater than n - 1.");
-
2615 
-
2616  return data_data[k * i + j];
-
2617 
-
2618 }
-
2619 
-
2620 template<typename TSeq>
-
2621 inline epiworld_double & UserData<TSeq>::operator()(
-
2622  epiworld_fast_uint i,
-
2623  std::string name
-
2624 )
-
2625 {
-
2626  int loc = -1;
-
2627  for (epiworld_fast_uint l = 0u; l < k; ++l)
-
2628  {
-
2629 
-
2630  if (name == data_names[l])
-
2631  {
+
2584  add(tmp);
+
2585 
+
2586  }
+
2587  else
+
2588  {
+
2589 
+
2590  this->operator()(n - 1, j) = x;
+
2591 
+
2592  }
+
2593 
+
2594 }
+
2595 
+
2596 template<typename TSeq>
+
2597 inline std::vector< std::string > & UserData<TSeq>::get_names()
+
2598 {
+
2599  return data_names;
+
2600 }
+
2601 
+
2602 template<typename TSeq>
+
2603 inline std::vector< int > & UserData<TSeq>::get_dates()
+
2604 {
+
2605  return data_dates;
+
2606 }
+
2607 
+
2608 template<typename TSeq>
+
2609 inline std::vector< epiworld_double > & UserData<TSeq>::get_data()
+
2610 {
+
2611  return data_data;
+
2612 }
+
2613 
+
2614 template<typename TSeq>
+
2615 inline void UserData<TSeq>::get_all(
+
2616  std::vector< std::string > * names,
+
2617  std::vector< int > * date,
+
2618  std::vector< epiworld_double > * data
+
2619 )
+
2620 {
+
2621 
+
2622  if (names != nullptr)
+
2623  names = &this->data_names;
+
2624 
+
2625  if (date != nullptr)
+
2626  date = &this->data_dates;
+
2627 
+
2628  if (data != nullptr)
+
2629  data = &this->data_data;
+
2630 
+
2631 }
2632 
-
2633  loc = l;
-
2634  break;
-
2635 
-
2636  }
-
2637 
-
2638  }
+
2633 template<typename TSeq>
+
2634 inline epiworld_double & UserData<TSeq>::operator()(
+
2635  epiworld_fast_uint i,
+
2636  epiworld_fast_uint j
+
2637 )
+
2638 {
2639 
-
2640  if (loc < 0)
-
2641  throw std::range_error(
-
2642  "The variable \"" + name + "\" is not present " +
-
2643  "in the user UserData database."
-
2644  );
+
2640  if (j >= k)
+
2641  throw std::out_of_range("j cannot be greater than k - 1.");
+
2642 
+
2643  if (i >= n)
+
2644  throw std::out_of_range("j cannot be greater than n - 1.");
2645 
-
2646  return operator()(i, static_cast<epiworld_fast_uint>(loc));
+
2646  return data_data[k * i + j];
2647 
2648 }
2649 
2650 template<typename TSeq>
-
2651 inline epiworld_fast_uint UserData<TSeq>::nrow() const
-
2652 {
-
2653  return n;
-
2654 }
-
2655 
-
2656 template<typename TSeq>
-
2657 inline epiworld_fast_uint UserData<TSeq>::ncol() const
-
2658 {
-
2659  return k;
-
2660 }
-
2661 
-
2662 template<typename TSeq>
-
2663 inline void UserData<TSeq>::write(std::string fn)
-
2664 {
-
2665  std::ofstream file_ud(fn, std::ios_base::out);
-
2666 
-
2667  // File header
-
2668  file_ud << "\"date\"";
-
2669  for (auto & cn : data_names)
-
2670  file_ud << " \"" + cn + "\"";
-
2671  file_ud << "\n";
-
2672 
-
2673  epiworld_fast_uint ndata = 0u;
-
2674  for (epiworld_fast_uint i = 0u; i < n; ++i)
-
2675  {
-
2676  file_ud << data_dates[i];
+
2651 inline epiworld_double & UserData<TSeq>::operator()(
+
2652  epiworld_fast_uint i,
+
2653  std::string name
+
2654 )
+
2655 {
+
2656  int loc = -1;
+
2657  for (epiworld_fast_uint l = 0u; l < k; ++l)
+
2658  {
+
2659 
+
2660  if (name == data_names[l])
+
2661  {
+
2662 
+
2663  loc = l;
+
2664  break;
+
2665 
+
2666  }
+
2667 
+
2668  }
+
2669 
+
2670  if (loc < 0)
+
2671  throw std::range_error(
+
2672  "The variable \"" + name + "\" is not present " +
+
2673  "in the user UserData database."
+
2674  );
+
2675 
+
2676  return operator()(i, static_cast<epiworld_fast_uint>(loc));
2677 
-
2678  for (epiworld_fast_uint j = 0u; j < k; ++j)
-
2679  file_ud << " " << data_data[ndata++];
-
2680 
-
2681  file_ud << "\n";
-
2682  }
-
2683 
-
2684  return;
-
2685 }
-
2686 
-
2687 template<typename TSeq>
-
2688 inline void UserData<TSeq>::print() const
-
2689 {
-
2690  // File header
-
2691  printf_epiworld("Total records: %llu\n", n);
-
2692  printf_epiworld("date");
-
2693 
-
2694  for (auto & cn : data_names)
-
2695  {
+
2678 }
+
2679 
+
2680 template<typename TSeq>
+
2681 inline epiworld_fast_uint UserData<TSeq>::nrow() const
+
2682 {
+
2683  return n;
+
2684 }
+
2685 
+
2686 template<typename TSeq>
+
2687 inline epiworld_fast_uint UserData<TSeq>::ncol() const
+
2688 {
+
2689  return k;
+
2690 }
+
2691 
+
2692 template<typename TSeq>
+
2693 inline void UserData<TSeq>::write(std::string fn)
+
2694 {
+
2695  std::ofstream file_ud(fn, std::ios_base::out);
2696 
-
2697  printf_epiworld(" %s", cn.c_str());
-
2698 
-
2699  }
-
2700 
-
2701  printf_epiworld("\n");
+
2697  // File header
+
2698  file_ud << "\"date\"";
+
2699  for (auto & cn : data_names)
+
2700  file_ud << " \"" + cn + "\"";
+
2701  file_ud << "\n";
2702 
2703  epiworld_fast_uint ndata = 0u;
-
2704 
-
2705  for (epiworld_fast_uint i = 0u; i < n; ++i)
-
2706  {
+
2704  for (epiworld_fast_uint i = 0u; i < n; ++i)
+
2705  {
+
2706  file_ud << data_dates[i];
2707 
-
2708  printf_epiworld("%i", data_dates[i]);
-
2709 
-
2710  for (epiworld_fast_uint j = 0u; j < k; ++j)
-
2711  {
-
2712 
-
2713  printf_epiworld(" %.2f", data_data[ndata++]);
-
2714 
-
2715  }
+
2708  for (epiworld_fast_uint j = 0u; j < k; ++j)
+
2709  file_ud << " " << data_data[ndata++];
+
2710 
+
2711  file_ud << "\n";
+
2712  }
+
2713 
+
2714  return;
+
2715 }
2716 
-
2717  printf_epiworld("\n");
-
2718 
-
2719  }
-
2720 
-
2721  return;
-
2722 }
+
2717 template<typename TSeq>
+
2718 inline void UserData<TSeq>::print() const
+
2719 {
+
2720  // File header
+
2721  printf_epiworld("Total records: %llu\n", n);
+
2722  printf_epiworld("date");
2723 
-
2724 #endif
-
2725 /*//////////////////////////////////////////////////////////////////////////////
-
2727 
-
2728  End of -include/epiworld/userdata-meat.hpp-
-
2729 
-
2732 
-
2733 
-
2734 
-
2735 /*//////////////////////////////////////////////////////////////////////////////
+
2724  for (auto & cn : data_names)
+
2725  {
+
2726 
+
2727  printf_epiworld(" %s", cn.c_str());
+
2728 
+
2729  }
+
2730 
+
2731  printf_epiworld("\n");
+
2732 
+
2733  epiworld_fast_uint ndata = 0u;
+
2734 
+
2735  for (epiworld_fast_uint i = 0u; i < n; ++i)
+
2736  {
2737 
-
2738  Start of -include/epiworld/seq_processing.hpp-
+
2738  printf_epiworld("%i", data_dates[i]);
2739 
+
2740  for (epiworld_fast_uint j = 0u; j < k; ++j)
+
2741  {
2742 
-
2743 
-
2744 #ifndef EPIWORLD_SEQ_PROCESSING_HPP
-
2745 #define EPIWORLD_SEQ_PROCESSING_HPP
+
2743  printf_epiworld(" %.2f", data_data[ndata++]);
+
2744 
+
2745  }
2746 
-
2754 template<typename TSeq>
-
2755 inline std::vector<int> default_seq_hasher(const TSeq & x);
-
2756 
-
2757 template<>
-
2758 inline std::vector<int> default_seq_hasher<std::vector<int>>(const std::vector<int> & x) {
-
2759  return x;
-
2760 }
-
2761 
-
2762 template<>
-
2763 inline std::vector<int> default_seq_hasher<std::vector<bool>>(const std::vector<bool> & x) {
-
2764  std::vector<int> ans(x.size());
-
2765  size_t j = 0;
-
2766  for (const auto & i : x)
-
2767  ans[j++] = i? 1 : 0;
-
2768  return ans;
-
2769 }
-
2770 
-
2771 template<>
-
2772 inline std::vector<int> default_seq_hasher<int>(const int & x) {
-
2773  return {x};
-
2774 }
-
2775 
-
2776 template<>
-
2777 inline std::vector<int> default_seq_hasher<bool>(const bool & x) {
-
2778  return {x ? 1 : 0};
-
2779 }
-
2780 
-
2788 template<typename TSeq = int>
-
2789 inline std::string default_seq_writer(const TSeq & seq);
-
2790 
-
2791 template<>
-
2792 inline std::string default_seq_writer<std::vector<int>>(
-
2793  const std::vector<int> & seq
-
2794 ) {
-
2795 
-
2796  std::string out = "";
-
2797  for (const auto & s : seq)
-
2798  out = out + std::to_string(s);
-
2799 
-
2800  return out;
-
2801 
-
2802 }
-
2803 
-
2804 template<>
-
2805 inline std::string default_seq_writer<std::vector<bool>>(
-
2806  const std::vector<bool> & seq
-
2807 ) {
-
2808 
-
2809  std::string out = "";
-
2810  for (const auto & s : seq)
-
2811  out = out + (s ? "1" : "0");
-
2812 
-
2813  return out;
-
2814 
-
2815 }
-
2816 
-
2817 template<>
-
2818 inline std::string default_seq_writer<bool>(
-
2819  const bool & seq
-
2820 ) {
-
2821 
-
2822  return seq ? "1" : "0";
-
2823 
-
2824 }
+
2747  printf_epiworld("\n");
+
2748 
+
2749  }
+
2750 
+
2751  return;
+
2752 }
+
2753 
+
2754 #endif
+
2755 /*//////////////////////////////////////////////////////////////////////////////
+
2757 
+
2758  End of -include/epiworld/userdata-meat.hpp-
+
2759 
+
2762 
+
2763 
+
2764 
+
2765 /*//////////////////////////////////////////////////////////////////////////////
+
2767 
+
2768  Start of -include/epiworld/seq_processing.hpp-
+
2769 
+
2772 
+
2773 
+
2774 #ifndef EPIWORLD_SEQ_PROCESSING_HPP
+
2775 #define EPIWORLD_SEQ_PROCESSING_HPP
+
2776 
+
2784 template<typename TSeq>
+
2785 inline std::vector<int> default_seq_hasher(const TSeq & x);
+
2786 
+
2787 template<>
+
2788 inline std::vector<int> default_seq_hasher<std::vector<int>>(const std::vector<int> & x) {
+
2789  return x;
+
2790 }
+
2791 
+
2792 template<>
+
2793 inline std::vector<int> default_seq_hasher<std::vector<bool>>(const std::vector<bool> & x) {
+
2794  std::vector<int> ans(x.size());
+
2795  size_t j = 0;
+
2796  for (const auto & i : x)
+
2797  ans[j++] = i? 1 : 0;
+
2798  return ans;
+
2799 }
+
2800 
+
2801 template<>
+
2802 inline std::vector<int> default_seq_hasher<int>(const int & x) {
+
2803  return {x};
+
2804 }
+
2805 
+
2806 template<>
+
2807 inline std::vector<int> default_seq_hasher<bool>(const bool & x) {
+
2808  return {x ? 1 : 0};
+
2809 }
+
2810 
+
2818 template<typename TSeq = int>
+
2819 inline std::string default_seq_writer(const TSeq & seq);
+
2820 
+
2821 template<>
+
2822 inline std::string default_seq_writer<std::vector<int>>(
+
2823  const std::vector<int> & seq
+
2824 ) {
2825 
-
2826 template<>
-
2827 inline std::string default_seq_writer<int>(
-
2828  const int & seq
-
2829 ) {
-
2830 
-
2831  return std::to_string(seq);
-
2832 
-
2833 }
-
2834 
-
2835 
-
2836 
-
2837 #endif
-
2838 /*//////////////////////////////////////////////////////////////////////////////
-
2840 
-
2841  End of -include/epiworld/seq_processing.hpp-
+
2826  std::string out = "";
+
2827  for (const auto & s : seq)
+
2828  out = out + std::to_string(s);
+
2829 
+
2830  return out;
+
2831 
+
2832 }
+
2833 
+
2834 template<>
+
2835 inline std::string default_seq_writer<std::vector<bool>>(
+
2836  const std::vector<bool> & seq
+
2837 ) {
+
2838 
+
2839  std::string out = "";
+
2840  for (const auto & s : seq)
+
2841  out = out + (s ? "1" : "0");
2842 
-
2845 
+
2843  return out;
+
2844 
+
2845 }
2846 
-
2847 
-
2848 /*//////////////////////////////////////////////////////////////////////////////
-
2850 
-
2851  Start of -include/epiworld/database-bones.hpp-
-
2852 
+
2847 template<>
+
2848 inline std::string default_seq_writer<bool>(
+
2849  const bool & seq
+
2850 ) {
+
2851 
+
2852  return seq ? "1" : "0";
+
2853 
+
2854 }
2855 
-
2856 
-
2857 #ifndef EPIWORLD_DATABASE_BONES_HPP
-
2858 #define EPIWORLD_DATABASE_BONES_HPP
-
2859 
-
2860 template<typename TSeq>
-
2861 class Model;
+
2856 template<>
+
2857 inline std::string default_seq_writer<int>(
+
2858  const int & seq
+
2859 ) {
+
2860 
+
2861  return std::to_string(seq);
2862 
-
2863 template<typename TSeq>
-
2864 class Virus;
+
2863 }
+
2864 
2865 
-
2866 template<typename TSeq>
-
2867 class UserData;
-
2868 
-
2869 template<typename TSeq>
-
2870 inline void default_add_virus(Event<TSeq> & a, Model<TSeq> * m);
-
2871 
-
2872 template<typename TSeq>
-
2873 inline void default_add_tool(Event<TSeq> & a, Model<TSeq> * m);
-
2874 
-
2875 template<typename TSeq>
-
2876 inline void default_rm_virus(Event<TSeq> & a, Model<TSeq> * m);
+
2866 
+
2867 #endif
+
2868 /*//////////////////////////////////////////////////////////////////////////////
+
2870 
+
2871  End of -include/epiworld/seq_processing.hpp-
+
2872 
+
2875 
+
2876 
2877 
-
2878 template<typename TSeq>
-
2879 inline void default_rm_tool(Event<TSeq> & a, Model<TSeq> * m);
+
2878 /*//////////////////////////////////////////////////////////////////////////////
2880 
-
2881 template<typename TSeq>
-
2882 inline void default_change_state(Event<TSeq> & a, Model<TSeq> * m);
-
2883 
-
2889 template<typename TSeq>
-
2890 class DataBase {
-
2891  friend class Model<TSeq>;
-
2892  friend void default_add_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
2893  friend void default_add_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
2894  friend void default_rm_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
2895  friend void default_rm_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
2896  friend void default_change_state<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
2897 private:
-
2898  Model<TSeq> * model;
-
2899 
-
2900  // Variants information
-
2901  MapVec_type<int,int> virus_id; ///< The squence is the key
-
2902  std::vector< std::string > virus_name;
-
2903  std::vector< TSeq> virus_sequence;
-
2904  std::vector< int > virus_origin_date;
-
2905  std::vector< int > virus_parent_id;
-
2906 
-
2907  MapVec_type<int,int> tool_id; ///< The squence is the key
-
2908  std::vector< std::string > tool_name;
-
2909  std::vector< TSeq> tool_sequence;
-
2910  std::vector< int > tool_origin_date;
-
2911 
-
2912  std::function<std::vector<int>(const TSeq&)> seq_hasher = default_seq_hasher<TSeq>;
-
2913  std::function<std::string(const TSeq &)> seq_writer = default_seq_writer<TSeq>;
-
2914 
-
2915  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
-
2916  std::vector< std::vector<int> > today_virus;
-
2917 
-
2918  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
-
2919  std::vector< std::vector<int> > today_tool;
-
2920 
-
2921  // {Susceptible, Infected, etc.}
-
2922  std::vector< int > today_total;
-
2923 
-
2924  // Totals
-
2925  int today_total_nviruses_active = 0;
-
2926 
-
2927  int sampling_freq = 1;
-
2928 
-
2929  // Variants history
-
2930  std::vector< int > hist_virus_date;
-
2931  std::vector< int > hist_virus_id;
-
2932  std::vector< epiworld_fast_uint > hist_virus_state;
-
2933  std::vector< int > hist_virus_counts;
-
2934 
-
2935  // Tools history
-
2936  std::vector< int > hist_tool_date;
-
2937  std::vector< int > hist_tool_id;
-
2938  std::vector< epiworld_fast_uint > hist_tool_state;
-
2939  std::vector< int > hist_tool_counts;
-
2940 
-
2941  // Overall hist
-
2942  std::vector< int > hist_total_date;
-
2943  std::vector< int > hist_total_nviruses_active;
-
2944  std::vector< epiworld_fast_uint > hist_total_state;
-
2945  std::vector< int > hist_total_counts;
-
2946  std::vector< int > hist_transition_matrix;
+
2881  Start of -include/epiworld/database-bones.hpp-
+
2882 
+
2885 
+
2886 
+
2887 #ifndef EPIWORLD_DATABASE_BONES_HPP
+
2888 #define EPIWORLD_DATABASE_BONES_HPP
+
2889 
+
2890 template<typename TSeq>
+
2891 class Model;
+
2892 
+
2893 template<typename TSeq>
+
2894 class Virus;
+
2895 
+
2896 template<typename TSeq>
+
2897 class UserData;
+
2898 
+
2899 template<typename TSeq>
+
2900 inline void default_add_virus(Event<TSeq> & a, Model<TSeq> * m);
+
2901 
+
2902 template<typename TSeq>
+
2903 inline void default_add_tool(Event<TSeq> & a, Model<TSeq> * m);
+
2904 
+
2905 template<typename TSeq>
+
2906 inline void default_rm_virus(Event<TSeq> & a, Model<TSeq> * m);
+
2907 
+
2908 template<typename TSeq>
+
2909 inline void default_rm_tool(Event<TSeq> & a, Model<TSeq> * m);
+
2910 
+
2911 template<typename TSeq>
+
2912 inline void default_change_state(Event<TSeq> & a, Model<TSeq> * m);
+
2913 
+
2919 template<typename TSeq>
+
2920 class DataBase {
+
2921  friend class Model<TSeq>;
+
2922  friend void default_add_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
2923  friend void default_add_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
2924  friend void default_rm_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
2925  friend void default_rm_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
2926  friend void default_change_state<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
2927 private:
+
2928  Model<TSeq> * model;
+
2929 
+
2930  // Variants information
+
2931  MapVec_type<int,int> virus_id; ///< The squence is the key
+
2932  std::vector< std::string > virus_name;
+
2933  std::vector< TSeq> virus_sequence;
+
2934  std::vector< int > virus_origin_date;
+
2935  std::vector< int > virus_parent_id;
+
2936 
+
2937  MapVec_type<int,int> tool_id; ///< The squence is the key
+
2938  std::vector< std::string > tool_name;
+
2939  std::vector< TSeq> tool_sequence;
+
2940  std::vector< int > tool_origin_date;
+
2941 
+
2942  std::function<std::vector<int>(const TSeq&)> seq_hasher = default_seq_hasher<TSeq>;
+
2943  std::function<std::string(const TSeq &)> seq_writer = default_seq_writer<TSeq>;
+
2944 
+
2945  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
+
2946  std::vector< std::vector<int> > today_virus;
2947 
-
2948  // Transmission network
-
2949  std::vector< int > transmission_date; ///< Date of the transmission event
-
2950  std::vector< int > transmission_source; ///< Id of the source
-
2951  std::vector< int > transmission_target; ///< Id of the target
-
2952  std::vector< int > transmission_virus; ///< Id of the variant
-
2953  std::vector< int > transmission_source_exposure_date; ///< Date when the source acquired the variant
-
2954 
-
2955  std::vector< int > transition_matrix;
-
2956 
-
2957  UserData<TSeq> user_data;
+
2948  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
+
2949  std::vector< std::vector<int> > today_tool;
+
2950 
+
2951  // {Susceptible, Infected, etc.}
+
2952  std::vector< int > today_total;
+
2953 
+
2954  // Totals
+
2955  int today_total_nviruses_active = 0;
+
2956 
+
2957  int sampling_freq = 1;
2958 
-
2959  void update_state(
-
2960  epiworld_fast_uint prev_state,
-
2961  epiworld_fast_uint new_state,
-
2962  bool undo = false
-
2963  );
+
2959  // Variants history
+
2960  std::vector< int > hist_virus_date;
+
2961  std::vector< int > hist_virus_id;
+
2962  std::vector< epiworld_fast_uint > hist_virus_state;
+
2963  std::vector< int > hist_virus_counts;
2964 
-
2965  void update_virus(
-
2966  epiworld_fast_uint virus_id,
-
2967  epiworld_fast_uint prev_state,
-
2968  epiworld_fast_uint new_state
-
2969  );
+
2965  // Tools history
+
2966  std::vector< int > hist_tool_date;
+
2967  std::vector< int > hist_tool_id;
+
2968  std::vector< epiworld_fast_uint > hist_tool_state;
+
2969  std::vector< int > hist_tool_counts;
2970 
-
2971  void update_tool(
-
2972  epiworld_fast_uint tool_id,
-
2973  epiworld_fast_uint prev_state,
-
2974  epiworld_fast_uint new_state
-
2975  );
-
2976 
-
2977  void record_transition(epiworld_fast_uint from, epiworld_fast_uint to, bool undo);
-
2978 
-
2979 
-
2980 public:
-
2981 
-
2982  #ifdef EPI_DEBUG
-
2983  int n_transmissions_potential = 0;
-
2984  int n_transmissions_today = 0;
-
2985  #endif
+
2971  // Overall hist
+
2972  std::vector< int > hist_total_date;
+
2973  std::vector< int > hist_total_nviruses_active;
+
2974  std::vector< epiworld_fast_uint > hist_total_state;
+
2975  std::vector< int > hist_total_counts;
+
2976  std::vector< int > hist_transition_matrix;
+
2977 
+
2978  // Transmission network
+
2979  std::vector< int > transmission_date; ///< Date of the transmission event
+
2980  std::vector< int > transmission_source; ///< Id of the source
+
2981  std::vector< int > transmission_target; ///< Id of the target
+
2982  std::vector< int > transmission_virus; ///< Id of the variant
+
2983  std::vector< int > transmission_source_exposure_date; ///< Date when the source acquired the variant
+
2984 
+
2985  std::vector< int > transition_matrix;
2986 
-
2987  DataBase() = delete;
-
2988  DataBase(Model<TSeq> & m) : model(&m), user_data(m) {};
-
2989  DataBase(const DataBase<TSeq> & db);
-
2990  // DataBase<TSeq> & operator=(const DataBase<TSeq> & m);
-
2991 
-
3000  void record_virus(Virus<TSeq> & v);
-
3001  void record_tool(Tool<TSeq> & t);
-
3002  void set_seq_hasher(std::function<std::vector<int>(TSeq)> fun);
-
3003  void reset();
-
3004  Model<TSeq> * get_model();
-
3005  void record();
+
2987  UserData<TSeq> user_data;
+
2988 
+
2989  void update_state(
+
2990  epiworld_fast_uint prev_state,
+
2991  epiworld_fast_uint new_state,
+
2992  bool undo = false
+
2993  );
+
2994 
+
2995  void update_virus(
+
2996  epiworld_fast_uint virus_id,
+
2997  epiworld_fast_uint prev_state,
+
2998  epiworld_fast_uint new_state
+
2999  );
+
3000 
+
3001  void update_tool(
+
3002  epiworld_fast_uint tool_id,
+
3003  epiworld_fast_uint prev_state,
+
3004  epiworld_fast_uint new_state
+
3005  );
3006 
-
3007  const std::vector< TSeq > & get_sequence() const;
-
3008  const std::vector< int > & get_nexposed() const;
-
3009  size_t size() const;
-
3010 
-
3024  int get_today_total(std::string what) const;
-
3025  int get_today_total(epiworld_fast_uint what) const;
-
3026  void get_today_total(
-
3027  std::vector< std::string > * state = nullptr,
-
3028  std::vector< int > * counts = nullptr
-
3029  ) const;
-
3030 
-
3031  void get_today_virus(
-
3032  std::vector< std::string > & state,
-
3033  std::vector< int > & id,
-
3034  std::vector< int > & counts
-
3035  ) const;
+
3007  void record_transition(epiworld_fast_uint from, epiworld_fast_uint to, bool undo);
+
3008 
+
3009 
+
3010 public:
+
3011 
+
3012  #ifdef EPI_DEBUG
+
3013  int n_transmissions_potential = 0;
+
3014  int n_transmissions_today = 0;
+
3015  #endif
+
3016 
+
3017  DataBase() = delete;
+
3018  DataBase(Model<TSeq> & m) : model(&m), user_data(m) {};
+
3019  DataBase(const DataBase<TSeq> & db);
+
3020  // DataBase<TSeq> & operator=(const DataBase<TSeq> & m);
+
3021 
+
3030  void record_virus(Virus<TSeq> & v);
+
3031  void record_tool(Tool<TSeq> & t);
+
3032  void set_seq_hasher(std::function<std::vector<int>(TSeq)> fun);
+
3033  void reset();
+
3034  Model<TSeq> * get_model();
+
3035  void record();
3036 
-
3037  void get_today_transition_matrix(
-
3038  std::vector< int > & counts
-
3039  ) const;
+
3037  const std::vector< TSeq > & get_sequence() const;
+
3038  const std::vector< int > & get_nexposed() const;
+
3039  size_t size() const;
3040 
-
3041  void get_hist_total(
-
3042  std::vector< int > * date,
-
3043  std::vector< std::string > * state,
-
3044  std::vector< int > * counts
-
3045  ) const;
-
3046 
-
3047  void get_hist_virus(
-
3048  std::vector< int > & date,
-
3049  std::vector< int > & id,
-
3050  std::vector< std::string > & state,
-
3051  std::vector< int > & counts
-
3052  ) const;
-
3053 
-
3054  void get_hist_tool(
-
3055  std::vector< int > & date,
-
3056  std::vector< int > & id,
-
3057  std::vector< std::string > & state,
-
3058  std::vector< int > & counts
+
3054  int get_today_total(std::string what) const;
+
3055  int get_today_total(epiworld_fast_uint what) const;
+
3056  void get_today_total(
+
3057  std::vector< std::string > * state = nullptr,
+
3058  std::vector< int > * counts = nullptr
3059  ) const;
3060 
-
3061  void get_hist_transition_matrix(
-
3062  std::vector< std::string > & state_from,
-
3063  std::vector< std::string > & state_to,
-
3064  std::vector< int > & date,
-
3065  std::vector< int > & counts,
-
3066  bool skip_zeros
-
3067  ) const;
-
3069 
-
3080  void get_transmissions(
-
3081  std::vector<int> & date,
-
3082  std::vector<int> & source,
-
3083  std::vector<int> & target,
-
3084  std::vector<int> & virus,
-
3085  std::vector<int> & source_exposure_date
-
3086  ) const;
-
3087 
-
3088  void get_transmissions(
-
3089  int * date,
-
3090  int * source,
-
3091  int * target,
-
3092  int * virus,
-
3093  int * source_exposure_date
-
3094  ) const;
-
3096 
-
3097  void write_data(
-
3098  std::string fn_virus_info,
-
3099  std::string fn_virus_hist,
-
3100  std::string fn_tool_info,
-
3101  std::string fn_tool_hist,
-
3102  std::string fn_total_hist,
-
3103  std::string fn_transmission,
-
3104  std::string fn_transition,
-
3105  std::string fn_reproductive_number,
-
3106  std::string fn_generation_time
-
3107  ) const;
-
3108 
-
3109  /***
-
3110  * @brief Record a transmission event
-
3111  */
-
3112  void record_transmission(int i, int j, int virus, int i_expo_date);
-
3113 
-
3114  size_t get_n_viruses() const;
-
3115  size_t get_n_tools() const;
-
3116 
-
3117  void set_user_data(std::vector< std::string > names);
-
3118  void add_user_data(std::vector< epiworld_double > x);
-
3119  void add_user_data(epiworld_fast_uint j, epiworld_double x);
-
3120  UserData<TSeq> & get_user_data();
-
3121 
-
3122 
-
3133  MapVec_type<int,int> reproductive_number() const;
-
3134 
-
3135  void reproductive_number(
-
3136  std::string fn
-
3137  ) const;
-
3139 
-
3145  std::vector< epiworld_double > transition_probability(
-
3146  bool print = true
-
3147  ) const;
-
3148 
-
3149  bool operator==(const DataBase<TSeq> & other) const;
-
3150  bool operator!=(const DataBase<TSeq> & other) const {return !operator==(other);};
+
3061  void get_today_virus(
+
3062  std::vector< std::string > & state,
+
3063  std::vector< int > & id,
+
3064  std::vector< int > & counts
+
3065  ) const;
+
3066 
+
3067  void get_today_transition_matrix(
+
3068  std::vector< int > & counts
+
3069  ) const;
+
3070 
+
3071  void get_hist_total(
+
3072  std::vector< int > * date,
+
3073  std::vector< std::string > * state,
+
3074  std::vector< int > * counts
+
3075  ) const;
+
3076 
+
3077  void get_hist_virus(
+
3078  std::vector< int > & date,
+
3079  std::vector< int > & id,
+
3080  std::vector< std::string > & state,
+
3081  std::vector< int > & counts
+
3082  ) const;
+
3083 
+
3084  void get_hist_tool(
+
3085  std::vector< int > & date,
+
3086  std::vector< int > & id,
+
3087  std::vector< std::string > & state,
+
3088  std::vector< int > & counts
+
3089  ) const;
+
3090 
+
3091  void get_hist_transition_matrix(
+
3092  std::vector< std::string > & state_from,
+
3093  std::vector< std::string > & state_to,
+
3094  std::vector< int > & date,
+
3095  std::vector< int > & counts,
+
3096  bool skip_zeros
+
3097  ) const;
+
3099 
+
3110  void get_transmissions(
+
3111  std::vector<int> & date,
+
3112  std::vector<int> & source,
+
3113  std::vector<int> & target,
+
3114  std::vector<int> & virus,
+
3115  std::vector<int> & source_exposure_date
+
3116  ) const;
+
3117 
+
3118  void get_transmissions(
+
3119  int * date,
+
3120  int * source,
+
3121  int * target,
+
3122  int * virus,
+
3123  int * source_exposure_date
+
3124  ) const;
+
3126 
+
3127  void write_data(
+
3128  std::string fn_virus_info,
+
3129  std::string fn_virus_hist,
+
3130  std::string fn_tool_info,
+
3131  std::string fn_tool_hist,
+
3132  std::string fn_total_hist,
+
3133  std::string fn_transmission,
+
3134  std::string fn_transition,
+
3135  std::string fn_reproductive_number,
+
3136  std::string fn_generation_time
+
3137  ) const;
+
3138 
+
3139  /***
+
3140  * @brief Record a transmission event
+
3141  */
+
3142  void record_transmission(int i, int j, int virus, int i_expo_date);
+
3143 
+
3144  size_t get_n_viruses() const;
+
3145  size_t get_n_tools() const;
+
3146 
+
3147  void set_user_data(std::vector< std::string > names);
+
3148  void add_user_data(std::vector< epiworld_double > x);
+
3149  void add_user_data(epiworld_fast_uint j, epiworld_double x);
+
3150  UserData<TSeq> & get_user_data();
3151 
-
3161  void generation_time(
-
3162  std::vector< int > & agent_id,
-
3163  std::vector< int > & virus_id,
-
3164  std::vector< int > & time,
-
3165  std::vector< int > & gentime
-
3166  ) const;
-
3167 
-
3168  void generation_time(
-
3169  std::string fn
-
3170  ) const;
-
3172 
-
3173 };
-
3174 
-
3175 
-
3176 #endif
-
3177 /*//////////////////////////////////////////////////////////////////////////////
-
3179 
-
3180  End of -include/epiworld/database-bones.hpp-
-
3181 
-
3184 
-
3185 
-
3186 /*//////////////////////////////////////////////////////////////////////////////
-
3188 
-
3189  Start of -include/epiworld/database-meat.hpp-
-
3190 
-
3193 
-
3194 
-
3195 #ifndef EPIWORLD_DATABASE_MEAT_HPP
-
3196 #define EPIWORLD_DATABASE_MEAT_HPP
-
3197 
-
3198 template<typename TSeq>
-
3199 inline void DataBase<TSeq>::reset()
-
3200 {
-
3201 
-
3202  // Initializing the counts
-
3203  today_total.resize(model->nstates);
-
3204  std::fill(today_total.begin(), today_total.end(), 0);
-
3205  for (auto & p : model->get_agents())
-
3206  ++today_total[p.get_state()];
-
3207 
-
3208  #ifdef EPI_DEBUG
-
3209  // Only the first should be different from zero
-
3210  {
-
3211  int n = static_cast<int>(model->size());
-
3212  if (today_total[0] != n)
-
3213  throw std::runtime_error("The number of susceptible agents is not equal to the total number of agents.");
+
3152 
+
3163  MapVec_type<int,int> reproductive_number() const;
+
3164 
+
3165  void reproductive_number(
+
3166  std::string fn
+
3167  ) const;
+
3169 
+
3175  std::vector< epiworld_double > transition_probability(
+
3176  bool print = true
+
3177  ) const;
+
3178 
+
3179  bool operator==(const DataBase<TSeq> & other) const;
+
3180  bool operator!=(const DataBase<TSeq> & other) const {return !operator==(other);};
+
3181 
+
3191  void generation_time(
+
3192  std::vector< int > & agent_id,
+
3193  std::vector< int > & virus_id,
+
3194  std::vector< int > & time,
+
3195  std::vector< int > & gentime
+
3196  ) const;
+
3197 
+
3198  void generation_time(
+
3199  std::string fn
+
3200  ) const;
+
3202 
+
3203 };
+
3204 
+
3205 
+
3206 #endif
+
3207 /*//////////////////////////////////////////////////////////////////////////////
+
3209 
+
3210  End of -include/epiworld/database-bones.hpp-
+
3211 
3214 
-
3215  if (std::accumulate(today_total.begin(), today_total.end(), 0) != n)
-
3216  throw std::runtime_error("The total number of agents is not equal to the sum of the number of agents in each state.");
-
3217 
-
3218  }
-
3219  #endif
+
3215 
+
3216 /*//////////////////////////////////////////////////////////////////////////////
+
3218 
+
3219  Start of -include/epiworld/database-meat.hpp-
3220 
-
3221 
-
3222  transition_matrix.resize(model->nstates * model->nstates);
-
3223  std::fill(transition_matrix.begin(), transition_matrix.end(), 0);
-
3224  for (size_t s = 0u; s < model->nstates; ++s)
-
3225  transition_matrix[s + s * model->nstates] = today_total[s];
-
3226 
-
3227  hist_virus_date.clear();
-
3228  hist_virus_id.clear();
-
3229  hist_virus_state.clear();
-
3230  hist_virus_counts.clear();
+
3223 
+
3224 
+
3225 #ifndef EPIWORLD_DATABASE_MEAT_HPP
+
3226 #define EPIWORLD_DATABASE_MEAT_HPP
+
3227 
+
3228 template<typename TSeq>
+
3229 inline void DataBase<TSeq>::reset()
+
3230 {
3231 
-
3232  hist_tool_date.clear();
-
3233  hist_tool_id.clear();
-
3234  hist_tool_state.clear();
-
3235  hist_tool_counts.clear();
-
3236 
-
3237  today_virus.resize(get_n_viruses());
-
3238  std::fill(today_virus.begin(), today_virus.begin(), std::vector<int>(model->nstates, 0));
-
3239 
-
3240  today_tool.resize(get_n_tools());
-
3241  std::fill(today_tool.begin(), today_tool.begin(), std::vector<int>(model->nstates, 0));
-
3242 
-
3243  hist_total_date.clear();
-
3244  hist_total_state.clear();
-
3245  hist_total_nviruses_active.clear();
-
3246  hist_total_counts.clear();
-
3247  hist_transition_matrix.clear();
-
3248 
-
3249  transmission_date.clear();
-
3250  transmission_virus.clear();
-
3251  transmission_source.clear();
-
3252  transmission_target.clear();
-
3253  transmission_source_exposure_date.clear();
-
3254 
-
3255  return;
+
3232  // Initializing the counts
+
3233  today_total.resize(model->nstates);
+
3234  std::fill(today_total.begin(), today_total.end(), 0);
+
3235  for (auto & p : model->get_agents())
+
3236  ++today_total[p.get_state()];
+
3237 
+
3238  #ifdef EPI_DEBUG
+
3239  // Only the first should be different from zero
+
3240  {
+
3241  int n = static_cast<int>(model->size());
+
3242  if (today_total[0] != n)
+
3243  throw std::runtime_error("The number of susceptible agents is not equal to the total number of agents.");
+
3244 
+
3245  if (std::accumulate(today_total.begin(), today_total.end(), 0) != n)
+
3246  throw std::runtime_error("The total number of agents is not equal to the sum of the number of agents in each state.");
+
3247 
+
3248  }
+
3249  #endif
+
3250 
+
3251 
+
3252  transition_matrix.resize(model->nstates * model->nstates);
+
3253  std::fill(transition_matrix.begin(), transition_matrix.end(), 0);
+
3254  for (size_t s = 0u; s < model->nstates; ++s)
+
3255  transition_matrix[s + s * model->nstates] = today_total[s];
3256 
-
3257 }
-
3258 
-
3259 template<typename TSeq>
-
3260 inline DataBase<TSeq>::DataBase(const DataBase<TSeq> & db) :
-
3261  virus_id(db.virus_id),
-
3262  virus_name(db.virus_name),
-
3263  virus_sequence(db.virus_sequence),
-
3264  virus_origin_date(db.virus_origin_date),
-
3265  virus_parent_id(db.virus_parent_id),
-
3266  tool_id(db.tool_id),
-
3267  tool_name(db.tool_name),
-
3268  tool_sequence(db.tool_sequence),
-
3269  tool_origin_date(db.tool_origin_date),
-
3270  seq_hasher(db.seq_hasher),
-
3271  seq_writer(db.seq_writer),
-
3272  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
-
3273  today_virus(db.today_virus),
-
3274  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
-
3275  today_tool(db.today_tool),
-
3276  // {Susceptible, Infected, etc.}
-
3277  today_total(db.today_total),
-
3278  // Totals
-
3279  today_total_nviruses_active(db.today_total_nviruses_active),
-
3280  sampling_freq(db.sampling_freq),
-
3281  // Variants history
-
3282  hist_virus_date(db.hist_virus_date),
-
3283  hist_virus_id(db.hist_virus_id),
-
3284  hist_virus_state(db.hist_virus_state),
-
3285  hist_virus_counts(db.hist_virus_counts),
-
3286  // Tools history
-
3287  hist_tool_date(db.hist_tool_date),
-
3288  hist_tool_id(db.hist_tool_id),
-
3289  hist_tool_state(db.hist_tool_state),
-
3290  hist_tool_counts(db.hist_tool_counts),
-
3291  // Overall hist
-
3292  hist_total_date(db.hist_total_date),
-
3293  hist_total_nviruses_active(db.hist_total_nviruses_active),
-
3294  hist_total_state(db.hist_total_state),
-
3295  hist_total_counts(db.hist_total_counts),
-
3296  hist_transition_matrix(db.hist_transition_matrix),
-
3297  // Transmission network
-
3298  transmission_date(db.transmission_date),
-
3299  transmission_source(db.transmission_source),
-
3300  transmission_target(db.transmission_target),
-
3301  transmission_virus(db.transmission_virus),
-
3302  transmission_source_exposure_date(db.transmission_source_exposure_date),
-
3303  transition_matrix(db.transition_matrix),
-
3304  user_data(nullptr)
-
3305 {}
-
3306 
-
3307 // DataBase<TSeq> & DataBase<TSeq>::operator=(const DataBase<TSeq> & m)
-
3308 // {
-
3309 
-
3310 // }
-
3311 
-
3312 template<typename TSeq>
-
3313 inline Model<TSeq> * DataBase<TSeq>::get_model() {
-
3314  return model;
-
3315 }
-
3316 
-
3317 template<typename TSeq>
-
3318 inline const std::vector< TSeq > & DataBase<TSeq>::get_sequence() const {
-
3319  return virus_sequence;
-
3320 }
-
3321 
-
3322 template<typename TSeq>
-
3323 inline void DataBase<TSeq>::record()
-
3324 {
-
3325 
-
3327  // DEBUGGING BLOCK
-
3329  EPI_DEBUG_SUM_INT(today_total, model->size())
-
3330  EPI_DEBUG_ALL_NON_NEGATIVE(today_total)
-
3331 
-
3332  #ifdef EPI_DEBUG
-
3333  // Checking whether the sums correspond
-
3334  std::vector< int > _today_total_cp(today_total.size(), 0);
-
3335  for (auto & p : model->population)
-
3336  _today_total_cp[p.get_state()]++;
-
3337 
-
3338  EPI_DEBUG_VECTOR_MATCH_INT(
-
3339  _today_total_cp, today_total,
-
3340  "Sums of __today_total_cp in database-meat.hpp"
-
3341  )
-
3342 
-
3343  if (model->today() == 0)
-
3344  {
-
3345  if (hist_total_date.size() != 0)
-
3346  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_total_date should be of length 0.")
-
3347  if (hist_total_nviruses_active.size() != 0)
-
3348  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_total_nviruses_active should be of length 0.")
-
3349  if (hist_total_state.size() != 0)
-
3350  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_total_state should be of length 0.")
-
3351  if (hist_total_counts.size() != 0)
-
3352  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_total_counts should be of length 0.")
-
3353  if (hist_virus_date.size() != 0)
-
3354  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_virus_date should be of length 0.")
-
3355  if (hist_virus_id.size() != 0)
-
3356  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_virus_id should be of length 0.")
-
3357  if (hist_virus_state.size() != 0)
-
3358  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_virus_state should be of length 0.")
-
3359  if (hist_virus_counts.size() != 0)
-
3360  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_virus_counts should be of length 0.")
-
3361  if (hist_tool_date.size() != 0)
-
3362  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_tool_date should be of length 0.")
-
3363  if (hist_tool_id.size() != 0)
-
3364  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_tool_id should be of length 0.")
-
3365  if (hist_tool_state.size() != 0)
-
3366  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_tool_state should be of length 0.")
-
3367  if (hist_tool_counts.size() != 0)
-
3368  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_tool_counts should be of length 0.")
-
3369  }
-
3370  #endif
+
3257  hist_virus_date.clear();
+
3258  hist_virus_id.clear();
+
3259  hist_virus_state.clear();
+
3260  hist_virus_counts.clear();
+
3261 
+
3262  hist_tool_date.clear();
+
3263  hist_tool_id.clear();
+
3264  hist_tool_state.clear();
+
3265  hist_tool_counts.clear();
+
3266 
+
3267  today_virus.resize(get_n_viruses());
+
3268  std::fill(today_virus.begin(), today_virus.begin(), std::vector<int>(model->nstates, 0));
+
3269 
+
3270  today_tool.resize(get_n_tools());
+
3271  std::fill(today_tool.begin(), today_tool.begin(), std::vector<int>(model->nstates, 0));
+
3272 
+
3273  hist_total_date.clear();
+
3274  hist_total_state.clear();
+
3275  hist_total_nviruses_active.clear();
+
3276  hist_total_counts.clear();
+
3277  hist_transition_matrix.clear();
+
3278 
+
3279  transmission_date.clear();
+
3280  transmission_virus.clear();
+
3281  transmission_source.clear();
+
3282  transmission_target.clear();
+
3283  transmission_source_exposure_date.clear();
+
3284 
+
3285  return;
+
3286 
+
3287 }
+
3288 
+
3289 template<typename TSeq>
+
3290 inline DataBase<TSeq>::DataBase(const DataBase<TSeq> & db) :
+
3291  virus_id(db.virus_id),
+
3292  virus_name(db.virus_name),
+
3293  virus_sequence(db.virus_sequence),
+
3294  virus_origin_date(db.virus_origin_date),
+
3295  virus_parent_id(db.virus_parent_id),
+
3296  tool_id(db.tool_id),
+
3297  tool_name(db.tool_name),
+
3298  tool_sequence(db.tool_sequence),
+
3299  tool_origin_date(db.tool_origin_date),
+
3300  seq_hasher(db.seq_hasher),
+
3301  seq_writer(db.seq_writer),
+
3302  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
+
3303  today_virus(db.today_virus),
+
3304  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
+
3305  today_tool(db.today_tool),
+
3306  // {Susceptible, Infected, etc.}
+
3307  today_total(db.today_total),
+
3308  // Totals
+
3309  today_total_nviruses_active(db.today_total_nviruses_active),
+
3310  sampling_freq(db.sampling_freq),
+
3311  // Variants history
+
3312  hist_virus_date(db.hist_virus_date),
+
3313  hist_virus_id(db.hist_virus_id),
+
3314  hist_virus_state(db.hist_virus_state),
+
3315  hist_virus_counts(db.hist_virus_counts),
+
3316  // Tools history
+
3317  hist_tool_date(db.hist_tool_date),
+
3318  hist_tool_id(db.hist_tool_id),
+
3319  hist_tool_state(db.hist_tool_state),
+
3320  hist_tool_counts(db.hist_tool_counts),
+
3321  // Overall hist
+
3322  hist_total_date(db.hist_total_date),
+
3323  hist_total_nviruses_active(db.hist_total_nviruses_active),
+
3324  hist_total_state(db.hist_total_state),
+
3325  hist_total_counts(db.hist_total_counts),
+
3326  hist_transition_matrix(db.hist_transition_matrix),
+
3327  // Transmission network
+
3328  transmission_date(db.transmission_date),
+
3329  transmission_source(db.transmission_source),
+
3330  transmission_target(db.transmission_target),
+
3331  transmission_virus(db.transmission_virus),
+
3332  transmission_source_exposure_date(db.transmission_source_exposure_date),
+
3333  transition_matrix(db.transition_matrix),
+
3334  user_data(nullptr)
+
3335 {}
+
3336 
+
3337 // DataBase<TSeq> & DataBase<TSeq>::operator=(const DataBase<TSeq> & m)
+
3338 // {
+
3339 
+
3340 // }
+
3341 
+
3342 template<typename TSeq>
+
3343 inline Model<TSeq> * DataBase<TSeq>::get_model() {
+
3344  return model;
+
3345 }
+
3346 
+
3347 template<typename TSeq>
+
3348 inline const std::vector< TSeq > & DataBase<TSeq>::get_sequence() const {
+
3349  return virus_sequence;
+
3350 }
+
3351 
+
3352 template<typename TSeq>
+
3353 inline void DataBase<TSeq>::record()
+
3354 {
+
3355 
+
3357  // DEBUGGING BLOCK
+
3359  EPI_DEBUG_SUM_INT(today_total, model->size())
+
3360  EPI_DEBUG_ALL_NON_NEGATIVE(today_total)
+
3361 
+
3362  #ifdef EPI_DEBUG
+
3363  // Checking whether the sums correspond
+
3364  std::vector< int > _today_total_cp(today_total.size(), 0);
+
3365  for (auto & p : model->population)
+
3366  _today_total_cp[p.get_state()]++;
+
3367 
+
3368  EPI_DEBUG_VECTOR_MATCH_INT(
+
3369  _today_total_cp, today_total,
+
3370  "Sums of __today_total_cp in database-meat.hpp"
+
3371  )
3372 
-
3373  // Only store every now and then
-
3374  if ((model->today() % sampling_freq) == 0)
-
3375  {
-
3376 
-
3377  // Recording virus's history
-
3378  for (auto & p : virus_id)
-
3379  {
-
3380 
-
3381  for (epiworld_fast_uint s = 0u; s < model->nstates; ++s)
-
3382  {
-
3383 
-
3384  hist_virus_date.push_back(model->today());
-
3385  hist_virus_id.push_back(p.second);
-
3386  hist_virus_state.push_back(s);
-
3387  hist_virus_counts.push_back(today_virus[p.second][s]);
-
3388 
-
3389  }
-
3390 
-
3391  }
-
3392 
-
3393  // Recording tool's history
-
3394  for (auto & p : tool_id)
-
3395  {
-
3396 
-
3397  for (epiworld_fast_uint s = 0u; s < model->nstates; ++s)
-
3398  {
-
3399 
-
3400  hist_tool_date.push_back(model->today());
-
3401  hist_tool_id.push_back(p.second);
-
3402  hist_tool_state.push_back(s);
-
3403  hist_tool_counts.push_back(today_tool[p.second][s]);
-
3404 
-
3405  }
+
3373  if (model->today() == 0)
+
3374  {
+
3375  if (hist_total_date.size() != 0)
+
3376  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_total_date should be of length 0.")
+
3377  if (hist_total_nviruses_active.size() != 0)
+
3378  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_total_nviruses_active should be of length 0.")
+
3379  if (hist_total_state.size() != 0)
+
3380  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_total_state should be of length 0.")
+
3381  if (hist_total_counts.size() != 0)
+
3382  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_total_counts should be of length 0.")
+
3383  if (hist_virus_date.size() != 0)
+
3384  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_virus_date should be of length 0.")
+
3385  if (hist_virus_id.size() != 0)
+
3386  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_virus_id should be of length 0.")
+
3387  if (hist_virus_state.size() != 0)
+
3388  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_virus_state should be of length 0.")
+
3389  if (hist_virus_counts.size() != 0)
+
3390  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_virus_counts should be of length 0.")
+
3391  if (hist_tool_date.size() != 0)
+
3392  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_tool_date should be of length 0.")
+
3393  if (hist_tool_id.size() != 0)
+
3394  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_tool_id should be of length 0.")
+
3395  if (hist_tool_state.size() != 0)
+
3396  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_tool_state should be of length 0.")
+
3397  if (hist_tool_counts.size() != 0)
+
3398  EPI_DEBUG_ERROR(std::logic_error, "DataBase::record hist_tool_counts should be of length 0.")
+
3399  }
+
3400  #endif
+
3402 
+
3403  // Only store every now and then
+
3404  if ((model->today() % sampling_freq) == 0)
+
3405  {
3406 
-
3407  }
-
3408 
-
3409  // Recording the overall history
-
3410  for (epiworld_fast_uint s = 0u; s < model->nstates; ++s)
-
3411  {
-
3412  hist_total_date.push_back(model->today());
-
3413  hist_total_nviruses_active.push_back(today_total_nviruses_active);
-
3414  hist_total_state.push_back(s);
-
3415  hist_total_counts.push_back(today_total[s]);
-
3416  }
-
3417 
-
3418  for (auto cell : transition_matrix)
-
3419  hist_transition_matrix.push_back(cell);
+
3407  // Recording virus's history
+
3408  for (auto & p : virus_id)
+
3409  {
+
3410 
+
3411  for (epiworld_fast_uint s = 0u; s < model->nstates; ++s)
+
3412  {
+
3413 
+
3414  hist_virus_date.push_back(model->today());
+
3415  hist_virus_id.push_back(p.second);
+
3416  hist_virus_state.push_back(s);
+
3417  hist_virus_counts.push_back(today_virus[p.second][s]);
+
3418 
+
3419  }
3420 
-
3421  // Now the diagonal must reflect the state
-
3422  for (size_t s_i = 0u; s_i < model->nstates; ++s_i)
-
3423  {
-
3424 
-
3425  for (size_t s_j = 0u; s_j < model->nstates; ++s_j)
-
3426  {
-
3427 
-
3428  if ((s_i != s_j) && (transition_matrix[s_i + s_j * model->nstates] > 0))
-
3429  {
-
3430  transition_matrix[s_j + s_j * model->nstates] +=
-
3431  transition_matrix[s_i + s_j * model->nstates];
-
3432 
-
3433  transition_matrix[s_i + s_j * model->nstates] = 0;
-
3434  }
-
3435 
-
3436  }
-
3437 
-
3438  }
-
3439 
-
3440  #ifdef EPI_DEBUG
-
3441  for (size_t s_i = 0u; s_i < model->nstates; ++s_i)
-
3442  {
-
3443  if (transition_matrix[s_i + s_i * model->nstates] !=
-
3444  today_total[s_i])
-
3445  throw std::logic_error(
-
3446  "The diagonal of the updated transition Matrix should match the daily totals"
-
3447  );
-
3448  }
-
3449  #endif
+
3421  }
+
3422 
+
3423  // Recording tool's history
+
3424  for (auto & p : tool_id)
+
3425  {
+
3426 
+
3427  for (epiworld_fast_uint s = 0u; s < model->nstates; ++s)
+
3428  {
+
3429 
+
3430  hist_tool_date.push_back(model->today());
+
3431  hist_tool_id.push_back(p.second);
+
3432  hist_tool_state.push_back(s);
+
3433  hist_tool_counts.push_back(today_tool[p.second][s]);
+
3434 
+
3435  }
+
3436 
+
3437  }
+
3438 
+
3439  // Recording the overall history
+
3440  for (epiworld_fast_uint s = 0u; s < model->nstates; ++s)
+
3441  {
+
3442  hist_total_date.push_back(model->today());
+
3443  hist_total_nviruses_active.push_back(today_total_nviruses_active);
+
3444  hist_total_state.push_back(s);
+
3445  hist_total_counts.push_back(today_total[s]);
+
3446  }
+
3447 
+
3448  for (auto cell : transition_matrix)
+
3449  hist_transition_matrix.push_back(cell);
3450 
-
3451  }
-
3452 
-
3453 }
+
3451  // Now the diagonal must reflect the state
+
3452  for (size_t s_i = 0u; s_i < model->nstates; ++s_i)
+
3453  {
3454 
-
3455 template<typename TSeq>
-
3456 inline void DataBase<TSeq>::record_virus(Virus<TSeq> & v)
-
3457 {
-
3458 
-
3459  // If no sequence, then need to add one. This is regardless of the case
-
3460  if (v.get_sequence() == nullptr)
-
3461  v.set_sequence(default_sequence<TSeq>(
-
3462  static_cast<int>(virus_name.size())
-
3463  ));
-
3464 
-
3465  // Negative id -> virus hasn't been recorded
-
3466  if (v.get_id() < 0)
-
3467  {
-
3468 
+
3455  for (size_t s_j = 0u; s_j < model->nstates; ++s_j)
+
3456  {
+
3457 
+
3458  if ((s_i != s_j) && (transition_matrix[s_i + s_j * model->nstates] > 0))
+
3459  {
+
3460  transition_matrix[s_j + s_j * model->nstates] +=
+
3461  transition_matrix[s_i + s_j * model->nstates];
+
3462 
+
3463  transition_matrix[s_i + s_j * model->nstates] = 0;
+
3464  }
+
3465 
+
3466  }
+
3467 
+
3468  }
3469 
-
3470  // Generating the hash
-
3471  std::vector< int > hash = seq_hasher(*v.get_sequence());
-
3472 
-
3473  epiworld_fast_uint new_id = virus_id.size();
-
3474  virus_id[hash] = new_id;
-
3475  virus_name.push_back(v.get_name());
-
3476  virus_sequence.push_back(*v.get_sequence());
-
3477  virus_origin_date.push_back(model->today());
-
3478 
-
3479  virus_parent_id.push_back(v.get_id()); // Must be -99
-
3480 
-
3481  today_virus.push_back({});
-
3482  today_virus[new_id].resize(model->nstates, 0);
-
3483 
-
3484  // Updating the variant
-
3485  v.set_id(new_id);
-
3486  v.set_date(model->today());
-
3487 
-
3488  today_total_nviruses_active++;
-
3489 
-
3490  } else { // In this case, the virus is already on record, need to make sure
-
3491  // The new sequence is new.
-
3492 
-
3493  // Updating registry
-
3494  std::vector< int > hash = seq_hasher(*v.get_sequence());
-
3495  epiworld_fast_uint old_id = v.get_id();
-
3496  epiworld_fast_uint new_id;
-
3497 
-
3498  // If the sequence is new, then it means that the
-
3499  if (virus_id.find(hash) == virus_id.end())
-
3500  {
-
3501 
-
3502  new_id = virus_id.size();
-
3503  virus_id[hash] = new_id;
-
3504  virus_name.push_back(v.get_name());
-
3505  virus_sequence.push_back(*v.get_sequence());
-
3506  virus_origin_date.push_back(model->today());
-
3507 
-
3508  virus_parent_id.push_back(old_id);
-
3509 
-
3510  today_virus.push_back({});
-
3511  today_virus[new_id].resize(model->nstates, 0);
-
3512 
-
3513  // Updating the variant
-
3514  v.set_id(new_id);
-
3515  v.set_date(model->today());
-
3516 
-
3517  today_total_nviruses_active++;
-
3518 
-
3519  } else {
-
3520 
-
3521  // Finding the id
-
3522  new_id = virus_id[hash];
-
3523 
-
3524  // Reflecting the change
-
3525  v.set_id(new_id);
-
3526  v.set_date(virus_origin_date[new_id]);
+
3470  #ifdef EPI_DEBUG
+
3471  for (size_t s_i = 0u; s_i < model->nstates; ++s_i)
+
3472  {
+
3473  if (transition_matrix[s_i + s_i * model->nstates] !=
+
3474  today_total[s_i])
+
3475  throw std::logic_error(
+
3476  "The diagonal of the updated transition Matrix should match the daily totals"
+
3477  );
+
3478  }
+
3479  #endif
+
3480 
+
3481  }
+
3482 
+
3483 }
+
3484 
+
3485 template<typename TSeq>
+
3486 inline void DataBase<TSeq>::record_virus(Virus<TSeq> & v)
+
3487 {
+
3488 
+
3489  // If no sequence, then need to add one. This is regardless of the case
+
3490  if (v.get_sequence() == nullptr)
+
3491  v.set_sequence(default_sequence<TSeq>(
+
3492  static_cast<int>(virus_name.size())
+
3493  ));
+
3494 
+
3495  // Negative id -> virus hasn't been recorded
+
3496  if (v.get_id() < 0)
+
3497  {
+
3498 
+
3499 
+
3500  // Generating the hash
+
3501  std::vector< int > hash = seq_hasher(*v.get_sequence());
+
3502 
+
3503  epiworld_fast_uint new_id = virus_id.size();
+
3504  virus_id[hash] = new_id;
+
3505  virus_name.push_back(v.get_name());
+
3506  virus_sequence.push_back(*v.get_sequence());
+
3507  virus_origin_date.push_back(model->today());
+
3508 
+
3509  virus_parent_id.push_back(v.get_id()); // Must be -99
+
3510 
+
3511  today_virus.push_back({});
+
3512  today_virus[new_id].resize(model->nstates, 0);
+
3513 
+
3514  // Updating the variant
+
3515  v.set_id(new_id);
+
3516  v.set_date(model->today());
+
3517 
+
3518  today_total_nviruses_active++;
+
3519 
+
3520  } else { // In this case, the virus is already on record, need to make sure
+
3521  // The new sequence is new.
+
3522 
+
3523  // Updating registry
+
3524  std::vector< int > hash = seq_hasher(*v.get_sequence());
+
3525  epiworld_fast_uint old_id = v.get_id();
+
3526  epiworld_fast_uint new_id;
3527 
-
3528  }
-
3529 
-
3530  // Moving statistics (only if we are affecting an individual)
-
3531  if (v.get_agent() != nullptr)
-
3532  {
-
3533  // Correcting math
-
3534  epiworld_fast_uint tmp_state = v.get_agent()->get_state();
-
3535  today_virus[old_id][tmp_state]--;
-
3536  today_virus[new_id][tmp_state]++;
-
3537 
-
3538  }
-
3539 
-
3540  }
-
3541 
-
3542  return;
-
3543 
-
3544 }
-
3545 
-
3546 template<typename TSeq>
-
3547 inline void DataBase<TSeq>::record_tool(Tool<TSeq> & t)
-
3548 {
-
3549 
-
3550  if (t.get_sequence() == nullptr)
-
3551  t.set_sequence(default_sequence<TSeq>(
-
3552  static_cast<int>(tool_name.size())
-
3553  ));
-
3554 
-
3555  if (t.get_id() < 0)
-
3556  {
+
3528  // If the sequence is new, then it means that the
+
3529  if (virus_id.find(hash) == virus_id.end())
+
3530  {
+
3531 
+
3532  new_id = virus_id.size();
+
3533  virus_id[hash] = new_id;
+
3534  virus_name.push_back(v.get_name());
+
3535  virus_sequence.push_back(*v.get_sequence());
+
3536  virus_origin_date.push_back(model->today());
+
3537 
+
3538  virus_parent_id.push_back(old_id);
+
3539 
+
3540  today_virus.push_back({});
+
3541  today_virus[new_id].resize(model->nstates, 0);
+
3542 
+
3543  // Updating the variant
+
3544  v.set_id(new_id);
+
3545  v.set_date(model->today());
+
3546 
+
3547  today_total_nviruses_active++;
+
3548 
+
3549  } else {
+
3550 
+
3551  // Finding the id
+
3552  new_id = virus_id[hash];
+
3553 
+
3554  // Reflecting the change
+
3555  v.set_id(new_id);
+
3556  v.set_date(virus_origin_date[new_id]);
3557 
-
3558  std::vector< int > hash = seq_hasher(*t.get_sequence());
-
3559  epiworld_fast_uint new_id = tool_id.size();
-
3560  tool_id[hash] = new_id;
-
3561  tool_name.push_back(t.get_name());
-
3562  tool_sequence.push_back(*t.get_sequence());
-
3563  tool_origin_date.push_back(model->today());
-
3564 
-
3565  today_tool.push_back({});
-
3566  today_tool[new_id].resize(model->nstates, 0);
+
3558  }
+
3559 
+
3560  // Moving statistics (only if we are affecting an individual)
+
3561  if (v.get_agent() != nullptr)
+
3562  {
+
3563  // Correcting math
+
3564  epiworld_fast_uint tmp_state = v.get_agent()->get_state();
+
3565  today_virus[old_id][tmp_state]--;
+
3566  today_virus[new_id][tmp_state]++;
3567 
-
3568  // Updating the tool
-
3569  t.set_id(new_id);
-
3570  t.set_date(model->today());
-
3571 
-
3572  } else {
+
3568  }
+
3569 
+
3570  }
+
3571 
+
3572  return;
3573 
-
3574  // Updating registry
-
3575  std::vector< int > hash = seq_hasher(*t.get_sequence());
-
3576  epiworld_fast_uint old_id = t.get_id();
-
3577  epiworld_fast_uint new_id;
-
3578 
-
3579  if (tool_id.find(hash) == tool_id.end())
-
3580  {
-
3581 
-
3582  new_id = tool_id.size();
-
3583  tool_id[hash] = new_id;
-
3584  tool_name.push_back(t.get_name());
-
3585  tool_sequence.push_back(*t.get_sequence());
-
3586  tool_origin_date.push_back(model->today());
-
3587 
-
3588  today_tool.push_back({});
-
3589  today_tool[new_id].resize(model->nstates, 0);
-
3590 
-
3591  // Updating the tool
-
3592  t.set_id(new_id);
-
3593  t.set_date(model->today());
-
3594 
-
3595  } else {
-
3596 
-
3597  // Finding the id
-
3598  new_id = tool_id[hash];
-
3599 
-
3600  // Reflecting the change
-
3601  t.set_id(new_id);
-
3602  t.set_date(tool_origin_date[new_id]);
+
3574 }
+
3575 
+
3576 template<typename TSeq>
+
3577 inline void DataBase<TSeq>::record_tool(Tool<TSeq> & t)
+
3578 {
+
3579 
+
3580  if (t.get_sequence() == nullptr)
+
3581  t.set_sequence(default_sequence<TSeq>(
+
3582  static_cast<int>(tool_name.size())
+
3583  ));
+
3584 
+
3585  if (t.get_id() < 0)
+
3586  {
+
3587 
+
3588  std::vector< int > hash = seq_hasher(*t.get_sequence());
+
3589  epiworld_fast_uint new_id = tool_id.size();
+
3590  tool_id[hash] = new_id;
+
3591  tool_name.push_back(t.get_name());
+
3592  tool_sequence.push_back(*t.get_sequence());
+
3593  tool_origin_date.push_back(model->today());
+
3594 
+
3595  today_tool.push_back({});
+
3596  today_tool[new_id].resize(model->nstates, 0);
+
3597 
+
3598  // Updating the tool
+
3599  t.set_id(new_id);
+
3600  t.set_date(model->today());
+
3601 
+
3602  } else {
3603 
-
3604  }
-
3605 
-
3606  // Moving statistics (only if we are affecting an individual)
-
3607  if (t.get_agent() != nullptr)
-
3608  {
-
3609  // Correcting math
-
3610  epiworld_fast_uint tmp_state = t.get_agent()->get_state();
-
3611  today_tool[old_id][tmp_state]--;
-
3612  today_tool[new_id][tmp_state]++;
-
3613 
-
3614  }
-
3615 
-
3616  }
-
3617 
-
3618 
-
3619 
-
3620  return;
-
3621 }
-
3622 
-
3623 template<typename TSeq>
-
3624 inline size_t DataBase<TSeq>::size() const
-
3625 {
-
3626  return virus_id.size();
-
3627 }
-
3628 
-
3629 template<typename TSeq>
-
3630 inline void DataBase<TSeq>::update_state(
-
3631  epiworld_fast_uint prev_state,
-
3632  epiworld_fast_uint new_state,
-
3633  bool undo
-
3634 ) {
+
3604  // Updating registry
+
3605  std::vector< int > hash = seq_hasher(*t.get_sequence());
+
3606  epiworld_fast_uint old_id = t.get_id();
+
3607  epiworld_fast_uint new_id;
+
3608 
+
3609  if (tool_id.find(hash) == tool_id.end())
+
3610  {
+
3611 
+
3612  new_id = tool_id.size();
+
3613  tool_id[hash] = new_id;
+
3614  tool_name.push_back(t.get_name());
+
3615  tool_sequence.push_back(*t.get_sequence());
+
3616  tool_origin_date.push_back(model->today());
+
3617 
+
3618  today_tool.push_back({});
+
3619  today_tool[new_id].resize(model->nstates, 0);
+
3620 
+
3621  // Updating the tool
+
3622  t.set_id(new_id);
+
3623  t.set_date(model->today());
+
3624 
+
3625  } else {
+
3626 
+
3627  // Finding the id
+
3628  new_id = tool_id[hash];
+
3629 
+
3630  // Reflecting the change
+
3631  t.set_id(new_id);
+
3632  t.set_date(tool_origin_date[new_id]);
+
3633 
+
3634  }
3635 
-
3636  if (undo)
-
3637  {
-
3638 
-
3639  today_total[prev_state]++;
-
3640  today_total[new_state]--;
-
3641 
-
3642  } else {
+
3636  // Moving statistics (only if we are affecting an individual)
+
3637  if (t.get_agent() != nullptr)
+
3638  {
+
3639  // Correcting math
+
3640  epiworld_fast_uint tmp_state = t.get_agent()->get_state();
+
3641  today_tool[old_id][tmp_state]--;
+
3642  today_tool[new_id][tmp_state]++;
3643 
-
3644  today_total[prev_state]--;
-
3645  today_total[new_state]++;
-
3646 
-
3647  }
-
3648 
-
3649  record_transition(prev_state, new_state, undo);
-
3650 
-
3651  return;
-
3652 }
-
3653 
-
3654 template<typename TSeq>
-
3655 inline void DataBase<TSeq>::update_virus(
-
3656  epiworld_fast_uint virus_id,
-
3657  epiworld_fast_uint prev_state,
-
3658  epiworld_fast_uint new_state
-
3659 ) {
-
3660 
-
3661  today_virus[virus_id][prev_state]--;
-
3662  today_virus[virus_id][new_state]++;
-
3663 
-
3664  return;
-
3665 
-
3666 }
-
3667 
-
3668 template<typename TSeq>
-
3669 inline void DataBase<TSeq>::update_tool(
-
3670  epiworld_fast_uint tool_id,
-
3671  epiworld_fast_uint prev_state,
-
3672  epiworld_fast_uint new_state
-
3673 ) {
-
3674 
-
3675 
-
3676  today_tool[tool_id][prev_state]--;
-
3677  today_tool[tool_id][new_state]++;
+
3644  }
+
3645 
+
3646  }
+
3647 
+
3648 
+
3649 
+
3650  return;
+
3651 }
+
3652 
+
3653 template<typename TSeq>
+
3654 inline size_t DataBase<TSeq>::size() const
+
3655 {
+
3656  return virus_id.size();
+
3657 }
+
3658 
+
3659 template<typename TSeq>
+
3660 inline void DataBase<TSeq>::update_state(
+
3661  epiworld_fast_uint prev_state,
+
3662  epiworld_fast_uint new_state,
+
3663  bool undo
+
3664 ) {
+
3665 
+
3666  if (undo)
+
3667  {
+
3668 
+
3669  today_total[prev_state]++;
+
3670  today_total[new_state]--;
+
3671 
+
3672  } else {
+
3673 
+
3674  today_total[prev_state]--;
+
3675  today_total[new_state]++;
+
3676 
+
3677  }
3678 
-
3679  return;
-
3680 
-
3681 }
-
3682 
-
3683 template<typename TSeq>
-
3684 inline void DataBase<TSeq>::record_transition(
-
3685  epiworld_fast_uint from,
-
3686  epiworld_fast_uint to,
-
3687  bool undo
-
3688 ) {
-
3689 
-
3690  if (undo)
-
3691  {
-
3692 
-
3693  transition_matrix[to * model->nstates + from]--;
-
3694  transition_matrix[from * model->nstates + from]++;
-
3695 
-
3696  } else {
+
3679  record_transition(prev_state, new_state, undo);
+
3680 
+
3681  return;
+
3682 }
+
3683 
+
3684 template<typename TSeq>
+
3685 inline void DataBase<TSeq>::update_virus(
+
3686  epiworld_fast_uint virus_id,
+
3687  epiworld_fast_uint prev_state,
+
3688  epiworld_fast_uint new_state
+
3689 ) {
+
3690 
+
3691  today_virus[virus_id][prev_state]--;
+
3692  today_virus[virus_id][new_state]++;
+
3693 
+
3694  return;
+
3695 
+
3696 }
3697 
-
3698  transition_matrix[to * model->nstates + from]++;
-
3699  transition_matrix[from * model->nstates + from]--;
-
3700 
-
3701  }
-
3702 
-
3703  #ifdef EPI_DEBUG
-
3704  if (transition_matrix[from * model->nstates + from] < 0)
-
3705  throw std::logic_error("An entry in transition matrix is negative.");
-
3706  #endif
-
3707 
-
3708 }
-
3709 
-
3710 template<typename TSeq>
-
3711 inline int DataBase<TSeq>::get_today_total(
-
3712  std::string what
-
3713 ) const
-
3714 {
-
3715 
-
3716  for (auto i = 0u; i < model->states_labels.size(); ++i)
-
3717  {
-
3718  if (model->states_labels[i] == what)
-
3719  return today_total[i];
-
3720  }
-
3721 
-
3722  throw std::range_error("The value '" + what + "' is not in the model.");
-
3723 
-
3724 }
+
3698 template<typename TSeq>
+
3699 inline void DataBase<TSeq>::update_tool(
+
3700  epiworld_fast_uint tool_id,
+
3701  epiworld_fast_uint prev_state,
+
3702  epiworld_fast_uint new_state
+
3703 ) {
+
3704 
+
3705 
+
3706  today_tool[tool_id][prev_state]--;
+
3707  today_tool[tool_id][new_state]++;
+
3708 
+
3709  return;
+
3710 
+
3711 }
+
3712 
+
3713 template<typename TSeq>
+
3714 inline void DataBase<TSeq>::record_transition(
+
3715  epiworld_fast_uint from,
+
3716  epiworld_fast_uint to,
+
3717  bool undo
+
3718 ) {
+
3719 
+
3720  if (undo)
+
3721  {
+
3722 
+
3723  transition_matrix[to * model->nstates + from]--;
+
3724  transition_matrix[from * model->nstates + from]++;
3725 
-
3726 template<typename TSeq>
-
3727 inline void DataBase<TSeq>::get_today_total(
-
3728  std::vector< std::string > * state,
-
3729  std::vector< int > * counts
-
3730 ) const
-
3731 {
-
3732  if (state != nullptr)
-
3733  (*state) = model->states_labels;
-
3734 
-
3735  if (counts != nullptr)
-
3736  *counts = today_total;
+
3726  } else {
+
3727 
+
3728  transition_matrix[to * model->nstates + from]++;
+
3729  transition_matrix[from * model->nstates + from]--;
+
3730 
+
3731  }
+
3732 
+
3733  #ifdef EPI_DEBUG
+
3734  if (transition_matrix[from * model->nstates + from] < 0)
+
3735  throw std::logic_error("An entry in transition matrix is negative.");
+
3736  #endif
3737 
3738 }
3739 
3740 template<typename TSeq>
-
3741 inline void DataBase<TSeq>::get_today_virus(
-
3742  std::vector< std::string > & state,
-
3743  std::vector< int > & id,
-
3744  std::vector< int > & counts
-
3745  ) const
-
3746 {
-
3747 
-
3748  state.resize(today_virus.size(), "");
-
3749  id.resize(today_virus.size(), 0);
-
3750  counts.resize(today_virus.size(),0);
+
3741 inline int DataBase<TSeq>::get_today_total(
+
3742  std::string what
+
3743 ) const
+
3744 {
+
3745 
+
3746  for (auto i = 0u; i < model->states_labels.size(); ++i)
+
3747  {
+
3748  if (model->states_labels[i] == what)
+
3749  return today_total[i];
+
3750  }
3751 
-
3752  int n = 0u;
-
3753  for (epiworld_fast_uint v = 0u; v < today_virus.size(); ++v)
-
3754  for (epiworld_fast_uint s = 0u; s < model->states_labels.size(); ++s)
-
3755  {
-
3756  state[n] = model->states_labels[s];
-
3757  id[n] = static_cast<int>(v);
-
3758  counts[n++] = today_virus[v][s];
-
3759 
-
3760  }
-
3761 
-
3762 }
-
3763 
-
3764 template<typename TSeq>
-
3765 inline void DataBase<TSeq>::get_hist_total(
-
3766  std::vector< int > * date,
-
3767  std::vector< std::string > * state,
-
3768  std::vector< int > * counts
-
3769 ) const
-
3770 {
-
3771 
-
3772  if (date != nullptr)
-
3773  *date = hist_total_date;
-
3774 
-
3775  if (state != nullptr)
-
3776  {
-
3777  state->resize(hist_total_state.size(), "");
-
3778  for (epiworld_fast_uint i = 0u; i < hist_total_state.size(); ++i)
-
3779  state->operator[](i) = model->states_labels[hist_total_state[i]];
-
3780  }
+
3752  throw std::range_error("The value '" + what + "' is not in the model.");
+
3753 
+
3754 }
+
3755 
+
3756 template<typename TSeq>
+
3757 inline void DataBase<TSeq>::get_today_total(
+
3758  std::vector< std::string > * state,
+
3759  std::vector< int > * counts
+
3760 ) const
+
3761 {
+
3762  if (state != nullptr)
+
3763  (*state) = model->states_labels;
+
3764 
+
3765  if (counts != nullptr)
+
3766  *counts = today_total;
+
3767 
+
3768 }
+
3769 
+
3770 template<typename TSeq>
+
3771 inline void DataBase<TSeq>::get_today_virus(
+
3772  std::vector< std::string > & state,
+
3773  std::vector< int > & id,
+
3774  std::vector< int > & counts
+
3775  ) const
+
3776 {
+
3777 
+
3778  state.resize(today_virus.size(), "");
+
3779  id.resize(today_virus.size(), 0);
+
3780  counts.resize(today_virus.size(),0);
3781 
-
3782  if (counts != nullptr)
-
3783  *counts = hist_total_counts;
-
3784 
-
3785  return;
-
3786 
-
3787 }
-
3788 
-
3789 template<typename TSeq>
-
3790 inline void DataBase<TSeq>::get_hist_virus(
-
3791  std::vector< int > & date,
-
3792  std::vector< int > & id,
-
3793  std::vector< std::string > & state,
-
3794  std::vector< int > & counts
-
3795 ) const {
-
3796 
-
3797  date = hist_virus_date;
-
3798  std::vector< std::string > labels;
-
3799  labels = model->states_labels;
-
3800 
-
3801  id = hist_virus_id;
-
3802  state.resize(hist_virus_state.size(), "");
-
3803  for (epiworld_fast_uint i = 0u; i < hist_virus_state.size(); ++i)
-
3804  state[i] = labels[hist_virus_state[i]];
-
3805 
-
3806  counts = hist_virus_counts;
-
3807 
-
3808  return;
-
3809 
-
3810 }
+
3782  int n = 0u;
+
3783  for (epiworld_fast_uint v = 0u; v < today_virus.size(); ++v)
+
3784  for (epiworld_fast_uint s = 0u; s < model->states_labels.size(); ++s)
+
3785  {
+
3786  state[n] = model->states_labels[s];
+
3787  id[n] = static_cast<int>(v);
+
3788  counts[n++] = today_virus[v][s];
+
3789 
+
3790  }
+
3791 
+
3792 }
+
3793 
+
3794 template<typename TSeq>
+
3795 inline void DataBase<TSeq>::get_hist_total(
+
3796  std::vector< int > * date,
+
3797  std::vector< std::string > * state,
+
3798  std::vector< int > * counts
+
3799 ) const
+
3800 {
+
3801 
+
3802  if (date != nullptr)
+
3803  *date = hist_total_date;
+
3804 
+
3805  if (state != nullptr)
+
3806  {
+
3807  state->resize(hist_total_state.size(), "");
+
3808  for (epiworld_fast_uint i = 0u; i < hist_total_state.size(); ++i)
+
3809  state->operator[](i) = model->states_labels[hist_total_state[i]];
+
3810  }
3811 
-
3812 
-
3813 template<typename TSeq>
-
3814 inline void DataBase<TSeq>::get_hist_tool(
-
3815  std::vector< int > & date,
-
3816  std::vector< int > & id,
-
3817  std::vector< std::string > & state,
-
3818  std::vector< int > & counts
-
3819 ) const {
-
3820 
-
3821  date = hist_tool_date;
-
3822  std::vector< std::string > labels;
-
3823  labels = model->states_labels;
-
3824 
-
3825  id = hist_tool_id;
-
3826  state.resize(hist_tool_state.size(), "");
-
3827  for (size_t i = 0u; i < hist_tool_state.size(); ++i)
-
3828  state[i] = labels[hist_tool_state[i]];
-
3829 
-
3830  counts = hist_tool_counts;
-
3831 
-
3832  return;
-
3833 
-
3834 }
+
3812  if (counts != nullptr)
+
3813  *counts = hist_total_counts;
+
3814 
+
3815  return;
+
3816 
+
3817 }
+
3818 
+
3819 template<typename TSeq>
+
3820 inline void DataBase<TSeq>::get_hist_virus(
+
3821  std::vector< int > & date,
+
3822  std::vector< int > & id,
+
3823  std::vector< std::string > & state,
+
3824  std::vector< int > & counts
+
3825 ) const {
+
3826 
+
3827  date = hist_virus_date;
+
3828  std::vector< std::string > labels;
+
3829  labels = model->states_labels;
+
3830 
+
3831  id = hist_virus_id;
+
3832  state.resize(hist_virus_state.size(), "");
+
3833  for (epiworld_fast_uint i = 0u; i < hist_virus_state.size(); ++i)
+
3834  state[i] = labels[hist_virus_state[i]];
3835 
-
3836 template<typename TSeq>
-
3837 inline void DataBase<TSeq>::get_today_transition_matrix(
-
3838  std::vector< int > & counts
-
3839 ) const
-
3840 {
+
3836  counts = hist_virus_counts;
+
3837 
+
3838  return;
+
3839 
+
3840 }
3841 
-
3842  counts = transition_matrix;
-
3843 
-
3844  return;
-
3845 
-
3846 }
-
3847 
-
3848 template<typename TSeq>
-
3849 inline void DataBase<TSeq>::get_hist_transition_matrix(
-
3850  std::vector< std::string > & state_from,
-
3851  std::vector< std::string > & state_to,
-
3852  std::vector< int > & date,
-
3853  std::vector< int > & counts,
-
3854  bool skip_zeros
-
3855 ) const
-
3856 {
-
3857 
-
3858  size_t n = this->hist_transition_matrix.size();
-
3859 
-
3860  // Clearing the previous vectors
-
3861  state_from.clear();
-
3862  state_to.clear();
-
3863  date.clear();
-
3864  counts.clear();
+
3842 
+
3843 template<typename TSeq>
+
3844 inline void DataBase<TSeq>::get_hist_tool(
+
3845  std::vector< int > & date,
+
3846  std::vector< int > & id,
+
3847  std::vector< std::string > & state,
+
3848  std::vector< int > & counts
+
3849 ) const {
+
3850 
+
3851  date = hist_tool_date;
+
3852  std::vector< std::string > labels;
+
3853  labels = model->states_labels;
+
3854 
+
3855  id = hist_tool_id;
+
3856  state.resize(hist_tool_state.size(), "");
+
3857  for (size_t i = 0u; i < hist_tool_state.size(); ++i)
+
3858  state[i] = labels[hist_tool_state[i]];
+
3859 
+
3860  counts = hist_tool_counts;
+
3861 
+
3862  return;
+
3863 
+
3864 }
3865 
-
3866  // Reserving space
-
3867  state_from.reserve(n);
-
3868  state_to.reserve(n);
-
3869  date.reserve(n);
-
3870  counts.reserve(n);
+
3866 template<typename TSeq>
+
3867 inline void DataBase<TSeq>::get_today_transition_matrix(
+
3868  std::vector< int > & counts
+
3869 ) const
+
3870 {
3871 
-
3872  size_t n_states = model->nstates;
-
3873  size_t n_steps = model->get_ndays();
-
3874 
-
3875  // If n is zero, then we are done
-
3876  if (n == 0u)
-
3877  return;
-
3878 
-
3879  for (size_t step = 0u; step <= n_steps; ++step) // The final step counts
-
3880  {
-
3881  for (size_t j = 0u; j < n_states; ++j) // Column major storage
-
3882  {
-
3883  for (size_t i = 0u; i < n_states; ++i)
-
3884  {
-
3885  // Retrieving the value of the day
-
3886  int v = hist_transition_matrix[
-
3887  step * n_states * n_states + // Day of the data
-
3888  j * n_states + // Column (to)
-
3889  i // Row (from)
-
3890  ];
-
3891 
-
3892  // If we are skipping the zeros and it is zero, then don't save
-
3893  if (skip_zeros && v == 0)
-
3894  continue;
-
3895 
-
3896  state_from.push_back(model->states_labels[i]);
-
3897  state_to.push_back(model->states_labels[j]);
-
3898  date.push_back(hist_total_date[step * n_states]);
-
3899  counts.push_back(v);
-
3900 
-
3901  }
-
3902 
-
3903  }
-
3904  }
-
3905 
-
3906  return;
-
3907 
+
3872  counts = transition_matrix;
+
3873 
+
3874  return;
+
3875 
+
3876 }
+
3877 
+
3878 template<typename TSeq>
+
3879 inline void DataBase<TSeq>::get_hist_transition_matrix(
+
3880  std::vector< std::string > & state_from,
+
3881  std::vector< std::string > & state_to,
+
3882  std::vector< int > & date,
+
3883  std::vector< int > & counts,
+
3884  bool skip_zeros
+
3885 ) const
+
3886 {
+
3887 
+
3888  size_t n = this->hist_transition_matrix.size();
+
3889 
+
3890  // Clearing the previous vectors
+
3891  state_from.clear();
+
3892  state_to.clear();
+
3893  date.clear();
+
3894  counts.clear();
+
3895 
+
3896  // Reserving space
+
3897  state_from.reserve(n);
+
3898  state_to.reserve(n);
+
3899  date.reserve(n);
+
3900  counts.reserve(n);
+
3901 
+
3902  size_t n_states = model->nstates;
+
3903  size_t n_steps = model->get_ndays();
+
3904 
+
3905  // If n is zero, then we are done
+
3906  if (n == 0u)
+
3907  return;
3908 
-
3909 }
-
3910 
-
3911 template<typename TSeq>
-
3912 inline void DataBase<TSeq>::get_transmissions(
-
3913  std::vector<int> & date,
-
3914  std::vector<int> & source,
-
3915  std::vector<int> & target,
-
3916  std::vector<int> & virus,
-
3917  std::vector<int> & source_exposure_date
-
3918 ) const
-
3919 {
-
3920 
-
3921  size_t nevents = transmission_date.size();
-
3922 
-
3923  date.resize(nevents);
-
3924  source.resize(nevents);
-
3925  target.resize(nevents);
-
3926  virus.resize(nevents);
-
3927  source_exposure_date.resize(nevents);
-
3928 
-
3929  get_transmissions(
-
3930  &date[0u],
-
3931  &source[0u],
-
3932  &target[0u],
-
3933  &virus[0u],
-
3934  &source_exposure_date[0u]
-
3935  );
-
3936 
-
3937 }
+
3909  for (size_t step = 0u; step <= n_steps; ++step) // The final step counts
+
3910  {
+
3911  for (size_t j = 0u; j < n_states; ++j) // Column major storage
+
3912  {
+
3913  for (size_t i = 0u; i < n_states; ++i)
+
3914  {
+
3915  // Retrieving the value of the day
+
3916  int v = hist_transition_matrix[
+
3917  step * n_states * n_states + // Day of the data
+
3918  j * n_states + // Column (to)
+
3919  i // Row (from)
+
3920  ];
+
3921 
+
3922  // If we are skipping the zeros and it is zero, then don't save
+
3923  if (skip_zeros && v == 0)
+
3924  continue;
+
3925 
+
3926  state_from.push_back(model->states_labels[i]);
+
3927  state_to.push_back(model->states_labels[j]);
+
3928  date.push_back(hist_total_date[step * n_states]);
+
3929  counts.push_back(v);
+
3930 
+
3931  }
+
3932 
+
3933  }
+
3934  }
+
3935 
+
3936  return;
+
3937 
3938 
-
3939 template<typename TSeq>
-
3940 inline void DataBase<TSeq>::get_transmissions(
-
3941  int * date,
-
3942  int * source,
-
3943  int * target,
-
3944  int * virus,
-
3945  int * source_exposure_date
-
3946 ) const
-
3947 {
-
3948 
-
3949  size_t nevents = transmission_date.size();
+
3939 }
+
3940 
+
3941 template<typename TSeq>
+
3942 inline void DataBase<TSeq>::get_transmissions(
+
3943  std::vector<int> & date,
+
3944  std::vector<int> & source,
+
3945  std::vector<int> & target,
+
3946  std::vector<int> & virus,
+
3947  std::vector<int> & source_exposure_date
+
3948 ) const
+
3949 {
3950 
-
3951  for (size_t i = 0u; i < nevents; ++i)
-
3952  {
-
3953 
-
3954  *(date + i) = transmission_date.at(i);
-
3955  *(source + i) = transmission_source.at(i);
-
3956  *(target + i) = transmission_target.at(i);
-
3957  *(virus + i) = transmission_virus.at(i);
-
3958  *(source_exposure_date + i) = transmission_source_exposure_date.at(i);
-
3959 
-
3960  }
-
3961 
-
3962 }
-
3963 
-
3964 template<typename TSeq>
-
3965 inline void DataBase<TSeq>::write_data(
-
3966  std::string fn_virus_info,
-
3967  std::string fn_virus_hist,
-
3968  std::string fn_tool_info,
-
3969  std::string fn_tool_hist,
-
3970  std::string fn_total_hist,
-
3971  std::string fn_transmission,
-
3972  std::string fn_transition,
-
3973  std::string fn_reproductive_number,
-
3974  std::string fn_generation_time
-
3975 ) const
-
3976 {
-
3977 
-
3978  if (fn_virus_info != "")
-
3979  {
-
3980  std::ofstream file_virus_info(fn_virus_info, std::ios_base::out);
-
3981 
-
3982  // Check if the file exists and throw an error if it doesn't
-
3983  if (!file_virus_info)
-
3984  {
-
3985  throw std::runtime_error(
-
3986  "Could not open file \"" + fn_virus_info +
-
3987  "\" for writing.")
-
3988  ;
-
3989  }
-
3990 
+
3951  size_t nevents = transmission_date.size();
+
3952 
+
3953  date.resize(nevents);
+
3954  source.resize(nevents);
+
3955  target.resize(nevents);
+
3956  virus.resize(nevents);
+
3957  source_exposure_date.resize(nevents);
+
3958 
+
3959  get_transmissions(
+
3960  &date[0u],
+
3961  &source[0u],
+
3962  &target[0u],
+
3963  &virus[0u],
+
3964  &source_exposure_date[0u]
+
3965  );
+
3966 
+
3967 }
+
3968 
+
3969 template<typename TSeq>
+
3970 inline void DataBase<TSeq>::get_transmissions(
+
3971  int * date,
+
3972  int * source,
+
3973  int * target,
+
3974  int * virus,
+
3975  int * source_exposure_date
+
3976 ) const
+
3977 {
+
3978 
+
3979  size_t nevents = transmission_date.size();
+
3980 
+
3981  for (size_t i = 0u; i < nevents; ++i)
+
3982  {
+
3983 
+
3984  *(date + i) = transmission_date.at(i);
+
3985  *(source + i) = transmission_source.at(i);
+
3986  *(target + i) = transmission_target.at(i);
+
3987  *(virus + i) = transmission_virus.at(i);
+
3988  *(source_exposure_date + i) = transmission_source_exposure_date.at(i);
+
3989 
+
3990  }
3991 
-
3992  file_virus_info <<
-
3993  #ifdef EPI_DEBUG
-
3994  "thread" << "virus_id " << "virus " << "virus_sequence " << "date_recorded " << "parent\n";
-
3995  #else
-
3996  "virus_id " << "virus " << "virus_sequence " << "date_recorded " << "parent\n";
-
3997  #endif
-
3998 
-
3999  for (const auto & v : virus_id)
-
4000  {
-
4001  int id = v.second;
-
4002  file_virus_info <<
-
4003  #ifdef EPI_DEBUG
-
4004  EPI_GET_THREAD_ID() << " " <<
-
4005  #endif
-
4006  id << " \"" <<
-
4007  virus_name[id] << "\" " <<
-
4008  seq_writer(virus_sequence[id]) << " " <<
-
4009  virus_origin_date[id] << " " <<
-
4010  virus_parent_id[id] << "\n";
-
4011  }
-
4012 
-
4013  }
-
4014 
-
4015  if (fn_virus_hist != "")
-
4016  {
-
4017  std::ofstream file_virus(fn_virus_hist, std::ios_base::out);
-
4018 
-
4019  // Repeat the same error if the file doesn't exists
-
4020  if (!file_virus)
-
4021  {
-
4022  throw std::runtime_error(
-
4023  "Could not open file \"" + fn_virus_hist +
-
4024  "\" for writing.")
-
4025  ;
-
4026  }
-
4027 
-
4028  file_virus <<
-
4029  #ifdef EPI_DEBUG
-
4030  "thread "<< "date " << "virus_id " << "virus " << "state " << "n\n";
-
4031  #else
-
4032  "date " << "virus_id " << "virus " << "state " << "n\n";
-
4033  #endif
-
4034 
-
4035  for (epiworld_fast_uint i = 0; i < hist_virus_id.size(); ++i)
-
4036  file_virus <<
-
4037  #ifdef EPI_DEBUG
-
4038  EPI_GET_THREAD_ID() << " " <<
-
4039  #endif
-
4040  hist_virus_date[i] << " " <<
-
4041  hist_virus_id[i] << " \"" <<
-
4042  virus_name[hist_virus_id[i]] << "\" " <<
-
4043  model->states_labels[hist_virus_state[i]] << " " <<
-
4044  hist_virus_counts[i] << "\n";
-
4045  }
-
4046 
-
4047  if (fn_tool_info != "")
-
4048  {
-
4049  std::ofstream file_tool_info(fn_tool_info, std::ios_base::out);
-
4050 
-
4051  // Repeat the same error if the file doesn't exists
-
4052  if (!file_tool_info)
-
4053  {
-
4054  throw std::runtime_error(
-
4055  "Could not open file \"" + fn_tool_info +
-
4056  "\" for writing.")
-
4057  ;
-
4058  }
-
4059 
-
4060  file_tool_info <<
-
4061  #ifdef EPI_DEBUG
-
4062  "thread " <<
+
3992 }
+
3993 
+
3994 template<typename TSeq>
+
3995 inline void DataBase<TSeq>::write_data(
+
3996  std::string fn_virus_info,
+
3997  std::string fn_virus_hist,
+
3998  std::string fn_tool_info,
+
3999  std::string fn_tool_hist,
+
4000  std::string fn_total_hist,
+
4001  std::string fn_transmission,
+
4002  std::string fn_transition,
+
4003  std::string fn_reproductive_number,
+
4004  std::string fn_generation_time
+
4005 ) const
+
4006 {
+
4007 
+
4008  if (fn_virus_info != "")
+
4009  {
+
4010  std::ofstream file_virus_info(fn_virus_info, std::ios_base::out);
+
4011 
+
4012  // Check if the file exists and throw an error if it doesn't
+
4013  if (!file_virus_info)
+
4014  {
+
4015  throw std::runtime_error(
+
4016  "Could not open file \"" + fn_virus_info +
+
4017  "\" for writing.")
+
4018  ;
+
4019  }
+
4020 
+
4021 
+
4022  file_virus_info <<
+
4023  #ifdef EPI_DEBUG
+
4024  "thread" << "virus_id " << "virus " << "virus_sequence " << "date_recorded " << "parent\n";
+
4025  #else
+
4026  "virus_id " << "virus " << "virus_sequence " << "date_recorded " << "parent\n";
+
4027  #endif
+
4028 
+
4029  for (const auto & v : virus_id)
+
4030  {
+
4031  int id = v.second;
+
4032  file_virus_info <<
+
4033  #ifdef EPI_DEBUG
+
4034  EPI_GET_THREAD_ID() << " " <<
+
4035  #endif
+
4036  id << " \"" <<
+
4037  virus_name[id] << "\" " <<
+
4038  seq_writer(virus_sequence[id]) << " " <<
+
4039  virus_origin_date[id] << " " <<
+
4040  virus_parent_id[id] << "\n";
+
4041  }
+
4042 
+
4043  }
+
4044 
+
4045  if (fn_virus_hist != "")
+
4046  {
+
4047  std::ofstream file_virus(fn_virus_hist, std::ios_base::out);
+
4048 
+
4049  // Repeat the same error if the file doesn't exists
+
4050  if (!file_virus)
+
4051  {
+
4052  throw std::runtime_error(
+
4053  "Could not open file \"" + fn_virus_hist +
+
4054  "\" for writing.")
+
4055  ;
+
4056  }
+
4057 
+
4058  file_virus <<
+
4059  #ifdef EPI_DEBUG
+
4060  "thread "<< "date " << "virus_id " << "virus " << "state " << "n\n";
+
4061  #else
+
4062  "date " << "virus_id " << "virus " << "state " << "n\n";
4063  #endif
-
4064  "id " << "tool_name " << "tool_sequence " << "date_recorded\n";
-
4065 
-
4066  for (const auto & t : tool_id)
-
4067  {
-
4068  int id = t.second;
-
4069  file_tool_info <<
-
4070  #ifdef EPI_DEBUG
-
4071  EPI_GET_THREAD_ID() << " " <<
-
4072  #endif
-
4073  id << " \"" <<
-
4074  tool_name[id] << "\" " <<
-
4075  seq_writer(tool_sequence[id]) << " " <<
-
4076  tool_origin_date[id] << "\n";
-
4077  }
-
4078 
-
4079  }
+
4064 
+
4065  for (epiworld_fast_uint i = 0; i < hist_virus_id.size(); ++i)
+
4066  file_virus <<
+
4067  #ifdef EPI_DEBUG
+
4068  EPI_GET_THREAD_ID() << " " <<
+
4069  #endif
+
4070  hist_virus_date[i] << " " <<
+
4071  hist_virus_id[i] << " \"" <<
+
4072  virus_name[hist_virus_id[i]] << "\" " <<
+
4073  model->states_labels[hist_virus_state[i]] << " " <<
+
4074  hist_virus_counts[i] << "\n";
+
4075  }
+
4076 
+
4077  if (fn_tool_info != "")
+
4078  {
+
4079  std::ofstream file_tool_info(fn_tool_info, std::ios_base::out);
4080 
-
4081  if (fn_tool_hist != "")
-
4082  {
-
4083  std::ofstream file_tool_hist(fn_tool_hist, std::ios_base::out);
-
4084 
-
4085  // Repeat the same error if the file doesn't exists
-
4086  if (!file_tool_hist)
-
4087  {
-
4088  throw std::runtime_error(
-
4089  "Could not open file \"" + fn_tool_hist +
-
4090  "\" for writing.")
-
4091  ;
-
4092  }
-
4093 
-
4094  file_tool_hist <<
-
4095  #ifdef EPI_DEBUG
-
4096  "thread " <<
-
4097  #endif
-
4098  "date " << "id " << "state " << "n\n";
-
4099 
-
4100  for (epiworld_fast_uint i = 0; i < hist_tool_id.size(); ++i)
-
4101  file_tool_hist <<
-
4102  #ifdef EPI_DEBUG
-
4103  EPI_GET_THREAD_ID() << " " <<
-
4104  #endif
-
4105  hist_tool_date[i] << " " <<
-
4106  hist_tool_id[i] << " " <<
-
4107  model->states_labels[hist_tool_state[i]] << " " <<
-
4108  hist_tool_counts[i] << "\n";
+
4081  // Repeat the same error if the file doesn't exists
+
4082  if (!file_tool_info)
+
4083  {
+
4084  throw std::runtime_error(
+
4085  "Could not open file \"" + fn_tool_info +
+
4086  "\" for writing.")
+
4087  ;
+
4088  }
+
4089 
+
4090  file_tool_info <<
+
4091  #ifdef EPI_DEBUG
+
4092  "thread " <<
+
4093  #endif
+
4094  "id " << "tool_name " << "tool_sequence " << "date_recorded\n";
+
4095 
+
4096  for (const auto & t : tool_id)
+
4097  {
+
4098  int id = t.second;
+
4099  file_tool_info <<
+
4100  #ifdef EPI_DEBUG
+
4101  EPI_GET_THREAD_ID() << " " <<
+
4102  #endif
+
4103  id << " \"" <<
+
4104  tool_name[id] << "\" " <<
+
4105  seq_writer(tool_sequence[id]) << " " <<
+
4106  tool_origin_date[id] << "\n";
+
4107  }
+
4108 
4109  }
4110 
-
4111  if (fn_total_hist != "")
+
4111  if (fn_tool_hist != "")
4112  {
-
4113  std::ofstream file_total(fn_total_hist, std::ios_base::out);
+
4113  std::ofstream file_tool_hist(fn_tool_hist, std::ios_base::out);
4114 
4115  // Repeat the same error if the file doesn't exists
-
4116  if (!file_total)
+
4116  if (!file_tool_hist)
4117  {
4118  throw std::runtime_error(
-
4119  "Could not open file \"" + fn_total_hist +
+
4119  "Could not open file \"" + fn_tool_hist +
4120  "\" for writing.")
4121  ;
4122  }
-
4123 
-
4124  file_total <<
+
4123 
+
4124  file_tool_hist <<
4125  #ifdef EPI_DEBUG
4126  "thread " <<
4127  #endif
-
4128  "date " << "nviruses " << "state " << "counts\n";
+
4128  "date " << "id " << "state " << "n\n";
4129 
-
4130  for (epiworld_fast_uint i = 0; i < hist_total_date.size(); ++i)
-
4131  file_total <<
+
4130  for (epiworld_fast_uint i = 0; i < hist_tool_id.size(); ++i)
+
4131  file_tool_hist <<
4132  #ifdef EPI_DEBUG
4133  EPI_GET_THREAD_ID() << " " <<
4134  #endif
-
4135  hist_total_date[i] << " " <<
-
4136  hist_total_nviruses_active[i] << " \"" <<
-
4137  model->states_labels[hist_total_state[i]] << "\" " <<
-
4138  hist_total_counts[i] << "\n";
+
4135  hist_tool_date[i] << " " <<
+
4136  hist_tool_id[i] << " " <<
+
4137  model->states_labels[hist_tool_state[i]] << " " <<
+
4138  hist_tool_counts[i] << "\n";
4139  }
4140 
-
4141  if (fn_transmission != "")
+
4141  if (fn_total_hist != "")
4142  {
-
4143  std::ofstream file_transmission(fn_transmission, std::ios_base::out);
+
4143  std::ofstream file_total(fn_total_hist, std::ios_base::out);
4144 
4145  // Repeat the same error if the file doesn't exists
-
4146  if (!file_transmission)
+
4146  if (!file_total)
4147  {
4148  throw std::runtime_error(
-
4149  "Could not open file \"" + fn_transmission +
+
4149  "Could not open file \"" + fn_total_hist +
4150  "\" for writing.")
4151  ;
4152  }
4153 
-
4154  file_transmission <<
+
4154  file_total <<
4155  #ifdef EPI_DEBUG
4156  "thread " <<
4157  #endif
-
4158  "date " << "virus_id virus " << "source_exposure_date " << "source " << "target\n";
+
4158  "date " << "nviruses " << "state " << "counts\n";
4159 
-
4160  for (epiworld_fast_uint i = 0; i < transmission_target.size(); ++i)
-
4161  file_transmission <<
+
4160  for (epiworld_fast_uint i = 0; i < hist_total_date.size(); ++i)
+
4161  file_total <<
4162  #ifdef EPI_DEBUG
4163  EPI_GET_THREAD_ID() << " " <<
4164  #endif
-
4165  transmission_date[i] << " " <<
-
4166  transmission_virus[i] << " \"" <<
-
4167  virus_name[transmission_virus[i]] << "\" " <<
-
4168  transmission_source_exposure_date[i] << " " <<
-
4169  transmission_source[i] << " " <<
-
4170  transmission_target[i] << "\n";
-
4171 
-
4172  }
-
4173 
-
4174  if (fn_transition != "")
-
4175  {
-
4176  std::ofstream file_transition(fn_transition, std::ios_base::out);
-
4177 
-
4178  // Repeat the same error if the file doesn't exists
-
4179  if (!file_transition)
-
4180  {
-
4181  throw std::runtime_error(
-
4182  "Could not open file \"" + fn_transition +
-
4183  "\" for writing.")
-
4184  ;
-
4185  }
-
4186 
-
4187  file_transition <<
-
4188  #ifdef EPI_DEBUG
-
4189  "thread " <<
-
4190  #endif
-
4191  "date " << "from " << "to " << "counts\n";
-
4192 
-
4193  int ns = model->nstates;
-
4194 
-
4195  for (int i = 0; i <= model->today(); ++i)
-
4196  {
-
4197 
-
4198  for (int from = 0u; from < ns; ++from)
-
4199  for (int to = 0u; to < ns; ++to)
-
4200  file_transition <<
-
4201  #ifdef EPI_DEBUG
-
4202  EPI_GET_THREAD_ID() << " " <<
-
4203  #endif
-
4204  i << " \"" <<
-
4205  model->states_labels[from] << "\" \"" <<
-
4206  model->states_labels[to] << "\" " <<
-
4207  hist_transition_matrix[i * (ns * ns) + to * ns + from] << "\n";
-
4208 
-
4209  }
-
4210 
-
4211  }
-
4212 
-
4213  if (fn_reproductive_number != "")
-
4214  reproductive_number(fn_reproductive_number);
-
4215 
-
4216  if (fn_generation_time != "")
-
4217  generation_time(fn_generation_time);
-
4218 
-
4219 }
-
4220 
-
4221 template<typename TSeq>
-
4222 inline void DataBase<TSeq>::record_transmission(
-
4223  int i,
-
4224  int j,
-
4225  int virus,
-
4226  int i_expo_date
-
4227 ) {
-
4228 
-
4229  transmission_date.push_back(model->today());
-
4230  transmission_source.push_back(i);
-
4231  transmission_target.push_back(j);
-
4232  transmission_virus.push_back(virus);
-
4233  transmission_source_exposure_date.push_back(i_expo_date);
-
4234 
-
4235 }
-
4236 
-
4237 template<typename TSeq>
-
4238 inline size_t DataBase<TSeq>::get_n_viruses() const
-
4239 {
-
4240  return virus_id.size();
-
4241 }
+
4165  hist_total_date[i] << " " <<
+
4166  hist_total_nviruses_active[i] << " \"" <<
+
4167  model->states_labels[hist_total_state[i]] << "\" " <<
+
4168  hist_total_counts[i] << "\n";
+
4169  }
+
4170 
+
4171  if (fn_transmission != "")
+
4172  {
+
4173  std::ofstream file_transmission(fn_transmission, std::ios_base::out);
+
4174 
+
4175  // Repeat the same error if the file doesn't exists
+
4176  if (!file_transmission)
+
4177  {
+
4178  throw std::runtime_error(
+
4179  "Could not open file \"" + fn_transmission +
+
4180  "\" for writing.")
+
4181  ;
+
4182  }
+
4183 
+
4184  file_transmission <<
+
4185  #ifdef EPI_DEBUG
+
4186  "thread " <<
+
4187  #endif
+
4188  "date " << "virus_id virus " << "source_exposure_date " << "source " << "target\n";
+
4189 
+
4190  for (epiworld_fast_uint i = 0; i < transmission_target.size(); ++i)
+
4191  file_transmission <<
+
4192  #ifdef EPI_DEBUG
+
4193  EPI_GET_THREAD_ID() << " " <<
+
4194  #endif
+
4195  transmission_date[i] << " " <<
+
4196  transmission_virus[i] << " \"" <<
+
4197  virus_name[transmission_virus[i]] << "\" " <<
+
4198  transmission_source_exposure_date[i] << " " <<
+
4199  transmission_source[i] << " " <<
+
4200  transmission_target[i] << "\n";
+
4201 
+
4202  }
+
4203 
+
4204  if (fn_transition != "")
+
4205  {
+
4206  std::ofstream file_transition(fn_transition, std::ios_base::out);
+
4207 
+
4208  // Repeat the same error if the file doesn't exists
+
4209  if (!file_transition)
+
4210  {
+
4211  throw std::runtime_error(
+
4212  "Could not open file \"" + fn_transition +
+
4213  "\" for writing.")
+
4214  ;
+
4215  }
+
4216 
+
4217  file_transition <<
+
4218  #ifdef EPI_DEBUG
+
4219  "thread " <<
+
4220  #endif
+
4221  "date " << "from " << "to " << "counts\n";
+
4222 
+
4223  int ns = model->nstates;
+
4224 
+
4225  for (int i = 0; i <= model->today(); ++i)
+
4226  {
+
4227 
+
4228  for (int from = 0u; from < ns; ++from)
+
4229  for (int to = 0u; to < ns; ++to)
+
4230  file_transition <<
+
4231  #ifdef EPI_DEBUG
+
4232  EPI_GET_THREAD_ID() << " " <<
+
4233  #endif
+
4234  i << " \"" <<
+
4235  model->states_labels[from] << "\" \"" <<
+
4236  model->states_labels[to] << "\" " <<
+
4237  hist_transition_matrix[i * (ns * ns) + to * ns + from] << "\n";
+
4238 
+
4239  }
+
4240 
+
4241  }
4242 
-
4243 template<typename TSeq>
-
4244 inline size_t DataBase<TSeq>::get_n_tools() const
-
4245 {
-
4246  return tool_id.size();
-
4247 }
+
4243  if (fn_reproductive_number != "")
+
4244  reproductive_number(fn_reproductive_number);
+
4245 
+
4246  if (fn_generation_time != "")
+
4247  generation_time(fn_generation_time);
4248 
-
4249 
-
4250 template<typename TSeq>
-
4251 inline void DataBase<TSeq>::set_user_data(
-
4252  std::vector< std::string > names
-
4253 )
-
4254 {
-
4255  user_data = UserData<TSeq>(names);
-
4256  user_data.model = model;
-
4257 }
+
4249 }
+
4250 
+
4251 template<typename TSeq>
+
4252 inline void DataBase<TSeq>::record_transmission(
+
4253  int i,
+
4254  int j,
+
4255  int virus,
+
4256  int i_expo_date
+
4257 ) {
4258 
-
4259 template<typename TSeq>
-
4260 inline void DataBase<TSeq>::add_user_data(
-
4261  std::vector< epiworld_double > x
-
4262 )
-
4263 {
+
4259  transmission_date.push_back(model->today());
+
4260  transmission_source.push_back(i);
+
4261  transmission_target.push_back(j);
+
4262  transmission_virus.push_back(virus);
+
4263  transmission_source_exposure_date.push_back(i_expo_date);
4264 
-
4265  user_data.add(x);
+
4265 }
4266 
-
4267 }
-
4268 
-
4269 template<typename TSeq>
-
4270 inline void DataBase<TSeq>::add_user_data(
-
4271  epiworld_fast_uint k,
-
4272  epiworld_double x
-
4273 )
-
4274 {
-
4275 
-
4276  user_data.add(k, x);
-
4277 
-
4278 }
+
4267 template<typename TSeq>
+
4268 inline size_t DataBase<TSeq>::get_n_viruses() const
+
4269 {
+
4270  return virus_id.size();
+
4271 }
+
4272 
+
4273 template<typename TSeq>
+
4274 inline size_t DataBase<TSeq>::get_n_tools() const
+
4275 {
+
4276  return tool_id.size();
+
4277 }
+
4278 
4279 
4280 template<typename TSeq>
-
4281 inline UserData<TSeq> & DataBase<TSeq>::get_user_data()
-
4282 {
-
4283  return user_data;
-
4284 }
-
4285 
-
4286 template<typename TSeq>
-
4287 inline MapVec_type<int,int> DataBase<TSeq>::reproductive_number()
-
4288 const {
-
4289 
-
4290  // Checking size
-
4291  MapVec_type<int,int> map;
-
4292 
-
4293  // Number of digits of maxid
-
4294  for (size_t i = 0u; i < transmission_date.size(); ++i)
-
4295  {
-
4296  // Fabricating id
-
4297  std::vector< int > h = {
-
4298  transmission_virus[i],
-
4299  transmission_source[i],
-
4300  transmission_source_exposure_date[i]
-
4301  };
-
4302 
-
4303  // Adding to counter
-
4304  if (map.find(h) == map.end())
-
4305  map[h] = 1;
-
4306  else
-
4307  map[h]++;
-
4308 
-
4309  // The target is added
-
4310  std::vector< int > h_target = {
-
4311  transmission_virus[i],
-
4312  transmission_target[i],
-
4313  transmission_date[i]
-
4314  };
+
4281 inline void DataBase<TSeq>::set_user_data(
+
4282  std::vector< std::string > names
+
4283 )
+
4284 {
+
4285  user_data = UserData<TSeq>(names);
+
4286  user_data.model = model;
+
4287 }
+
4288 
+
4289 template<typename TSeq>
+
4290 inline void DataBase<TSeq>::add_user_data(
+
4291  std::vector< epiworld_double > x
+
4292 )
+
4293 {
+
4294 
+
4295  user_data.add(x);
+
4296 
+
4297 }
+
4298 
+
4299 template<typename TSeq>
+
4300 inline void DataBase<TSeq>::add_user_data(
+
4301  epiworld_fast_uint k,
+
4302  epiworld_double x
+
4303 )
+
4304 {
+
4305 
+
4306  user_data.add(k, x);
+
4307 
+
4308 }
+
4309 
+
4310 template<typename TSeq>
+
4311 inline UserData<TSeq> & DataBase<TSeq>::get_user_data()
+
4312 {
+
4313  return user_data;
+
4314 }
4315 
-
4316  map[h_target] = 0;
-
4317 
-
4318  }
+
4316 template<typename TSeq>
+
4317 inline MapVec_type<int,int> DataBase<TSeq>::reproductive_number()
+
4318 const {
4319 
-
4320  return map;
-
4321 
-
4322 }
-
4323 
-
4324 template<typename TSeq>
-
4325 inline void DataBase<TSeq>::reproductive_number(
-
4326  std::string fn
-
4327 ) const {
-
4328 
-
4329 
-
4330  auto map = reproductive_number();
-
4331 
-
4332  std::ofstream fn_file(fn, std::ios_base::out);
-
4333 
-
4334  // Repeat the same error if the file doesn't exists
-
4335  if (!fn_file)
-
4336  {
-
4337  throw std::runtime_error(
-
4338  "Could not open file \"" + fn +
-
4339  "\" for writing.")
-
4340  ;
-
4341  }
-
4342 
-
4343  fn_file <<
-
4344  #ifdef EPI_DEBUG
-
4345  "thread " <<
-
4346  #endif
-
4347  "virus_id virus source source_exposure_date rt\n";
-
4348 
+
4320  // Checking size
+
4321  MapVec_type<int,int> map;
+
4322 
+
4323  // Number of digits of maxid
+
4324  for (size_t i = 0u; i < transmission_date.size(); ++i)
+
4325  {
+
4326  // Fabricating id
+
4327  std::vector< int > h = {
+
4328  transmission_virus[i],
+
4329  transmission_source[i],
+
4330  transmission_source_exposure_date[i]
+
4331  };
+
4332 
+
4333  // Adding to counter
+
4334  if (map.find(h) == map.end())
+
4335  map[h] = 1;
+
4336  else
+
4337  map[h]++;
+
4338 
+
4339  // The target is added
+
4340  std::vector< int > h_target = {
+
4341  transmission_virus[i],
+
4342  transmission_target[i],
+
4343  transmission_date[i]
+
4344  };
+
4345 
+
4346  map[h_target] = 0;
+
4347 
+
4348  }
4349 
-
4350  for (auto & m : map)
-
4351  fn_file <<
-
4352  #ifdef EPI_DEBUG
-
4353  EPI_GET_THREAD_ID() << " " <<
-
4354  #endif
-
4355  m.first[0u] << " \"" <<
-
4356  virus_name[m.first[0u]] << "\" " <<
-
4357  m.first[1u] << " " <<
-
4358  m.first[2u] << " " <<
-
4359  m.second << "\n";
-
4360 
-
4361  return;
-
4362 
-
4363 }
-
4364 
-
4365 template<typename TSeq>
-
4366 inline std::vector< epiworld_double > DataBase<TSeq>::transition_probability(
-
4367  bool print
-
4368 ) const {
-
4369 
-
4370  auto states_labels = model->get_states();
-
4371  size_t n_state = states_labels.size();
-
4372  size_t n_days = model->get_ndays();
-
4373  std::vector< epiworld_double > res(n_state * n_state, 0.0);
-
4374  std::vector< epiworld_double > days_to_include(n_state, 0.0);
-
4375 
-
4376  for (size_t t = 1; t < n_days; ++t)
-
4377  {
+
4350  return map;
+
4351 
+
4352 }
+
4353 
+
4354 template<typename TSeq>
+
4355 inline void DataBase<TSeq>::reproductive_number(
+
4356  std::string fn
+
4357 ) const {
+
4358 
+
4359 
+
4360  auto map = reproductive_number();
+
4361 
+
4362  std::ofstream fn_file(fn, std::ios_base::out);
+
4363 
+
4364  // Repeat the same error if the file doesn't exists
+
4365  if (!fn_file)
+
4366  {
+
4367  throw std::runtime_error(
+
4368  "Could not open file \"" + fn +
+
4369  "\" for writing.")
+
4370  ;
+
4371  }
+
4372 
+
4373  fn_file <<
+
4374  #ifdef EPI_DEBUG
+
4375  "thread " <<
+
4376  #endif
+
4377  "virus_id virus source source_exposure_date rt\n";
4378 
-
4379  for (size_t s_i = 0; s_i < n_state; ++s_i)
-
4380  {
-
4381  epiworld_double daily_total = hist_total_counts[(t - 1) * n_state + s_i];
-
4382 
-
4383  if (daily_total == 0)
-
4384  continue;
-
4385 
-
4386  days_to_include[s_i] += 1.0;
-
4387 
-
4388  for (size_t s_j = 0u; s_j < n_state; ++s_j)
-
4389  {
-
4390  #ifdef EPI_DEBUG
-
4391  epiworld_double entry = hist_transition_matrix[
-
4392  s_i + s_j * n_state +
-
4393  t * (n_state * n_state)
-
4394  ];
-
4395 
-
4396  if (entry > daily_total)
-
4397  throw std::logic_error(
-
4398  "The entry in hist_transition_matrix cannot have more elememnts than the total"
-
4399  );
-
4400 
-
4401  res[s_i + s_j * n_state] += (entry / daily_total);
-
4402  #else
-
4403  res[s_i + s_j * n_state] += (
-
4404  hist_transition_matrix[
-
4405  s_i + s_j * n_state +
-
4406  t * (n_state * n_state)
-
4407  ] / daily_total
-
4408  );
-
4409  #endif
-
4410  }
-
4411 
-
4412  }
-
4413 
-
4414  }
+
4379 
+
4380  for (auto & m : map)
+
4381  fn_file <<
+
4382  #ifdef EPI_DEBUG
+
4383  EPI_GET_THREAD_ID() << " " <<
+
4384  #endif
+
4385  m.first[0u] << " \"" <<
+
4386  virus_name[m.first[0u]] << "\" " <<
+
4387  m.first[1u] << " " <<
+
4388  m.first[2u] << " " <<
+
4389  m.second << "\n";
+
4390 
+
4391  return;
+
4392 
+
4393 }
+
4394 
+
4395 template<typename TSeq>
+
4396 inline std::vector< epiworld_double > DataBase<TSeq>::transition_probability(
+
4397  bool print
+
4398 ) const {
+
4399 
+
4400  auto states_labels = model->get_states();
+
4401  size_t n_state = states_labels.size();
+
4402  size_t n_days = model->get_ndays();
+
4403  std::vector< epiworld_double > res(n_state * n_state, 0.0);
+
4404  std::vector< epiworld_double > days_to_include(n_state, 0.0);
+
4405 
+
4406  for (size_t t = 1; t < n_days; ++t)
+
4407  {
+
4408 
+
4409  for (size_t s_i = 0; s_i < n_state; ++s_i)
+
4410  {
+
4411  epiworld_double daily_total = hist_total_counts[(t - 1) * n_state + s_i];
+
4412 
+
4413  if (daily_total == 0)
+
4414  continue;
4415 
-
4416  for (size_t s_i = 0; s_i < n_state; ++s_i)
-
4417  {
-
4418  for (size_t s_j = 0; s_j < n_state; ++s_j)
-
4419  res[s_i + s_j * n_state] /= days_to_include[s_i];
-
4420  }
-
4421 
-
4422  if (print)
-
4423  {
-
4424 
-
4425  size_t nchar = 0u;
-
4426  for (auto & l : states_labels)
-
4427  if (l.length() > nchar)
-
4428  nchar = l.length();
-
4429 
-
4430  std::string fmt = " - %-" + std::to_string(nchar) + "s";
-
4431 
-
4432  printf_epiworld("\nTransition Probabilities:\n");
-
4433  for (size_t s_i = 0u; s_i < n_state; ++s_i)
-
4434  {
-
4435  printf_epiworld(fmt.c_str(), states_labels[s_i].c_str());
-
4436  for (size_t s_j = 0u; s_j < n_state; ++s_j)
-
4437  {
-
4438  if (std::isnan(res[s_i + s_j * n_state]))
-
4439  {
-
4440  printf_epiworld(" -");
-
4441  } else {
-
4442  printf_epiworld(" % 4.2f", res[s_i + s_j * n_state]);
-
4443  }
-
4444  }
-
4445  printf_epiworld("\n");
-
4446  }
-
4447 
-
4448  printf_epiworld("\n");
-
4449 
+
4416  days_to_include[s_i] += 1.0;
+
4417 
+
4418  for (size_t s_j = 0u; s_j < n_state; ++s_j)
+
4419  {
+
4420  #ifdef EPI_DEBUG
+
4421  epiworld_double entry = hist_transition_matrix[
+
4422  s_i + s_j * n_state +
+
4423  t * (n_state * n_state)
+
4424  ];
+
4425 
+
4426  if (entry > daily_total)
+
4427  throw std::logic_error(
+
4428  "The entry in hist_transition_matrix cannot have more elememnts than the total"
+
4429  );
+
4430 
+
4431  res[s_i + s_j * n_state] += (entry / daily_total);
+
4432  #else
+
4433  res[s_i + s_j * n_state] += (
+
4434  hist_transition_matrix[
+
4435  s_i + s_j * n_state +
+
4436  t * (n_state * n_state)
+
4437  ] / daily_total
+
4438  );
+
4439  #endif
+
4440  }
+
4441 
+
4442  }
+
4443 
+
4444  }
+
4445 
+
4446  for (size_t s_i = 0; s_i < n_state; ++s_i)
+
4447  {
+
4448  for (size_t s_j = 0; s_j < n_state; ++s_j)
+
4449  res[s_i + s_j * n_state] /= days_to_include[s_i];
4450  }
4451 
-
4452  return res;
-
4453 
+
4452  if (print)
+
4453  {
4454 
-
4455 }
-
4456 
-
4457 #define VECT_MATCH(a, b, c) \
-
4458  EPI_DEBUG_FAIL_AT_TRUE(a.size() != b.size(), c) \
-
4459  for (size_t __i = 0u; __i < a.size(); ++__i) \
-
4460  {\
-
4461  EPI_DEBUG_FAIL_AT_TRUE(a[__i] != b[__i], c) \
-
4462  }
-
4463 
-
4464 template<>
-
4465 inline bool DataBase<std::vector<int>>::operator==(const DataBase<std::vector<int>> & other) const
-
4466 {
-
4467  VECT_MATCH(
-
4468  virus_name, other.virus_name,
-
4469  "DataBase:: virus_name don't match"
-
4470  )
-
4471 
-
4472  EPI_DEBUG_FAIL_AT_TRUE(
-
4473  virus_sequence.size() != other.virus_sequence.size(),
-
4474  "DataBase:: virus_sequence don't match."
-
4475  )
-
4476 
-
4477  for (size_t i = 0u; i < virus_sequence.size(); ++i)
-
4478  {
-
4479  VECT_MATCH(
-
4480  virus_sequence[i], other.virus_sequence[i],
-
4481  "DataBase:: virus_sequence[i] don't match"
-
4482  )
-
4483  }
+
4455  size_t nchar = 0u;
+
4456  for (auto & l : states_labels)
+
4457  if (l.length() > nchar)
+
4458  nchar = l.length();
+
4459 
+
4460  std::string fmt = " - %-" + std::to_string(nchar) + "s";
+
4461 
+
4462  printf_epiworld("\nTransition Probabilities:\n");
+
4463  for (size_t s_i = 0u; s_i < n_state; ++s_i)
+
4464  {
+
4465  printf_epiworld(fmt.c_str(), states_labels[s_i].c_str());
+
4466  for (size_t s_j = 0u; s_j < n_state; ++s_j)
+
4467  {
+
4468  if (std::isnan(res[s_i + s_j * n_state]))
+
4469  {
+
4470  printf_epiworld(" -");
+
4471  } else {
+
4472  printf_epiworld(" % 4.2f", res[s_i + s_j * n_state]);
+
4473  }
+
4474  }
+
4475  printf_epiworld("\n");
+
4476  }
+
4477 
+
4478  printf_epiworld("\n");
+
4479 
+
4480  }
+
4481 
+
4482  return res;
+
4483 
4484 
-
4485  VECT_MATCH(
-
4486  virus_origin_date,
-
4487  other.virus_origin_date,
-
4488  "DataBase:: virus_origin_date[i] don't match"
-
4489  )
-
4490 
-
4491  VECT_MATCH(
-
4492  virus_parent_id,
-
4493  other.virus_parent_id,
-
4494  "DataBase:: virus_parent_id[i] don't match"
-
4495  )
-
4496 
+
4485 }
+
4486 
+
4487 #define VECT_MATCH(a, b, c) \
+
4488  EPI_DEBUG_FAIL_AT_TRUE(a.size() != b.size(), c) \
+
4489  for (size_t __i = 0u; __i < a.size(); ++__i) \
+
4490  {\
+
4491  EPI_DEBUG_FAIL_AT_TRUE(a[__i] != b[__i], c) \
+
4492  }
+
4493 
+
4494 template<>
+
4495 inline bool DataBase<std::vector<int>>::operator==(const DataBase<std::vector<int>> & other) const
+
4496 {
4497  VECT_MATCH(
-
4498  tool_name,
-
4499  other.tool_name,
-
4500  "DataBase:: tool_name[i] don't match"
-
4501  )
-
4502 
-
4503  VECT_MATCH(
-
4504  tool_sequence,
-
4505  other.tool_sequence,
-
4506  "DataBase:: tool_sequence[i] don't match"
-
4507  )
-
4508 
-
4509  VECT_MATCH(
-
4510  tool_origin_date,
-
4511  other.tool_origin_date,
-
4512  "DataBase:: tool_origin_date[i] don't match"
-
4513  )
+
4498  virus_name, other.virus_name,
+
4499  "DataBase:: virus_name don't match"
+
4500  )
+
4501 
+
4502  EPI_DEBUG_FAIL_AT_TRUE(
+
4503  virus_sequence.size() != other.virus_sequence.size(),
+
4504  "DataBase:: virus_sequence don't match."
+
4505  )
+
4506 
+
4507  for (size_t i = 0u; i < virus_sequence.size(); ++i)
+
4508  {
+
4509  VECT_MATCH(
+
4510  virus_sequence[i], other.virus_sequence[i],
+
4511  "DataBase:: virus_sequence[i] don't match"
+
4512  )
+
4513  }
4514 
-
4515 
-
4516  EPI_DEBUG_FAIL_AT_TRUE(
-
4517  sampling_freq != other.sampling_freq,
-
4518  "DataBase:: sampling_freq don't match."
-
4519  )
+
4515  VECT_MATCH(
+
4516  virus_origin_date,
+
4517  other.virus_origin_date,
+
4518  "DataBase:: virus_origin_date[i] don't match"
+
4519  )
4520 
-
4521  // Variants history
-
4522  VECT_MATCH(
-
4523  hist_virus_date,
-
4524  other.hist_virus_date,
-
4525  "DataBase:: hist_virus_date[i] don't match"
-
4526  )
-
4527 
-
4528  VECT_MATCH(
-
4529  hist_virus_id,
-
4530  other.hist_virus_id,
-
4531  "DataBase:: hist_virus_id[i] don't match"
-
4532  )
-
4533 
-
4534  VECT_MATCH(
-
4535  hist_virus_state,
-
4536  other.hist_virus_state,
-
4537  "DataBase:: hist_virus_state[i] don't match"
-
4538  )
-
4539 
-
4540  VECT_MATCH(
-
4541  hist_virus_counts,
-
4542  other.hist_virus_counts,
-
4543  "DataBase:: hist_virus_counts[i] don't match"
-
4544  )
+
4521  VECT_MATCH(
+
4522  virus_parent_id,
+
4523  other.virus_parent_id,
+
4524  "DataBase:: virus_parent_id[i] don't match"
+
4525  )
+
4526 
+
4527  VECT_MATCH(
+
4528  tool_name,
+
4529  other.tool_name,
+
4530  "DataBase:: tool_name[i] don't match"
+
4531  )
+
4532 
+
4533  VECT_MATCH(
+
4534  tool_sequence,
+
4535  other.tool_sequence,
+
4536  "DataBase:: tool_sequence[i] don't match"
+
4537  )
+
4538 
+
4539  VECT_MATCH(
+
4540  tool_origin_date,
+
4541  other.tool_origin_date,
+
4542  "DataBase:: tool_origin_date[i] don't match"
+
4543  )
+
4544 
4545 
-
4546  // Tools history
-
4547  VECT_MATCH(
-
4548  hist_tool_date,
-
4549  other.hist_tool_date,
-
4550  "DataBase:: hist_tool_date[i] don't match"
-
4551  )
-
4552 
-
4553  VECT_MATCH(
-
4554  hist_tool_id,
-
4555  other.hist_tool_id,
-
4556  "DataBase:: hist_tool_id[i] don't match"
-
4557  )
-
4558 
-
4559  VECT_MATCH(
-
4560  hist_tool_state,
-
4561  other.hist_tool_state,
-
4562  "DataBase:: hist_tool_state[i] don't match"
-
4563  )
-
4564 
-
4565  VECT_MATCH(
-
4566  hist_tool_counts,
-
4567  other.hist_tool_counts,
-
4568  "DataBase:: hist_tool_counts[i] don't match"
-
4569  )
-
4570 
-
4571  // Overall hist
-
4572  VECT_MATCH(
-
4573  hist_total_date,
-
4574  other.hist_total_date,
-
4575  "DataBase:: hist_total_date[i] don't match"
-
4576  )
-
4577 
-
4578  VECT_MATCH(
-
4579  hist_total_nviruses_active,
-
4580  other.hist_total_nviruses_active,
-
4581  "DataBase:: hist_total_nviruses_active[i] don't match"
-
4582  )
-
4583 
-
4584  VECT_MATCH(
-
4585  hist_total_state,
-
4586  other.hist_total_state,
-
4587  "DataBase:: hist_total_state[i] don't match"
-
4588  )
-
4589 
-
4590  VECT_MATCH(
-
4591  hist_total_counts,
-
4592  other.hist_total_counts,
-
4593  "DataBase:: hist_total_counts[i] don't match"
-
4594  )
-
4595 
-
4596  VECT_MATCH(
-
4597  hist_transition_matrix,
-
4598  other.hist_transition_matrix,
-
4599  "DataBase:: hist_transition_matrix[i] don't match"
-
4600  )
-
4601 
-
4602  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
-
4603  EPI_DEBUG_FAIL_AT_TRUE(
-
4604  today_virus.size() != other.today_virus.size(),
-
4605  "DataBase:: today_virus don't match."
+
4546  EPI_DEBUG_FAIL_AT_TRUE(
+
4547  sampling_freq != other.sampling_freq,
+
4548  "DataBase:: sampling_freq don't match."
+
4549  )
+
4550 
+
4551  // Variants history
+
4552  VECT_MATCH(
+
4553  hist_virus_date,
+
4554  other.hist_virus_date,
+
4555  "DataBase:: hist_virus_date[i] don't match"
+
4556  )
+
4557 
+
4558  VECT_MATCH(
+
4559  hist_virus_id,
+
4560  other.hist_virus_id,
+
4561  "DataBase:: hist_virus_id[i] don't match"
+
4562  )
+
4563 
+
4564  VECT_MATCH(
+
4565  hist_virus_state,
+
4566  other.hist_virus_state,
+
4567  "DataBase:: hist_virus_state[i] don't match"
+
4568  )
+
4569 
+
4570  VECT_MATCH(
+
4571  hist_virus_counts,
+
4572  other.hist_virus_counts,
+
4573  "DataBase:: hist_virus_counts[i] don't match"
+
4574  )
+
4575 
+
4576  // Tools history
+
4577  VECT_MATCH(
+
4578  hist_tool_date,
+
4579  other.hist_tool_date,
+
4580  "DataBase:: hist_tool_date[i] don't match"
+
4581  )
+
4582 
+
4583  VECT_MATCH(
+
4584  hist_tool_id,
+
4585  other.hist_tool_id,
+
4586  "DataBase:: hist_tool_id[i] don't match"
+
4587  )
+
4588 
+
4589  VECT_MATCH(
+
4590  hist_tool_state,
+
4591  other.hist_tool_state,
+
4592  "DataBase:: hist_tool_state[i] don't match"
+
4593  )
+
4594 
+
4595  VECT_MATCH(
+
4596  hist_tool_counts,
+
4597  other.hist_tool_counts,
+
4598  "DataBase:: hist_tool_counts[i] don't match"
+
4599  )
+
4600 
+
4601  // Overall hist
+
4602  VECT_MATCH(
+
4603  hist_total_date,
+
4604  other.hist_total_date,
+
4605  "DataBase:: hist_total_date[i] don't match"
4606  )
-
4607 
-
4608  for (size_t i = 0u; i < today_virus.size(); ++i)
-
4609  {
-
4610  VECT_MATCH(
-
4611  today_virus[i], other.today_virus[i],
-
4612  "DataBase:: today_virus[i] don't match"
-
4613  )
-
4614  }
-
4615 
-
4616  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
-
4617  if (today_tool.size() != other.today_tool.size())
-
4618  return false;
-
4619 
-
4620  for (size_t i = 0u; i < today_tool.size(); ++i)
-
4621  {
-
4622  VECT_MATCH(
-
4623  today_tool[i], other.today_tool[i],
-
4624  "DataBase:: today_tool[i] don't match"
-
4625  )
-
4626  }
-
4627 
-
4628  // {Susceptible, Infected, etc.}
-
4629  VECT_MATCH(
-
4630  today_total, other.today_total,
-
4631  "DataBase:: today_total don't match"
-
4632  )
-
4633 
-
4634  // Totals
-
4635  EPI_DEBUG_FAIL_AT_TRUE(
-
4636  today_total_nviruses_active != other.today_total_nviruses_active,
-
4637  "DataBase:: today_total_nviruses_active don't match."
-
4638  )
-
4639 
-
4640  // Transmission network
-
4641  VECT_MATCH(
-
4642  transmission_date,
-
4643  other.transmission_date, ///< Date of the transmission eve,
-
4644  "DataBase:: transmission_date[i] don't match"
-
4645  )
-
4646 
-
4647  VECT_MATCH(
-
4648  transmission_source,
-
4649  other.transmission_source, ///< Id of the sour,
-
4650  "DataBase:: transmission_source[i] don't match"
-
4651  )
-
4652 
-
4653  VECT_MATCH(
-
4654  transmission_target,
-
4655  other.transmission_target, ///< Id of the targ,
-
4656  "DataBase:: transmission_target[i] don't match"
-
4657  )
-
4658 
+
4607 
+
4608  VECT_MATCH(
+
4609  hist_total_nviruses_active,
+
4610  other.hist_total_nviruses_active,
+
4611  "DataBase:: hist_total_nviruses_active[i] don't match"
+
4612  )
+
4613 
+
4614  VECT_MATCH(
+
4615  hist_total_state,
+
4616  other.hist_total_state,
+
4617  "DataBase:: hist_total_state[i] don't match"
+
4618  )
+
4619 
+
4620  VECT_MATCH(
+
4621  hist_total_counts,
+
4622  other.hist_total_counts,
+
4623  "DataBase:: hist_total_counts[i] don't match"
+
4624  )
+
4625 
+
4626  VECT_MATCH(
+
4627  hist_transition_matrix,
+
4628  other.hist_transition_matrix,
+
4629  "DataBase:: hist_transition_matrix[i] don't match"
+
4630  )
+
4631 
+
4632  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
+
4633  EPI_DEBUG_FAIL_AT_TRUE(
+
4634  today_virus.size() != other.today_virus.size(),
+
4635  "DataBase:: today_virus don't match."
+
4636  )
+
4637 
+
4638  for (size_t i = 0u; i < today_virus.size(); ++i)
+
4639  {
+
4640  VECT_MATCH(
+
4641  today_virus[i], other.today_virus[i],
+
4642  "DataBase:: today_virus[i] don't match"
+
4643  )
+
4644  }
+
4645 
+
4646  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
+
4647  if (today_tool.size() != other.today_tool.size())
+
4648  return false;
+
4649 
+
4650  for (size_t i = 0u; i < today_tool.size(); ++i)
+
4651  {
+
4652  VECT_MATCH(
+
4653  today_tool[i], other.today_tool[i],
+
4654  "DataBase:: today_tool[i] don't match"
+
4655  )
+
4656  }
+
4657 
+
4658  // {Susceptible, Infected, etc.}
4659  VECT_MATCH(
-
4660  transmission_virus,
-
4661  other.transmission_virus, ///< Id of the varia,
-
4662  "DataBase:: transmission_virus[i] don't match"
-
4663  )
-
4664 
-
4665  VECT_MATCH(
-
4666  transmission_source_exposure_date,
-
4667  other.transmission_source_exposure_date, ///< Date when the source acquired the varia,
-
4668  "DataBase:: transmission_source_exposure_date[i] don't match"
-
4669  )
-
4670 
-
4671 
-
4672  VECT_MATCH(
-
4673  transition_matrix,
-
4674  other.transition_matrix,
-
4675  "DataBase:: transition_matrix[i] don't match"
-
4676  )
-
4677 
-
4678 
-
4679  return true;
-
4680 
-
4681 }
+
4660  today_total, other.today_total,
+
4661  "DataBase:: today_total don't match"
+
4662  )
+
4663 
+
4664  // Totals
+
4665  EPI_DEBUG_FAIL_AT_TRUE(
+
4666  today_total_nviruses_active != other.today_total_nviruses_active,
+
4667  "DataBase:: today_total_nviruses_active don't match."
+
4668  )
+
4669 
+
4670  // Transmission network
+
4671  VECT_MATCH(
+
4672  transmission_date,
+
4673  other.transmission_date, ///< Date of the transmission eve,
+
4674  "DataBase:: transmission_date[i] don't match"
+
4675  )
+
4676 
+
4677  VECT_MATCH(
+
4678  transmission_source,
+
4679  other.transmission_source, ///< Id of the sour,
+
4680  "DataBase:: transmission_source[i] don't match"
+
4681  )
4682 
-
4683 template<typename TSeq>
-
4684 inline bool DataBase<TSeq>::operator==(const DataBase<TSeq> & other) const
-
4685 {
-
4686  VECT_MATCH(
-
4687  virus_name,
-
4688  other.virus_name,
-
4689  "DataBase:: virus_name[i] don't match"
-
4690  )
-
4691 
-
4692  VECT_MATCH(
-
4693  virus_sequence,
-
4694  other.virus_sequence,
-
4695  "DataBase:: virus_sequence[i] don't match"
-
4696  )
-
4697 
-
4698  VECT_MATCH(
-
4699  virus_origin_date,
-
4700  other.virus_origin_date,
-
4701  "DataBase:: virus_origin_date[i] don't match"
-
4702  )
-
4703 
-
4704  VECT_MATCH(
-
4705  virus_parent_id,
-
4706  other.virus_parent_id,
-
4707  "DataBase:: virus_parent_id[i] don't match"
-
4708  )
-
4709 
-
4710  VECT_MATCH(
-
4711  tool_name,
-
4712  other.tool_name,
-
4713  "DataBase:: tool_name[i] don't match"
-
4714  )
-
4715 
+
4683  VECT_MATCH(
+
4684  transmission_target,
+
4685  other.transmission_target, ///< Id of the targ,
+
4686  "DataBase:: transmission_target[i] don't match"
+
4687  )
+
4688 
+
4689  VECT_MATCH(
+
4690  transmission_virus,
+
4691  other.transmission_virus, ///< Id of the varia,
+
4692  "DataBase:: transmission_virus[i] don't match"
+
4693  )
+
4694 
+
4695  VECT_MATCH(
+
4696  transmission_source_exposure_date,
+
4697  other.transmission_source_exposure_date, ///< Date when the source acquired the varia,
+
4698  "DataBase:: transmission_source_exposure_date[i] don't match"
+
4699  )
+
4700 
+
4701 
+
4702  VECT_MATCH(
+
4703  transition_matrix,
+
4704  other.transition_matrix,
+
4705  "DataBase:: transition_matrix[i] don't match"
+
4706  )
+
4707 
+
4708 
+
4709  return true;
+
4710 
+
4711 }
+
4712 
+
4713 template<typename TSeq>
+
4714 inline bool DataBase<TSeq>::operator==(const DataBase<TSeq> & other) const
+
4715 {
4716  VECT_MATCH(
-
4717  tool_sequence,
-
4718  other.tool_sequence,
-
4719  "DataBase:: tool_sequence[i] don't match"
+
4717  virus_name,
+
4718  other.virus_name,
+
4719  "DataBase:: virus_name[i] don't match"
4720  )
4721 
4722  VECT_MATCH(
-
4723  tool_origin_date,
-
4724  other.tool_origin_date,
-
4725  "DataBase:: tool_origin_date[i] don't match"
+
4723  virus_sequence,
+
4724  other.virus_sequence,
+
4725  "DataBase:: virus_sequence[i] don't match"
4726  )
4727 
-
4728 
-
4729  EPI_DEBUG_FAIL_AT_TRUE(
-
4730  sampling_freq != other.sampling_freq,
-
4731  "DataBase:: sampling_freq don't match."
+
4728  VECT_MATCH(
+
4729  virus_origin_date,
+
4730  other.virus_origin_date,
+
4731  "DataBase:: virus_origin_date[i] don't match"
4732  )
4733 
-
4734  // Variants history
-
4735  VECT_MATCH(
-
4736  hist_virus_date,
-
4737  other.hist_virus_date,
-
4738  "DataBase:: hist_virus_date[i] don't match"
-
4739  )
-
4740 
-
4741  VECT_MATCH(
-
4742  hist_virus_id,
-
4743  other.hist_virus_id,
-
4744  "DataBase:: hist_virus_id[i] don't match"
-
4745  )
-
4746 
-
4747  VECT_MATCH(
-
4748  hist_virus_state,
-
4749  other.hist_virus_state,
-
4750  "DataBase:: hist_virus_state[i] don't match"
-
4751  )
-
4752 
-
4753  VECT_MATCH(
-
4754  hist_virus_counts,
-
4755  other.hist_virus_counts,
-
4756  "DataBase:: hist_virus_counts[i] don't match"
-
4757  )
-
4758 
-
4759  // Tools history
-
4760  VECT_MATCH(
-
4761  hist_tool_date,
-
4762  other.hist_tool_date,
-
4763  "DataBase:: hist_tool_date[i] don't match"
-
4764  )
-
4765 
-
4766  VECT_MATCH(
-
4767  hist_tool_id,
-
4768  other.hist_tool_id,
-
4769  "DataBase:: hist_tool_id[i] don't match"
-
4770  )
-
4771 
-
4772  VECT_MATCH(
-
4773  hist_tool_state,
-
4774  other.hist_tool_state,
-
4775  "DataBase:: hist_tool_state[i] don't match"
-
4776  )
-
4777 
-
4778  VECT_MATCH(
-
4779  hist_tool_counts,
-
4780  other.hist_tool_counts,
-
4781  "DataBase:: hist_tool_counts[i] don't match"
-
4782  )
-
4783 
-
4784  // Overall hist
-
4785  VECT_MATCH(
-
4786  hist_total_date,
-
4787  other.hist_total_date,
-
4788  "DataBase:: hist_total_date[i] don't match"
-
4789  )
-
4790 
-
4791  VECT_MATCH(
-
4792  hist_total_nviruses_active,
-
4793  other.hist_total_nviruses_active,
-
4794  "DataBase:: hist_total_nviruses_active[i] don't match"
-
4795  )
-
4796 
-
4797  VECT_MATCH(
-
4798  hist_total_state,
-
4799  other.hist_total_state,
-
4800  "DataBase:: hist_total_state[i] don't match"
-
4801  )
-
4802 
-
4803  VECT_MATCH(
-
4804  hist_total_counts,
-
4805  other.hist_total_counts,
-
4806  "DataBase:: hist_total_counts[i] don't match"
-
4807  )
-
4808 
-
4809  VECT_MATCH(
-
4810  hist_transition_matrix,
-
4811  other.hist_transition_matrix,
-
4812  "DataBase:: hist_transition_matrix[i] don't match"
-
4813  )
-
4814 
-
4815  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
-
4816  EPI_DEBUG_FAIL_AT_TRUE(
-
4817  today_virus.size() != other.today_virus.size(),
-
4818  "DataBase:: today_virus.size() don't match."
+
4734  VECT_MATCH(
+
4735  virus_parent_id,
+
4736  other.virus_parent_id,
+
4737  "DataBase:: virus_parent_id[i] don't match"
+
4738  )
+
4739 
+
4740  VECT_MATCH(
+
4741  tool_name,
+
4742  other.tool_name,
+
4743  "DataBase:: tool_name[i] don't match"
+
4744  )
+
4745 
+
4746  VECT_MATCH(
+
4747  tool_sequence,
+
4748  other.tool_sequence,
+
4749  "DataBase:: tool_sequence[i] don't match"
+
4750  )
+
4751 
+
4752  VECT_MATCH(
+
4753  tool_origin_date,
+
4754  other.tool_origin_date,
+
4755  "DataBase:: tool_origin_date[i] don't match"
+
4756  )
+
4757 
+
4758 
+
4759  EPI_DEBUG_FAIL_AT_TRUE(
+
4760  sampling_freq != other.sampling_freq,
+
4761  "DataBase:: sampling_freq don't match."
+
4762  )
+
4763 
+
4764  // Variants history
+
4765  VECT_MATCH(
+
4766  hist_virus_date,
+
4767  other.hist_virus_date,
+
4768  "DataBase:: hist_virus_date[i] don't match"
+
4769  )
+
4770 
+
4771  VECT_MATCH(
+
4772  hist_virus_id,
+
4773  other.hist_virus_id,
+
4774  "DataBase:: hist_virus_id[i] don't match"
+
4775  )
+
4776 
+
4777  VECT_MATCH(
+
4778  hist_virus_state,
+
4779  other.hist_virus_state,
+
4780  "DataBase:: hist_virus_state[i] don't match"
+
4781  )
+
4782 
+
4783  VECT_MATCH(
+
4784  hist_virus_counts,
+
4785  other.hist_virus_counts,
+
4786  "DataBase:: hist_virus_counts[i] don't match"
+
4787  )
+
4788 
+
4789  // Tools history
+
4790  VECT_MATCH(
+
4791  hist_tool_date,
+
4792  other.hist_tool_date,
+
4793  "DataBase:: hist_tool_date[i] don't match"
+
4794  )
+
4795 
+
4796  VECT_MATCH(
+
4797  hist_tool_id,
+
4798  other.hist_tool_id,
+
4799  "DataBase:: hist_tool_id[i] don't match"
+
4800  )
+
4801 
+
4802  VECT_MATCH(
+
4803  hist_tool_state,
+
4804  other.hist_tool_state,
+
4805  "DataBase:: hist_tool_state[i] don't match"
+
4806  )
+
4807 
+
4808  VECT_MATCH(
+
4809  hist_tool_counts,
+
4810  other.hist_tool_counts,
+
4811  "DataBase:: hist_tool_counts[i] don't match"
+
4812  )
+
4813 
+
4814  // Overall hist
+
4815  VECT_MATCH(
+
4816  hist_total_date,
+
4817  other.hist_total_date,
+
4818  "DataBase:: hist_total_date[i] don't match"
4819  )
-
4820 
-
4821  for (size_t i = 0u; i < today_virus.size(); ++i)
-
4822  {
-
4823  VECT_MATCH(
-
4824  today_virus[i], other.today_virus[i],
-
4825  "DataBase:: today_virus[i] don't match"
-
4826  )
-
4827  }
-
4828 
-
4829  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
-
4830  EPI_DEBUG_FAIL_AT_TRUE(
-
4831  today_tool.size() != other.today_tool.size(),
-
4832  "DataBase:: today_tool.size() don't match."
-
4833  )
-
4834 
-
4835  for (size_t i = 0u; i < today_tool.size(); ++i)
-
4836  {
-
4837  VECT_MATCH(
-
4838  today_tool[i], other.today_tool[i],
-
4839  "DataBase:: today_tool[i] don't match"
-
4840  )
-
4841  }
-
4842 
-
4843  // {Susceptible, Infected, etc.}
-
4844  VECT_MATCH(
-
4845  today_total, other.today_total,
-
4846  "DataBase:: today_total[i] don't match"
-
4847  )
-
4848 
-
4849  // Totals
-
4850  EPI_DEBUG_FAIL_AT_TRUE(
-
4851  today_total_nviruses_active != other.today_total_nviruses_active,
-
4852  "DataBase:: today_total_nviruses_active don't match."
-
4853  )
-
4854 
-
4855  // Transmission network
-
4856  VECT_MATCH( ///< Date of the transmission eve
-
4857  transmission_date,
-
4858  other.transmission_date,
-
4859  "DataBase:: transmission_date[i] don't match"
-
4860  )
-
4861 
-
4862  VECT_MATCH( ///< Id of the sour
-
4863  transmission_source,
-
4864  other.transmission_source,
-
4865  "DataBase:: transmission_source[i] don't match"
-
4866  )
-
4867 
-
4868  VECT_MATCH( ///< Id of the targ
-
4869  transmission_target,
-
4870  other.transmission_target,
-
4871  "DataBase:: transmission_target[i] don't match"
-
4872  )
-
4873 
-
4874  VECT_MATCH( ///< Id of the varia
-
4875  transmission_virus,
-
4876  other.transmission_virus,
-
4877  "DataBase:: transmission_virus[i] don't match"
-
4878  )
-
4879 
-
4880  VECT_MATCH( ///< Date when the source acquired the varia
-
4881  transmission_source_exposure_date,
-
4882  other.transmission_source_exposure_date,
-
4883  "DataBase:: transmission_source_exposure_date[i] don't match"
-
4884  )
-
4885 
-
4886  VECT_MATCH(
-
4887  transition_matrix,
-
4888  other.transition_matrix,
-
4889  "DataBase:: transition_matrix[i] don't match"
+
4820 
+
4821  VECT_MATCH(
+
4822  hist_total_nviruses_active,
+
4823  other.hist_total_nviruses_active,
+
4824  "DataBase:: hist_total_nviruses_active[i] don't match"
+
4825  )
+
4826 
+
4827  VECT_MATCH(
+
4828  hist_total_state,
+
4829  other.hist_total_state,
+
4830  "DataBase:: hist_total_state[i] don't match"
+
4831  )
+
4832 
+
4833  VECT_MATCH(
+
4834  hist_total_counts,
+
4835  other.hist_total_counts,
+
4836  "DataBase:: hist_total_counts[i] don't match"
+
4837  )
+
4838 
+
4839  VECT_MATCH(
+
4840  hist_transition_matrix,
+
4841  other.hist_transition_matrix,
+
4842  "DataBase:: hist_transition_matrix[i] don't match"
+
4843  )
+
4844 
+
4845  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
+
4846  EPI_DEBUG_FAIL_AT_TRUE(
+
4847  today_virus.size() != other.today_virus.size(),
+
4848  "DataBase:: today_virus.size() don't match."
+
4849  )
+
4850 
+
4851  for (size_t i = 0u; i < today_virus.size(); ++i)
+
4852  {
+
4853  VECT_MATCH(
+
4854  today_virus[i], other.today_virus[i],
+
4855  "DataBase:: today_virus[i] don't match"
+
4856  )
+
4857  }
+
4858 
+
4859  // {Variant 1: {state 1, state 2, etc.}, Variant 2: {...}, ...}
+
4860  EPI_DEBUG_FAIL_AT_TRUE(
+
4861  today_tool.size() != other.today_tool.size(),
+
4862  "DataBase:: today_tool.size() don't match."
+
4863  )
+
4864 
+
4865  for (size_t i = 0u; i < today_tool.size(); ++i)
+
4866  {
+
4867  VECT_MATCH(
+
4868  today_tool[i], other.today_tool[i],
+
4869  "DataBase:: today_tool[i] don't match"
+
4870  )
+
4871  }
+
4872 
+
4873  // {Susceptible, Infected, etc.}
+
4874  VECT_MATCH(
+
4875  today_total, other.today_total,
+
4876  "DataBase:: today_total[i] don't match"
+
4877  )
+
4878 
+
4879  // Totals
+
4880  EPI_DEBUG_FAIL_AT_TRUE(
+
4881  today_total_nviruses_active != other.today_total_nviruses_active,
+
4882  "DataBase:: today_total_nviruses_active don't match."
+
4883  )
+
4884 
+
4885  // Transmission network
+
4886  VECT_MATCH( ///< Date of the transmission eve
+
4887  transmission_date,
+
4888  other.transmission_date,
+
4889  "DataBase:: transmission_date[i] don't match"
4890  )
4891 
-
4892  return true;
-
4893 
-
4894 }
-
4895 
-
4896 template<typename TSeq>
-
4897 inline void DataBase<TSeq>::generation_time(
-
4898  std::vector< int > & agent_id,
-
4899  std::vector< int > & virus_id,
-
4900  std::vector< int > & time,
-
4901  std::vector< int > & gentime
-
4902 ) const {
-
4903 
-
4904  size_t nevents = transmission_date.size();
-
4905 
-
4906  agent_id.reserve(nevents);
-
4907  virus_id.reserve(nevents);
-
4908  time.reserve(nevents);
-
4909  gentime.reserve(nevents);
-
4910 
-
4911  // Iterating through the individuals
-
4912  for (size_t i = 0u; i < nevents; ++i)
-
4913  {
-
4914  int agent_id_i = transmission_target[i];
-
4915  agent_id.push_back(agent_id_i);
-
4916  virus_id.push_back(transmission_virus[i]);
-
4917  time.push_back(transmission_date[i]);
-
4918 
-
4919  bool found = false;
-
4920  for (size_t j = i; j < nevents; ++j)
-
4921  {
-
4922 
-
4923  if (transmission_source[j] == agent_id_i)
-
4924  {
-
4925  gentime.push_back(transmission_date[j] - time[i]);
-
4926  found = true;
-
4927  break;
-
4928  }
-
4929 
-
4930  }
-
4931 
-
4932  // If there's no transmission, we set the generation time to
-
4933  // minus 1;
-
4934  if (!found)
-
4935  gentime.push_back(-1);
-
4936 
-
4937  }
-
4938 
-
4939  agent_id.shrink_to_fit();
-
4940  virus_id.shrink_to_fit();
-
4941  time.shrink_to_fit();
-
4942  gentime.shrink_to_fit();
-
4943 
-
4944  return;
-
4945 
-
4946 }
-
4947 
-
4948 template<typename TSeq>
-
4949 inline void DataBase<TSeq>::generation_time(
-
4950  std::string fn
-
4951 ) const
-
4952 {
-
4953 
-
4954  std::vector< int > agent_id;
-
4955  std::vector< int > virus_id;
-
4956  std::vector< int > time;
-
4957  std::vector< int > gentime;
-
4958 
-
4959  generation_time(agent_id, virus_id, time, gentime);
-
4960 
-
4961  std::ofstream fn_file(fn, std::ios_base::out);
-
4962 
-
4963  // Throw an error if the file doesn't exists using throw
-
4964  if (!fn_file)
-
4965  {
-
4966  throw std::runtime_error(
-
4967  "DataBase::generation_time: "
-
4968  "Cannot open file " + fn + "."
-
4969  );
-
4970  }
-
4971 
-
4972 
+
4892  VECT_MATCH( ///< Id of the sour
+
4893  transmission_source,
+
4894  other.transmission_source,
+
4895  "DataBase:: transmission_source[i] don't match"
+
4896  )
+
4897 
+
4898  VECT_MATCH( ///< Id of the targ
+
4899  transmission_target,
+
4900  other.transmission_target,
+
4901  "DataBase:: transmission_target[i] don't match"
+
4902  )
+
4903 
+
4904  VECT_MATCH( ///< Id of the varia
+
4905  transmission_virus,
+
4906  other.transmission_virus,
+
4907  "DataBase:: transmission_virus[i] don't match"
+
4908  )
+
4909 
+
4910  VECT_MATCH( ///< Date when the source acquired the varia
+
4911  transmission_source_exposure_date,
+
4912  other.transmission_source_exposure_date,
+
4913  "DataBase:: transmission_source_exposure_date[i] don't match"
+
4914  )
+
4915 
+
4916  VECT_MATCH(
+
4917  transition_matrix,
+
4918  other.transition_matrix,
+
4919  "DataBase:: transition_matrix[i] don't match"
+
4920  )
+
4921 
+
4922  return true;
+
4923 
+
4924 }
+
4925 
+
4926 template<typename TSeq>
+
4927 inline void DataBase<TSeq>::generation_time(
+
4928  std::vector< int > & agent_id,
+
4929  std::vector< int > & virus_id,
+
4930  std::vector< int > & time,
+
4931  std::vector< int > & gentime
+
4932 ) const {
+
4933 
+
4934  size_t nevents = transmission_date.size();
+
4935 
+
4936  agent_id.reserve(nevents);
+
4937  virus_id.reserve(nevents);
+
4938  time.reserve(nevents);
+
4939  gentime.reserve(nevents);
+
4940 
+
4941  // Iterating through the individuals
+
4942  for (size_t i = 0u; i < nevents; ++i)
+
4943  {
+
4944  int agent_id_i = transmission_target[i];
+
4945  agent_id.push_back(agent_id_i);
+
4946  virus_id.push_back(transmission_virus[i]);
+
4947  time.push_back(transmission_date[i]);
+
4948 
+
4949  bool found = false;
+
4950  for (size_t j = i; j < nevents; ++j)
+
4951  {
+
4952 
+
4953  if (transmission_source[j] == agent_id_i)
+
4954  {
+
4955  gentime.push_back(transmission_date[j] - time[i]);
+
4956  found = true;
+
4957  break;
+
4958  }
+
4959 
+
4960  }
+
4961 
+
4962  // If there's no transmission, we set the generation time to
+
4963  // minus 1;
+
4964  if (!found)
+
4965  gentime.push_back(-1);
+
4966 
+
4967  }
+
4968 
+
4969  agent_id.shrink_to_fit();
+
4970  virus_id.shrink_to_fit();
+
4971  time.shrink_to_fit();
+
4972  gentime.shrink_to_fit();
4973 
-
4974  fn_file <<
-
4975  #ifdef EPI_DEBUG
-
4976  "thread " <<
-
4977  #endif
-
4978  "virus source source_exposure_date gentime\n";
-
4979 
-
4980  size_t n = agent_id.size();
-
4981  for (size_t i = 0u; i < n; ++i)
-
4982  fn_file <<
-
4983  #ifdef EPI_DEBUG
-
4984  EPI_GET_THREAD_ID() << " " <<
-
4985  #endif
-
4986  virus_id[i] << " " <<
-
4987  agent_id[i] << " " <<
-
4988  time[i] << " " <<
-
4989  gentime[i] << "\n";
+
4974  return;
+
4975 
+
4976 }
+
4977 
+
4978 template<typename TSeq>
+
4979 inline void DataBase<TSeq>::generation_time(
+
4980  std::string fn
+
4981 ) const
+
4982 {
+
4983 
+
4984  std::vector< int > agent_id;
+
4985  std::vector< int > virus_id;
+
4986  std::vector< int > time;
+
4987  std::vector< int > gentime;
+
4988 
+
4989  generation_time(agent_id, virus_id, time, gentime);
4990 
-
4991  return;
+
4991  std::ofstream fn_file(fn, std::ios_base::out);
4992 
-
4993 }
-
4994 
-
4995 #undef VECT_MATCH
-
4996 
-
4997 #endif
-
4998 /*//////////////////////////////////////////////////////////////////////////////
-
5000 
-
5001  End of -include/epiworld/database-meat.hpp-
+
4993  // Throw an error if the file doesn't exists using throw
+
4994  if (!fn_file)
+
4995  {
+
4996  throw std::runtime_error(
+
4997  "DataBase::generation_time: "
+
4998  "Cannot open file " + fn + "."
+
4999  );
+
5000  }
+
5001 
5002 
-
5005 
-
5006 
-
5007 /*//////////////////////////////////////////////////////////////////////////////
+
5003 
+
5004  fn_file <<
+
5005  #ifdef EPI_DEBUG
+
5006  "thread " <<
+
5007  #endif
+
5008  "virus source source_exposure_date gentime\n";
5009 
-
5010  Start of -include/epiworld/adjlist-bones.hpp-
-
5011 
-
5014 
-
5015 
-
5016 #ifndef EPIWORLD_ADJLIST_BONES_HPP
-
5017 #define EPIWORLD_ADJLIST_BONES_HPP
-
5018 
-
5019 class AdjList {
-
5020 private:
-
5021 
-
5022  std::vector<std::map<int, int>> dat;
-
5023  bool directed;
-
5024  epiworld_fast_uint N = 0;
-
5025  epiworld_fast_uint E = 0;
+
5010  size_t n = agent_id.size();
+
5011  for (size_t i = 0u; i < n; ++i)
+
5012  fn_file <<
+
5013  #ifdef EPI_DEBUG
+
5014  EPI_GET_THREAD_ID() << " " <<
+
5015  #endif
+
5016  virus_id[i] << " " <<
+
5017  agent_id[i] << " " <<
+
5018  time[i] << " " <<
+
5019  gentime[i] << "\n";
+
5020 
+
5021  return;
+
5022 
+
5023 }
+
5024 
+
5025 #undef VECT_MATCH
5026 
-
5027 public:
-
5028 
-
5029  AdjList() {};
+
5027 #endif
+
5028 /*//////////////////////////////////////////////////////////////////////////////
5030 
-
5042  AdjList(
-
5043  const std::vector< int > & source,
-
5044  const std::vector< int > & target,
-
5045  int size,
-
5046  bool directed
-
5047  );
+
5031  End of -include/epiworld/database-meat.hpp-
+
5032 
+
5035 
+
5036 
+
5037 /*//////////////////////////////////////////////////////////////////////////////
+
5039 
+
5040  Start of -include/epiworld/adjlist-bones.hpp-
+
5041 
+
5044 
+
5045 
+
5046 #ifndef EPIWORLD_ADJLIST_BONES_HPP
+
5047 #define EPIWORLD_ADJLIST_BONES_HPP
5048 
-
5049  AdjList(AdjList && a); // Move constructor
-
5050  AdjList(const AdjList & a); // Copy constructor
-
5051  AdjList& operator=(const AdjList& a);
-
5052 
-
5053 
-
5064  void read_edgelist(
-
5065  std::string fn,
-
5066  int size,
-
5067  int skip = 0,
-
5068  bool directed = true
-
5069  );
-
5070 
-
5071  std::map<int, int> operator()(
-
5072  epiworld_fast_uint i
-
5073  ) const;
-
5074 
-
5075  void print(epiworld_fast_uint limit = 20u) const;
-
5076  size_t vcount() const; ///< Number of vertices/nodes in the network.
-
5077  size_t ecount() const; ///< Number of edges/arcs/ties in the network.
-
5078 
-
5079  std::vector<std::map<int,int>> & get_dat() {
-
5080  return dat;
-
5081  };
+
5049 class AdjList {
+
5050 private:
+
5051 
+
5052  std::vector<std::map<int, int>> dat;
+
5053  bool directed;
+
5054  epiworld_fast_uint N = 0;
+
5055  epiworld_fast_uint E = 0;
+
5056 
+
5057 public:
+
5058 
+
5059  AdjList() {};
+
5060 
+
5072  AdjList(
+
5073  const std::vector< int > & source,
+
5074  const std::vector< int > & target,
+
5075  int size,
+
5076  bool directed
+
5077  );
+
5078 
+
5079  AdjList(AdjList && a); // Move constructor
+
5080  AdjList(const AdjList & a); // Copy constructor
+
5081  AdjList& operator=(const AdjList& a);
5082 
-
5083  bool is_directed() const; ///< `true` if the network is directed.
-
5084 
-
5085 };
-
5086 
-
5087 
-
5088 #endif
-
5089 
-
5090 /*//////////////////////////////////////////////////////////////////////////////
-
5092 
-
5093  End of -include/epiworld/adjlist-bones.hpp-
-
5094 
-
5097 
-
5098 
-
5099 /*//////////////////////////////////////////////////////////////////////////////
-
5101 
-
5102  Start of -include/epiworld/adjlist-meat.hpp-
-
5103 
-
5106 
-
5107 
-
5108 #ifndef EPIWORLD_ADJLIST_MEAT_HPP
-
5109 #define EPIWORLD_ADJLIST_MEAT_HPP
-
5110 
-
5111 inline AdjList::AdjList(
-
5112  const std::vector< int > & source,
-
5113  const std::vector< int > & target,
-
5114  int size,
-
5115  bool directed
-
5116 ) : directed(directed) {
+
5083 
+
5094  void read_edgelist(
+
5095  std::string fn,
+
5096  int size,
+
5097  int skip = 0,
+
5098  bool directed = true
+
5099  );
+
5100 
+
5101  std::map<int, int> operator()(
+
5102  epiworld_fast_uint i
+
5103  ) const;
+
5104 
+
5105  void print(epiworld_fast_uint limit = 20u) const;
+
5106  size_t vcount() const; ///< Number of vertices/nodes in the network.
+
5107  size_t ecount() const; ///< Number of edges/arcs/ties in the network.
+
5108 
+
5109  std::vector<std::map<int,int>> & get_dat() {
+
5110  return dat;
+
5111  };
+
5112 
+
5113  bool is_directed() const; ///< `true` if the network is directed.
+
5114 
+
5115 };
+
5116 
5117 
-
5118 
-
5119  dat.resize(size, std::map<int,int>({}));
-
5120  int max_id = size - 1;
-
5121 
-
5122  int i,j;
-
5123  for (int m = 0; m < static_cast<int>(source.size()); ++m)
-
5124  {
-
5125 
-
5126  i = source[m];
-
5127  j = target[m];
+
5118 #endif
+
5119 
+
5120 /*//////////////////////////////////////////////////////////////////////////////
+
5122 
+
5123  End of -include/epiworld/adjlist-bones.hpp-
+
5124 
+
5127 
5128 
-
5129  if (i > max_id)
-
5130  throw std::range_error(
-
5131  "The source["+std::to_string(m)+"] = " + std::to_string(i) +
-
5132  " is above the max_id " + std::to_string(max_id)
-
5133  );
-
5134 
-
5135  if (j > max_id)
-
5136  throw std::range_error(
-
5137  "The target["+std::to_string(m)+"] = " + std::to_string(j) +
-
5138  " is above the max_id " + std::to_string(max_id)
-
5139  );
+
5129 /*//////////////////////////////////////////////////////////////////////////////
+
5131 
+
5132  Start of -include/epiworld/adjlist-meat.hpp-
+
5133 
+
5136 
+
5137 
+
5138 #ifndef EPIWORLD_ADJLIST_MEAT_HPP
+
5139 #define EPIWORLD_ADJLIST_MEAT_HPP
5140 
-
5141  // Adding nodes
-
5142  if (dat[i].find(j) == dat[i].end())
-
5143  dat[i].insert(std::pair<int, int>(j, 1u));
-
5144  else
-
5145  dat[i][j]++;
-
5146 
-
5147  if (!directed)
-
5148  {
-
5149 
-
5150  if (dat[j].find(i) == dat[j].end())
-
5151  dat[j].insert(std::pair<int, int>(i, 1u));
-
5152  else
-
5153  dat[j][i]++;
-
5154 
-
5155  }
-
5156 
-
5157  E++;
+
5141 inline AdjList::AdjList(
+
5142  const std::vector< int > & source,
+
5143  const std::vector< int > & target,
+
5144  int size,
+
5145  bool directed
+
5146 ) : directed(directed) {
+
5147 
+
5148 
+
5149  dat.resize(size, std::map<int,int>({}));
+
5150  int max_id = size - 1;
+
5151 
+
5152  int i,j;
+
5153  for (int m = 0; m < static_cast<int>(source.size()); ++m)
+
5154  {
+
5155 
+
5156  i = source[m];
+
5157  j = target[m];
5158 
-
5159  }
-
5160 
-
5161  N = size;
-
5162 
-
5163  return;
+
5159  if (i > max_id)
+
5160  throw std::range_error(
+
5161  "The source["+std::to_string(m)+"] = " + std::to_string(i) +
+
5162  " is above the max_id " + std::to_string(max_id)
+
5163  );
5164 
-
5165 }
-
5166 
-
5167 
-
5168 inline AdjList::AdjList(AdjList && a) :
-
5169  dat(std::move(a.dat)),
-
5170  directed(a.directed),
-
5171  N(a.N),
-
5172  E(a.E)
-
5173 {
-
5174 
-
5175 }
-
5176 
-
5177 inline AdjList::AdjList(const AdjList & a) :
-
5178  dat(a.dat),
-
5179  directed(a.directed),
-
5180  N(a.N),
-
5181  E(a.E)
-
5182 {
-
5183 
-
5184 }
-
5185 
-
5186 inline AdjList& AdjList::operator=(const AdjList& a)
-
5187 {
-
5188  if (this == &a)
-
5189  return *this;
+
5165  if (j > max_id)
+
5166  throw std::range_error(
+
5167  "The target["+std::to_string(m)+"] = " + std::to_string(j) +
+
5168  " is above the max_id " + std::to_string(max_id)
+
5169  );
+
5170 
+
5171  // Adding nodes
+
5172  if (dat[i].find(j) == dat[i].end())
+
5173  dat[i].insert(std::pair<int, int>(j, 1u));
+
5174  else
+
5175  dat[i][j]++;
+
5176 
+
5177  if (!directed)
+
5178  {
+
5179 
+
5180  if (dat[j].find(i) == dat[j].end())
+
5181  dat[j].insert(std::pair<int, int>(i, 1u));
+
5182  else
+
5183  dat[j][i]++;
+
5184 
+
5185  }
+
5186 
+
5187  E++;
+
5188 
+
5189  }
5190 
-
5191  this->dat = a.dat;
-
5192  this->directed = a.directed;
-
5193  this->N = a.N;
-
5194  this->E = a.E;
-
5195 
-
5196  return *this;
-
5197 }
-
5198 
-
5199 inline void AdjList::read_edgelist(
-
5200  std::string fn,
-
5201  int size,
-
5202  int skip,
-
5203  bool directed
-
5204 ) {
-
5205 
-
5206  int i,j;
-
5207  std::ifstream filei(fn);
-
5208 
-
5209  if (!filei)
-
5210  throw std::logic_error("The file " + fn + " was not found.");
-
5211 
-
5212  int linenum = 0;
-
5213  std::vector< int > source_;
-
5214  std::vector< int > target_;
+
5191  N = size;
+
5192 
+
5193  return;
+
5194 
+
5195 }
+
5196 
+
5197 
+
5198 inline AdjList::AdjList(AdjList && a) :
+
5199  dat(std::move(a.dat)),
+
5200  directed(a.directed),
+
5201  N(a.N),
+
5202  E(a.E)
+
5203 {
+
5204 
+
5205 }
+
5206 
+
5207 inline AdjList::AdjList(const AdjList & a) :
+
5208  dat(a.dat),
+
5209  directed(a.directed),
+
5210  N(a.N),
+
5211  E(a.E)
+
5212 {
+
5213 
+
5214 }
5215 
-
5216  source_.reserve(1e5);
-
5217  target_.reserve(1e5);
-
5218 
-
5219  int max_id = size - 1;
+
5216 inline AdjList& AdjList::operator=(const AdjList& a)
+
5217 {
+
5218  if (this == &a)
+
5219  return *this;
5220 
-
5221  while (!filei.eof())
-
5222  {
-
5223 
-
5224  if (linenum++ < skip)
-
5225  continue;
-
5226 
-
5227  filei >> i >> j;
+
5221  this->dat = a.dat;
+
5222  this->directed = a.directed;
+
5223  this->N = a.N;
+
5224  this->E = a.E;
+
5225 
+
5226  return *this;
+
5227 }
5228 
-
5229  // Looking for exceptions
-
5230  if (filei.bad())
-
5231  throw std::logic_error(
-
5232  "I/O error while reading the file " +
-
5233  fn
-
5234  );
+
5229 inline void AdjList::read_edgelist(
+
5230  std::string fn,
+
5231  int size,
+
5232  int skip,
+
5233  bool directed
+
5234 ) {
5235 
-
5236  if (filei.fail())
-
5237  break;
+
5236  int i,j;
+
5237  std::ifstream filei(fn);
5238 
-
5239  if (i > max_id)
-
5240  throw std::range_error(
-
5241  "The source["+std::to_string(linenum)+"] = " + std::to_string(i) +
-
5242  " is above the max_id " + std::to_string(max_id)
-
5243  );
-
5244 
-
5245  if (j > max_id)
-
5246  throw std::range_error(
-
5247  "The target["+std::to_string(linenum)+"] = " + std::to_string(j) +
-
5248  " is above the max_id " + std::to_string(max_id)
-
5249  );
+
5239  if (!filei)
+
5240  throw std::logic_error("The file " + fn + " was not found.");
+
5241 
+
5242  int linenum = 0;
+
5243  std::vector< int > source_;
+
5244  std::vector< int > target_;
+
5245 
+
5246  source_.reserve(1e5);
+
5247  target_.reserve(1e5);
+
5248 
+
5249  int max_id = size - 1;
5250 
-
5251  source_.push_back(i);
-
5252  target_.push_back(j);
+
5251  while (!filei.eof())
+
5252  {
5253 
-
5254  }
-
5255 
-
5256  // Now using the right constructor
-
5257  *this = AdjList(source_, target_, size, directed);
+
5254  if (linenum++ < skip)
+
5255  continue;
+
5256 
+
5257  filei >> i >> j;
5258 
-
5259  return;
-
5260 
-
5261 }
-
5262 
-
5263 inline std::map<int,int> AdjList::operator()(
-
5264  epiworld_fast_uint i
-
5265  ) const {
-
5266 
-
5267  if (i >= N)
-
5268  throw std::range_error(
-
5269  "The vertex id " + std::to_string(i) + " is not in the network."
-
5270  );
-
5271 
-
5272  return dat[i];
-
5273 
-
5274 }
-
5275 
-
5276 inline void AdjList::print(epiworld_fast_uint limit) const {
-
5277 
-
5278 
-
5279  epiworld_fast_uint counter = 0;
-
5280  printf_epiworld("Nodeset:\n");
-
5281  int i = -1;
-
5282  for (auto & n : dat)
-
5283  {
-
5284 
-
5285  if (counter++ > limit)
-
5286  break;
-
5287 
-
5288  printf_epiworld(" % 3i: {", ++i);
-
5289  int niter = 0;
-
5290  for (auto n_n : n)
-
5291  if (++niter < static_cast<int>(n.size()))
-
5292  {
-
5293  printf_epiworld("%i, ", static_cast<int>(n_n.first));
-
5294  }
-
5295  else {
-
5296  printf_epiworld("%i}\n", static_cast<int>(n_n.first));
-
5297  }
-
5298  }
-
5299 
-
5300  if (limit < dat.size())
-
5301  {
-
5302  printf_epiworld(
-
5303  " (... skipping %i records ...)\n",
-
5304  static_cast<int>(dat.size() - limit)
-
5305  );
-
5306  }
+
5259  // Looking for exceptions
+
5260  if (filei.bad())
+
5261  throw std::logic_error(
+
5262  "I/O error while reading the file " +
+
5263  fn
+
5264  );
+
5265 
+
5266  if (filei.fail())
+
5267  break;
+
5268 
+
5269  if (i > max_id)
+
5270  throw std::range_error(
+
5271  "The source["+std::to_string(linenum)+"] = " + std::to_string(i) +
+
5272  " is above the max_id " + std::to_string(max_id)
+
5273  );
+
5274 
+
5275  if (j > max_id)
+
5276  throw std::range_error(
+
5277  "The target["+std::to_string(linenum)+"] = " + std::to_string(j) +
+
5278  " is above the max_id " + std::to_string(max_id)
+
5279  );
+
5280 
+
5281  source_.push_back(i);
+
5282  target_.push_back(j);
+
5283 
+
5284  }
+
5285 
+
5286  // Now using the right constructor
+
5287  *this = AdjList(source_, target_, size, directed);
+
5288 
+
5289  return;
+
5290 
+
5291 }
+
5292 
+
5293 inline std::map<int,int> AdjList::operator()(
+
5294  epiworld_fast_uint i
+
5295  ) const {
+
5296 
+
5297  if (i >= N)
+
5298  throw std::range_error(
+
5299  "The vertex id " + std::to_string(i) + " is not in the network."
+
5300  );
+
5301 
+
5302  return dat[i];
+
5303 
+
5304 }
+
5305 
+
5306 inline void AdjList::print(epiworld_fast_uint limit) const {
5307 
-
5308 }
-
5309 
-
5310 inline size_t AdjList::vcount() const
-
5311 {
-
5312  return N;
-
5313 }
+
5308 
+
5309  epiworld_fast_uint counter = 0;
+
5310  printf_epiworld("Nodeset:\n");
+
5311  int i = -1;
+
5312  for (auto & n : dat)
+
5313  {
5314 
-
5315 inline size_t AdjList::ecount() const
-
5316 {
-
5317  return E;
-
5318 }
-
5319 
-
5320 inline bool AdjList::is_directed() const {
-
5321 
-
5322  if (dat.size() == 0u)
-
5323  throw std::logic_error("The edgelist is empty.");
-
5324 
-
5325  return directed;
-
5326 
-
5327 }
-
5328 
-
5329 #endif
-
5330 /*//////////////////////////////////////////////////////////////////////////////
-
5332 
-
5333  End of -include/epiworld/adjlist-meat.hpp-
-
5334 
+
5315  if (counter++ > limit)
+
5316  break;
+
5317 
+
5318  printf_epiworld(" % 3i: {", ++i);
+
5319  int niter = 0;
+
5320  for (auto n_n : n)
+
5321  if (++niter < static_cast<int>(n.size()))
+
5322  {
+
5323  printf_epiworld("%i, ", static_cast<int>(n_n.first));
+
5324  }
+
5325  else {
+
5326  printf_epiworld("%i}\n", static_cast<int>(n_n.first));
+
5327  }
+
5328  }
+
5329 
+
5330  if (limit < dat.size())
+
5331  {
+
5332  printf_epiworld(
+
5333  " (... skipping %i records ...)\n",
+
5334  static_cast<int>(dat.size() - limit)
+
5335  );
+
5336  }
5337 
-
5338 
+
5338 }
5339 
-
5340 /*//////////////////////////////////////////////////////////////////////////////
-
5342 
-
5343  Start of -include/epiworld/randgraph.hpp-
+
5340 inline size_t AdjList::vcount() const
+
5341 {
+
5342  return N;
+
5343 }
5344 
-
5347 
-
5348 
-
5349 #ifndef EPIWORLD_RANDGRA
-
5350 #define EPIWORLD_RANDGRA
+
5345 inline size_t AdjList::ecount() const
+
5346 {
+
5347  return E;
+
5348 }
+
5349 
+
5350 inline bool AdjList::is_directed() const {
5351 
-
5352 template<typename TSeq>
-
5353 class Model;
-
5354 
-
5355 template<typename TSeq>
-
5356 class Agent;
-
5357 
-
5358 class AdjList;
-
5359 
-
5360 
-
5361 template<typename TSeq, typename TDat>
-
5362 inline void rewire_degseq(
-
5363  TDat * agents,
-
5364  Model<TSeq> * model,
-
5365  epiworld_double proportion
-
5366  );
+
5352  if (dat.size() == 0u)
+
5353  throw std::logic_error("The edgelist is empty.");
+
5354 
+
5355  return directed;
+
5356 
+
5357 }
+
5358 
+
5359 #endif
+
5360 /*//////////////////////////////////////////////////////////////////////////////
+
5362 
+
5363  End of -include/epiworld/adjlist-meat.hpp-
+
5364 
5367 
-
5368 template<typename TSeq = int>
-
5369 inline void rewire_degseq(
-
5370  std::vector< Agent<TSeq> > * agents,
-
5371  Model<TSeq> * model,
-
5372  epiworld_double proportion
-
5373  )
-
5374 {
-
5375 
-
5376  #ifdef EPI_DEBUG
-
5377  std::vector< int > _degree0(agents->size(), 0);
-
5378  for (size_t i = 0u; i < _degree0.size(); ++i)
-
5379  _degree0[i] = model->get_agents()[i].get_neighbors().size();
-
5380  #endif
+
5368 
+
5369 
+
5370 /*//////////////////////////////////////////////////////////////////////////////
+
5372 
+
5373  Start of -include/epiworld/randgraph.hpp-
+
5374 
+
5377 
+
5378 
+
5379 #ifndef EPIWORLD_RANDGRA
+
5380 #define EPIWORLD_RANDGRA
5381 
-
5382  // Identifying individuals with degree > 0
-
5383  std::vector< epiworld_fast_uint > non_isolates;
-
5384  std::vector< epiworld_double > weights;
-
5385  epiworld_double nedges = 0.0;
-
5386 
-
5387  for (epiworld_fast_uint i = 0u; i < agents->size(); ++i)
-
5388  {
-
5389  if (agents->operator[](i).get_neighbors().size() > 0u)
-
5390  {
-
5391  non_isolates.push_back(i);
-
5392  epiworld_double wtemp = static_cast<epiworld_double>(
-
5393  agents->operator[](i).get_neighbors().size()
-
5394  );
-
5395  weights.push_back(wtemp);
-
5396  nedges += wtemp;
-
5397  }
-
5398  }
-
5399 
-
5400  if (non_isolates.size() == 0u)
-
5401  throw std::logic_error("The graph is completely disconnected.");
-
5402 
-
5403  // Cumulative probs
-
5404  weights[0u] /= nedges;
-
5405  for (epiworld_fast_uint i = 1u; i < non_isolates.size(); ++i)
-
5406  {
-
5407  weights[i] /= nedges;
-
5408  weights[i] += weights[i - 1u];
-
5409  }
-
5410 
-
5411  // Only swap if needed
-
5412  epiworld_fast_uint N = non_isolates.size();
-
5413  epiworld_double prob;
-
5414  int nrewires = floor(proportion * nedges);
-
5415  while (nrewires-- > 0)
-
5416  {
-
5417 
-
5418  // Picking egos
-
5419  prob = model->runif();
-
5420  int id0 = N - 1;
-
5421  for (epiworld_fast_uint i = 0u; i < N; ++i)
-
5422  if (prob <= weights[i])
-
5423  {
-
5424  id0 = i;
-
5425  break;
-
5426  }
-
5427 
-
5428  prob = model->runif();
-
5429  int id1 = N - 1;
-
5430  for (epiworld_fast_uint i = 0u; i < N; ++i)
-
5431  if (prob <= weights[i])
-
5432  {
-
5433  id1 = i;
-
5434  break;
-
5435  }
-
5436 
-
5437  // Correcting for under or overflow.
-
5438  if (id1 == id0)
-
5439  id1++;
+
5382 template<typename TSeq>
+
5383 class Model;
+
5384 
+
5385 template<typename TSeq>
+
5386 class Agent;
+
5387 
+
5388 class AdjList;
+
5389 
+
5390 
+
5391 template<typename TSeq, typename TDat>
+
5392 inline void rewire_degseq(
+
5393  TDat * agents,
+
5394  Model<TSeq> * model,
+
5395  epiworld_double proportion
+
5396  );
+
5397 
+
5398 template<typename TSeq = int>
+
5399 inline void rewire_degseq(
+
5400  std::vector< Agent<TSeq> > * agents,
+
5401  Model<TSeq> * model,
+
5402  epiworld_double proportion
+
5403  )
+
5404 {
+
5405 
+
5406  #ifdef EPI_DEBUG
+
5407  std::vector< int > _degree0(agents->size(), 0);
+
5408  for (size_t i = 0u; i < _degree0.size(); ++i)
+
5409  _degree0[i] = model->get_agents()[i].get_neighbors().size();
+
5410  #endif
+
5411 
+
5412  // Identifying individuals with degree > 0
+
5413  std::vector< epiworld_fast_uint > non_isolates;
+
5414  std::vector< epiworld_double > weights;
+
5415  epiworld_double nedges = 0.0;
+
5416 
+
5417  for (epiworld_fast_uint i = 0u; i < agents->size(); ++i)
+
5418  {
+
5419  if (agents->operator[](i).get_neighbors().size() > 0u)
+
5420  {
+
5421  non_isolates.push_back(i);
+
5422  epiworld_double wtemp = static_cast<epiworld_double>(
+
5423  agents->operator[](i).get_neighbors().size()
+
5424  );
+
5425  weights.push_back(wtemp);
+
5426  nedges += wtemp;
+
5427  }
+
5428  }
+
5429 
+
5430  if (non_isolates.size() == 0u)
+
5431  throw std::logic_error("The graph is completely disconnected.");
+
5432 
+
5433  // Cumulative probs
+
5434  weights[0u] /= nedges;
+
5435  for (epiworld_fast_uint i = 1u; i < non_isolates.size(); ++i)
+
5436  {
+
5437  weights[i] /= nedges;
+
5438  weights[i] += weights[i - 1u];
+
5439  }
5440 
-
5441  if (id1 >= static_cast<int>(N))
-
5442  id1 = 0;
-
5443 
-
5444  Agent<TSeq> & p0 = agents->operator[](non_isolates[id0]);
-
5445  Agent<TSeq> & p1 = agents->operator[](non_isolates[id1]);
-
5446 
-
5447  // Picking alters (relative location in their lists)
-
5448  // In this case, these are uniformly distributed within the list
-
5449  int id01 = std::floor(p0.get_n_neighbors() * model->runif());
-
5450  int id11 = std::floor(p1.get_n_neighbors() * model->runif());
-
5451 
-
5452  // When rewiring, we need to flip the individuals from the other
-
5453  // end as well, since we are dealing withi an undirected graph
-
5454 
-
5455  // Finding what neighbour is id0
-
5456  model->get_agents()[id0].swap_neighbors(
-
5457  model->get_agents()[id1],
-
5458  id01,
-
5459  id11
-
5460  );
-
5461 
-
5462 
-
5463  }
-
5464 
-
5465  #ifdef EPI_DEBUG
-
5466  for (size_t _i = 0u; _i < _degree0.size(); ++_i)
-
5467  {
-
5468  if (_degree0[_i] != static_cast<int>(model->get_agents()[_i].get_n_neighbors()))
-
5469  throw std::logic_error("[epi-debug] Degree does not match afted rewire_degseq.");
-
5470  }
-
5471  #endif
-
5472 
-
5473  return;
-
5474 
-
5475 }
+
5441  // Only swap if needed
+
5442  epiworld_fast_uint N = non_isolates.size();
+
5443  epiworld_double prob;
+
5444  int nrewires = floor(proportion * nedges);
+
5445  while (nrewires-- > 0)
+
5446  {
+
5447 
+
5448  // Picking egos
+
5449  prob = model->runif();
+
5450  int id0 = N - 1;
+
5451  for (epiworld_fast_uint i = 0u; i < N; ++i)
+
5452  if (prob <= weights[i])
+
5453  {
+
5454  id0 = i;
+
5455  break;
+
5456  }
+
5457 
+
5458  prob = model->runif();
+
5459  int id1 = N - 1;
+
5460  for (epiworld_fast_uint i = 0u; i < N; ++i)
+
5461  if (prob <= weights[i])
+
5462  {
+
5463  id1 = i;
+
5464  break;
+
5465  }
+
5466 
+
5467  // Correcting for under or overflow.
+
5468  if (id1 == id0)
+
5469  id1++;
+
5470 
+
5471  if (id1 >= static_cast<int>(N))
+
5472  id1 = 0;
+
5473 
+
5474  Agent<TSeq> & p0 = agents->operator[](non_isolates[id0]);
+
5475  Agent<TSeq> & p1 = agents->operator[](non_isolates[id1]);
5476 
-
5477 template<typename TSeq>
-
5478 inline void rewire_degseq(
-
5479  AdjList * agents,
-
5480  Model<TSeq> * model,
-
5481  epiworld_double proportion
-
5482  )
-
5483 {
-
5484 
-
5485  // Identifying individuals with degree > 0
-
5486  std::vector< epiworld_fast_int > nties(agents->vcount(), 0);
-
5487 
-
5488  #ifdef EPI_DEBUG
-
5489  std::vector< int > _degree0(agents->vcount(), 0);
-
5490  for (size_t i = 0u; i < _degree0.size(); ++i)
-
5491  _degree0[i] = agents->get_dat()[i].size();
-
5492  #endif
-
5493 
-
5494  std::vector< epiworld_fast_uint > non_isolates;
-
5495  non_isolates.reserve(nties.size());
-
5496 
-
5497  std::vector< epiworld_double > weights;
-
5498  weights.reserve(nties.size());
-
5499 
-
5500  epiworld_double nedges = 0.0;
-
5501  auto & dat = agents->get_dat();
+
5477  // Picking alters (relative location in their lists)
+
5478  // In this case, these are uniformly distributed within the list
+
5479  int id01 = std::floor(p0.get_n_neighbors() * model->runif());
+
5480  int id11 = std::floor(p1.get_n_neighbors() * model->runif());
+
5481 
+
5482  // When rewiring, we need to flip the individuals from the other
+
5483  // end as well, since we are dealing withi an undirected graph
+
5484 
+
5485  // Finding what neighbour is id0
+
5486  model->get_agents()[id0].swap_neighbors(
+
5487  model->get_agents()[id1],
+
5488  id01,
+
5489  id11
+
5490  );
+
5491 
+
5492 
+
5493  }
+
5494 
+
5495  #ifdef EPI_DEBUG
+
5496  for (size_t _i = 0u; _i < _degree0.size(); ++_i)
+
5497  {
+
5498  if (_degree0[_i] != static_cast<int>(model->get_agents()[_i].get_n_neighbors()))
+
5499  throw std::logic_error("[epi-debug] Degree does not match afted rewire_degseq.");
+
5500  }
+
5501  #endif
5502 
-
5503  for (size_t i = 0u; i < dat.size(); ++i)
-
5504  nties[i] += dat[i].size();
-
5505 
-
5506  bool directed = agents->is_directed();
-
5507  for (size_t i = 0u; i < dat.size(); ++i)
-
5508  {
-
5509  if (nties[i] > 0)
-
5510  {
-
5511  non_isolates.push_back(i);
-
5512  if (directed)
-
5513  {
-
5514  weights.push_back(
-
5515  static_cast<epiworld_double>(nties[i])
-
5516  );
-
5517  nedges += static_cast<epiworld_double>(nties[i]);
-
5518  }
-
5519  else {
-
5520  weights.push_back(
-
5521  static_cast<epiworld_double>(nties[i])/2.0
-
5522  );
-
5523  nedges += static_cast<epiworld_double>(nties[i]) / 2.0;
-
5524  }
-
5525  }
-
5526  }
-
5527 
-
5528  if (non_isolates.size() == 0u)
-
5529  throw std::logic_error("The graph is completely disconnected.");
-
5530 
-
5531  // Cumulative probs
-
5532  weights[0u] /= nedges;
-
5533  for (epiworld_fast_uint i = 1u; i < non_isolates.size(); ++i)
-
5534  {
-
5535  weights[i] /= nedges;
-
5536  weights[i] += weights[i - 1u];
-
5537  }
-
5538 
-
5539  // Only swap if needed
-
5540  epiworld_fast_uint N = non_isolates.size();
-
5541  epiworld_double prob;
-
5542  int nrewires = floor(proportion * nedges / (
-
5543  agents->is_directed() ? 1.0 : 2.0
-
5544  ));
-
5545 
-
5546  while (nrewires-- > 0)
-
5547  {
-
5548 
-
5549  // Picking egos
-
5550  prob = model->runif();
-
5551  int id0 = N - 1;
-
5552  for (epiworld_fast_uint i = 0u; i < N; ++i)
-
5553  if (prob <= weights[i])
-
5554  {
-
5555  id0 = i;
-
5556  break;
-
5557  }
-
5558 
-
5559  prob = model->runif();
-
5560  int id1 = N - 1;
-
5561  for (epiworld_fast_uint i = 0u; i < N; ++i)
-
5562  if (prob <= weights[i])
-
5563  {
-
5564  id1 = i;
-
5565  break;
-
5566  }
-
5567 
-
5568  // Correcting for under or overflow.
-
5569  if (id1 == id0)
-
5570  id1++;
-
5571 
-
5572  if (id1 >= static_cast<int>(N))
-
5573  id1 = 0;
-
5574 
-
5575  std::map<int,int> & p0 = agents->get_dat()[non_isolates[id0]];
-
5576  std::map<int,int> & p1 = agents->get_dat()[non_isolates[id1]];
-
5577 
-
5578  // Picking alters (relative location in their lists)
-
5579  // In this case, these are uniformly distributed within the list
-
5580  int id01 = std::floor(p0.size() * model->runif());
-
5581  int id11 = std::floor(p1.size() * model->runif());
-
5582 
-
5583  // Since it is a map, we need to find the actual ids (positions)
-
5584  // are not good enough.
-
5585  int count = 0;
-
5586  for (auto & n : p0)
-
5587  if (count++ == id01)
-
5588  id01 = n.first;
-
5589 
-
5590  count = 0;
-
5591  for (auto & n : p1)
-
5592  if (count++ == id11)
-
5593  id11 = n.first;
-
5594 
-
5595  // When rewiring, we need to flip the individuals from the other
-
5596  // end as well, since we are dealing withi an undirected graph
-
5597 
-
5598  // Finding what neighbour is id0
-
5599  if (!agents->is_directed())
-
5600  {
+
5503  return;
+
5504 
+
5505 }
+
5506 
+
5507 template<typename TSeq>
+
5508 inline void rewire_degseq(
+
5509  AdjList * agents,
+
5510  Model<TSeq> * model,
+
5511  epiworld_double proportion
+
5512  )
+
5513 {
+
5514 
+
5515  // Identifying individuals with degree > 0
+
5516  std::vector< epiworld_fast_int > nties(agents->vcount(), 0);
+
5517 
+
5518  #ifdef EPI_DEBUG
+
5519  std::vector< int > _degree0(agents->vcount(), 0);
+
5520  for (size_t i = 0u; i < _degree0.size(); ++i)
+
5521  _degree0[i] = agents->get_dat()[i].size();
+
5522  #endif
+
5523 
+
5524  std::vector< epiworld_fast_uint > non_isolates;
+
5525  non_isolates.reserve(nties.size());
+
5526 
+
5527  std::vector< epiworld_double > weights;
+
5528  weights.reserve(nties.size());
+
5529 
+
5530  epiworld_double nedges = 0.0;
+
5531  auto & dat = agents->get_dat();
+
5532 
+
5533  for (size_t i = 0u; i < dat.size(); ++i)
+
5534  nties[i] += dat[i].size();
+
5535 
+
5536  bool directed = agents->is_directed();
+
5537  for (size_t i = 0u; i < dat.size(); ++i)
+
5538  {
+
5539  if (nties[i] > 0)
+
5540  {
+
5541  non_isolates.push_back(i);
+
5542  if (directed)
+
5543  {
+
5544  weights.push_back(
+
5545  static_cast<epiworld_double>(nties[i])
+
5546  );
+
5547  nedges += static_cast<epiworld_double>(nties[i]);
+
5548  }
+
5549  else {
+
5550  weights.push_back(
+
5551  static_cast<epiworld_double>(nties[i])/2.0
+
5552  );
+
5553  nedges += static_cast<epiworld_double>(nties[i]) / 2.0;
+
5554  }
+
5555  }
+
5556  }
+
5557 
+
5558  if (non_isolates.size() == 0u)
+
5559  throw std::logic_error("The graph is completely disconnected.");
+
5560 
+
5561  // Cumulative probs
+
5562  weights[0u] /= nedges;
+
5563  for (epiworld_fast_uint i = 1u; i < non_isolates.size(); ++i)
+
5564  {
+
5565  weights[i] /= nedges;
+
5566  weights[i] += weights[i - 1u];
+
5567  }
+
5568 
+
5569  // Only swap if needed
+
5570  epiworld_fast_uint N = non_isolates.size();
+
5571  epiworld_double prob;
+
5572  int nrewires = floor(proportion * nedges / (
+
5573  agents->is_directed() ? 1.0 : 2.0
+
5574  ));
+
5575 
+
5576  while (nrewires-- > 0)
+
5577  {
+
5578 
+
5579  // Picking egos
+
5580  prob = model->runif();
+
5581  int id0 = N - 1;
+
5582  for (epiworld_fast_uint i = 0u; i < N; ++i)
+
5583  if (prob <= weights[i])
+
5584  {
+
5585  id0 = i;
+
5586  break;
+
5587  }
+
5588 
+
5589  prob = model->runif();
+
5590  int id1 = N - 1;
+
5591  for (epiworld_fast_uint i = 0u; i < N; ++i)
+
5592  if (prob <= weights[i])
+
5593  {
+
5594  id1 = i;
+
5595  break;
+
5596  }
+
5597 
+
5598  // Correcting for under or overflow.
+
5599  if (id1 == id0)
+
5600  id1++;
5601 
-
5602  std::map<int,int> & p01 = agents->get_dat()[id01];
-
5603  std::map<int,int> & p11 = agents->get_dat()[id11];
+
5602  if (id1 >= static_cast<int>(N))
+
5603  id1 = 0;
5604 
-
5605  std::swap(p01[id0], p11[id1]);
-
5606 
-
5607  }
-
5608 
-
5609  // Moving alter first
-
5610  std::swap(p0[id01], p1[id11]);
-
5611 
-
5612  }
-
5613 
-
5614  #ifdef EPI_DEBUG
-
5615  for (size_t _i = 0u; _i < _degree0.size(); ++_i)
-
5616  {
-
5617  if (_degree0[_i] != static_cast<int>(agents->get_dat()[_i].size()))
-
5618  throw std::logic_error(
-
5619  "[epi-debug] Degree does not match afted rewire_degseq. " +
-
5620  std::string("Expected: ") +
-
5621  std::to_string(_degree0[_i]) +
-
5622  std::string(", observed: ") +
-
5623  std::to_string(agents->get_dat()[_i].size())
-
5624  );
-
5625  }
-
5626  #endif
-
5627 
-
5628 
-
5629  return;
-
5630 
-
5631 }
-
5632 
-
5633 template<typename TSeq>
-
5634 inline AdjList rgraph_bernoulli(
-
5635  epiworld_fast_uint n,
-
5636  epiworld_double p,
-
5637  bool directed,
-
5638  Model<TSeq> & model
-
5639 ) {
-
5640 
-
5641  std::vector< int > source;
-
5642  std::vector< int > target;
+
5605  std::map<int,int> & p0 = agents->get_dat()[non_isolates[id0]];
+
5606  std::map<int,int> & p1 = agents->get_dat()[non_isolates[id1]];
+
5607 
+
5608  // Picking alters (relative location in their lists)
+
5609  // In this case, these are uniformly distributed within the list
+
5610  int id01 = std::floor(p0.size() * model->runif());
+
5611  int id11 = std::floor(p1.size() * model->runif());
+
5612 
+
5613  // Since it is a map, we need to find the actual ids (positions)
+
5614  // are not good enough.
+
5615  int count = 0;
+
5616  for (auto & n : p0)
+
5617  if (count++ == id01)
+
5618  id01 = n.first;
+
5619 
+
5620  count = 0;
+
5621  for (auto & n : p1)
+
5622  if (count++ == id11)
+
5623  id11 = n.first;
+
5624 
+
5625  // When rewiring, we need to flip the individuals from the other
+
5626  // end as well, since we are dealing withi an undirected graph
+
5627 
+
5628  // Finding what neighbour is id0
+
5629  if (!agents->is_directed())
+
5630  {
+
5631 
+
5632  std::map<int,int> & p01 = agents->get_dat()[id01];
+
5633  std::map<int,int> & p11 = agents->get_dat()[id11];
+
5634 
+
5635  std::swap(p01[id0], p11[id1]);
+
5636 
+
5637  }
+
5638 
+
5639  // Moving alter first
+
5640  std::swap(p0[id01], p1[id11]);
+
5641 
+
5642  }
5643 
-
5644  // Checking the density (how many)
-
5645  std::binomial_distribution<> d(
-
5646  n * (n - 1.0) / (directed ? 1.0 : 2.0),
-
5647  p
-
5648  );
-
5649 
-
5650  epiworld_fast_uint m = d(model.get_rand_endgine());
-
5651 
-
5652  source.resize(m);
-
5653  target.resize(m);
-
5654 
-
5655  epiworld_fast_uint a,b;
-
5656  for (epiworld_fast_uint i = 0u; i < m; ++i)
-
5657  {
-
5658  a = floor(model.runif() * n);
-
5659 
-
5660  if (!directed)
-
5661  b = floor(model.runif() * a);
-
5662  else
-
5663  {
-
5664  b = floor(model.runif() * n);
-
5665  if (b == a)
-
5666  b++;
-
5667 
-
5668  if (b >= n)
-
5669  b = 0u;
-
5670  }
-
5671 
-
5672  source[i] = static_cast<int>(a);
-
5673  target[i] = static_cast<int>(b);
-
5674 
-
5675  }
-
5676 
-
5677  AdjList al(source, target, static_cast<int>(n), directed);
-
5678 
-
5679  return al;
-
5680 
-
5681 }
-
5682 
-
5683 template<typename TSeq>
-
5684 inline AdjList rgraph_bernoulli2(
-
5685  epiworld_fast_uint n,
-
5686  epiworld_double p,
-
5687  bool directed,
-
5688  Model<TSeq> & model
-
5689 ) {
-
5690 
-
5691  std::vector< int > source;
-
5692  std::vector< int > target;
-
5693 
-
5694  // Checking the density (how many)
-
5695  std::binomial_distribution<> d(
-
5696  n * (n - 1.0) / (directed ? 1.0 : 2.0),
-
5697  p
-
5698  );
-
5699 
-
5700  // Need to compensate for the possible number of diagonal
-
5701  // elements sampled. If n * n, then each diag element has
-
5702  // 1/(n^2) chance of sampling
-
5703 
-
5704  epiworld_fast_uint m = d(model.get_rand_endgine());
-
5705 
-
5706  source.resize(m);
-
5707  target.resize(m);
+
5644  #ifdef EPI_DEBUG
+
5645  for (size_t _i = 0u; _i < _degree0.size(); ++_i)
+
5646  {
+
5647  if (_degree0[_i] != static_cast<int>(agents->get_dat()[_i].size()))
+
5648  throw std::logic_error(
+
5649  "[epi-debug] Degree does not match afted rewire_degseq. " +
+
5650  std::string("Expected: ") +
+
5651  std::to_string(_degree0[_i]) +
+
5652  std::string(", observed: ") +
+
5653  std::to_string(agents->get_dat()[_i].size())
+
5654  );
+
5655  }
+
5656  #endif
+
5657 
+
5658 
+
5659  return;
+
5660 
+
5661 }
+
5662 
+
5663 template<typename TSeq>
+
5664 inline AdjList rgraph_bernoulli(
+
5665  epiworld_fast_uint n,
+
5666  epiworld_double p,
+
5667  bool directed,
+
5668  Model<TSeq> & model
+
5669 ) {
+
5670 
+
5671  std::vector< int > source;
+
5672  std::vector< int > target;
+
5673 
+
5674  // Checking the density (how many)
+
5675  std::binomial_distribution<> d(
+
5676  n * (n - 1.0) / (directed ? 1.0 : 2.0),
+
5677  p
+
5678  );
+
5679 
+
5680  epiworld_fast_uint m = d(model.get_rand_endgine());
+
5681 
+
5682  source.resize(m);
+
5683  target.resize(m);
+
5684 
+
5685  epiworld_fast_uint a,b;
+
5686  for (epiworld_fast_uint i = 0u; i < m; ++i)
+
5687  {
+
5688  a = floor(model.runif() * n);
+
5689 
+
5690  if (!directed)
+
5691  b = floor(model.runif() * a);
+
5692  else
+
5693  {
+
5694  b = floor(model.runif() * n);
+
5695  if (b == a)
+
5696  b++;
+
5697 
+
5698  if (b >= n)
+
5699  b = 0u;
+
5700  }
+
5701 
+
5702  source[i] = static_cast<int>(a);
+
5703  target[i] = static_cast<int>(b);
+
5704 
+
5705  }
+
5706 
+
5707  AdjList al(source, target, static_cast<int>(n), directed);
5708 
-
5709  double n2 = static_cast<double>(n * n);
-
5710 
-
5711  int loc,row,col;
-
5712  for (epiworld_fast_uint i = 0u; i < m; ++i)
-
5713  {
-
5714  loc = floor(model.runif() * n2);
-
5715  col = floor(static_cast<double>(loc)/static_cast<double>(n));
-
5716  row = loc - row * n;
-
5717 
-
5718  // Undirected needs to swap
-
5719  if (!directed && (col > row))
-
5720  std::swap(col, row);
-
5721 
-
5722  source[i] = row;
-
5723  target[i] = col;
-
5724 
-
5725  }
-
5726 
-
5727  AdjList al(source, target, static_cast<int>(n), directed);
-
5728 
-
5729  return al;
-
5730 
-
5731 }
-
5732 
-
5733 inline AdjList rgraph_ring_lattice(
-
5734  epiworld_fast_uint n,
-
5735  epiworld_fast_uint k,
-
5736  bool directed = false
-
5737 ) {
+
5709  return al;
+
5710 
+
5711 }
+
5712 
+
5713 template<typename TSeq>
+
5714 inline AdjList rgraph_bernoulli2(
+
5715  epiworld_fast_uint n,
+
5716  epiworld_double p,
+
5717  bool directed,
+
5718  Model<TSeq> & model
+
5719 ) {
+
5720 
+
5721  std::vector< int > source;
+
5722  std::vector< int > target;
+
5723 
+
5724  // Checking the density (how many)
+
5725  std::binomial_distribution<> d(
+
5726  n * (n - 1.0) / (directed ? 1.0 : 2.0),
+
5727  p
+
5728  );
+
5729 
+
5730  // Need to compensate for the possible number of diagonal
+
5731  // elements sampled. If n * n, then each diag element has
+
5732  // 1/(n^2) chance of sampling
+
5733 
+
5734  epiworld_fast_uint m = d(model.get_rand_endgine());
+
5735 
+
5736  source.resize(m);
+
5737  target.resize(m);
5738 
-
5739  if ((n - 1u) < k)
-
5740  throw std::logic_error("k can be at most n - 1.");
-
5741 
-
5742  std::vector< int > source;
-
5743  std::vector< int > target;
-
5744 
-
5745  if (!directed)
-
5746  if (k > 1u) k = static_cast< size_t >(floor(k / 2.0));
+
5739  double n2 = static_cast<double>(n * n);
+
5740 
+
5741  int loc,row,col;
+
5742  for (epiworld_fast_uint i = 0u; i < m; ++i)
+
5743  {
+
5744  loc = floor(model.runif() * n2);
+
5745  col = floor(static_cast<double>(loc)/static_cast<double>(n));
+
5746  row = loc - row * n;
5747 
-
5748  for (size_t i = 0; i < n; ++i)
-
5749  {
-
5750 
-
5751  for (size_t j = 1u; j <= k; ++j)
-
5752  {
-
5753 
-
5754  // Next neighbor
-
5755  size_t l = i + j;
-
5756  if (l >= n) l = l - n;
-
5757 
-
5758  source.push_back(i);
-
5759  target.push_back(l);
-
5760 
-
5761  }
+
5748  // Undirected needs to swap
+
5749  if (!directed && (col > row))
+
5750  std::swap(col, row);
+
5751 
+
5752  source[i] = row;
+
5753  target[i] = col;
+
5754 
+
5755  }
+
5756 
+
5757  AdjList al(source, target, static_cast<int>(n), directed);
+
5758 
+
5759  return al;
+
5760 
+
5761 }
5762 
-
5763  }
-
5764 
-
5765  return AdjList(source, target, n, directed);
-
5766 
-
5767 }
+
5763 inline AdjList rgraph_ring_lattice(
+
5764  epiworld_fast_uint n,
+
5765  epiworld_fast_uint k,
+
5766  bool directed = false
+
5767 ) {
5768 
-
5780 template<typename TSeq>
-
5781 inline AdjList rgraph_smallworld(
-
5782  epiworld_fast_uint n,
-
5783  epiworld_fast_uint k,
-
5784  epiworld_double p,
-
5785  bool directed,
-
5786  Model<TSeq> & model
-
5787 ) {
-
5788 
-
5789  // Creating the ring lattice
-
5790  AdjList ring = rgraph_ring_lattice(n,k,directed);
-
5791 
-
5792  // Rewiring and returning
-
5793  if (k > 0u)
-
5794  rewire_degseq(&ring, &model, p);
-
5795 
-
5796  return ring;
-
5797 
-
5798 }
-
5799 
-
5813 template<typename TSeq>
-
5814 inline AdjList rgraph_blocked(
-
5815  epiworld_fast_uint n,
-
5816  epiworld_fast_uint blocksize,
-
5817  epiworld_fast_uint ncons,
-
5818  Model<TSeq>&
-
5819 ) {
-
5820 
-
5821  std::vector< int > source_;
-
5822  std::vector< int > target_;
-
5823 
-
5824  size_t i = 0u;
-
5825  size_t cum_node_count = 0u;
-
5826  while (i < n)
-
5827  {
-
5828 
-
5829  for (size_t j = 0; j < blocksize; ++j)
-
5830  {
-
5831 
-
5832  for (size_t k = 0; k < j; ++k)
-
5833  {
-
5834  // No loops
-
5835  if (k == j)
-
5836  continue;
-
5837 
-
5838  // Exists the loop in case there are no more
-
5839  // nodes available
-
5840  if ((i + k) >= n)
-
5841  break;
-
5842 
-
5843  source_.push_back(static_cast<int>(j + i));
-
5844  target_.push_back(static_cast<int>(k + i));
-
5845  }
-
5846 
-
5847  // No more nodes left to build connections
-
5848  if (++cum_node_count >= n)
-
5849  break;
-
5850 
-
5851  }
-
5852 
-
5853  // Connections between this and the previou sone
-
5854  if (i != 0)
-
5855  {
-
5856 
-
5857  size_t max_cons = std::min(ncons, n - cum_node_count);
+
5769  if ((n - 1u) < k)
+
5770  throw std::logic_error("k can be at most n - 1.");
+
5771 
+
5772  std::vector< int > source;
+
5773  std::vector< int > target;
+
5774 
+
5775  if (!directed)
+
5776  if (k > 1u) k = static_cast< size_t >(floor(k / 2.0));
+
5777 
+
5778  for (size_t i = 0; i < n; ++i)
+
5779  {
+
5780 
+
5781  for (size_t j = 1u; j <= k; ++j)
+
5782  {
+
5783 
+
5784  // Next neighbor
+
5785  size_t l = i + j;
+
5786  if (l >= n) l = l - n;
+
5787 
+
5788  source.push_back(i);
+
5789  target.push_back(l);
+
5790 
+
5791  }
+
5792 
+
5793  }
+
5794 
+
5795  return AdjList(source, target, n, directed);
+
5796 
+
5797 }
+
5798 
+
5810 template<typename TSeq>
+
5811 inline AdjList rgraph_smallworld(
+
5812  epiworld_fast_uint n,
+
5813  epiworld_fast_uint k,
+
5814  epiworld_double p,
+
5815  bool directed,
+
5816  Model<TSeq> & model
+
5817 ) {
+
5818 
+
5819  // Creating the ring lattice
+
5820  AdjList ring = rgraph_ring_lattice(n,k,directed);
+
5821 
+
5822  // Rewiring and returning
+
5823  if (k > 0u)
+
5824  rewire_degseq(&ring, &model, p);
+
5825 
+
5826  return ring;
+
5827 
+
5828 }
+
5829 
+
5843 template<typename TSeq>
+
5844 inline AdjList rgraph_blocked(
+
5845  epiworld_fast_uint n,
+
5846  epiworld_fast_uint blocksize,
+
5847  epiworld_fast_uint ncons,
+
5848  Model<TSeq>&
+
5849 ) {
+
5850 
+
5851  std::vector< int > source_;
+
5852  std::vector< int > target_;
+
5853 
+
5854  size_t i = 0u;
+
5855  size_t cum_node_count = 0u;
+
5856  while (i < n)
+
5857  {
5858 
-
5859  // Generating the connections
-
5860  for (size_t j = 0u; j < max_cons; ++j)
-
5861  {
-
5862 
-
5863  source_.push_back(static_cast<int>(i + j - blocksize));
-
5864  target_.push_back(static_cast<int>(i + j));
-
5865 
-
5866  }
-
5867  }
-
5868 
-
5869  i += blocksize;
-
5870 
-
5871  }
-
5872 
-
5873  return AdjList(source_, target_, n, false);
-
5874 
-
5875 }
+
5859  for (size_t j = 0; j < blocksize; ++j)
+
5860  {
+
5861 
+
5862  for (size_t k = 0; k < j; ++k)
+
5863  {
+
5864  // No loops
+
5865  if (k == j)
+
5866  continue;
+
5867 
+
5868  // Exists the loop in case there are no more
+
5869  // nodes available
+
5870  if ((i + k) >= n)
+
5871  break;
+
5872 
+
5873  source_.push_back(static_cast<int>(j + i));
+
5874  target_.push_back(static_cast<int>(k + i));
+
5875  }
5876 
-
5877 #endif
-
5878 /*//////////////////////////////////////////////////////////////////////////////
-
5880 
-
5881  End of -include/epiworld/randgraph.hpp-
+
5877  // No more nodes left to build connections
+
5878  if (++cum_node_count >= n)
+
5879  break;
+
5880 
+
5881  }
5882 
-
5885 
+
5883  // Connections between this and the previou sone
+
5884  if (i != 0)
+
5885  {
5886 
-
5887 
-
5888 /*//////////////////////////////////////////////////////////////////////////////
-
5890 
-
5891  Start of -include/epiworld/queue-bones.hpp-
+
5887  size_t max_cons = std::min(ncons, n - cum_node_count);
+
5888 
+
5889  // Generating the connections
+
5890  for (size_t j = 0u; j < max_cons; ++j)
+
5891  {
5892 
+
5893  source_.push_back(static_cast<int>(i + j - blocksize));
+
5894  target_.push_back(static_cast<int>(i + j));
5895 
-
5896 
-
5897 #ifndef EPIWORLD_QUEUE_BONES_HPP
-
5898 #define EPIWORLD_QUEUE_BONES_HPP
-
5899 
-
5910 template<typename TSeq>
-
5911 class Queue
-
5912 {
-
5913  friend class Model<TSeq>;
-
5914 
-
5915 private:
+
5896  }
+
5897  }
+
5898 
+
5899  i += blocksize;
+
5900 
+
5901  }
+
5902 
+
5903  return AdjList(source_, target_, n, false);
+
5904 
+
5905 }
+
5906 
+
5907 #endif
+
5908 /*//////////////////////////////////////////////////////////////////////////////
+
5910 
+
5911  End of -include/epiworld/randgraph.hpp-
+
5912 
+
5915 
5916 
-
5920  std::vector< epiworld_fast_int > active;
-
5921  Model<TSeq> * model = nullptr;
-
5922  int n_in_queue = 0;
-
5923 
-
5924  // Auxiliary variable that checks how many steps
-
5925  // left are there
-
5926  // int n_steps_left;
-
5927  // bool queuing_started = false;
-
5928 
-
5929 public:
-
5930 
-
5931  void operator+=(Agent<TSeq> * p);
-
5932  void operator-=(Agent<TSeq> * p);
-
5933  epiworld_fast_int & operator[](epiworld_fast_uint i);
-
5934 
-
5935  // void initialize(Model<TSeq> * m, Agent<TSeq> * p);
-
5936  void reset();
-
5937 
-
5938  bool operator==(const Queue<TSeq> & other) const;
-
5939  bool operator!=(const Queue<TSeq> & other) const {return !operator==(other);};
-
5940 
-
5941  static const int NoOne = 0;
-
5942  static const int OnlySelf = 1;
-
5943  static const int Everyone = 2;
+
5917 
+
5918 /*//////////////////////////////////////////////////////////////////////////////
+
5920 
+
5921  Start of -include/epiworld/queue-bones.hpp-
+
5922 
+
5925 
+
5926 
+
5927 #ifndef EPIWORLD_QUEUE_BONES_HPP
+
5928 #define EPIWORLD_QUEUE_BONES_HPP
+
5929 
+
5940 template<typename TSeq>
+
5941 class Queue
+
5942 {
+
5943  friend class Model<TSeq>;
5944 
-
5945 };
+
5945 private:
5946 
-
5947 template<typename TSeq>
-
5948 inline void Queue<TSeq>::operator+=(Agent<TSeq> * p)
-
5949 {
-
5950 
-
5951  if (++active[p->id] == 1)
-
5952  n_in_queue++;
+
5950  std::vector< epiworld_fast_int > active;
+
5951  Model<TSeq> * model = nullptr;
+
5952  int n_in_queue = 0;
5953 
-
5954  for (auto n : p->neighbors)
-
5955  {
-
5956 
-
5957  if (++active[n] == 1)
-
5958  n_in_queue++;
-
5959 
-
5960  }
-
5961 
-
5962 }
-
5963 
-
5964 template<typename TSeq>
-
5965 inline void Queue<TSeq>::operator-=(Agent<TSeq> * p)
-
5966 {
+
5954  // Auxiliary variable that checks how many steps
+
5955  // left are there
+
5956  // int n_steps_left;
+
5957  // bool queuing_started = false;
+
5958 
+
5959 public:
+
5960 
+
5961  void operator+=(Agent<TSeq> * p);
+
5962  void operator-=(Agent<TSeq> * p);
+
5963  epiworld_fast_int & operator[](epiworld_fast_uint i);
+
5964 
+
5965  // void initialize(Model<TSeq> * m, Agent<TSeq> * p);
+
5966  void reset();
5967 
-
5968  if (--active[p->id] == 0)
-
5969  n_in_queue--;
+
5968  bool operator==(const Queue<TSeq> & other) const;
+
5969  bool operator!=(const Queue<TSeq> & other) const {return !operator==(other);};
5970 
-
5971  for (auto n : p->neighbors)
-
5972  {
-
5973  if (--active[n] == 0)
-
5974  n_in_queue--;
-
5975  }
+
5971  static const int NoOne = 0;
+
5972  static const int OnlySelf = 1;
+
5973  static const int Everyone = 2;
+
5974 
+
5975 };
5976 
-
5977 }
-
5978 
-
5979 template<typename TSeq>
-
5980 inline epiworld_fast_int & Queue<TSeq>::operator[](epiworld_fast_uint i)
-
5981 {
-
5982  return active[i];
-
5983 }
-
5984 
-
5985 template<typename TSeq>
-
5986 inline void Queue<TSeq>::reset()
-
5987 {
-
5988 
-
5989  if (n_in_queue)
-
5990  {
+
5977 template<typename TSeq>
+
5978 inline void Queue<TSeq>::operator+=(Agent<TSeq> * p)
+
5979 {
+
5980 
+
5981  if (++active[p->id] == 1)
+
5982  n_in_queue++;
+
5983 
+
5984  for (auto n : p->neighbors)
+
5985  {
+
5986 
+
5987  if (++active[n] == 1)
+
5988  n_in_queue++;
+
5989 
+
5990  }
5991 
-
5992  for (auto & q : this->active)
-
5993  q = 0;
-
5994 
-
5995  n_in_queue = 0;
-
5996 
-
5997  }
-
5998 
-
5999  active.resize(model->size(), 0);
+
5992 }
+
5993 
+
5994 template<typename TSeq>
+
5995 inline void Queue<TSeq>::operator-=(Agent<TSeq> * p)
+
5996 {
+
5997 
+
5998  if (--active[p->id] == 0)
+
5999  n_in_queue--;
6000 
-
6001 }
-
6002 
-
6003 template<typename TSeq>
-
6004 inline bool Queue<TSeq>::operator==(const Queue<TSeq> & other) const
-
6005 {
-
6006  if (active.size() != other.active.size())
-
6007  return false;
+
6001  for (auto n : p->neighbors)
+
6002  {
+
6003  if (--active[n] == 0)
+
6004  n_in_queue--;
+
6005  }
+
6006 
+
6007 }
6008 
-
6009  for (size_t i = 0u; i < active.size(); ++i)
-
6010  {
-
6011  if (active[i] != other.active[i])
-
6012  return false;
-
6013  }
+
6009 template<typename TSeq>
+
6010 inline epiworld_fast_int & Queue<TSeq>::operator[](epiworld_fast_uint i)
+
6011 {
+
6012  return active[i];
+
6013 }
6014 
-
6015  return true;
-
6016 }
-
6017 
-
6018 #endif
-
6019 /*//////////////////////////////////////////////////////////////////////////////
+
6015 template<typename TSeq>
+
6016 inline void Queue<TSeq>::reset()
+
6017 {
+
6018 
+
6019  if (n_in_queue)
+
6020  {
6021 
-
6022  End of -include/epiworld/queue-bones.hpp-
-
6023 
-
6026 
-
6027 
+
6022  for (auto & q : this->active)
+
6023  q = 0;
+
6024 
+
6025  n_in_queue = 0;
+
6026 
+
6027  }
6028 
-
6029 /*//////////////////////////////////////////////////////////////////////////////
-
6031 
-
6032  Start of -include/epiworld/globalevent-bones.hpp-
-
6033 
-
6036 
-
6037 
-
6038 #ifndef EPIWORLD_GLOBALEVENT_BONES_HPP
-
6039 #define EPIWORLD_GLOBALEVENT_BONES_HPP
-
6040 
-
6041 // template<typename TSeq = EPI_DEFAULT_TSEQ>
-
6042 // using GlobalFun = std::function<void(Model<TSeq>*)>;
-
6043 
-
6050 template<typename TSeq>
-
6051 class GlobalEvent
-
6052 {
-
6053 private:
-
6054  GlobalFun<TSeq> fun = nullptr;
-
6055  std::string name = "A global action";
-
6056  int day = -99;
-
6057 public:
+
6029  active.resize(model->size(), 0);
+
6030 
+
6031 }
+
6032 
+
6033 template<typename TSeq>
+
6034 inline bool Queue<TSeq>::operator==(const Queue<TSeq> & other) const
+
6035 {
+
6036  if (active.size() != other.active.size())
+
6037  return false;
+
6038 
+
6039  for (size_t i = 0u; i < active.size(); ++i)
+
6040  {
+
6041  if (active[i] != other.active[i])
+
6042  return false;
+
6043  }
+
6044 
+
6045  return true;
+
6046 }
+
6047 
+
6048 #endif
+
6049 /*//////////////////////////////////////////////////////////////////////////////
+
6051 
+
6052  End of -include/epiworld/queue-bones.hpp-
+
6053 
+
6056 
+
6057 
6058 
-
6059  GlobalEvent() {};
-
6060 
-
6068  GlobalEvent(GlobalFun<TSeq> fun, std::string name, int day = -99);
-
6069 
-
6070  ~GlobalEvent() {};
-
6071 
-
6072  void operator()(Model<TSeq> * m, int day);
+
6059 /*//////////////////////////////////////////////////////////////////////////////
+
6061 
+
6062  Start of -include/epiworld/globalevent-bones.hpp-
+
6063 
+
6066 
+
6067 
+
6068 #ifndef EPIWORLD_GLOBALEVENT_BONES_HPP
+
6069 #define EPIWORLD_GLOBALEVENT_BONES_HPP
+
6070 
+
6071 // template<typename TSeq = EPI_DEFAULT_TSEQ>
+
6072 // using GlobalFun = std::function<void(Model<TSeq>*)>;
6073 
-
6074  void set_name(std::string name);
-
6075  std::string get_name() const;
-
6076 
-
6077  void set_day(int day);
-
6078  int get_day() const;
-
6079 
-
6080  void print() const;
-
6081 
-
6082  // Comparison operators
-
6083  bool operator==(const GlobalEvent<TSeq> & other) const;
-
6084  bool operator!=(const GlobalEvent<TSeq> & other) const;
-
6085 
-
6086 };
-
6087 
+
6080 template<typename TSeq>
+
6081 class GlobalEvent
+
6082 {
+
6083 private:
+
6084  GlobalFun<TSeq> fun = nullptr;
+
6085  std::string name = "A global action";
+
6086  int day = -99;
+
6087 public:
6088 
-
6089 
-
6090 #endif
-
6091 /*//////////////////////////////////////////////////////////////////////////////
-
6093 
-
6094  End of -include/epiworld/globalevent-bones.hpp-
-
6095 
-
6098 
-
6099 
-
6100 /*//////////////////////////////////////////////////////////////////////////////
-
6102 
-
6103  Start of -include/epiworld/globalevent-meat.hpp-
-
6104 
-
6107 
-
6108 
-
6109 #ifndef EPIWORLD_GLOBALEVENT_MEAT_HPP
-
6110 #define EPIWORLD_GLOBALEVENT_MEAT_HPP
+
6089  GlobalEvent() {};
+
6090 
+
6098  GlobalEvent(GlobalFun<TSeq> fun, std::string name, int day = -99);
+
6099 
+
6100  ~GlobalEvent() {};
+
6101 
+
6102  void operator()(Model<TSeq> * m, int day);
+
6103 
+
6104  void set_name(std::string name);
+
6105  std::string get_name() const;
+
6106 
+
6107  void set_day(int day);
+
6108  int get_day() const;
+
6109 
+
6110  void print() const;
6111 
-
6112 template<typename TSeq>
-
6113 inline GlobalEvent<TSeq>::GlobalEvent(
-
6114  GlobalFun<TSeq> fun,
-
6115  std::string name,
-
6116  int day
-
6117  )
-
6118 {
-
6119  this->fun = fun;
-
6120  this->name = name;
-
6121  this->day = day;
-
6122 }
+
6112  // Comparison operators
+
6113  bool operator==(const GlobalEvent<TSeq> & other) const;
+
6114  bool operator!=(const GlobalEvent<TSeq> & other) const;
+
6115 
+
6116 };
+
6117 
+
6118 
+
6119 
+
6120 #endif
+
6121 /*//////////////////////////////////////////////////////////////////////////////
6123 
-
6124 template<typename TSeq>
-
6125 inline void GlobalEvent<TSeq>::operator()(Model<TSeq> * m, int day)
-
6126 {
-
6127 
-
6128  if (this->fun == nullptr)
-
6129  return;
-
6130 
-
6131  // events apply if day is negative or if day is equal to the day of the action
-
6132  if (this->day < 0 || this->day == day)
-
6133  this->fun(m);
-
6134 
-
6135  return;
-
6136 
-
6137 }
+
6124  End of -include/epiworld/globalevent-bones.hpp-
+
6125 
+
6128 
+
6129 
+
6130 /*//////////////////////////////////////////////////////////////////////////////
+
6132 
+
6133  Start of -include/epiworld/globalevent-meat.hpp-
+
6134 
+
6137 
6138 
-
6139 template<typename TSeq>
-
6140 inline void GlobalEvent<TSeq>::set_name(std::string name)
-
6141 {
-
6142  this->name = name;
-
6143 }
-
6144 
-
6145 template<typename TSeq>
-
6146 inline std::string GlobalEvent<TSeq>::get_name() const
-
6147 {
-
6148  return this->name;
-
6149 }
-
6150 
-
6151 template<typename TSeq>
-
6152 inline void GlobalEvent<TSeq>::set_day(int day)
-
6153 {
-
6154  this->day = day;
-
6155 }
-
6156 
-
6157 template<typename TSeq>
-
6158 inline int GlobalEvent<TSeq>::get_day() const
-
6159 {
-
6160  return this->day;
-
6161 }
-
6162 
-
6163 template<typename TSeq>
-
6164 inline void GlobalEvent<TSeq>::print() const
-
6165 {
-
6166  printf_epiworld(
-
6167  "Global action: %s\n"
-
6168  " - Day: %i\n",
-
6169  this->name.c_str(),
-
6170  this->day
-
6171  );
-
6172 }
-
6173 
-
6174 template<typename TSeq>
-
6175 inline bool GlobalEvent<TSeq>::operator==(const GlobalEvent<TSeq> & other) const
-
6176 {
-
6177  return (this->name == other.name) && (this->day == other.day);
-
6178 }
-
6179 
-
6180 template<typename TSeq>
-
6181 inline bool GlobalEvent<TSeq>::operator!=(const GlobalEvent<TSeq> & other) const
-
6182 {
-
6183  return !(*this == other);
-
6184 }
-
6185 
-
6186 #endif
-
6187 /*//////////////////////////////////////////////////////////////////////////////
-
6189 
-
6190  End of -include/epiworld/globalevent-meat.hpp-
-
6191 
-
6194 
-
6195 
-
6196 
-
6197 /*//////////////////////////////////////////////////////////////////////////////
-
6199 
-
6200  Start of -include/epiworld/model-bones.hpp-
-
6201 
-
6204 
-
6205 
-
6206 #ifndef EPIWORLD_MODEL_HPP
-
6207 #define EPIWORLD_MODEL_HPP
-
6208 
-
6209 template<typename TSeq>
-
6210 class Agent;
-
6211 
-
6212 template<typename TSeq>
-
6213 class AgentsSample;
-
6214 
-
6215 template<typename TSeq>
-
6216 class Virus;
-
6217 
-
6218 template<typename TSeq>
-
6219 class Viruses;
-
6220 
-
6221 template<typename TSeq>
-
6222 class Viruses_const;
-
6223 
-
6224 template<typename TSeq>
-
6225 class Tool;
+
6139 #ifndef EPIWORLD_GLOBALEVENT_MEAT_HPP
+
6140 #define EPIWORLD_GLOBALEVENT_MEAT_HPP
+
6141 
+
6142 template<typename TSeq>
+
6143 inline GlobalEvent<TSeq>::GlobalEvent(
+
6144  GlobalFun<TSeq> fun,
+
6145  std::string name,
+
6146  int day
+
6147  )
+
6148 {
+
6149  this->fun = fun;
+
6150  this->name = name;
+
6151  this->day = day;
+
6152 }
+
6153 
+
6154 template<typename TSeq>
+
6155 inline void GlobalEvent<TSeq>::operator()(Model<TSeq> * m, int day)
+
6156 {
+
6157 
+
6158  if (this->fun == nullptr)
+
6159  return;
+
6160 
+
6161  // events apply if day is negative or if day is equal to the day of the action
+
6162  if (this->day < 0 || this->day == day)
+
6163  this->fun(m);
+
6164 
+
6165  return;
+
6166 
+
6167 }
+
6168 
+
6169 template<typename TSeq>
+
6170 inline void GlobalEvent<TSeq>::set_name(std::string name)
+
6171 {
+
6172  this->name = name;
+
6173 }
+
6174 
+
6175 template<typename TSeq>
+
6176 inline std::string GlobalEvent<TSeq>::get_name() const
+
6177 {
+
6178  return this->name;
+
6179 }
+
6180 
+
6181 template<typename TSeq>
+
6182 inline void GlobalEvent<TSeq>::set_day(int day)
+
6183 {
+
6184  this->day = day;
+
6185 }
+
6186 
+
6187 template<typename TSeq>
+
6188 inline int GlobalEvent<TSeq>::get_day() const
+
6189 {
+
6190  return this->day;
+
6191 }
+
6192 
+
6193 template<typename TSeq>
+
6194 inline void GlobalEvent<TSeq>::print() const
+
6195 {
+
6196  printf_epiworld(
+
6197  "Global action: %s\n"
+
6198  " - Day: %i\n",
+
6199  this->name.c_str(),
+
6200  this->day
+
6201  );
+
6202 }
+
6203 
+
6204 template<typename TSeq>
+
6205 inline bool GlobalEvent<TSeq>::operator==(const GlobalEvent<TSeq> & other) const
+
6206 {
+
6207  return (this->name == other.name) && (this->day == other.day);
+
6208 }
+
6209 
+
6210 template<typename TSeq>
+
6211 inline bool GlobalEvent<TSeq>::operator!=(const GlobalEvent<TSeq> & other) const
+
6212 {
+
6213  return !(*this == other);
+
6214 }
+
6215 
+
6216 #endif
+
6217 /*//////////////////////////////////////////////////////////////////////////////
+
6219 
+
6220  End of -include/epiworld/globalevent-meat.hpp-
+
6221 
+
6224 
+
6225 
6226 
-
6227 class AdjList;
-
6228 
-
6229 template<typename TSeq>
-
6230 class DataBase;
+
6227 /*//////////////////////////////////////////////////////////////////////////////
+
6229 
+
6230  Start of -include/epiworld/model-bones.hpp-
6231 
-
6232 template<typename TSeq>
-
6233 class Queue;
6234 
-
6235 template<typename TSeq>
-
6236 struct Event;
-
6237 
-
6238 template<typename TSeq>
-
6239 class GlobalEvent;
-
6240 
-
6241 template<typename TSeq>
-
6242 inline epiworld_double susceptibility_reduction_mixer_default(
-
6243  Agent<TSeq>* p,
-
6244  VirusPtr<TSeq> v,
-
6245  Model<TSeq>* m
-
6246  );
-
6247 template<typename TSeq>
-
6248 inline epiworld_double transmission_reduction_mixer_default(
-
6249  Agent<TSeq>* p,
-
6250  VirusPtr<TSeq> v,
-
6251  Model<TSeq>* m
-
6252  );
-
6253 template<typename TSeq>
-
6254 inline epiworld_double recovery_enhancer_mixer_default(
-
6255  Agent<TSeq>* p,
-
6256  VirusPtr<TSeq> v,
-
6257  Model<TSeq>* m
-
6258  );
+
6235 
+
6236 #ifndef EPIWORLD_MODEL_HPP
+
6237 #define EPIWORLD_MODEL_HPP
+
6238 
+
6239 template<typename TSeq>
+
6240 class Agent;
+
6241 
+
6242 template<typename TSeq>
+
6243 class AgentsSample;
+
6244 
+
6245 template<typename TSeq>
+
6246 class Virus;
+
6247 
+
6248 template<typename TSeq>
+
6249 class Viruses;
+
6250 
+
6251 template<typename TSeq>
+
6252 class Viruses_const;
+
6253 
+
6254 template<typename TSeq>
+
6255 class Tool;
+
6256 
+
6257 class AdjList;
+
6258 
6259 template<typename TSeq>
-
6260 inline epiworld_double death_reduction_mixer_default(
-
6261  Agent<TSeq>* p,
-
6262  VirusPtr<TSeq> v,
-
6263  Model<TSeq>* m
-
6264  );
-
6265 
-
6266 template<typename TSeq>
-
6267 inline std::function<void(size_t,Model<TSeq>*)> make_save_run(
-
6268  std::string fmt = "%03lu-episimulation.csv",
-
6269  bool total_hist = true,
-
6270  bool virus_info = false,
-
6271  bool virus_hist = false,
-
6272  bool tool_info = false,
-
6273  bool tool_hist = false,
-
6274  bool transmission = false,
-
6275  bool transition = false,
-
6276  bool reproductive = false,
-
6277  bool generation = false
-
6278  );
-
6279 
-
6280 // template<typename TSeq>
-
6281 // class VirusPtr;
-
6282 
-
6283 // template<typename TSeq>
-
6284 // class ToolPtr;
-
6285 
-
6295 template<typename TSeq>
-
6296 class Model {
-
6297  friend class Agent<TSeq>;
-
6298  friend class AgentsSample<TSeq>;
-
6299  friend class DataBase<TSeq>;
-
6300  friend class Queue<TSeq>;
-
6301 protected:
-
6302 
-
6303  std::string name = ""; ///< Name of the model
-
6304 
-
6305  DataBase<TSeq> db = DataBase<TSeq>(*this);
-
6306 
-
6307  std::vector< Agent<TSeq> > population = {};
-
6308 
-
6309  bool using_backup = true;
-
6310  std::vector< Agent<TSeq> > population_backup = {};
-
6311 
-
6321  std::vector< Agent<TSeq> * > sampled_population;
-
6322  size_t sampled_population_n = 0u;
-
6323  std::vector< size_t > population_left;
-
6324  size_t population_left_n = 0u;
-
6326 
-
6336  double * agents_data = nullptr;
-
6337  size_t agents_data_ncols = 0u;
-
6339 
-
6340  bool directed = false;
-
6341 
-
6342  std::vector< VirusPtr<TSeq> > viruses = {};
-
6343  std::vector< ToolPtr<TSeq> > tools = {};
-
6344 
-
6345  std::vector< Entity<TSeq> > entities = {};
-
6346  std::vector< Entity<TSeq> > entities_backup = {};
-
6347 
-
6348  std::shared_ptr< std::mt19937 > engine = std::make_shared< std::mt19937 >();
-
6349 
-
6350  std::uniform_real_distribution<> runifd =
-
6351  std::uniform_real_distribution<> (0.0, 1.0);
-
6352  std::normal_distribution<> rnormd =
-
6353  std::normal_distribution<>(0.0);
-
6354  std::gamma_distribution<> rgammad =
-
6355  std::gamma_distribution<>();
-
6356  std::lognormal_distribution<> rlognormald =
-
6357  std::lognormal_distribution<>();
-
6358  std::exponential_distribution<> rexpd =
-
6359  std::exponential_distribution<>();
-
6360  std::binomial_distribution<> rbinomd =
-
6361  std::binomial_distribution<>();
-
6362 
-
6363  std::function<void(std::vector<Agent<TSeq>>*,Model<TSeq>*,epiworld_double)> rewire_fun;
-
6364  epiworld_double rewire_prop = 0.0;
-
6365 
-
6366  std::map<std::string, epiworld_double > parameters;
-
6367  epiworld_fast_uint ndays = 0;
-
6368  Progress pb;
+
6260 class DataBase;
+
6261 
+
6262 template<typename TSeq>
+
6263 class Queue;
+
6264 
+
6265 template<typename TSeq>
+
6266 struct Event;
+
6267 
+
6268 template<typename TSeq>
+
6269 class GlobalEvent;
+
6270 
+
6271 template<typename TSeq>
+
6272 inline epiworld_double susceptibility_reduction_mixer_default(
+
6273  Agent<TSeq>* p,
+
6274  VirusPtr<TSeq> v,
+
6275  Model<TSeq>* m
+
6276  );
+
6277 template<typename TSeq>
+
6278 inline epiworld_double transmission_reduction_mixer_default(
+
6279  Agent<TSeq>* p,
+
6280  VirusPtr<TSeq> v,
+
6281  Model<TSeq>* m
+
6282  );
+
6283 template<typename TSeq>
+
6284 inline epiworld_double recovery_enhancer_mixer_default(
+
6285  Agent<TSeq>* p,
+
6286  VirusPtr<TSeq> v,
+
6287  Model<TSeq>* m
+
6288  );
+
6289 template<typename TSeq>
+
6290 inline epiworld_double death_reduction_mixer_default(
+
6291  Agent<TSeq>* p,
+
6292  VirusPtr<TSeq> v,
+
6293  Model<TSeq>* m
+
6294  );
+
6295 
+
6296 template<typename TSeq>
+
6297 inline std::function<void(size_t,Model<TSeq>*)> make_save_run(
+
6298  std::string fmt = "%03lu-episimulation.csv",
+
6299  bool total_hist = true,
+
6300  bool virus_info = false,
+
6301  bool virus_hist = false,
+
6302  bool tool_info = false,
+
6303  bool tool_hist = false,
+
6304  bool transmission = false,
+
6305  bool transition = false,
+
6306  bool reproductive = false,
+
6307  bool generation = false
+
6308  );
+
6309 
+
6310 // template<typename TSeq>
+
6311 // class VirusPtr;
+
6312 
+
6313 // template<typename TSeq>
+
6314 // class ToolPtr;
+
6315 
+
6325 template<typename TSeq>
+
6326 class Model {
+
6327  friend class Agent<TSeq>;
+
6328  friend class AgentsSample<TSeq>;
+
6329  friend class DataBase<TSeq>;
+
6330  friend class Queue<TSeq>;
+
6331 protected:
+
6332 
+
6333  std::string name = ""; ///< Name of the model
+
6334 
+
6335  DataBase<TSeq> db = DataBase<TSeq>(*this);
+
6336 
+
6337  std::vector< Agent<TSeq> > population = {};
+
6338 
+
6339  bool using_backup = true;
+
6340  std::vector< Agent<TSeq> > population_backup = {};
+
6341 
+
6351  std::vector< Agent<TSeq> * > sampled_population;
+
6352  size_t sampled_population_n = 0u;
+
6353  std::vector< size_t > population_left;
+
6354  size_t population_left_n = 0u;
+
6356 
+
6366  double * agents_data = nullptr;
+
6367  size_t agents_data_ncols = 0u;
6369 
-
6370  std::vector< UpdateFun<TSeq> > state_fun = {}; ///< Functions to update states
-
6371  std::vector< std::string > states_labels = {}; ///< Labels of the states
-
6372 
-
6374  std::function<void(Model<TSeq>*)> initial_states_fun = [](Model<TSeq> * /**/)
-
6375  -> void {};
-
6376 
-
6377  epiworld_fast_uint nstates = 0u;
-
6378 
-
6379  bool verbose = true;
-
6380  int current_date = 0;
-
6381 
-
6382  void dist_tools();
-
6383  void dist_virus();
-
6384  void dist_entities();
-
6385 
-
6386  std::chrono::time_point<std::chrono::steady_clock> time_start;
-
6387  std::chrono::time_point<std::chrono::steady_clock> time_end;
-
6388 
-
6389  // std::chrono::milliseconds
-
6390  std::chrono::duration<epiworld_double,std::micro> time_elapsed =
-
6391  std::chrono::duration<epiworld_double,std::micro>::zero();
-
6392  epiworld_fast_uint n_replicates = 0u;
-
6393  void chrono_start();
-
6394  void chrono_end();
-
6395 
-
6396  std::vector<GlobalEvent<TSeq>> globalevents;
-
6397 
-
6398  Queue<TSeq> queue;
-
6399  bool use_queuing = true;
-
6400 
-
6405  std::vector< Event<TSeq> > events = {};
-
6406  epiworld_fast_uint nactions = 0u;
-
6407 
- -
6422  Agent<TSeq> * agent_,
-
6423  VirusPtr<TSeq> virus_,
-
6424  ToolPtr<TSeq> tool_,
-
6425  Entity<TSeq> * entity_,
-
6426  epiworld_fast_int new_state_,
-
6427  epiworld_fast_int queue_,
-
6428  EventFun<TSeq> call_,
-
6429  int idx_agent_,
-
6430  int idx_object_
-
6431  );
-
6432 
-
6442  MixerFun<TSeq> susceptibility_reduction_mixer = susceptibility_reduction_mixer_default<TSeq>;
-
6443  MixerFun<TSeq> transmission_reduction_mixer = transmission_reduction_mixer_default<TSeq>;
-
6444  MixerFun<TSeq> recovery_enhancer_mixer = recovery_enhancer_mixer_default<TSeq>;
-
6445  MixerFun<TSeq> death_reduction_mixer = death_reduction_mixer_default<TSeq>;
-
6446 
-
6452  virtual Model<TSeq> * clone_ptr();
-
6453 
-
6454 public:
-
6455 
-
6456 
-
6457  std::vector<epiworld_double> array_double_tmp;
-
6458  std::vector<Virus<TSeq> * > array_virus_tmp;
-
6459  std::vector< int > array_int_tmp;
-
6460 
-
6461  Model();
-
6462  Model(const Model<TSeq> & m);
-
6463  Model(Model<TSeq> & m);
-
6464  Model(Model<TSeq> && m);
-
6465  Model<TSeq> & operator=(const Model<TSeq> & m);
-
6466 
-
6467  virtual ~Model() {};
-
6468 
-
6477  void set_backup();
-
6478  // void restore_backup();
-
6480 
-
6481  DataBase<TSeq> & get_db();
-
6482  const DataBase<TSeq> & get_db() const;
-
6483  epiworld_double & operator()(std::string pname);
-
6484 
-
6485  size_t size() const;
-
6486 
-
6494  void set_rand_engine(std::shared_ptr< std::mt19937 > & eng);
-
6495  std::shared_ptr< std::mt19937 > & get_rand_endgine();
-
6496  void seed(size_t s);
-
6497  void set_rand_norm(epiworld_double mean, epiworld_double sd);
-
6498  void set_rand_unif(epiworld_double a, epiworld_double b);
-
6499  void set_rand_exp(epiworld_double lambda);
-
6500  void set_rand_gamma(epiworld_double alpha, epiworld_double beta);
-
6501  void set_rand_lognormal(epiworld_double mean, epiworld_double shape);
-
6502  void set_rand_binom(int n, epiworld_double p);
-
6503  epiworld_double runif();
-
6504  epiworld_double runif(epiworld_double a, epiworld_double b);
-
6505  epiworld_double rnorm();
-
6506  epiworld_double rnorm(epiworld_double mean, epiworld_double sd);
-
6507  epiworld_double rgamma();
-
6508  epiworld_double rgamma(epiworld_double alpha, epiworld_double beta);
-
6509  epiworld_double rexp();
-
6510  epiworld_double rexp(epiworld_double lambda);
-
6511  epiworld_double rlognormal();
-
6512  epiworld_double rlognormal(epiworld_double mean, epiworld_double shape);
-
6513  int rbinom();
-
6514  int rbinom(int n, epiworld_double p);
+
6370  bool directed = false;
+
6371 
+
6372  std::vector< VirusPtr<TSeq> > viruses = {};
+
6373  std::vector< ToolPtr<TSeq> > tools = {};
+
6374 
+
6375  std::vector< Entity<TSeq> > entities = {};
+
6376  std::vector< Entity<TSeq> > entities_backup = {};
+
6377 
+
6378  std::shared_ptr< std::mt19937 > engine = std::make_shared< std::mt19937 >();
+
6379 
+
6380  std::uniform_real_distribution<> runifd =
+
6381  std::uniform_real_distribution<> (0.0, 1.0);
+
6382  std::normal_distribution<> rnormd =
+
6383  std::normal_distribution<>(0.0);
+
6384  std::gamma_distribution<> rgammad =
+
6385  std::gamma_distribution<>();
+
6386  std::lognormal_distribution<> rlognormald =
+
6387  std::lognormal_distribution<>();
+
6388  std::exponential_distribution<> rexpd =
+
6389  std::exponential_distribution<>();
+
6390  std::binomial_distribution<> rbinomd =
+
6391  std::binomial_distribution<>();
+
6392 
+
6393  std::function<void(std::vector<Agent<TSeq>>*,Model<TSeq>*,epiworld_double)> rewire_fun;
+
6394  epiworld_double rewire_prop = 0.0;
+
6395 
+
6396  std::map<std::string, epiworld_double > parameters;
+
6397  epiworld_fast_uint ndays = 0;
+
6398  Progress pb;
+
6399 
+
6400  std::vector< UpdateFun<TSeq> > state_fun = {}; ///< Functions to update states
+
6401  std::vector< std::string > states_labels = {}; ///< Labels of the states
+
6402 
+
6404  std::function<void(Model<TSeq>*)> initial_states_fun = [](Model<TSeq> * /**/)
+
6405  -> void {};
+
6406 
+
6407  epiworld_fast_uint nstates = 0u;
+
6408 
+
6409  bool verbose = true;
+
6410  int current_date = 0;
+
6411 
+
6412  void dist_tools();
+
6413  void dist_virus();
+
6414  void dist_entities();
+
6415 
+
6416  std::chrono::time_point<std::chrono::steady_clock> time_start;
+
6417  std::chrono::time_point<std::chrono::steady_clock> time_end;
+
6418 
+
6419  // std::chrono::milliseconds
+
6420  std::chrono::duration<epiworld_double,std::micro> time_elapsed =
+
6421  std::chrono::duration<epiworld_double,std::micro>::zero();
+
6422  epiworld_fast_uint n_replicates = 0u;
+
6423  void chrono_start();
+
6424  void chrono_end();
+
6425 
+
6426  std::vector<GlobalEvent<TSeq>> globalevents;
+
6427 
+
6428  Queue<TSeq> queue;
+
6429  bool use_queuing = true;
+
6430 
+
6435  std::vector< Event<TSeq> > events = {};
+
6436  epiworld_fast_uint nactions = 0u;
+
6437 
+ +
6452  Agent<TSeq> * agent_,
+
6453  VirusPtr<TSeq> virus_,
+
6454  ToolPtr<TSeq> tool_,
+
6455  Entity<TSeq> * entity_,
+
6456  epiworld_fast_int new_state_,
+
6457  epiworld_fast_int queue_,
+
6458  EventFun<TSeq> call_,
+
6459  int idx_agent_,
+
6460  int idx_object_
+
6461  );
+
6462 
+
6472  MixerFun<TSeq> susceptibility_reduction_mixer = susceptibility_reduction_mixer_default<TSeq>;
+
6473  MixerFun<TSeq> transmission_reduction_mixer = transmission_reduction_mixer_default<TSeq>;
+
6474  MixerFun<TSeq> recovery_enhancer_mixer = recovery_enhancer_mixer_default<TSeq>;
+
6475  MixerFun<TSeq> death_reduction_mixer = death_reduction_mixer_default<TSeq>;
+
6476 
+
6482  virtual Model<TSeq> * clone_ptr();
+
6483 
+
6484 public:
+
6485 
+
6486 
+
6487  std::vector<epiworld_double> array_double_tmp;
+
6488  std::vector<Virus<TSeq> * > array_virus_tmp;
+
6489  std::vector< int > array_int_tmp;
+
6490 
+
6491  Model();
+
6492  Model(const Model<TSeq> & m);
+
6493  Model(Model<TSeq> & m);
+
6494  Model(Model<TSeq> && m);
+
6495  Model<TSeq> & operator=(const Model<TSeq> & m);
+
6496 
+
6497  virtual ~Model() {};
+
6498 
+
6507  void set_backup();
+
6508  // void restore_backup();
+
6510 
+
6511  DataBase<TSeq> & get_db();
+
6512  const DataBase<TSeq> & get_db() const;
+
6513  epiworld_double & operator()(std::string pname);
+
6514 
+
6515  size_t size() const;
6516 
-
6529  void add_virus(Virus<TSeq> & v);
-
6530  void add_tool(Tool<TSeq> & t);
-
6531  void add_entity(Entity<TSeq> e);
-
6532  void rm_virus(size_t virus_pos);
-
6533  void rm_tool(size_t tool_pos);
-
6534  void rm_entity(size_t entity_id);
-
6536 
-
6547  void load_agents_entities_ties(std::string fn, int skip);
-
6548 
- -
6553  const std::vector<int> & agents_ids,
-
6554  const std::vector<int> & entities_ids
-
6555  );
-
6556 
-
6557  void load_agents_entities_ties(
-
6558  const int * agents_id,
-
6559  const int * entities_id,
-
6560  size_t n
-
6561  );
-
6562 
-
6573  void agents_from_adjlist(
-
6574  std::string fn,
-
6575  int size,
-
6576  int skip = 0,
-
6577  bool directed = false
-
6578  );
-
6579 
-
6580  void agents_from_edgelist(
-
6581  const std::vector< int > & source,
-
6582  const std::vector< int > & target,
-
6583  int size,
-
6584  bool directed
-
6585  );
+
6524  void set_rand_engine(std::shared_ptr< std::mt19937 > & eng);
+
6525  std::shared_ptr< std::mt19937 > & get_rand_endgine();
+
6526  void seed(size_t s);
+
6527  void set_rand_norm(epiworld_double mean, epiworld_double sd);
+
6528  void set_rand_unif(epiworld_double a, epiworld_double b);
+
6529  void set_rand_exp(epiworld_double lambda);
+
6530  void set_rand_gamma(epiworld_double alpha, epiworld_double beta);
+
6531  void set_rand_lognormal(epiworld_double mean, epiworld_double shape);
+
6532  void set_rand_binom(int n, epiworld_double p);
+
6533  epiworld_double runif();
+
6534  epiworld_double runif(epiworld_double a, epiworld_double b);
+
6535  epiworld_double rnorm();
+
6536  epiworld_double rnorm(epiworld_double mean, epiworld_double sd);
+
6537  epiworld_double rgamma();
+
6538  epiworld_double rgamma(epiworld_double alpha, epiworld_double beta);
+
6539  epiworld_double rexp();
+
6540  epiworld_double rexp(epiworld_double lambda);
+
6541  epiworld_double rlognormal();
+
6542  epiworld_double rlognormal(epiworld_double mean, epiworld_double shape);
+
6543  int rbinom();
+
6544  int rbinom(int n, epiworld_double p);
+
6546 
+
6559  void add_virus(Virus<TSeq> & v);
+
6560  void add_tool(Tool<TSeq> & t);
+
6561  void add_entity(Entity<TSeq> e);
+
6562  void rm_virus(size_t virus_pos);
+
6563  void rm_tool(size_t tool_pos);
+
6564  void rm_entity(size_t entity_id);
+
6566 
+
6577  void load_agents_entities_ties(std::string fn, int skip);
+
6578 
+ +
6583  const std::vector<int> & agents_ids,
+
6584  const std::vector<int> & entities_ids
+
6585  );
6586 
-
6587  void agents_from_adjlist(AdjList al);
-
6588 
-
6589  bool is_directed() const;
-
6590 
-
6591  std::vector< Agent<TSeq> > & get_agents();
+
6587  void load_agents_entities_ties(
+
6588  const int * agents_id,
+
6589  const int * entities_id,
+
6590  size_t n
+
6591  );
6592 
-
6593  Agent<TSeq> & get_agent(size_t i);
-
6594 
-
6595  std::vector< epiworld_fast_uint > get_agents_states() const;
-
6596 
-
6597  std::vector< Viruses_const<TSeq> > get_agents_viruses() const;
-
6598 
-
6599  std::vector< Viruses<TSeq> > get_agents_viruses();
-
6600 
-
6601  std::vector< Entity<TSeq> > & get_entities();
-
6602 
-
6603  Entity<TSeq> & get_entity(size_t entity_id, int * entity_pos = nullptr);
-
6604 
-
6605  Model<TSeq> & agents_smallworld(
-
6606  epiworld_fast_uint n = 1000,
-
6607  epiworld_fast_uint k = 5,
-
6608  bool d = false,
-
6609  epiworld_double p = .01
-
6610  );
-
6611  void agents_empty_graph(epiworld_fast_uint n = 1000);
-
6613 
-
6624  void update_state();
-
6625  void mutate_virus();
-
6626  void next();
-
6627  virtual Model<TSeq> & run(
-
6628  epiworld_fast_uint ndays,
-
6629  int seed = -1
-
6630  );
- -
6632  epiworld_fast_uint ndays,
-
6633  epiworld_fast_uint nexperiments,
-
6634  int seed_ = -1,
-
6635  std::function<void(size_t,Model<TSeq>*)> fun = make_save_run<TSeq>(),
-
6636  bool reset = true,
-
6637  bool verbose = true,
-
6638  int nthreads = 1
-
6639  );
-
6641 
-
6642  size_t get_n_viruses() const;
-
6643  size_t get_n_tools() const;
-
6644  epiworld_fast_uint get_ndays() const;
-
6645  epiworld_fast_uint get_n_replicates() const;
-
6646  void set_ndays(epiworld_fast_uint ndays);
-
6647  bool get_verbose() const;
-
6648  Model<TSeq> & verbose_off();
-
6649  Model<TSeq> & verbose_on();
-
6650  int today() const;
-
6651 
-
6664  void set_rewire_fun(std::function<void(std::vector<Agent<TSeq>>*,Model<TSeq>*,epiworld_double)> fun);
-
6665  void set_rewire_prop(epiworld_double prop);
-
6666  epiworld_double get_rewire_prop() const;
-
6667  void rewire();
-
6669 
- -
6683  std::string fn_virus_info,
-
6684  std::string fn_virus_hist,
-
6685  std::string fn_tool_info,
-
6686  std::string fn_tool_hist,
-
6687  std::string fn_total_hist,
-
6688  std::string fn_transmission,
-
6689  std::string fn_transition,
-
6690  std::string fn_reproductive_number,
-
6691  std::string fn_generation_time
-
6692  ) const;
-
6693 
-
6705  void write_edgelist(
-
6706  std::string fn
-
6707  ) const;
-
6708 
-
6709  void write_edgelist(
-
6710  std::vector< int > & source,
-
6711  std::vector< int > & target
-
6712  ) const;
-
6714 
-
6715  std::map<std::string, epiworld_double> & params();
-
6716 
-
6728  virtual void reset();
-
6729  const Model<TSeq> & print(bool lite = false) const;
-
6730 
-
6746  void add_state(std::string lab, UpdateFun<TSeq> fun = nullptr);
-
6747  const std::vector< std::string > & get_states() const;
-
6748  const std::vector< UpdateFun<TSeq> > & get_state_fun() const;
-
6749  void print_state_codes() const;
-
6751 
-
6760  virtual Model<TSeq> & initial_states(
-
6761  std::vector< double > /*proportions_*/,
-
6762  std::vector< int > /*queue_*/
-
6763  ) {return *this;};
-
6764 
-
6800  epiworld_double add_param(epiworld_double initial_val, std::string pname);
-
6801  void read_params(std::string fn);
-
6802  epiworld_double get_param(epiworld_fast_uint k);
-
6803  epiworld_double get_param(std::string pname);
-
6804  // void set_param(size_t k, epiworld_double val);
-
6805  void set_param(std::string pname, epiworld_double val);
-
6806  // epiworld_double par(epiworld_fast_uint k);
-
6807  epiworld_double par(std::string pname) const;
-
6809 
-
6810  void get_elapsed(
-
6811  std::string unit = "auto",
-
6812  epiworld_double * last_elapsed = nullptr,
-
6813  epiworld_double * total_elapsed = nullptr,
-
6814  std::string * unit_abbr = nullptr,
-
6815  bool print = true
-
6816  ) const;
-
6817 
-
6824  void set_user_data(std::vector< std::string > names);
-
6825  void add_user_data(epiworld_fast_uint j, epiworld_double x);
-
6826  void add_user_data(std::vector< epiworld_double > x);
-
6827  UserData<TSeq> & get_user_data();
-
6829 
- -
6842  std::function<void(Model<TSeq>*)> fun,
-
6843  std::string name = "A global action",
-
6844  int date = -99
-
6845  );
-
6846 
-
6847  void add_globalevent(
-
6848  GlobalEvent<TSeq> action
-
6849  );
-
6850 
-
6851  GlobalEvent<TSeq> & get_globalevent(std::string name);
- -
6853 
-
6854  void rm_globalevent(std::string name);
-
6855  void rm_globalevent(size_t i);
-
6856 
-
6857  void run_globalevents();
-
6858 
-
6859  void clear_state_set();
-
6860 
-
6869  void queuing_on();
- -
6871  bool is_queuing_on() const;
- -
6874 
-
6882  void set_susceptibility_reduction_mixer(MixerFun<TSeq> fun);
-
6883  void set_transmission_reduction_mixer(MixerFun<TSeq> fun);
-
6884  void set_recovery_enhancer_mixer(MixerFun<TSeq> fun);
-
6885  void set_death_reduction_mixer(MixerFun<TSeq> fun);
-
6887 
-
6888  const std::vector< VirusPtr<TSeq> > & get_viruses() const;
-
6889  const std::vector< ToolPtr<TSeq> > & get_tools() const;
-
6890  Virus<TSeq> & get_virus(size_t id);
-
6891  Tool<TSeq> & get_tool(size_t id);
-
6892 
-
6904  void set_agents_data(double * data_, size_t ncols_);
-
6905  double * get_agents_data();
-
6906  size_t get_agents_data_ncols() const;
-
6907 
-
6913  void set_name(std::string name);
-
6914  std::string get_name() const;
-
6915 
-
6916  bool operator==(const Model<TSeq> & other) const;
-
6917  bool operator!=(const Model<TSeq> & other) const {return !operator==(other);};
-
6918 
-
6924  void events_run();
-
6925 
-
6926 
-
6927 };
-
6928 
-
6929 #endif
-
6930 /*//////////////////////////////////////////////////////////////////////////////
-
6932 
-
6933  End of -include/epiworld/model-bones.hpp-
-
6934 
-
6937 
-
6938 
-
6939 /*//////////////////////////////////////////////////////////////////////////////
-
6941 
-
6942  Start of -include/epiworld/model-meat.hpp-
-
6943 
-
6946 
-
6947 
-
6948 #ifndef EPIWORLD_MODEL_MEAT_HPP
-
6949 #define EPIWORLD_MODEL_MEAT_HPP
-
6950 
-
6969 template<typename TSeq = int>
-
6970 inline std::function<void(size_t,Model<TSeq>*)> make_save_run(
-
6971  std::string fmt,
-
6972  bool total_hist,
-
6973  bool virus_info,
-
6974  bool virus_hist,
-
6975  bool tool_info,
-
6976  bool tool_hist,
-
6977  bool transmission,
-
6978  bool transition,
-
6979  bool reproductive,
-
6980  bool generation
-
6981  )
-
6982 {
-
6983 
-
6984  // Counting number of %
-
6985  int n_fmt = 0;
-
6986  for (auto & f : fmt)
-
6987  if (f == '%')
-
6988  n_fmt++;
-
6989 
-
6990  if (n_fmt != 1)
-
6991  throw std::logic_error("The -fmt- argument must have only one \"%\" symbol.");
-
6992 
-
6993  // Listting things to save
-
6994  std::vector< bool > what_to_save = {
-
6995  virus_info,
-
6996  virus_hist,
-
6997  tool_info,
-
6998  tool_hist,
-
6999  total_hist,
-
7000  transmission,
-
7001  transition,
-
7002  reproductive,
-
7003  generation
-
7004  };
-
7005 
-
7006  std::function<void(size_t,Model<TSeq>*)> saver = [fmt,what_to_save](
-
7007  size_t niter, Model<TSeq> * m
-
7008  ) -> void {
-
7009 
-
7010  std::string virus_info = "";
-
7011  std::string virus_hist = "";
-
7012  std::string tool_info = "";
-
7013  std::string tool_hist = "";
-
7014  std::string total_hist = "";
-
7015  std::string transmission = "";
-
7016  std::string transition = "";
-
7017  std::string reproductive = "";
-
7018  std::string generation = "";
+
6603  void agents_from_adjlist(
+
6604  std::string fn,
+
6605  int size,
+
6606  int skip = 0,
+
6607  bool directed = false
+
6608  );
+
6609 
+
6610  void agents_from_edgelist(
+
6611  const std::vector< int > & source,
+
6612  const std::vector< int > & target,
+
6613  int size,
+
6614  bool directed
+
6615  );
+
6616 
+
6617  void agents_from_adjlist(AdjList al);
+
6618 
+
6619  bool is_directed() const;
+
6620 
+
6621  std::vector< Agent<TSeq> > & get_agents();
+
6622 
+
6623  Agent<TSeq> & get_agent(size_t i);
+
6624 
+
6625  std::vector< epiworld_fast_uint > get_agents_states() const;
+
6626 
+
6627  std::vector< Viruses_const<TSeq> > get_agents_viruses() const;
+
6628 
+
6629  std::vector< Viruses<TSeq> > get_agents_viruses();
+
6630 
+
6631  std::vector< Entity<TSeq> > & get_entities();
+
6632 
+
6633  Entity<TSeq> & get_entity(size_t entity_id, int * entity_pos = nullptr);
+
6634 
+
6635  Model<TSeq> & agents_smallworld(
+
6636  epiworld_fast_uint n = 1000,
+
6637  epiworld_fast_uint k = 5,
+
6638  bool d = false,
+
6639  epiworld_double p = .01
+
6640  );
+
6641  void agents_empty_graph(epiworld_fast_uint n = 1000);
+
6643 
+
6654  void update_state();
+
6655  void mutate_virus();
+
6656  void next();
+
6657  virtual Model<TSeq> & run(
+
6658  epiworld_fast_uint ndays,
+
6659  int seed = -1
+
6660  );
+ +
6662  epiworld_fast_uint ndays,
+
6663  epiworld_fast_uint nexperiments,
+
6664  int seed_ = -1,
+
6665  std::function<void(size_t,Model<TSeq>*)> fun = make_save_run<TSeq>(),
+
6666  bool reset = true,
+
6667  bool verbose = true,
+
6668  int nthreads = 1
+
6669  );
+
6671 
+
6672  size_t get_n_viruses() const;
+
6673  size_t get_n_tools() const;
+
6674  epiworld_fast_uint get_ndays() const;
+
6675  epiworld_fast_uint get_n_replicates() const;
+
6676  void set_ndays(epiworld_fast_uint ndays);
+
6677  bool get_verbose() const;
+
6678  Model<TSeq> & verbose_off();
+
6679  Model<TSeq> & verbose_on();
+
6680  int today() const;
+
6681 
+
6694  void set_rewire_fun(std::function<void(std::vector<Agent<TSeq>>*,Model<TSeq>*,epiworld_double)> fun);
+
6695  void set_rewire_prop(epiworld_double prop);
+
6696  epiworld_double get_rewire_prop() const;
+
6697  void rewire();
+
6699 
+ +
6713  std::string fn_virus_info,
+
6714  std::string fn_virus_hist,
+
6715  std::string fn_tool_info,
+
6716  std::string fn_tool_hist,
+
6717  std::string fn_total_hist,
+
6718  std::string fn_transmission,
+
6719  std::string fn_transition,
+
6720  std::string fn_reproductive_number,
+
6721  std::string fn_generation_time
+
6722  ) const;
+
6723 
+
6735  void write_edgelist(
+
6736  std::string fn
+
6737  ) const;
+
6738 
+
6739  void write_edgelist(
+
6740  std::vector< int > & source,
+
6741  std::vector< int > & target
+
6742  ) const;
+
6744 
+
6745  std::map<std::string, epiworld_double> & params();
+
6746 
+
6758  virtual void reset();
+
6759  const Model<TSeq> & print(bool lite = false) const;
+
6760 
+
6776  void add_state(std::string lab, UpdateFun<TSeq> fun = nullptr);
+
6777  const std::vector< std::string > & get_states() const;
+
6778  const std::vector< UpdateFun<TSeq> > & get_state_fun() const;
+
6779  void print_state_codes() const;
+
6781 
+
6790  virtual Model<TSeq> & initial_states(
+
6791  std::vector< double > /*proportions_*/,
+
6792  std::vector< int > /*queue_*/
+
6793  ) {return *this;};
+
6794 
+
6830  epiworld_double add_param(epiworld_double initial_val, std::string pname);
+
6831  void read_params(std::string fn);
+
6832  epiworld_double get_param(epiworld_fast_uint k);
+
6833  epiworld_double get_param(std::string pname);
+
6834  // void set_param(size_t k, epiworld_double val);
+
6835  void set_param(std::string pname, epiworld_double val);
+
6836  // epiworld_double par(epiworld_fast_uint k);
+
6837  epiworld_double par(std::string pname) const;
+
6839 
+
6840  void get_elapsed(
+
6841  std::string unit = "auto",
+
6842  epiworld_double * last_elapsed = nullptr,
+
6843  epiworld_double * total_elapsed = nullptr,
+
6844  std::string * unit_abbr = nullptr,
+
6845  bool print = true
+
6846  ) const;
+
6847 
+
6854  void set_user_data(std::vector< std::string > names);
+
6855  void add_user_data(epiworld_fast_uint j, epiworld_double x);
+
6856  void add_user_data(std::vector< epiworld_double > x);
+
6857  UserData<TSeq> & get_user_data();
+
6859 
+ +
6872  std::function<void(Model<TSeq>*)> fun,
+
6873  std::string name = "A global action",
+
6874  int date = -99
+
6875  );
+
6876 
+
6877  void add_globalevent(
+
6878  GlobalEvent<TSeq> action
+
6879  );
+
6880 
+
6881  GlobalEvent<TSeq> & get_globalevent(std::string name);
+ +
6883 
+
6884  void rm_globalevent(std::string name);
+
6885  void rm_globalevent(size_t i);
+
6886 
+
6887  void run_globalevents();
+
6888 
+
6889  void clear_state_set();
+
6890 
+
6899  void queuing_on();
+ +
6901  bool is_queuing_on() const;
+ +
6904 
+
6912  void set_susceptibility_reduction_mixer(MixerFun<TSeq> fun);
+
6913  void set_transmission_reduction_mixer(MixerFun<TSeq> fun);
+
6914  void set_recovery_enhancer_mixer(MixerFun<TSeq> fun);
+
6915  void set_death_reduction_mixer(MixerFun<TSeq> fun);
+
6917 
+
6918  const std::vector< VirusPtr<TSeq> > & get_viruses() const;
+
6919  const std::vector< ToolPtr<TSeq> > & get_tools() const;
+
6920  Virus<TSeq> & get_virus(size_t id);
+
6921  Tool<TSeq> & get_tool(size_t id);
+
6922 
+
6934  void set_agents_data(double * data_, size_t ncols_);
+
6935  double * get_agents_data();
+
6936  size_t get_agents_data_ncols() const;
+
6937 
+
6943  void set_name(std::string name);
+
6944  std::string get_name() const;
+
6945 
+
6946  bool operator==(const Model<TSeq> & other) const;
+
6947  bool operator!=(const Model<TSeq> & other) const {return !operator==(other);};
+
6948 
+
6954  void events_run();
+
6955 
+
6956 
+
6957 };
+
6958 
+
6959 #endif
+
6960 /*//////////////////////////////////////////////////////////////////////////////
+
6962 
+
6963  End of -include/epiworld/model-bones.hpp-
+
6964 
+
6967 
+
6968 
+
6969 /*//////////////////////////////////////////////////////////////////////////////
+
6971 
+
6972  Start of -include/epiworld/model-meat.hpp-
+
6973 
+
6976 
+
6977 
+
6978 #ifndef EPIWORLD_MODEL_MEAT_HPP
+
6979 #define EPIWORLD_MODEL_MEAT_HPP
+
6980 
+
6999 template<typename TSeq = int>
+
7000 inline std::function<void(size_t,Model<TSeq>*)> make_save_run(
+
7001  std::string fmt,
+
7002  bool total_hist,
+
7003  bool virus_info,
+
7004  bool virus_hist,
+
7005  bool tool_info,
+
7006  bool tool_hist,
+
7007  bool transmission,
+
7008  bool transition,
+
7009  bool reproductive,
+
7010  bool generation
+
7011  )
+
7012 {
+
7013 
+
7014  // Counting number of %
+
7015  int n_fmt = 0;
+
7016  for (auto & f : fmt)
+
7017  if (f == '%')
+
7018  n_fmt++;
7019 
-
7020  char buff[1024u];
-
7021  if (what_to_save[0u])
-
7022  {
-
7023  virus_info = fmt + std::string("_virus_info.csv");
-
7024  snprintf(buff, sizeof(buff), virus_info.c_str(), niter);
-
7025  virus_info = buff;
-
7026  }
-
7027  if (what_to_save[1u])
-
7028  {
-
7029  virus_hist = fmt + std::string("_virus_hist.csv");
-
7030  snprintf(buff, sizeof(buff), virus_hist.c_str(), niter);
-
7031  virus_hist = buff;
-
7032  }
-
7033  if (what_to_save[2u])
-
7034  {
-
7035  tool_info = fmt + std::string("_tool_info.csv");
-
7036  snprintf(buff, sizeof(buff), tool_info.c_str(), niter);
-
7037  tool_info = buff;
-
7038  }
-
7039  if (what_to_save[3u])
-
7040  {
-
7041  tool_hist = fmt + std::string("_tool_hist.csv");
-
7042  snprintf(buff, sizeof(buff), tool_hist.c_str(), niter);
-
7043  tool_hist = buff;
-
7044  }
-
7045  if (what_to_save[4u])
-
7046  {
-
7047  total_hist = fmt + std::string("_total_hist.csv");
-
7048  snprintf(buff, sizeof(buff), total_hist.c_str(), niter);
-
7049  total_hist = buff;
-
7050  }
-
7051  if (what_to_save[5u])
+
7020  if (n_fmt != 1)
+
7021  throw std::logic_error("The -fmt- argument must have only one \"%\" symbol.");
+
7022 
+
7023  // Listting things to save
+
7024  std::vector< bool > what_to_save = {
+
7025  virus_info,
+
7026  virus_hist,
+
7027  tool_info,
+
7028  tool_hist,
+
7029  total_hist,
+
7030  transmission,
+
7031  transition,
+
7032  reproductive,
+
7033  generation
+
7034  };
+
7035 
+
7036  std::function<void(size_t,Model<TSeq>*)> saver = [fmt,what_to_save](
+
7037  size_t niter, Model<TSeq> * m
+
7038  ) -> void {
+
7039 
+
7040  std::string virus_info = "";
+
7041  std::string virus_hist = "";
+
7042  std::string tool_info = "";
+
7043  std::string tool_hist = "";
+
7044  std::string total_hist = "";
+
7045  std::string transmission = "";
+
7046  std::string transition = "";
+
7047  std::string reproductive = "";
+
7048  std::string generation = "";
+
7049 
+
7050  char buff[1024u];
+
7051  if (what_to_save[0u])
7052  {
-
7053  transmission = fmt + std::string("_transmission.csv");
-
7054  snprintf(buff, sizeof(buff), transmission.c_str(), niter);
-
7055  transmission = buff;
+
7053  virus_info = fmt + std::string("_virus_info.csv");
+
7054  snprintf(buff, sizeof(buff), virus_info.c_str(), niter);
+
7055  virus_info = buff;
7056  }
-
7057  if (what_to_save[6u])
+
7057  if (what_to_save[1u])
7058  {
-
7059  transition = fmt + std::string("_transition.csv");
-
7060  snprintf(buff, sizeof(buff), transition.c_str(), niter);
-
7061  transition = buff;
+
7059  virus_hist = fmt + std::string("_virus_hist.csv");
+
7060  snprintf(buff, sizeof(buff), virus_hist.c_str(), niter);
+
7061  virus_hist = buff;
7062  }
-
7063  if (what_to_save[7u])
+
7063  if (what_to_save[2u])
7064  {
-
7065 
-
7066  reproductive = fmt + std::string("_reproductive.csv");
-
7067  snprintf(buff, sizeof(buff), reproductive.c_str(), niter);
-
7068  reproductive = buff;
-
7069 
-
7070  }
-
7071  if (what_to_save[8u])
-
7072  {
-
7073 
-
7074  generation = fmt + std::string("_generation.csv");
-
7075  snprintf(buff, sizeof(buff), generation.c_str(), niter);
-
7076  generation = buff;
-
7077 
-
7078  }
-
7079 
-
7080 
-
7081  m->write_data(
-
7082  virus_info,
-
7083  virus_hist,
-
7084  tool_info,
-
7085  tool_hist,
-
7086  total_hist,
-
7087  transmission,
-
7088  transition,
-
7089  reproductive,
-
7090  generation
-
7091  );
-
7092 
-
7093  };
-
7094 
-
7095  return saver;
-
7096 }
-
7097 
-
7098 
-
7099 template<typename TSeq>
-
7100 inline void Model<TSeq>::events_add(
-
7101  Agent<TSeq> * agent_,
-
7102  VirusPtr<TSeq> virus_,
-
7103  ToolPtr<TSeq> tool_,
-
7104  Entity<TSeq> * entity_,
-
7105  epiworld_fast_int new_state_,
-
7106  epiworld_fast_int queue_,
-
7107  EventFun<TSeq> call_,
-
7108  int idx_agent_,
-
7109  int idx_object_
-
7110 ) {
-
7111 
-
7112  ++nactions;
-
7113 
-
7114  #ifdef EPI_DEBUG
-
7115  if (nactions == 0)
-
7116  throw std::logic_error("Events cannot be zero!!");
-
7117  #endif
-
7118 
-
7119  if (nactions > events.size())
-
7120  {
-
7121 
-
7122  events.emplace_back(
-
7123  Event<TSeq>(
-
7124  agent_, virus_, tool_, entity_, new_state_, queue_, call_,
-
7125  idx_agent_, idx_object_
-
7126  ));
+
7065  tool_info = fmt + std::string("_tool_info.csv");
+
7066  snprintf(buff, sizeof(buff), tool_info.c_str(), niter);
+
7067  tool_info = buff;
+
7068  }
+
7069  if (what_to_save[3u])
+
7070  {
+
7071  tool_hist = fmt + std::string("_tool_hist.csv");
+
7072  snprintf(buff, sizeof(buff), tool_hist.c_str(), niter);
+
7073  tool_hist = buff;
+
7074  }
+
7075  if (what_to_save[4u])
+
7076  {
+
7077  total_hist = fmt + std::string("_total_hist.csv");
+
7078  snprintf(buff, sizeof(buff), total_hist.c_str(), niter);
+
7079  total_hist = buff;
+
7080  }
+
7081  if (what_to_save[5u])
+
7082  {
+
7083  transmission = fmt + std::string("_transmission.csv");
+
7084  snprintf(buff, sizeof(buff), transmission.c_str(), niter);
+
7085  transmission = buff;
+
7086  }
+
7087  if (what_to_save[6u])
+
7088  {
+
7089  transition = fmt + std::string("_transition.csv");
+
7090  snprintf(buff, sizeof(buff), transition.c_str(), niter);
+
7091  transition = buff;
+
7092  }
+
7093  if (what_to_save[7u])
+
7094  {
+
7095 
+
7096  reproductive = fmt + std::string("_reproductive.csv");
+
7097  snprintf(buff, sizeof(buff), reproductive.c_str(), niter);
+
7098  reproductive = buff;
+
7099 
+
7100  }
+
7101  if (what_to_save[8u])
+
7102  {
+
7103 
+
7104  generation = fmt + std::string("_generation.csv");
+
7105  snprintf(buff, sizeof(buff), generation.c_str(), niter);
+
7106  generation = buff;
+
7107 
+
7108  }
+
7109 
+
7110 
+
7111  m->write_data(
+
7112  virus_info,
+
7113  virus_hist,
+
7114  tool_info,
+
7115  tool_hist,
+
7116  total_hist,
+
7117  transmission,
+
7118  transition,
+
7119  reproductive,
+
7120  generation
+
7121  );
+
7122 
+
7123  };
+
7124 
+
7125  return saver;
+
7126 }
7127 
-
7128  }
-
7129  else
-
7130  {
-
7131 
-
7132  Event<TSeq> & A = events.at(nactions - 1u);
-
7133 
-
7134  A.agent = agent_;
-
7135  A.virus = virus_;
-
7136  A.tool = tool_;
-
7137  A.entity = entity_;
-
7138  A.new_state = new_state_;
-
7139  A.queue = queue_;
-
7140  A.call = call_;
-
7141  A.idx_agent = idx_agent_;
-
7142  A.idx_object = idx_object_;
+
7128 
+
7129 template<typename TSeq>
+
7130 inline void Model<TSeq>::events_add(
+
7131  Agent<TSeq> * agent_,
+
7132  VirusPtr<TSeq> virus_,
+
7133  ToolPtr<TSeq> tool_,
+
7134  Entity<TSeq> * entity_,
+
7135  epiworld_fast_int new_state_,
+
7136  epiworld_fast_int queue_,
+
7137  EventFun<TSeq> call_,
+
7138  int idx_agent_,
+
7139  int idx_object_
+
7140 ) {
+
7141 
+
7142  ++nactions;
7143 
-
7144  }
-
7145 
-
7146  return;
-
7147 
-
7148 }
-
7149 
-
7150 template<typename TSeq>
-
7151 inline void Model<TSeq>::events_run()
-
7152 {
-
7153  // Making the call
-
7154  size_t nevents_tmp = 0;
-
7155  while (nevents_tmp < nactions)
-
7156  {
+
7144  #ifdef EPI_DEBUG
+
7145  if (nactions == 0)
+
7146  throw std::logic_error("Events cannot be zero!!");
+
7147  #endif
+
7148 
+
7149  if (nactions > events.size())
+
7150  {
+
7151 
+
7152  events.emplace_back(
+
7153  Event<TSeq>(
+
7154  agent_, virus_, tool_, entity_, new_state_, queue_, call_,
+
7155  idx_agent_, idx_object_
+
7156  ));
7157 
-
7158  Event<TSeq> & a = events[nevents_tmp++];
-
7159  Agent<TSeq> * p = a.agent;
-
7160 
-
7161  #ifdef EPI_DEBUG
-
7162  if (a.new_state >= static_cast<epiworld_fast_int>(nstates))
-
7163  throw std::range_error(
-
7164  "The proposed state " + std::to_string(a.new_state) + " is out of range. " +
-
7165  "The model currently has " + std::to_string(nstates - 1) + " states.");
-
7166 
-
7167  if (a.new_state < 0)
-
7168  throw std::range_error(
-
7169  "The proposed state " + std::to_string(a.new_state) + " is out of range. " +
-
7170  "The state cannot be negative.");
-
7171  #endif
-
7172 
-
7173  // Undoing the change in the transition matrix
-
7174  if ((p->state_last_changed == today()) && (static_cast<int>(p->state) != a.new_state))
-
7175  {
-
7176  // Undoing state change in the transition matrix
-
7177  // The previous state is already recorded
-
7178  db.update_state(p->state_prev, p->state, true);
+
7158  }
+
7159  else
+
7160  {
+
7161 
+
7162  Event<TSeq> & A = events.at(nactions - 1u);
+
7163 
+
7164  A.agent = agent_;
+
7165  A.virus = virus_;
+
7166  A.tool = tool_;
+
7167  A.entity = entity_;
+
7168  A.new_state = new_state_;
+
7169  A.queue = queue_;
+
7170  A.call = call_;
+
7171  A.idx_agent = idx_agent_;
+
7172  A.idx_object = idx_object_;
+
7173 
+
7174  }
+
7175 
+
7176  return;
+
7177 
+
7178 }
7179 
-
7180  } else
-
7181  p->state_prev = p->state; // Recording the previous state
-
7182 
-
7183  // Applying function after the fact. This way, if there were
-
7184  // updates, they can be recorded properly, before losing the information
-
7185  p->state = a.new_state;
-
7186  if (a.call)
-
7187  {
-
7188  a.call(a, this);
-
7189  }
+
7180 template<typename TSeq>
+
7181 inline void Model<TSeq>::events_run()
+
7182 {
+
7183  // Making the call
+
7184  size_t nevents_tmp = 0;
+
7185  while (nevents_tmp < nactions)
+
7186  {
+
7187 
+
7188  Event<TSeq> & a = events[nevents_tmp++];
+
7189  Agent<TSeq> * p = a.agent;
7190 
-
7191  // Registering that the last change was today
-
7192  p->state_last_changed = today();
-
7193 
-
7194  #ifdef EPI_DEBUG
-
7195  if (static_cast<int>(p->state) >= static_cast<int>(nstates))
-
7196  throw std::range_error(
-
7197  "The new state " + std::to_string(p->state) + " is out of range. " +
-
7198  "The model currently has " + std::to_string(nstates - 1) + " states.");
-
7199  #endif
-
7200 
-
7201  // Updating queue
-
7202  if (use_queuing)
-
7203  {
-
7204 
-
7205  if (a.queue == Queue<TSeq>::Everyone)
-
7206  queue += p;
-
7207  else if (a.queue == -Queue<TSeq>::Everyone)
-
7208  queue -= p;
-
7209  else if (a.queue == Queue<TSeq>::OnlySelf)
-
7210  queue[p->get_id()]++;
-
7211  else if (a.queue == -Queue<TSeq>::OnlySelf)
-
7212  queue[p->get_id()]--;
-
7213  else if (a.queue != Queue<TSeq>::NoOne)
-
7214  throw std::logic_error(
-
7215  "The proposed queue change is not valid. Queue values can be {-2, -1, 0, 1, 2}."
-
7216  );
-
7217 
-
7218  }
-
7219 
-
7220  }
-
7221 
-
7222  // Go back to square 1
-
7223  nactions = 0u;
-
7224 
-
7225  return;
-
7226 
-
7227 }
-
7228 
-
7237 template<typename TSeq>
-
7238 inline epiworld_double susceptibility_reduction_mixer_default(
-
7239  Agent<TSeq>* p,
-
7240  VirusPtr<TSeq> v,
-
7241  Model<TSeq> * m
-
7242 )
-
7243 {
-
7244  epiworld_double total = 1.0;
-
7245  for (auto & tool : p->get_tools())
-
7246  total *= (1.0 - tool->get_susceptibility_reduction(v, m));
-
7247 
-
7248  return 1.0 - total;
-
7249 
-
7250 }
+
7191  #ifdef EPI_DEBUG
+
7192  if (a.new_state >= static_cast<epiworld_fast_int>(nstates))
+
7193  throw std::range_error(
+
7194  "The proposed state " + std::to_string(a.new_state) + " is out of range. " +
+
7195  "The model currently has " + std::to_string(nstates - 1) + " states.");
+
7196 
+
7197  if (a.new_state < 0)
+
7198  throw std::range_error(
+
7199  "The proposed state " + std::to_string(a.new_state) + " is out of range. " +
+
7200  "The state cannot be negative.");
+
7201  #endif
+
7202 
+
7203  // Undoing the change in the transition matrix
+
7204  if ((p->state_last_changed == today()) && (static_cast<int>(p->state) != a.new_state))
+
7205  {
+
7206  // Undoing state change in the transition matrix
+
7207  // The previous state is already recorded
+
7208  db.update_state(p->state_prev, p->state, true);
+
7209 
+
7210  } else
+
7211  p->state_prev = p->state; // Recording the previous state
+
7212 
+
7213  // Applying function after the fact. This way, if there were
+
7214  // updates, they can be recorded properly, before losing the information
+
7215  p->state = a.new_state;
+
7216  if (a.call)
+
7217  {
+
7218  a.call(a, this);
+
7219  }
+
7220 
+
7221  // Registering that the last change was today
+
7222  p->state_last_changed = today();
+
7223 
+
7224  #ifdef EPI_DEBUG
+
7225  if (static_cast<int>(p->state) >= static_cast<int>(nstates))
+
7226  throw std::range_error(
+
7227  "The new state " + std::to_string(p->state) + " is out of range. " +
+
7228  "The model currently has " + std::to_string(nstates - 1) + " states.");
+
7229  #endif
+
7230 
+
7231  // Updating queue
+
7232  if (use_queuing)
+
7233  {
+
7234 
+
7235  if (a.queue == Queue<TSeq>::Everyone)
+
7236  queue += p;
+
7237  else if (a.queue == -Queue<TSeq>::Everyone)
+
7238  queue -= p;
+
7239  else if (a.queue == Queue<TSeq>::OnlySelf)
+
7240  queue[p->get_id()]++;
+
7241  else if (a.queue == -Queue<TSeq>::OnlySelf)
+
7242  queue[p->get_id()]--;
+
7243  else if (a.queue != Queue<TSeq>::NoOne)
+
7244  throw std::logic_error(
+
7245  "The proposed queue change is not valid. Queue values can be {-2, -1, 0, 1, 2}."
+
7246  );
+
7247 
+
7248  }
+
7249 
+
7250  }
7251 
-
7252 template<typename TSeq>
-
7253 inline epiworld_double transmission_reduction_mixer_default(
-
7254  Agent<TSeq>* p,
-
7255  VirusPtr<TSeq> v,
-
7256  Model<TSeq>* m
-
7257 )
-
7258 {
-
7259  epiworld_double total = 1.0;
-
7260  for (auto & tool : p->get_tools())
-
7261  total *= (1.0 - tool->get_transmission_reduction(v, m));
-
7262 
-
7263  return (1.0 - total);
-
7264 
-
7265 }
-
7266 
+
7252  // Go back to square 1
+
7253  nactions = 0u;
+
7254 
+
7255  return;
+
7256 
+
7257 }
+
7258 
7267 template<typename TSeq>
-
7268 inline epiworld_double recovery_enhancer_mixer_default(
+
7268 inline epiworld_double susceptibility_reduction_mixer_default(
7269  Agent<TSeq>* p,
7270  VirusPtr<TSeq> v,
-
7271  Model<TSeq>* m
+
7271  Model<TSeq> * m
7272 )
7273 {
7274  epiworld_double total = 1.0;
7275  for (auto & tool : p->get_tools())
-
7276  total *= (1.0 - tool->get_recovery_enhancer(v, m));
+
7276  total *= (1.0 - tool->get_susceptibility_reduction(v, m));
7277 
7278  return 1.0 - total;
7279 
7280 }
7281 
7282 template<typename TSeq>
-
7283 inline epiworld_double death_reduction_mixer_default(
+
7283 inline epiworld_double transmission_reduction_mixer_default(
7284  Agent<TSeq>* p,
7285  VirusPtr<TSeq> v,
7286  Model<TSeq>* m
-
7287 ) {
-
7288 
+
7287 )
+
7288 {
7289  epiworld_double total = 1.0;
7290  for (auto & tool : p->get_tools())
-
7291  {
-
7292  total *= (1.0 - tool->get_death_reduction(v, m));
-
7293  }
-
7294 
-
7295  return 1.0 - total;
-
7296 
-
7297 }
-
7299 
-
7300 template<typename TSeq>
-
7301 inline Model<TSeq> * Model<TSeq>::clone_ptr()
-
7302 {
-
7303  Model<TSeq> * ptr = new Model<TSeq>(*dynamic_cast<const Model<TSeq>*>(this));
-
7304 
-
7305  #ifdef EPI_DEBUG
-
7306  if (*this != *ptr)
-
7307  throw std::logic_error("Model::clone_ptr The copies of the model don't match.");
-
7308  #endif
-
7309 
-
7310  return ptr;
-
7311 }
-
7312 
-
7313 template<typename TSeq>
-
7314 inline Model<TSeq>::Model()
-
7315 {
-
7316  db.model = this;
-
7317  db.user_data = this;
-
7318  if (use_queuing)
-
7319  queue.model = this;
-
7320 }
-
7321 
-
7322 template<typename TSeq>
-
7323 inline Model<TSeq>::Model(const Model<TSeq> & model) :
-
7324  name(model.name),
-
7325  db(model.db),
-
7326  population(model.population),
-
7327  population_backup(model.population_backup),
-
7328  directed(model.directed),
-
7329  viruses(model.viruses),
-
7330  tools(model.tools),
-
7331  entities(model.entities),
-
7332  entities_backup(model.entities_backup),
-
7333  rewire_fun(model.rewire_fun),
-
7334  rewire_prop(model.rewire_prop),
-
7335  parameters(model.parameters),
-
7336  ndays(model.ndays),
-
7337  pb(model.pb),
-
7338  state_fun(model.state_fun),
-
7339  states_labels(model.states_labels),
-
7340  initial_states_fun(model.initial_states_fun),
-
7341  nstates(model.nstates),
-
7342  verbose(model.verbose),
-
7343  current_date(model.current_date),
-
7344  globalevents(model.globalevents),
-
7345  queue(model.queue),
-
7346  use_queuing(model.use_queuing),
-
7347  array_double_tmp(model.array_double_tmp.size()),
-
7348  array_virus_tmp(model.array_virus_tmp.size()),
-
7349  array_int_tmp(model.array_int_tmp.size())
-
7350 {
+
7291  total *= (1.0 - tool->get_transmission_reduction(v, m));
+
7292 
+
7293  return (1.0 - total);
+
7294 
+
7295 }
+
7296 
+
7297 template<typename TSeq>
+
7298 inline epiworld_double recovery_enhancer_mixer_default(
+
7299  Agent<TSeq>* p,
+
7300  VirusPtr<TSeq> v,
+
7301  Model<TSeq>* m
+
7302 )
+
7303 {
+
7304  epiworld_double total = 1.0;
+
7305  for (auto & tool : p->get_tools())
+
7306  total *= (1.0 - tool->get_recovery_enhancer(v, m));
+
7307 
+
7308  return 1.0 - total;
+
7309 
+
7310 }
+
7311 
+
7312 template<typename TSeq>
+
7313 inline epiworld_double death_reduction_mixer_default(
+
7314  Agent<TSeq>* p,
+
7315  VirusPtr<TSeq> v,
+
7316  Model<TSeq>* m
+
7317 ) {
+
7318 
+
7319  epiworld_double total = 1.0;
+
7320  for (auto & tool : p->get_tools())
+
7321  {
+
7322  total *= (1.0 - tool->get_death_reduction(v, m));
+
7323  }
+
7324 
+
7325  return 1.0 - total;
+
7326 
+
7327 }
+
7329 
+
7330 template<typename TSeq>
+
7331 inline Model<TSeq> * Model<TSeq>::clone_ptr()
+
7332 {
+
7333  Model<TSeq> * ptr = new Model<TSeq>(*dynamic_cast<const Model<TSeq>*>(this));
+
7334 
+
7335  #ifdef EPI_DEBUG
+
7336  if (*this != *ptr)
+
7337  throw std::logic_error("Model::clone_ptr The copies of the model don't match.");
+
7338  #endif
+
7339 
+
7340  return ptr;
+
7341 }
+
7342 
+
7343 template<typename TSeq>
+
7344 inline Model<TSeq>::Model()
+
7345 {
+
7346  db.model = this;
+
7347  db.user_data = this;
+
7348  if (use_queuing)
+
7349  queue.model = this;
+
7350 }
7351 
-
7352 
-
7353  // Removing old neighbors
-
7354  for (auto & p : population)
-
7355  p.model = this;
-
7356 
-
7357  if (population_backup.size() != 0u)
-
7358  for (auto & p : population_backup)
-
7359  p.model = this;
-
7360 
-
7361  // Pointing to the right place. This needs
-
7362  // to be done afterwards since the state zero is set as a function
-
7363  // of the population.
-
7364  db.model = this;
-
7365  db.user_data.model = this;
-
7366 
-
7367  if (use_queuing)
-
7368  queue.model = this;
-
7369 
-
7370  agents_data = model.agents_data;
-
7371  agents_data_ncols = model.agents_data_ncols;
-
7372 
-
7373 }
-
7374 
-
7375 template<typename TSeq>
-
7376 inline Model<TSeq>::Model(Model<TSeq> & model) :
-
7377  Model(dynamic_cast< const Model<TSeq> & >(model)) {}
-
7378 
-
7379 template<typename TSeq>
-
7380 inline Model<TSeq>::Model(Model<TSeq> && model) :
-
7381  name(std::move(model.name)),
-
7382  db(std::move(model.db)),
-
7383  population(std::move(model.population)),
-
7384  agents_data(std::move(model.agents_data)),
-
7385  agents_data_ncols(std::move(model.agents_data_ncols)),
-
7386  directed(std::move(model.directed)),
-
7387  // Virus
-
7388  viruses(std::move(model.viruses)),
-
7389  // Tools
-
7390  tools(std::move(model.tools)),
-
7391  // Entities
-
7392  entities(std::move(model.entities)),
-
7393  entities_backup(std::move(model.entities_backup)),
-
7394  // Pseudo-RNG
-
7395  engine(std::move(model.engine)),
-
7396  runifd(std::move(model.runifd)),
-
7397  rnormd(std::move(model.rnormd)),
-
7398  rgammad(std::move(model.rgammad)),
-
7399  rlognormald(std::move(model.rlognormald)),
-
7400  rexpd(std::move(model.rexpd)),
-
7401  // Rewiring
-
7402  rewire_fun(std::move(model.rewire_fun)),
-
7403  rewire_prop(std::move(model.rewire_prop)),
-
7404  parameters(std::move(model.parameters)),
-
7405  // Others
-
7406  ndays(model.ndays),
-
7407  pb(std::move(model.pb)),
-
7408  state_fun(std::move(model.state_fun)),
-
7409  states_labels(std::move(model.states_labels)),
-
7410  initial_states_fun(std::move(model.initial_states_fun)),
-
7411  nstates(model.nstates),
-
7412  verbose(model.verbose),
-
7413  current_date(std::move(model.current_date)),
-
7414  globalevents(std::move(model.globalevents)),
-
7415  queue(std::move(model.queue)),
-
7416  use_queuing(model.use_queuing),
-
7417  array_double_tmp(model.array_double_tmp.size()),
-
7418  array_virus_tmp(model.array_virus_tmp.size()),
-
7419  array_int_tmp(model.array_int_tmp.size())
-
7420 {
-
7421 
-
7422  db.model = this;
-
7423  db.user_data.model = this;
-
7424 
-
7425  if (use_queuing)
-
7426  queue.model = this;
-
7427 
-
7428 }
-
7429 
-
7430 template<typename TSeq>
-
7431 inline Model<TSeq> & Model<TSeq>::operator=(const Model<TSeq> & m)
-
7432 {
-
7433  name = m.name;
-
7434 
-
7435  population = m.population;
-
7436  population_backup = m.population_backup;
-
7437 
-
7438  for (auto & p : population)
-
7439  p.model = this;
-
7440 
-
7441  if (population_backup.size() != 0)
-
7442  for (auto & p : population_backup)
-
7443  p.model = this;
-
7444 
-
7445  db = m.db;
-
7446  db.model = this;
-
7447  db.user_data.model = this;
-
7448 
-
7449  directed = m.directed;
-
7450 
-
7451  viruses = m.viruses;
-
7452 
-
7453  tools = m.tools;
-
7454 
-
7455  entities = m.entities;
-
7456  entities_backup = m.entities_backup;
-
7457 
-
7458  rewire_fun = m.rewire_fun;
-
7459  rewire_prop = m.rewire_prop;
-
7460 
-
7461  parameters = m.parameters;
-
7462  ndays = m.ndays;
-
7463  pb = m.pb;
+
7352 template<typename TSeq>
+
7353 inline Model<TSeq>::Model(const Model<TSeq> & model) :
+
7354  name(model.name),
+
7355  db(model.db),
+
7356  population(model.population),
+
7357  population_backup(model.population_backup),
+
7358  directed(model.directed),
+
7359  viruses(model.viruses),
+
7360  tools(model.tools),
+
7361  entities(model.entities),
+
7362  entities_backup(model.entities_backup),
+
7363  rewire_fun(model.rewire_fun),
+
7364  rewire_prop(model.rewire_prop),
+
7365  parameters(model.parameters),
+
7366  ndays(model.ndays),
+
7367  pb(model.pb),
+
7368  state_fun(model.state_fun),
+
7369  states_labels(model.states_labels),
+
7370  initial_states_fun(model.initial_states_fun),
+
7371  nstates(model.nstates),
+
7372  verbose(model.verbose),
+
7373  current_date(model.current_date),
+
7374  globalevents(model.globalevents),
+
7375  queue(model.queue),
+
7376  use_queuing(model.use_queuing),
+
7377  array_double_tmp(model.array_double_tmp.size()),
+
7378  array_virus_tmp(model.array_virus_tmp.size()),
+
7379  array_int_tmp(model.array_int_tmp.size())
+
7380 {
+
7381 
+
7382 
+
7383  // Removing old neighbors
+
7384  for (auto & p : population)
+
7385  p.model = this;
+
7386 
+
7387  if (population_backup.size() != 0u)
+
7388  for (auto & p : population_backup)
+
7389  p.model = this;
+
7390 
+
7391  // Pointing to the right place. This needs
+
7392  // to be done afterwards since the state zero is set as a function
+
7393  // of the population.
+
7394  db.model = this;
+
7395  db.user_data.model = this;
+
7396 
+
7397  if (use_queuing)
+
7398  queue.model = this;
+
7399 
+
7400  agents_data = model.agents_data;
+
7401  agents_data_ncols = model.agents_data_ncols;
+
7402 
+
7403 }
+
7404 
+
7405 template<typename TSeq>
+
7406 inline Model<TSeq>::Model(Model<TSeq> & model) :
+
7407  Model(dynamic_cast< const Model<TSeq> & >(model)) {}
+
7408 
+
7409 template<typename TSeq>
+
7410 inline Model<TSeq>::Model(Model<TSeq> && model) :
+
7411  name(std::move(model.name)),
+
7412  db(std::move(model.db)),
+
7413  population(std::move(model.population)),
+
7414  agents_data(std::move(model.agents_data)),
+
7415  agents_data_ncols(std::move(model.agents_data_ncols)),
+
7416  directed(std::move(model.directed)),
+
7417  // Virus
+
7418  viruses(std::move(model.viruses)),
+
7419  // Tools
+
7420  tools(std::move(model.tools)),
+
7421  // Entities
+
7422  entities(std::move(model.entities)),
+
7423  entities_backup(std::move(model.entities_backup)),
+
7424  // Pseudo-RNG
+
7425  engine(std::move(model.engine)),
+
7426  runifd(std::move(model.runifd)),
+
7427  rnormd(std::move(model.rnormd)),
+
7428  rgammad(std::move(model.rgammad)),
+
7429  rlognormald(std::move(model.rlognormald)),
+
7430  rexpd(std::move(model.rexpd)),
+
7431  // Rewiring
+
7432  rewire_fun(std::move(model.rewire_fun)),
+
7433  rewire_prop(std::move(model.rewire_prop)),
+
7434  parameters(std::move(model.parameters)),
+
7435  // Others
+
7436  ndays(model.ndays),
+
7437  pb(std::move(model.pb)),
+
7438  state_fun(std::move(model.state_fun)),
+
7439  states_labels(std::move(model.states_labels)),
+
7440  initial_states_fun(std::move(model.initial_states_fun)),
+
7441  nstates(model.nstates),
+
7442  verbose(model.verbose),
+
7443  current_date(std::move(model.current_date)),
+
7444  globalevents(std::move(model.globalevents)),
+
7445  queue(std::move(model.queue)),
+
7446  use_queuing(model.use_queuing),
+
7447  array_double_tmp(model.array_double_tmp.size()),
+
7448  array_virus_tmp(model.array_virus_tmp.size()),
+
7449  array_int_tmp(model.array_int_tmp.size())
+
7450 {
+
7451 
+
7452  db.model = this;
+
7453  db.user_data.model = this;
+
7454 
+
7455  if (use_queuing)
+
7456  queue.model = this;
+
7457 
+
7458 }
+
7459 
+
7460 template<typename TSeq>
+
7461 inline Model<TSeq> & Model<TSeq>::operator=(const Model<TSeq> & m)
+
7462 {
+
7463  name = m.name;
7464 
-
7465  state_fun = m.state_fun;
-
7466  states_labels = m.states_labels;
-
7467  initial_states_fun = m.initial_states_fun;
-
7468  nstates = m.nstates;
-
7469 
-
7470  verbose = m.verbose;
-
7471 
-
7472  current_date = m.current_date;
-
7473 
-
7474  globalevents = m.globalevents;
-
7475 
-
7476  queue = m.queue;
-
7477  use_queuing = m.use_queuing;
+
7465  population = m.population;
+
7466  population_backup = m.population_backup;
+
7467 
+
7468  for (auto & p : population)
+
7469  p.model = this;
+
7470 
+
7471  if (population_backup.size() != 0)
+
7472  for (auto & p : population_backup)
+
7473  p.model = this;
+
7474 
+
7475  db = m.db;
+
7476  db.model = this;
+
7477  db.user_data.model = this;
7478 
-
7479  // Making sure population is passed correctly
-
7480  // Pointing to the right place
-
7481  db.model = this;
-
7482  db.user_data.model = this;
-
7483 
-
7484  agents_data = m.agents_data;
-
7485  agents_data_ncols = m.agents_data_ncols;
-
7486 
-
7487  // Figure out the queuing
-
7488  if (use_queuing)
-
7489  queue.model = this;
+
7479  directed = m.directed;
+
7480 
+
7481  viruses = m.viruses;
+
7482 
+
7483  tools = m.tools;
+
7484 
+
7485  entities = m.entities;
+
7486  entities_backup = m.entities_backup;
+
7487 
+
7488  rewire_fun = m.rewire_fun;
+
7489  rewire_prop = m.rewire_prop;
7490 
-
7491  array_double_tmp.resize(std::max(
-
7492  size(),
-
7493  static_cast<size_t>(1024 * 1024)
-
7494  ));
-
7495 
-
7496  array_virus_tmp.resize(1024u);
-
7497  array_int_tmp.resize(1024u * 1024);
-
7498 
-
7499  return *this;
-
7500 
-
7501 }
-
7502 
-
7503 template<typename TSeq>
-
7504 inline DataBase<TSeq> & Model<TSeq>::get_db()
-
7505 {
-
7506  return db;
-
7507 }
+
7491  parameters = m.parameters;
+
7492  ndays = m.ndays;
+
7493  pb = m.pb;
+
7494 
+
7495  state_fun = m.state_fun;
+
7496  states_labels = m.states_labels;
+
7497  initial_states_fun = m.initial_states_fun;
+
7498  nstates = m.nstates;
+
7499 
+
7500  verbose = m.verbose;
+
7501 
+
7502  current_date = m.current_date;
+
7503 
+
7504  globalevents = m.globalevents;
+
7505 
+
7506  queue = m.queue;
+
7507  use_queuing = m.use_queuing;
7508 
-
7509 template<typename TSeq>
-
7510 inline const DataBase<TSeq> & Model<TSeq>::get_db() const
-
7511 {
-
7512  return db;
-
7513 }
-
7514 
-
7515 
-
7516 template<typename TSeq>
-
7517 inline std::vector<Agent<TSeq>> & Model<TSeq>::get_agents()
-
7518 {
-
7519  return population;
-
7520 }
-
7521 
-
7522 template<typename TSeq>
-
7523 inline Agent<TSeq> & Model<TSeq>::get_agent(size_t i)
-
7524 {
-
7525  return population[i];
-
7526 }
-
7527 
-
7528 template<typename TSeq>
-
7529 inline std::vector< epiworld_fast_uint > Model<TSeq>::get_agents_states() const
-
7530 {
-
7531  std::vector< epiworld_fast_uint > states(population.size());
-
7532  for (size_t i = 0u; i < population.size(); ++i)
-
7533  states[i] = population[i].get_state();
-
7534 
-
7535  return states;
-
7536 }
-
7537 
-
7538 template<typename TSeq>
-
7539 inline std::vector< Viruses_const<TSeq> > Model<TSeq>::get_agents_viruses() const
-
7540 {
-
7541 
-
7542  std::vector< Viruses_const<TSeq> > viruses(population.size());
-
7543  for (size_t i = 0u; i < population.size(); ++i)
-
7544  viruses[i] = population[i].get_virus();
+
7509  // Making sure population is passed correctly
+
7510  // Pointing to the right place
+
7511  db.model = this;
+
7512  db.user_data.model = this;
+
7513 
+
7514  agents_data = m.agents_data;
+
7515  agents_data_ncols = m.agents_data_ncols;
+
7516 
+
7517  // Figure out the queuing
+
7518  if (use_queuing)
+
7519  queue.model = this;
+
7520 
+
7521  array_double_tmp.resize(std::max(
+
7522  size(),
+
7523  static_cast<size_t>(1024 * 1024)
+
7524  ));
+
7525 
+
7526  array_virus_tmp.resize(1024u);
+
7527  array_int_tmp.resize(1024u * 1024);
+
7528 
+
7529  return *this;
+
7530 
+
7531 }
+
7532 
+
7533 template<typename TSeq>
+
7534 inline DataBase<TSeq> & Model<TSeq>::get_db()
+
7535 {
+
7536  return db;
+
7537 }
+
7538 
+
7539 template<typename TSeq>
+
7540 inline const DataBase<TSeq> & Model<TSeq>::get_db() const
+
7541 {
+
7542  return db;
+
7543 }
+
7544 
7545 
-
7546  return viruses;
-
7547 
-
7548 }
-
7549 
-
7550 // Same as before, but the non const version
-
7551 template<typename TSeq>
-
7552 inline std::vector< Viruses<TSeq> > Model<TSeq>::get_agents_viruses()
-
7553 {
-
7554 
-
7555  std::vector< Viruses<TSeq> > viruses(population.size());
-
7556  for (size_t i = 0u; i < population.size(); ++i)
-
7557  viruses[i] = population[i].get_virus();
-
7558 
-
7559  return viruses;
-
7560 
-
7561 }
-
7562 
-
7563 template<typename TSeq>
-
7564 inline std::vector<Entity<TSeq>> & Model<TSeq>::get_entities()
-
7565 {
-
7566  return entities;
-
7567 }
-
7568 
-
7569 template<typename TSeq>
-
7570 inline Entity<TSeq> & Model<TSeq>::get_entity(size_t i, int * entity_pos)
-
7571 {
-
7572 
-
7573  for (size_t j = 0u; j < entities.size(); ++j)
-
7574  if (entities[j].get_id() == static_cast<int>(i))
-
7575  {
-
7576 
-
7577  if (entity_pos)
-
7578  *entity_pos = j;
+
7546 template<typename TSeq>
+
7547 inline std::vector<Agent<TSeq>> & Model<TSeq>::get_agents()
+
7548 {
+
7549  return population;
+
7550 }
+
7551 
+
7552 template<typename TSeq>
+
7553 inline Agent<TSeq> & Model<TSeq>::get_agent(size_t i)
+
7554 {
+
7555  return population[i];
+
7556 }
+
7557 
+
7558 template<typename TSeq>
+
7559 inline std::vector< epiworld_fast_uint > Model<TSeq>::get_agents_states() const
+
7560 {
+
7561  std::vector< epiworld_fast_uint > states(population.size());
+
7562  for (size_t i = 0u; i < population.size(); ++i)
+
7563  states[i] = population[i].get_state();
+
7564 
+
7565  return states;
+
7566 }
+
7567 
+
7568 template<typename TSeq>
+
7569 inline std::vector< Viruses_const<TSeq> > Model<TSeq>::get_agents_viruses() const
+
7570 {
+
7571 
+
7572  std::vector< Viruses_const<TSeq> > viruses(population.size());
+
7573  for (size_t i = 0u; i < population.size(); ++i)
+
7574  viruses[i] = population[i].get_virus();
+
7575 
+
7576  return viruses;
+
7577 
+
7578 }
7579 
-
7580  return entities[j];
-
7581 
-
7582  }
-
7583 
-
7584  throw std::range_error("The entity with id " + std::to_string(i) + " was not found.");
-
7585 
-
7586 }
-
7587 
-
7588 template<typename TSeq>
-
7589 inline Model<TSeq> & Model<TSeq>::agents_smallworld(
-
7590  epiworld_fast_uint n,
-
7591  epiworld_fast_uint k,
-
7592  bool d,
-
7593  epiworld_double p
-
7594 )
+
7580 // Same as before, but the non const version
+
7581 template<typename TSeq>
+
7582 inline std::vector< Viruses<TSeq> > Model<TSeq>::get_agents_viruses()
+
7583 {
+
7584 
+
7585  std::vector< Viruses<TSeq> > viruses(population.size());
+
7586  for (size_t i = 0u; i < population.size(); ++i)
+
7587  viruses[i] = population[i].get_virus();
+
7588 
+
7589  return viruses;
+
7590 
+
7591 }
+
7592 
+
7593 template<typename TSeq>
+
7594 inline std::vector<Entity<TSeq>> & Model<TSeq>::get_entities()
7595 {
-
7596  agents_from_adjlist(
-
7597  rgraph_smallworld(n, k, p, d, *this)
-
7598  );
-
7599 
-
7600  return *this;
-
7601 }
-
7602 
-
7603 template<typename TSeq>
-
7604 inline void Model<TSeq>::agents_empty_graph(
-
7605  epiworld_fast_uint n
-
7606 )
-
7607 {
-
7608 
-
7609  // Resizing the people
-
7610  population.clear();
-
7611  population.resize(n, Agent<TSeq>());
-
7612 
-
7613  // Filling the model and ids
-
7614  size_t i = 0u;
-
7615  for (auto & p : population)
-
7616  {
-
7617  p.id = i++;
-
7618  p.model = this;
-
7619  }
-
7620 
-
7621 
-
7622 }
-
7623 
-
7624 template<typename TSeq>
-
7625 inline void Model<TSeq>::set_rand_gamma(epiworld_double alpha, epiworld_double beta)
-
7626 {
-
7627  rgammad = std::gamma_distribution<>(alpha,beta);
-
7628 }
+
7596  return entities;
+
7597 }
+
7598 
+
7599 template<typename TSeq>
+
7600 inline Entity<TSeq> & Model<TSeq>::get_entity(size_t i, int * entity_pos)
+
7601 {
+
7602 
+
7603  for (size_t j = 0u; j < entities.size(); ++j)
+
7604  if (entities[j].get_id() == static_cast<int>(i))
+
7605  {
+
7606 
+
7607  if (entity_pos)
+
7608  *entity_pos = j;
+
7609 
+
7610  return entities[j];
+
7611 
+
7612  }
+
7613 
+
7614  throw std::range_error("The entity with id " + std::to_string(i) + " was not found.");
+
7615 
+
7616 }
+
7617 
+
7618 template<typename TSeq>
+
7619 inline Model<TSeq> & Model<TSeq>::agents_smallworld(
+
7620  epiworld_fast_uint n,
+
7621  epiworld_fast_uint k,
+
7622  bool d,
+
7623  epiworld_double p
+
7624 )
+
7625 {
+
7626  agents_from_adjlist(
+
7627  rgraph_smallworld(n, k, p, d, *this)
+
7628  );
7629 
-
7630 template<typename TSeq>
-
7631 inline void Model<TSeq>::set_rand_norm(epiworld_double mean, epiworld_double sd)
-
7632 {
-
7633  rnormd = std::normal_distribution<>(mean, sd);
-
7634 }
-
7635 
-
7636 template<typename TSeq>
-
7637 inline void Model<TSeq>::set_rand_unif(epiworld_double a, epiworld_double b)
-
7638 {
-
7639  runifd = std::uniform_real_distribution<>(a, b);
-
7640 }
-
7641 
-
7642 template<typename TSeq>
-
7643 inline void Model<TSeq>::set_rand_lognormal(epiworld_double mean, epiworld_double shape)
-
7644 {
-
7645  rlognormald = std::lognormal_distribution<>(mean, shape);
-
7646 }
-
7647 
-
7648 template<typename TSeq>
-
7649 inline void Model<TSeq>::set_rand_exp(epiworld_double lambda)
-
7650 {
-
7651  rexpd = std::exponential_distribution<>(lambda);
+
7630  return *this;
+
7631 }
+
7632 
+
7633 template<typename TSeq>
+
7634 inline void Model<TSeq>::agents_empty_graph(
+
7635  epiworld_fast_uint n
+
7636 )
+
7637 {
+
7638 
+
7639  // Resizing the people
+
7640  population.clear();
+
7641  population.resize(n, Agent<TSeq>());
+
7642 
+
7643  // Filling the model and ids
+
7644  size_t i = 0u;
+
7645  for (auto & p : population)
+
7646  {
+
7647  p.id = i++;
+
7648  p.model = this;
+
7649  }
+
7650 
+
7651 
7652 }
7653 
7654 template<typename TSeq>
-
7655 inline void Model<TSeq>::set_rand_binom(int n, epiworld_double p)
-
7656 {
-
7657  rbinomd = std::binomial_distribution<>(n, p);
+
7655 inline void Model<TSeq>::set_rand_gamma(epiworld_double alpha, epiworld_double beta)
+
7656 {
+
7657  rgammad = std::gamma_distribution<>(alpha,beta);
7658 }
7659 
7660 template<typename TSeq>
-
7661 inline epiworld_double & Model<TSeq>::operator()(std::string pname) {
-
7662 
-
7663  if (parameters.find(pname) == parameters.end())
-
7664  throw std::range_error("The parameter "+ pname + "is not in the model.");
+
7661 inline void Model<TSeq>::set_rand_norm(epiworld_double mean, epiworld_double sd)
+
7662 {
+
7663  rnormd = std::normal_distribution<>(mean, sd);
+
7664 }
7665 
-
7666  return parameters[pname];
-
7667 
-
7668 }
-
7669 
-
7670 template<typename TSeq>
-
7671 inline size_t Model<TSeq>::size() const {
-
7672  return population.size();
-
7673 }
-
7674 
-
7675 template<typename TSeq>
-
7676 inline void Model<TSeq>::dist_virus()
-
7677 {
-
7678 
-
7679  for (auto & v: viruses)
-
7680  {
-
7681 
-
7682  v->distribute(this);
+
7666 template<typename TSeq>
+
7667 inline void Model<TSeq>::set_rand_unif(epiworld_double a, epiworld_double b)
+
7668 {
+
7669  runifd = std::uniform_real_distribution<>(a, b);
+
7670 }
+
7671 
+
7672 template<typename TSeq>
+
7673 inline void Model<TSeq>::set_rand_lognormal(epiworld_double mean, epiworld_double shape)
+
7674 {
+
7675  rlognormald = std::lognormal_distribution<>(mean, shape);
+
7676 }
+
7677 
+
7678 template<typename TSeq>
+
7679 inline void Model<TSeq>::set_rand_exp(epiworld_double lambda)
+
7680 {
+
7681  rexpd = std::exponential_distribution<>(lambda);
+
7682 }
7683 
-
7684  // Apply the events
-
7685  events_run();
-
7686  }
-
7687 
+
7684 template<typename TSeq>
+
7685 inline void Model<TSeq>::set_rand_binom(int n, epiworld_double p)
+
7686 {
+
7687  rbinomd = std::binomial_distribution<>(n, p);
7688 }
7689 
7690 template<typename TSeq>
-
7691 inline void Model<TSeq>::dist_tools()
-
7692 {
-
7693 
-
7694  for (auto & tool: tools)
-
7695  {
-
7696 
-
7697  tool->distribute(this);
-
7698 
-
7699  // Apply the events
-
7700  events_run();
-
7701 
-
7702  }
-
7703 
-
7704 }
-
7705 
-
7706 template<typename TSeq>
-
7707 inline void Model<TSeq>::dist_entities()
-
7708 {
-
7709 
-
7710  for (auto & entity: entities)
-
7711  {
-
7712 
-
7713  entity.distribute(this);
-
7714 
-
7715  // Apply the events
-
7716  events_run();
+
7691 inline epiworld_double & Model<TSeq>::operator()(std::string pname) {
+
7692 
+
7693  if (parameters.find(pname) == parameters.end())
+
7694  throw std::range_error("The parameter '"+ pname + "' is not in the model.");
+
7695 
+
7696  return parameters[pname];
+
7697 
+
7698 }
+
7699 
+
7700 template<typename TSeq>
+
7701 inline size_t Model<TSeq>::size() const {
+
7702  return population.size();
+
7703 }
+
7704 
+
7705 template<typename TSeq>
+
7706 inline void Model<TSeq>::dist_virus()
+
7707 {
+
7708 
+
7709  for (auto & v: viruses)
+
7710  {
+
7711 
+
7712  v->distribute(this);
+
7713 
+
7714  // Apply the events
+
7715  events_run();
+
7716  }
7717 
-
7718  }
+
7718 }
7719 
-
7720 }
-
7721 
-
7722 template<typename TSeq>
-
7723 inline void Model<TSeq>::chrono_start() {
-
7724  time_start = std::chrono::steady_clock::now();
-
7725 }
+
7720 template<typename TSeq>
+
7721 inline void Model<TSeq>::dist_tools()
+
7722 {
+
7723 
+
7724  for (auto & tool: tools)
+
7725  {
7726 
-
7727 template<typename TSeq>
-
7728 inline void Model<TSeq>::chrono_end() {
-
7729  time_end = std::chrono::steady_clock::now();
-
7730  time_elapsed += (time_end - time_start);
-
7731  n_replicates++;
-
7732 }
+
7727  tool->distribute(this);
+
7728 
+
7729  // Apply the events
+
7730  events_run();
+
7731 
+
7732  }
7733 
-
7734 template<typename TSeq>
-
7735 inline void Model<TSeq>::set_backup()
-
7736 {
-
7737 
-
7738  if (population_backup.size() == 0u)
-
7739  population_backup = population;
-
7740 
-
7741  if (entities_backup.size() == 0u)
-
7742  entities_backup = entities;
-
7743 
-
7744 }
-
7745 
-
7746 // template<typename TSeq>
-
7747 // inline void Model<TSeq>::restore_backup()
-
7748 // {
+
7734 }
+
7735 
+
7736 template<typename TSeq>
+
7737 inline void Model<TSeq>::dist_entities()
+
7738 {
+
7739 
+
7740  for (auto & entity: entities)
+
7741  {
+
7742 
+
7743  entity.distribute(this);
+
7744 
+
7745  // Apply the events
+
7746  events_run();
+
7747 
+
7748  }
7749 
-
7750 // // Restoring the data
-
7751 // population = *population_backup;
-
7752 // entities = *entities_backup;
-
7753 
-
7754 // // And correcting the pointer
-
7755 // for (auto & p : population)
-
7756 // p.model = this;
-
7757 
-
7758 // for (auto & e : entities)
-
7759 // e.model = this;
-
7760 
-
7761 // }
-
7762 
-
7763 template<typename TSeq>
-
7764 inline std::shared_ptr< std::mt19937 > & Model<TSeq>::get_rand_endgine()
-
7765 {
-
7766  return engine;
-
7767 }
-
7768 
-
7769 template<typename TSeq>
-
7770 inline epiworld_double Model<TSeq>::runif() {
-
7771  // CHECK_INIT()
-
7772  return runifd(*engine);
-
7773 }
-
7774 
-
7775 template<typename TSeq>
-
7776 inline epiworld_double Model<TSeq>::runif(epiworld_double a, epiworld_double b) {
-
7777  // CHECK_INIT()
-
7778  return runifd(*engine) * (b - a) + a;
-
7779 }
-
7780 
-
7781 template<typename TSeq>
-
7782 inline epiworld_double Model<TSeq>::rnorm() {
-
7783  // CHECK_INIT()
-
7784  return rnormd(*engine);
-
7785 }
-
7786 
-
7787 template<typename TSeq>
-
7788 inline epiworld_double Model<TSeq>::rnorm(epiworld_double mean, epiworld_double sd) {
-
7789  // CHECK_INIT()
-
7790  return rnormd(*engine) * sd + mean;
-
7791 }
+
7750 }
+
7751 
+
7752 template<typename TSeq>
+
7753 inline void Model<TSeq>::chrono_start() {
+
7754  time_start = std::chrono::steady_clock::now();
+
7755 }
+
7756 
+
7757 template<typename TSeq>
+
7758 inline void Model<TSeq>::chrono_end() {
+
7759  time_end = std::chrono::steady_clock::now();
+
7760  time_elapsed += (time_end - time_start);
+
7761  n_replicates++;
+
7762 }
+
7763 
+
7764 template<typename TSeq>
+
7765 inline void Model<TSeq>::set_backup()
+
7766 {
+
7767 
+
7768  if (population_backup.size() == 0u)
+
7769  population_backup = population;
+
7770 
+
7771  if (entities_backup.size() == 0u)
+
7772  entities_backup = entities;
+
7773 
+
7774 }
+
7775 
+
7776 // template<typename TSeq>
+
7777 // inline void Model<TSeq>::restore_backup()
+
7778 // {
+
7779 
+
7780 // // Restoring the data
+
7781 // population = *population_backup;
+
7782 // entities = *entities_backup;
+
7783 
+
7784 // // And correcting the pointer
+
7785 // for (auto & p : population)
+
7786 // p.model = this;
+
7787 
+
7788 // for (auto & e : entities)
+
7789 // e.model = this;
+
7790 
+
7791 // }
7792 
7793 template<typename TSeq>
-
7794 inline epiworld_double Model<TSeq>::rgamma() {
-
7795  return rgammad(*engine);
-
7796 }
-
7797 
-
7798 template<typename TSeq>
-
7799 inline epiworld_double Model<TSeq>::rgamma(epiworld_double alpha, epiworld_double beta) {
-
7800  auto old_param = rgammad.param();
-
7801  rgammad.param(std::gamma_distribution<>::param_type(alpha, beta));
-
7802  epiworld_double ans = rgammad(*engine);
-
7803  rgammad.param(old_param);
-
7804  return ans;
-
7805 }
-
7806 
-
7807 template<typename TSeq>
-
7808 inline epiworld_double Model<TSeq>::rexp() {
-
7809  return rexpd(*engine);
-
7810 }
-
7811 
-
7812 template<typename TSeq>
-
7813 inline epiworld_double Model<TSeq>::rexp(epiworld_double lambda) {
-
7814  auto old_param = rexpd.param();
-
7815  rexpd.param(std::exponential_distribution<>::param_type(lambda));
-
7816  epiworld_double ans = rexpd(*engine);
-
7817  rexpd.param(old_param);
-
7818  return ans;
-
7819 }
-
7820 
-
7821 template<typename TSeq>
-
7822 inline epiworld_double Model<TSeq>::rlognormal() {
-
7823  return rlognormald(*engine);
-
7824 }
-
7825 
-
7826 template<typename TSeq>
-
7827 inline epiworld_double Model<TSeq>::rlognormal(epiworld_double mean, epiworld_double shape) {
-
7828  auto old_param = rlognormald.param();
-
7829  rlognormald.param(std::lognormal_distribution<>::param_type(mean, shape));
-
7830  epiworld_double ans = rlognormald(*engine);
-
7831  rlognormald.param(old_param);
-
7832  return ans;
-
7833 }
-
7834 
-
7835 template<typename TSeq>
-
7836 inline int Model<TSeq>::rbinom() {
-
7837  return rbinomd(*engine);
-
7838 }
-
7839 
-
7840 template<typename TSeq>
-
7841 inline int Model<TSeq>::rbinom(int n, epiworld_double p) {
-
7842  auto old_param = rbinomd.param();
-
7843  rbinomd.param(std::binomial_distribution<>::param_type(n, p));
-
7844  epiworld_double ans = rbinomd(*engine);
-
7845  rbinomd.param(old_param);
-
7846  return ans;
-
7847 }
-
7848 
-
7849 template<typename TSeq>
-
7850 inline void Model<TSeq>::seed(size_t s) {
-
7851  this->engine->seed(s);
-
7852 }
-
7853 
-
7854 template<typename TSeq>
-
7855 inline void Model<TSeq>::add_virus(
-
7856  Virus<TSeq> & v
-
7857  )
-
7858 {
-
7859 
-
7860  // Checking the state
-
7861  epiworld_fast_int init_, post_, rm_;
-
7862  v.get_state(&init_, &post_, &rm_);
-
7863 
-
7864  if (init_ == -99)
-
7865  throw std::logic_error(
-
7866  "The virus \"" + v.get_name() + "\" has no -init- state."
-
7867  );
-
7868  else if (post_ == -99)
-
7869  throw std::logic_error(
-
7870  "The virus \"" + v.get_name() + "\" has no -post- state."
-
7871  );
-
7872 
-
7873  // Recording the variant
-
7874  db.record_virus(v);
-
7875 
-
7876  // Adding new virus
-
7877  viruses.push_back(std::make_shared< Virus<TSeq> >(v));
+
7794 inline std::shared_ptr< std::mt19937 > & Model<TSeq>::get_rand_endgine()
+
7795 {
+
7796  return engine;
+
7797 }
+
7798 
+
7799 template<typename TSeq>
+
7800 inline epiworld_double Model<TSeq>::runif() {
+
7801  // CHECK_INIT()
+
7802  return runifd(*engine);
+
7803 }
+
7804 
+
7805 template<typename TSeq>
+
7806 inline epiworld_double Model<TSeq>::runif(epiworld_double a, epiworld_double b) {
+
7807  // CHECK_INIT()
+
7808  return runifd(*engine) * (b - a) + a;
+
7809 }
+
7810 
+
7811 template<typename TSeq>
+
7812 inline epiworld_double Model<TSeq>::rnorm() {
+
7813  // CHECK_INIT()
+
7814  return rnormd(*engine);
+
7815 }
+
7816 
+
7817 template<typename TSeq>
+
7818 inline epiworld_double Model<TSeq>::rnorm(epiworld_double mean, epiworld_double sd) {
+
7819  // CHECK_INIT()
+
7820  return rnormd(*engine) * sd + mean;
+
7821 }
+
7822 
+
7823 template<typename TSeq>
+
7824 inline epiworld_double Model<TSeq>::rgamma() {
+
7825  return rgammad(*engine);
+
7826 }
+
7827 
+
7828 template<typename TSeq>
+
7829 inline epiworld_double Model<TSeq>::rgamma(epiworld_double alpha, epiworld_double beta) {
+
7830  auto old_param = rgammad.param();
+
7831  rgammad.param(std::gamma_distribution<>::param_type(alpha, beta));
+
7832  epiworld_double ans = rgammad(*engine);
+
7833  rgammad.param(old_param);
+
7834  return ans;
+
7835 }
+
7836 
+
7837 template<typename TSeq>
+
7838 inline epiworld_double Model<TSeq>::rexp() {
+
7839  return rexpd(*engine);
+
7840 }
+
7841 
+
7842 template<typename TSeq>
+
7843 inline epiworld_double Model<TSeq>::rexp(epiworld_double lambda) {
+
7844  auto old_param = rexpd.param();
+
7845  rexpd.param(std::exponential_distribution<>::param_type(lambda));
+
7846  epiworld_double ans = rexpd(*engine);
+
7847  rexpd.param(old_param);
+
7848  return ans;
+
7849 }
+
7850 
+
7851 template<typename TSeq>
+
7852 inline epiworld_double Model<TSeq>::rlognormal() {
+
7853  return rlognormald(*engine);
+
7854 }
+
7855 
+
7856 template<typename TSeq>
+
7857 inline epiworld_double Model<TSeq>::rlognormal(epiworld_double mean, epiworld_double shape) {
+
7858  auto old_param = rlognormald.param();
+
7859  rlognormald.param(std::lognormal_distribution<>::param_type(mean, shape));
+
7860  epiworld_double ans = rlognormald(*engine);
+
7861  rlognormald.param(old_param);
+
7862  return ans;
+
7863 }
+
7864 
+
7865 template<typename TSeq>
+
7866 inline int Model<TSeq>::rbinom() {
+
7867  return rbinomd(*engine);
+
7868 }
+
7869 
+
7870 template<typename TSeq>
+
7871 inline int Model<TSeq>::rbinom(int n, epiworld_double p) {
+
7872  auto old_param = rbinomd.param();
+
7873  rbinomd.param(std::binomial_distribution<>::param_type(n, p));
+
7874  epiworld_double ans = rbinomd(*engine);
+
7875  rbinomd.param(old_param);
+
7876  return ans;
+
7877 }
7878 
-
7879 }
-
7880 
-
7881 template<typename TSeq>
-
7882 inline void Model<TSeq>::add_tool(Tool<TSeq> & t)
-
7883 {
-
7884 
-
7885 
-
7886  db.record_tool(t);
-
7887 
-
7888  // Adding the tool to the model (and database.)
-
7889  tools.push_back(std::make_shared< Tool<TSeq> >(t));
-
7890 
-
7891 }
-
7892 
-
7893 template<typename TSeq>
-
7894 inline void Model<TSeq>::add_entity(Entity<TSeq> e)
-
7895 {
-
7896 
-
7897  e.id = entities.size();
-
7898  entities.push_back(e);
-
7899 
-
7900 }
-
7901 
-
7902 template<typename TSeq>
-
7903 inline void Model<TSeq>::rm_entity(size_t entity_id)
-
7904 {
+
7879 template<typename TSeq>
+
7880 inline void Model<TSeq>::seed(size_t s) {
+
7881  this->engine->seed(s);
+
7882 }
+
7883 
+
7884 template<typename TSeq>
+
7885 inline void Model<TSeq>::add_virus(
+
7886  Virus<TSeq> & v
+
7887  )
+
7888 {
+
7889 
+
7890  // Checking the state
+
7891  epiworld_fast_int init_, post_, rm_;
+
7892  v.get_state(&init_, &post_, &rm_);
+
7893 
+
7894  if (init_ == -99)
+
7895  throw std::logic_error(
+
7896  "The virus \"" + v.get_name() + "\" has no -init- state."
+
7897  );
+
7898  else if (post_ == -99)
+
7899  throw std::logic_error(
+
7900  "The virus \"" + v.get_name() + "\" has no -post- state."
+
7901  );
+
7902 
+
7903  // Recording the variant
+
7904  db.record_virus(v);
7905 
-
7906  int entity_pos = 0;
-
7907  auto & entity = this->get_entity(entity_id, &entity_pos);
+
7906  // Adding new virus
+
7907  viruses.push_back(std::make_shared< Virus<TSeq> >(v));
7908 
-
7909  // First, resetting the entity
-
7910  entity.reset();
-
7911 
-
7912  // How should
-
7913  if (entity_pos != (static_cast<int>(entities.size()) - 1))
-
7914  std::swap(entities[entity_pos], entities[entities.size() - 1]);
-
7915 
-
7916  entities.pop_back();
-
7917 }
-
7918 
-
7919 template<typename TSeq>
-
7920 inline void Model<TSeq>::rm_virus(size_t virus_pos)
-
7921 {
+
7909 }
+
7910 
+
7911 template<typename TSeq>
+
7912 inline void Model<TSeq>::add_tool(Tool<TSeq> & t)
+
7913 {
+
7914 
+
7915 
+
7916  db.record_tool(t);
+
7917 
+
7918  // Adding the tool to the model (and database.)
+
7919  tools.push_back(std::make_shared< Tool<TSeq> >(t));
+
7920 
+
7921 }
7922 
-
7923  if (viruses.size() <= virus_pos)
-
7924  throw std::range_error(
-
7925  std::string("The specified virus (") +
-
7926  std::to_string(virus_pos) +
-
7927  std::string(") is out of range. ") +
-
7928  std::string("There are only ") +
-
7929  std::to_string(viruses.size()) +
-
7930  std::string(" viruses.")
-
7931  );
-
7932 
-
7933  // Flipping with the last one
-
7934  std::swap(viruses[virus_pos], viruses[viruses.size() - 1]);
-
7935  viruses.pop_back();
-
7936 
-
7937  return;
+
7923 template<typename TSeq>
+
7924 inline void Model<TSeq>::add_entity(Entity<TSeq> e)
+
7925 {
+
7926 
+
7927  e.id = entities.size();
+
7928  entities.push_back(e);
+
7929 
+
7930 }
+
7931 
+
7932 template<typename TSeq>
+
7933 inline void Model<TSeq>::rm_entity(size_t entity_id)
+
7934 {
+
7935 
+
7936  int entity_pos = 0;
+
7937  auto & entity = this->get_entity(entity_id, &entity_pos);
7938 
-
7939 }
-
7940 
-
7941 template<typename TSeq>
-
7942 inline void Model<TSeq>::rm_tool(size_t tool_pos)
-
7943 {
-
7944 
-
7945  if (tools.size() <= tool_pos)
-
7946  throw std::range_error(
-
7947  std::string("The specified tool (") +
-
7948  std::to_string(tool_pos) +
-
7949  std::string(") is out of range. ") +
-
7950  std::string("There are only ") +
-
7951  std::to_string(tools.size()) +
-
7952  std::string(" tools.")
-
7953  );
-
7954 
-
7955  // Flipping with the last one
-
7956  std::swap(tools[tool_pos], tools[tools.size() - 1]);
-
7957 
-
7958  /* There's an error on windows:
-
7959  https://github.com/UofUEpiBio/epiworldR/actions/runs/4801482395/jobs/8543744180#step:6:84
-
7960 
-
7961  More clear here:
-
7962  https://stackoverflow.com/questions/58660207/why-doesnt-stdswap-work-on-vectorbool-elements-under-clang-win
-
7963  */
-
7964 
-
7965  tools.pop_back();
-
7966 
-
7967  return;
-
7968 
-
7969 }
-
7970 
-
7971 template<typename TSeq>
- -
7973  std::string fn,
-
7974  int skip
-
7975  )
-
7976 {
-
7977 
-
7978  int i,j;
-
7979  std::ifstream filei(fn);
-
7980 
-
7981  if (!filei)
-
7982  throw std::logic_error("The file " + fn + " was not found.");
-
7983 
-
7984  int linenum = 0;
-
7985  std::vector< std::vector< epiworld_fast_uint > > target_(entities.size());
-
7986 
-
7987  target_.reserve(1e5);
-
7988 
-
7989  while (!filei.eof())
-
7990  {
-
7991 
-
7992  if (linenum++ < skip)
-
7993  continue;
+
7939  // First, resetting the entity
+
7940  entity.reset();
+
7941 
+
7942  // How should
+
7943  if (entity_pos != (static_cast<int>(entities.size()) - 1))
+
7944  std::swap(entities[entity_pos], entities[entities.size() - 1]);
+
7945 
+
7946  entities.pop_back();
+
7947 }
+
7948 
+
7949 template<typename TSeq>
+
7950 inline void Model<TSeq>::rm_virus(size_t virus_pos)
+
7951 {
+
7952 
+
7953  if (viruses.size() <= virus_pos)
+
7954  throw std::range_error(
+
7955  std::string("The specified virus (") +
+
7956  std::to_string(virus_pos) +
+
7957  std::string(") is out of range. ") +
+
7958  std::string("There are only ") +
+
7959  std::to_string(viruses.size()) +
+
7960  std::string(" viruses.")
+
7961  );
+
7962 
+
7963  // Flipping with the last one
+
7964  std::swap(viruses[virus_pos], viruses[viruses.size() - 1]);
+
7965  viruses.pop_back();
+
7966 
+
7967  return;
+
7968 
+
7969 }
+
7970 
+
7971 template<typename TSeq>
+
7972 inline void Model<TSeq>::rm_tool(size_t tool_pos)
+
7973 {
+
7974 
+
7975  if (tools.size() <= tool_pos)
+
7976  throw std::range_error(
+
7977  std::string("The specified tool (") +
+
7978  std::to_string(tool_pos) +
+
7979  std::string(") is out of range. ") +
+
7980  std::string("There are only ") +
+
7981  std::to_string(tools.size()) +
+
7982  std::string(" tools.")
+
7983  );
+
7984 
+
7985  // Flipping with the last one
+
7986  std::swap(tools[tool_pos], tools[tools.size() - 1]);
+
7987 
+
7988  /* There's an error on windows:
+
7989  https://github.com/UofUEpiBio/epiworldR/actions/runs/4801482395/jobs/8543744180#step:6:84
+
7990 
+
7991  More clear here:
+
7992  https://stackoverflow.com/questions/58660207/why-doesnt-stdswap-work-on-vectorbool-elements-under-clang-win
+
7993  */
7994 
-
7995  filei >> i >> j;
+
7995  tools.pop_back();
7996 
-
7997  // Looking for exceptions
-
7998  if (filei.bad())
-
7999  throw std::logic_error(
-
8000  "I/O error while reading the file " +
-
8001  fn
-
8002  );
-
8003 
-
8004  if (filei.fail())
-
8005  break;
-
8006 
-
8007  if (i >= static_cast<int>(this->size()))
-
8008  throw std::range_error(
-
8009  "The agent["+std::to_string(linenum)+"] = " + std::to_string(i) +
-
8010  " is above the max id " + std::to_string(this->size() - 1)
-
8011  );
-
8012 
-
8013  if (j >= static_cast<int>(this->entities.size()))
-
8014  throw std::range_error(
-
8015  "The entity["+std::to_string(linenum)+"] = " + std::to_string(j) +
-
8016  " is above the max id " + std::to_string(this->entities.size() - 1)
-
8017  );
+
7997  return;
+
7998 
+
7999 }
+
8000 
+
8001 template<typename TSeq>
+ +
8003  std::string fn,
+
8004  int skip
+
8005  )
+
8006 {
+
8007 
+
8008  int i,j;
+
8009  std::ifstream filei(fn);
+
8010 
+
8011  if (!filei)
+
8012  throw std::logic_error("The file " + fn + " was not found.");
+
8013 
+
8014  int linenum = 0;
+
8015  std::vector< std::vector< epiworld_fast_uint > > target_(entities.size());
+
8016 
+
8017  target_.reserve(1e5);
8018 
-
8019  target_[j].push_back(i);
-
8020 
-
8021  population[i].add_entity(entities[j], nullptr);
-
8022 
-
8023  }
+
8019  while (!filei.eof())
+
8020  {
+
8021 
+
8022  if (linenum++ < skip)
+
8023  continue;
8024 
-
8025  return;
+
8025  filei >> i >> j;
8026 
-
8027 }
-
8028 
-
8029 template<typename TSeq>
- -
8031  const std::vector< int > & agents_ids,
-
8032  const std::vector< int > & entities_ids
-
8033 ) {
-
8034 
-
8035  // Checking the size
-
8036  if (agents_ids.size() != entities_ids.size())
-
8037  throw std::length_error(
-
8038  std::string("The size of agents_ids (") +
-
8039  std::to_string(agents_ids.size()) +
-
8040  std::string(") and entities_ids (") +
-
8041  std::to_string(entities_ids.size()) +
-
8042  std::string(") must be the same.")
-
8043  );
-
8044 
-
8045  return this->load_agents_entities_ties(
-
8046  agents_ids.data(),
-
8047  entities_ids.data(),
-
8048  agents_ids.size()
-
8049  );
+
8027  // Looking for exceptions
+
8028  if (filei.bad())
+
8029  throw std::logic_error(
+
8030  "I/O error while reading the file " +
+
8031  fn
+
8032  );
+
8033 
+
8034  if (filei.fail())
+
8035  break;
+
8036 
+
8037  if (i >= static_cast<int>(this->size()))
+
8038  throw std::range_error(
+
8039  "The agent["+std::to_string(linenum)+"] = " + std::to_string(i) +
+
8040  " is above the max id " + std::to_string(this->size() - 1)
+
8041  );
+
8042 
+
8043  if (j >= static_cast<int>(this->entities.size()))
+
8044  throw std::range_error(
+
8045  "The entity["+std::to_string(linenum)+"] = " + std::to_string(j) +
+
8046  " is above the max id " + std::to_string(this->entities.size() - 1)
+
8047  );
+
8048 
+
8049  target_[j].push_back(i);
8050 
-
8051 }
+
8051  population[i].add_entity(entities[j], nullptr);
8052 
-
8053 template<typename TSeq>
- -
8055  const int * agents_ids,
-
8056  const int * entities_ids,
-
8057  size_t n
-
8058 ) {
-
8059 
-
8060  auto get_agent = [agents_ids](int i) -> int {
-
8061  return *(agents_ids + i);
-
8062  };
-
8063 
-
8064  auto get_entity = [entities_ids](int i) -> int {
-
8065  return *(entities_ids + i);
-
8066  };
-
8067 
-
8068  for (size_t i = 0u; i < n; ++i)
-
8069  {
-
8070 
-
8071  if (get_agent(i) < 0)
-
8072  throw std::length_error(
-
8073  std::string("agents_ids[") +
-
8074  std::to_string(i) +
-
8075  std::string("] = ") +
-
8076  std::to_string(get_agent(i)) +
-
8077  std::string(" is negative.")
-
8078  );
-
8079 
-
8080  if (get_entity(i) < 0)
-
8081  throw std::length_error(
-
8082  std::string("entities_ids[") +
-
8083  std::to_string(i) +
-
8084  std::string("] = ") +
-
8085  std::to_string(get_entity(i)) +
-
8086  std::string(" is negative.")
-
8087  );
-
8088 
-
8089  int pop_size = static_cast<int>(this->population.size());
-
8090  if (get_agent(i) >= pop_size)
-
8091  throw std::length_error(
-
8092  std::string("agents_ids[") +
-
8093  std::to_string(i) +
-
8094  std::string("] = ") +
-
8095  std::to_string(get_agent(i)) +
-
8096  std::string(" is out of range (population size: ") +
-
8097  std::to_string(pop_size) +
-
8098  std::string(").")
-
8099  );
+
8053  }
+
8054 
+
8055  return;
+
8056 
+
8057 }
+
8058 
+
8059 template<typename TSeq>
+ +
8061  const std::vector< int > & agents_ids,
+
8062  const std::vector< int > & entities_ids
+
8063 ) {
+
8064 
+
8065  // Checking the size
+
8066  if (agents_ids.size() != entities_ids.size())
+
8067  throw std::length_error(
+
8068  std::string("The size of agents_ids (") +
+
8069  std::to_string(agents_ids.size()) +
+
8070  std::string(") and entities_ids (") +
+
8071  std::to_string(entities_ids.size()) +
+
8072  std::string(") must be the same.")
+
8073  );
+
8074 
+
8075  return this->load_agents_entities_ties(
+
8076  agents_ids.data(),
+
8077  entities_ids.data(),
+
8078  agents_ids.size()
+
8079  );
+
8080 
+
8081 }
+
8082 
+
8083 template<typename TSeq>
+ +
8085  const int * agents_ids,
+
8086  const int * entities_ids,
+
8087  size_t n
+
8088 ) {
+
8089 
+
8090  auto get_agent = [agents_ids](int i) -> int {
+
8091  return *(agents_ids + i);
+
8092  };
+
8093 
+
8094  auto get_entity = [entities_ids](int i) -> int {
+
8095  return *(entities_ids + i);
+
8096  };
+
8097 
+
8098  for (size_t i = 0u; i < n; ++i)
+
8099  {
8100 
-
8101  int ent_size = static_cast<int>(this->entities.size());
-
8102  if (get_entity(i) >= ent_size)
-
8103  throw std::length_error(
-
8104  std::string("entities_ids[") +
-
8105  std::to_string(i) +
-
8106  std::string("] = ") +
-
8107  std::to_string(get_entity(i)) +
-
8108  std::string(" is out of range (entities size: ") +
-
8109  std::to_string(ent_size) +
-
8110  std::string(").")
-
8111  );
-
8112 
-
8113  // Adding the entity to the agent
-
8114  this->population[get_agent(i)].add_entity(
-
8115  this->entities[get_entity(i)],
-
8116  nullptr /* Immediately add it to the agent */
-
8117  );
+
8101  if (get_agent(i) < 0)
+
8102  throw std::length_error(
+
8103  std::string("agents_ids[") +
+
8104  std::to_string(i) +
+
8105  std::string("] = ") +
+
8106  std::to_string(get_agent(i)) +
+
8107  std::string(" is negative.")
+
8108  );
+
8109 
+
8110  if (get_entity(i) < 0)
+
8111  throw std::length_error(
+
8112  std::string("entities_ids[") +
+
8113  std::to_string(i) +
+
8114  std::string("] = ") +
+
8115  std::to_string(get_entity(i)) +
+
8116  std::string(" is negative.")
+
8117  );
8118 
-
8119  }
-
8120 
-
8121  return;
-
8122 
-
8123 
-
8124 }
-
8125 
-
8126 template<typename TSeq>
- -
8128  std::string fn,
-
8129  int size,
-
8130  int skip,
-
8131  bool directed
-
8132  ) {
-
8133 
-
8134  AdjList al;
-
8135  al.read_edgelist(fn, size, skip, directed);
-
8136  this->agents_from_adjlist(al);
-
8137 
-
8138 }
-
8139 
-
8140 template<typename TSeq>
- -
8142  const std::vector< int > & source,
-
8143  const std::vector< int > & target,
-
8144  int size,
-
8145  bool directed
-
8146 ) {
-
8147 
-
8148  AdjList al(source, target, size, directed);
-
8149  agents_from_adjlist(al);
+
8119  int pop_size = static_cast<int>(this->population.size());
+
8120  if (get_agent(i) >= pop_size)
+
8121  throw std::length_error(
+
8122  std::string("agents_ids[") +
+
8123  std::to_string(i) +
+
8124  std::string("] = ") +
+
8125  std::to_string(get_agent(i)) +
+
8126  std::string(" is out of range (population size: ") +
+
8127  std::to_string(pop_size) +
+
8128  std::string(").")
+
8129  );
+
8130 
+
8131  int ent_size = static_cast<int>(this->entities.size());
+
8132  if (get_entity(i) >= ent_size)
+
8133  throw std::length_error(
+
8134  std::string("entities_ids[") +
+
8135  std::to_string(i) +
+
8136  std::string("] = ") +
+
8137  std::to_string(get_entity(i)) +
+
8138  std::string(" is out of range (entities size: ") +
+
8139  std::to_string(ent_size) +
+
8140  std::string(").")
+
8141  );
+
8142 
+
8143  // Adding the entity to the agent
+
8144  this->population[get_agent(i)].add_entity(
+
8145  this->entities[get_entity(i)],
+
8146  nullptr /* Immediately add it to the agent */
+
8147  );
+
8148 
+
8149  }
8150 
-
8151 }
+
8151  return;
8152 
-
8153 template<typename TSeq>
-
8154 inline void Model<TSeq>::agents_from_adjlist(AdjList al) {
+
8153 
+
8154 }
8155 
-
8156  // Resizing the people
-
8157  agents_empty_graph(al.vcount());
-
8158 
-
8159  const auto & tmpdat = al.get_dat();
-
8160 
-
8161  for (size_t i = 0u; i < tmpdat.size(); ++i)
-
8162  {
+
8156 template<typename TSeq>
+ +
8158  std::string fn,
+
8159  int size,
+
8160  int skip,
+
8161  bool directed
+
8162  ) {
8163 
-
8164  // population[i].id = i;
-
8165  population[i].model = this;
-
8166 
-
8167  for (const auto & link: tmpdat[i])
-
8168  {
+
8164  AdjList al;
+
8165  al.read_edgelist(fn, size, skip, directed);
+
8166  this->agents_from_adjlist(al);
+
8167 
+
8168 }
8169 
-
8170  population[i].add_neighbor(
-
8171  population[link.first],
-
8172  true, true
-
8173  );
-
8174 
-
8175  }
-
8176 
-
8177  }
-
8178 
-
8179  #ifdef EPI_DEBUG
-
8180  for (auto & p: population)
-
8181  {
-
8182  if (p.id >= static_cast<int>(al.vcount()))
-
8183  throw std::logic_error(
-
8184  "Agent's id cannot be negative above or equal to the number of agents!");
-
8185  }
-
8186  #endif
-
8187 
-
8188 }
-
8189 
-
8190 template<typename TSeq>
-
8191 inline bool Model<TSeq>::is_directed() const
-
8192 {
-
8193  if (population.size() == 0u)
-
8194  throw std::logic_error("The population hasn't been initialized.");
-
8195 
-
8196  return directed;
-
8197 }
-
8198 
-
8199 template<typename TSeq>
-
8200 inline int Model<TSeq>::today() const {
-
8201 
-
8202  if (ndays == 0)
-
8203  return 0;
+
8170 template<typename TSeq>
+ +
8172  const std::vector< int > & source,
+
8173  const std::vector< int > & target,
+
8174  int size,
+
8175  bool directed
+
8176 ) {
+
8177 
+
8178  AdjList al(source, target, size, directed);
+
8179  agents_from_adjlist(al);
+
8180 
+
8181 }
+
8182 
+
8183 template<typename TSeq>
+
8184 inline void Model<TSeq>::agents_from_adjlist(AdjList al) {
+
8185 
+
8186  // Resizing the people
+
8187  agents_empty_graph(al.vcount());
+
8188 
+
8189  const auto & tmpdat = al.get_dat();
+
8190 
+
8191  for (size_t i = 0u; i < tmpdat.size(); ++i)
+
8192  {
+
8193 
+
8194  // population[i].id = i;
+
8195  population[i].model = this;
+
8196 
+
8197  for (const auto & link: tmpdat[i])
+
8198  {
+
8199 
+
8200  population[i].add_neighbor(
+
8201  population[link.first],
+
8202  true, true
+
8203  );
8204 
-
8205  return this->current_date;
-
8206 }
-
8207 
-
8208 template<typename TSeq>
-
8209 inline void Model<TSeq>::next() {
-
8210 
-
8211  db.record();
-
8212  ++this->current_date;
-
8213 
-
8214  // Advancing the progress bar
-
8215  if ((this->current_date >= 1) && verbose)
-
8216  pb.next();
+
8205  }
+
8206 
+
8207  }
+
8208 
+
8209  #ifdef EPI_DEBUG
+
8210  for (auto & p: population)
+
8211  {
+
8212  if (p.id >= static_cast<int>(al.vcount()))
+
8213  throw std::logic_error(
+
8214  "Agent's id cannot be negative above or equal to the number of agents!");
+
8215  }
+
8216  #endif
8217 
-
8218  return ;
-
8219 }
-
8220 
-
8221 template<typename TSeq>
- -
8223  epiworld_fast_uint ndays,
-
8224  int seed
-
8225 )
-
8226 {
-
8227 
-
8228  if (size() == 0u)
-
8229  throw std::logic_error("There's no agents in this model!");
-
8230 
-
8231  if (nstates == 0u)
-
8232  throw std::logic_error(
-
8233  std::string("No states registered in this model. ") +
-
8234  std::string("At least one state should be included. See the function -Model::add_state()-")
-
8235  );
-
8236 
-
8237  // Setting up the number of steps
-
8238  this->ndays = ndays;
-
8239 
-
8240  if (seed >= 0)
-
8241  engine->seed(seed);
-
8242 
-
8243  array_double_tmp.resize(std::max(
-
8244  size(),
-
8245  static_cast<size_t>(1024 * 1024)
-
8246  ));
+
8218 }
+
8219 
+
8220 template<typename TSeq>
+
8221 inline bool Model<TSeq>::is_directed() const
+
8222 {
+
8223  if (population.size() == 0u)
+
8224  throw std::logic_error("The population hasn't been initialized.");
+
8225 
+
8226  return directed;
+
8227 }
+
8228 
+
8229 template<typename TSeq>
+
8230 inline int Model<TSeq>::today() const {
+
8231 
+
8232  if (ndays == 0)
+
8233  return 0;
+
8234 
+
8235  return this->current_date;
+
8236 }
+
8237 
+
8238 template<typename TSeq>
+
8239 inline void Model<TSeq>::next() {
+
8240 
+
8241  db.record();
+
8242  ++this->current_date;
+
8243 
+
8244  // Advancing the progress bar
+
8245  if ((this->current_date >= 1) && verbose)
+
8246  pb.next();
8247 
-
8248 
-
8249  array_virus_tmp.resize(1024);
-
8250  array_int_tmp.resize(1024 * 1024);
-
8251 
-
8252  // Checking whether the proposed state in/out/removed
-
8253  // are valid
-
8254  epiworld_fast_int _init, _end, _removed;
-
8255  int nstate_int = static_cast<int>(nstates);
-
8256  for (auto & v : viruses)
-
8257  {
-
8258  v->get_state(&_init, &_end, &_removed);
-
8259 
-
8260  // Negative unspecified state
-
8261  if (((_init != -99) && (_init < 0)) || (_init >= nstate_int))
-
8262  throw std::range_error("States must be between 0 and " +
-
8263  std::to_string(nstates - 1));
-
8264 
-
8265  // Negative unspecified state
-
8266  if (((_end != -99) && (_end < 0)) || (_end >= nstate_int))
-
8267  throw std::range_error("States must be between 0 and " +
-
8268  std::to_string(nstates - 1));
+
8248  return ;
+
8249 }
+
8250 
+
8251 template<typename TSeq>
+ +
8253  epiworld_fast_uint ndays,
+
8254  int seed
+
8255 )
+
8256 {
+
8257 
+
8258  if (size() == 0u)
+
8259  throw std::logic_error("There's no agents in this model!");
+
8260 
+
8261  if (nstates == 0u)
+
8262  throw std::logic_error(
+
8263  std::string("No states registered in this model. ") +
+
8264  std::string("At least one state should be included. See the function -Model::add_state()-")
+
8265  );
+
8266 
+
8267  // Setting up the number of steps
+
8268  this->ndays = ndays;
8269 
-
8270  if (((_removed != -99) && (_removed < 0)) || (_removed >= nstate_int))
-
8271  throw std::range_error("States must be between 0 and " +
-
8272  std::to_string(nstates - 1));
-
8273 
-
8274  }
-
8275 
-
8276  for (auto & t : tools)
-
8277  {
-
8278  t->get_state(&_init, &_end);
-
8279 
-
8280  // Negative unspecified state
-
8281  if (((_init != -99) && (_init < 0)) || (_init >= nstate_int))
-
8282  throw std::range_error("States must be between 0 and " +
-
8283  std::to_string(nstates - 1));
-
8284 
-
8285  // Negative unspecified state
-
8286  if (((_end != -99) && (_end < 0)) || (_end >= nstate_int))
-
8287  throw std::range_error("States must be between 0 and " +
-
8288  std::to_string(nstates - 1));
-
8289 
-
8290  }
-
8291 
-
8292  // Starting first infection and tools
-
8293  reset();
+
8270  if (seed >= 0)
+
8271  engine->seed(seed);
+
8272 
+
8273  array_double_tmp.resize(std::max(
+
8274  size(),
+
8275  static_cast<size_t>(1024 * 1024)
+
8276  ));
+
8277 
+
8278 
+
8279  array_virus_tmp.resize(1024);
+
8280  array_int_tmp.resize(1024 * 1024);
+
8281 
+
8282  // Checking whether the proposed state in/out/removed
+
8283  // are valid
+
8284  epiworld_fast_int _init, _end, _removed;
+
8285  int nstate_int = static_cast<int>(nstates);
+
8286  for (auto & v : viruses)
+
8287  {
+
8288  v->get_state(&_init, &_end, &_removed);
+
8289 
+
8290  // Negative unspecified state
+
8291  if (((_init != -99) && (_init < 0)) || (_init >= nstate_int))
+
8292  throw std::range_error("States must be between 0 and " +
+
8293  std::to_string(nstates - 1));
8294 
-
8295  // Initializing the simulation
-
8296  chrono_start();
-
8297  EPIWORLD_RUN((*this))
-
8298  {
+
8295  // Negative unspecified state
+
8296  if (((_end != -99) && (_end < 0)) || (_end >= nstate_int))
+
8297  throw std::range_error("States must be between 0 and " +
+
8298  std::to_string(nstates - 1));
8299 
-
8300  #ifdef EPI_DEBUG
-
8301  db.n_transmissions_potential = 0;
-
8302  db.n_transmissions_today = 0;
-
8303  #endif
-
8304 
-
8305  // We can execute these components in whatever order the
-
8306  // user needs.
-
8307  this->update_state();
-
8308 
-
8309  // We start with the Global events
-
8310  this->run_globalevents();
-
8311 
-
8312  // In this case we are applying degree sequence rewiring
-
8313  // to change the network just a bit.
-
8314  this->rewire();
-
8315 
-
8316  // This locks all the changes
-
8317  this->next();
-
8318 
-
8319  // Mutation must happen at the very end of all
-
8320  this->mutate_virus();
+
8300  if (((_removed != -99) && (_removed < 0)) || (_removed >= nstate_int))
+
8301  throw std::range_error("States must be between 0 and " +
+
8302  std::to_string(nstates - 1));
+
8303 
+
8304  }
+
8305 
+
8306  for (auto & t : tools)
+
8307  {
+
8308  t->get_state(&_init, &_end);
+
8309 
+
8310  // Negative unspecified state
+
8311  if (((_init != -99) && (_init < 0)) || (_init >= nstate_int))
+
8312  throw std::range_error("States must be between 0 and " +
+
8313  std::to_string(nstates - 1));
+
8314 
+
8315  // Negative unspecified state
+
8316  if (((_end != -99) && (_end < 0)) || (_end >= nstate_int))
+
8317  throw std::range_error("States must be between 0 and " +
+
8318  std::to_string(nstates - 1));
+
8319 
+
8320  }
8321 
-
8322  }
-
8323 
-
8324  // The last reaches the end...
-
8325  this->current_date--;
-
8326 
-
8327  chrono_end();
-
8328 
-
8329  return *this;
-
8330 
-
8331 }
-
8332 
-
8333 template<typename TSeq>
- -
8335  epiworld_fast_uint ndays,
-
8336  epiworld_fast_uint nexperiments,
-
8337  int seed_,
-
8338  std::function<void(size_t,Model<TSeq>*)> fun,
-
8339  bool reset,
-
8340  bool verbose,
-
8341  #ifdef _OPENMP
-
8342  int nthreads
-
8343  #else
-
8344  int
-
8345  #endif
-
8346 )
-
8347 {
+
8322  // Starting first infection and tools
+
8323  reset();
+
8324 
+
8325  // Initializing the simulation
+
8326  chrono_start();
+
8327  EPIWORLD_RUN((*this))
+
8328  {
+
8329 
+
8330  #ifdef EPI_DEBUG
+
8331  db.n_transmissions_potential = 0;
+
8332  db.n_transmissions_today = 0;
+
8333  #endif
+
8334 
+
8335  // We can execute these components in whatever order the
+
8336  // user needs.
+
8337  this->update_state();
+
8338 
+
8339  // We start with the Global events
+
8340  this->run_globalevents();
+
8341 
+
8342  // In this case we are applying degree sequence rewiring
+
8343  // to change the network just a bit.
+
8344  this->rewire();
+
8345 
+
8346  // This locks all the changes
+
8347  this->next();
8348 
-
8349  if (seed_ >= 0)
-
8350  this->seed(seed_);
+
8349  // Mutation must happen at the very end of all
+
8350  this->mutate_virus();
8351 
-
8352  // Seeds will be reproducible by default
-
8353  std::vector< int > seeds_n(nexperiments);
-
8354  for (auto & s : seeds_n)
-
8355  {
-
8356  s = static_cast<int>(
-
8357  std::floor(
-
8358  runif() * static_cast<double>(std::numeric_limits<int>::max())
-
8359  )
-
8360  );
-
8361  }
-
8362  // #endif
-
8363 
-
8364  EPI_DEBUG_NOTIFY_ACTIVE()
-
8365 
-
8366  bool old_verb = this->verbose;
-
8367  verbose_off();
-
8368 
-
8369  // Setting up backup
-
8370  if (reset)
-
8371  set_backup();
-
8372 
-
8373  #ifdef _OPENMP
-
8374 
-
8375  omp_set_num_threads(nthreads);
-
8376 
-
8377  // Generating copies of the model
-
8378  std::vector< Model<TSeq> * > these;
-
8379  for (size_t i = 0; i < static_cast<size_t>(std::max(nthreads - 1, 0)); ++i)
-
8380  these.push_back(clone_ptr());
+
8352  }
+
8353 
+
8354  // The last reaches the end...
+
8355  this->current_date--;
+
8356 
+
8357  chrono_end();
+
8358 
+
8359  return *this;
+
8360 
+
8361 }
+
8362 
+
8363 template<typename TSeq>
+ +
8365  epiworld_fast_uint ndays,
+
8366  epiworld_fast_uint nexperiments,
+
8367  int seed_,
+
8368  std::function<void(size_t,Model<TSeq>*)> fun,
+
8369  bool reset,
+
8370  bool verbose,
+
8371  #ifdef _OPENMP
+
8372  int nthreads
+
8373  #else
+
8374  int
+
8375  #endif
+
8376 )
+
8377 {
+
8378 
+
8379  if (seed_ >= 0)
+
8380  this->seed(seed_);
8381 
-
8382  // Figuring out how many replicates
-
8383  std::vector< size_t > nreplicates(nthreads, 0);
-
8384  std::vector< size_t > nreplicates_csum(nthreads, 0);
-
8385  size_t sums = 0u;
-
8386  for (int i = 0; i < nthreads; ++i)
-
8387  {
-
8388  nreplicates[i] = static_cast<epiworld_fast_uint>(
-
8389  std::floor(nexperiments/nthreads)
-
8390  );
-
8391 
-
8392  // This takes the cumsum
-
8393  nreplicates_csum[i] = sums;
-
8394 
-
8395  sums += nreplicates[i];
-
8396 
-
8397  }
+
8382  // Seeds will be reproducible by default
+
8383  std::vector< int > seeds_n(nexperiments);
+
8384  for (auto & s : seeds_n)
+
8385  {
+
8386  s = static_cast<int>(
+
8387  std::floor(
+
8388  runif() * static_cast<double>(std::numeric_limits<int>::max())
+
8389  )
+
8390  );
+
8391  }
+
8392  // #endif
+
8393 
+
8394  EPI_DEBUG_NOTIFY_ACTIVE()
+
8395 
+
8396  bool old_verb = this->verbose;
+
8397  verbose_off();
8398 
-
8399  if (sums < nexperiments)
-
8400  nreplicates[nthreads - 1] += (nexperiments - sums);
-
8401 
-
8402  Progress pb_multiple(
-
8403  nreplicates[0u],
-
8404  EPIWORLD_PROGRESS_BAR_WIDTH
-
8405  );
+
8399  // Setting up backup
+
8400  if (reset)
+
8401  set_backup();
+
8402 
+
8403  #ifdef _OPENMP
+
8404 
+
8405  omp_set_num_threads(nthreads);
8406 
-
8407  if (verbose)
-
8408  {
-
8409 
-
8410  printf_epiworld(
-
8411  "Starting multiple runs (%i) using %i thread(s)\n",
-
8412  static_cast<int>(nexperiments),
-
8413  static_cast<int>(nthreads)
-
8414  );
-
8415 
-
8416  pb_multiple.start();
-
8417 
-
8418  }
-
8419 
-
8420  #ifdef EPI_DEBUG
-
8421  // Checking the initial state of all the models. Throw an
-
8422  // exception if they are not the same.
-
8423  for (size_t i = 1; i < static_cast<size_t>(std::max(nthreads - 1, 0)); ++i)
-
8424  {
-
8425 
-
8426  if (db != these[i]->db)
-
8427  {
-
8428  throw std::runtime_error(
-
8429  "The initial state of the models is not the same"
-
8430  );
-
8431  }
-
8432  }
-
8433  #endif
-
8434 
-
8435  #pragma omp parallel shared(these, nreplicates, nreplicates_csum, seeds_n) \
-
8436  firstprivate(nexperiments, nthreads, fun, reset, verbose, pb_multiple, ndays) \
-
8437  default(shared)
+
8407  // Generating copies of the model
+
8408  std::vector< Model<TSeq> * > these;
+
8409  for (size_t i = 0; i < static_cast<size_t>(std::max(nthreads - 1, 0)); ++i)
+
8410  these.push_back(clone_ptr());
+
8411 
+
8412  // Figuring out how many replicates
+
8413  std::vector< size_t > nreplicates(nthreads, 0);
+
8414  std::vector< size_t > nreplicates_csum(nthreads, 0);
+
8415  size_t sums = 0u;
+
8416  for (int i = 0; i < nthreads; ++i)
+
8417  {
+
8418  nreplicates[i] = static_cast<epiworld_fast_uint>(
+
8419  std::floor(nexperiments/nthreads)
+
8420  );
+
8421 
+
8422  // This takes the cumsum
+
8423  nreplicates_csum[i] = sums;
+
8424 
+
8425  sums += nreplicates[i];
+
8426 
+
8427  }
+
8428 
+
8429  if (sums < nexperiments)
+
8430  nreplicates[nthreads - 1] += (nexperiments - sums);
+
8431 
+
8432  Progress pb_multiple(
+
8433  nreplicates[0u],
+
8434  EPIWORLD_PROGRESS_BAR_WIDTH
+
8435  );
+
8436 
+
8437  if (verbose)
8438  {
8439 
-
8440  auto iam = omp_get_thread_num();
-
8441 
-
8442  for (size_t n = 0u; n < nreplicates[iam]; ++n)
-
8443  {
-
8444  size_t sim_id = nreplicates_csum[iam] + n;
-
8445  if (iam == 0)
-
8446  {
+
8440  printf_epiworld(
+
8441  "Starting multiple runs (%i) using %i thread(s)\n",
+
8442  static_cast<int>(nexperiments),
+
8443  static_cast<int>(nthreads)
+
8444  );
+
8445 
+
8446  pb_multiple.start();
8447 
-
8448  // Initializing the seed
-
8449  run(ndays, seeds_n[sim_id]);
-
8450 
-
8451  if (fun)
-
8452  fun(n, this);
-
8453 
-
8454  // Only the first one prints
-
8455  if (verbose)
-
8456  pb_multiple.next();
-
8457 
-
8458  } else {
-
8459 
-
8460  // Initializing the seed
-
8461  these[iam - 1]->run(ndays, seeds_n[sim_id]);
-
8462 
-
8463  if (fun)
-
8464  fun(sim_id, these[iam - 1]);
-
8465 
-
8466  }
-
8467 
-
8468  }
-
8469 
-
8470  }
+
8448  }
+
8449 
+
8450  #ifdef EPI_DEBUG
+
8451  // Checking the initial state of all the models. Throw an
+
8452  // exception if they are not the same.
+
8453  for (size_t i = 1; i < static_cast<size_t>(std::max(nthreads - 1, 0)); ++i)
+
8454  {
+
8455 
+
8456  if (db != these[i]->db)
+
8457  {
+
8458  throw std::runtime_error(
+
8459  "The initial state of the models is not the same"
+
8460  );
+
8461  }
+
8462  }
+
8463  #endif
+
8464 
+
8465  #pragma omp parallel shared(these, nreplicates, nreplicates_csum, seeds_n) \
+
8466  firstprivate(nexperiments, nthreads, fun, reset, verbose, pb_multiple, ndays) \
+
8467  default(shared)
+
8468  {
+
8469 
+
8470  auto iam = omp_get_thread_num();
8471 
-
8472  // Adjusting the number of replicates
-
8473  n_replicates += (nexperiments - nreplicates[0u]);
-
8474 
-
8475  for (auto & ptr : these)
-
8476  delete ptr;
+
8472  for (size_t n = 0u; n < nreplicates[iam]; ++n)
+
8473  {
+
8474  size_t sim_id = nreplicates_csum[iam] + n;
+
8475  if (iam == 0)
+
8476  {
8477 
-
8478  #else
-
8479  // if (reset)
-
8480  // set_backup();
-
8481 
-
8482  Progress pb_multiple(
-
8483  nexperiments,
-
8484  EPIWORLD_PROGRESS_BAR_WIDTH
-
8485  )
-
8486  ;
-
8487  if (verbose)
-
8488  {
+
8478  // Initializing the seed
+
8479  run(ndays, seeds_n[sim_id]);
+
8480 
+
8481  if (fun)
+
8482  fun(n, this);
+
8483 
+
8484  // Only the first one prints
+
8485  if (verbose)
+
8486  pb_multiple.next();
+
8487 
+
8488  } else {
8489 
-
8490  printf_epiworld(
-
8491  "Starting multiple runs (%i)\n",
-
8492  static_cast<int>(nexperiments)
-
8493  );
-
8494 
-
8495  pb_multiple.start();
-
8496 
-
8497  }
-
8498 
-
8499  for (size_t n = 0u; n < nexperiments; ++n)
-
8500  {
+
8490  // Initializing the seed
+
8491  these[iam - 1]->run(ndays, seeds_n[sim_id]);
+
8492 
+
8493  if (fun)
+
8494  fun(sim_id, these[iam - 1]);
+
8495 
+
8496  }
+
8497 
+
8498  }
+
8499 
+
8500  }
8501 
-
8502  run(ndays, seeds_n[n]);
-
8503 
-
8504  if (fun)
-
8505  fun(n, this);
-
8506 
-
8507  if (verbose)
-
8508  pb_multiple.next();
-
8509 
-
8510  }
-
8511  #endif
-
8512 
-
8513  if (verbose)
-
8514  pb_multiple.end();
-
8515 
-
8516  if (old_verb)
-
8517  verbose_on();
-
8518 
-
8519  return;
-
8520 
-
8521 }
-
8522 
-
8523 template<typename TSeq>
-
8524 inline void Model<TSeq>::update_state() {
-
8525 
-
8526  // Next state
-
8527  if (use_queuing)
-
8528  {
-
8529  int i = -1;
-
8530  for (auto & p: population)
-
8531  if (queue[++i] > 0)
-
8532  {
-
8533  if (state_fun[p.state])
-
8534  state_fun[p.state](&p, this);
-
8535  }
+
8502  // Adjusting the number of replicates
+
8503  n_replicates += (nexperiments - nreplicates[0u]);
+
8504 
+
8505  for (auto & ptr : these)
+
8506  delete ptr;
+
8507 
+
8508  #else
+
8509  // if (reset)
+
8510  // set_backup();
+
8511 
+
8512  Progress pb_multiple(
+
8513  nexperiments,
+
8514  EPIWORLD_PROGRESS_BAR_WIDTH
+
8515  )
+
8516  ;
+
8517  if (verbose)
+
8518  {
+
8519 
+
8520  printf_epiworld(
+
8521  "Starting multiple runs (%i)\n",
+
8522  static_cast<int>(nexperiments)
+
8523  );
+
8524 
+
8525  pb_multiple.start();
+
8526 
+
8527  }
+
8528 
+
8529  for (size_t n = 0u; n < nexperiments; ++n)
+
8530  {
+
8531 
+
8532  run(ndays, seeds_n[n]);
+
8533 
+
8534  if (fun)
+
8535  fun(n, this);
8536 
-
8537  }
-
8538  else
-
8539  {
-
8540 
-
8541  for (auto & p: population)
-
8542  if (state_fun[p.state])
-
8543  state_fun[p.state](&p, this);
-
8544 
-
8545  }
-
8546 
-
8547  events_run();
-
8548 
-
8549 }
+
8537  if (verbose)
+
8538  pb_multiple.next();
+
8539 
+
8540  }
+
8541  #endif
+
8542 
+
8543  if (verbose)
+
8544  pb_multiple.end();
+
8545 
+
8546  if (old_verb)
+
8547  verbose_on();
+
8548 
+
8549  return;
8550 
-
8551 
+
8551 }
8552 
8553 template<typename TSeq>
-
8554 inline void Model<TSeq>::mutate_virus() {
+
8554 inline void Model<TSeq>::update_state() {
8555 
-
8556  // Checking if any virus has mutation
-
8557  size_t nmutates = 0u;
-
8558  for (const auto & v: viruses)
-
8559  if (v->mutation_fun)
-
8560  nmutates++;
-
8561 
-
8562  if (nmutates == 0u)
-
8563  return;
-
8564 
-
8565  if (use_queuing)
-
8566  {
-
8567 
-
8568  int i = -1;
-
8569  for (auto & p: population)
-
8570  {
-
8571 
-
8572  if (queue[++i] == 0)
-
8573  continue;
+
8556  // Next state
+
8557  if (use_queuing)
+
8558  {
+
8559  int i = -1;
+
8560  for (auto & p: population)
+
8561  if (queue[++i] > 0)
+
8562  {
+
8563  if (state_fun[p.state])
+
8564  state_fun[p.state](&p, this);
+
8565  }
+
8566 
+
8567  }
+
8568  else
+
8569  {
+
8570 
+
8571  for (auto & p: population)
+
8572  if (state_fun[p.state])
+
8573  state_fun[p.state](&p, this);
8574 
-
8575  if (p.virus != nullptr)
-
8576  p.virus->mutate(this);
-
8577 
-
8578  }
-
8579 
-
8580  }
-
8581  else
-
8582  {
-
8583 
-
8584  for (auto & p: population)
-
8585  {
-
8586 
-
8587  if (p.virus != nullptr)
-
8588  p.virus->mutate(this);
-
8589 
-
8590  }
+
8575  }
+
8576 
+
8577  events_run();
+
8578 
+
8579 }
+
8580 
+
8581 
+
8582 
+
8583 template<typename TSeq>
+
8584 inline void Model<TSeq>::mutate_virus() {
+
8585 
+
8586  // Checking if any virus has mutation
+
8587  size_t nmutates = 0u;
+
8588  for (const auto & v: viruses)
+
8589  if (v->mutation_fun)
+
8590  nmutates++;
8591 
-
8592  }
-
8593 
+
8592  if (nmutates == 0u)
+
8593  return;
8594 
-
8595 }
-
8596 
-
8597 template<typename TSeq>
-
8598 inline size_t Model<TSeq>::get_n_viruses() const {
-
8599  return db.size();
-
8600 }
+
8595  if (use_queuing)
+
8596  {
+
8597 
+
8598  int i = -1;
+
8599  for (auto & p: population)
+
8600  {
8601 
-
8602 template<typename TSeq>
-
8603 inline size_t Model<TSeq>::get_n_tools() const {
-
8604  return tools.size();
-
8605 }
-
8606 
-
8607 template<typename TSeq>
-
8608 inline epiworld_fast_uint Model<TSeq>::get_ndays() const {
-
8609  return ndays;
-
8610 }
-
8611 
-
8612 template<typename TSeq>
-
8613 inline epiworld_fast_uint Model<TSeq>::get_n_replicates() const
-
8614 {
-
8615  return n_replicates;
-
8616 }
-
8617 
-
8618 template<typename TSeq>
-
8619 inline void Model<TSeq>::set_ndays(epiworld_fast_uint ndays) {
-
8620  this->ndays = ndays;
-
8621 }
-
8622 
-
8623 template<typename TSeq>
-
8624 inline bool Model<TSeq>::get_verbose() const {
-
8625  return verbose;
-
8626 }
-
8627 
-
8628 template<typename TSeq>
- -
8630  verbose = true;
-
8631  return *this;
-
8632 }
-
8633 
-
8634 template<typename TSeq>
- -
8636  verbose = false;
-
8637  return *this;
-
8638 }
-
8639 
-
8640 template<typename TSeq>
-
8641 inline void Model<TSeq>::set_rewire_fun(
-
8642  std::function<void(std::vector<Agent<TSeq>>*,Model<TSeq>*,epiworld_double)> fun
-
8643  ) {
-
8644  rewire_fun = fun;
-
8645 }
-
8646 
-
8647 template<typename TSeq>
-
8648 inline void Model<TSeq>::set_rewire_prop(epiworld_double prop)
-
8649 {
-
8650 
-
8651  if (prop < 0.0)
-
8652  throw std::range_error("Proportions cannot be negative.");
-
8653 
-
8654  if (prop > 1.0)
-
8655  throw std::range_error("Proportions cannot be above 1.0.");
-
8656 
-
8657  rewire_prop = prop;
-
8658 }
-
8659 
-
8660 template<typename TSeq>
-
8661 inline epiworld_double Model<TSeq>::get_rewire_prop() const {
-
8662  return rewire_prop;
-
8663 }
-
8664 
-
8665 template<typename TSeq>
-
8666 inline void Model<TSeq>::rewire() {
-
8667 
-
8668  if (rewire_fun)
-
8669  rewire_fun(&population, this, rewire_prop);
-
8670 }
-
8671 
-
8672 
-
8673 template<typename TSeq>
- -
8675  std::string fn_virus_info,
-
8676  std::string fn_virus_hist,
-
8677  std::string fn_tool_info,
-
8678  std::string fn_tool_hist,
-
8679  std::string fn_total_hist,
-
8680  std::string fn_transmission,
-
8681  std::string fn_transition,
-
8682  std::string fn_reproductive_number,
-
8683  std::string fn_generation_time
-
8684  ) const
-
8685 {
+
8602  if (queue[++i] == 0)
+
8603  continue;
+
8604 
+
8605  if (p.virus != nullptr)
+
8606  p.virus->mutate(this);
+
8607 
+
8608  }
+
8609 
+
8610  }
+
8611  else
+
8612  {
+
8613 
+
8614  for (auto & p: population)
+
8615  {
+
8616 
+
8617  if (p.virus != nullptr)
+
8618  p.virus->mutate(this);
+
8619 
+
8620  }
+
8621 
+
8622  }
+
8623 
+
8624 
+
8625 }
+
8626 
+
8627 template<typename TSeq>
+
8628 inline size_t Model<TSeq>::get_n_viruses() const {
+
8629  return db.size();
+
8630 }
+
8631 
+
8632 template<typename TSeq>
+
8633 inline size_t Model<TSeq>::get_n_tools() const {
+
8634  return tools.size();
+
8635 }
+
8636 
+
8637 template<typename TSeq>
+
8638 inline epiworld_fast_uint Model<TSeq>::get_ndays() const {
+
8639  return ndays;
+
8640 }
+
8641 
+
8642 template<typename TSeq>
+
8643 inline epiworld_fast_uint Model<TSeq>::get_n_replicates() const
+
8644 {
+
8645  return n_replicates;
+
8646 }
+
8647 
+
8648 template<typename TSeq>
+
8649 inline void Model<TSeq>::set_ndays(epiworld_fast_uint ndays) {
+
8650  this->ndays = ndays;
+
8651 }
+
8652 
+
8653 template<typename TSeq>
+
8654 inline bool Model<TSeq>::get_verbose() const {
+
8655  return verbose;
+
8656 }
+
8657 
+
8658 template<typename TSeq>
+ +
8660  verbose = true;
+
8661  return *this;
+
8662 }
+
8663 
+
8664 template<typename TSeq>
+ +
8666  verbose = false;
+
8667  return *this;
+
8668 }
+
8669 
+
8670 template<typename TSeq>
+
8671 inline void Model<TSeq>::set_rewire_fun(
+
8672  std::function<void(std::vector<Agent<TSeq>>*,Model<TSeq>*,epiworld_double)> fun
+
8673  ) {
+
8674  rewire_fun = fun;
+
8675 }
+
8676 
+
8677 template<typename TSeq>
+
8678 inline void Model<TSeq>::set_rewire_prop(epiworld_double prop)
+
8679 {
+
8680 
+
8681  if (prop < 0.0)
+
8682  throw std::range_error("Proportions cannot be negative.");
+
8683 
+
8684  if (prop > 1.0)
+
8685  throw std::range_error("Proportions cannot be above 1.0.");
8686 
-
8687  db.write_data(
-
8688  fn_virus_info, fn_virus_hist,
-
8689  fn_tool_info, fn_tool_hist,
-
8690  fn_total_hist, fn_transmission, fn_transition,
-
8691  fn_reproductive_number, fn_generation_time
-
8692  );
-
8693 
-
8694 }
-
8695 
-
8696 template<typename TSeq>
-
8697 inline void Model<TSeq>::write_edgelist(
-
8698  std::string fn
-
8699  ) const
-
8700 {
+
8687  rewire_prop = prop;
+
8688 }
+
8689 
+
8690 template<typename TSeq>
+
8691 inline epiworld_double Model<TSeq>::get_rewire_prop() const {
+
8692  return rewire_prop;
+
8693 }
+
8694 
+
8695 template<typename TSeq>
+
8696 inline void Model<TSeq>::rewire() {
+
8697 
+
8698  if (rewire_fun)
+
8699  rewire_fun(&population, this, rewire_prop);
+
8700 }
8701 
-
8702  // Figuring out the writing sequence
-
8703  std::vector< const Agent<TSeq> * > wseq(size());
-
8704  for (const auto & p: population)
-
8705  wseq[p.id] = &p;
-
8706 
-
8707  std::ofstream efile(fn, std::ios_base::out);
-
8708  efile << "source target\n";
-
8709  if (this->is_directed())
-
8710  {
-
8711 
-
8712  for (const auto & p : wseq)
-
8713  {
-
8714  for (auto & n : p->neighbors)
-
8715  efile << p->id << " " << n << "\n";
-
8716  }
-
8717 
-
8718  } else {
-
8719 
-
8720  for (const auto & p : wseq)
-
8721  {
-
8722  for (auto & n : p->neighbors)
-
8723  if (static_cast<int>(p->id) <= static_cast<int>(n))
-
8724  efile << p->id << " " << n << "\n";
-
8725  }
-
8726 
-
8727  }
-
8728 
-
8729 }
-
8730 
-
8731 template<typename TSeq>
-
8732 inline void Model<TSeq>::write_edgelist(
-
8733 std::vector< int > & source,
-
8734 std::vector< int > & target
-
8735 ) const {
+
8702 
+
8703 template<typename TSeq>
+ +
8705  std::string fn_virus_info,
+
8706  std::string fn_virus_hist,
+
8707  std::string fn_tool_info,
+
8708  std::string fn_tool_hist,
+
8709  std::string fn_total_hist,
+
8710  std::string fn_transmission,
+
8711  std::string fn_transition,
+
8712  std::string fn_reproductive_number,
+
8713  std::string fn_generation_time
+
8714  ) const
+
8715 {
+
8716 
+
8717  db.write_data(
+
8718  fn_virus_info, fn_virus_hist,
+
8719  fn_tool_info, fn_tool_hist,
+
8720  fn_total_hist, fn_transmission, fn_transition,
+
8721  fn_reproductive_number, fn_generation_time
+
8722  );
+
8723 
+
8724 }
+
8725 
+
8726 template<typename TSeq>
+
8727 inline void Model<TSeq>::write_edgelist(
+
8728  std::string fn
+
8729  ) const
+
8730 {
+
8731 
+
8732  // Figuring out the writing sequence
+
8733  std::vector< const Agent<TSeq> * > wseq(size());
+
8734  for (const auto & p: population)
+
8735  wseq[p.id] = &p;
8736 
-
8737  // Figuring out the writing sequence
-
8738  std::vector< const Agent<TSeq> * > wseq(size());
-
8739  for (const auto & p: population)
-
8740  wseq[p.id] = &p;
+
8737  std::ofstream efile(fn, std::ios_base::out);
+
8738  efile << "source target\n";
+
8739  if (this->is_directed())
+
8740  {
8741 
-
8742  if (this->is_directed())
-
8743  {
-
8744 
-
8745  for (const auto & p : wseq)
-
8746  {
-
8747  for (auto & n : p->neighbors)
-
8748  {
-
8749  source.push_back(static_cast<int>(p->id));
-
8750  target.push_back(static_cast<int>(n));
-
8751  }
-
8752  }
-
8753 
-
8754  } else {
-
8755 
-
8756  for (const auto & p : wseq)
-
8757  {
-
8758  for (auto & n : p->neighbors) {
-
8759  if (static_cast<int>(p->id) <= static_cast<int>(n)) {
-
8760  source.push_back(static_cast<int>(p->id));
-
8761  target.push_back(static_cast<int>(n));
-
8762  }
-
8763  }
-
8764  }
-
8765 
-
8766  }
-
8767 
-
8768 
-
8769 }
-
8770 
-
8771 template<typename TSeq>
-
8772 inline std::map<std::string,epiworld_double> & Model<TSeq>::params()
-
8773 {
-
8774  return parameters;
-
8775 }
-
8776 
-
8777 template<typename TSeq>
-
8778 inline void Model<TSeq>::reset() {
-
8779 
-
8780  // Restablishing people
-
8781  pb = Progress(ndays, 80);
-
8782 
-
8783  if (population_backup.size() != 0u)
-
8784  {
-
8785  population = population_backup;
-
8786 
-
8787  #ifdef EPI_DEBUG
-
8788  for (size_t i = 0; i < population.size(); ++i)
-
8789  {
-
8790 
-
8791  if (population[i] != population_backup[i])
-
8792  throw std::logic_error("Model::reset population doesn't match.");
-
8793 
+
8742  for (const auto & p : wseq)
+
8743  {
+
8744  for (auto & n : p->neighbors)
+
8745  efile << p->id << " " << n << "\n";
+
8746  }
+
8747 
+
8748  } else {
+
8749 
+
8750  for (const auto & p : wseq)
+
8751  {
+
8752  for (auto & n : p->neighbors)
+
8753  if (static_cast<int>(p->id) <= static_cast<int>(n))
+
8754  efile << p->id << " " << n << "\n";
+
8755  }
+
8756 
+
8757  }
+
8758 
+
8759 }
+
8760 
+
8761 template<typename TSeq>
+
8762 inline void Model<TSeq>::write_edgelist(
+
8763 std::vector< int > & source,
+
8764 std::vector< int > & target
+
8765 ) const {
+
8766 
+
8767  // Figuring out the writing sequence
+
8768  std::vector< const Agent<TSeq> * > wseq(size());
+
8769  for (const auto & p: population)
+
8770  wseq[p.id] = &p;
+
8771 
+
8772  if (this->is_directed())
+
8773  {
+
8774 
+
8775  for (const auto & p : wseq)
+
8776  {
+
8777  for (auto & n : p->neighbors)
+
8778  {
+
8779  source.push_back(static_cast<int>(p->id));
+
8780  target.push_back(static_cast<int>(n));
+
8781  }
+
8782  }
+
8783 
+
8784  } else {
+
8785 
+
8786  for (const auto & p : wseq)
+
8787  {
+
8788  for (auto & n : p->neighbors) {
+
8789  if (static_cast<int>(p->id) <= static_cast<int>(n)) {
+
8790  source.push_back(static_cast<int>(p->id));
+
8791  target.push_back(static_cast<int>(n));
+
8792  }
+
8793  }
8794  }
-
8795  #endif
-
8796 
-
8797  }
+
8795 
+
8796  }
+
8797 
8798 
-
8799  for (auto & p : population)
-
8800  p.reset();
-
8801 
-
8802  #ifdef EPI_DEBUG
-
8803  for (auto & a: population)
-
8804  {
-
8805  if (a.get_state() != 0u)
-
8806  throw std::logic_error("Model::reset population doesn't match."
-
8807  "Some agents are not in the baseline state.");
-
8808  }
-
8809  #endif
-
8810 
-
8811  if (entities_backup.size() != 0)
-
8812  {
-
8813  entities = entities_backup;
-
8814 
-
8815  #ifdef EPI_DEBUG
-
8816  for (size_t i = 0; i < entities.size(); ++i)
-
8817  {
-
8818 
-
8819  if (entities[i] != entities_backup[i])
-
8820  throw std::logic_error("Model::reset entities don't match.");
-
8821 
-
8822  }
-
8823  #endif
-
8824 
-
8825  }
+
8799 }
+
8800 
+
8801 template<typename TSeq>
+
8802 inline std::map<std::string,epiworld_double> & Model<TSeq>::params()
+
8803 {
+
8804  return parameters;
+
8805 }
+
8806 
+
8807 template<typename TSeq>
+
8808 inline void Model<TSeq>::reset() {
+
8809 
+
8810  // Restablishing people
+
8811  pb = Progress(ndays, 80);
+
8812 
+
8813  if (population_backup.size() != 0u)
+
8814  {
+
8815  population = population_backup;
+
8816 
+
8817  #ifdef EPI_DEBUG
+
8818  for (size_t i = 0; i < population.size(); ++i)
+
8819  {
+
8820 
+
8821  if (population[i] != population_backup[i])
+
8822  throw std::logic_error("Model::reset population doesn't match.");
+
8823 
+
8824  }
+
8825  #endif
8826 
-
8827  for (auto & e: entities)
-
8828  e.reset();
-
8829 
-
8830  current_date = 0;
+
8827  }
+
8828 
+
8829  for (auto & p : population)
+
8830  p.reset();
8831 
-
8832  db.reset();
-
8833 
-
8834  // This also clears the queue
-
8835  if (use_queuing)
-
8836  queue.reset();
-
8837 
-
8838  // Re distributing tools and virus
-
8839  dist_virus();
-
8840  dist_tools();
-
8841  dist_entities();
-
8842 
-
8843  // Distributing initial state, if specified
-
8844  initial_states_fun(this);
-
8845 
-
8846  // Recording the original state (at time 0) and advancing
-
8847  // to time 1
-
8848  next();
-
8849 
-
8850 
-
8851 }
-
8852 
-
8853 // Too big to keep here
-
8854 /*//////////////////////////////////////////////////////////////////////////////
-
8856 
-
8857  Start of -include/epiworld//model-meat-print.hpp-
-
8858 
-
8861 
-
8862 
-
8863 #ifndef EPIWORLD_MODEL_MEAT_PRINT_HPP
-
8864 #define EPIWORLD_MODEL_MEAT_PRINT_HPP
-
8865 
-
8866 template<typename TSeq>
-
8867 inline const Model<TSeq> & Model<TSeq>::print(bool lite) const
-
8868 {
-
8869 
-
8870  // Horizontal line
-
8871  std::string line = "";
-
8872  for (epiworld_fast_uint i = 0u; i < 80u; ++i)
-
8873  line += "_";
-
8874 
-
8875  // Prints a message if debugging is on
-
8876  EPI_DEBUG_NOTIFY_ACTIVE()
-
8877 
-
8878  printf_epiworld("%s\n",line.c_str());
-
8879 
-
8880  if (lite)
-
8881  {
-
8882  // Printing the name of the model
-
8883  printf_epiworld("%s", name.c_str());
-
8884 
-
8885  // Printing the number of agents, viruses, and tools
-
8886  printf_epiworld(
-
8887  "\nIt features %i agents, %i virus(es), and %i tool(s).\n",
-
8888  static_cast<int>(size()),
-
8889  static_cast<int>(get_n_viruses()),
-
8890  static_cast<int>(get_n_tools())
-
8891  );
+
8832  #ifdef EPI_DEBUG
+
8833  for (auto & a: population)
+
8834  {
+
8835  if (a.get_state() != 0u)
+
8836  throw std::logic_error("Model::reset population doesn't match."
+
8837  "Some agents are not in the baseline state.");
+
8838  }
+
8839  #endif
+
8840 
+
8841  if (entities_backup.size() != 0)
+
8842  {
+
8843  entities = entities_backup;
+
8844 
+
8845  #ifdef EPI_DEBUG
+
8846  for (size_t i = 0; i < entities.size(); ++i)
+
8847  {
+
8848 
+
8849  if (entities[i] != entities_backup[i])
+
8850  throw std::logic_error("Model::reset entities don't match.");
+
8851 
+
8852  }
+
8853  #endif
+
8854 
+
8855  }
+
8856 
+
8857  for (auto & e: entities)
+
8858  e.reset();
+
8859 
+
8860  current_date = 0;
+
8861 
+
8862  db.reset();
+
8863 
+
8864  // This also clears the queue
+
8865  if (use_queuing)
+
8866  queue.reset();
+
8867 
+
8868  // Re distributing tools and virus
+
8869  dist_virus();
+
8870  dist_tools();
+
8871  dist_entities();
+
8872 
+
8873  // Distributing initial state, if specified
+
8874  initial_states_fun(this);
+
8875 
+
8876  // Recording the original state (at time 0) and advancing
+
8877  // to time 1
+
8878  next();
+
8879 
+
8880 
+
8881 }
+
8882 
+
8883 // Too big to keep here
+
8884 /*//////////////////////////////////////////////////////////////////////////////
+
8886 
+
8887  Start of -include/epiworld//model-meat-print.hpp-
+
8888 
+
8891 
8892 
-
8893  printf_epiworld(
-
8894  "The model has %i states.",
-
8895  static_cast<int>(nstates)
-
8896  );
-
8897 
-
8898  if (today() != 0)
-
8899  {
-
8900  printf_epiworld(
-
8901  "\nThe final distribution is: "
-
8902  );
-
8903 
-
8904  int nstate_int = static_cast<int>(nstates);
-
8905 
-
8906  for (int i = 0u; i < nstate_int; ++i)
-
8907  {
-
8908  printf_epiworld(
-
8909  "%i %s%s",
-
8910  static_cast<int>(db.today_total[ i ]),
-
8911  states_labels[i].c_str(),
-
8912  (
-
8913  i == (nstate_int - 2)
-
8914  ) ? ", and " : (
-
8915  (i == (nstate_int - 1)) ? ".\n" : ", "
-
8916  )
-
8917  );
-
8918  }
-
8919  } else {
-
8920  printf_epiworld(" The model hasn't been run yet.\n");
-
8921  }
+
8893 #ifndef EPIWORLD_MODEL_MEAT_PRINT_HPP
+
8894 #define EPIWORLD_MODEL_MEAT_PRINT_HPP
+
8895 
+
8896 template<typename TSeq>
+
8897 inline const Model<TSeq> & Model<TSeq>::print(bool lite) const
+
8898 {
+
8899 
+
8900  // Horizontal line
+
8901  std::string line = "";
+
8902  for (epiworld_fast_uint i = 0u; i < 80u; ++i)
+
8903  line += "_";
+
8904 
+
8905  // Prints a message if debugging is on
+
8906  EPI_DEBUG_NOTIFY_ACTIVE()
+
8907 
+
8908  printf_epiworld("%s\n",line.c_str());
+
8909 
+
8910  if (lite)
+
8911  {
+
8912  // Printing the name of the model
+
8913  printf_epiworld("%s", name.c_str());
+
8914 
+
8915  // Printing the number of agents, viruses, and tools
+
8916  printf_epiworld(
+
8917  "\nIt features %i agents, %i virus(es), and %i tool(s).\n",
+
8918  static_cast<int>(size()),
+
8919  static_cast<int>(get_n_viruses()),
+
8920  static_cast<int>(get_n_tools())
+
8921  );
8922 
-
8923  return *this;
-
8924  }
-
8925 
-
8926  printf_epiworld("%s\n%s\n\n",line.c_str(), "SIMULATION STUDY");
+
8923  printf_epiworld(
+
8924  "The model has %i states.",
+
8925  static_cast<int>(nstates)
+
8926  );
8927 
-
8928  printf_epiworld("Name of the model : %s\n", (this->name == "") ? std::string("(none)").c_str() : name.c_str());
-
8929  printf_epiworld("Population size : %i\n", static_cast<int>(size()));
-
8930 
-
8931  auto ncols = get_agents_data_ncols();
-
8932 
-
8933  if (ncols > 0)
-
8934  {
-
8935  printf_epiworld("Agents' data loaded : yes (%i columns/features)\n", static_cast<int>(ncols));
-
8936  }
-
8937  else
-
8938  {
-
8939  printf_epiworld("Agents' data : (none)\n");
-
8940  }
-
8941 
-
8942  printf_epiworld("Number of entities : %i\n", static_cast<int>(entities.size()));
-
8943  printf_epiworld("Days (duration) : %i (of %i)\n", today(), static_cast<int>(ndays));
-
8944  printf_epiworld("Number of viruses : %i\n", static_cast<int>(db.get_n_viruses()));
-
8945  if (n_replicates > 0u)
-
8946  {
-
8947  std::string abbr;
-
8948  epiworld_double elapsed;
-
8949  epiworld_double total;
-
8950  get_elapsed("auto", &elapsed, &total, &abbr, false);
-
8951  printf_epiworld("Last run elapsed t : %.2f%s\n", elapsed, abbr.c_str());
-
8952  if (n_replicates > 1u)
-
8953  {
-
8954  printf_epiworld("Total elapsed t : %.2f%s (%i runs)\n", total, abbr.c_str(), static_cast<int>(n_replicates));
-
8955  }
-
8956 
-
8957  // Elapsed time in speed
-
8958  get_elapsed("microseconds", &elapsed, &total, &abbr, false);
-
8959  printf_epiworld("Last run speed : %.2f million agents x day / second\n",
-
8960  static_cast<double>(this->size()) *
-
8961  static_cast<double>(this->get_ndays()) /
-
8962  static_cast<double>(elapsed)
-
8963  );
-
8964  if (n_replicates > 1u)
-
8965  {
-
8966  printf_epiworld("Average run speed : %.2f million agents x day / second\n",
-
8967  static_cast<double>(this->size()) *
-
8968  static_cast<double>(this->get_ndays()) *
-
8969  static_cast<double>(n_replicates) /
-
8970  static_cast<double>(total)
-
8971  );
-
8972  }
-
8973 
-
8974  } else {
-
8975  printf_epiworld("Last run elapsed t : -\n");
-
8976  }
-
8977 
-
8978 
-
8979  if (rewire_fun)
-
8980  {
-
8981  printf_epiworld("Rewiring : on (%.2f)\n\n", rewire_prop);
-
8982  } else {
-
8983  printf_epiworld("Rewiring : off\n\n");
-
8984  }
-
8985 
-
8986  // Printing Global events
-
8987  printf_epiworld("Global events:\n");
-
8988  for (auto & a : globalevents)
-
8989  {
-
8990  if (a.get_day() < 0)
-
8991  {
-
8992  printf_epiworld(" - %s (runs daily)\n", a.get_name().c_str());
-
8993  } else {
-
8994  printf_epiworld(" - %s (day %i)\n", a.get_name().c_str(), a.get_day());
-
8995  }
-
8996  }
-
8997 
-
8998  if (globalevents.size() == 0u)
-
8999  {
-
9000  printf_epiworld(" (none)\n");
-
9001  }
-
9002 
-
9003  printf_epiworld("\nVirus(es):\n");
-
9004  size_t n_viruses_model = viruses.size();
-
9005  for (size_t i = 0u; i < n_viruses_model; ++i)
-
9006  {
-
9007 
-
9008 
-
9009  const auto & virus = viruses[i];
-
9010  if ((n_viruses_model > 10) && (i >= 10))
-
9011  {
-
9012  printf_epiworld(" ...and %i more viruses...\n",
-
9013  static_cast<int>(n_viruses_model) -
-
9014  static_cast<int>(i)
-
9015  );
-
9016  break;
-
9017  }
-
9018 
-
9019  if (i < n_viruses_model)
-
9020  {
-
9021 
-
9022  printf_epiworld(
-
9023  " - %s\n",
-
9024  virus->get_name().c_str()
-
9025  );
-
9026 
-
9027  } else {
-
9028 
-
9029  printf_epiworld(
-
9030  " - %s (originated in the model...)\n",
-
9031  virus->get_name().c_str()
-
9032  );
-
9033 
-
9034  }
-
9035 
-
9036  }
+
8928  if (today() != 0)
+
8929  {
+
8930  printf_epiworld(
+
8931  "\nThe final distribution is: "
+
8932  );
+
8933 
+
8934  int nstate_int = static_cast<int>(nstates);
+
8935 
+
8936  for (int i = 0u; i < nstate_int; ++i)
+
8937  {
+
8938  printf_epiworld(
+
8939  "%i %s%s",
+
8940  static_cast<int>(db.today_total[ i ]),
+
8941  states_labels[i].c_str(),
+
8942  (
+
8943  i == (nstate_int - 2)
+
8944  ) ? ", and " : (
+
8945  (i == (nstate_int - 1)) ? ".\n" : ", "
+
8946  )
+
8947  );
+
8948  }
+
8949  } else {
+
8950  printf_epiworld(" The model hasn't been run yet.\n");
+
8951  }
+
8952 
+
8953  return *this;
+
8954  }
+
8955 
+
8956  printf_epiworld("%s\n%s\n\n",line.c_str(), "SIMULATION STUDY");
+
8957 
+
8958  printf_epiworld("Name of the model : %s\n", (this->name == "") ? std::string("(none)").c_str() : name.c_str());
+
8959  printf_epiworld("Population size : %i\n", static_cast<int>(size()));
+
8960 
+
8961  auto ncols = get_agents_data_ncols();
+
8962 
+
8963  if (ncols > 0)
+
8964  {
+
8965  printf_epiworld("Agents' data loaded : yes (%i columns/features)\n", static_cast<int>(ncols));
+
8966  }
+
8967  else
+
8968  {
+
8969  printf_epiworld("Agents' data : (none)\n");
+
8970  }
+
8971 
+
8972  printf_epiworld("Number of entities : %i\n", static_cast<int>(entities.size()));
+
8973  printf_epiworld("Days (duration) : %i (of %i)\n", today(), static_cast<int>(ndays));
+
8974  printf_epiworld("Number of viruses : %i\n", static_cast<int>(db.get_n_viruses()));
+
8975  if (n_replicates > 0u)
+
8976  {
+
8977  std::string abbr;
+
8978  epiworld_double elapsed;
+
8979  epiworld_double total;
+
8980  get_elapsed("auto", &elapsed, &total, &abbr, false);
+
8981  printf_epiworld("Last run elapsed t : %.2f%s\n", elapsed, abbr.c_str());
+
8982  if (n_replicates > 1u)
+
8983  {
+
8984  printf_epiworld("Total elapsed t : %.2f%s (%i runs)\n", total, abbr.c_str(), static_cast<int>(n_replicates));
+
8985  }
+
8986 
+
8987  // Elapsed time in speed
+
8988  get_elapsed("microseconds", &elapsed, &total, &abbr, false);
+
8989  printf_epiworld("Last run speed : %.2f million agents x day / second\n",
+
8990  static_cast<double>(this->size()) *
+
8991  static_cast<double>(this->get_ndays()) /
+
8992  static_cast<double>(elapsed)
+
8993  );
+
8994  if (n_replicates > 1u)
+
8995  {
+
8996  printf_epiworld("Average run speed : %.2f million agents x day / second\n",
+
8997  static_cast<double>(this->size()) *
+
8998  static_cast<double>(this->get_ndays()) *
+
8999  static_cast<double>(n_replicates) /
+
9000  static_cast<double>(total)
+
9001  );
+
9002  }
+
9003 
+
9004  } else {
+
9005  printf_epiworld("Last run elapsed t : -\n");
+
9006  }
+
9007 
+
9008 
+
9009  if (rewire_fun)
+
9010  {
+
9011  printf_epiworld("Rewiring : on (%.2f)\n\n", rewire_prop);
+
9012  } else {
+
9013  printf_epiworld("Rewiring : off\n\n");
+
9014  }
+
9015 
+
9016  // Printing Global events
+
9017  printf_epiworld("Global events:\n");
+
9018  for (auto & a : globalevents)
+
9019  {
+
9020  if (a.get_day() < 0)
+
9021  {
+
9022  printf_epiworld(" - %s (runs daily)\n", a.get_name().c_str());
+
9023  } else {
+
9024  printf_epiworld(" - %s (day %i)\n", a.get_name().c_str(), a.get_day());
+
9025  }
+
9026  }
+
9027 
+
9028  if (globalevents.size() == 0u)
+
9029  {
+
9030  printf_epiworld(" (none)\n");
+
9031  }
+
9032 
+
9033  printf_epiworld("\nVirus(es):\n");
+
9034  size_t n_viruses_model = viruses.size();
+
9035  for (size_t i = 0u; i < n_viruses_model; ++i)
+
9036  {
9037 
-
9038  auto nvariants = db.get_n_viruses() - n_viruses_model;
-
9039  if (nvariants > 0)
-
9040  {
-
9041 
-
9042  printf_epiworld(" ...and %i more variants...\n", static_cast<int>(nvariants));
-
9043 
-
9044  }
-
9045 
-
9046  if (viruses.size() == 0u)
-
9047  {
-
9048  printf_epiworld(" (none)\n");
-
9049  }
-
9050 
-
9051  printf_epiworld("\nTool(s):\n");
-
9052  size_t n_tools_model = tools.size();
-
9053  for (size_t i = 0u; i < tools.size(); ++i)
-
9054  {
-
9055  const auto & tool = tools[i];
+
9038 
+
9039  const auto & virus = viruses[i];
+
9040  if ((n_viruses_model > 10) && (i >= 10))
+
9041  {
+
9042  printf_epiworld(" ...and %i more viruses...\n",
+
9043  static_cast<int>(n_viruses_model) -
+
9044  static_cast<int>(i)
+
9045  );
+
9046  break;
+
9047  }
+
9048 
+
9049  if (i < n_viruses_model)
+
9050  {
+
9051 
+
9052  printf_epiworld(
+
9053  " - %s\n",
+
9054  virus->get_name().c_str()
+
9055  );
9056 
-
9057  if ((n_tools_model > 10) && (i >= 10))
-
9058  {
+
9057  } else {
+
9058 
9059  printf_epiworld(
-
9060  " ...and %i more tools...\n",
-
9061  static_cast<int>(n_tools_model) - static_cast<int>(i)
-
9062  );
-
9063  break;
+
9060  " - %s (originated in the model...)\n",
+
9061  virus->get_name().c_str()
+
9062  );
+
9063 
9064  }
9065 
-
9066  if (i < n_tools_model)
-
9067  {
-
9068  printf_epiworld(
-
9069  " - %s\n",
-
9070  tool->get_name().c_str()
-
9071  );
-
9072 
+
9066  }
+
9067 
+
9068  auto nvariants = db.get_n_viruses() - n_viruses_model;
+
9069  if (nvariants > 0)
+
9070  {
+
9071 
+
9072  printf_epiworld(" ...and %i more variants...\n", static_cast<int>(nvariants));
9073 
-
9074  } else {
+
9074  }
9075 
-
9076  printf_epiworld(
-
9077  " - %s (originated in the model...)\n",
-
9078  tool->get_name().c_str()
-
9079  );
+
9076  if (viruses.size() == 0u)
+
9077  {
+
9078  printf_epiworld(" (none)\n");
+
9079  }
9080 
-
9081  }
-
9082 
-
9083 
-
9084  }
-
9085 
-
9086  if (tools.size() == 0u)
-
9087  {
-
9088  printf_epiworld(" (none)\n");
-
9089  }
-
9090 
-
9091  // Information about the parameters included
-
9092  printf_epiworld("\nModel parameters:\n");
-
9093  epiworld_fast_uint nchar = 0u;
-
9094  for (auto & p : parameters)
-
9095  if (p.first.length() > nchar)
-
9096  nchar = p.first.length();
-
9097 
-
9098  std::string fmt = " - %-" + std::to_string(nchar + 1) + "s: ";
-
9099  for (auto & p : parameters)
-
9100  {
-
9101  std::string fmt_tmp = fmt;
-
9102  if (std::fabs(p.second) < 0.0001)
-
9103  fmt_tmp += "%.1e\n";
-
9104  else
-
9105  fmt_tmp += "%.4f\n";
-
9106 
-
9107  printf_epiworld(
-
9108  fmt_tmp.c_str(),
-
9109  p.first.c_str(),
-
9110  p.second
-
9111  );
+
9081  printf_epiworld("\nTool(s):\n");
+
9082  size_t n_tools_model = tools.size();
+
9083  for (size_t i = 0u; i < tools.size(); ++i)
+
9084  {
+
9085  const auto & tool = tools[i];
+
9086 
+
9087  if ((n_tools_model > 10) && (i >= 10))
+
9088  {
+
9089  printf_epiworld(
+
9090  " ...and %i more tools...\n",
+
9091  static_cast<int>(n_tools_model) - static_cast<int>(i)
+
9092  );
+
9093  break;
+
9094  }
+
9095 
+
9096  if (i < n_tools_model)
+
9097  {
+
9098  printf_epiworld(
+
9099  " - %s\n",
+
9100  tool->get_name().c_str()
+
9101  );
+
9102 
+
9103 
+
9104  } else {
+
9105 
+
9106  printf_epiworld(
+
9107  " - %s (originated in the model...)\n",
+
9108  tool->get_name().c_str()
+
9109  );
+
9110 
+
9111  }
9112 
-
9113  }
-
9114 
-
9115  if (parameters.size() == 0u)
-
9116  {
-
9117  printf_epiworld(" (none)\n");
-
9118  }
-
9119 
-
9120  nchar = 0u;
-
9121  for (auto & p : states_labels)
-
9122  if (p.length() > nchar)
-
9123  nchar = p.length();
-
9124 
-
9125 
-
9126 
-
9127  if (today() != 0)
-
9128  {
-
9129  fmt =
-
9130  std::string(" - (%") +
-
9131  std::to_string(std::to_string(nstates).length()) +
-
9132  std::string("d) %-") + std::to_string(nchar) +
-
9133  std::string("s : %") +
-
9134  std::to_string(std::to_string(size()).length()) +
-
9135  std::string("i -> %i\n");
-
9136  } else {
-
9137  fmt =
-
9138  std::string(" - (%") +
-
9139  std::to_string(std::to_string(nstates).length()) +
-
9140  std::string("d) %-") + std::to_string(nchar) +
-
9141  std::string("s : %i\n");
-
9142  }
-
9143 
-
9144  if (today() != 0)
-
9145  {
-
9146  printf_epiworld("\nDistribution of the population at time %i:\n", today());
-
9147  for (size_t s = 0u; s < nstates; ++s)
-
9148  {
+
9113 
+
9114  }
+
9115 
+
9116  if (tools.size() == 0u)
+
9117  {
+
9118  printf_epiworld(" (none)\n");
+
9119  }
+
9120 
+
9121  // Information about the parameters included
+
9122  printf_epiworld("\nModel parameters:\n");
+
9123  epiworld_fast_uint nchar = 0u;
+
9124  for (auto & p : parameters)
+
9125  if (p.first.length() > nchar)
+
9126  nchar = p.first.length();
+
9127 
+
9128  std::string fmt = " - %-" + std::to_string(nchar + 1) + "s: ";
+
9129  for (auto & p : parameters)
+
9130  {
+
9131  std::string fmt_tmp = fmt;
+
9132  if (std::fabs(p.second) < 0.0001)
+
9133  fmt_tmp += "%.1e\n";
+
9134  else
+
9135  fmt_tmp += "%.4f\n";
+
9136 
+
9137  printf_epiworld(
+
9138  fmt_tmp.c_str(),
+
9139  p.first.c_str(),
+
9140  p.second
+
9141  );
+
9142 
+
9143  }
+
9144 
+
9145  if (parameters.size() == 0u)
+
9146  {
+
9147  printf_epiworld(" (none)\n");
+
9148  }
9149 
-
9150  printf_epiworld(
-
9151  fmt.c_str(),
-
9152  s,
-
9153  states_labels[s].c_str(),
-
9154  db.hist_total_counts[s],
-
9155  db.today_total[ s ]
-
9156  );
-
9157 
-
9158  }
-
9159  // else
-
9160  // {
-
9161 
-
9162  // printf_epiworld(
-
9163  // fmt.c_str(),
-
9164  // s,
-
9165  // states_labels[s].c_str(),
-
9166  // db.today_total[ s ]
-
9167  // );
-
9168 
-
9169  // }
-
9170  }
-
9171 
-
9172  if (today() != 0)
-
9173  (void) db.transition_probability(true);
-
9174 
-
9175  return *this;
-
9176 
-
9177 }
-
9178 
-
9179 #endif
-
9180 /*//////////////////////////////////////////////////////////////////////////////
-
9182 
-
9183  End of -include/epiworld//model-meat-print.hpp-
-
9184 
+
9150  nchar = 0u;
+
9151  for (auto & p : states_labels)
+
9152  if (p.length() > nchar)
+
9153  nchar = p.length();
+
9154 
+
9155 
+
9156 
+
9157  if (today() != 0)
+
9158  {
+
9159  fmt =
+
9160  std::string(" - (%") +
+
9161  std::to_string(std::to_string(nstates).length()) +
+
9162  std::string("d) %-") + std::to_string(nchar) +
+
9163  std::string("s : %") +
+
9164  std::to_string(std::to_string(size()).length()) +
+
9165  std::string("i -> %i\n");
+
9166  } else {
+
9167  fmt =
+
9168  std::string(" - (%") +
+
9169  std::to_string(std::to_string(nstates).length()) +
+
9170  std::string("d) %-") + std::to_string(nchar) +
+
9171  std::string("s : %i\n");
+
9172  }
+
9173 
+
9174  if (today() != 0)
+
9175  {
+
9176  printf_epiworld("\nDistribution of the population at time %i:\n", today());
+
9177  for (size_t s = 0u; s < nstates; ++s)
+
9178  {
+
9179 
+
9180  printf_epiworld(
+
9181  fmt.c_str(),
+
9182  s,
+
9183  states_labels[s].c_str(),
+
9184  db.hist_total_counts[s],
+
9185  db.today_total[ s ]
+
9186  );
9187 
-
9188 
-
9189 
-
9190 
-
9191 template<typename TSeq>
-
9192 inline void Model<TSeq>::add_state(
-
9193  std::string lab,
-
9194  UpdateFun<TSeq> fun
-
9195 )
-
9196 {
-
9197 
-
9198  // Checking it doesn't match
-
9199  for (auto & s : states_labels)
-
9200  if (s == lab)
-
9201  throw std::logic_error("state \"" + s + "\" already registered.");
-
9202 
-
9203  states_labels.push_back(lab);
-
9204  state_fun.push_back(fun);
-
9205  nstates++;
+
9188  }
+
9189  // else
+
9190  // {
+
9191 
+
9192  // printf_epiworld(
+
9193  // fmt.c_str(),
+
9194  // s,
+
9195  // states_labels[s].c_str(),
+
9196  // db.today_total[ s ]
+
9197  // );
+
9198 
+
9199  // }
+
9200  }
+
9201 
+
9202  if (today() != 0)
+
9203  (void) db.transition_probability(true);
+
9204 
+
9205  return *this;
9206 
9207 }
9208 
-
9209 
-
9210 template<typename TSeq>
-
9211 inline const std::vector< std::string > &
-
9212 Model<TSeq>::get_states() const
-
9213 {
-
9214  return states_labels;
-
9215 }
-
9216 
-
9217 template<typename TSeq>
-
9218 inline const std::vector< UpdateFun<TSeq> > &
-
9219 Model<TSeq>::get_state_fun() const
-
9220 {
-
9221  return state_fun;
-
9222 }
-
9223 
-
9224 template<typename TSeq>
-
9225 inline void Model<TSeq>::print_state_codes() const
+
9209 #endif
+
9210 /*//////////////////////////////////////////////////////////////////////////////
+
9212 
+
9213  End of -include/epiworld//model-meat-print.hpp-
+
9214 
+
9217 
+
9218 
+
9219 
+
9220 
+
9221 template<typename TSeq>
+
9222 inline void Model<TSeq>::add_state(
+
9223  std::string lab,
+
9224  UpdateFun<TSeq> fun
+
9225 )
9226 {
9227 
-
9228  // Horizontal line
-
9229  std::string line = "";
-
9230  for (epiworld_fast_uint i = 0u; i < 80u; ++i)
-
9231  line += "_";
+
9228  // Checking it doesn't match
+
9229  for (auto & s : states_labels)
+
9230  if (s == lab)
+
9231  throw std::logic_error("state \"" + s + "\" already registered.");
9232 
-
9233  printf_epiworld("\n%s\nstates CODES\n\n", line.c_str());
-
9234 
-
9235  epiworld_fast_uint nchar = 0u;
-
9236  for (auto & p : states_labels)
-
9237  if (p.length() > nchar)
-
9238  nchar = p.length();
-
9239 
-
9240  std::string fmt = " %2i = %-" + std::to_string(nchar + 1 + 4) + "s\n";
-
9241  for (epiworld_fast_uint i = 0u; i < nstates; ++i)
-
9242  {
-
9243 
-
9244  printf_epiworld(
-
9245  fmt.c_str(),
-
9246  i,
-
9247  (states_labels[i] + " (S)").c_str()
-
9248  );
-
9249 
-
9250  }
-
9251 
+
9233  states_labels.push_back(lab);
+
9234  state_fun.push_back(fun);
+
9235  nstates++;
+
9236 
+
9237 }
+
9238 
+
9239 
+
9240 template<typename TSeq>
+
9241 inline const std::vector< std::string > &
+
9242 Model<TSeq>::get_states() const
+
9243 {
+
9244  return states_labels;
+
9245 }
+
9246 
+
9247 template<typename TSeq>
+
9248 inline const std::vector< UpdateFun<TSeq> > &
+
9249 Model<TSeq>::get_state_fun() const
+
9250 {
+
9251  return state_fun;
9252 }
9253 
-
9254 
-
9255 
-
9256 template<typename TSeq>
-
9257 inline epiworld_double Model<TSeq>::add_param(
-
9258  epiworld_double initial_value,
-
9259  std::string pname
-
9260  ) {
-
9261 
-
9262  if (parameters.find(pname) == parameters.end())
-
9263  parameters[pname] = initial_value;
-
9264 
-
9265  return initial_value;
-
9266 
-
9267 }
-
9268 
-
9269 template<typename TSeq>
-
9270 inline void Model<TSeq>::read_params(std::string fn)
-
9271 {
-
9272 
-
9273  std::ifstream paramsfile(fn);
-
9274 
-
9275  if (!paramsfile)
-
9276  throw std::logic_error("The file " + fn + " was not found.");
-
9277 
-
9278  std::regex pattern("^([^:]+)\\s*[:]\\s*([0-9]+|[0-9]*\\.[0-9]+)?\\s*$");
+
9254 template<typename TSeq>
+
9255 inline void Model<TSeq>::print_state_codes() const
+
9256 {
+
9257 
+
9258  // Horizontal line
+
9259  std::string line = "";
+
9260  for (epiworld_fast_uint i = 0u; i < 80u; ++i)
+
9261  line += "_";
+
9262 
+
9263  printf_epiworld("\n%s\nstates CODES\n\n", line.c_str());
+
9264 
+
9265  epiworld_fast_uint nchar = 0u;
+
9266  for (auto & p : states_labels)
+
9267  if (p.length() > nchar)
+
9268  nchar = p.length();
+
9269 
+
9270  std::string fmt = " %2i = %-" + std::to_string(nchar + 1 + 4) + "s\n";
+
9271  for (epiworld_fast_uint i = 0u; i < nstates; ++i)
+
9272  {
+
9273 
+
9274  printf_epiworld(
+
9275  fmt.c_str(),
+
9276  i,
+
9277  (states_labels[i] + " (S)").c_str()
+
9278  );
9279 
-
9280  std::string line;
-
9281  std::smatch match;
-
9282  auto empty = std::sregex_iterator();
+
9280  }
+
9281 
+
9282 }
9283 
-
9284  while (std::getline(paramsfile, line))
-
9285  {
-
9286 
-
9287  // Is it a comment or an empty line?
-
9288  if (std::regex_match(line, std::regex("^([*].+|//.+|#.+|\\s*)$")))
-
9289  continue;
-
9290 
-
9291  // Finding the patter, if it doesn't match, then error
-
9292  std::regex_match(line, match, pattern);
-
9293 
-
9294  if (match.empty())
-
9295  throw std::logic_error("The line does not match parameters:\n" + line);
+
9284 
+
9285 
+
9286 template<typename TSeq>
+
9287 inline epiworld_double Model<TSeq>::add_param(
+
9288  epiworld_double initial_value,
+
9289  std::string pname
+
9290  ) {
+
9291 
+
9292  if (parameters.find(pname) == parameters.end())
+
9293  parameters[pname] = initial_value;
+
9294 
+
9295  return initial_value;
9296 
-
9297  // Capturing the number
-
9298  std::string anumber = match[2u].str() + match[3u].str();
-
9299  epiworld_double tmp_num = static_cast<epiworld_double>(
-
9300  std::strtod(anumber.c_str(), nullptr)
-
9301  );
+
9297 }
+
9298 
+
9299 template<typename TSeq>
+
9300 inline void Model<TSeq>::read_params(std::string fn)
+
9301 {
9302 
-
9303  add_param(
-
9304  tmp_num,
-
9305  std::regex_replace(
-
9306  match[1u].str(),
-
9307  std::regex("^\\s+|\\s+$"),
-
9308  "")
-
9309  );
-
9310 
-
9311  }
-
9312 
-
9313 }
-
9314 
-
9315 template<typename TSeq>
-
9316 inline epiworld_double Model<TSeq>::get_param(std::string pname)
-
9317 {
-
9318  if (parameters.find(pname) == parameters.end())
-
9319  throw std::logic_error("The parameter " + pname + " does not exists.");
+
9303  std::ifstream paramsfile(fn);
+
9304 
+
9305  if (!paramsfile)
+
9306  throw std::logic_error("The file " + fn + " was not found.");
+
9307 
+
9308  std::regex pattern("^([^:]+)\\s*[:]\\s*([0-9]+|[0-9]*\\.[0-9]+)?\\s*$");
+
9309 
+
9310  std::string line;
+
9311  std::smatch match;
+
9312  auto empty = std::sregex_iterator();
+
9313 
+
9314  while (std::getline(paramsfile, line))
+
9315  {
+
9316 
+
9317  // Is it a comment or an empty line?
+
9318  if (std::regex_match(line, std::regex("^([*].+|//.+|#.+|\\s*)$")))
+
9319  continue;
9320 
-
9321  return parameters[pname];
-
9322 }
+
9321  // Finding the patter, if it doesn't match, then error
+
9322  std::regex_match(line, match, pattern);
9323 
-
9324 template<typename TSeq>
-
9325 inline void Model<TSeq>::set_param(std::string pname, epiworld_double value)
-
9326 {
-
9327  if (parameters.find(pname) == parameters.end())
-
9328  throw std::logic_error("The parameter " + pname + " does not exists.");
-
9329 
-
9330  parameters[pname] = value;
-
9331 
-
9332  return;
-
9333 
-
9334 }
-
9335 
-
9336 // // Same as before but using the size_t method
-
9337 // template<typename TSeq>
-
9338 // inline void Model<TSeq>::set_param(size_t k, epiworld_double value)
-
9339 // {
-
9340 // if (k >= parameters.size())
-
9341 // throw std::logic_error("The parameter index " + std::to_string(k) + " does not exists.");
+
9324  if (match.empty())
+
9325  throw std::logic_error("The line does not match parameters:\n" + line);
+
9326 
+
9327  // Capturing the number
+
9328  std::string anumber = match[2u].str() + match[3u].str();
+
9329  epiworld_double tmp_num = static_cast<epiworld_double>(
+
9330  std::strtod(anumber.c_str(), nullptr)
+
9331  );
+
9332 
+
9333  add_param(
+
9334  tmp_num,
+
9335  std::regex_replace(
+
9336  match[1u].str(),
+
9337  std::regex("^\\s+|\\s+$"),
+
9338  "")
+
9339  );
+
9340 
+
9341  }
9342 
-
9343 // // Access the k-th element of the std::unordered_map parameters
+
9343 }
9344 
-
9345 
-
9346 // *(parameters.begin() + k) = value;
-
9347 
-
9348 // return;
-
9349 // }
+
9345 template<typename TSeq>
+
9346 inline epiworld_double Model<TSeq>::get_param(std::string pname)
+
9347 {
+
9348  if (parameters.find(pname) == parameters.end())
+
9349  throw std::logic_error("The parameter " + pname + " does not exists.");
9350 
-
9351 template<typename TSeq>
-
9352 inline epiworld_double Model<TSeq>::par(std::string pname) const
-
9353 {
-
9354  const auto iter = parameters.find(pname);
-
9355  if (iter == parameters.end())
-
9356  throw std::logic_error("The parameter " + pname + " does not exists.");
-
9357  return iter->second;
-
9358 }
+
9351  return parameters[pname];
+
9352 }
+
9353 
+
9354 template<typename TSeq>
+
9355 inline void Model<TSeq>::set_param(std::string pname, epiworld_double value)
+
9356 {
+
9357  if (parameters.find(pname) == parameters.end())
+
9358  throw std::logic_error("The parameter " + pname + " does not exists.");
9359 
-
9360 #define DURCAST(tunit,txtunit) {\
-
9361  elapsed = std::chrono::duration_cast<std::chrono:: tunit>(\
-
9362  time_end - time_start).count(); \
-
9363  elapsed_total = std::chrono::duration_cast<std::chrono:: tunit>(time_elapsed).count(); \
-
9364  abbr_unit = txtunit;}
+
9360  parameters[pname] = value;
+
9361 
+
9362  return;
+
9363 
+
9364 }
9365 
-
9366 template<typename TSeq>
-
9367 inline void Model<TSeq>::get_elapsed(
-
9368  std::string unit,
-
9369  epiworld_double * last_elapsed,
-
9370  epiworld_double * total_elapsed,
-
9371  std::string * unit_abbr,
-
9372  bool print
-
9373 ) const {
+
9366 // // Same as before but using the size_t method
+
9367 // template<typename TSeq>
+
9368 // inline void Model<TSeq>::set_param(size_t k, epiworld_double value)
+
9369 // {
+
9370 // if (k >= parameters.size())
+
9371 // throw std::logic_error("The parameter index " + std::to_string(k) + " does not exists.");
+
9372 
+
9373 // // Access the k-th element of the std::unordered_map parameters
9374 
-
9375  // Preparing the result
-
9376  epiworld_double elapsed, elapsed_total;
-
9377  std::string abbr_unit;
-
9378 
-
9379  // Figuring out the length
-
9380  if (unit == "auto")
-
9381  {
-
9382 
-
9383  size_t tlength = std::to_string(
-
9384  static_cast<int>(floor(time_elapsed.count()))
-
9385  ).length();
-
9386 
-
9387  if (tlength <= 1)
-
9388  unit = "nanoseconds";
-
9389  else if (tlength <= 3)
-
9390  unit = "microseconds";
-
9391  else if (tlength <= 6)
-
9392  unit = "milliseconds";
-
9393  else if (tlength <= 8)
-
9394  unit = "seconds";
-
9395  else if (tlength <= 9)
-
9396  unit = "minutes";
-
9397  else
-
9398  unit = "hours";
-
9399 
-
9400  }
-
9401 
-
9402  if (unit == "nanoseconds") DURCAST(nanoseconds,"ns")
-
9403  else if (unit == "microseconds") DURCAST(microseconds,"\xC2\xB5s")
-
9404  else if (unit == "milliseconds") DURCAST(milliseconds,"ms")
-
9405  else if (unit == "seconds") DURCAST(seconds,"s")
-
9406  else if (unit == "minutes") DURCAST(minutes,"m")
-
9407  else if (unit == "hours") DURCAST(hours,"h")
-
9408  else
-
9409  throw std::range_error("The time unit " + unit + " is not supported.");
-
9410 
-
9411 
-
9412  if (last_elapsed != nullptr)
-
9413  *last_elapsed = elapsed;
-
9414  if (total_elapsed != nullptr)
-
9415  *total_elapsed = elapsed_total;
-
9416  if (unit_abbr != nullptr)
-
9417  *unit_abbr = abbr_unit;
-
9418 
-
9419  if (!print)
-
9420  return;
-
9421 
-
9422  if (n_replicates > 1u)
-
9423  {
-
9424  printf_epiworld("last run elapsed time : %.2f%s\n",
-
9425  elapsed, abbr_unit.c_str());
-
9426  printf_epiworld("total elapsed time : %.2f%s\n",
-
9427  elapsed_total, abbr_unit.c_str());
-
9428  printf_epiworld("total runs : %i\n",
-
9429  static_cast<int>(n_replicates));
-
9430  printf_epiworld("mean run elapsed time : %.2f%s\n",
-
9431  elapsed_total/static_cast<epiworld_double>(n_replicates), abbr_unit.c_str());
-
9432 
-
9433  } else {
-
9434  printf_epiworld("last run elapsed time : %.2f%s.\n", elapsed, abbr_unit.c_str());
-
9435  }
-
9436 }
-
9437 
-
9438 template<typename TSeq>
-
9439 inline void Model<TSeq>::set_user_data(std::vector< std::string > names)
-
9440 {
-
9441  db.set_user_data(names);
-
9442 }
-
9443 
-
9444 template<typename TSeq>
-
9445 inline void Model<TSeq>::add_user_data(epiworld_fast_uint j, epiworld_double x)
-
9446 {
-
9447  db.add_user_data(j, x);
-
9448 }
-
9449 
-
9450 template<typename TSeq>
-
9451 inline void Model<TSeq>::add_user_data(std::vector<epiworld_double> x)
-
9452 {
-
9453  db.add_user_data(x);
-
9454 }
-
9455 
-
9456 template<typename TSeq>
-
9457 inline UserData<TSeq> & Model<TSeq>::get_user_data()
-
9458 {
-
9459  return db.get_user_data();
-
9460 }
-
9461 
-
9462 template<typename TSeq>
-
9463 inline void Model<TSeq>::add_globalevent(
-
9464  std::function<void(Model<TSeq>*)> fun,
-
9465  std::string name,
-
9466  int date
-
9467 )
-
9468 {
-
9469 
-
9470  globalevents.push_back(
-
9471  GlobalEvent<TSeq>(
-
9472  fun,
-
9473  name,
-
9474  date
-
9475  )
-
9476  );
-
9477 
+
9375 
+
9376 // *(parameters.begin() + k) = value;
+
9377 
+
9378 // return;
+
9379 // }
+
9380 
+
9381 template<typename TSeq>
+
9382 inline epiworld_double Model<TSeq>::par(std::string pname) const
+
9383 {
+
9384  const auto iter = parameters.find(pname);
+
9385  if (iter == parameters.end())
+
9386  throw std::logic_error("The parameter " + pname + " does not exists.");
+
9387  return iter->second;
+
9388 }
+
9389 
+
9390 #define DURCAST(tunit,txtunit) {\
+
9391  elapsed = std::chrono::duration_cast<std::chrono:: tunit>(\
+
9392  time_end - time_start).count(); \
+
9393  elapsed_total = std::chrono::duration_cast<std::chrono:: tunit>(time_elapsed).count(); \
+
9394  abbr_unit = txtunit;}
+
9395 
+
9396 template<typename TSeq>
+
9397 inline void Model<TSeq>::get_elapsed(
+
9398  std::string unit,
+
9399  epiworld_double * last_elapsed,
+
9400  epiworld_double * total_elapsed,
+
9401  std::string * unit_abbr,
+
9402  bool print
+
9403 ) const {
+
9404 
+
9405  // Preparing the result
+
9406  epiworld_double elapsed, elapsed_total;
+
9407  std::string abbr_unit;
+
9408 
+
9409  // Figuring out the length
+
9410  if (unit == "auto")
+
9411  {
+
9412 
+
9413  size_t tlength = std::to_string(
+
9414  static_cast<int>(floor(time_elapsed.count()))
+
9415  ).length();
+
9416 
+
9417  if (tlength <= 1)
+
9418  unit = "nanoseconds";
+
9419  else if (tlength <= 3)
+
9420  unit = "microseconds";
+
9421  else if (tlength <= 6)
+
9422  unit = "milliseconds";
+
9423  else if (tlength <= 8)
+
9424  unit = "seconds";
+
9425  else if (tlength <= 9)
+
9426  unit = "minutes";
+
9427  else
+
9428  unit = "hours";
+
9429 
+
9430  }
+
9431 
+
9432  if (unit == "nanoseconds") DURCAST(nanoseconds,"ns")
+
9433  else if (unit == "microseconds") DURCAST(microseconds,"\xC2\xB5s")
+
9434  else if (unit == "milliseconds") DURCAST(milliseconds,"ms")
+
9435  else if (unit == "seconds") DURCAST(seconds,"s")
+
9436  else if (unit == "minutes") DURCAST(minutes,"m")
+
9437  else if (unit == "hours") DURCAST(hours,"h")
+
9438  else
+
9439  throw std::range_error("The time unit " + unit + " is not supported.");
+
9440 
+
9441 
+
9442  if (last_elapsed != nullptr)
+
9443  *last_elapsed = elapsed;
+
9444  if (total_elapsed != nullptr)
+
9445  *total_elapsed = elapsed_total;
+
9446  if (unit_abbr != nullptr)
+
9447  *unit_abbr = abbr_unit;
+
9448 
+
9449  if (!print)
+
9450  return;
+
9451 
+
9452  if (n_replicates > 1u)
+
9453  {
+
9454  printf_epiworld("last run elapsed time : %.2f%s\n",
+
9455  elapsed, abbr_unit.c_str());
+
9456  printf_epiworld("total elapsed time : %.2f%s\n",
+
9457  elapsed_total, abbr_unit.c_str());
+
9458  printf_epiworld("total runs : %i\n",
+
9459  static_cast<int>(n_replicates));
+
9460  printf_epiworld("mean run elapsed time : %.2f%s\n",
+
9461  elapsed_total/static_cast<epiworld_double>(n_replicates), abbr_unit.c_str());
+
9462 
+
9463  } else {
+
9464  printf_epiworld("last run elapsed time : %.2f%s.\n", elapsed, abbr_unit.c_str());
+
9465  }
+
9466 }
+
9467 
+
9468 template<typename TSeq>
+
9469 inline void Model<TSeq>::set_user_data(std::vector< std::string > names)
+
9470 {
+
9471  db.set_user_data(names);
+
9472 }
+
9473 
+
9474 template<typename TSeq>
+
9475 inline void Model<TSeq>::add_user_data(epiworld_fast_uint j, epiworld_double x)
+
9476 {
+
9477  db.add_user_data(j, x);
9478 }
9479 
9480 template<typename TSeq>
-
9481 inline void Model<TSeq>::add_globalevent(
-
9482  GlobalEvent<TSeq> action
-
9483 )
-
9484 {
-
9485  globalevents.push_back(action);
-
9486 }
-
9487 
-
9488 template<typename TSeq>
-
9489 GlobalEvent<TSeq> & Model<TSeq>::get_globalevent(
-
9490  std::string name
-
9491 )
-
9492 {
-
9493 
-
9494  for (auto & a : globalevents)
-
9495  if (a.name == name)
-
9496  return a;
-
9497 
-
9498  throw std::logic_error("The global action " + name + " was not found.");
+
9481 inline void Model<TSeq>::add_user_data(std::vector<epiworld_double> x)
+
9482 {
+
9483  db.add_user_data(x);
+
9484 }
+
9485 
+
9486 template<typename TSeq>
+
9487 inline UserData<TSeq> & Model<TSeq>::get_user_data()
+
9488 {
+
9489  return db.get_user_data();
+
9490 }
+
9491 
+
9492 template<typename TSeq>
+
9493 inline void Model<TSeq>::add_globalevent(
+
9494  std::function<void(Model<TSeq>*)> fun,
+
9495  std::string name,
+
9496  int date
+
9497 )
+
9498 {
9499 
-
9500 }
-
9501 
-
9502 template<typename TSeq>
-
9503 GlobalEvent<TSeq> & Model<TSeq>::get_globalevent(
-
9504  size_t index
-
9505 )
-
9506 {
+
9500  globalevents.push_back(
+
9501  GlobalEvent<TSeq>(
+
9502  fun,
+
9503  name,
+
9504  date
+
9505  )
+
9506  );
9507 
-
9508  if (index >= globalevents.size())
-
9509  throw std::range_error("The index " + std::to_string(index) + " is out of range.");
-
9510 
-
9511  return globalevents[index];
-
9512 
-
9513 }
-
9514 
-
9515 // Remove implementation
-
9516 template<typename TSeq>
-
9517 inline void Model<TSeq>::rm_globalevent(
-
9518  std::string name
-
9519 )
-
9520 {
-
9521 
-
9522  for (auto it = globalevents.begin(); it != globalevents.end(); ++it)
-
9523  {
-
9524  if (it->get_name() == name)
-
9525  {
-
9526  globalevents.erase(it);
-
9527  return;
-
9528  }
-
9529  }
-
9530 
-
9531  throw std::logic_error("The global action " + name + " was not found.");
-
9532 
-
9533 }
-
9534 
-
9535 // Same as above, but the index implementation
-
9536 template<typename TSeq>
-
9537 inline void Model<TSeq>::rm_globalevent(
-
9538  size_t index
-
9539 )
-
9540 {
-
9541 
-
9542  if (index >= globalevents.size())
-
9543  throw std::range_error("The index " + std::to_string(index) + " is out of range.");
+
9508 }
+
9509 
+
9510 template<typename TSeq>
+
9511 inline void Model<TSeq>::add_globalevent(
+
9512  GlobalEvent<TSeq> action
+
9513 )
+
9514 {
+
9515  globalevents.push_back(action);
+
9516 }
+
9517 
+
9518 template<typename TSeq>
+
9519 GlobalEvent<TSeq> & Model<TSeq>::get_globalevent(
+
9520  std::string name
+
9521 )
+
9522 {
+
9523 
+
9524  for (auto & a : globalevents)
+
9525  if (a.name == name)
+
9526  return a;
+
9527 
+
9528  throw std::logic_error("The global action " + name + " was not found.");
+
9529 
+
9530 }
+
9531 
+
9532 template<typename TSeq>
+
9533 GlobalEvent<TSeq> & Model<TSeq>::get_globalevent(
+
9534  size_t index
+
9535 )
+
9536 {
+
9537 
+
9538  if (index >= globalevents.size())
+
9539  throw std::range_error("The index " + std::to_string(index) + " is out of range.");
+
9540 
+
9541  return globalevents[index];
+
9542 
+
9543 }
9544 
-
9545  globalevents.erase(globalevents.begin() + index);
-
9546 
-
9547 }
-
9548 
-
9549 template<typename TSeq>
-
9550 inline void Model<TSeq>::run_globalevents()
-
9551 {
-
9552 
-
9553  for (auto & action: globalevents)
-
9554  {
-
9555  action(this, today());
-
9556  events_run();
-
9557  }
-
9558 
-
9559 }
+
9545 // Remove implementation
+
9546 template<typename TSeq>
+
9547 inline void Model<TSeq>::rm_globalevent(
+
9548  std::string name
+
9549 )
+
9550 {
+
9551 
+
9552  for (auto it = globalevents.begin(); it != globalevents.end(); ++it)
+
9553  {
+
9554  if (it->get_name() == name)
+
9555  {
+
9556  globalevents.erase(it);
+
9557  return;
+
9558  }
+
9559  }
9560 
-
9561 template<typename TSeq>
-
9562 inline void Model<TSeq>::queuing_on()
-
9563 {
-
9564  use_queuing = true;
-
9565 }
-
9566 
-
9567 template<typename TSeq>
-
9568 inline Model<TSeq> & Model<TSeq>::queuing_off()
-
9569 {
-
9570  use_queuing = false;
-
9571  return *this;
-
9572 }
-
9573 
-
9574 template<typename TSeq>
-
9575 inline bool Model<TSeq>::is_queuing_on() const
-
9576 {
-
9577  return use_queuing;
-
9578 }
-
9579 
-
9580 template<typename TSeq>
-
9581 inline Queue<TSeq> & Model<TSeq>::get_queue()
-
9582 {
-
9583  return queue;
-
9584 }
-
9585 
-
9586 template<typename TSeq>
-
9587 inline const std::vector< VirusPtr<TSeq> > & Model<TSeq>::get_viruses() const
-
9588 {
-
9589  return viruses;
-
9590 }
-
9591 
-
9592 template<typename TSeq>
-
9593 const std::vector< ToolPtr<TSeq> > & Model<TSeq>::get_tools() const
-
9594 {
-
9595  return tools;
-
9596 }
-
9597 
-
9598 template<typename TSeq>
-
9599 inline Virus<TSeq> & Model<TSeq>::get_virus(size_t id)
-
9600 {
-
9601 
-
9602  if (viruses.size() <= id)
-
9603  throw std::length_error("The specified id for the virus is out of range");
-
9604 
-
9605  return *viruses[id];
-
9606 
-
9607 }
-
9608 
-
9609 template<typename TSeq>
-
9610 inline Tool<TSeq> & Model<TSeq>::get_tool(size_t id)
-
9611 {
-
9612 
-
9613  if (tools.size() <= id)
-
9614  throw std::length_error("The specified id for the tools is out of range");
+
9561  throw std::logic_error("The global action " + name + " was not found.");
+
9562 
+
9563 }
+
9564 
+
9565 // Same as above, but the index implementation
+
9566 template<typename TSeq>
+
9567 inline void Model<TSeq>::rm_globalevent(
+
9568  size_t index
+
9569 )
+
9570 {
+
9571 
+
9572  if (index >= globalevents.size())
+
9573  throw std::range_error("The index " + std::to_string(index) + " is out of range.");
+
9574 
+
9575  globalevents.erase(globalevents.begin() + index);
+
9576 
+
9577 }
+
9578 
+
9579 template<typename TSeq>
+
9580 inline void Model<TSeq>::run_globalevents()
+
9581 {
+
9582 
+
9583  for (auto & action: globalevents)
+
9584  {
+
9585  action(this, today());
+
9586  events_run();
+
9587  }
+
9588 
+
9589 }
+
9590 
+
9591 template<typename TSeq>
+
9592 inline void Model<TSeq>::queuing_on()
+
9593 {
+
9594  use_queuing = true;
+
9595 }
+
9596 
+
9597 template<typename TSeq>
+
9598 inline Model<TSeq> & Model<TSeq>::queuing_off()
+
9599 {
+
9600  use_queuing = false;
+
9601  return *this;
+
9602 }
+
9603 
+
9604 template<typename TSeq>
+
9605 inline bool Model<TSeq>::is_queuing_on() const
+
9606 {
+
9607  return use_queuing;
+
9608 }
+
9609 
+
9610 template<typename TSeq>
+
9611 inline Queue<TSeq> & Model<TSeq>::get_queue()
+
9612 {
+
9613  return queue;
+
9614 }
9615 
-
9616  return *tools[id];
-
9617 
-
9618 }
-
9619 
-
9620 
-
9621 template<typename TSeq>
-
9622 inline void Model<TSeq>::set_agents_data(double * data_, size_t ncols_)
-
9623 {
-
9624  agents_data = data_;
-
9625  agents_data_ncols = ncols_;
+
9616 template<typename TSeq>
+
9617 inline const std::vector< VirusPtr<TSeq> > & Model<TSeq>::get_viruses() const
+
9618 {
+
9619  return viruses;
+
9620 }
+
9621 
+
9622 template<typename TSeq>
+
9623 const std::vector< ToolPtr<TSeq> > & Model<TSeq>::get_tools() const
+
9624 {
+
9625  return tools;
9626 }
9627 
9628 template<typename TSeq>
-
9629 inline double * Model<TSeq>::get_agents_data() {
-
9630  return this->agents_data;
-
9631 }
-
9632 
-
9633 template<typename TSeq>
-
9634 inline size_t Model<TSeq>::get_agents_data_ncols() const {
-
9635  return this->agents_data_ncols;
-
9636 }
-
9637 
+
9629 inline Virus<TSeq> & Model<TSeq>::get_virus(size_t id)
+
9630 {
+
9631 
+
9632  if (viruses.size() <= id)
+
9633  throw std::length_error("The specified id for the virus is out of range");
+
9634 
+
9635  return *viruses[id];
+
9636 
+
9637 }
9638 
9639 template<typename TSeq>
-
9640 inline void Model<TSeq>::set_name(std::string name)
+
9640 inline Tool<TSeq> & Model<TSeq>::get_tool(size_t id)
9641 {
-
9642  this->name = name;
-
9643 }
-
9644 
-
9645 template<typename TSeq>
-
9646 inline std::string Model<TSeq>::get_name() const
-
9647 {
-
9648  return this->name;
-
9649 }
+
9642 
+
9643  if (tools.size() <= id)
+
9644  throw std::length_error("The specified id for the tools is out of range");
+
9645 
+
9646  return *tools[id];
+
9647 
+
9648 }
+
9649 
9650 
-
9651 #define VECT_MATCH(a, b, c) \
-
9652  EPI_DEBUG_FAIL_AT_TRUE(a.size() != b.size(), c) \
-
9653  for (size_t __i = 0u; __i < a.size(); ++__i) \
-
9654  {\
-
9655  EPI_DEBUG_FAIL_AT_TRUE(a[__i] != b[__i], c) \
-
9656  }
+
9651 template<typename TSeq>
+
9652 inline void Model<TSeq>::set_agents_data(double * data_, size_t ncols_)
+
9653 {
+
9654  agents_data = data_;
+
9655  agents_data_ncols = ncols_;
+
9656 }
9657 
9658 template<typename TSeq>
-
9659 inline bool Model<TSeq>::operator==(const Model<TSeq> & other) const
-
9660 {
-
9661  EPI_DEBUG_FAIL_AT_TRUE(name != other.name, "names don't match")
-
9662  EPI_DEBUG_FAIL_AT_TRUE(db != other.db, "database don't match")
-
9663 
-
9664  VECT_MATCH(population, other.population, "population doesn't match")
-
9665 
-
9666  EPI_DEBUG_FAIL_AT_TRUE(
-
9667  using_backup != other.using_backup,
-
9668  "Model:: using_backup don't match"
-
9669  )
-
9670 
-
9671  if ((population_backup.size() != 0) & (other.population_backup.size() != 0))
-
9672  {
-
9673 
-
9674  // False is population_backup.size() != other.population_backup.size()
-
9675  if (population_backup.size() != other.population_backup.size())
-
9676  return false;
-
9677 
-
9678  for (size_t i = 0u; i < population_backup.size(); ++i)
-
9679  {
-
9680  if (population_backup[i] != other.population_backup[i])
-
9681  return false;
-
9682  }
-
9683 
-
9684  } else if ((population_backup.size() == 0) & (other.population_backup.size() != 0)) {
-
9685  return false;
-
9686  } else if ((population_backup.size() != 0) & (other.population_backup.size() == 0))
-
9687  {
-
9688  return false;
-
9689  }
-
9690 
-
9691  EPI_DEBUG_FAIL_AT_TRUE(
-
9692  agents_data != other.agents_data,
-
9693  "Model:: agents_data don't match"
-
9694  )
+
9659 inline double * Model<TSeq>::get_agents_data() {
+
9660  return this->agents_data;
+
9661 }
+
9662 
+
9663 template<typename TSeq>
+
9664 inline size_t Model<TSeq>::get_agents_data_ncols() const {
+
9665  return this->agents_data_ncols;
+
9666 }
+
9667 
+
9668 
+
9669 template<typename TSeq>
+
9670 inline void Model<TSeq>::set_name(std::string name)
+
9671 {
+
9672  this->name = name;
+
9673 }
+
9674 
+
9675 template<typename TSeq>
+
9676 inline std::string Model<TSeq>::get_name() const
+
9677 {
+
9678  return this->name;
+
9679 }
+
9680 
+
9681 #define VECT_MATCH(a, b, c) \
+
9682  EPI_DEBUG_FAIL_AT_TRUE(a.size() != b.size(), c) \
+
9683  for (size_t __i = 0u; __i < a.size(); ++__i) \
+
9684  {\
+
9685  EPI_DEBUG_FAIL_AT_TRUE(a[__i] != b[__i], c) \
+
9686  }
+
9687 
+
9688 template<typename TSeq>
+
9689 inline bool Model<TSeq>::operator==(const Model<TSeq> & other) const
+
9690 {
+
9691  EPI_DEBUG_FAIL_AT_TRUE(name != other.name, "names don't match")
+
9692  EPI_DEBUG_FAIL_AT_TRUE(db != other.db, "database don't match")
+
9693 
+
9694  VECT_MATCH(population, other.population, "population doesn't match")
9695 
9696  EPI_DEBUG_FAIL_AT_TRUE(
-
9697  agents_data_ncols != other.agents_data_ncols,
-
9698  "Model:: agents_data_ncols don't match"
-
9699  )
-
9700 
-
9701  EPI_DEBUG_FAIL_AT_TRUE(
-
9702  directed != other.directed,
-
9703  "Model:: directed don't match"
-
9704  )
-
9705 
-
9706  // Viruses -----------------------------------------------------------------
-
9707  EPI_DEBUG_FAIL_AT_TRUE(
-
9708  viruses.size() != other.viruses.size(),
-
9709  "Model:: viruses.size() don't match"
-
9710  )
-
9711 
-
9712  for (size_t i = 0u; i < viruses.size(); ++i)
-
9713  {
-
9714  EPI_DEBUG_FAIL_AT_TRUE(
-
9715  *viruses[i] != *other.viruses[i],
-
9716  "Model:: *viruses[i] don't match"
-
9717  )
-
9718 
+
9697  using_backup != other.using_backup,
+
9698  "Model:: using_backup don't match"
+
9699  )
+
9700 
+
9701  if ((population_backup.size() != 0) & (other.population_backup.size() != 0))
+
9702  {
+
9703 
+
9704  // False is population_backup.size() != other.population_backup.size()
+
9705  if (population_backup.size() != other.population_backup.size())
+
9706  return false;
+
9707 
+
9708  for (size_t i = 0u; i < population_backup.size(); ++i)
+
9709  {
+
9710  if (population_backup[i] != other.population_backup[i])
+
9711  return false;
+
9712  }
+
9713 
+
9714  } else if ((population_backup.size() == 0) & (other.population_backup.size() != 0)) {
+
9715  return false;
+
9716  } else if ((population_backup.size() != 0) & (other.population_backup.size() == 0))
+
9717  {
+
9718  return false;
9719  }
-
9720 
-
9721  // Tools -------------------------------------------------------------------
-
9722  EPI_DEBUG_FAIL_AT_TRUE(
-
9723  tools.size() != other.tools.size(),
-
9724  "Model:: tools.size() don't match"
-
9725  )
-
9726 
-
9727  for (size_t i = 0u; i < tools.size(); ++i)
-
9728  {
-
9729  EPI_DEBUG_FAIL_AT_TRUE(
-
9730  *tools[i] != *other.tools[i],
-
9731  "Model:: *tools[i] don't match"
-
9732  )
-
9733 
-
9734  }
+
9720 
+
9721  EPI_DEBUG_FAIL_AT_TRUE(
+
9722  agents_data != other.agents_data,
+
9723  "Model:: agents_data don't match"
+
9724  )
+
9725 
+
9726  EPI_DEBUG_FAIL_AT_TRUE(
+
9727  agents_data_ncols != other.agents_data_ncols,
+
9728  "Model:: agents_data_ncols don't match"
+
9729  )
+
9730 
+
9731  EPI_DEBUG_FAIL_AT_TRUE(
+
9732  directed != other.directed,
+
9733  "Model:: directed don't match"
+
9734  )
9735 
-
9736  VECT_MATCH(
-
9737  entities,
-
9738  other.entities,
-
9739  "entities don't match"
-
9740  )
+
9736  // Viruses -----------------------------------------------------------------
+
9737  EPI_DEBUG_FAIL_AT_TRUE(
+
9738  viruses.size() != other.viruses.size(),
+
9739  "Model:: viruses.size() don't match"
+
9740  )
9741 
-
9742  if ((entities_backup.size() != 0) & (other.entities_backup.size() != 0))
+
9742  for (size_t i = 0u; i < viruses.size(); ++i)
9743  {
-
9744 
-
9745  for (size_t i = 0u; i < entities_backup.size(); ++i)
-
9746  {
-
9747 
-
9748  EPI_DEBUG_FAIL_AT_TRUE(
-
9749  entities_backup[i] != other.entities_backup[i],
-
9750  "Model:: entities_backup[i] don't match"
-
9751  )
-
9752 
-
9753  }
-
9754 
-
9755  } else if ((entities_backup.size() == 0) & (other.entities_backup.size() != 0)) {
-
9756  EPI_DEBUG_FAIL_AT_TRUE(true, "entities_backup don't match")
-
9757  } else if ((entities_backup.size() != 0) & (other.entities_backup.size() == 0))
+
9744  EPI_DEBUG_FAIL_AT_TRUE(
+
9745  *viruses[i] != *other.viruses[i],
+
9746  "Model:: *viruses[i] don't match"
+
9747  )
+
9748 
+
9749  }
+
9750 
+
9751  // Tools -------------------------------------------------------------------
+
9752  EPI_DEBUG_FAIL_AT_TRUE(
+
9753  tools.size() != other.tools.size(),
+
9754  "Model:: tools.size() don't match"
+
9755  )
+
9756 
+
9757  for (size_t i = 0u; i < tools.size(); ++i)
9758  {
-
9759  EPI_DEBUG_FAIL_AT_TRUE(true, "entities_backup don't match")
-
9760  }
-
9761 
-
9762  EPI_DEBUG_FAIL_AT_TRUE(
-
9763  rewire_prop != other.rewire_prop,
-
9764  "Model:: rewire_prop don't match"
-
9765  )
-
9766 
-
9767  EPI_DEBUG_FAIL_AT_TRUE(
-
9768  parameters.size() != other.parameters.size(),
-
9769  "Model:: () don't match"
+
9759  EPI_DEBUG_FAIL_AT_TRUE(
+
9760  *tools[i] != *other.tools[i],
+
9761  "Model:: *tools[i] don't match"
+
9762  )
+
9763 
+
9764  }
+
9765 
+
9766  VECT_MATCH(
+
9767  entities,
+
9768  other.entities,
+
9769  "entities don't match"
9770  )
9771 
-
9772  EPI_DEBUG_FAIL_AT_TRUE(
-
9773  parameters != other.parameters,
-
9774  "Model:: parameters don't match"
-
9775  )
-
9776 
-
9777  EPI_DEBUG_FAIL_AT_TRUE(
-
9778  ndays != other.ndays,
-
9779  "Model:: ndays don't match"
-
9780  )
-
9781 
-
9782  VECT_MATCH(
-
9783  states_labels,
-
9784  other.states_labels,
-
9785  "state labels don't match"
-
9786  )
-
9787 
-
9788  EPI_DEBUG_FAIL_AT_TRUE(
-
9789  nstates != other.nstates,
-
9790  "Model:: nstates don't match"
-
9791  )
-
9792 
-
9793  EPI_DEBUG_FAIL_AT_TRUE(
-
9794  verbose != other.verbose,
-
9795  "Model:: verbose don't match"
-
9796  )
-
9797 
-
9798  EPI_DEBUG_FAIL_AT_TRUE(
-
9799  current_date != other.current_date,
-
9800  "Model:: current_date don't match"
-
9801  )
-
9802 
-
9803  VECT_MATCH(globalevents, other.globalevents, "global action don't match");
-
9804 
-
9805  EPI_DEBUG_FAIL_AT_TRUE(
-
9806  queue != other.queue,
-
9807  "Model:: queue don't match"
-
9808  )
-
9809 
-
9810 
-
9811  EPI_DEBUG_FAIL_AT_TRUE(
-
9812  use_queuing != other.use_queuing,
-
9813  "Model:: use_queuing don't match"
-
9814  )
-
9815 
-
9816  return true;
+
9772  if ((entities_backup.size() != 0) & (other.entities_backup.size() != 0))
+
9773  {
+
9774 
+
9775  for (size_t i = 0u; i < entities_backup.size(); ++i)
+
9776  {
+
9777 
+
9778  EPI_DEBUG_FAIL_AT_TRUE(
+
9779  entities_backup[i] != other.entities_backup[i],
+
9780  "Model:: entities_backup[i] don't match"
+
9781  )
+
9782 
+
9783  }
+
9784 
+
9785  } else if ((entities_backup.size() == 0) & (other.entities_backup.size() != 0)) {
+
9786  EPI_DEBUG_FAIL_AT_TRUE(true, "entities_backup don't match")
+
9787  } else if ((entities_backup.size() != 0) & (other.entities_backup.size() == 0))
+
9788  {
+
9789  EPI_DEBUG_FAIL_AT_TRUE(true, "entities_backup don't match")
+
9790  }
+
9791 
+
9792  EPI_DEBUG_FAIL_AT_TRUE(
+
9793  rewire_prop != other.rewire_prop,
+
9794  "Model:: rewire_prop don't match"
+
9795  )
+
9796 
+
9797  EPI_DEBUG_FAIL_AT_TRUE(
+
9798  parameters.size() != other.parameters.size(),
+
9799  "Model:: () don't match"
+
9800  )
+
9801 
+
9802  EPI_DEBUG_FAIL_AT_TRUE(
+
9803  parameters != other.parameters,
+
9804  "Model:: parameters don't match"
+
9805  )
+
9806 
+
9807  EPI_DEBUG_FAIL_AT_TRUE(
+
9808  ndays != other.ndays,
+
9809  "Model:: ndays don't match"
+
9810  )
+
9811 
+
9812  VECT_MATCH(
+
9813  states_labels,
+
9814  other.states_labels,
+
9815  "state labels don't match"
+
9816  )
9817 
-
9818 }
-
9819 
-
9820 #undef VECT_MATCH
-
9821 #undef DURCAST
-
9822 #undef CASES_PAR
-
9823 #undef CASE_PAR
-
9824 #undef CHECK_INIT
-
9825 #endif
-
9826 /*//////////////////////////////////////////////////////////////////////////////
-
9828 
-
9829  End of -include/epiworld/model-meat.hpp-
-
9830 
-
9833 
+
9818  EPI_DEBUG_FAIL_AT_TRUE(
+
9819  nstates != other.nstates,
+
9820  "Model:: nstates don't match"
+
9821  )
+
9822 
+
9823  EPI_DEBUG_FAIL_AT_TRUE(
+
9824  verbose != other.verbose,
+
9825  "Model:: verbose don't match"
+
9826  )
+
9827 
+
9828  EPI_DEBUG_FAIL_AT_TRUE(
+
9829  current_date != other.current_date,
+
9830  "Model:: current_date don't match"
+
9831  )
+
9832 
+
9833  VECT_MATCH(globalevents, other.globalevents, "global action don't match");
9834 
-
9835 
-
9836 /*//////////////////////////////////////////////////////////////////////////////
-
9838 
-
9839  Start of -include/epiworld/viruses-bones.hpp-
+
9835  EPI_DEBUG_FAIL_AT_TRUE(
+
9836  queue != other.queue,
+
9837  "Model:: queue don't match"
+
9838  )
+
9839 
9840 
-
9843 
-
9844 
-
9845 #ifndef EPIWORLD_VIRUSES_BONES_HPP
-
9846 #define EPIWORLD_VIRUSES_BONES_HPP
+
9841  EPI_DEBUG_FAIL_AT_TRUE(
+
9842  use_queuing != other.use_queuing,
+
9843  "Model:: use_queuing don't match"
+
9844  )
+
9845 
+
9846  return true;
9847 
-
9848 template<typename TSeq>
-
9849 class Virus;
-
9850 
-
9851 template<typename TSeq>
-
9852 class Agent;
-
9853 
-
9859 template<typename TSeq>
-
9860 class Viruses {
-
9861  friend class Virus<TSeq>;
-
9862  friend class Agent<TSeq>;
-
9863 private:
-
9864  std::vector< VirusPtr<TSeq> > * dat;
-
9865  const epiworld_fast_uint * n_viruses;
-
9866 
-
9867 public:
+
9848 }
+
9849 
+
9850 #undef VECT_MATCH
+
9851 #undef DURCAST
+
9852 #undef CASES_PAR
+
9853 #undef CASE_PAR
+
9854 #undef CHECK_INIT
+
9855 #endif
+
9856 /*//////////////////////////////////////////////////////////////////////////////
+
9858 
+
9859  End of -include/epiworld/model-meat.hpp-
+
9860 
+
9863 
+
9864 
+
9865 
+
9866 /*//////////////////////////////////////////////////////////////////////////////
9868 
-
9869  Viruses() = delete;
-
9870  Viruses(Agent<TSeq> & p) : dat(&p.viruses), n_viruses(&p.n_viruses) {};
-
9871 
-
9872  typename std::vector< VirusPtr<TSeq> >::iterator begin();
-
9873  typename std::vector< VirusPtr<TSeq> >::iterator end();
+
9869  Start of -include/epiworld/viruses-bones.hpp-
+
9870 
+
9873 
9874 
-
9875  VirusPtr<TSeq> & operator()(size_t i);
-
9876  VirusPtr<TSeq> & operator[](size_t i);
+
9875 #ifndef EPIWORLD_VIRUSES_BONES_HPP
+
9876 #define EPIWORLD_VIRUSES_BONES_HPP
9877 
-
9878  size_t size() const noexcept;
-
9879 
-
9880  void print() const noexcept;
-
9881 
-
9882 };
+
9878 template<typename TSeq>
+
9879 class Virus;
+
9880 
+
9881 template<typename TSeq>
+
9882 class Agent;
9883 
-
9884 template<typename TSeq>
-
9885 inline typename std::vector< VirusPtr<TSeq> >::iterator Viruses<TSeq>::begin()
-
9886 {
-
9887 
-
9888  if (*n_viruses == 0u)
-
9889  return dat->end();
-
9890 
-
9891  return dat->begin();
-
9892 }
-
9893 
-
9894 template<typename TSeq>
-
9895 inline typename std::vector< VirusPtr<TSeq> >::iterator Viruses<TSeq>::end()
-
9896 {
-
9897 
-
9898  #ifdef EPI_DEBUG
-
9899  if (dat->size() < *n_viruses)
-
9900  throw EPI_DEBUG_ERROR(std::logic_error, "Viruses:: The end of the virus is out of range");
-
9901  #endif
-
9902 
-
9903  return begin() + *n_viruses;
-
9904 }
-
9905 
-
9906 template<typename TSeq>
-
9907 inline VirusPtr<TSeq> & Viruses<TSeq>::operator()(size_t i)
-
9908 {
+
9889 template<typename TSeq>
+
9890 class Viruses {
+
9891  friend class Virus<TSeq>;
+
9892  friend class Agent<TSeq>;
+
9893 private:
+
9894  std::vector< VirusPtr<TSeq> > * dat;
+
9895  const epiworld_fast_uint * n_viruses;
+
9896 
+
9897 public:
+
9898 
+
9899  Viruses() = delete;
+
9900  Viruses(Agent<TSeq> & p) : dat(&p.viruses), n_viruses(&p.n_viruses) {};
+
9901 
+
9902  typename std::vector< VirusPtr<TSeq> >::iterator begin();
+
9903  typename std::vector< VirusPtr<TSeq> >::iterator end();
+
9904 
+
9905  VirusPtr<TSeq> & operator()(size_t i);
+
9906  VirusPtr<TSeq> & operator[](size_t i);
+
9907 
+
9908  size_t size() const noexcept;
9909 
-
9910  if (i >= *n_viruses)
-
9911  throw std::range_error("Virus index out of range.");
-
9912 
-
9913  return dat->operator[](i);
-
9914 
-
9915 }
-
9916 
-
9917 template<typename TSeq>
-
9918 inline VirusPtr<TSeq> & Viruses<TSeq>::operator[](size_t i)
-
9919 {
-
9920 
-
9921  return dat->operator[](i);
-
9922 
-
9923 }
-
9924 
-
9925 template<typename TSeq>
-
9926 inline size_t Viruses<TSeq>::size() const noexcept
-
9927 {
-
9928  return *n_viruses;
-
9929 }
-
9930 
-
9931 template<typename TSeq>
-
9932 inline void Viruses<TSeq>::print() const noexcept
-
9933 {
-
9934 
-
9935  if (*n_viruses == 0u)
-
9936  {
-
9937  printf_epiworld("List of viruses (none)\n");
-
9938  return;
-
9939  }
-
9940 
-
9941  printf_epiworld("List of viruses (%i): ", *n_viruses);
+
9910  void print() const noexcept;
+
9911 
+
9912 };
+
9913 
+
9914 template<typename TSeq>
+
9915 inline typename std::vector< VirusPtr<TSeq> >::iterator Viruses<TSeq>::begin()
+
9916 {
+
9917 
+
9918  if (*n_viruses == 0u)
+
9919  return dat->end();
+
9920 
+
9921  return dat->begin();
+
9922 }
+
9923 
+
9924 template<typename TSeq>
+
9925 inline typename std::vector< VirusPtr<TSeq> >::iterator Viruses<TSeq>::end()
+
9926 {
+
9927 
+
9928  #ifdef EPI_DEBUG
+
9929  if (dat->size() < *n_viruses)
+
9930  throw EPI_DEBUG_ERROR(std::logic_error, "Viruses:: The end of the virus is out of range");
+
9931  #endif
+
9932 
+
9933  return begin() + *n_viruses;
+
9934 }
+
9935 
+
9936 template<typename TSeq>
+
9937 inline VirusPtr<TSeq> & Viruses<TSeq>::operator()(size_t i)
+
9938 {
+
9939 
+
9940  if (i >= *n_viruses)
+
9941  throw std::range_error("Virus index out of range.");
9942 
-
9943  // Printing the name of each virus separated by a comma
-
9944  for (size_t i = 0u; i < *n_viruses; ++i)
-
9945  {
-
9946  if (i == *n_viruses - 1u)
-
9947  {
-
9948  printf_epiworld("%s", dat->operator[](i)->get_name().c_str());
-
9949  } else
-
9950  {
-
9951  printf_epiworld("%s, ", dat->operator[](i)->get_name().c_str());
-
9952  }
-
9953  }
-
9954 
-
9955  printf_epiworld("\n");
-
9956 
-
9957 }
-
9958 
-
9964 template<typename TSeq>
-
9965 class Viruses_const {
-
9966  friend class Virus<TSeq>;
-
9967  friend class Agent<TSeq>;
-
9968 private:
-
9969  const std::vector< VirusPtr<TSeq> > * dat;
-
9970  const epiworld_fast_uint * n_viruses;
-
9971 
-
9972 public:
-
9973 
-
9974  Viruses_const() = delete;
-
9975  Viruses_const(const Agent<TSeq> & p) : dat(&p.viruses), n_viruses(&p.n_viruses) {};
-
9976 
-
9977  typename std::vector< VirusPtr<TSeq> >::const_iterator begin() const;
-
9978  typename std::vector< VirusPtr<TSeq> >::const_iterator end() const;
-
9979 
-
9980  const VirusPtr<TSeq> & operator()(size_t i);
-
9981  const VirusPtr<TSeq> & operator[](size_t i);
-
9982 
-
9983  size_t size() const noexcept;
-
9984 
-
9985  void print() const noexcept;
+
9943  return dat->operator[](i);
+
9944 
+
9945 }
+
9946 
+
9947 template<typename TSeq>
+
9948 inline VirusPtr<TSeq> & Viruses<TSeq>::operator[](size_t i)
+
9949 {
+
9950 
+
9951  return dat->operator[](i);
+
9952 
+
9953 }
+
9954 
+
9955 template<typename TSeq>
+
9956 inline size_t Viruses<TSeq>::size() const noexcept
+
9957 {
+
9958  return *n_viruses;
+
9959 }
+
9960 
+
9961 template<typename TSeq>
+
9962 inline void Viruses<TSeq>::print() const noexcept
+
9963 {
+
9964 
+
9965  if (*n_viruses == 0u)
+
9966  {
+
9967  printf_epiworld("List of viruses (none)\n");
+
9968  return;
+
9969  }
+
9970 
+
9971  printf_epiworld("List of viruses (%i): ", *n_viruses);
+
9972 
+
9973  // Printing the name of each virus separated by a comma
+
9974  for (size_t i = 0u; i < *n_viruses; ++i)
+
9975  {
+
9976  if (i == *n_viruses - 1u)
+
9977  {
+
9978  printf_epiworld("%s", dat->operator[](i)->get_name().c_str());
+
9979  } else
+
9980  {
+
9981  printf_epiworld("%s, ", dat->operator[](i)->get_name().c_str());
+
9982  }
+
9983  }
+
9984 
+
9985  printf_epiworld("\n");
9986 
-
9987 };
+
9987 }
9988 
-
9989 template<typename TSeq>
-
9990 inline typename std::vector< VirusPtr<TSeq> >::const_iterator Viruses_const<TSeq>::begin() const {
-
9991 
-
9992  if (*n_viruses == 0u)
-
9993  return dat->end();
-
9994 
-
9995  return dat->begin();
-
9996 }
-
9997 
-
9998 template<typename TSeq>
-
9999 inline typename std::vector< VirusPtr<TSeq> >::const_iterator Viruses_const<TSeq>::end() const {
-
10000 
-
10001  #ifdef EPI_DEBUG
-
10002  if (dat->size() < *n_viruses)
-
10003  throw EPI_DEBUG_ERROR(std::logic_error, "Viruses_const:: The end of the virus is out of range");
-
10004  #endif
-
10005  return begin() + *n_viruses;
-
10006 }
-
10007 
-
10008 template<typename TSeq>
-
10009 inline const VirusPtr<TSeq> & Viruses_const<TSeq>::operator()(size_t i)
-
10010 {
-
10011 
-
10012  if (i >= *n_viruses)
-
10013  throw std::range_error("Virus index out of range.");
+
9994 template<typename TSeq>
+
9995 class Viruses_const {
+
9996  friend class Virus<TSeq>;
+
9997  friend class Agent<TSeq>;
+
9998 private:
+
9999  const std::vector< VirusPtr<TSeq> > * dat;
+
10000  const epiworld_fast_uint * n_viruses;
+
10001 
+
10002 public:
+
10003 
+
10004  Viruses_const() = delete;
+
10005  Viruses_const(const Agent<TSeq> & p) : dat(&p.viruses), n_viruses(&p.n_viruses) {};
+
10006 
+
10007  typename std::vector< VirusPtr<TSeq> >::const_iterator begin() const;
+
10008  typename std::vector< VirusPtr<TSeq> >::const_iterator end() const;
+
10009 
+
10010  const VirusPtr<TSeq> & operator()(size_t i);
+
10011  const VirusPtr<TSeq> & operator[](size_t i);
+
10012 
+
10013  size_t size() const noexcept;
10014 
-
10015  return dat->operator[](i);
+
10015  void print() const noexcept;
10016 
-
10017 }
+
10017 };
10018 
10019 template<typename TSeq>
-
10020 inline const VirusPtr<TSeq> & Viruses_const<TSeq>::operator[](size_t i)
-
10021 {
-
10022 
-
10023  return dat->operator[](i);
-
10024 
-
10025 }
-
10026 
-
10027 template<typename TSeq>
-
10028 inline size_t Viruses_const<TSeq>::size() const noexcept
-
10029 {
-
10030  return *n_viruses;
-
10031 }
-
10032 
-
10033 template<typename TSeq>
-
10034 inline void Viruses_const<TSeq>::print() const noexcept
-
10035 {
-
10036 
-
10037  if (*n_viruses == 0u)
-
10038  {
-
10039  printf_epiworld("List of viruses (none)\n");
-
10040  return;
-
10041  }
-
10042 
-
10043  printf_epiworld("List of viruses (%i): ", *n_viruses);
+
10020 inline typename std::vector< VirusPtr<TSeq> >::const_iterator Viruses_const<TSeq>::begin() const {
+
10021 
+
10022  if (*n_viruses == 0u)
+
10023  return dat->end();
+
10024 
+
10025  return dat->begin();
+
10026 }
+
10027 
+
10028 template<typename TSeq>
+
10029 inline typename std::vector< VirusPtr<TSeq> >::const_iterator Viruses_const<TSeq>::end() const {
+
10030 
+
10031  #ifdef EPI_DEBUG
+
10032  if (dat->size() < *n_viruses)
+
10033  throw EPI_DEBUG_ERROR(std::logic_error, "Viruses_const:: The end of the virus is out of range");
+
10034  #endif
+
10035  return begin() + *n_viruses;
+
10036 }
+
10037 
+
10038 template<typename TSeq>
+
10039 inline const VirusPtr<TSeq> & Viruses_const<TSeq>::operator()(size_t i)
+
10040 {
+
10041 
+
10042  if (i >= *n_viruses)
+
10043  throw std::range_error("Virus index out of range.");
10044 
-
10045  // Printing the name of each virus separated by a comma
-
10046  for (size_t i = 0u; i < *n_viruses; ++i)
-
10047  {
-
10048  if (i == *n_viruses - 1u)
-
10049  {
-
10050  printf_epiworld("%s", dat->operator[](i)->get_name().c_str());
-
10051  } else
-
10052  {
-
10053  printf_epiworld("%s, ", dat->operator[](i)->get_name().c_str());
-
10054  }
-
10055  }
-
10056 
-
10057  printf_epiworld("\n");
-
10058 
-
10059 }
-
10060 
-
10061 
-
10062 #endif
-
10063 /*//////////////////////////////////////////////////////////////////////////////
-
10065 
-
10066  End of -include/epiworld/viruses-bones.hpp-
-
10067 
-
10070 
-
10071 
+
10045  return dat->operator[](i);
+
10046 
+
10047 }
+
10048 
+
10049 template<typename TSeq>
+
10050 inline const VirusPtr<TSeq> & Viruses_const<TSeq>::operator[](size_t i)
+
10051 {
+
10052 
+
10053  return dat->operator[](i);
+
10054 
+
10055 }
+
10056 
+
10057 template<typename TSeq>
+
10058 inline size_t Viruses_const<TSeq>::size() const noexcept
+
10059 {
+
10060  return *n_viruses;
+
10061 }
+
10062 
+
10063 template<typename TSeq>
+
10064 inline void Viruses_const<TSeq>::print() const noexcept
+
10065 {
+
10066 
+
10067  if (*n_viruses == 0u)
+
10068  {
+
10069  printf_epiworld("List of viruses (none)\n");
+
10070  return;
+
10071  }
10072 
-
10073 /*//////////////////////////////////////////////////////////////////////////////
-
10075 
-
10076  Start of -include/epiworld/virus-bones.hpp-
-
10077 
-
10080 
-
10081 
-
10082 #ifndef EPIWORLD_VIRUS_HPP
-
10083 #define EPIWORLD_VIRUS_HPP
-
10084 
-
10085 template<typename TSeq>
-
10086 class Agent;
-
10087 
-
10088 template<typename TSeq>
-
10089 class Virus;
+
10073  printf_epiworld("List of viruses (%i): ", *n_viruses);
+
10074 
+
10075  // Printing the name of each virus separated by a comma
+
10076  for (size_t i = 0u; i < *n_viruses; ++i)
+
10077  {
+
10078  if (i == *n_viruses - 1u)
+
10079  {
+
10080  printf_epiworld("%s", dat->operator[](i)->get_name().c_str());
+
10081  } else
+
10082  {
+
10083  printf_epiworld("%s, ", dat->operator[](i)->get_name().c_str());
+
10084  }
+
10085  }
+
10086 
+
10087  printf_epiworld("\n");
+
10088 
+
10089 }
10090 
-
10091 template<typename TSeq>
-
10092 class Model;
-
10093 
-
10104 template<typename TSeq>
-
10105 class Virus {
-
10106  friend class Agent<TSeq>;
-
10107  friend class Model<TSeq>;
-
10108  friend class DataBase<TSeq>;
-
10109  friend void default_add_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
10110  friend void default_rm_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
10111 private:
-
10112 
-
10113  Agent<TSeq> * agent = nullptr;
+
10091 
+
10092 #endif
+
10093 /*//////////////////////////////////////////////////////////////////////////////
+
10095 
+
10096  End of -include/epiworld/viruses-bones.hpp-
+
10097 
+
10100 
+
10101 
+
10102 
+
10103 /*//////////////////////////////////////////////////////////////////////////////
+
10105 
+
10106  Start of -include/epiworld/virus-bones.hpp-
+
10107 
+
10110 
+
10111 
+
10112 #ifndef EPIWORLD_VIRUS_HPP
+
10113 #define EPIWORLD_VIRUS_HPP
10114 
-
10115  std::shared_ptr<TSeq> baseline_sequence = nullptr;
-
10116  std::shared_ptr<std::string> virus_name = nullptr;
-
10117  int date = -99;
-
10118  int id = -99;
-
10119  bool active = true;
-
10120  MutFun<TSeq> mutation_fun = nullptr;
-
10121  PostRecoveryFun<TSeq> post_recovery_fun = nullptr;
-
10122  VirusFun<TSeq> probability_of_infecting_fun = nullptr;
-
10123  VirusFun<TSeq> probability_of_recovery_fun = nullptr;
-
10124  VirusFun<TSeq> probability_of_death_fun = nullptr;
-
10125  VirusFun<TSeq> incubation_fun = nullptr;
-
10126 
-
10127  // Setup parameters
-
10128  std::vector< epiworld_double > data = {};
-
10129 
-
10130  epiworld_fast_int state_init = -99; ///< Change of state when added to agent.
-
10131  epiworld_fast_int state_post = -99; ///< Change of state when removed from agent.
-
10132  epiworld_fast_int state_removed = -99; ///< Change of state when agent is removed
-
10133 
-
10134  epiworld_fast_int queue_init = Queue<TSeq>::Everyone; ///< Change of state when added to agent.
-
10135  epiworld_fast_int queue_post = -Queue<TSeq>::Everyone; ///< Change of state when removed from agent.
-
10136  epiworld_fast_int queue_removed = -99; ///< Change of state when agent is removed
-
10137 
-
10138  // Information about how distribution works
-
10139  VirusToAgentFun<TSeq> dist_fun = nullptr;
-
10140 
-
10141 public:
-
10142  Virus(std::string name = "unknown virus");
-
10143 
-
10144  Virus(
-
10145  std::string name,
-
10146  epiworld_double prevalence,
-
10147  bool as_proportion
-
10148  );
-
10149 
-
10150  void mutate(Model<TSeq> * model);
-
10151  void set_mutation(MutFun<TSeq> fun);
-
10152 
-
10153  std::shared_ptr<TSeq> get_sequence();
-
10154  void set_sequence(TSeq sequence);
-
10155 
-
10156  Agent<TSeq> * get_agent();
-
10157  void set_agent(Agent<TSeq> * p);
-
10158 
-
10159  void set_date(int d);
-
10160  int get_date() const;
-
10161 
-
10162  void set_id(int idx);
-
10163  int get_id() const;
-
10164 
-
10174  epiworld_double get_prob_infecting(Model<TSeq> * model);
-
10175  epiworld_double get_prob_recovery(Model<TSeq> * model);
-
10176  epiworld_double get_prob_death(Model<TSeq> * model);
-
10177  epiworld_double get_incubation(Model<TSeq> * model);
-
10178 
-
10179  void post_recovery(Model<TSeq> * model);
-
10180  void set_post_recovery(PostRecoveryFun<TSeq> fun);
-
10181  void set_post_immunity(epiworld_double prob);
-
10182  void set_post_immunity(epiworld_double * prob);
-
10183 
-
10184  void set_prob_infecting_fun(VirusFun<TSeq> fun);
-
10185  void set_prob_recovery_fun(VirusFun<TSeq> fun);
-
10186  void set_prob_death_fun(VirusFun<TSeq> fun);
-
10187  void set_incubation_fun(VirusFun<TSeq> fun);
+
10115 template<typename TSeq>
+
10116 class Agent;
+
10117 
+
10118 template<typename TSeq>
+
10119 class Virus;
+
10120 
+
10121 template<typename TSeq>
+
10122 class Model;
+
10123 
+
10134 template<typename TSeq>
+
10135 class Virus {
+
10136  friend class Agent<TSeq>;
+
10137  friend class Model<TSeq>;
+
10138  friend class DataBase<TSeq>;
+
10139  friend void default_add_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
10140  friend void default_rm_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
10141 private:
+
10142 
+
10143  Agent<TSeq> * agent = nullptr;
+
10144 
+
10145  std::shared_ptr<TSeq> baseline_sequence = nullptr;
+
10146  std::shared_ptr<std::string> virus_name = nullptr;
+
10147  int date = -99;
+
10148  int id = -99;
+
10149  bool active = true;
+
10150  MutFun<TSeq> mutation_fun = nullptr;
+
10151  PostRecoveryFun<TSeq> post_recovery_fun = nullptr;
+
10152  VirusFun<TSeq> probability_of_infecting_fun = nullptr;
+
10153  VirusFun<TSeq> probability_of_recovery_fun = nullptr;
+
10154  VirusFun<TSeq> probability_of_death_fun = nullptr;
+
10155  VirusFun<TSeq> incubation_fun = nullptr;
+
10156 
+
10157  // Setup parameters
+
10158  std::vector< epiworld_double > data = {};
+
10159 
+
10160  epiworld_fast_int state_init = -99; ///< Change of state when added to agent.
+
10161  epiworld_fast_int state_post = -99; ///< Change of state when removed from agent.
+
10162  epiworld_fast_int state_removed = -99; ///< Change of state when agent is removed
+
10163 
+
10164  epiworld_fast_int queue_init = Queue<TSeq>::Everyone; ///< Change of state when added to agent.
+
10165  epiworld_fast_int queue_post = -Queue<TSeq>::Everyone; ///< Change of state when removed from agent.
+
10166  epiworld_fast_int queue_removed = -99; ///< Change of state when agent is removed
+
10167 
+
10168  // Information about how distribution works
+
10169  VirusToAgentFun<TSeq> dist_fun = nullptr;
+
10170 
+
10171 public:
+
10172  Virus(std::string name = "unknown virus");
+
10173 
+
10174  Virus(
+
10175  std::string name,
+
10176  epiworld_double prevalence,
+
10177  bool as_proportion
+
10178  );
+
10179 
+
10180  void mutate(Model<TSeq> * model);
+
10181  void set_mutation(MutFun<TSeq> fun);
+
10182 
+
10183  std::shared_ptr<TSeq> get_sequence();
+
10184  void set_sequence(TSeq sequence);
+
10185 
+
10186  Agent<TSeq> * get_agent();
+
10187  void set_agent(Agent<TSeq> * p);
10188 
-
10189  void set_prob_infecting(const epiworld_double * prob);
-
10190  void set_prob_recovery(const epiworld_double * prob);
-
10191  void set_prob_death(const epiworld_double * prob);
-
10192  void set_incubation(const epiworld_double * prob);
-
10193 
-
10194  void set_prob_infecting(epiworld_double prob);
-
10195  void set_prob_recovery(epiworld_double prob);
-
10196  void set_prob_death(epiworld_double prob);
-
10197  void set_incubation(epiworld_double prob);
-
10199 
-
10200 
-
10201  void set_name(std::string name);
-
10202  std::string get_name() const;
-
10203 
-
10204  std::vector< epiworld_double > & get_data();
-
10205 
-
10219  void set_state(
-
10220  epiworld_fast_int init,
-
10221  epiworld_fast_int end,
-
10222  epiworld_fast_int removed = -99
-
10223  );
-
10224 
-
10225  void set_queue(
-
10226  epiworld_fast_int init,
-
10227  epiworld_fast_int end,
-
10228  epiworld_fast_int removed = -99
-
10229  );
+
10189  void set_date(int d);
+
10190  int get_date() const;
+
10191 
+
10192  void set_id(int idx);
+
10193  int get_id() const;
+
10194 
+
10204  epiworld_double get_prob_infecting(Model<TSeq> * model);
+
10205  epiworld_double get_prob_recovery(Model<TSeq> * model);
+
10206  epiworld_double get_prob_death(Model<TSeq> * model);
+
10207  epiworld_double get_incubation(Model<TSeq> * model);
+
10208 
+
10209  void post_recovery(Model<TSeq> * model);
+
10210  void set_post_recovery(PostRecoveryFun<TSeq> fun);
+
10211  void set_post_immunity(epiworld_double prob);
+
10212  void set_post_immunity(epiworld_double * prob);
+
10213 
+
10214  void set_prob_infecting_fun(VirusFun<TSeq> fun);
+
10215  void set_prob_recovery_fun(VirusFun<TSeq> fun);
+
10216  void set_prob_death_fun(VirusFun<TSeq> fun);
+
10217  void set_incubation_fun(VirusFun<TSeq> fun);
+
10218 
+
10219  void set_prob_infecting(const epiworld_double * prob);
+
10220  void set_prob_recovery(const epiworld_double * prob);
+
10221  void set_prob_death(const epiworld_double * prob);
+
10222  void set_incubation(const epiworld_double * prob);
+
10223 
+
10224  void set_prob_infecting(epiworld_double prob);
+
10225  void set_prob_recovery(epiworld_double prob);
+
10226  void set_prob_death(epiworld_double prob);
+
10227  void set_incubation(epiworld_double prob);
+
10229 
10230 
-
10231  void get_state(
-
10232  epiworld_fast_int * init,
-
10233  epiworld_fast_int * end,
-
10234  epiworld_fast_int * removed = nullptr
-
10235  );
-
10236 
-
10237  void get_queue(
-
10238  epiworld_fast_int * init,
-
10239  epiworld_fast_int * end,
-
10240  epiworld_fast_int * removed = nullptr
-
10241  );
-
10243 
-
10244  bool operator==(const Virus<TSeq> & other) const;
-
10245  bool operator!=(const Virus<TSeq> & other) const {return !operator==(other);};
-
10246 
-
10247  void print() const;
-
10248 
-
10253  void distribute(Model<TSeq> * model);
-
10254  void set_distribution(VirusToAgentFun<TSeq> fun);
-
10256 
-
10257 
-
10258 };
-
10259 
-
10260 #endif
-
10261 /*//////////////////////////////////////////////////////////////////////////////
-
10263 
-
10264  End of -include/epiworld/virus-bones.hpp-
-
10265 
-
10268 
-
10269 
-
10270 /*//////////////////////////////////////////////////////////////////////////////
-
10272 
-
10273  Start of -include/epiworld/virus-distribute-meat.hpp-
-
10274 
-
10277 
+
10231  void set_name(std::string name);
+
10232  std::string get_name() const;
+
10233 
+
10234  std::vector< epiworld_double > & get_data();
+
10235 
+
10249  void set_state(
+
10250  epiworld_fast_int init,
+
10251  epiworld_fast_int end,
+
10252  epiworld_fast_int removed = -99
+
10253  );
+
10254 
+
10255  void set_queue(
+
10256  epiworld_fast_int init,
+
10257  epiworld_fast_int end,
+
10258  epiworld_fast_int removed = -99
+
10259  );
+
10260 
+
10261  void get_state(
+
10262  epiworld_fast_int * init,
+
10263  epiworld_fast_int * end,
+
10264  epiworld_fast_int * removed = nullptr
+
10265  );
+
10266 
+
10267  void get_queue(
+
10268  epiworld_fast_int * init,
+
10269  epiworld_fast_int * end,
+
10270  epiworld_fast_int * removed = nullptr
+
10271  );
+
10273 
+
10274  bool operator==(const Virus<TSeq> & other) const;
+
10275  bool operator!=(const Virus<TSeq> & other) const {return !operator==(other);};
+
10276 
+
10277  void print() const;
10278 
-
10279 #ifndef EPIWORLD_VIRUS_DISTRIBUTE_MEAT_HPP
-
10280 #define EPIWORLD_VIRUS_DISTRIBUTE_MEAT_HPP
-
10281 
-
10294 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
10295 inline VirusToAgentFun<TSeq> distribute_virus_to_set(
-
10296  std::vector< size_t > agents_ids
-
10297 ) {
+
10283  void distribute(Model<TSeq> * model);
+
10284  void set_distribution(VirusToAgentFun<TSeq> fun);
+
10286 
+
10287 
+
10288 };
+
10289 
+
10290 #endif
+
10291 /*//////////////////////////////////////////////////////////////////////////////
+
10293 
+
10294  End of -include/epiworld/virus-bones.hpp-
+
10295 
10298 
-
10299  return [agents_ids](
-
10300  Virus<TSeq> & virus, Model<TSeq> * model
-
10301  ) -> void
-
10302  {
-
10303  // Adding action
-
10304  for (auto i: agents_ids)
-
10305  {
-
10306  model->get_agent(i).set_virus(
-
10307  virus,
-
10308  const_cast<Model<TSeq> * >(model)
-
10309  );
-
10310  }
-
10311  };
-
10312 
-
10313 }
-
10314 
-
10325 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
10326 inline VirusToAgentFun<TSeq> distribute_virus_randomly(
-
10327  epiworld_double prevalence,
-
10328  bool prevalence_as_proportion = true
-
10329 ) {
-
10330 
-
10331  return [prevalence,prevalence_as_proportion](
-
10332  Virus<TSeq> & virus, Model<TSeq> * model
-
10333  ) -> void
-
10334  {
-
10335 
-
10336  // Figuring out how what agents are available
-
10337  std::vector< size_t > idx;
-
10338  for (const auto & agent: model->get_agents())
-
10339  if (agent.get_virus() == nullptr)
-
10340  idx.push_back(agent.get_id());
-
10341 
-
10342  // Picking how many
-
10343  size_t n = model->size();
-
10344  int n_available = static_cast<int>(idx.size());
-
10345  int n_to_sample;
-
10346  if (prevalence_as_proportion)
-
10347  {
-
10348  n_to_sample = static_cast<int>(std::floor(prevalence * n));
-
10349 
-
10350  if (n_to_sample == static_cast<int>(n))
-
10351  n_to_sample--;
-
10352  }
-
10353  else
-
10354  {
-
10355  n_to_sample = static_cast<int>(prevalence);
-
10356  }
-
10357 
-
10358  if (n_to_sample > n_available)
-
10359  throw std::range_error(
-
10360  "There are only " + std::to_string(n_available) +
-
10361  " individuals with no virus in the population. " +
-
10362  "Cannot add the virus to " +
-
10363  std::to_string(n_to_sample)
-
10364  );
+
10299 
+
10300 /*//////////////////////////////////////////////////////////////////////////////
+
10302 
+
10303  Start of -include/epiworld/virus-distribute-meat.hpp-
+
10304 
+
10307 
+
10308 
+
10309 #ifndef EPIWORLD_VIRUS_DISTRIBUTE_MEAT_HPP
+
10310 #define EPIWORLD_VIRUS_DISTRIBUTE_MEAT_HPP
+
10311 
+
10324 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
10325 inline VirusToAgentFun<TSeq> distribute_virus_to_set(
+
10326  std::vector< size_t > agents_ids
+
10327 ) {
+
10328 
+
10329  return [agents_ids](
+
10330  Virus<TSeq> & virus, Model<TSeq> * model
+
10331  ) -> void
+
10332  {
+
10333  // Adding action
+
10334  for (auto i: agents_ids)
+
10335  {
+
10336  model->get_agent(i).set_virus(
+
10337  virus,
+
10338  const_cast<Model<TSeq> * >(model)
+
10339  );
+
10340  }
+
10341  };
+
10342 
+
10343 }
+
10344 
+
10355 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
10356 inline VirusToAgentFun<TSeq> distribute_virus_randomly(
+
10357  epiworld_double prevalence,
+
10358  bool prevalence_as_proportion = true
+
10359 ) {
+
10360 
+
10361  return [prevalence,prevalence_as_proportion](
+
10362  Virus<TSeq> & virus, Model<TSeq> * model
+
10363  ) -> void
+
10364  {
10365 
-
10366  auto & population = model->get_agents();
-
10367  for (int i = 0; i < n_to_sample; ++i)
-
10368  {
-
10369 
-
10370  int loc = static_cast<epiworld_fast_uint>(
-
10371  floor(model->runif() * (n_available--))
-
10372  );
-
10373 
-
10374  // Correcting for possible overflow
-
10375  if ((loc > 0) && (loc >= n_available))
-
10376  loc = n_available - 1;
-
10377 
-
10378  Agent<TSeq> & agent = population[idx[loc]];
-
10379 
-
10380  // Adding action
-
10381  agent.set_virus(
-
10382  virus,
-
10383  const_cast<Model<TSeq> * >(model)
-
10384  );
-
10385 
-
10386  // Adjusting sample
-
10387  std::swap(idx[loc], idx[n_available]);
-
10388 
-
10389  }
-
10390 
-
10391  };
-
10392 
-
10393 }
-
10394 
-
10395 #endif
-
10396 /*//////////////////////////////////////////////////////////////////////////////
-
10398 
-
10399  End of -include/epiworld/virus-distribute-meat.hpp-
-
10400 
+
10366  // Figuring out how what agents are available
+
10367  std::vector< size_t > idx;
+
10368  for (const auto & agent: model->get_agents())
+
10369  if (agent.get_virus() == nullptr)
+
10370  idx.push_back(agent.get_id());
+
10371 
+
10372  // Picking how many
+
10373  size_t n = model->size();
+
10374  int n_available = static_cast<int>(idx.size());
+
10375  int n_to_sample;
+
10376  if (prevalence_as_proportion)
+
10377  {
+
10378  n_to_sample = static_cast<int>(std::floor(prevalence * n));
+
10379 
+
10380  if (n_to_sample == static_cast<int>(n))
+
10381  n_to_sample--;
+
10382  }
+
10383  else
+
10384  {
+
10385  n_to_sample = static_cast<int>(prevalence);
+
10386  }
+
10387 
+
10388  if (n_to_sample > n_available)
+
10389  throw std::range_error(
+
10390  "There are only " + std::to_string(n_available) +
+
10391  " individuals with no virus in the population. " +
+
10392  "Cannot add the virus to " +
+
10393  std::to_string(n_to_sample)
+
10394  );
+
10395 
+
10396  auto & population = model->get_agents();
+
10397  for (int i = 0; i < n_to_sample; ++i)
+
10398  {
+
10399 
+
10400  int loc = static_cast<epiworld_fast_uint>(
+
10401  floor(model->runif() * (n_available--))
+
10402  );
10403 
-
10404 
-
10405 /*//////////////////////////////////////////////////////////////////////////////
+
10404  // Correcting for possible overflow
+
10405  if ((loc > 0) && (loc >= n_available))
+
10406  loc = n_available - 1;
10407 
-
10408  Start of -include/epiworld/virus-meat.hpp-
-
10409 
-
10412 
-
10413 
-
10414 #ifndef EPIWORLD_VIRUS_MEAT_HPP
-
10415 #define EPIWORLD_VIRUS_MEAT_HPP
-
10416 
-
10425 template<typename TSeq>
-
10426 inline VirusFun<TSeq> virus_fun_logit(
-
10427  std::vector< int > vars,
-
10428  std::vector< double > coefs,
-
10429  Model<TSeq> * model,
-
10430  bool logit = true
-
10431 ) {
-
10432 
-
10433  // Checking that there are features
-
10434  if (coefs.size() == 0u)
-
10435  throw std::logic_error(
-
10436  "The -coefs- argument should feature at least one element."
-
10437  );
-
10438 
-
10439  if (coefs.size() != vars.size())
-
10440  throw std::length_error(
-
10441  std::string("The length of -coef- (") +
-
10442  std::to_string(coefs.size()) +
-
10443  std::string(") and -vars- (") +
-
10444  std::to_string(vars.size()) +
-
10445  std::string(") should match. ")
-
10446  );
-
10447 
-
10448  // Checking that there are variables in the model
-
10449  if (model != nullptr)
-
10450  {
-
10451 
-
10452  size_t K = model->get_agents_data_ncols();
-
10453  for (const auto & var: vars)
-
10454  {
-
10455  if ((var >= static_cast<int>(K)) | (var < 0))
-
10456  throw std::range_error(
-
10457  std::string("The variable ") +
-
10458  std::to_string(var) +
-
10459  std::string(" is out of range.") +
-
10460  std::string(" The agents only feature ") +
-
10461  std::to_string(K) +
-
10462  std::string("variables (features).")
-
10463  );
-
10464  }
-
10465 
-
10466  }
-
10467 
-
10468  std::vector< epiworld_double > coefs_f;
-
10469  for (auto c: coefs)
-
10470  coefs_f.push_back(static_cast<epiworld_double>(c));
-
10471 
-
10472  VirusFun<TSeq> fun_infect = [coefs_f,vars](
-
10473  Agent<TSeq> * agent,
-
10474  Virus<TSeq> &,
-
10475  Model<TSeq> *
-
10476  ) -> epiworld_double {
+
10408  Agent<TSeq> & agent = population[idx[loc]];
+
10409 
+
10410  // Adding action
+
10411  agent.set_virus(
+
10412  virus,
+
10413  const_cast<Model<TSeq> * >(model)
+
10414  );
+
10415 
+
10416  // Adjusting sample
+
10417  std::swap(idx[loc], idx[n_available]);
+
10418 
+
10419  }
+
10420 
+
10421  };
+
10422 
+
10423 }
+
10424 
+
10425 #endif
+
10426 /*//////////////////////////////////////////////////////////////////////////////
+
10428 
+
10429  End of -include/epiworld/virus-distribute-meat.hpp-
+
10430 
+
10433 
+
10434 
+
10435 /*//////////////////////////////////////////////////////////////////////////////
+
10437 
+
10438  Start of -include/epiworld/virus-meat.hpp-
+
10439 
+
10442 
+
10443 
+
10444 #ifndef EPIWORLD_VIRUS_MEAT_HPP
+
10445 #define EPIWORLD_VIRUS_MEAT_HPP
+
10446 
+
10455 template<typename TSeq>
+
10456 inline VirusFun<TSeq> virus_fun_logit(
+
10457  std::vector< int > vars,
+
10458  std::vector< double > coefs,
+
10459  Model<TSeq> * model,
+
10460  bool logit = true
+
10461 ) {
+
10462 
+
10463  // Checking that there are features
+
10464  if (coefs.size() == 0u)
+
10465  throw std::logic_error(
+
10466  "The -coefs- argument should feature at least one element."
+
10467  );
+
10468 
+
10469  if (coefs.size() != vars.size())
+
10470  throw std::length_error(
+
10471  std::string("The length of -coef- (") +
+
10472  std::to_string(coefs.size()) +
+
10473  std::string(") and -vars- (") +
+
10474  std::to_string(vars.size()) +
+
10475  std::string(") should match. ")
+
10476  );
10477 
-
10478  size_t K = coefs_f.size();
-
10479  epiworld_double res = 0.0;
-
10480 
-
10481  #if defined(__OPENMP) || defined(_OPENMP)
-
10482  #pragma omp simd reduction(+:res)
-
10483  #endif
-
10484  for (size_t i = 0u; i < K; ++i)
-
10485  res += agent->operator[](vars.at(i)) * coefs_f.at(i);
-
10486 
-
10487  return 1.0/(1.0 + std::exp(-res));
-
10488 
-
10489  };
-
10490 
-
10491  return fun_infect;
-
10492 
-
10493 }
-
10494 
-
10495 template<typename TSeq>
-
10496 inline Virus<TSeq>::Virus(
-
10497  std::string name
-
10498  ) {
-
10499  set_name(name);
-
10500 }
+
10478  // Checking that there are variables in the model
+
10479  if (model != nullptr)
+
10480  {
+
10481 
+
10482  size_t K = model->get_agents_data_ncols();
+
10483  for (const auto & var: vars)
+
10484  {
+
10485  if ((var >= static_cast<int>(K)) | (var < 0))
+
10486  throw std::range_error(
+
10487  std::string("The variable ") +
+
10488  std::to_string(var) +
+
10489  std::string(" is out of range.") +
+
10490  std::string(" The agents only feature ") +
+
10491  std::to_string(K) +
+
10492  std::string("variables (features).")
+
10493  );
+
10494  }
+
10495 
+
10496  }
+
10497 
+
10498  std::vector< epiworld_double > coefs_f;
+
10499  for (auto c: coefs)
+
10500  coefs_f.push_back(static_cast<epiworld_double>(c));
10501 
-
10502 template<typename TSeq>
-
10503 inline Virus<TSeq>::Virus(
-
10504  std::string name,
-
10505  epiworld_double prevalence,
-
10506  bool prevalence_as_proportion
-
10507  ) {
-
10508  set_name(name);
-
10509  set_distribution(
-
10510  distribute_virus_randomly<TSeq>(
-
10511  prevalence,
-
10512  prevalence_as_proportion
-
10513  )
-
10514  );
-
10515 }
+
10502  VirusFun<TSeq> fun_infect = [coefs_f,vars](
+
10503  Agent<TSeq> * agent,
+
10504  Virus<TSeq> &,
+
10505  Model<TSeq> *
+
10506  ) -> epiworld_double {
+
10507 
+
10508  size_t K = coefs_f.size();
+
10509  epiworld_double res = 0.0;
+
10510 
+
10511  #if defined(__OPENMP) || defined(_OPENMP)
+
10512  #pragma omp simd reduction(+:res)
+
10513  #endif
+
10514  for (size_t i = 0u; i < K; ++i)
+
10515  res += agent->operator[](vars.at(i)) * coefs_f.at(i);
10516 
-
10517 template<typename TSeq>
-
10518 inline void Virus<TSeq>::mutate(
-
10519  Model<TSeq> * model
-
10520 ) {
-
10521 
-
10522  if (mutation_fun)
-
10523  if (mutation_fun(agent, *this, model))
-
10524  model->get_db().record_virus(*this);
-
10525 
-
10526  return;
-
10527 
-
10528 }
-
10529 
-
10530 template<typename TSeq>
-
10531 inline void Virus<TSeq>::set_mutation(
-
10532  MutFun<TSeq> fun
-
10533 ) {
-
10534  mutation_fun = MutFun<TSeq>(fun);
-
10535 }
-
10536 
-
10537 template<typename TSeq>
-
10538 inline std::shared_ptr<TSeq> Virus<TSeq>::get_sequence()
-
10539 {
-
10540 
-
10541  return baseline_sequence;
-
10542 
-
10543 }
-
10544 
-
10545 template<typename TSeq>
-
10546 inline void Virus<TSeq>::set_sequence(TSeq sequence)
-
10547 {
-
10548 
-
10549  baseline_sequence = std::make_shared<TSeq>(sequence);
-
10550  return;
+
10517  return 1.0/(1.0 + std::exp(-res));
+
10518 
+
10519  };
+
10520 
+
10521  return fun_infect;
+
10522 
+
10523 }
+
10524 
+
10525 template<typename TSeq>
+
10526 inline Virus<TSeq>::Virus(
+
10527  std::string name
+
10528  ) {
+
10529  set_name(name);
+
10530 }
+
10531 
+
10532 template<typename TSeq>
+
10533 inline Virus<TSeq>::Virus(
+
10534  std::string name,
+
10535  epiworld_double prevalence,
+
10536  bool prevalence_as_proportion
+
10537  ) {
+
10538  set_name(name);
+
10539  set_distribution(
+
10540  distribute_virus_randomly<TSeq>(
+
10541  prevalence,
+
10542  prevalence_as_proportion
+
10543  )
+
10544  );
+
10545 }
+
10546 
+
10547 template<typename TSeq>
+
10548 inline void Virus<TSeq>::mutate(
+
10549  Model<TSeq> * model
+
10550 ) {
10551 
-
10552 }
-
10553 
-
10554 template<typename TSeq>
-
10555 inline Agent<TSeq> * Virus<TSeq>::get_agent()
-
10556 {
-
10557 
-
10558  return agent;
+
10552  if (mutation_fun)
+
10553  if (mutation_fun(agent, *this, model))
+
10554  model->get_db().record_virus(*this);
+
10555 
+
10556  return;
+
10557 
+
10558 }
10559 
-
10560 }
-
10561 
-
10562 template<typename TSeq>
-
10563 inline void Virus<TSeq>::set_agent(Agent<TSeq> * p)
-
10564 {
-
10565  agent = p;
-
10566 }
-
10567 
-
10568 template<typename TSeq>
-
10569 inline void Virus<TSeq>::set_id(int idx)
-
10570 {
-
10571 
-
10572  id = idx;
-
10573  return;
+
10560 template<typename TSeq>
+
10561 inline void Virus<TSeq>::set_mutation(
+
10562  MutFun<TSeq> fun
+
10563 ) {
+
10564  mutation_fun = MutFun<TSeq>(fun);
+
10565 }
+
10566 
+
10567 template<typename TSeq>
+
10568 inline std::shared_ptr<TSeq> Virus<TSeq>::get_sequence()
+
10569 {
+
10570 
+
10571  return baseline_sequence;
+
10572 
+
10573 }
10574 
-
10575 }
-
10576 
-
10577 template<typename TSeq>
-
10578 inline int Virus<TSeq>::get_id() const
-
10579 {
-
10580 
-
10581  return id;
-
10582 
-
10583 }
-
10584 
-
10585 template<typename TSeq>
-
10586 inline void Virus<TSeq>::set_date(int d)
-
10587 {
-
10588 
-
10589  date = d;
-
10590  return;
+
10575 template<typename TSeq>
+
10576 inline void Virus<TSeq>::set_sequence(TSeq sequence)
+
10577 {
+
10578 
+
10579  baseline_sequence = std::make_shared<TSeq>(sequence);
+
10580  return;
+
10581 
+
10582 }
+
10583 
+
10584 template<typename TSeq>
+
10585 inline Agent<TSeq> * Virus<TSeq>::get_agent()
+
10586 {
+
10587 
+
10588  return agent;
+
10589 
+
10590 }
10591 
-
10592 }
-
10593 
-
10594 template<typename TSeq>
-
10595 inline int Virus<TSeq>::get_date() const
-
10596 {
-
10597 
-
10598  return date;
-
10599 
-
10600 }
+
10592 template<typename TSeq>
+
10593 inline void Virus<TSeq>::set_agent(Agent<TSeq> * p)
+
10594 {
+
10595  agent = p;
+
10596 }
+
10597 
+
10598 template<typename TSeq>
+
10599 inline void Virus<TSeq>::set_id(int idx)
+
10600 {
10601 
-
10602 template<typename TSeq>
-
10603 inline epiworld_double Virus<TSeq>::get_prob_infecting(
-
10604  Model<TSeq> * model
-
10605 )
-
10606 {
-
10607 
-
10608  if (probability_of_infecting_fun)
-
10609  return probability_of_infecting_fun(agent, *this, model);
-
10610 
-
10611  return EPI_DEFAULT_VIRUS_PROB_INFECTION;
+
10602  id = idx;
+
10603  return;
+
10604 
+
10605 }
+
10606 
+
10607 template<typename TSeq>
+
10608 inline int Virus<TSeq>::get_id() const
+
10609 {
+
10610 
+
10611  return id;
10612 
10613 }
10614 
-
10615 
-
10616 
-
10617 template<typename TSeq>
-
10618 inline epiworld_double Virus<TSeq>::get_prob_recovery(
-
10619  Model<TSeq> * model
-
10620 )
-
10621 {
-
10622 
-
10623  if (probability_of_recovery_fun)
-
10624  return probability_of_recovery_fun(agent, *this, model);
-
10625 
-
10626  return EPI_DEFAULT_VIRUS_PROB_RECOVERY;
-
10627 
-
10628 }
-
10629 
-
10630 
+
10615 template<typename TSeq>
+
10616 inline void Virus<TSeq>::set_date(int d)
+
10617 {
+
10618 
+
10619  date = d;
+
10620  return;
+
10621 
+
10622 }
+
10623 
+
10624 template<typename TSeq>
+
10625 inline int Virus<TSeq>::get_date() const
+
10626 {
+
10627 
+
10628  return date;
+
10629 
+
10630 }
10631 
10632 template<typename TSeq>
-
10633 inline epiworld_double Virus<TSeq>::get_prob_death(
+
10633 inline epiworld_double Virus<TSeq>::get_prob_infecting(
10634  Model<TSeq> * model
10635 )
10636 {
10637 
-
10638  if (probability_of_death_fun)
-
10639  return probability_of_death_fun(agent, *this, model);
+
10638  if (probability_of_infecting_fun)
+
10639  return probability_of_infecting_fun(agent, *this, model);
10640 
-
10641  return EPI_DEFAULT_VIRUS_PROB_DEATH;
+
10641  return EPI_DEFAULT_VIRUS_PROB_INFECTION;
10642 
10643 }
10644 
-
10645 template<typename TSeq>
-
10646 inline epiworld_double Virus<TSeq>::get_incubation(
-
10647  Model<TSeq> * model
-
10648 )
-
10649 {
-
10650 
-
10651  if (incubation_fun)
-
10652  return incubation_fun(agent, *this, model);
-
10653 
-
10654  return EPI_DEFAULT_INCUBATION_DAYS;
-
10655 
-
10656 }
+
10645 
+
10646 
+
10647 template<typename TSeq>
+
10648 inline epiworld_double Virus<TSeq>::get_prob_recovery(
+
10649  Model<TSeq> * model
+
10650 )
+
10651 {
+
10652 
+
10653  if (probability_of_recovery_fun)
+
10654  return probability_of_recovery_fun(agent, *this, model);
+
10655 
+
10656  return EPI_DEFAULT_VIRUS_PROB_RECOVERY;
10657 
-
10658 template<typename TSeq>
-
10659 inline void Virus<TSeq>::set_prob_infecting_fun(VirusFun<TSeq> fun)
-
10660 {
-
10661  probability_of_infecting_fun = fun;
-
10662 }
-
10663 
-
10664 template<typename TSeq>
-
10665 inline void Virus<TSeq>::set_prob_recovery_fun(VirusFun<TSeq> fun)
+
10658 }
+
10659 
+
10660 
+
10661 
+
10662 template<typename TSeq>
+
10663 inline epiworld_double Virus<TSeq>::get_prob_death(
+
10664  Model<TSeq> * model
+
10665 )
10666 {
-
10667  probability_of_recovery_fun = fun;
-
10668 }
-
10669 
-
10670 template<typename TSeq>
-
10671 inline void Virus<TSeq>::set_prob_death_fun(VirusFun<TSeq> fun)
-
10672 {
-
10673  probability_of_death_fun = fun;
-
10674 }
-
10675 
-
10676 template<typename TSeq>
-
10677 inline void Virus<TSeq>::set_incubation_fun(VirusFun<TSeq> fun)
-
10678 {
-
10679  incubation_fun = fun;
-
10680 }
-
10681 
-
10682 template<typename TSeq>
-
10683 inline void Virus<TSeq>::set_prob_infecting(const epiworld_double * prob)
-
10684 {
-
10685  VirusFun<TSeq> tmpfun =
-
10686  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
-
10687  {
-
10688  return *prob;
-
10689  };
-
10690 
-
10691  probability_of_infecting_fun = tmpfun;
+
10667 
+
10668  if (probability_of_death_fun)
+
10669  return probability_of_death_fun(agent, *this, model);
+
10670 
+
10671  return EPI_DEFAULT_VIRUS_PROB_DEATH;
+
10672 
+
10673 }
+
10674 
+
10675 template<typename TSeq>
+
10676 inline epiworld_double Virus<TSeq>::get_incubation(
+
10677  Model<TSeq> * model
+
10678 )
+
10679 {
+
10680 
+
10681  if (incubation_fun)
+
10682  return incubation_fun(agent, *this, model);
+
10683 
+
10684  return EPI_DEFAULT_INCUBATION_DAYS;
+
10685 
+
10686 }
+
10687 
+
10688 template<typename TSeq>
+
10689 inline void Virus<TSeq>::set_prob_infecting_fun(VirusFun<TSeq> fun)
+
10690 {
+
10691  probability_of_infecting_fun = fun;
10692 }
10693 
10694 template<typename TSeq>
-
10695 inline void Virus<TSeq>::set_prob_recovery(const epiworld_double * prob)
+
10695 inline void Virus<TSeq>::set_prob_recovery_fun(VirusFun<TSeq> fun)
10696 {
-
10697  VirusFun<TSeq> tmpfun =
-
10698  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
-
10699  {
-
10700  return *prob;
-
10701  };
-
10702 
-
10703  probability_of_recovery_fun = tmpfun;
+
10697  probability_of_recovery_fun = fun;
+
10698 }
+
10699 
+
10700 template<typename TSeq>
+
10701 inline void Virus<TSeq>::set_prob_death_fun(VirusFun<TSeq> fun)
+
10702 {
+
10703  probability_of_death_fun = fun;
10704 }
10705 
10706 template<typename TSeq>
-
10707 inline void Virus<TSeq>::set_prob_death(const epiworld_double * prob)
+
10707 inline void Virus<TSeq>::set_incubation_fun(VirusFun<TSeq> fun)
10708 {
-
10709  VirusFun<TSeq> tmpfun =
-
10710  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
-
10711  {
-
10712  return *prob;
-
10713  };
-
10714 
-
10715  probability_of_death_fun = tmpfun;
-
10716 }
-
10717 
-
10718 template<typename TSeq>
-
10719 inline void Virus<TSeq>::set_incubation(const epiworld_double * prob)
-
10720 {
-
10721  VirusFun<TSeq> tmpfun =
-
10722  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
-
10723  {
-
10724  return *prob;
-
10725  };
-
10726 
-
10727  incubation_fun = tmpfun;
-
10728 }
-
10729 
-
10730 template<typename TSeq>
-
10731 inline void Virus<TSeq>::set_prob_infecting(epiworld_double prob)
-
10732 {
-
10733  VirusFun<TSeq> tmpfun =
-
10734  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
-
10735  {
-
10736  return prob;
-
10737  };
-
10738 
-
10739  probability_of_infecting_fun = tmpfun;
-
10740 }
-
10741 
-
10742 template<typename TSeq>
-
10743 inline void Virus<TSeq>::set_prob_recovery(epiworld_double prob)
-
10744 {
-
10745  VirusFun<TSeq> tmpfun =
-
10746  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
-
10747  {
-
10748  return prob;
-
10749  };
-
10750 
-
10751  probability_of_recovery_fun = tmpfun;
-
10752 }
-
10753 
-
10754 template<typename TSeq>
-
10755 inline void Virus<TSeq>::set_prob_death(epiworld_double prob)
-
10756 {
-
10757  VirusFun<TSeq> tmpfun =
-
10758  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
-
10759  {
-
10760  return prob;
-
10761  };
-
10762 
-
10763  probability_of_death_fun = tmpfun;
-
10764 }
-
10765 
-
10766 template<typename TSeq>
-
10767 inline void Virus<TSeq>::set_incubation(epiworld_double prob)
-
10768 {
-
10769  VirusFun<TSeq> tmpfun =
-
10770  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
-
10771  {
-
10772  return prob;
-
10773  };
-
10774 
-
10775  incubation_fun = tmpfun;
-
10776 }
-
10777 
-
10778 template<typename TSeq>
-
10779 inline void Virus<TSeq>::set_post_recovery(PostRecoveryFun<TSeq> fun)
-
10780 {
-
10781  if (post_recovery_fun)
-
10782  {
-
10783  printf_epiworld(
-
10784  "Warning: a PostRecoveryFun is alreay in place (overwriting)."
-
10785  );
-
10786  }
-
10787 
-
10788  post_recovery_fun = fun;
-
10789 }
-
10790 
-
10791 template<typename TSeq>
-
10792 inline void Virus<TSeq>::post_recovery(
-
10793  Model<TSeq> * model
-
10794 )
-
10795 {
-
10796 
-
10797  if (post_recovery_fun)
-
10798  post_recovery_fun(agent, *this, model);
-
10799 
-
10800  return;
-
10801 
-
10802 }
-
10803 
-
10804 template<typename TSeq>
-
10805 inline void Virus<TSeq>::set_post_immunity(
-
10806  epiworld_double prob
-
10807 )
-
10808 {
-
10809 
-
10810  if (post_recovery_fun)
-
10811  {
-
10812 
-
10813  std::string msg =
-
10814  std::string(
-
10815  "You cannot set post immunity when a post_recovery "
-
10816  ) +
-
10817  std::string(
-
10818  "function is already in place. Redesign the post_recovery function."
-
10819  );
+
10709  incubation_fun = fun;
+
10710 }
+
10711 
+
10712 template<typename TSeq>
+
10713 inline void Virus<TSeq>::set_prob_infecting(const epiworld_double * prob)
+
10714 {
+
10715  VirusFun<TSeq> tmpfun =
+
10716  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
+
10717  {
+
10718  return *prob;
+
10719  };
+
10720 
+
10721  probability_of_infecting_fun = tmpfun;
+
10722 }
+
10723 
+
10724 template<typename TSeq>
+
10725 inline void Virus<TSeq>::set_prob_recovery(const epiworld_double * prob)
+
10726 {
+
10727  VirusFun<TSeq> tmpfun =
+
10728  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
+
10729  {
+
10730  return *prob;
+
10731  };
+
10732 
+
10733  probability_of_recovery_fun = tmpfun;
+
10734 }
+
10735 
+
10736 template<typename TSeq>
+
10737 inline void Virus<TSeq>::set_prob_death(const epiworld_double * prob)
+
10738 {
+
10739  VirusFun<TSeq> tmpfun =
+
10740  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
+
10741  {
+
10742  return *prob;
+
10743  };
+
10744 
+
10745  probability_of_death_fun = tmpfun;
+
10746 }
+
10747 
+
10748 template<typename TSeq>
+
10749 inline void Virus<TSeq>::set_incubation(const epiworld_double * prob)
+
10750 {
+
10751  VirusFun<TSeq> tmpfun =
+
10752  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
+
10753  {
+
10754  return *prob;
+
10755  };
+
10756 
+
10757  incubation_fun = tmpfun;
+
10758 }
+
10759 
+
10760 template<typename TSeq>
+
10761 inline void Virus<TSeq>::set_prob_infecting(epiworld_double prob)
+
10762 {
+
10763  VirusFun<TSeq> tmpfun =
+
10764  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
+
10765  {
+
10766  return prob;
+
10767  };
+
10768 
+
10769  probability_of_infecting_fun = tmpfun;
+
10770 }
+
10771 
+
10772 template<typename TSeq>
+
10773 inline void Virus<TSeq>::set_prob_recovery(epiworld_double prob)
+
10774 {
+
10775  VirusFun<TSeq> tmpfun =
+
10776  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
+
10777  {
+
10778  return prob;
+
10779  };
+
10780 
+
10781  probability_of_recovery_fun = tmpfun;
+
10782 }
+
10783 
+
10784 template<typename TSeq>
+
10785 inline void Virus<TSeq>::set_prob_death(epiworld_double prob)
+
10786 {
+
10787  VirusFun<TSeq> tmpfun =
+
10788  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
+
10789  {
+
10790  return prob;
+
10791  };
+
10792 
+
10793  probability_of_death_fun = tmpfun;
+
10794 }
+
10795 
+
10796 template<typename TSeq>
+
10797 inline void Virus<TSeq>::set_incubation(epiworld_double prob)
+
10798 {
+
10799  VirusFun<TSeq> tmpfun =
+
10800  [prob](Agent<TSeq> *, Virus<TSeq> &, Model<TSeq> *)
+
10801  {
+
10802  return prob;
+
10803  };
+
10804 
+
10805  incubation_fun = tmpfun;
+
10806 }
+
10807 
+
10808 template<typename TSeq>
+
10809 inline void Virus<TSeq>::set_post_recovery(PostRecoveryFun<TSeq> fun)
+
10810 {
+
10811  if (post_recovery_fun)
+
10812  {
+
10813  printf_epiworld(
+
10814  "Warning: a PostRecoveryFun is alreay in place (overwriting)."
+
10815  );
+
10816  }
+
10817 
+
10818  post_recovery_fun = fun;
+
10819 }
10820 
-
10821  throw std::logic_error(msg);
-
10822 
-
10823  }
-
10824 
-
10825  // To make sure that we keep registering the virus
-
10826  ToolPtr<TSeq> __no_reinfect = std::make_shared<Tool<TSeq>>(
-
10827  "Immunity (" + *virus_name + ")"
-
10828  );
+
10821 template<typename TSeq>
+
10822 inline void Virus<TSeq>::post_recovery(
+
10823  Model<TSeq> * model
+
10824 )
+
10825 {
+
10826 
+
10827  if (post_recovery_fun)
+
10828  post_recovery_fun(agent, *this, model);
10829 
-
10830  __no_reinfect->set_susceptibility_reduction(prob);
-
10831  __no_reinfect->set_death_reduction(0.0);
-
10832  __no_reinfect->set_transmission_reduction(0.0);
-
10833  __no_reinfect->set_recovery_enhancer(0.0);
-
10834 
-
10835  PostRecoveryFun<TSeq> tmpfun =
-
10836  [__no_reinfect](
-
10837  Agent<TSeq> * p, Virus<TSeq> &, Model<TSeq> * m
-
10838  )
-
10839  {
-
10840 
-
10841  // Have we registered the tool?
-
10842  if (__no_reinfect->get_id() == -99)
-
10843  m->get_db().record_tool(*__no_reinfect);
-
10844 
-
10845  p->add_tool(__no_reinfect, m);
-
10846 
-
10847  return;
-
10848 
-
10849  };
+
10830  return;
+
10831 
+
10832 }
+
10833 
+
10834 template<typename TSeq>
+
10835 inline void Virus<TSeq>::set_post_immunity(
+
10836  epiworld_double prob
+
10837 )
+
10838 {
+
10839 
+
10840  if (post_recovery_fun)
+
10841  {
+
10842 
+
10843  std::string msg =
+
10844  std::string(
+
10845  "You cannot set post immunity when a post_recovery "
+
10846  ) +
+
10847  std::string(
+
10848  "function is already in place. Redesign the post_recovery function."
+
10849  );
10850 
-
10851  post_recovery_fun = tmpfun;
-
10852 
-
10853 }
+
10851  throw std::logic_error(msg);
+
10852 
+
10853  }
10854 
-
10855 template<typename TSeq>
-
10856 inline void Virus<TSeq>::set_post_immunity(
-
10857  epiworld_double * prob
-
10858 )
-
10859 {
-
10860 
-
10861  if (post_recovery_fun)
-
10862  {
-
10863 
-
10864  std::string msg =
-
10865  std::string(
-
10866  "You cannot set post immunity when a post_recovery "
-
10867  ) +
-
10868  std::string(
-
10869  "function is already in place. Redesign the post_recovery function."
-
10870  );
-
10871 
-
10872  throw std::logic_error(msg);
-
10873 
-
10874  }
-
10875 
-
10876  // To make sure that we keep registering the virus
-
10877  ToolPtr<TSeq> __no_reinfect = std::make_shared<Tool<TSeq>>(
-
10878  "Immunity (" + *virus_name + ")"
-
10879  );
+
10855  // To make sure that we keep registering the virus
+
10856  ToolPtr<TSeq> __no_reinfect = std::make_shared<Tool<TSeq>>(
+
10857  "Immunity (" + *virus_name + ")"
+
10858  );
+
10859 
+
10860  __no_reinfect->set_susceptibility_reduction(prob);
+
10861  __no_reinfect->set_death_reduction(0.0);
+
10862  __no_reinfect->set_transmission_reduction(0.0);
+
10863  __no_reinfect->set_recovery_enhancer(0.0);
+
10864 
+
10865  PostRecoveryFun<TSeq> tmpfun =
+
10866  [__no_reinfect](
+
10867  Agent<TSeq> * p, Virus<TSeq> &, Model<TSeq> * m
+
10868  )
+
10869  {
+
10870 
+
10871  // Have we registered the tool?
+
10872  if (__no_reinfect->get_id() == -99)
+
10873  m->get_db().record_tool(*__no_reinfect);
+
10874 
+
10875  p->add_tool(__no_reinfect, m);
+
10876 
+
10877  return;
+
10878 
+
10879  };
10880 
-
10881  __no_reinfect->set_susceptibility_reduction(prob);
-
10882  __no_reinfect->set_death_reduction(0.0);
-
10883  __no_reinfect->set_transmission_reduction(0.0);
-
10884  __no_reinfect->set_recovery_enhancer(0.0);
-
10885 
-
10886  PostRecoveryFun<TSeq> tmpfun =
-
10887  [__no_reinfect](Agent<TSeq> * p, Virus<TSeq> &, Model<TSeq> * m)
-
10888  {
-
10889 
-
10890  // Have we registered the tool?
-
10891  if (__no_reinfect->get_id() == -99)
-
10892  m->get_db().record_tool(*__no_reinfect);
+
10881  post_recovery_fun = tmpfun;
+
10882 
+
10883 }
+
10884 
+
10885 template<typename TSeq>
+
10886 inline void Virus<TSeq>::set_post_immunity(
+
10887  epiworld_double * prob
+
10888 )
+
10889 {
+
10890 
+
10891  if (post_recovery_fun)
+
10892  {
10893 
-
10894  p->add_tool(__no_reinfect, m);
-
10895 
-
10896  return;
-
10897 
-
10898  };
-
10899 
-
10900  post_recovery_fun = tmpfun;
+
10894  std::string msg =
+
10895  std::string(
+
10896  "You cannot set post immunity when a post_recovery "
+
10897  ) +
+
10898  std::string(
+
10899  "function is already in place. Redesign the post_recovery function."
+
10900  );
10901 
-
10902 }
+
10902  throw std::logic_error(msg);
10903 
-
10904 template<typename TSeq>
-
10905 inline void Virus<TSeq>::set_name(std::string name)
-
10906 {
-
10907 
-
10908  if (name == "")
-
10909  virus_name = nullptr;
-
10910  else
-
10911  virus_name = std::make_shared<std::string>(name);
-
10912 
-
10913 }
-
10914 
-
10915 template<typename TSeq>
-
10916 inline std::string Virus<TSeq>::get_name() const
-
10917 {
-
10918 
-
10919  if (virus_name)
-
10920  return *virus_name;
-
10921 
-
10922  return "unknown virus";
+
10904  }
+
10905 
+
10906  // To make sure that we keep registering the virus
+
10907  ToolPtr<TSeq> __no_reinfect = std::make_shared<Tool<TSeq>>(
+
10908  "Immunity (" + *virus_name + ")"
+
10909  );
+
10910 
+
10911  __no_reinfect->set_susceptibility_reduction(prob);
+
10912  __no_reinfect->set_death_reduction(0.0);
+
10913  __no_reinfect->set_transmission_reduction(0.0);
+
10914  __no_reinfect->set_recovery_enhancer(0.0);
+
10915 
+
10916  PostRecoveryFun<TSeq> tmpfun =
+
10917  [__no_reinfect](Agent<TSeq> * p, Virus<TSeq> &, Model<TSeq> * m)
+
10918  {
+
10919 
+
10920  // Have we registered the tool?
+
10921  if (__no_reinfect->get_id() == -99)
+
10922  m->get_db().record_tool(*__no_reinfect);
10923 
-
10924 }
+
10924  p->add_tool(__no_reinfect, m);
10925 
-
10926 template<typename TSeq>
-
10927 inline std::vector< epiworld_double > & Virus<TSeq>::get_data() {
-
10928  return data;
-
10929 }
-
10930 
-
10931 template<typename TSeq>
-
10932 inline void Virus<TSeq>::set_state(
-
10933  epiworld_fast_int init,
-
10934  epiworld_fast_int end,
-
10935  epiworld_fast_int removed
-
10936 )
-
10937 {
-
10938  state_init = init;
-
10939  state_post = end;
-
10940  state_removed = removed;
-
10941 }
+
10926  return;
+
10927 
+
10928  };
+
10929 
+
10930  post_recovery_fun = tmpfun;
+
10931 
+
10932 }
+
10933 
+
10934 template<typename TSeq>
+
10935 inline void Virus<TSeq>::set_name(std::string name)
+
10936 {
+
10937 
+
10938  if (name == "")
+
10939  virus_name = nullptr;
+
10940  else
+
10941  virus_name = std::make_shared<std::string>(name);
10942 
-
10943 template<typename TSeq>
-
10944 inline void Virus<TSeq>::set_queue(
-
10945  epiworld_fast_int init,
-
10946  epiworld_fast_int end,
-
10947  epiworld_fast_int removed
-
10948 )
-
10949 {
-
10950 
-
10951  queue_init = init;
-
10952  queue_post = end;
-
10953  queue_removed = removed;
-
10954 
-
10955 }
-
10956 
-
10957 template<typename TSeq>
-
10958 inline void Virus<TSeq>::get_state(
-
10959  epiworld_fast_int * init,
-
10960  epiworld_fast_int * end,
-
10961  epiworld_fast_int * removed
-
10962 )
-
10963 {
-
10964 
-
10965  if (init != nullptr)
-
10966  *init = state_init;
-
10967 
-
10968  if (end != nullptr)
-
10969  *end = state_post;
-
10970 
-
10971  if (removed != nullptr)
-
10972  *removed = state_removed;
-
10973 
-
10974 }
-
10975 
-
10976 template<typename TSeq>
-
10977 inline void Virus<TSeq>::get_queue(
-
10978  epiworld_fast_int * init,
-
10979  epiworld_fast_int * end,
-
10980  epiworld_fast_int * removed
-
10981 )
-
10982 {
-
10983 
-
10984  if (init != nullptr)
-
10985  *init = queue_init;
+
10943 }
+
10944 
+
10945 template<typename TSeq>
+
10946 inline std::string Virus<TSeq>::get_name() const
+
10947 {
+
10948 
+
10949  if (virus_name)
+
10950  return *virus_name;
+
10951 
+
10952  return "unknown virus";
+
10953 
+
10954 }
+
10955 
+
10956 template<typename TSeq>
+
10957 inline std::vector< epiworld_double > & Virus<TSeq>::get_data() {
+
10958  return data;
+
10959 }
+
10960 
+
10961 template<typename TSeq>
+
10962 inline void Virus<TSeq>::set_state(
+
10963  epiworld_fast_int init,
+
10964  epiworld_fast_int end,
+
10965  epiworld_fast_int removed
+
10966 )
+
10967 {
+
10968  state_init = init;
+
10969  state_post = end;
+
10970  state_removed = removed;
+
10971 }
+
10972 
+
10973 template<typename TSeq>
+
10974 inline void Virus<TSeq>::set_queue(
+
10975  epiworld_fast_int init,
+
10976  epiworld_fast_int end,
+
10977  epiworld_fast_int removed
+
10978 )
+
10979 {
+
10980 
+
10981  queue_init = init;
+
10982  queue_post = end;
+
10983  queue_removed = removed;
+
10984 
+
10985 }
10986 
-
10987  if (end != nullptr)
-
10988  *end = queue_post;
-
10989 
-
10990  if (removed != nullptr)
-
10991  *removed = queue_removed;
-
10992 
-
10993 }
+
10987 template<typename TSeq>
+
10988 inline void Virus<TSeq>::get_state(
+
10989  epiworld_fast_int * init,
+
10990  epiworld_fast_int * end,
+
10991  epiworld_fast_int * removed
+
10992 )
+
10993 {
10994 
-
10995 template<>
-
10996 inline bool Virus<std::vector<int>>::operator==(
-
10997  const Virus<std::vector<int>> & other
-
10998  ) const
-
10999 {
-
11000 
-
11001 
-
11002  EPI_DEBUG_FAIL_AT_TRUE(
-
11003  baseline_sequence->size() != other.baseline_sequence->size(),
-
11004  "Virus:: baseline_sequence don't match"
-
11005  )
-
11006 
-
11007  for (size_t i = 0u; i < baseline_sequence->size(); ++i)
-
11008  {
-
11009 
-
11010  EPI_DEBUG_FAIL_AT_TRUE(
-
11011  baseline_sequence->operator[](i) != other.baseline_sequence->operator[](i),
-
11012  "Virus:: baseline_sequence[i] don't match"
-
11013  )
-
11014 
-
11015  }
+
10995  if (init != nullptr)
+
10996  *init = state_init;
+
10997 
+
10998  if (end != nullptr)
+
10999  *end = state_post;
+
11000 
+
11001  if (removed != nullptr)
+
11002  *removed = state_removed;
+
11003 
+
11004 }
+
11005 
+
11006 template<typename TSeq>
+
11007 inline void Virus<TSeq>::get_queue(
+
11008  epiworld_fast_int * init,
+
11009  epiworld_fast_int * end,
+
11010  epiworld_fast_int * removed
+
11011 )
+
11012 {
+
11013 
+
11014  if (init != nullptr)
+
11015  *init = queue_init;
11016 
-
11017  EPI_DEBUG_FAIL_AT_TRUE(
-
11018  virus_name != other.virus_name,
-
11019  "Virus:: virus_name don't match"
-
11020  )
-
11021 
-
11022  EPI_DEBUG_FAIL_AT_TRUE(
-
11023  state_init != other.state_init,
-
11024  "Virus:: state_init don't match"
-
11025  )
-
11026 
-
11027  EPI_DEBUG_FAIL_AT_TRUE(
-
11028  state_post != other.state_post,
-
11029  "Virus:: state_post don't match"
-
11030  )
+
11017  if (end != nullptr)
+
11018  *end = queue_post;
+
11019 
+
11020  if (removed != nullptr)
+
11021  *removed = queue_removed;
+
11022 
+
11023 }
+
11024 
+
11025 template<>
+
11026 inline bool Virus<std::vector<int>>::operator==(
+
11027  const Virus<std::vector<int>> & other
+
11028  ) const
+
11029 {
+
11030 
11031 
11032  EPI_DEBUG_FAIL_AT_TRUE(
-
11033  state_removed != other.state_removed,
-
11034  "Virus:: state_removed don't match"
+
11033  baseline_sequence->size() != other.baseline_sequence->size(),
+
11034  "Virus:: baseline_sequence don't match"
11035  )
11036 
-
11037  EPI_DEBUG_FAIL_AT_TRUE(
-
11038  queue_init != other.queue_init,
-
11039  "Virus:: queue_init don't match"
-
11040  )
-
11041 
-
11042  EPI_DEBUG_FAIL_AT_TRUE(
-
11043  queue_post != other.queue_post,
-
11044  "Virus:: queue_post don't match"
-
11045  )
+
11037  for (size_t i = 0u; i < baseline_sequence->size(); ++i)
+
11038  {
+
11039 
+
11040  EPI_DEBUG_FAIL_AT_TRUE(
+
11041  baseline_sequence->operator[](i) != other.baseline_sequence->operator[](i),
+
11042  "Virus:: baseline_sequence[i] don't match"
+
11043  )
+
11044 
+
11045  }
11046 
11047  EPI_DEBUG_FAIL_AT_TRUE(
-
11048  queue_removed != other.queue_removed,
-
11049  "Virus:: queue_removed don't match"
+
11048  virus_name != other.virus_name,
+
11049  "Virus:: virus_name don't match"
11050  )
-
11051 
-
11052  return true;
-
11053 
-
11054 }
-
11055 
-
11056 template<typename TSeq>
-
11057 inline bool Virus<TSeq>::operator==(const Virus<TSeq> & other) const
-
11058 {
-
11059 
-
11060  EPI_DEBUG_FAIL_AT_TRUE(
-
11061  *baseline_sequence != *other.baseline_sequence,
-
11062  "Virus:: baseline_sequence don't match"
-
11063  )
-
11064 
-
11065  EPI_DEBUG_FAIL_AT_TRUE(
-
11066  virus_name != other.virus_name,
-
11067  "Virus:: virus_name don't match"
-
11068  )
-
11069 
-
11070  EPI_DEBUG_FAIL_AT_TRUE(
-
11071  state_init != other.state_init,
-
11072  "Virus:: state_init don't match"
-
11073  )
-
11074 
-
11075  EPI_DEBUG_FAIL_AT_TRUE(
-
11076  state_post != other.state_post,
-
11077  "Virus:: state_post don't match"
-
11078  )
-
11079 
-
11080  EPI_DEBUG_FAIL_AT_TRUE(
-
11081  state_removed != other.state_removed,
-
11082  "Virus:: state_removed don't match"
-
11083  )
-
11084 
-
11085  EPI_DEBUG_FAIL_AT_TRUE(
-
11086  queue_init != other.queue_init,
-
11087  "Virus:: queue_init don't match"
-
11088  )
-
11089 
+
11051 
+
11052  EPI_DEBUG_FAIL_AT_TRUE(
+
11053  state_init != other.state_init,
+
11054  "Virus:: state_init don't match"
+
11055  )
+
11056 
+
11057  EPI_DEBUG_FAIL_AT_TRUE(
+
11058  state_post != other.state_post,
+
11059  "Virus:: state_post don't match"
+
11060  )
+
11061 
+
11062  EPI_DEBUG_FAIL_AT_TRUE(
+
11063  state_removed != other.state_removed,
+
11064  "Virus:: state_removed don't match"
+
11065  )
+
11066 
+
11067  EPI_DEBUG_FAIL_AT_TRUE(
+
11068  queue_init != other.queue_init,
+
11069  "Virus:: queue_init don't match"
+
11070  )
+
11071 
+
11072  EPI_DEBUG_FAIL_AT_TRUE(
+
11073  queue_post != other.queue_post,
+
11074  "Virus:: queue_post don't match"
+
11075  )
+
11076 
+
11077  EPI_DEBUG_FAIL_AT_TRUE(
+
11078  queue_removed != other.queue_removed,
+
11079  "Virus:: queue_removed don't match"
+
11080  )
+
11081 
+
11082  return true;
+
11083 
+
11084 }
+
11085 
+
11086 template<typename TSeq>
+
11087 inline bool Virus<TSeq>::operator==(const Virus<TSeq> & other) const
+
11088 {
+
11089 
11090  EPI_DEBUG_FAIL_AT_TRUE(
-
11091  queue_post != other.queue_post,
-
11092  "Virus:: queue_post don't match"
+
11091  *baseline_sequence != *other.baseline_sequence,
+
11092  "Virus:: baseline_sequence don't match"
11093  )
11094 
11095  EPI_DEBUG_FAIL_AT_TRUE(
-
11096  queue_removed != other.queue_removed,
-
11097  "Virus:: queue_removed don't match"
+
11096  virus_name != other.virus_name,
+
11097  "Virus:: virus_name don't match"
11098  )
-
11099 
-
11100  return true;
-
11101 
-
11102 }
-
11103 
-
11104 template<typename TSeq>
-
11105 inline void Virus<TSeq>::print() const
-
11106 {
-
11107 
-
11108  printf_epiworld("Virus : %s\n", virus_name->c_str());
-
11109  printf_epiworld("Id : %s\n", (id < 0)? std::string("(empty)").c_str() : std::to_string(id).c_str());
-
11110  printf_epiworld("state_init : %i\n", static_cast<int>(state_init));
-
11111  printf_epiworld("state_post : %i\n", static_cast<int>(state_post));
-
11112  printf_epiworld("state_removed : %i\n", static_cast<int>(state_removed));
-
11113  printf_epiworld("queue_init : %i\n", static_cast<int>(queue_init));
-
11114  printf_epiworld("queue_post : %i\n", static_cast<int>(queue_post));
-
11115  printf_epiworld("queue_removed : %i\n", static_cast<int>(queue_removed));
-
11116 
-
11117 }
-
11118 
-
11119 template<typename TSeq>
-
11120 inline void Virus<TSeq>::distribute(Model<TSeq> * model)
-
11121 {
-
11122 
-
11123  if (dist_fun)
-
11124  {
-
11125 
-
11126  dist_fun(*this, model);
-
11127 
-
11128  }
+
11099 
+
11100  EPI_DEBUG_FAIL_AT_TRUE(
+
11101  state_init != other.state_init,
+
11102  "Virus:: state_init don't match"
+
11103  )
+
11104 
+
11105  EPI_DEBUG_FAIL_AT_TRUE(
+
11106  state_post != other.state_post,
+
11107  "Virus:: state_post don't match"
+
11108  )
+
11109 
+
11110  EPI_DEBUG_FAIL_AT_TRUE(
+
11111  state_removed != other.state_removed,
+
11112  "Virus:: state_removed don't match"
+
11113  )
+
11114 
+
11115  EPI_DEBUG_FAIL_AT_TRUE(
+
11116  queue_init != other.queue_init,
+
11117  "Virus:: queue_init don't match"
+
11118  )
+
11119 
+
11120  EPI_DEBUG_FAIL_AT_TRUE(
+
11121  queue_post != other.queue_post,
+
11122  "Virus:: queue_post don't match"
+
11123  )
+
11124 
+
11125  EPI_DEBUG_FAIL_AT_TRUE(
+
11126  queue_removed != other.queue_removed,
+
11127  "Virus:: queue_removed don't match"
+
11128  )
11129 
-
11130 }
+
11130  return true;
11131 
-
11132 template<typename TSeq>
-
11133 inline void Virus<TSeq>::set_distribution(VirusToAgentFun<TSeq> fun)
-
11134 {
-
11135  dist_fun = fun;
-
11136 }
+
11132 }
+
11133 
+
11134 template<typename TSeq>
+
11135 inline void Virus<TSeq>::print() const
+
11136 {
11137 
-
11138 #endif
-
11139 /*//////////////////////////////////////////////////////////////////////////////
-
11141 
-
11142  End of -include/epiworld/virus-meat.hpp-
-
11143 
+
11138  printf_epiworld("Virus : %s\n", virus_name->c_str());
+
11139  printf_epiworld("Id : %s\n", (id < 0)? std::string("(empty)").c_str() : std::to_string(id).c_str());
+
11140  printf_epiworld("state_init : %i\n", static_cast<int>(state_init));
+
11141  printf_epiworld("state_post : %i\n", static_cast<int>(state_post));
+
11142  printf_epiworld("state_removed : %i\n", static_cast<int>(state_removed));
+
11143  printf_epiworld("queue_init : %i\n", static_cast<int>(queue_init));
+
11144  printf_epiworld("queue_post : %i\n", static_cast<int>(queue_post));
+
11145  printf_epiworld("queue_removed : %i\n", static_cast<int>(queue_removed));
11146 
-
11147 
-
11148 
-
11149 /*//////////////////////////////////////////////////////////////////////////////
-
11151 
-
11152  Start of -include/epiworld/tools-bones.hpp-
-
11153 
-
11156 
+
11147 }
+
11148 
+
11149 template<typename TSeq>
+
11150 inline void Virus<TSeq>::distribute(Model<TSeq> * model)
+
11151 {
+
11152 
+
11153  if (dist_fun)
+
11154  {
+
11155 
+
11156  dist_fun(*this, model);
11157 
-
11158 #ifndef EPIWORLD_TOOLS_BONES_HPP
-
11159 #define EPIWORLD_TOOLS_BONES_HPP
-
11160 
-
11161 template<typename TSeq>
-
11162 class Tool;
-
11163 
-
11164 template<typename TSeq>
-
11165 class Agent;
-
11166 
-
11167 // #define ToolPtr<TSeq> std::shared_ptr< Tool<TSeq> >
-
11168 
-
11174 template<typename TSeq>
-
11175 class Tools {
-
11176  friend class Tool<TSeq>;
-
11177  friend class Agent<TSeq>;
-
11178 private:
-
11179  std::vector< ToolPtr<TSeq> > * dat;
-
11180  const epiworld_fast_uint * n_tools;
+
11158  }
+
11159 
+
11160 }
+
11161 
+
11162 template<typename TSeq>
+
11163 inline void Virus<TSeq>::set_distribution(VirusToAgentFun<TSeq> fun)
+
11164 {
+
11165  dist_fun = fun;
+
11166 }
+
11167 
+
11168 #endif
+
11169 /*//////////////////////////////////////////////////////////////////////////////
+
11171 
+
11172  End of -include/epiworld/virus-meat.hpp-
+
11173 
+
11176 
+
11177 
+
11178 
+
11179 /*//////////////////////////////////////////////////////////////////////////////
11181 
-
11182 public:
+
11182  Start of -include/epiworld/tools-bones.hpp-
11183 
-
11184  Tools() = delete;
-
11185  Tools(Agent<TSeq> & p) : dat(&p.tools), n_tools(&p.n_tools) {};
11186 
-
11187  typename std::vector< ToolPtr<TSeq> >::iterator begin();
-
11188  typename std::vector< ToolPtr<TSeq> >::iterator end();
-
11189 
-
11190  ToolPtr<TSeq> & operator()(size_t i);
-
11191  ToolPtr<TSeq> & operator[](size_t i);
-
11192 
-
11193  size_t size() const noexcept;
-
11194 
-
11195  void print() const noexcept;
+
11187 
+
11188 #ifndef EPIWORLD_TOOLS_BONES_HPP
+
11189 #define EPIWORLD_TOOLS_BONES_HPP
+
11190 
+
11191 template<typename TSeq>
+
11192 class Tool;
+
11193 
+
11194 template<typename TSeq>
+
11195 class Agent;
11196 
-
11197 };
+
11197 // #define ToolPtr<TSeq> std::shared_ptr< Tool<TSeq> >
11198 
-
11199 template<typename TSeq>
-
11200 inline typename std::vector< ToolPtr<TSeq> >::iterator Tools<TSeq>::begin()
-
11201 {
-
11202 
-
11203  if (*n_tools == 0u)
-
11204  return dat->end();
-
11205 
-
11206  return dat->begin();
-
11207 }
-
11208 
-
11209 template<typename TSeq>
-
11210 inline typename std::vector< ToolPtr<TSeq> >::iterator Tools<TSeq>::end()
-
11211 {
-
11212 
-
11213  return begin() + *n_tools;
-
11214 }
-
11215 
-
11216 template<typename TSeq>
-
11217 inline ToolPtr<TSeq> & Tools<TSeq>::operator()(size_t i)
-
11218 {
+
11204 template<typename TSeq>
+
11205 class Tools {
+
11206  friend class Tool<TSeq>;
+
11207  friend class Agent<TSeq>;
+
11208 private:
+
11209  std::vector< ToolPtr<TSeq> > * dat;
+
11210  const epiworld_fast_uint * n_tools;
+
11211 
+
11212 public:
+
11213 
+
11214  Tools() = delete;
+
11215  Tools(Agent<TSeq> & p) : dat(&p.tools), n_tools(&p.n_tools) {};
+
11216 
+
11217  typename std::vector< ToolPtr<TSeq> >::iterator begin();
+
11218  typename std::vector< ToolPtr<TSeq> >::iterator end();
11219 
-
11220  if (i >= *n_tools)
-
11221  throw std::range_error("Tool index out of range.");
+
11220  ToolPtr<TSeq> & operator()(size_t i);
+
11221  ToolPtr<TSeq> & operator[](size_t i);
11222 
-
11223  return dat->operator[](i);
+
11223  size_t size() const noexcept;
11224 
-
11225 }
+
11225  void print() const noexcept;
11226 
-
11227 template<typename TSeq>
-
11228 inline ToolPtr<TSeq> & Tools<TSeq>::operator[](size_t i)
-
11229 {
-
11230 
-
11231  return dat->operator[](i);
+
11227 };
+
11228 
+
11229 template<typename TSeq>
+
11230 inline typename std::vector< ToolPtr<TSeq> >::iterator Tools<TSeq>::begin()
+
11231 {
11232 
-
11233 }
-
11234 
-
11235 template<typename TSeq>
-
11236 inline size_t Tools<TSeq>::size() const noexcept
-
11237 {
-
11238  return *n_tools;
-
11239 }
-
11240 
-
11241 template<typename TSeq>
-
11242 inline void Tools<TSeq>::print() const noexcept
-
11243 {
-
11244  if (*n_tools == 0u)
-
11245  {
-
11246  printf_epiworld("List of tools (none)\n");
-
11247  return;
-
11248  }
+
11233  if (*n_tools == 0u)
+
11234  return dat->end();
+
11235 
+
11236  return dat->begin();
+
11237 }
+
11238 
+
11239 template<typename TSeq>
+
11240 inline typename std::vector< ToolPtr<TSeq> >::iterator Tools<TSeq>::end()
+
11241 {
+
11242 
+
11243  return begin() + *n_tools;
+
11244 }
+
11245 
+
11246 template<typename TSeq>
+
11247 inline ToolPtr<TSeq> & Tools<TSeq>::operator()(size_t i)
+
11248 {
11249 
-
11250  printf_epiworld("List of tools (%i): ", static_cast<int>(*n_tools));
-
11251 
-
11252  // Printing the name of each virus separated by a comma
-
11253  for (size_t i = 0u; i < *n_tools; ++i)
-
11254  {
-
11255  if (i == *n_tools - 1u)
-
11256  {
-
11257  printf_epiworld("%s", dat->operator[](i)->get_name().c_str());
-
11258  } else
-
11259  {
-
11260  printf_epiworld("%s, ", dat->operator[](i)->get_name().c_str());
-
11261  }
-
11262  }
-
11263 
-
11264  printf_epiworld("\n");
-
11265 
-
11266 }
-
11267 
-
11273 template<typename TSeq>
-
11274 class Tools_const {
-
11275  friend class Tool<TSeq>;
-
11276  friend class Agent<TSeq>;
-
11277 private:
-
11278  const std::vector< ToolPtr<TSeq> > * dat;
-
11279  const epiworld_fast_uint * n_tools;
-
11280 
-
11281 public:
-
11282 
-
11283  Tools_const() = delete;
-
11284  Tools_const(const Agent<TSeq> & p) : dat(&p.tools), n_tools(&p.n_tools) {};
-
11285 
-
11286  typename std::vector< ToolPtr<TSeq> >::const_iterator begin() const;
-
11287  typename std::vector< ToolPtr<TSeq> >::const_iterator end() const;
-
11288 
-
11289  const ToolPtr<TSeq> & operator()(size_t i);
-
11290  const ToolPtr<TSeq> & operator[](size_t i);
-
11291 
-
11292  size_t size() const noexcept;
-
11293 
-
11294  void print() const noexcept;
+
11250  if (i >= *n_tools)
+
11251  throw std::range_error("Tool index out of range.");
+
11252 
+
11253  return dat->operator[](i);
+
11254 
+
11255 }
+
11256 
+
11257 template<typename TSeq>
+
11258 inline ToolPtr<TSeq> & Tools<TSeq>::operator[](size_t i)
+
11259 {
+
11260 
+
11261  return dat->operator[](i);
+
11262 
+
11263 }
+
11264 
+
11265 template<typename TSeq>
+
11266 inline size_t Tools<TSeq>::size() const noexcept
+
11267 {
+
11268  return *n_tools;
+
11269 }
+
11270 
+
11271 template<typename TSeq>
+
11272 inline void Tools<TSeq>::print() const noexcept
+
11273 {
+
11274  if (*n_tools == 0u)
+
11275  {
+
11276  printf_epiworld("List of tools (none)\n");
+
11277  return;
+
11278  }
+
11279 
+
11280  printf_epiworld("List of tools (%i): ", static_cast<int>(*n_tools));
+
11281 
+
11282  // Printing the name of each virus separated by a comma
+
11283  for (size_t i = 0u; i < *n_tools; ++i)
+
11284  {
+
11285  if (i == *n_tools - 1u)
+
11286  {
+
11287  printf_epiworld("%s", dat->operator[](i)->get_name().c_str());
+
11288  } else
+
11289  {
+
11290  printf_epiworld("%s, ", dat->operator[](i)->get_name().c_str());
+
11291  }
+
11292  }
+
11293 
+
11294  printf_epiworld("\n");
11295 
-
11296 };
+
11296 }
11297 
-
11298 template<typename TSeq>
-
11299 inline typename std::vector< ToolPtr<TSeq> >::const_iterator Tools_const<TSeq>::begin() const {
-
11300 
-
11301  if (*n_tools == 0u)
-
11302  return dat->end();
-
11303 
-
11304  return dat->begin();
-
11305 }
-
11306 
-
11307 template<typename TSeq>
-
11308 inline typename std::vector< ToolPtr<TSeq> >::const_iterator Tools_const<TSeq>::end() const {
-
11309 
-
11310  return begin() + *n_tools;
-
11311 }
+
11303 template<typename TSeq>
+
11304 class Tools_const {
+
11305  friend class Tool<TSeq>;
+
11306  friend class Agent<TSeq>;
+
11307 private:
+
11308  const std::vector< ToolPtr<TSeq> > * dat;
+
11309  const epiworld_fast_uint * n_tools;
+
11310 
+
11311 public:
11312 
-
11313 template<typename TSeq>
-
11314 inline const ToolPtr<TSeq> & Tools_const<TSeq>::operator()(size_t i)
-
11315 {
-
11316 
-
11317  if (i >= *n_tools)
-
11318  throw std::range_error("Tool index out of range.");
-
11319 
-
11320  return dat->operator[](i);
+
11313  Tools_const() = delete;
+
11314  Tools_const(const Agent<TSeq> & p) : dat(&p.tools), n_tools(&p.n_tools) {};
+
11315 
+
11316  typename std::vector< ToolPtr<TSeq> >::const_iterator begin() const;
+
11317  typename std::vector< ToolPtr<TSeq> >::const_iterator end() const;
+
11318 
+
11319  const ToolPtr<TSeq> & operator()(size_t i);
+
11320  const ToolPtr<TSeq> & operator[](size_t i);
11321 
-
11322 }
+
11322  size_t size() const noexcept;
11323 
-
11324 template<typename TSeq>
-
11325 inline const ToolPtr<TSeq> & Tools_const<TSeq>::operator[](size_t i)
-
11326 {
+
11324  void print() const noexcept;
+
11325 
+
11326 };
11327 
-
11328  return dat->operator[](i);
-
11329 
-
11330 }
-
11331 
-
11332 template<typename TSeq>
-
11333 inline size_t Tools_const<TSeq>::size() const noexcept
-
11334 {
-
11335  return *n_tools;
-
11336 }
-
11337 
-
11338 template<typename TSeq>
-
11339 inline void Tools_const<TSeq>::print() const noexcept
-
11340 {
-
11341  if (*n_tools == 0u)
-
11342  {
-
11343  printf_epiworld("List of tools (none)\n");
-
11344  return;
-
11345  }
+
11328 template<typename TSeq>
+
11329 inline typename std::vector< ToolPtr<TSeq> >::const_iterator Tools_const<TSeq>::begin() const {
+
11330 
+
11331  if (*n_tools == 0u)
+
11332  return dat->end();
+
11333 
+
11334  return dat->begin();
+
11335 }
+
11336 
+
11337 template<typename TSeq>
+
11338 inline typename std::vector< ToolPtr<TSeq> >::const_iterator Tools_const<TSeq>::end() const {
+
11339 
+
11340  return begin() + *n_tools;
+
11341 }
+
11342 
+
11343 template<typename TSeq>
+
11344 inline const ToolPtr<TSeq> & Tools_const<TSeq>::operator()(size_t i)
+
11345 {
11346 
-
11347  printf_epiworld("List of tools (%i): ", *n_tools);
-
11348 
-
11349  // Printing the name of each virus separated by a comma
-
11350  for (size_t i = 0u; i < *n_tools; ++i)
-
11351  {
-
11352  if (i == *n_tools - 1u)
-
11353  {
-
11354  printf_epiworld("%s", dat->operator[](i)->get_name().c_str());
-
11355  } else
-
11356  {
-
11357  printf_epiworld("%s, ", dat->operator[](i)->get_name().c_str());
-
11358  }
-
11359  }
-
11360 
-
11361  printf_epiworld("\n");
-
11362 
-
11363 }
-
11364 
-
11365 
-
11366 
-
11367 #endif
-
11368 /*//////////////////////////////////////////////////////////////////////////////
-
11370 
-
11371  End of -include/epiworld/tools-bones.hpp-
-
11372 
-
11375 
+
11347  if (i >= *n_tools)
+
11348  throw std::range_error("Tool index out of range.");
+
11349 
+
11350  return dat->operator[](i);
+
11351 
+
11352 }
+
11353 
+
11354 template<typename TSeq>
+
11355 inline const ToolPtr<TSeq> & Tools_const<TSeq>::operator[](size_t i)
+
11356 {
+
11357 
+
11358  return dat->operator[](i);
+
11359 
+
11360 }
+
11361 
+
11362 template<typename TSeq>
+
11363 inline size_t Tools_const<TSeq>::size() const noexcept
+
11364 {
+
11365  return *n_tools;
+
11366 }
+
11367 
+
11368 template<typename TSeq>
+
11369 inline void Tools_const<TSeq>::print() const noexcept
+
11370 {
+
11371  if (*n_tools == 0u)
+
11372  {
+
11373  printf_epiworld("List of tools (none)\n");
+
11374  return;
+
11375  }
11376 
-
11377 
-
11378 /*//////////////////////////////////////////////////////////////////////////////
-
11380 
-
11381  Start of -include/epiworld/tool-bones.hpp-
-
11382 
-
11385 
-
11386 
-
11387 
-
11388 #ifndef EPIWORLD_TOOL_BONES_HPP
-
11389 #define EPIWORLD_TOOL_BONES_HPP
-
11390 
-
11391 template<typename TSeq>
-
11392 class Virus;
-
11393 
-
11394 template<typename TSeq>
-
11395 class Agent;
+
11377  printf_epiworld("List of tools (%i): ", *n_tools);
+
11378 
+
11379  // Printing the name of each virus separated by a comma
+
11380  for (size_t i = 0u; i < *n_tools; ++i)
+
11381  {
+
11382  if (i == *n_tools - 1u)
+
11383  {
+
11384  printf_epiworld("%s", dat->operator[](i)->get_name().c_str());
+
11385  } else
+
11386  {
+
11387  printf_epiworld("%s, ", dat->operator[](i)->get_name().c_str());
+
11388  }
+
11389  }
+
11390 
+
11391  printf_epiworld("\n");
+
11392 
+
11393 }
+
11394 
+
11395 
11396 
-
11397 template<typename TSeq>
-
11398 class Model;
-
11399 
-
11400 template<typename TSeq>
-
11401 class Tool;
+
11397 #endif
+
11398 /*//////////////////////////////////////////////////////////////////////////////
+
11400 
+
11401  End of -include/epiworld/tools-bones.hpp-
11402 
-
11408 template<typename TSeq>
-
11409 class Tool {
-
11410  friend class Agent<TSeq>;
-
11411  friend class Model<TSeq>;
-
11412  friend void default_add_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
11413  friend void default_rm_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
11414 private:
+
11405 
+
11406 
+
11407 
+
11408 /*//////////////////////////////////////////////////////////////////////////////
+
11410 
+
11411  Start of -include/epiworld/tool-bones.hpp-
+
11412 
11415 
-
11416  Agent<TSeq> * agent = nullptr;
-
11417  int pos_in_agent = -99; ///< Location in the agent
-
11418 
-
11419  int date = -99;
-
11420  int id = -99;
-
11421  std::shared_ptr<std::string> tool_name = nullptr;
-
11422  std::shared_ptr<TSeq> sequence = nullptr;
-
11423  ToolFun<TSeq> susceptibility_reduction_fun = nullptr;
-
11424  ToolFun<TSeq> transmission_reduction_fun = nullptr;
-
11425  ToolFun<TSeq> recovery_enhancer_fun = nullptr;
-
11426  ToolFun<TSeq> death_reduction_fun = nullptr;
-
11427 
-
11428  // Setup parameters
-
11429  std::vector< epiworld_double * > params;
-
11430 
-
11431  epiworld_fast_int state_init = -99;
-
11432  epiworld_fast_int state_post = -99;
-
11433 
-
11434  epiworld_fast_int queue_init = Queue<TSeq>::NoOne; ///< Change of state when added to agent.
-
11435  epiworld_fast_int queue_post = Queue<TSeq>::NoOne; ///< Change of state when removed from agent.
-
11436 
-
11437  void set_agent(Agent<TSeq> * p, size_t idx);
-
11438 
-
11439  ToolToAgentFun<TSeq> dist_fun = nullptr;
-
11440 
-
11441 public:
-
11442  Tool(std::string name = "unknown tool");
-
11443  Tool(
-
11444  std::string name,
-
11445  epiworld_double prevalence,
-
11446  bool as_proportion
-
11447  );
+
11416 
+
11417 
+
11418 #ifndef EPIWORLD_TOOL_BONES_HPP
+
11419 #define EPIWORLD_TOOL_BONES_HPP
+
11420 
+
11421 template<typename TSeq>
+
11422 class Virus;
+
11423 
+
11424 template<typename TSeq>
+
11425 class Agent;
+
11426 
+
11427 template<typename TSeq>
+
11428 class Model;
+
11429 
+
11430 template<typename TSeq>
+
11431 class Tool;
+
11432 
+
11438 template<typename TSeq>
+
11439 class Tool {
+
11440  friend class Agent<TSeq>;
+
11441  friend class Model<TSeq>;
+
11442  friend void default_add_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
11443  friend void default_rm_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
11444 private:
+
11445 
+
11446  Agent<TSeq> * agent = nullptr;
+
11447  int pos_in_agent = -99; ///< Location in the agent
11448 
-
11449  void set_sequence(TSeq d);
-
11450  void set_sequence(std::shared_ptr<TSeq> d);
-
11451  std::shared_ptr<TSeq> get_sequence();
-
11452 
-
11462  epiworld_double get_susceptibility_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
-
11463  epiworld_double get_transmission_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
-
11464  epiworld_double get_recovery_enhancer(VirusPtr<TSeq> v, Model<TSeq> * model);
-
11465  epiworld_double get_death_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
-
11466 
-
11467  void set_susceptibility_reduction_fun(ToolFun<TSeq> fun);
-
11468  void set_transmission_reduction_fun(ToolFun<TSeq> fun);
-
11469  void set_recovery_enhancer_fun(ToolFun<TSeq> fun);
-
11470  void set_death_reduction_fun(ToolFun<TSeq> fun);
-
11471 
-
11472  void set_susceptibility_reduction(epiworld_double * prob);
-
11473  void set_transmission_reduction(epiworld_double * prob);
-
11474  void set_recovery_enhancer(epiworld_double * prob);
-
11475  void set_death_reduction(epiworld_double * prob);
-
11476 
-
11477  void set_susceptibility_reduction(epiworld_double prob);
-
11478  void set_transmission_reduction(epiworld_double prob);
-
11479  void set_recovery_enhancer(epiworld_double prob);
-
11480  void set_death_reduction(epiworld_double prob);
+
11449  int date = -99;
+
11450  int id = -99;
+
11451  std::shared_ptr<std::string> tool_name = nullptr;
+
11452  std::shared_ptr<TSeq> sequence = nullptr;
+
11453  ToolFun<TSeq> susceptibility_reduction_fun = nullptr;
+
11454  ToolFun<TSeq> transmission_reduction_fun = nullptr;
+
11455  ToolFun<TSeq> recovery_enhancer_fun = nullptr;
+
11456  ToolFun<TSeq> death_reduction_fun = nullptr;
+
11457 
+
11458  // Setup parameters
+
11459  std::vector< epiworld_double * > params;
+
11460 
+
11461  epiworld_fast_int state_init = -99;
+
11462  epiworld_fast_int state_post = -99;
+
11463 
+
11464  epiworld_fast_int queue_init = Queue<TSeq>::NoOne; ///< Change of state when added to agent.
+
11465  epiworld_fast_int queue_post = Queue<TSeq>::NoOne; ///< Change of state when removed from agent.
+
11466 
+
11467  void set_agent(Agent<TSeq> * p, size_t idx);
+
11468 
+
11469  ToolToAgentFun<TSeq> dist_fun = nullptr;
+
11470 
+
11471 public:
+
11472  Tool(std::string name = "unknown tool");
+
11473  Tool(
+
11474  std::string name,
+
11475  epiworld_double prevalence,
+
11476  bool as_proportion
+
11477  );
+
11478 
+
11479  void set_sequence(TSeq d);
+
11480  void set_sequence(std::shared_ptr<TSeq> d);
+
11481  std::shared_ptr<TSeq> get_sequence();
11482 
-
11483  void set_name(std::string name);
-
11484  std::string get_name() const;
-
11485 
-
11486  Agent<TSeq> * get_agent();
-
11487  int get_id() const;
-
11488  void set_id(int id);
-
11489  void set_date(int d);
-
11490  int get_date() const;
-
11491 
-
11492  void set_state(epiworld_fast_int init, epiworld_fast_int post);
-
11493  void set_queue(epiworld_fast_int init, epiworld_fast_int post);
-
11494  void get_state(epiworld_fast_int * init, epiworld_fast_int * post);
-
11495  void get_queue(epiworld_fast_int * init, epiworld_fast_int * post);
-
11496 
-
11497  bool operator==(const Tool<TSeq> & other) const;
-
11498  bool operator!=(const Tool<TSeq> & other) const {return !operator==(other);};
-
11499 
-
11500  void print() const;
+
11492  epiworld_double get_susceptibility_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
+
11493  epiworld_double get_transmission_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
+
11494  epiworld_double get_recovery_enhancer(VirusPtr<TSeq> v, Model<TSeq> * model);
+
11495  epiworld_double get_death_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
+
11496 
+
11497  void set_susceptibility_reduction_fun(ToolFun<TSeq> fun);
+
11498  void set_transmission_reduction_fun(ToolFun<TSeq> fun);
+
11499  void set_recovery_enhancer_fun(ToolFun<TSeq> fun);
+
11500  void set_death_reduction_fun(ToolFun<TSeq> fun);
11501 
-
11502  void distribute(Model<TSeq> * model);
-
11503  void set_distribution(ToolToAgentFun<TSeq> fun);
-
11504 
-
11505 };
+
11502  void set_susceptibility_reduction(epiworld_double * prob);
+
11503  void set_transmission_reduction(epiworld_double * prob);
+
11504  void set_recovery_enhancer(epiworld_double * prob);
+
11505  void set_death_reduction(epiworld_double * prob);
11506 
-
11507 #endif
-
11508 /*//////////////////////////////////////////////////////////////////////////////
-
11510 
-
11511  End of -include/epiworld/tool-bones.hpp-
+
11507  void set_susceptibility_reduction(epiworld_double prob);
+
11508  void set_transmission_reduction(epiworld_double prob);
+
11509  void set_recovery_enhancer(epiworld_double prob);
+
11510  void set_death_reduction(epiworld_double prob);
11512 
+
11513  void set_name(std::string name);
+
11514  std::string get_name() const;
11515 
-
11516 
-
11517 /*//////////////////////////////////////////////////////////////////////////////
-
11519 
-
11520  Start of -include/epiworld/tool-distribute-meat.hpp-
+
11516  Agent<TSeq> * get_agent();
+
11517  int get_id() const;
+
11518  void set_id(int id);
+
11519  void set_date(int d);
+
11520  int get_date() const;
11521 
-
11524 
-
11525 
-
11526 #ifndef TOOL_DISTRIBUTE_MEAT_HPP
-
11527 #define TOOL_DISTRIBUTE_MEAT_HPP
-
11528 
-
11544 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
11545 inline ToolToAgentFun<TSeq> distribute_tool_to_set(
-
11546  std::vector< size_t > agents_ids
-
11547 ) {
-
11548 
-
11549  return [agents_ids](
-
11550  Tool<TSeq> & tool, Model<TSeq> * model
-
11551  ) -> void
-
11552  {
-
11553  // Adding action
-
11554  for (auto i: agents_ids)
-
11555  {
-
11556  model->get_agent(i).add_tool(
-
11557  tool,
-
11558  const_cast<Model<TSeq> * >(model)
-
11559  );
-
11560  }
-
11561  };
-
11562 
-
11563 }
-
11564 
-
11575 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
11576 inline ToolToAgentFun<TSeq> distribute_tool_randomly(
-
11577  epiworld_double prevalence,
-
11578  bool as_proportion = true
-
11579 ) {
-
11580 
-
11581  return [prevalence, as_proportion](
-
11582  Tool<TSeq> & tool, Model<TSeq> * model
-
11583  ) -> void {
-
11584 
-
11585  // Picking how many
-
11586  int n_to_distribute;
-
11587  int n = model->size();
-
11588  if (as_proportion)
-
11589  {
-
11590  n_to_distribute = static_cast<int>(std::floor(prevalence * n));
-
11591 
-
11592  if (n_to_distribute == n)
-
11593  n_to_distribute--;
-
11594  }
-
11595  else
-
11596  {
-
11597  n_to_distribute = static_cast<int>(prevalence);
-
11598  }
-
11599 
-
11600  if (n_to_distribute > n)
-
11601  throw std::range_error("There are only " + std::to_string(n) +
-
11602  " individuals in the population. Cannot add the tool to " + std::to_string(n_to_distribute));
-
11603 
-
11604  std::vector< int > idx(n);
-
11605  std::iota(idx.begin(), idx.end(), 0);
-
11606  auto & population = model->get_agents();
-
11607  for (int i = 0u; i < n_to_distribute; ++i)
-
11608  {
-
11609  int loc = static_cast<epiworld_fast_uint>(
-
11610  floor(model->runif() * n--)
-
11611  );
-
11612 
-
11613  if ((loc > 0) && (loc == n))
-
11614  loc--;
-
11615 
-
11616  population[idx[loc]].add_tool(
-
11617  tool,
-
11618  const_cast< Model<TSeq> * >(model)
-
11619  );
-
11620 
-
11621  std::swap(idx[loc], idx[n]);
-
11622 
-
11623  }
-
11624 
-
11625  };
-
11626 
-
11627 }
-
11628 #endif
-
11629 /*//////////////////////////////////////////////////////////////////////////////
-
11631 
-
11632  End of -include/epiworld/tool-distribute-meat.hpp-
-
11633 
-
11636 
-
11637 
-
11638 /*//////////////////////////////////////////////////////////////////////////////
-
11640 
-
11641  Start of -include/epiworld/tool-meat.hpp-
+
11522  void set_state(epiworld_fast_int init, epiworld_fast_int post);
+
11523  void set_queue(epiworld_fast_int init, epiworld_fast_int post);
+
11524  void get_state(epiworld_fast_int * init, epiworld_fast_int * post);
+
11525  void get_queue(epiworld_fast_int * init, epiworld_fast_int * post);
+
11526 
+
11527  bool operator==(const Tool<TSeq> & other) const;
+
11528  bool operator!=(const Tool<TSeq> & other) const {return !operator==(other);};
+
11529 
+
11530  void print() const;
+
11531 
+
11532  void distribute(Model<TSeq> * model);
+
11533  void set_distribution(ToolToAgentFun<TSeq> fun);
+
11534 
+
11535 };
+
11536 
+
11537 #endif
+
11538 /*//////////////////////////////////////////////////////////////////////////////
+
11540 
+
11541  End of -include/epiworld/tool-bones.hpp-
+
11542 
+
11545 
+
11546 
+
11547 /*//////////////////////////////////////////////////////////////////////////////
+
11549 
+
11550  Start of -include/epiworld/tool-distribute-meat.hpp-
+
11551 
+
11554 
+
11555 
+
11556 #ifndef TOOL_DISTRIBUTE_MEAT_HPP
+
11557 #define TOOL_DISTRIBUTE_MEAT_HPP
+
11558 
+
11574 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
11575 inline ToolToAgentFun<TSeq> distribute_tool_to_set(
+
11576  std::vector< size_t > agents_ids
+
11577 ) {
+
11578 
+
11579  return [agents_ids](
+
11580  Tool<TSeq> & tool, Model<TSeq> * model
+
11581  ) -> void
+
11582  {
+
11583  // Adding action
+
11584  for (auto i: agents_ids)
+
11585  {
+
11586  model->get_agent(i).add_tool(
+
11587  tool,
+
11588  const_cast<Model<TSeq> * >(model)
+
11589  );
+
11590  }
+
11591  };
+
11592 
+
11593 }
+
11594 
+
11605 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
11606 inline ToolToAgentFun<TSeq> distribute_tool_randomly(
+
11607  epiworld_double prevalence,
+
11608  bool as_proportion = true
+
11609 ) {
+
11610 
+
11611  return [prevalence, as_proportion](
+
11612  Tool<TSeq> & tool, Model<TSeq> * model
+
11613  ) -> void {
+
11614 
+
11615  // Picking how many
+
11616  int n_to_distribute;
+
11617  int n = model->size();
+
11618  if (as_proportion)
+
11619  {
+
11620  n_to_distribute = static_cast<int>(std::floor(prevalence * n));
+
11621 
+
11622  if (n_to_distribute == n)
+
11623  n_to_distribute--;
+
11624  }
+
11625  else
+
11626  {
+
11627  n_to_distribute = static_cast<int>(prevalence);
+
11628  }
+
11629 
+
11630  if (n_to_distribute > n)
+
11631  throw std::range_error("There are only " + std::to_string(n) +
+
11632  " individuals in the population. Cannot add the tool to " + std::to_string(n_to_distribute));
+
11633 
+
11634  std::vector< int > idx(n);
+
11635  std::iota(idx.begin(), idx.end(), 0);
+
11636  auto & population = model->get_agents();
+
11637  for (int i = 0u; i < n_to_distribute; ++i)
+
11638  {
+
11639  int loc = static_cast<epiworld_fast_uint>(
+
11640  floor(model->runif() * n--)
+
11641  );
11642 
-
11645 
-
11646 
-
11647 
-
11648 #ifndef EPIWORLD_TOOLS_MEAT_HPP
-
11649 #define EPIWORLD_TOOLS_MEAT_HPP
-
11650 
-
11659 template<typename TSeq>
-
11660 inline ToolFun<TSeq> tool_fun_logit(
-
11661  std::vector< int > vars,
-
11662  std::vector< double > coefs,
-
11663  Model<TSeq> * model
-
11664 ) {
-
11665 
-
11666  // Checking that there are features
-
11667  if (coefs.size() == 0u)
-
11668  throw std::logic_error(
-
11669  "The -coefs- argument should feature at least one element."
-
11670  );
-
11671 
-
11672  if (coefs.size() != vars.size())
-
11673  throw std::length_error(
-
11674  std::string("The length of -coef- (") +
-
11675  std::to_string(coefs.size()) +
-
11676  std::string(") and -vars- (") +
-
11677  std::to_string(vars.size()) +
-
11678  std::string(") should match. ")
-
11679  );
+
11643  if ((loc > 0) && (loc == n))
+
11644  loc--;
+
11645 
+
11646  population[idx[loc]].add_tool(
+
11647  tool,
+
11648  const_cast< Model<TSeq> * >(model)
+
11649  );
+
11650 
+
11651  std::swap(idx[loc], idx[n]);
+
11652 
+
11653  }
+
11654 
+
11655  };
+
11656 
+
11657 }
+
11658 #endif
+
11659 /*//////////////////////////////////////////////////////////////////////////////
+
11661 
+
11662  End of -include/epiworld/tool-distribute-meat.hpp-
+
11663 
+
11666 
+
11667 
+
11668 /*//////////////////////////////////////////////////////////////////////////////
+
11670 
+
11671  Start of -include/epiworld/tool-meat.hpp-
+
11672 
+
11675 
+
11676 
+
11677 
+
11678 #ifndef EPIWORLD_TOOLS_MEAT_HPP
+
11679 #define EPIWORLD_TOOLS_MEAT_HPP
11680 
-
11681  // Checking that there are variables in the model
-
11682  if (model != nullptr)
-
11683  {
-
11684 
-
11685  size_t K = model->get_agents_data_ncols();
-
11686  for (const auto & var: vars)
-
11687  {
-
11688  if ((var >= static_cast<int>(K)) | (var < 0))
-
11689  throw std::range_error(
-
11690  std::string("The variable ") +
-
11691  std::to_string(var) +
-
11692  std::string(" is out of range.") +
-
11693  std::string(" The agents only feature ") +
-
11694  std::to_string(K) +
-
11695  std::string("variables (features).")
-
11696  );
-
11697  }
-
11698 
-
11699  }
-
11700 
-
11701  std::vector< epiworld_double > coefs_f;
-
11702  for (auto c: coefs)
-
11703  coefs_f.push_back(static_cast<epiworld_double>(c));
-
11704 
-
11705  ToolFun<TSeq> fun_ = [coefs_f,vars](
-
11706  Tool<TSeq>& tool,
-
11707  Agent<TSeq> * agent,
-
11708  VirusPtr<TSeq> virus,
-
11709  Model<TSeq> * model
-
11710  ) -> epiworld_double {
-
11711 
-
11712  size_t K = coefs_f.size();
-
11713  epiworld_double res = 0.0;
+
11689 template<typename TSeq>
+
11690 inline ToolFun<TSeq> tool_fun_logit(
+
11691  std::vector< int > vars,
+
11692  std::vector< double > coefs,
+
11693  Model<TSeq> * model
+
11694 ) {
+
11695 
+
11696  // Checking that there are features
+
11697  if (coefs.size() == 0u)
+
11698  throw std::logic_error(
+
11699  "The -coefs- argument should feature at least one element."
+
11700  );
+
11701 
+
11702  if (coefs.size() != vars.size())
+
11703  throw std::length_error(
+
11704  std::string("The length of -coef- (") +
+
11705  std::to_string(coefs.size()) +
+
11706  std::string(") and -vars- (") +
+
11707  std::to_string(vars.size()) +
+
11708  std::string(") should match. ")
+
11709  );
+
11710 
+
11711  // Checking that there are variables in the model
+
11712  if (model != nullptr)
+
11713  {
11714 
-
11715  #if defined(__OPENMP) || defined(_OPENMP)
-
11716  #pragma omp simd reduction(+:res)
-
11717  #endif
-
11718  for (size_t i = 0u; i < K; ++i)
-
11719  res += agent->operator[](vars.at(i)) * coefs_f.at(i);
-
11720 
-
11721  return 1.0/(1.0 + std::exp(-res));
-
11722 
-
11723  };
-
11724 
-
11725  return fun_;
-
11726 
-
11727 }
-
11728 
-
11729 template<typename TSeq>
-
11730 inline Tool<TSeq>::Tool(std::string name)
-
11731 {
-
11732  set_name(name);
-
11733 }
+
11715  size_t K = model->get_agents_data_ncols();
+
11716  for (const auto & var: vars)
+
11717  {
+
11718  if ((var >= static_cast<int>(K)) | (var < 0))
+
11719  throw std::range_error(
+
11720  std::string("The variable ") +
+
11721  std::to_string(var) +
+
11722  std::string(" is out of range.") +
+
11723  std::string(" The agents only feature ") +
+
11724  std::to_string(K) +
+
11725  std::string("variables (features).")
+
11726  );
+
11727  }
+
11728 
+
11729  }
+
11730 
+
11731  std::vector< epiworld_double > coefs_f;
+
11732  for (auto c: coefs)
+
11733  coefs_f.push_back(static_cast<epiworld_double>(c));
11734 
-
11735 template<typename TSeq>
-
11736 inline Tool<TSeq>::Tool(
-
11737  std::string name,
-
11738  epiworld_double prevalence,
-
11739  bool as_proportion
-
11740  )
-
11741 {
-
11742  set_name(name);
-
11743 
-
11744  set_distribution(
-
11745  distribute_tool_randomly<TSeq>(prevalence, as_proportion)
-
11746  );
-
11747 }
-
11748 
-
11749 // template<typename TSeq>
-
11750 // inline Tool<TSeq>::Tool(TSeq d, std::string name) {
-
11751 // sequence = std::make_shared<TSeq>(d);
-
11752 // tool_name = std::make_shared<std::string>(name);
-
11753 // }
+
11735  ToolFun<TSeq> fun_ = [coefs_f,vars](
+
11736  Tool<TSeq>& tool,
+
11737  Agent<TSeq> * agent,
+
11738  VirusPtr<TSeq> virus,
+
11739  Model<TSeq> * model
+
11740  ) -> epiworld_double {
+
11741 
+
11742  size_t K = coefs_f.size();
+
11743  epiworld_double res = 0.0;
+
11744 
+
11745  #if defined(__OPENMP) || defined(_OPENMP)
+
11746  #pragma omp simd reduction(+:res)
+
11747  #endif
+
11748  for (size_t i = 0u; i < K; ++i)
+
11749  res += agent->operator[](vars.at(i)) * coefs_f.at(i);
+
11750 
+
11751  return 1.0/(1.0 + std::exp(-res));
+
11752 
+
11753  };
11754 
-
11755 template<typename TSeq>
-
11756 inline void Tool<TSeq>::set_sequence(TSeq d) {
-
11757  sequence = std::make_shared<TSeq>(d);
-
11758 }
-
11759 
-
11760 template<typename TSeq>
-
11761 inline void Tool<TSeq>::set_sequence(std::shared_ptr<TSeq> d) {
-
11762  sequence = d;
+
11755  return fun_;
+
11756 
+
11757 }
+
11758 
+
11759 template<typename TSeq>
+
11760 inline Tool<TSeq>::Tool(std::string name)
+
11761 {
+
11762  set_name(name);
11763 }
11764 
11765 template<typename TSeq>
-
11766 inline std::shared_ptr<TSeq> Tool<TSeq>::get_sequence() {
-
11767  return sequence;
-
11768 }
-
11769 
-
11770 template<typename TSeq>
-
11771 inline epiworld_double Tool<TSeq>::get_susceptibility_reduction(
-
11772  VirusPtr<TSeq> v,
-
11773  Model<TSeq> * model
-
11774 )
-
11775 {
-
11776 
-
11777  if (susceptibility_reduction_fun)
-
11778  return susceptibility_reduction_fun(*this, this->agent, v, model);
-
11779 
-
11780  return DEFAULT_TOOL_CONTAGION_REDUCTION;
-
11781 
-
11782 }
-
11783 
-
11784 template<typename TSeq>
-
11785 inline epiworld_double Tool<TSeq>::get_transmission_reduction(
-
11786  VirusPtr<TSeq> v,
-
11787  Model<TSeq> * model
-
11788 )
-
11789 {
-
11790 
-
11791  if (transmission_reduction_fun)
-
11792  return transmission_reduction_fun(*this, this->agent, v, model);
-
11793 
-
11794  return DEFAULT_TOOL_TRANSMISSION_REDUCTION;
-
11795 
-
11796 }
-
11797 
-
11798 template<typename TSeq>
-
11799 inline epiworld_double Tool<TSeq>::get_recovery_enhancer(
-
11800  VirusPtr<TSeq> v,
-
11801  Model<TSeq> * model
-
11802 )
-
11803 {
-
11804 
-
11805  if (recovery_enhancer_fun)
-
11806  return recovery_enhancer_fun(*this, this->agent, v, model);
-
11807 
-
11808  return DEFAULT_TOOL_RECOVERY_ENHANCER;
+
11766 inline Tool<TSeq>::Tool(
+
11767  std::string name,
+
11768  epiworld_double prevalence,
+
11769  bool as_proportion
+
11770  )
+
11771 {
+
11772  set_name(name);
+
11773 
+
11774  set_distribution(
+
11775  distribute_tool_randomly<TSeq>(prevalence, as_proportion)
+
11776  );
+
11777 }
+
11778 
+
11779 // template<typename TSeq>
+
11780 // inline Tool<TSeq>::Tool(TSeq d, std::string name) {
+
11781 // sequence = std::make_shared<TSeq>(d);
+
11782 // tool_name = std::make_shared<std::string>(name);
+
11783 // }
+
11784 
+
11785 template<typename TSeq>
+
11786 inline void Tool<TSeq>::set_sequence(TSeq d) {
+
11787  sequence = std::make_shared<TSeq>(d);
+
11788 }
+
11789 
+
11790 template<typename TSeq>
+
11791 inline void Tool<TSeq>::set_sequence(std::shared_ptr<TSeq> d) {
+
11792  sequence = d;
+
11793 }
+
11794 
+
11795 template<typename TSeq>
+
11796 inline std::shared_ptr<TSeq> Tool<TSeq>::get_sequence() {
+
11797  return sequence;
+
11798 }
+
11799 
+
11800 template<typename TSeq>
+
11801 inline epiworld_double Tool<TSeq>::get_susceptibility_reduction(
+
11802  VirusPtr<TSeq> v,
+
11803  Model<TSeq> * model
+
11804 )
+
11805 {
+
11806 
+
11807  if (susceptibility_reduction_fun)
+
11808  return susceptibility_reduction_fun(*this, this->agent, v, model);
11809 
-
11810 }
+
11810  return DEFAULT_TOOL_CONTAGION_REDUCTION;
11811 
-
11812 template<typename TSeq>
-
11813 inline epiworld_double Tool<TSeq>::get_death_reduction(
-
11814  VirusPtr<TSeq> v,
-
11815  Model<TSeq> * model
-
11816 )
-
11817 {
-
11818 
-
11819  if (death_reduction_fun)
-
11820  return death_reduction_fun(*this, this->agent, v, model);
-
11821 
-
11822  return DEFAULT_TOOL_DEATH_REDUCTION;
+
11812 }
+
11813 
+
11814 template<typename TSeq>
+
11815 inline epiworld_double Tool<TSeq>::get_transmission_reduction(
+
11816  VirusPtr<TSeq> v,
+
11817  Model<TSeq> * model
+
11818 )
+
11819 {
+
11820 
+
11821  if (transmission_reduction_fun)
+
11822  return transmission_reduction_fun(*this, this->agent, v, model);
11823 
-
11824 }
+
11824  return DEFAULT_TOOL_TRANSMISSION_REDUCTION;
11825 
-
11826 template<typename TSeq>
-
11827 inline void Tool<TSeq>::set_susceptibility_reduction_fun(
-
11828  ToolFun<TSeq> fun
-
11829 )
-
11830 {
-
11831  susceptibility_reduction_fun = fun;
-
11832 }
-
11833 
-
11834 template<typename TSeq>
-
11835 inline void Tool<TSeq>::set_transmission_reduction_fun(
-
11836  ToolFun<TSeq> fun
-
11837 )
-
11838 {
-
11839  transmission_reduction_fun = fun;
+
11826 }
+
11827 
+
11828 template<typename TSeq>
+
11829 inline epiworld_double Tool<TSeq>::get_recovery_enhancer(
+
11830  VirusPtr<TSeq> v,
+
11831  Model<TSeq> * model
+
11832 )
+
11833 {
+
11834 
+
11835  if (recovery_enhancer_fun)
+
11836  return recovery_enhancer_fun(*this, this->agent, v, model);
+
11837 
+
11838  return DEFAULT_TOOL_RECOVERY_ENHANCER;
+
11839 
11840 }
11841 
11842 template<typename TSeq>
-
11843 inline void Tool<TSeq>::set_recovery_enhancer_fun(
-
11844  ToolFun<TSeq> fun
-
11845 )
-
11846 {
-
11847  recovery_enhancer_fun = fun;
-
11848 }
-
11849 
-
11850 template<typename TSeq>
-
11851 inline void Tool<TSeq>::set_death_reduction_fun(
-
11852  ToolFun<TSeq> fun
-
11853 )
-
11854 {
-
11855  death_reduction_fun = fun;
-
11856 }
-
11857 
-
11858 template<typename TSeq>
-
11859 inline void Tool<TSeq>::set_susceptibility_reduction(epiworld_double * prob)
+
11843 inline epiworld_double Tool<TSeq>::get_death_reduction(
+
11844  VirusPtr<TSeq> v,
+
11845  Model<TSeq> * model
+
11846 )
+
11847 {
+
11848 
+
11849  if (death_reduction_fun)
+
11850  return death_reduction_fun(*this, this->agent, v, model);
+
11851 
+
11852  return DEFAULT_TOOL_DEATH_REDUCTION;
+
11853 
+
11854 }
+
11855 
+
11856 template<typename TSeq>
+
11857 inline void Tool<TSeq>::set_susceptibility_reduction_fun(
+
11858  ToolFun<TSeq> fun
+
11859 )
11860 {
-
11861 
-
11862  ToolFun<TSeq> tmpfun =
-
11863  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
-
11864  {
-
11865  return *prob;
-
11866  };
-
11867 
-
11868  susceptibility_reduction_fun = tmpfun;
-
11869 
+
11861  susceptibility_reduction_fun = fun;
+
11862 }
+
11863 
+
11864 template<typename TSeq>
+
11865 inline void Tool<TSeq>::set_transmission_reduction_fun(
+
11866  ToolFun<TSeq> fun
+
11867 )
+
11868 {
+
11869  transmission_reduction_fun = fun;
11870 }
11871 
-
11872 // EPIWORLD_SET_LAMBDA(susceptibility_reduction)
-
11873 template<typename TSeq>
-
11874 inline void Tool<TSeq>::set_transmission_reduction(epiworld_double * prob)
-
11875 {
-
11876 
-
11877  ToolFun<TSeq> tmpfun =
-
11878  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
-
11879  {
-
11880  return *prob;
-
11881  };
-
11882 
-
11883  transmission_reduction_fun = tmpfun;
-
11884 
-
11885 }
-
11886 
-
11887 // EPIWORLD_SET_LAMBDA(transmission_reduction)
+
11872 template<typename TSeq>
+
11873 inline void Tool<TSeq>::set_recovery_enhancer_fun(
+
11874  ToolFun<TSeq> fun
+
11875 )
+
11876 {
+
11877  recovery_enhancer_fun = fun;
+
11878 }
+
11879 
+
11880 template<typename TSeq>
+
11881 inline void Tool<TSeq>::set_death_reduction_fun(
+
11882  ToolFun<TSeq> fun
+
11883 )
+
11884 {
+
11885  death_reduction_fun = fun;
+
11886 }
+
11887 
11888 template<typename TSeq>
-
11889 inline void Tool<TSeq>::set_recovery_enhancer(epiworld_double * prob)
+
11889 inline void Tool<TSeq>::set_susceptibility_reduction(epiworld_double * prob)
11890 {
11891 
11892  ToolFun<TSeq> tmpfun =
@@ -10825,4146 +10825,4154 @@
11895  return *prob;
11896  };
11897 
-
11898  recovery_enhancer_fun = tmpfun;
+
11898  susceptibility_reduction_fun = tmpfun;
11899 
11900 }
11901 
-
11902 // EPIWORLD_SET_LAMBDA(recovery_enhancer)
+
11902 // EPIWORLD_SET_LAMBDA(susceptibility_reduction)
11903 template<typename TSeq>
-
11904 inline void Tool<TSeq>::set_death_reduction(epiworld_double * prob)
+
11904 inline void Tool<TSeq>::set_transmission_reduction(epiworld_double * prob)
11905 {
-
11906 
+
11906 
11907  ToolFun<TSeq> tmpfun =
11908  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
11909  {
11910  return *prob;
11911  };
11912 
-
11913  death_reduction_fun = tmpfun;
+
11913  transmission_reduction_fun = tmpfun;
11914 
11915 }
11916 
-
11917 // EPIWORLD_SET_LAMBDA(death_reduction)
-
11918 
-
11919 // #undef EPIWORLD_SET_LAMBDA
-
11920 template<typename TSeq>
-
11921 inline void Tool<TSeq>::set_susceptibility_reduction(
-
11922  epiworld_double prob
-
11923 )
-
11924 {
-
11925 
-
11926  ToolFun<TSeq> tmpfun =
-
11927  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
-
11928  {
-
11929  return prob;
-
11930  };
+
11917 // EPIWORLD_SET_LAMBDA(transmission_reduction)
+
11918 template<typename TSeq>
+
11919 inline void Tool<TSeq>::set_recovery_enhancer(epiworld_double * prob)
+
11920 {
+
11921 
+
11922  ToolFun<TSeq> tmpfun =
+
11923  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
+
11924  {
+
11925  return *prob;
+
11926  };
+
11927 
+
11928  recovery_enhancer_fun = tmpfun;
+
11929 
+
11930 }
11931 
-
11932  susceptibility_reduction_fun = tmpfun;
-
11933 
-
11934 }
-
11935 
-
11936 template<typename TSeq>
-
11937 inline void Tool<TSeq>::set_transmission_reduction(
-
11938  epiworld_double prob
-
11939 )
-
11940 {
-
11941 
-
11942  ToolFun<TSeq> tmpfun =
-
11943  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
-
11944  {
-
11945  return prob;
-
11946  };
-
11947 
-
11948  transmission_reduction_fun = tmpfun;
-
11949 
-
11950 }
-
11951 
-
11952 template<typename TSeq>
-
11953 inline void Tool<TSeq>::set_recovery_enhancer(
-
11954  epiworld_double prob
-
11955 )
-
11956 {
-
11957 
-
11958  ToolFun<TSeq> tmpfun =
-
11959  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
-
11960  {
-
11961  return prob;
-
11962  };
+
11932 // EPIWORLD_SET_LAMBDA(recovery_enhancer)
+
11933 template<typename TSeq>
+
11934 inline void Tool<TSeq>::set_death_reduction(epiworld_double * prob)
+
11935 {
+
11936 
+
11937  ToolFun<TSeq> tmpfun =
+
11938  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
+
11939  {
+
11940  return *prob;
+
11941  };
+
11942 
+
11943  death_reduction_fun = tmpfun;
+
11944 
+
11945 }
+
11946 
+
11947 // EPIWORLD_SET_LAMBDA(death_reduction)
+
11948 
+
11949 // #undef EPIWORLD_SET_LAMBDA
+
11950 template<typename TSeq>
+
11951 inline void Tool<TSeq>::set_susceptibility_reduction(
+
11952  epiworld_double prob
+
11953 )
+
11954 {
+
11955 
+
11956  ToolFun<TSeq> tmpfun =
+
11957  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
+
11958  {
+
11959  return prob;
+
11960  };
+
11961 
+
11962  susceptibility_reduction_fun = tmpfun;
11963 
-
11964  recovery_enhancer_fun = tmpfun;
+
11964 }
11965 
-
11966 }
-
11967 
-
11968 template<typename TSeq>
-
11969 inline void Tool<TSeq>::set_death_reduction(
-
11970  epiworld_double prob
-
11971 )
-
11972 {
-
11973 
-
11974  ToolFun<TSeq> tmpfun =
-
11975  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
-
11976  {
-
11977  return prob;
-
11978  };
+
11966 template<typename TSeq>
+
11967 inline void Tool<TSeq>::set_transmission_reduction(
+
11968  epiworld_double prob
+
11969 )
+
11970 {
+
11971 
+
11972  ToolFun<TSeq> tmpfun =
+
11973  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
+
11974  {
+
11975  return prob;
+
11976  };
+
11977 
+
11978  transmission_reduction_fun = tmpfun;
11979 
-
11980  death_reduction_fun = tmpfun;
+
11980 }
11981 
-
11982 }
-
11983 
-
11984 template<typename TSeq>
-
11985 inline void Tool<TSeq>::set_name(std::string name)
+
11982 template<typename TSeq>
+
11983 inline void Tool<TSeq>::set_recovery_enhancer(
+
11984  epiworld_double prob
+
11985 )
11986 {
-
11987  if (name != "")
-
11988  tool_name = std::make_shared<std::string>(name);
-
11989 }
-
11990 
-
11991 template<typename TSeq>
-
11992 inline std::string Tool<TSeq>::get_name() const {
+
11987 
+
11988  ToolFun<TSeq> tmpfun =
+
11989  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
+
11990  {
+
11991  return prob;
+
11992  };
11993 
-
11994  if (tool_name)
-
11995  return *tool_name;
-
11996 
-
11997  return "unknown tool";
-
11998 
-
11999 }
-
12000 
-
12001 template<typename TSeq>
-
12002 inline Agent<TSeq> * Tool<TSeq>::get_agent()
-
12003 {
-
12004  return this->agent;
-
12005 }
-
12006 
-
12007 template<typename TSeq>
-
12008 inline void Tool<TSeq>::set_agent(Agent<TSeq> * p, size_t idx)
-
12009 {
-
12010  agent = p;
-
12011  pos_in_agent = static_cast<int>(idx);
+
11994  recovery_enhancer_fun = tmpfun;
+
11995 
+
11996 }
+
11997 
+
11998 template<typename TSeq>
+
11999 inline void Tool<TSeq>::set_death_reduction(
+
12000  epiworld_double prob
+
12001 )
+
12002 {
+
12003 
+
12004  ToolFun<TSeq> tmpfun =
+
12005  [prob](Tool<TSeq> &, Agent<TSeq> *, VirusPtr<TSeq>, Model<TSeq> *)
+
12006  {
+
12007  return prob;
+
12008  };
+
12009 
+
12010  death_reduction_fun = tmpfun;
+
12011 
12012 }
12013 
12014 template<typename TSeq>
-
12015 inline int Tool<TSeq>::get_id() const {
-
12016  return id;
-
12017 }
-
12018 
-
12019 
-
12020 template<typename TSeq>
-
12021 inline void Tool<TSeq>::set_id(int id)
-
12022 {
-
12023  this->id = id;
-
12024 }
-
12025 
-
12026 template<typename TSeq>
-
12027 inline void Tool<TSeq>::set_date(int d)
-
12028 {
-
12029  this->date = d;
-
12030 }
-
12031 
-
12032 template<typename TSeq>
-
12033 inline int Tool<TSeq>::get_date() const
-
12034 {
-
12035  return date;
-
12036 }
-
12037 
-
12038 template<typename TSeq>
-
12039 inline void Tool<TSeq>::set_state(
-
12040  epiworld_fast_int init,
-
12041  epiworld_fast_int end
-
12042 )
-
12043 {
-
12044  state_init = init;
-
12045  state_post = end;
-
12046 }
-
12047 
-
12048 template<typename TSeq>
-
12049 inline void Tool<TSeq>::set_queue(
-
12050  epiworld_fast_int init,
-
12051  epiworld_fast_int end
-
12052 )
-
12053 {
-
12054  queue_init = init;
-
12055  queue_post = end;
-
12056 }
-
12057 
-
12058 template<typename TSeq>
-
12059 inline void Tool<TSeq>::get_state(
-
12060  epiworld_fast_int * init,
-
12061  epiworld_fast_int * post
-
12062 )
-
12063 {
-
12064  if (init != nullptr)
-
12065  *init = state_init;
-
12066 
-
12067  if (post != nullptr)
-
12068  *post = state_post;
-
12069 
-
12070 }
-
12071 
-
12072 template<typename TSeq>
-
12073 inline void Tool<TSeq>::get_queue(
-
12074  epiworld_fast_int * init,
-
12075  epiworld_fast_int * post
-
12076 )
-
12077 {
-
12078  if (init != nullptr)
-
12079  *init = queue_init;
-
12080 
-
12081  if (post != nullptr)
-
12082  *post = queue_post;
-
12083 
-
12084 }
-
12085 
-
12086 template<>
-
12087 inline bool Tool<std::vector<int>>::operator==(
-
12088  const Tool<std::vector<int>> & other
-
12089  ) const
-
12090 {
-
12091 
-
12092  if (sequence->size() != other.sequence->size())
-
12093  return false;
-
12094 
-
12095  for (size_t i = 0u; i < sequence->size(); ++i)
-
12096  {
-
12097  if (sequence->operator[](i) != other.sequence->operator[](i))
-
12098  return false;
-
12099  }
-
12100 
-
12101  if (tool_name != other.tool_name)
-
12102  return false;
-
12103 
-
12104  if (state_init != other.state_init)
-
12105  return false;
-
12106 
-
12107  if (state_post != other.state_post)
-
12108  return false;
-
12109 
-
12110  if (queue_init != other.queue_init)
-
12111  return false;
-
12112 
-
12113  if (queue_post != other.queue_post)
-
12114  return false;
+
12015 inline void Tool<TSeq>::set_name(std::string name)
+
12016 {
+
12017  if (name != "")
+
12018  tool_name = std::make_shared<std::string>(name);
+
12019 }
+
12020 
+
12021 template<typename TSeq>
+
12022 inline std::string Tool<TSeq>::get_name() const {
+
12023 
+
12024  if (tool_name)
+
12025  return *tool_name;
+
12026 
+
12027  return "unknown tool";
+
12028 
+
12029 }
+
12030 
+
12031 template<typename TSeq>
+
12032 inline Agent<TSeq> * Tool<TSeq>::get_agent()
+
12033 {
+
12034  return this->agent;
+
12035 }
+
12036 
+
12037 template<typename TSeq>
+
12038 inline void Tool<TSeq>::set_agent(Agent<TSeq> * p, size_t idx)
+
12039 {
+
12040  agent = p;
+
12041  pos_in_agent = static_cast<int>(idx);
+
12042 }
+
12043 
+
12044 template<typename TSeq>
+
12045 inline int Tool<TSeq>::get_id() const {
+
12046  return id;
+
12047 }
+
12048 
+
12049 
+
12050 template<typename TSeq>
+
12051 inline void Tool<TSeq>::set_id(int id)
+
12052 {
+
12053  this->id = id;
+
12054 }
+
12055 
+
12056 template<typename TSeq>
+
12057 inline void Tool<TSeq>::set_date(int d)
+
12058 {
+
12059  this->date = d;
+
12060 }
+
12061 
+
12062 template<typename TSeq>
+
12063 inline int Tool<TSeq>::get_date() const
+
12064 {
+
12065  return date;
+
12066 }
+
12067 
+
12068 template<typename TSeq>
+
12069 inline void Tool<TSeq>::set_state(
+
12070  epiworld_fast_int init,
+
12071  epiworld_fast_int end
+
12072 )
+
12073 {
+
12074  state_init = init;
+
12075  state_post = end;
+
12076 }
+
12077 
+
12078 template<typename TSeq>
+
12079 inline void Tool<TSeq>::set_queue(
+
12080  epiworld_fast_int init,
+
12081  epiworld_fast_int end
+
12082 )
+
12083 {
+
12084  queue_init = init;
+
12085  queue_post = end;
+
12086 }
+
12087 
+
12088 template<typename TSeq>
+
12089 inline void Tool<TSeq>::get_state(
+
12090  epiworld_fast_int * init,
+
12091  epiworld_fast_int * post
+
12092 )
+
12093 {
+
12094  if (init != nullptr)
+
12095  *init = state_init;
+
12096 
+
12097  if (post != nullptr)
+
12098  *post = state_post;
+
12099 
+
12100 }
+
12101 
+
12102 template<typename TSeq>
+
12103 inline void Tool<TSeq>::get_queue(
+
12104  epiworld_fast_int * init,
+
12105  epiworld_fast_int * post
+
12106 )
+
12107 {
+
12108  if (init != nullptr)
+
12109  *init = queue_init;
+
12110 
+
12111  if (post != nullptr)
+
12112  *post = queue_post;
+
12113 
+
12114 }
12115 
-
12116 
-
12117  return true;
-
12118 
-
12119 }
-
12120 
-
12121 template<typename TSeq>
-
12122 inline bool Tool<TSeq>::operator==(const Tool<TSeq> & other) const
-
12123 {
-
12124  if (*sequence != *other.sequence)
-
12125  return false;
-
12126 
-
12127  if (tool_name != other.tool_name)
-
12128  return false;
-
12129 
-
12130  if (state_init != other.state_init)
-
12131  return false;
-
12132 
-
12133  if (state_post != other.state_post)
-
12134  return false;
-
12135 
-
12136  if (queue_init != other.queue_init)
-
12137  return false;
-
12138 
-
12139  if (queue_post != other.queue_post)
-
12140  return false;
-
12141 
-
12142  return true;
-
12143 
-
12144 }
+
12116 template<>
+
12117 inline bool Tool<std::vector<int>>::operator==(
+
12118  const Tool<std::vector<int>> & other
+
12119  ) const
+
12120 {
+
12121 
+
12122  if (sequence->size() != other.sequence->size())
+
12123  return false;
+
12124 
+
12125  for (size_t i = 0u; i < sequence->size(); ++i)
+
12126  {
+
12127  if (sequence->operator[](i) != other.sequence->operator[](i))
+
12128  return false;
+
12129  }
+
12130 
+
12131  if (tool_name != other.tool_name)
+
12132  return false;
+
12133 
+
12134  if (state_init != other.state_init)
+
12135  return false;
+
12136 
+
12137  if (state_post != other.state_post)
+
12138  return false;
+
12139 
+
12140  if (queue_init != other.queue_init)
+
12141  return false;
+
12142 
+
12143  if (queue_post != other.queue_post)
+
12144  return false;
12145 
12146 
-
12147 template<typename TSeq>
-
12148 inline void Tool<TSeq>::print() const
-
12149 {
+
12147  return true;
+
12148 
+
12149 }
12150 
-
12151  printf_epiworld("Tool : %s\n", tool_name->c_str());
-
12152  printf_epiworld("Id : %s\n", (id < 0)? std::string("(empty)").c_str() : std::to_string(id).c_str());
-
12153  printf_epiworld("state_init : %i\n", static_cast<int>(state_init));
-
12154  printf_epiworld("state_post : %i\n", static_cast<int>(state_post));
-
12155  printf_epiworld("queue_init : %i\n", static_cast<int>(queue_init));
-
12156  printf_epiworld("queue_post : %i\n", static_cast<int>(queue_post));
-
12157 
-
12158 }
-
12159 
-
12160 template<typename TSeq>
-
12161 inline void Tool<TSeq>::distribute(Model<TSeq> * model)
-
12162 {
-
12163 
-
12164  if (dist_fun)
-
12165  {
-
12166 
-
12167  dist_fun(*this, model);
+
12151 template<typename TSeq>
+
12152 inline bool Tool<TSeq>::operator==(const Tool<TSeq> & other) const
+
12153 {
+
12154  if (*sequence != *other.sequence)
+
12155  return false;
+
12156 
+
12157  if (tool_name != other.tool_name)
+
12158  return false;
+
12159 
+
12160  if (state_init != other.state_init)
+
12161  return false;
+
12162 
+
12163  if (state_post != other.state_post)
+
12164  return false;
+
12165 
+
12166  if (queue_init != other.queue_init)
+
12167  return false;
12168 
-
12169  }
-
12170 
-
12171 }
-
12172 
-
12173 template<typename TSeq>
-
12174 inline void Tool<TSeq>::set_distribution(ToolToAgentFun<TSeq> fun)
-
12175 {
-
12176  dist_fun = fun;
-
12177 }
-
12178 
-
12179 #endif
-
12180 /*//////////////////////////////////////////////////////////////////////////////
-
12182 
-
12183  End of -include/epiworld/tool-meat.hpp-
-
12184 
+
12169  if (queue_post != other.queue_post)
+
12170  return false;
+
12171 
+
12172  return true;
+
12173 
+
12174 }
+
12175 
+
12176 
+
12177 template<typename TSeq>
+
12178 inline void Tool<TSeq>::print() const
+
12179 {
+
12180 
+
12181  printf_epiworld("Tool : %s\n", tool_name->c_str());
+
12182  printf_epiworld("Id : %s\n", (id < 0)? std::string("(empty)").c_str() : std::to_string(id).c_str());
+
12183  printf_epiworld("state_init : %i\n", static_cast<int>(state_init));
+
12184  printf_epiworld("state_post : %i\n", static_cast<int>(state_post));
+
12185  printf_epiworld("queue_init : %i\n", static_cast<int>(queue_init));
+
12186  printf_epiworld("queue_post : %i\n", static_cast<int>(queue_post));
12187 
-
12188 
+
12188 }
12189 
-
12190 /*//////////////////////////////////////////////////////////////////////////////
-
12192 
-
12193  Start of -include/epiworld/entity-bones.hpp-
-
12194 
-
12197 
+
12190 template<typename TSeq>
+
12191 inline void Tool<TSeq>::distribute(Model<TSeq> * model)
+
12192 {
+
12193 
+
12194  if (dist_fun)
+
12195  {
+
12196 
+
12197  dist_fun(*this, model);
12198 
-
12199 #ifndef EPIWORLD_ENTITY_BONES_HPP
-
12200 #define EPIWORLD_ENTITY_BONES_HPP
-
12201 
-
12202 template<typename TSeq>
-
12203 class Model;
-
12204 
-
12205 template<typename TSeq>
-
12206 class Agent;
-
12207 
-
12208 template<typename TSeq>
-
12209 class AgentsSample;
-
12210 
-
12211 template<typename TSeq>
-
12212 inline void default_add_entity(Event<TSeq> & a, Model<TSeq> * m);
-
12213 
-
12214 template<typename TSeq>
-
12215 inline void default_rm_entity(Event<TSeq> & a, Model<TSeq> * m);
-
12216 
-
12217 template<typename TSeq>
-
12218 class Entity {
-
12219  friend class Agent<TSeq>;
-
12220  friend class AgentsSample<TSeq>;
-
12221  friend class Model<TSeq>;
-
12222  friend void default_add_entity<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
12223  friend void default_rm_entity<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
12224 private:
-
12225 
-
12226  int id = -1;
-
12227  std::vector< size_t > agents; ///< Vector of agents
-
12228  std::vector< size_t > agents_location; ///< Location where the entity is stored in the agent
-
12229  size_t n_agents = 0u;
-
12230 
-
12240  std::vector< Agent<TSeq> * > sampled_agents;
-
12241  size_t sampled_agents_n = 0u;
-
12242  std::vector< size_t > sampled_agents_left;
-
12243  size_t sampled_agents_left_n = 0u;
-
12244  // int date_last_add_or_remove = -99; ///< Last time the entity added or removed an agent
+
12199  }
+
12200 
+
12201 }
+
12202 
+
12203 template<typename TSeq>
+
12204 inline void Tool<TSeq>::set_distribution(ToolToAgentFun<TSeq> fun)
+
12205 {
+
12206  dist_fun = fun;
+
12207 }
+
12208 
+
12209 #endif
+
12210 /*//////////////////////////////////////////////////////////////////////////////
+
12212 
+
12213  End of -include/epiworld/tool-meat.hpp-
+
12214 
+
12217 
+
12218 
+
12219 
+
12220 /*//////////////////////////////////////////////////////////////////////////////
+
12222 
+
12223  Start of -include/epiworld/entity-bones.hpp-
+
12224 
+
12227 
+
12228 
+
12229 #ifndef EPIWORLD_ENTITY_BONES_HPP
+
12230 #define EPIWORLD_ENTITY_BONES_HPP
+
12231 
+
12232 template<typename TSeq>
+
12233 class Model;
+
12234 
+
12235 template<typename TSeq>
+
12236 class Agent;
+
12237 
+
12238 template<typename TSeq>
+
12239 class AgentsSample;
+
12240 
+
12241 template<typename TSeq>
+
12242 inline void default_add_entity(Event<TSeq> & a, Model<TSeq> * m);
+
12243 
+
12244 template<typename TSeq>
+
12245 inline void default_rm_entity(Event<TSeq> & a, Model<TSeq> * m);
12246 
-
12247  int max_capacity = -1;
-
12248  std::string entity_name = "Unnamed entity";
-
12249 
-
12250  std::vector< epiworld_double > location = {0.0}; ///< An arbitrary vector for location
-
12251 
-
12252  epiworld_fast_int state_init = -99;
-
12253  epiworld_fast_int state_post = -99;
-
12254 
-
12255  epiworld_fast_int queue_init = 0; ///< Change of state when added to agent.
-
12256  epiworld_fast_int queue_post = 0; ///< Change of state when removed from agent.
-
12257 
-
12258  EntityToAgentFun<TSeq> dist_fun = nullptr;
-
12259 
-
12260 public:
-
12261 
-
12262 
-
12271  Entity(
-
12272  std::string name,
-
12273  EntityToAgentFun<TSeq> fun = nullptr
-
12274  ) :
-
12275  entity_name(name),
-
12276  dist_fun(fun)
-
12277  {};
-
12278 
-
12279  void add_agent(Agent<TSeq> & p, Model<TSeq> * model);
-
12280  void add_agent(Agent<TSeq> * p, Model<TSeq> * model);
-
12281  void rm_agent(size_t idx, Model<TSeq> * model);
-
12282  size_t size() const noexcept;
-
12283  void set_location(std::vector< epiworld_double > loc);
-
12284  std::vector< epiworld_double > & get_location();
-
12285 
-
12286  typename std::vector< Agent<TSeq> * >::iterator begin();
-
12287  typename std::vector< Agent<TSeq> * >::iterator end();
-
12288 
-
12289  typename std::vector< Agent<TSeq> * >::const_iterator begin() const;
-
12290  typename std::vector< Agent<TSeq> * >::const_iterator end() const;
+
12247 template<typename TSeq>
+
12248 class Entity {
+
12249  friend class Agent<TSeq>;
+
12250  friend class AgentsSample<TSeq>;
+
12251  friend class Model<TSeq>;
+
12252  friend void default_add_entity<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
12253  friend void default_rm_entity<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
12254 private:
+
12255 
+
12256  int id = -1;
+
12257  std::vector< size_t > agents; ///< Vector of agents
+
12258  std::vector< size_t > agents_location; ///< Location where the entity is stored in the agent
+
12259  size_t n_agents = 0u;
+
12260 
+
12270  std::vector< Agent<TSeq> * > sampled_agents;
+
12271  size_t sampled_agents_n = 0u;
+
12272  std::vector< size_t > sampled_agents_left;
+
12273  size_t sampled_agents_left_n = 0u;
+
12274  // int date_last_add_or_remove = -99; ///< Last time the entity added or removed an agent
+
12276 
+
12277  int max_capacity = -1;
+
12278  std::string entity_name = "Unnamed entity";
+
12279 
+
12280  std::vector< epiworld_double > location = {0.0}; ///< An arbitrary vector for location
+
12281 
+
12282  epiworld_fast_int state_init = -99;
+
12283  epiworld_fast_int state_post = -99;
+
12284 
+
12285  epiworld_fast_int queue_init = 0; ///< Change of state when added to agent.
+
12286  epiworld_fast_int queue_post = 0; ///< Change of state when removed from agent.
+
12287 
+
12288  EntityToAgentFun<TSeq> dist_fun = nullptr;
+
12289 
+
12290 public:
12291 
-
12292  size_t operator[](size_t i);
-
12293 
-
12294  int get_id() const noexcept;
-
12295  const std::string & get_name() const noexcept;
-
12296 
-
12297  void set_state(epiworld_fast_int init, epiworld_fast_int post);
-
12298  void set_queue(epiworld_fast_int init, epiworld_fast_int post);
-
12299  void get_state(epiworld_fast_int * init, epiworld_fast_int * post);
-
12300  void get_queue(epiworld_fast_int * init, epiworld_fast_int * post);
-
12301 
-
12302  void reset();
-
12303 
-
12304  bool operator==(const Entity<TSeq> & other) const;
-
12305  bool operator!=(const Entity<TSeq> & other) const {return !operator==(other);};
-
12306 
-
12314  void distribute(Model<TSeq> * model);
+
12292 
+
12301  Entity(
+
12302  std::string name,
+
12303  EntityToAgentFun<TSeq> fun = nullptr
+
12304  ) :
+
12305  entity_name(name),
+
12306  dist_fun(fun)
+
12307  {};
+
12308 
+
12309  void add_agent(Agent<TSeq> & p, Model<TSeq> * model);
+
12310  void add_agent(Agent<TSeq> * p, Model<TSeq> * model);
+
12311  void rm_agent(size_t idx, Model<TSeq> * model);
+
12312  size_t size() const noexcept;
+
12313  void set_location(std::vector< epiworld_double > loc);
+
12314  std::vector< epiworld_double > & get_location();
12315 
-
12316  std::vector< size_t > & get_agents();
-
12317 
-
12318  void print() const;
-
12319  void set_distribution(EntityToAgentFun<TSeq> fun);
-
12320 
-
12321 };
-
12322 
+
12316  typename std::vector< Agent<TSeq> * >::iterator begin();
+
12317  typename std::vector< Agent<TSeq> * >::iterator end();
+
12318 
+
12319  typename std::vector< Agent<TSeq> * >::const_iterator begin() const;
+
12320  typename std::vector< Agent<TSeq> * >::const_iterator end() const;
+
12321 
+
12322  size_t operator[](size_t i);
12323 
-
12324 #endif
-
12325 /*//////////////////////////////////////////////////////////////////////////////
-
12327 
-
12328  End of -include/epiworld/entity-bones.hpp-
-
12329 
-
12332 
+
12324  int get_id() const noexcept;
+
12325  const std::string & get_name() const noexcept;
+
12326 
+
12327  void set_state(epiworld_fast_int init, epiworld_fast_int post);
+
12328  void set_queue(epiworld_fast_int init, epiworld_fast_int post);
+
12329  void get_state(epiworld_fast_int * init, epiworld_fast_int * post);
+
12330  void get_queue(epiworld_fast_int * init, epiworld_fast_int * post);
+
12331 
+
12332  void reset();
12333 
-
12334 /*//////////////////////////////////////////////////////////////////////////////
+
12334  bool operator==(const Entity<TSeq> & other) const;
+
12335  bool operator!=(const Entity<TSeq> & other) const {return !operator==(other);};
12336 
-
12337  Start of -include/epiworld/entity-distribute-meat.hpp-
-
12338 
-
12341 
-
12342 
-
12343 #ifndef EPIWORLD_ENTITY_DISTRIBUTE_MEAT_HPP
-
12344 #define EPIWORLD_ENTITY_DISTRIBUTE_MEAT_HPP
+
12344  void distribute(Model<TSeq> * model);
12345 
-
12346 
-
12347 template <typename TSeq = EPI_DEFAULT_TSEQ>
-
12358 inline EntityToAgentFun<TSeq> distribute_entity_randomly(
-
12359  epiworld_double prevalence,
-
12360  bool as_proportion,
-
12361  bool to_unassigned
-
12362 )
-
12363 {
-
12364 
-
12365  return [prevalence, as_proportion, to_unassigned](
-
12366  Entity<TSeq> & e, Model<TSeq> * m
-
12367  ) -> void {
+
12346  std::vector< size_t > & get_agents();
+
12347 
+
12348  void print() const;
+
12349  void set_distribution(EntityToAgentFun<TSeq> fun);
+
12350 
+
12351 };
+
12352 
+
12353 
+
12354 #endif
+
12355 /*//////////////////////////////////////////////////////////////////////////////
+
12357 
+
12358  End of -include/epiworld/entity-bones.hpp-
+
12359 
+
12362 
+
12363 
+
12364 /*//////////////////////////////////////////////////////////////////////////////
+
12366 
+
12367  Start of -include/epiworld/entity-distribute-meat.hpp-
12368 
-
12369 
-
12370  // Preparing the sampling space
-
12371  std::vector< size_t > idx;
-
12372  if (to_unassigned)
-
12373  {
-
12374  for (const auto & a: m->get_agents())
-
12375  if (a.get_n_entities() == 0)
-
12376  idx.push_back(a.get_id());
-
12377  }
-
12378  else
-
12379  {
-
12380 
-
12381  for (const auto & a: m->get_agents())
-
12382  idx.push_back(a.get_id());
-
12383 
-
12384  }
-
12385 
-
12386  size_t n = idx.size();
-
12387 
-
12388  // Figuring out how many to sample
-
12389  int n_to_sample;
-
12390  if (as_proportion)
-
12391  {
-
12392  n_to_sample = static_cast<int>(std::floor(prevalence * n));
-
12393  if (n_to_sample > static_cast<int>(n))
-
12394  --n_to_sample;
-
12395 
-
12396  } else
-
12397  {
-
12398  n_to_sample = static_cast<int>(prevalence);
-
12399  if (n_to_sample > static_cast<int>(n))
-
12400  throw std::range_error("There are only " + std::to_string(n) +
-
12401  " individuals in the population. Cannot add the entity to " +
-
12402  std::to_string(n_to_sample));
-
12403  }
-
12404 
-
12405  int n_left = n;
-
12406  for (int i = 0; i < n_to_sample; ++i)
-
12407  {
-
12408  int loc = static_cast<epiworld_fast_uint>(
-
12409  floor(m->runif() * n_left--)
-
12410  );
-
12411 
-
12412  // Correcting for possible overflow
-
12413  if ((loc > 0) && (loc >= n_left))
-
12414  loc = n_left - 1;
-
12415 
-
12416  m->get_agent(idx[loc]).add_entity(e, m);
+
12371 
+
12372 
+
12373 #ifndef EPIWORLD_ENTITY_DISTRIBUTE_MEAT_HPP
+
12374 #define EPIWORLD_ENTITY_DISTRIBUTE_MEAT_HPP
+
12375 
+
12376 
+
12377 template <typename TSeq = EPI_DEFAULT_TSEQ>
+
12388 inline EntityToAgentFun<TSeq> distribute_entity_randomly(
+
12389  epiworld_double prevalence,
+
12390  bool as_proportion,
+
12391  bool to_unassigned
+
12392 )
+
12393 {
+
12394 
+
12395  return [prevalence, as_proportion, to_unassigned](
+
12396  Entity<TSeq> & e, Model<TSeq> * m
+
12397  ) -> void {
+
12398 
+
12399 
+
12400  // Preparing the sampling space
+
12401  std::vector< size_t > idx;
+
12402  if (to_unassigned)
+
12403  {
+
12404  for (const auto & a: m->get_agents())
+
12405  if (a.get_n_entities() == 0)
+
12406  idx.push_back(a.get_id());
+
12407  }
+
12408  else
+
12409  {
+
12410 
+
12411  for (const auto & a: m->get_agents())
+
12412  idx.push_back(a.get_id());
+
12413 
+
12414  }
+
12415 
+
12416  size_t n = idx.size();
12417 
-
12418  std::swap(idx[loc], idx[n_left]);
-
12419 
-
12420  }
-
12421 
-
12422  };
-
12423 
-
12424 }
+
12418  // Figuring out how many to sample
+
12419  int n_to_sample;
+
12420  if (as_proportion)
+
12421  {
+
12422  n_to_sample = static_cast<int>(std::floor(prevalence * n));
+
12423  if (n_to_sample > static_cast<int>(n))
+
12424  --n_to_sample;
12425 
-
12426 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
12437 inline EntityToAgentFun<TSeq> distribute_entity_to_range(
-
12438  int from,
-
12439  int to,
-
12440  bool to_unassigned = false
-
12441  ) {
-
12442 
-
12443  if (to_unassigned)
-
12444  {
+
12426  } else
+
12427  {
+
12428  n_to_sample = static_cast<int>(prevalence);
+
12429  if (n_to_sample > static_cast<int>(n))
+
12430  throw std::range_error("There are only " + std::to_string(n) +
+
12431  " individuals in the population. Cannot add the entity to " +
+
12432  std::to_string(n_to_sample));
+
12433  }
+
12434 
+
12435  int n_left = n;
+
12436  for (int i = 0; i < n_to_sample; ++i)
+
12437  {
+
12438  int loc = static_cast<epiworld_fast_uint>(
+
12439  floor(m->runif() * n_left--)
+
12440  );
+
12441 
+
12442  // Correcting for possible overflow
+
12443  if ((loc > 0) && (loc >= n_left))
+
12444  loc = n_left - 1;
12445 
-
12446  return [from, to](Entity<TSeq> & e, Model<TSeq> * m) -> void {
+
12446  m->get_agent(idx[loc]).add_entity(e, m);
12447 
-
12448  auto & agents = m->get_agents();
-
12449  for (size_t i = from; i < to; ++i)
-
12450  {
-
12451  if (agents[i].get_n_entities() == 0)
-
12452  e.add_agent(&agents[i], m);
-
12453  else
-
12454  throw std::logic_error(
-
12455  "Agent " + std::to_string(i) + " already has an entity."
-
12456  );
-
12457  }
-
12458 
-
12459  return;
-
12460 
-
12461  };
-
12462 
-
12463  }
-
12464  else
-
12465  {
-
12466 
-
12467  return [from, to](Entity<TSeq> & e, Model<TSeq> * m) -> void {
-
12468 
-
12469  auto & agents = m->get_agents();
-
12470  for (size_t i = from; i < to; ++i)
-
12471  {
-
12472  e.add_agent(&agents[i], m);
-
12473  }
-
12474 
-
12475  return;
-
12476 
-
12477  };
-
12478 
-
12479  }
-
12480 }
-
12481 
-
12482 
-
12483 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
12484 inline EntityToAgentFun<TSeq> distribute_entity_to_set(
-
12485  std::vector< size_t > & idx
-
12486  ) {
-
12487 
-
12488  return [idx](Entity<TSeq> & e, Model<TSeq> * m) -> void {
-
12489 
-
12490  for (const auto & i: idx)
-
12491  {
-
12492  e.add_agent(&m->get_agent(i), m);
-
12493  }
-
12494 
-
12495  };
+
12448  std::swap(idx[loc], idx[n_left]);
+
12449 
+
12450  }
+
12451 
+
12452  };
+
12453 
+
12454 }
+
12455 
+
12456 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
12467 inline EntityToAgentFun<TSeq> distribute_entity_to_range(
+
12468  int from,
+
12469  int to,
+
12470  bool to_unassigned = false
+
12471  ) {
+
12472 
+
12473  if (to_unassigned)
+
12474  {
+
12475 
+
12476  return [from, to](Entity<TSeq> & e, Model<TSeq> * m) -> void {
+
12477 
+
12478  auto & agents = m->get_agents();
+
12479  for (size_t i = from; i < to; ++i)
+
12480  {
+
12481  if (agents[i].get_n_entities() == 0)
+
12482  e.add_agent(&agents[i], m);
+
12483  else
+
12484  throw std::logic_error(
+
12485  "Agent " + std::to_string(i) + " already has an entity."
+
12486  );
+
12487  }
+
12488 
+
12489  return;
+
12490 
+
12491  };
+
12492 
+
12493  }
+
12494  else
+
12495  {
12496 
-
12497 }
+
12497  return [from, to](Entity<TSeq> & e, Model<TSeq> * m) -> void {
12498 
-
12499 #endif
-
12500 /*//////////////////////////////////////////////////////////////////////////////
-
12502 
-
12503  End of -include/epiworld/entity-distribute-meat.hpp-
-
12504 
-
12507 
+
12499  auto & agents = m->get_agents();
+
12500  for (size_t i = from; i < to; ++i)
+
12501  {
+
12502  e.add_agent(&agents[i], m);
+
12503  }
+
12504 
+
12505  return;
+
12506 
+
12507  };
12508 
-
12509 /*//////////////////////////////////////////////////////////////////////////////
+
12509  }
+
12510 }
12511 
-
12512  Start of -include/epiworld/entity-meat.hpp-
-
12513 
-
12516 
+
12512 
+
12513 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
12514 inline EntityToAgentFun<TSeq> distribute_entity_to_set(
+
12515  std::vector< size_t > & idx
+
12516  ) {
12517 
-
12518 #ifndef EPIWORLD_ENTITY_MEAT_HPP
-
12519 #define EPIWORLD_ENTITY_MEAT_HPP
-
12520 
-
12521 template<typename TSeq>
-
12522 inline void Entity<TSeq>::add_agent(
-
12523  Agent<TSeq> & p,
-
12524  Model<TSeq> * model
-
12525  )
-
12526 {
-
12527 
-
12528  // Need to add it to the events, through the individual
-
12529  p.add_entity(*this, model);
-
12530 
-
12531 }
+
12518  return [idx](Entity<TSeq> & e, Model<TSeq> * m) -> void {
+
12519 
+
12520  for (const auto & i: idx)
+
12521  {
+
12522  e.add_agent(&m->get_agent(i), m);
+
12523  }
+
12524 
+
12525  };
+
12526 
+
12527 }
+
12528 
+
12529 #endif
+
12530 /*//////////////////////////////////////////////////////////////////////////////
12532 
-
12533 template<typename TSeq>
-
12534 inline void Entity<TSeq>::add_agent(
-
12535  Agent<TSeq> * p,
-
12536  Model<TSeq> * model
-
12537  )
-
12538 {
-
12539  p->add_entity(*this, model);
-
12540 }
+
12533  End of -include/epiworld/entity-distribute-meat.hpp-
+
12534 
+
12537 
+
12538 
+
12539 /*//////////////////////////////////////////////////////////////////////////////
12541 
-
12542 template<typename TSeq>
-
12543 inline void Entity<TSeq>::rm_agent(size_t idx, Model<TSeq> * model)
-
12544 {
-
12545  if (idx >= n_agents)
-
12546  throw std::out_of_range(
-
12547  "Trying to remove agent "+ std::to_string(idx) +
-
12548  " out of " + std::to_string(n_agents)
-
12549  );
+
12542  Start of -include/epiworld/entity-meat.hpp-
+
12543 
+
12546 
+
12547 
+
12548 #ifndef EPIWORLD_ENTITY_MEAT_HPP
+
12549 #define EPIWORLD_ENTITY_MEAT_HPP
12550 
-
12551  model->get_agents()[agents[idx]].rm_entity(*this, model);
-
12552 
-
12553  return;
-
12554 }
-
12555 
-
12556 template<typename TSeq>
-
12557 inline size_t Entity<TSeq>::size() const noexcept
-
12558 {
-
12559  return n_agents;
-
12560 }
-
12561 
-
12562 template<typename TSeq>
-
12563 inline void Entity<TSeq>::set_location(std::vector< epiworld_double > loc)
-
12564 {
-
12565  location = loc;
-
12566 }
-
12567 
-
12568 template<typename TSeq>
-
12569 inline std::vector< epiworld_double > & Entity<TSeq>::get_location()
-
12570 {
-
12571  return location;
-
12572 }
-
12573 
-
12574 template<typename TSeq>
-
12575 inline typename std::vector< Agent<TSeq> * >::iterator Entity<TSeq>::begin()
-
12576 {
-
12577 
-
12578  if (n_agents == 0)
-
12579  return agents.end();
+
12551 template<typename TSeq>
+
12552 inline void Entity<TSeq>::add_agent(
+
12553  Agent<TSeq> & p,
+
12554  Model<TSeq> * model
+
12555  )
+
12556 {
+
12557 
+
12558  // Need to add it to the events, through the individual
+
12559  p.add_entity(*this, model);
+
12560 
+
12561 }
+
12562 
+
12563 template<typename TSeq>
+
12564 inline void Entity<TSeq>::add_agent(
+
12565  Agent<TSeq> * p,
+
12566  Model<TSeq> * model
+
12567  )
+
12568 {
+
12569  p->add_entity(*this, model);
+
12570 }
+
12571 
+
12572 template<typename TSeq>
+
12573 inline void Entity<TSeq>::rm_agent(size_t idx, Model<TSeq> * model)
+
12574 {
+
12575  if (idx >= n_agents)
+
12576  throw std::out_of_range(
+
12577  "Trying to remove agent "+ std::to_string(idx) +
+
12578  " out of " + std::to_string(n_agents)
+
12579  );
12580 
-
12581  return agents.begin();
+
12581  model->get_agents()[agents[idx]].rm_entity(*this, model);
12582 
-
12583 }
-
12584 
-
12585 template<typename TSeq>
-
12586 inline typename std::vector< Agent<TSeq> * >::iterator Entity<TSeq>::end()
-
12587 {
-
12588  return agents.begin() + n_agents;
-
12589 }
-
12590 
-
12591 template<typename TSeq>
-
12592 inline typename std::vector< Agent<TSeq> * >::const_iterator Entity<TSeq>::begin() const
-
12593 {
-
12594 
-
12595  if (n_agents == 0)
-
12596  return agents.end();
+
12583  return;
+
12584 }
+
12585 
+
12586 template<typename TSeq>
+
12587 inline size_t Entity<TSeq>::size() const noexcept
+
12588 {
+
12589  return n_agents;
+
12590 }
+
12591 
+
12592 template<typename TSeq>
+
12593 inline void Entity<TSeq>::set_location(std::vector< epiworld_double > loc)
+
12594 {
+
12595  location = loc;
+
12596 }
12597 
-
12598  return agents.begin();
-
12599 
-
12600 }
-
12601 
-
12602 template<typename TSeq>
-
12603 inline typename std::vector< Agent<TSeq> * >::const_iterator Entity<TSeq>::end() const
-
12604 {
-
12605  return agents.begin() + n_agents;
-
12606 }
+
12598 template<typename TSeq>
+
12599 inline std::vector< epiworld_double > & Entity<TSeq>::get_location()
+
12600 {
+
12601  return location;
+
12602 }
+
12603 
+
12604 template<typename TSeq>
+
12605 inline typename std::vector< Agent<TSeq> * >::iterator Entity<TSeq>::begin()
+
12606 {
12607 
-
12608 template<typename TSeq>
-
12609 size_t Entity<TSeq>::operator[](size_t i)
-
12610 {
-
12611  if (n_agents <= i)
-
12612  throw std::logic_error(
-
12613  "There are not that many agents in this entity. " +
-
12614  std::to_string(n_agents) + " <= " + std::to_string(i)
-
12615  );
-
12616 
-
12617  return i;
-
12618 }
-
12619 
-
12620 template<typename TSeq>
-
12621 inline int Entity<TSeq>::get_id() const noexcept
-
12622 {
-
12623  return id;
-
12624 }
-
12625 
-
12626 template<typename TSeq>
-
12627 inline const std::string & Entity<TSeq>::get_name() const noexcept
-
12628 {
-
12629  return entity_name;
+
12608  if (n_agents == 0)
+
12609  return agents.end();
+
12610 
+
12611  return agents.begin();
+
12612 
+
12613 }
+
12614 
+
12615 template<typename TSeq>
+
12616 inline typename std::vector< Agent<TSeq> * >::iterator Entity<TSeq>::end()
+
12617 {
+
12618  return agents.begin() + n_agents;
+
12619 }
+
12620 
+
12621 template<typename TSeq>
+
12622 inline typename std::vector< Agent<TSeq> * >::const_iterator Entity<TSeq>::begin() const
+
12623 {
+
12624 
+
12625  if (n_agents == 0)
+
12626  return agents.end();
+
12627 
+
12628  return agents.begin();
+
12629 
12630 }
12631 
12632 template<typename TSeq>
-
12633 inline void Entity<TSeq>::set_state(
-
12634  epiworld_fast_int init,
-
12635  epiworld_fast_int end
-
12636 )
-
12637 {
-
12638  state_init = init;
-
12639  state_post = end;
-
12640 }
-
12641 
-
12642 template<typename TSeq>
-
12643 inline void Entity<TSeq>::set_queue(
-
12644  epiworld_fast_int init,
-
12645  epiworld_fast_int end
-
12646 )
-
12647 {
-
12648  queue_init = init;
-
12649  queue_post = end;
-
12650 }
-
12651 
-
12652 template<typename TSeq>
-
12653 inline void Entity<TSeq>::get_state(
-
12654  epiworld_fast_int * init,
-
12655  epiworld_fast_int * post
-
12656 )
-
12657 {
-
12658  if (init != nullptr)
-
12659  *init = state_init;
-
12660 
-
12661  if (post != nullptr)
-
12662  *post = state_post;
-
12663 
-
12664 }
-
12665 
-
12666 template<typename TSeq>
-
12667 inline void Entity<TSeq>::get_queue(
-
12668  epiworld_fast_int * init,
-
12669  epiworld_fast_int * post
-
12670 )
-
12671 {
-
12672  if (init != nullptr)
-
12673  *init = queue_init;
-
12674 
-
12675  if (post != nullptr)
-
12676  *post = queue_post;
-
12677 
-
12678 }
-
12679 
-
12680 template<typename TSeq>
-
12681 inline void Entity<TSeq>::reset()
-
12682 {
-
12683  sampled_agents.clear();
-
12684  sampled_agents_n = 0u;
-
12685  sampled_agents_left.clear();
-
12686  sampled_agents_left_n = 0u;
-
12687 
-
12688  this->agents.clear();
-
12689  this->n_agents = 0u;
-
12690  this->agents_location.clear();
-
12691 
-
12692  return;
+
12633 inline typename std::vector< Agent<TSeq> * >::const_iterator Entity<TSeq>::end() const
+
12634 {
+
12635  return agents.begin() + n_agents;
+
12636 }
+
12637 
+
12638 template<typename TSeq>
+
12639 size_t Entity<TSeq>::operator[](size_t i)
+
12640 {
+
12641  if (n_agents <= i)
+
12642  throw std::logic_error(
+
12643  "There are not that many agents in this entity. " +
+
12644  std::to_string(n_agents) + " <= " + std::to_string(i)
+
12645  );
+
12646 
+
12647  return i;
+
12648 }
+
12649 
+
12650 template<typename TSeq>
+
12651 inline int Entity<TSeq>::get_id() const noexcept
+
12652 {
+
12653  return id;
+
12654 }
+
12655 
+
12656 template<typename TSeq>
+
12657 inline const std::string & Entity<TSeq>::get_name() const noexcept
+
12658 {
+
12659  return entity_name;
+
12660 }
+
12661 
+
12662 template<typename TSeq>
+
12663 inline void Entity<TSeq>::set_state(
+
12664  epiworld_fast_int init,
+
12665  epiworld_fast_int end
+
12666 )
+
12667 {
+
12668  state_init = init;
+
12669  state_post = end;
+
12670 }
+
12671 
+
12672 template<typename TSeq>
+
12673 inline void Entity<TSeq>::set_queue(
+
12674  epiworld_fast_int init,
+
12675  epiworld_fast_int end
+
12676 )
+
12677 {
+
12678  queue_init = init;
+
12679  queue_post = end;
+
12680 }
+
12681 
+
12682 template<typename TSeq>
+
12683 inline void Entity<TSeq>::get_state(
+
12684  epiworld_fast_int * init,
+
12685  epiworld_fast_int * post
+
12686 )
+
12687 {
+
12688  if (init != nullptr)
+
12689  *init = state_init;
+
12690 
+
12691  if (post != nullptr)
+
12692  *post = state_post;
12693 
12694 }
12695 
12696 template<typename TSeq>
-
12697 inline bool Entity<TSeq>::operator==(const Entity<TSeq> & other) const
-
12698 {
-
12699 
-
12700  if (id != other.id)
-
12701  return false;
-
12702 
-
12703  if (n_agents != other.n_agents)
-
12704  return false;
-
12705 
-
12706  for (size_t i = 0u; i < n_agents; ++i)
-
12707  {
-
12708  if (agents[i] != other.agents[i])
-
12709  return false;
-
12710  }
-
12711 
-
12712 
-
12713  if (max_capacity != other.max_capacity)
-
12714  return false;
-
12715 
-
12716  if (entity_name != other.entity_name)
-
12717  return false;
-
12718 
-
12719  if (location.size() != other.location.size())
-
12720  return false;
+
12697 inline void Entity<TSeq>::get_queue(
+
12698  epiworld_fast_int * init,
+
12699  epiworld_fast_int * post
+
12700 )
+
12701 {
+
12702  if (init != nullptr)
+
12703  *init = queue_init;
+
12704 
+
12705  if (post != nullptr)
+
12706  *post = queue_post;
+
12707 
+
12708 }
+
12709 
+
12710 template<typename TSeq>
+
12711 inline void Entity<TSeq>::reset()
+
12712 {
+
12713  sampled_agents.clear();
+
12714  sampled_agents_n = 0u;
+
12715  sampled_agents_left.clear();
+
12716  sampled_agents_left_n = 0u;
+
12717 
+
12718  this->agents.clear();
+
12719  this->n_agents = 0u;
+
12720  this->agents_location.clear();
12721 
-
12722  for (size_t i = 0u; i < location.size(); ++i)
-
12723  {
-
12724 
-
12725  if (location[i] != other.location[i])
-
12726  return false;
-
12727 
-
12728  }
+
12722  return;
+
12723 
+
12724 }
+
12725 
+
12726 template<typename TSeq>
+
12727 inline bool Entity<TSeq>::operator==(const Entity<TSeq> & other) const
+
12728 {
12729 
-
12730  if (state_init != other.state_init)
+
12730  if (id != other.id)
12731  return false;
12732 
-
12733  if (state_post != other.state_post)
+
12733  if (n_agents != other.n_agents)
12734  return false;
12735 
-
12736  if (queue_init != other.queue_init)
-
12737  return false;
-
12738 
-
12739  if (queue_post != other.queue_post)
-
12740  return false;
+
12736  for (size_t i = 0u; i < n_agents; ++i)
+
12737  {
+
12738  if (agents[i] != other.agents[i])
+
12739  return false;
+
12740  }
12741 
-
12742  return true;
-
12743 
-
12744 }
+
12742 
+
12743  if (max_capacity != other.max_capacity)
+
12744  return false;
12745 
-
12746 template<typename TSeq>
-
12747 inline void Entity<TSeq>::distribute(Model<TSeq> * model)
-
12748 {
-
12749 
-
12750  if (dist_fun)
-
12751  {
-
12752 
-
12753  dist_fun(*this, model);
+
12746  if (entity_name != other.entity_name)
+
12747  return false;
+
12748 
+
12749  if (location.size() != other.location.size())
+
12750  return false;
+
12751 
+
12752  for (size_t i = 0u; i < location.size(); ++i)
+
12753  {
12754 
-
12755  }
-
12756 
-
12757 }
-
12758 
-
12759 template<typename TSeq>
-
12760 inline std::vector< size_t > & Entity<TSeq>::get_agents()
-
12761 {
-
12762  return agents;
-
12763 }
-
12764 
-
12765 template<typename TSeq>
-
12766 inline void Entity<TSeq>::print() const
-
12767 {
+
12755  if (location[i] != other.location[i])
+
12756  return false;
+
12757 
+
12758  }
+
12759 
+
12760  if (state_init != other.state_init)
+
12761  return false;
+
12762 
+
12763  if (state_post != other.state_post)
+
12764  return false;
+
12765 
+
12766  if (queue_init != other.queue_init)
+
12767  return false;
12768 
-
12769  printf_epiworld(
-
12770  "Entity '%s' (id %i) with %i agents.\n",
-
12771  this->entity_name.c_str(),
-
12772  static_cast<int>(id),
-
12773  static_cast<int>(n_agents)
-
12774  );
-
12775 }
-
12776 
-
12777 template<typename TSeq>
-
12778 inline void Entity<TSeq>::set_distribution(EntityToAgentFun<TSeq> fun)
-
12779 {
-
12780  dist_fun = fun;
-
12781 }
+
12769  if (queue_post != other.queue_post)
+
12770  return false;
+
12771 
+
12772  return true;
+
12773 
+
12774 }
+
12775 
+
12776 template<typename TSeq>
+
12777 inline void Entity<TSeq>::distribute(Model<TSeq> * model)
+
12778 {
+
12779 
+
12780  if (dist_fun)
+
12781  {
12782 
-
12783 #endif
-
12784 /*//////////////////////////////////////////////////////////////////////////////
+
12783  dist_fun(*this, model);
+
12784 
+
12785  }
12786 
-
12787  End of -include/epiworld/entity-meat.hpp-
+
12787 }
12788 
-
12791 
-
12792 
-
12793 
-
12794 /*//////////////////////////////////////////////////////////////////////////////
-
12796 
-
12797  Start of -include/epiworld/entities-bones.hpp-
+
12789 template<typename TSeq>
+
12790 inline std::vector< size_t > & Entity<TSeq>::get_agents()
+
12791 {
+
12792  return agents;
+
12793 }
+
12794 
+
12795 template<typename TSeq>
+
12796 inline void Entity<TSeq>::print() const
+
12797 {
12798 
-
12801 
-
12802 
-
12803 #ifndef EPIWORLD_ENTITIES_BONES_HPP
-
12804 #define EPIWORLD_ENTITIES_BONES_HPP
-
12805 
-
12806 template<typename TSeq>
-
12807 class Virus;
-
12808 
-
12809 template<typename TSeq>
-
12810 class Agent;
-
12811 
+
12799  printf_epiworld(
+
12800  "Entity '%s' (id %i) with %i agents.\n",
+
12801  this->entity_name.c_str(),
+
12802  static_cast<int>(id),
+
12803  static_cast<int>(n_agents)
+
12804  );
+
12805 }
+
12806 
+
12807 template<typename TSeq>
+
12808 inline void Entity<TSeq>::set_distribution(EntityToAgentFun<TSeq> fun)
+
12809 {
+
12810  dist_fun = fun;
+
12811 }
12812 
-
12818 template<typename TSeq>
-
12819 class Entities {
-
12820  friend class Entity<TSeq>;
-
12821  friend class Agent<TSeq>;
-
12822 private:
-
12823  std::vector< Entity<TSeq> * > dat;
-
12824  const size_t n_entities;
-
12825 
-
12826 public:
-
12827 
-
12828  Entities() = delete;
-
12829  Entities(Agent<TSeq> & p);
-
12830 
-
12831  typename std::vector< Entity<TSeq> * >::iterator begin();
-
12832  typename std::vector< Entity<TSeq> * >::iterator end();
-
12833 
-
12834  Entity<TSeq> & operator()(size_t i);
-
12835  Entity<TSeq> & operator[](size_t i);
-
12836 
-
12837  size_t size() const noexcept;
+
12813 #endif
+
12814 /*//////////////////////////////////////////////////////////////////////////////
+
12816 
+
12817  End of -include/epiworld/entity-meat.hpp-
+
12818 
+
12821 
+
12822 
+
12823 
+
12824 /*//////////////////////////////////////////////////////////////////////////////
+
12826 
+
12827  Start of -include/epiworld/entities-bones.hpp-
+
12828 
+
12831 
+
12832 
+
12833 #ifndef EPIWORLD_ENTITIES_BONES_HPP
+
12834 #define EPIWORLD_ENTITIES_BONES_HPP
+
12835 
+
12836 template<typename TSeq>
+
12837 class Virus;
12838 
-
12839  bool operator==(const Entities<TSeq> & other) const;
-
12840 
-
12841 };
+
12839 template<typename TSeq>
+
12840 class Agent;
+
12841 
12842 
-
12843 template<typename TSeq>
-
12844 inline Entities<TSeq>::Entities(Agent<TSeq> & p) :
-
12845  n_entities(p.get_n_entities())
-
12846 {
-
12847 
-
12848  dat.reserve(n_entities);
-
12849  for (size_t i = 0u; i < n_entities; ++i)
-
12850  dat.push_back(&p.get_entity(i));
-
12851 
-
12852 }
-
12853 
-
12854 template<typename TSeq>
-
12855 inline typename std::vector< Entity<TSeq>* >::iterator Entities<TSeq>::begin()
-
12856 {
+
12848 template<typename TSeq>
+
12849 class Entities {
+
12850  friend class Entity<TSeq>;
+
12851  friend class Agent<TSeq>;
+
12852 private:
+
12853  std::vector< Entity<TSeq> * > dat;
+
12854  const size_t n_entities;
+
12855 
+
12856 public:
12857 
-
12858  if (n_entities == 0u)
-
12859  return dat.end();
-
12860 
-
12861  return dat.begin();
-
12862 }
+
12858  Entities() = delete;
+
12859  Entities(Agent<TSeq> & p);
+
12860 
+
12861  typename std::vector< Entity<TSeq> * >::iterator begin();
+
12862  typename std::vector< Entity<TSeq> * >::iterator end();
12863 
-
12864 template<typename TSeq>
-
12865 inline typename std::vector< Entity<TSeq>* >::iterator Entities<TSeq>::end()
-
12866 {
-
12867 
-
12868  return begin() + n_entities;
-
12869 }
+
12864  Entity<TSeq> & operator()(size_t i);
+
12865  Entity<TSeq> & operator[](size_t i);
+
12866 
+
12867  size_t size() const noexcept;
+
12868 
+
12869  bool operator==(const Entities<TSeq> & other) const;
12870 
-
12871 template<typename TSeq>
-
12872 inline Entity<TSeq> & Entities<TSeq>::operator()(size_t i)
-
12873 {
-
12874 
-
12875  if (i >= n_entities)
-
12876  throw std::range_error("Entity index out of range.");
+
12871 };
+
12872 
+
12873 template<typename TSeq>
+
12874 inline Entities<TSeq>::Entities(Agent<TSeq> & p) :
+
12875  n_entities(p.get_n_entities())
+
12876 {
12877 
-
12878  return *dat[i];
-
12879 
-
12880 }
+
12878  dat.reserve(n_entities);
+
12879  for (size_t i = 0u; i < n_entities; ++i)
+
12880  dat.push_back(&p.get_entity(i));
12881 
-
12882 template<typename TSeq>
-
12883 inline Entity<TSeq> & Entities<TSeq>::operator[](size_t i)
-
12884 {
-
12885 
-
12886  return *dat[i];
+
12882 }
+
12883 
+
12884 template<typename TSeq>
+
12885 inline typename std::vector< Entity<TSeq>* >::iterator Entities<TSeq>::begin()
+
12886 {
12887 
-
12888 }
-
12889 
-
12890 template<typename TSeq>
-
12891 inline size_t Entities<TSeq>::size() const noexcept
-
12892 {
-
12893  return n_entities;
-
12894 }
-
12895 
-
12896 template<typename TSeq>
-
12897 inline bool Entities<TSeq>::operator==(const Entities<TSeq> & other) const
-
12898 {
-
12899 
-
12900  if (n_entities != other.n_entities)
-
12901  return false;
-
12902 
-
12903  for (size_t i = 0u; i < dat.size(); ++i)
-
12904  {
-
12905  if (dat[i] != other.dat[i])
-
12906  return false;
-
12907  }
-
12908 
-
12909  return true;
+
12888  if (n_entities == 0u)
+
12889  return dat.end();
+
12890 
+
12891  return dat.begin();
+
12892 }
+
12893 
+
12894 template<typename TSeq>
+
12895 inline typename std::vector< Entity<TSeq>* >::iterator Entities<TSeq>::end()
+
12896 {
+
12897 
+
12898  return begin() + n_entities;
+
12899 }
+
12900 
+
12901 template<typename TSeq>
+
12902 inline Entity<TSeq> & Entities<TSeq>::operator()(size_t i)
+
12903 {
+
12904 
+
12905  if (i >= n_entities)
+
12906  throw std::range_error("Entity index out of range.");
+
12907 
+
12908  return *dat[i];
+
12909 
12910 }
12911 
-
12917 template<typename TSeq>
-
12918 class Entities_const {
-
12919  friend class Virus<TSeq>;
-
12920  friend class Agent<TSeq>;
-
12921 private:
-
12922  const std::vector< Entity<TSeq>* > dat;
-
12923  const size_t n_entities;
-
12924 
-
12925 public:
-
12926 
-
12927  Entities_const() = delete;
-
12928  Entities_const(const Agent<TSeq> & p);
+
12912 template<typename TSeq>
+
12913 inline Entity<TSeq> & Entities<TSeq>::operator[](size_t i)
+
12914 {
+
12915 
+
12916  return *dat[i];
+
12917 
+
12918 }
+
12919 
+
12920 template<typename TSeq>
+
12921 inline size_t Entities<TSeq>::size() const noexcept
+
12922 {
+
12923  return n_entities;
+
12924 }
+
12925 
+
12926 template<typename TSeq>
+
12927 inline bool Entities<TSeq>::operator==(const Entities<TSeq> & other) const
+
12928 {
12929 
-
12930  typename std::vector< Entity<TSeq>* >::const_iterator begin();
-
12931  typename std::vector< Entity<TSeq>* >::const_iterator end();
+
12930  if (n_entities != other.n_entities)
+
12931  return false;
12932 
-
12933  const Entity<TSeq> & operator()(size_t i);
-
12934  const Entity<TSeq> & operator[](size_t i);
-
12935 
-
12936  size_t size() const noexcept;
-
12937 
-
12938  bool operator==(const Entities_const<TSeq> & other) const;
-
12939 
-
12940 };
+
12933  for (size_t i = 0u; i < dat.size(); ++i)
+
12934  {
+
12935  if (dat[i] != other.dat[i])
+
12936  return false;
+
12937  }
+
12938 
+
12939  return true;
+
12940 }
12941 
-
12942 template<typename TSeq>
-
12943 inline Entities_const<TSeq>::Entities_const(const Agent<TSeq> & p) :
-
12944  n_entities(p.get_n_entities())
-
12945 {
-
12946 
-
12947  dat.reserve(n_entities);
-
12948  for (size_t i = 0u; i < n_entities; ++i)
-
12949  dat.push_back(&p.get_entity(i));
-
12950 
-
12951 }
-
12952 
-
12953 template<typename TSeq>
-
12954 inline typename std::vector< Entity<TSeq>* >::const_iterator Entities_const<TSeq>::begin() {
-
12955 
-
12956  if (n_entities == 0u)
-
12957  return dat.end();
-
12958 
-
12959  return dat.begin();
-
12960 }
-
12961 
-
12962 template<typename TSeq>
-
12963 inline typename std::vector< Entity<TSeq>* >::const_iterator Entities_const<TSeq>::end() {
-
12964 
-
12965  return begin() + n_entities;
-
12966 }
+
12947 template<typename TSeq>
+
12948 class Entities_const {
+
12949  friend class Virus<TSeq>;
+
12950  friend class Agent<TSeq>;
+
12951 private:
+
12952  const std::vector< Entity<TSeq>* > dat;
+
12953  const size_t n_entities;
+
12954 
+
12955 public:
+
12956 
+
12957  Entities_const() = delete;
+
12958  Entities_const(const Agent<TSeq> & p);
+
12959 
+
12960  typename std::vector< Entity<TSeq>* >::const_iterator begin();
+
12961  typename std::vector< Entity<TSeq>* >::const_iterator end();
+
12962 
+
12963  const Entity<TSeq> & operator()(size_t i);
+
12964  const Entity<TSeq> & operator[](size_t i);
+
12965 
+
12966  size_t size() const noexcept;
12967 
-
12968 template<typename TSeq>
-
12969 inline const Entity<TSeq> & Entities_const<TSeq>::operator()(size_t i)
-
12970 {
+
12968  bool operator==(const Entities_const<TSeq> & other) const;
+
12969 
+
12970 };
12971 
-
12972  if (i >= n_entities)
-
12973  throw std::range_error("Entity index out of range.");
-
12974 
-
12975  return *dat[i];
+
12972 template<typename TSeq>
+
12973 inline Entities_const<TSeq>::Entities_const(const Agent<TSeq> & p) :
+
12974  n_entities(p.get_n_entities())
+
12975 {
12976 
-
12977 }
-
12978 
-
12979 template<typename TSeq>
-
12980 inline const Entity<TSeq> & Entities_const<TSeq>::operator[](size_t i)
-
12981 {
+
12977  dat.reserve(n_entities);
+
12978  for (size_t i = 0u; i < n_entities; ++i)
+
12979  dat.push_back(&p.get_entity(i));
+
12980 
+
12981 }
12982 
-
12983  return *dat[i];
-
12984 
-
12985 }
-
12986 
-
12987 template<typename TSeq>
-
12988 inline size_t Entities_const<TSeq>::size() const noexcept
-
12989 {
-
12990  return n_entities;
-
12991 }
-
12992 
-
12993 template<typename TSeq>
-
12994 inline bool Entities_const<TSeq>::operator==(const Entities_const<TSeq> & other) const
-
12995 {
-
12996 
-
12997  if (n_entities != other.n_entities)
-
12998  return false;
-
12999 
-
13000  for (size_t i = 0u; i < dat.size(); ++i)
-
13001  {
-
13002  if (dat[i] != other.dat[i])
-
13003  return false;
-
13004  }
-
13005 
-
13006  return true;
+
12983 template<typename TSeq>
+
12984 inline typename std::vector< Entity<TSeq>* >::const_iterator Entities_const<TSeq>::begin() {
+
12985 
+
12986  if (n_entities == 0u)
+
12987  return dat.end();
+
12988 
+
12989  return dat.begin();
+
12990 }
+
12991 
+
12992 template<typename TSeq>
+
12993 inline typename std::vector< Entity<TSeq>* >::const_iterator Entities_const<TSeq>::end() {
+
12994 
+
12995  return begin() + n_entities;
+
12996 }
+
12997 
+
12998 template<typename TSeq>
+
12999 inline const Entity<TSeq> & Entities_const<TSeq>::operator()(size_t i)
+
13000 {
+
13001 
+
13002  if (i >= n_entities)
+
13003  throw std::range_error("Entity index out of range.");
+
13004 
+
13005  return *dat[i];
+
13006 
13007 }
13008 
-
13009 
-
13010 #endif
-
13011 /*//////////////////////////////////////////////////////////////////////////////
-
13013 
-
13014  End of -include/epiworld/entities-bones.hpp-
-
13015 
-
13018 
-
13019 
-
13020 
-
13021 /*//////////////////////////////////////////////////////////////////////////////
-
13023 
-
13024  Start of -include/epiworld/agent-meat-state.hpp-
-
13025 
-
13028 
+
13009 template<typename TSeq>
+
13010 inline const Entity<TSeq> & Entities_const<TSeq>::operator[](size_t i)
+
13011 {
+
13012 
+
13013  return *dat[i];
+
13014 
+
13015 }
+
13016 
+
13017 template<typename TSeq>
+
13018 inline size_t Entities_const<TSeq>::size() const noexcept
+
13019 {
+
13020  return n_entities;
+
13021 }
+
13022 
+
13023 template<typename TSeq>
+
13024 inline bool Entities_const<TSeq>::operator==(const Entities_const<TSeq> & other) const
+
13025 {
+
13026 
+
13027  if (n_entities != other.n_entities)
+
13028  return false;
13029 
-
13030 #ifndef EPIWORLD_PERSON_MEAT_STATE_HPP
-
13031 #define EPIWORLD_PERSON_MEAT_STATE_HPP
-
13032 
-
13033 // template<typename TSeq>
-
13034 // class Model;
+
13030  for (size_t i = 0u; i < dat.size(); ++i)
+
13031  {
+
13032  if (dat[i] != other.dat[i])
+
13033  return false;
+
13034  }
13035 
-
13036 // template<typename TSeq>
-
13037 // class Agent;
+
13036  return true;
+
13037 }
13038 
13039 
-
13050 /*//////////////////////////////////////////////////////////////////////////////
-
13052 
-
13053  Start of -include/epiworld//agent-meat-virus-sampling.hpp-
-
13054 
-
13057 
+
13040 #endif
+
13041 /*//////////////////////////////////////////////////////////////////////////////
+
13043 
+
13044  End of -include/epiworld/entities-bones.hpp-
+
13045 
+
13048 
+
13049 
+
13050 
+
13051 /*//////////////////////////////////////////////////////////////////////////////
+
13053 
+
13054  Start of -include/epiworld/agent-meat-state.hpp-
+
13055 
13058 
-
13059 #ifndef EPIWORLD_AGENT_MEAT_VIRUS_SAMPLING
-
13060 #define EPIWORLD_AGENT_MEAT_VIRUS_SAMPLING
-
13061 
-
13066 namespace sampler {
-
13067 
-
13081 template<typename TSeq>
-
13082 inline std::function<void(Agent<TSeq>*,Model<TSeq>*)> make_update_susceptible(
-
13083  std::vector< epiworld_fast_uint > exclude = {}
-
13084  )
-
13085 {
-
13086 
+
13059 
+
13060 #ifndef EPIWORLD_PERSON_MEAT_STATE_HPP
+
13061 #define EPIWORLD_PERSON_MEAT_STATE_HPP
+
13062 
+
13063 // template<typename TSeq>
+
13064 // class Model;
+
13065 
+
13066 // template<typename TSeq>
+
13067 // class Agent;
+
13068 
+
13069 
+
13080 /*//////////////////////////////////////////////////////////////////////////////
+
13082 
+
13083  Start of -include/epiworld//agent-meat-virus-sampling.hpp-
+
13084 
13087 
-
13088  if (exclude.size() == 0u)
-
13089  {
-
13090 
-
13091  std::function<void(Agent<TSeq>*,Model<TSeq>*)> sampler =
-
13092  [](Agent<TSeq> * p, Model<TSeq> * m) -> void
-
13093  {
-
13094 
-
13095  if (p->get_virus() != nullptr)
-
13096  throw std::logic_error(
-
13097  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense! ") +
-
13098  std::string("Agent id ") + std::to_string(p->get_id()) +
-
13099  std::string(" has a virus.")
-
13100  );
-
13101 
-
13102  // This computes the prob of getting any neighbor variant
-
13103  size_t nviruses_tmp = 0u;
-
13104  for (auto & neighbor: p->get_neighbors())
-
13105  {
-
13106 
-
13107  auto & v = neighbor->get_virus();
-
13108  if (v == nullptr)
-
13109  continue;
-
13110 
-
13111  /* And it is a function of susceptibility_reduction as well */
-
13112  m->array_double_tmp[nviruses_tmp] =
-
13113  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
13114  v->get_prob_infecting(m) *
-
13115  (1.0 - neighbor->get_transmission_reduction(v, m))
-
13116  ;
-
13117 
-
13118  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
13119 
-
13120  }
-
13121 
-
13122  // No virus to compute
-
13123  if (nviruses_tmp == 0u)
-
13124  return;
-
13125 
-
13126  // Running the roulette
-
13127  int which = roulette(nviruses_tmp, m);
-
13128 
-
13129  if (which < 0)
-
13130  return;
-
13131 
-
13132  p->set_virus(*m->array_virus_tmp[which], m);
-
13133 
-
13134  return;
-
13135  };
-
13136 
-
13137  return sampler;
-
13138 
-
13139  } else {
-
13140 
-
13141  // Making room for the query
-
13142  std::shared_ptr<std::vector<bool>> exclude_agent_bool =
-
13143  std::make_shared<std::vector<bool>>(0);
-
13144 
-
13145  std::shared_ptr<std::vector<epiworld_fast_uint>> exclude_agent_bool_idx =
-
13146  std::make_shared<std::vector<epiworld_fast_uint>>(exclude);
-
13147 
-
13148  std::function<void(Agent<TSeq>*,Model<TSeq>*)> sampler =
-
13149  [exclude_agent_bool,exclude_agent_bool_idx](Agent<TSeq> * p, Model<TSeq> * m) -> void
-
13150  {
+
13088 
+
13089 #ifndef EPIWORLD_AGENT_MEAT_VIRUS_SAMPLING
+
13090 #define EPIWORLD_AGENT_MEAT_VIRUS_SAMPLING
+
13091 
+
13096 namespace sampler {
+
13097 
+
13111 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
13112 inline std::function<void(Agent<TSeq>*,Model<TSeq>*)> make_update_susceptible(
+
13113  std::vector< epiworld_fast_uint > exclude = {}
+
13114  )
+
13115 {
+
13116 
+
13117 
+
13118  if (exclude.size() == 0u)
+
13119  {
+
13120 
+
13121  std::function<void(Agent<TSeq>*,Model<TSeq>*)> sampler =
+
13122  [](Agent<TSeq> * p, Model<TSeq> * m) -> void
+
13123  {
+
13124 
+
13125  if (p->get_virus() != nullptr)
+
13126  throw std::logic_error(
+
13127  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense! ") +
+
13128  std::string("Agent id ") + std::to_string(p->get_id()) +
+
13129  std::string(" has a virus.")
+
13130  );
+
13131 
+
13132  // This computes the prob of getting any neighbor variant
+
13133  size_t nviruses_tmp = 0u;
+
13134  for (auto & neighbor: p->get_neighbors())
+
13135  {
+
13136 
+
13137  auto & v = neighbor->get_virus();
+
13138  if (v == nullptr)
+
13139  continue;
+
13140 
+
13141  /* And it is a function of susceptibility_reduction as well */
+
13142  m->array_double_tmp[nviruses_tmp] =
+
13143  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
13144  v->get_prob_infecting(m) *
+
13145  (1.0 - neighbor->get_transmission_reduction(v, m))
+
13146  ;
+
13147 
+
13148  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
13149 
+
13150  }
13151 
-
13152  // The first time we call it, we need to initialize the vector
-
13153  if (exclude_agent_bool->size() == 0u)
-
13154  {
+
13152  // No virus to compute
+
13153  if (nviruses_tmp == 0u)
+
13154  return;
13155 
-
13156  exclude_agent_bool->resize(m->get_states().size(), false);
-
13157  for (auto s : *exclude_agent_bool_idx)
-
13158  {
-
13159  if (s >= exclude_agent_bool->size())
-
13160  throw std::logic_error(
-
13161  std::string("You are trying to exclude a state that is out of range: ") +
-
13162  std::to_string(s) + std::string(". There are only ") +
-
13163  std::to_string(exclude_agent_bool->size()) +
-
13164  std::string(" states in the model.")
-
13165  );
+
13156  // Running the roulette
+
13157  int which = roulette(nviruses_tmp, m);
+
13158 
+
13159  if (which < 0)
+
13160  return;
+
13161 
+
13162  p->set_virus(*m->array_virus_tmp[which], m);
+
13163 
+
13164  return;
+
13165  };
13166 
-
13167  exclude_agent_bool->operator[](s) = true;
+
13167  return sampler;
13168 
-
13169  }
+
13169  } else {
13170 
-
13171  }
-
13172 
-
13173  if (p->get_virus() != nullptr)
-
13174  throw std::logic_error(
-
13175  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense! ") +
-
13176  std::string("Agent id ") + std::to_string(p->get_id()) +
-
13177  std::string(" has a virus.")
-
13178  );
-
13179 
-
13180  // This computes the prob of getting any neighbor variant
-
13181  size_t nviruses_tmp = 0u;
-
13182  for (auto & neighbor: p->get_neighbors())
-
13183  {
-
13184 
-
13185  // If the state is in the list, exclude it
-
13186  if (exclude_agent_bool->operator[](neighbor->get_state()))
-
13187  continue;
-
13188 
-
13189  auto & v = neighbor->get_virus();
-
13190  if (v == nullptr)
-
13191  continue;
-
13192 
-
13193 
-
13194  /* And it is a function of susceptibility_reduction as well */
-
13195  m->array_double_tmp[nviruses_tmp] =
-
13196  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
13197  v->get_prob_infecting(m) *
-
13198  (1.0 - neighbor->get_transmission_reduction(v, m))
-
13199  ;
-
13200 
-
13201  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
13202 
-
13203  }
-
13204 
-
13205  // No virus to compute
-
13206  if (nviruses_tmp == 0u)
-
13207  return;
-
13208 
-
13209  // Running the roulette
-
13210  int which = roulette(nviruses_tmp, m);
-
13211 
-
13212  if (which < 0)
-
13213  return;
+
13171  // Making room for the query
+
13172  std::shared_ptr<std::vector<bool>> exclude_agent_bool =
+
13173  std::make_shared<std::vector<bool>>(0);
+
13174 
+
13175  std::shared_ptr<std::vector<epiworld_fast_uint>> exclude_agent_bool_idx =
+
13176  std::make_shared<std::vector<epiworld_fast_uint>>(exclude);
+
13177 
+
13178  std::function<void(Agent<TSeq>*,Model<TSeq>*)> sampler =
+
13179  [exclude_agent_bool,exclude_agent_bool_idx](Agent<TSeq> * p, Model<TSeq> * m) -> void
+
13180  {
+
13181 
+
13182  // The first time we call it, we need to initialize the vector
+
13183  if (exclude_agent_bool->size() == 0u)
+
13184  {
+
13185 
+
13186  exclude_agent_bool->resize(m->get_states().size(), false);
+
13187  for (auto s : *exclude_agent_bool_idx)
+
13188  {
+
13189  if (s >= exclude_agent_bool->size())
+
13190  throw std::logic_error(
+
13191  std::string("You are trying to exclude a state that is out of range: ") +
+
13192  std::to_string(s) + std::string(". There are only ") +
+
13193  std::to_string(exclude_agent_bool->size()) +
+
13194  std::string(" states in the model.")
+
13195  );
+
13196 
+
13197  exclude_agent_bool->operator[](s) = true;
+
13198 
+
13199  }
+
13200 
+
13201  }
+
13202 
+
13203  if (p->get_virus() != nullptr)
+
13204  throw std::logic_error(
+
13205  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense! ") +
+
13206  std::string("Agent id ") + std::to_string(p->get_id()) +
+
13207  std::string(" has a virus.")
+
13208  );
+
13209 
+
13210  // This computes the prob of getting any neighbor variant
+
13211  size_t nviruses_tmp = 0u;
+
13212  for (auto & neighbor: p->get_neighbors())
+
13213  {
13214 
-
13215  p->set_virus(*m->array_virus_tmp[which], m);
-
13216 
-
13217  return;
+
13215  // If the state is in the list, exclude it
+
13216  if (exclude_agent_bool->operator[](neighbor->get_state()))
+
13217  continue;
13218 
-
13219  };
-
13220 
-
13221  return sampler;
-
13222 
-
13223  }
-
13224 
-
13225 }
-
13226 
-
13240 template<typename TSeq = int>
-
13241 inline std::function<Virus<TSeq>*(Agent<TSeq>*,Model<TSeq>*)> make_sample_virus_neighbors(
-
13242  std::vector< epiworld_fast_uint > exclude = {}
-
13243 )
-
13244 {
-
13245  if (exclude.size() == 0u)
-
13246  {
-
13247 
-
13248  std::function<Virus<TSeq>*(Agent<TSeq>*,Model<TSeq>*)> res =
-
13249  [](Agent<TSeq> * p, Model<TSeq> * m) -> Virus<TSeq>* {
+
13219  auto & v = neighbor->get_virus();
+
13220  if (v == nullptr)
+
13221  continue;
+
13222 
+
13223 
+
13224  /* And it is a function of susceptibility_reduction as well */
+
13225  m->array_double_tmp[nviruses_tmp] =
+
13226  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
13227  v->get_prob_infecting(m) *
+
13228  (1.0 - neighbor->get_transmission_reduction(v, m))
+
13229  ;
+
13230 
+
13231  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
13232 
+
13233  }
+
13234 
+
13235  // No virus to compute
+
13236  if (nviruses_tmp == 0u)
+
13237  return;
+
13238 
+
13239  // Running the roulette
+
13240  int which = roulette(nviruses_tmp, m);
+
13241 
+
13242  if (which < 0)
+
13243  return;
+
13244 
+
13245  p->set_virus(*m->array_virus_tmp[which], m);
+
13246 
+
13247  return;
+
13248 
+
13249  };
13250 
-
13251  if (p->get_virus() != nullptr)
-
13252  throw std::logic_error(
-
13253  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense! ") +
-
13254  std::string("Agent id ") + std::to_string(p->get_id()) +
-
13255  std::string(" has a virus.")
-
13256  );
-
13257 
-
13258  // This computes the prob of getting any neighbor variant
-
13259  size_t nviruses_tmp = 0u;
-
13260  for (auto & neighbor: p->get_neighbors())
-
13261  {
-
13262 
-
13263  if (neighbor->get_virus() == nullptr)
-
13264  continue;
-
13265 
-
13266  auto & v = neighbor->get_virus();
-
13267 
-
13268  #ifdef EPI_DEBUG
-
13269  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
-
13270  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
13271  #endif
-
13272 
-
13273  /* And it is a function of susceptibility_reduction as well */
-
13274  m->array_double_tmp[nviruses_tmp] =
-
13275  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
13276  v->get_prob_infecting(m) *
-
13277  (1.0 - neighbor->get_transmission_reduction(v, m))
-
13278  ;
-
13279 
-
13280  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
13281 
-
13282  }
-
13283 
-
13284  // No virus to compute
-
13285  if (nviruses_tmp == 0u)
-
13286  return nullptr;
+
13251  return sampler;
+
13252 
+
13253  }
+
13254 
+
13255 }
+
13256 
+
13270 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
13271 inline std::function<Virus<TSeq>*(Agent<TSeq>*,Model<TSeq>*)> make_sample_virus_neighbors(
+
13272  std::vector< epiworld_fast_uint > exclude = {}
+
13273 )
+
13274 {
+
13275  if (exclude.size() == 0u)
+
13276  {
+
13277 
+
13278  std::function<Virus<TSeq>*(Agent<TSeq>*,Model<TSeq>*)> res =
+
13279  [](Agent<TSeq> * p, Model<TSeq> * m) -> Virus<TSeq>* {
+
13280 
+
13281  if (p->get_virus() != nullptr)
+
13282  throw std::logic_error(
+
13283  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense! ") +
+
13284  std::string("Agent id ") + std::to_string(p->get_id()) +
+
13285  std::string(" has a virus.")
+
13286  );
13287 
-
13288  // Running the roulette
-
13289  int which = roulette(nviruses_tmp, m);
-
13290 
-
13291  if (which < 0)
-
13292  return nullptr;
-
13293 
-
13294  return m->array_virus_tmp[which];
+
13288  // This computes the prob of getting any neighbor variant
+
13289  size_t nviruses_tmp = 0u;
+
13290  for (auto & neighbor: p->get_neighbors())
+
13291  {
+
13292 
+
13293  if (neighbor->get_virus() == nullptr)
+
13294  continue;
13295 
-
13296  };
+
13296  auto & v = neighbor->get_virus();
13297 
-
13298  return res;
-
13299 
-
13300 
-
13301  } else {
-
13302 
-
13303  // Making room for the query
-
13304  std::shared_ptr<std::vector<bool>> exclude_agent_bool =
-
13305  std::make_shared<std::vector<bool>>(0);
-
13306 
-
13307  std::shared_ptr<std::vector<epiworld_fast_uint>> exclude_agent_bool_idx =
-
13308  std::make_shared<std::vector<epiworld_fast_uint>>(exclude);
-
13309 
-
13310 
-
13311  std::function<Virus<TSeq>*(Agent<TSeq>*,Model<TSeq>*)> res =
-
13312  [exclude_agent_bool,exclude_agent_bool_idx](Agent<TSeq> * p, Model<TSeq> * m) -> Virus<TSeq>* {
+
13298  #ifdef EPI_DEBUG
+
13299  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
+
13300  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
13301  #endif
+
13302 
+
13303  /* And it is a function of susceptibility_reduction as well */
+
13304  m->array_double_tmp[nviruses_tmp] =
+
13305  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
13306  v->get_prob_infecting(m) *
+
13307  (1.0 - neighbor->get_transmission_reduction(v, m))
+
13308  ;
+
13309 
+
13310  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
13311 
+
13312  }
13313 
-
13314  // The first time we call it, we need to initialize the vector
-
13315  if (exclude_agent_bool->size() == 0u)
-
13316  {
+
13314  // No virus to compute
+
13315  if (nviruses_tmp == 0u)
+
13316  return nullptr;
13317 
-
13318  exclude_agent_bool->resize(m->get_states().size(), false);
-
13319  for (auto s : *exclude_agent_bool_idx)
-
13320  {
-
13321  if (s >= exclude_agent_bool->size())
-
13322  throw std::logic_error(
-
13323  std::string("You are trying to exclude a state that is out of range: ") +
-
13324  std::to_string(s) + std::string(". There are only ") +
-
13325  std::to_string(exclude_agent_bool->size()) +
-
13326  std::string(" states in the model.")
-
13327  );
-
13328 
-
13329  exclude_agent_bool->operator[](s) = true;
+
13318  // Running the roulette
+
13319  int which = roulette(nviruses_tmp, m);
+
13320 
+
13321  if (which < 0)
+
13322  return nullptr;
+
13323 
+
13324  return m->array_virus_tmp[which];
+
13325 
+
13326  };
+
13327 
+
13328  return res;
+
13329 
13330 
-
13331  }
+
13331  } else {
13332 
-
13333  }
-
13334 
-
13335  if (p->get_virus() != nullptr)
-
13336  throw std::logic_error(
-
13337  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense! ") +
-
13338  std::string("Agent id ") + std::to_string(p->get_id()) +
-
13339  std::string(" has a virus.")
-
13340  );
-
13341 
-
13342  // This computes the prob of getting any neighbor variant
-
13343  size_t nviruses_tmp = 0u;
-
13344  for (auto & neighbor: p->get_neighbors())
-
13345  {
-
13346 
-
13347  // If the state is in the list, exclude it
-
13348  if (exclude_agent_bool->operator[](neighbor->get_state()))
-
13349  continue;
-
13350 
-
13351  if (neighbor->get_virus() == nullptr)
-
13352  continue;
-
13353 
-
13354  auto & v = neighbor->get_virus();
-
13355 
-
13356  #ifdef EPI_DEBUG
-
13357  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
-
13358  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
13359  #endif
-
13360 
-
13361  /* And it is a function of susceptibility_reduction as well */
-
13362  m->array_double_tmp[nviruses_tmp] =
-
13363  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
13364  v->get_prob_infecting(m) *
-
13365  (1.0 - neighbor->get_transmission_reduction(v, m))
-
13366  ;
-
13367 
-
13368  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
13369 
-
13370  }
+
13333  // Making room for the query
+
13334  std::shared_ptr<std::vector<bool>> exclude_agent_bool =
+
13335  std::make_shared<std::vector<bool>>(0);
+
13336 
+
13337  std::shared_ptr<std::vector<epiworld_fast_uint>> exclude_agent_bool_idx =
+
13338  std::make_shared<std::vector<epiworld_fast_uint>>(exclude);
+
13339 
+
13340 
+
13341  std::function<Virus<TSeq>*(Agent<TSeq>*,Model<TSeq>*)> res =
+
13342  [exclude_agent_bool,exclude_agent_bool_idx](Agent<TSeq> * p, Model<TSeq> * m) -> Virus<TSeq>* {
+
13343 
+
13344  // The first time we call it, we need to initialize the vector
+
13345  if (exclude_agent_bool->size() == 0u)
+
13346  {
+
13347 
+
13348  exclude_agent_bool->resize(m->get_states().size(), false);
+
13349  for (auto s : *exclude_agent_bool_idx)
+
13350  {
+
13351  if (s >= exclude_agent_bool->size())
+
13352  throw std::logic_error(
+
13353  std::string("You are trying to exclude a state that is out of range: ") +
+
13354  std::to_string(s) + std::string(". There are only ") +
+
13355  std::to_string(exclude_agent_bool->size()) +
+
13356  std::string(" states in the model.")
+
13357  );
+
13358 
+
13359  exclude_agent_bool->operator[](s) = true;
+
13360 
+
13361  }
+
13362 
+
13363  }
+
13364 
+
13365  if (p->get_virus() != nullptr)
+
13366  throw std::logic_error(
+
13367  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense! ") +
+
13368  std::string("Agent id ") + std::to_string(p->get_id()) +
+
13369  std::string(" has a virus.")
+
13370  );
13371 
-
13372  // No virus to compute
-
13373  if (nviruses_tmp == 0u)
-
13374  return nullptr;
-
13375 
-
13376  // Running the roulette
-
13377  int which = roulette(nviruses_tmp, m);
-
13378 
-
13379  if (which < 0)
-
13380  return nullptr;
-
13381 
-
13382  return m->array_virus_tmp[which];
+
13372  // This computes the prob of getting any neighbor variant
+
13373  size_t nviruses_tmp = 0u;
+
13374  for (auto & neighbor: p->get_neighbors())
+
13375  {
+
13376 
+
13377  // If the state is in the list, exclude it
+
13378  if (exclude_agent_bool->operator[](neighbor->get_state()))
+
13379  continue;
+
13380 
+
13381  if (neighbor->get_virus() == nullptr)
+
13382  continue;
13383 
-
13384  };
-
13385 
-
13386  return res;
-
13387 
-
13388  }
-
13389 
-
13390 }
-
13391 
-
13408 template<typename TSeq = int>
- -
13410 {
+
13384  auto & v = neighbor->get_virus();
+
13385 
+
13386  #ifdef EPI_DEBUG
+
13387  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
+
13388  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
13389  #endif
+
13390 
+
13391  /* And it is a function of susceptibility_reduction as well */
+
13392  m->array_double_tmp[nviruses_tmp] =
+
13393  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
13394  v->get_prob_infecting(m) *
+
13395  (1.0 - neighbor->get_transmission_reduction(v, m))
+
13396  ;
+
13397 
+
13398  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
13399 
+
13400  }
+
13401 
+
13402  // No virus to compute
+
13403  if (nviruses_tmp == 0u)
+
13404  return nullptr;
+
13405 
+
13406  // Running the roulette
+
13407  int which = roulette(nviruses_tmp, m);
+
13408 
+
13409  if (which < 0)
+
13410  return nullptr;
13411 
-
13412  if (p->get_virus() != nullptr)
-
13413  throw std::logic_error(
-
13414  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense!") +
-
13415  std::string("Agent id ") + std::to_string(p->get_id()) +
-
13416  std::string(" has a virus.")
-
13417  );
-
13418 
-
13419  // This computes the prob of getting any neighbor variant
-
13420  size_t nviruses_tmp = 0u;
-
13421  for (auto & neighbor: p->get_neighbors())
-
13422  {
-
13423  #ifdef EPI_DEBUG
-
13424  int _vcount_neigh = 0;
-
13425  #endif
-
13426 
-
13427  if (neighbor->get_virus() == nullptr)
-
13428  continue;
-
13429 
-
13430  auto & v = neighbor->get_virus();
-
13431 
-
13432  #ifdef EPI_DEBUG
-
13433  if (nviruses_tmp >= m->array_virus_tmp.size())
-
13434  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
13435  #endif
-
13436 
-
13437  /* And it is a function of susceptibility_reduction as well */
-
13438  m->array_double_tmp[nviruses_tmp] =
-
13439  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
13440  v->get_prob_infecting(m) *
-
13441  (1.0 - neighbor->get_transmission_reduction(v, m))
-
13442  ;
-
13443 
-
13444  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
13445 
-
13446  #ifdef EPI_DEBUG
-
13447  if (
-
13448  (m->array_double_tmp[nviruses_tmp - 1] < 0.0) |
-
13449  (m->array_double_tmp[nviruses_tmp - 1] > 1.0)
-
13450  )
-
13451  {
-
13452  printf_epiworld(
-
13453  "[epi-debug] Agent %i's virus %i has transmission prob outside of [0, 1]: %.4f!\n",
-
13454  static_cast<int>(neighbor->get_id()),
-
13455  static_cast<int>(_vcount_neigh++),
-
13456  m->array_double_tmp[nviruses_tmp - 1]
-
13457  );
-
13458  }
-
13459  #endif
-
13460 
-
13461  }
-
13462 
-
13463 
-
13464  // No virus to compute
-
13465  if (nviruses_tmp == 0u)
-
13466  return nullptr;
-
13467 
-
13468  #ifdef EPI_DEBUG
-
13469  m->get_db().n_transmissions_potential++;
-
13470  #endif
-
13471 
-
13472  // Running the roulette
-
13473  int which = roulette(nviruses_tmp, m);
-
13474 
-
13475  if (which < 0)
-
13476  return nullptr;
-
13477 
-
13478  #ifdef EPI_DEBUG
-
13479  m->get_db().n_transmissions_today++;
-
13480  #endif
-
13481 
-
13482  return m->array_virus_tmp[which];
-
13483 
-
13484 }
-
13485 
-
13486 }
-
13487 
-
13488 #endif
-
13489 /*//////////////////////////////////////////////////////////////////////////////
-
13491 
-
13492  End of -include/epiworld//agent-meat-virus-sampling.hpp-
-
13493 
-
13496 
-
13497 
-
13498 
-
13499 
-
13500 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
13501 inline void default_update_susceptible(
-
13502  Agent<TSeq> * p,
-
13503  Model<TSeq> * m
-
13504  )
-
13505 {
-
13506 
-
13507  Virus<TSeq> * virus = sampler::sample_virus_single<TSeq>(p, m);
-
13508 
-
13509  if (virus == nullptr)
-
13510  return;
-
13511 
-
13512  p->set_virus(*virus, m);
-
13513 
-
13514  return;
-
13515 
-
13516 }
-
13517 
-
13518 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
13519 inline void default_update_exposed(Agent<TSeq> * p, Model<TSeq> * m) {
-
13520 
-
13521  if (p->get_virus() == nullptr)
-
13522  throw std::logic_error(
-
13523  std::string("Using the -default_update_exposed- on agents WITHOUT viruses makes no sense! ") +
-
13524  std::string("Agent id ") + std::to_string(p->get_id()) + std::string(" has no virus registered.")
-
13525  );
+
13412  return m->array_virus_tmp[which];
+
13413 
+
13414  };
+
13415 
+
13416  return res;
+
13417 
+
13418  }
+
13419 
+
13420 }
+
13421 
+
13438 template<typename TSeq = EPI_DEFAULT_TSEQ>
+ +
13440 {
+
13441 
+
13442  if (p->get_virus() != nullptr)
+
13443  throw std::logic_error(
+
13444  std::string("Using the -default_update_susceptible- on agents WITH viruses makes no sense!") +
+
13445  std::string("Agent id ") + std::to_string(p->get_id()) +
+
13446  std::string(" has a virus.")
+
13447  );
+
13448 
+
13449  // This computes the prob of getting any neighbor variant
+
13450  size_t nviruses_tmp = 0u;
+
13451  for (auto & neighbor: p->get_neighbors())
+
13452  {
+
13453  #ifdef EPI_DEBUG
+
13454  int _vcount_neigh = 0;
+
13455  #endif
+
13456 
+
13457  if (neighbor->get_virus() == nullptr)
+
13458  continue;
+
13459 
+
13460  auto & v = neighbor->get_virus();
+
13461 
+
13462  #ifdef EPI_DEBUG
+
13463  if (nviruses_tmp >= m->array_virus_tmp.size())
+
13464  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
13465  #endif
+
13466 
+
13467  /* And it is a function of susceptibility_reduction as well */
+
13468  m->array_double_tmp[nviruses_tmp] =
+
13469  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
13470  v->get_prob_infecting(m) *
+
13471  (1.0 - neighbor->get_transmission_reduction(v, m))
+
13472  ;
+
13473 
+
13474  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
13475 
+
13476  #ifdef EPI_DEBUG
+
13477  if (
+
13478  (m->array_double_tmp[nviruses_tmp - 1] < 0.0) |
+
13479  (m->array_double_tmp[nviruses_tmp - 1] > 1.0)
+
13480  )
+
13481  {
+
13482  printf_epiworld(
+
13483  "[epi-debug] Agent %i's virus %i has transmission prob outside of [0, 1]: %.4f!\n",
+
13484  static_cast<int>(neighbor->get_id()),
+
13485  static_cast<int>(_vcount_neigh++),
+
13486  m->array_double_tmp[nviruses_tmp - 1]
+
13487  );
+
13488  }
+
13489  #endif
+
13490 
+
13491  }
+
13492 
+
13493 
+
13494  // No virus to compute
+
13495  if (nviruses_tmp == 0u)
+
13496  return nullptr;
+
13497 
+
13498  #ifdef EPI_DEBUG
+
13499  m->get_db().n_transmissions_potential++;
+
13500  #endif
+
13501 
+
13502  // Running the roulette
+
13503  int which = roulette(nviruses_tmp, m);
+
13504 
+
13505  if (which < 0)
+
13506  return nullptr;
+
13507 
+
13508  #ifdef EPI_DEBUG
+
13509  m->get_db().n_transmissions_today++;
+
13510  #endif
+
13511 
+
13512  return m->array_virus_tmp[which];
+
13513 
+
13514 }
+
13515 
+
13516 }
+
13517 
+
13518 #endif
+
13519 /*//////////////////////////////////////////////////////////////////////////////
+
13521 
+
13522  End of -include/epiworld//agent-meat-virus-sampling.hpp-
+
13523 
13526 
-
13527  // Die
-
13528  auto & virus = p->get_virus();
-
13529  m->array_double_tmp[0u] =
-
13530  virus->get_prob_death(m) * (1.0 - p->get_death_reduction(virus, m));
-
13531 
-
13532  // Recover
-
13533  m->array_double_tmp[1u] =
-
13534  1.0 - (1.0 - virus->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(virus, m));
-
13535 
+
13527 
+
13528 
+
13529 
+
13530 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
13531 inline void default_update_susceptible(
+
13532  Agent<TSeq> * p,
+
13533  Model<TSeq> * m
+
13534  )
+
13535 {
13536 
-
13537  // Running the roulette
-
13538  int which = roulette(2u, m);
-
13539 
-
13540  if (which < 0)
-
13541  return;
-
13542 
-
13543  // Which roulette happen?
-
13544  if (which == 0u) // If odd
-
13545  {
-
13546 
-
13547  p->rm_agent_by_virus(m);
-
13548 
-
13549  } else {
+
13537  Virus<TSeq> * virus = sampler::sample_virus_single<TSeq>(p, m);
+
13538 
+
13539  if (virus == nullptr)
+
13540  return;
+
13541 
+
13542  p->set_virus(*virus, m);
+
13543 
+
13544  return;
+
13545 
+
13546 }
+
13547 
+
13548 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
13549 inline void default_update_exposed(Agent<TSeq> * p, Model<TSeq> * m) {
13550 
-
13551  p->rm_virus(m);
-
13552 
-
13553  }
-
13554 
-
13555  return ;
+
13551  if (p->get_virus() == nullptr)
+
13552  throw std::logic_error(
+
13553  std::string("Using the -default_update_exposed- on agents WITHOUT viruses makes no sense! ") +
+
13554  std::string("Agent id ") + std::to_string(p->get_id()) + std::string(" has no virus registered.")
+
13555  );
13556 
-
13557 }
-
13558 
-
13559 #endif
-
13560 /*//////////////////////////////////////////////////////////////////////////////
-
13562 
-
13563  End of -include/epiworld/agent-meat-state.hpp-
-
13564 
-
13567 
-
13568 
-
13569 /*//////////////////////////////////////////////////////////////////////////////
-
13571 
-
13572  Start of -include/epiworld/agent-bones.hpp-
-
13573 
+
13557  // Die
+
13558  auto & virus = p->get_virus();
+
13559  m->array_double_tmp[0u] =
+
13560  virus->get_prob_death(m) * (1.0 - p->get_death_reduction(virus, m));
+
13561 
+
13562  // Recover
+
13563  m->array_double_tmp[1u] =
+
13564  1.0 - (1.0 - virus->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(virus, m));
+
13565 
+
13566 
+
13567  // Running the roulette
+
13568  int which = roulette(2u, m);
+
13569 
+
13570  if (which < 0)
+
13571  return;
+
13572 
+
13573  // Which roulette happen?
+
13574  if (which == 0u) // If odd
+
13575  {
13576 
-
13577 
-
13578 #ifndef EPIWORLD_PERSON_BONES_HPP
-
13579 #define EPIWORLD_PERSON_BONES_HPP
+
13577  p->rm_agent_by_virus(m);
+
13578 
+
13579  } else {
13580 
-
13581 template<typename TSeq>
-
13582 class Model;
-
13583 
-
13584 template<typename TSeq>
-
13585 class Virus;
+
13581  p->rm_virus(m);
+
13582 
+
13583  }
+
13584 
+
13585  return ;
13586 
-
13587 template<typename TSeq>
-
13588 class Viruses;
-
13589 
-
13590 template<typename TSeq>
-
13591 class Viruses_const;
+
13587 }
+
13588 
+
13589 #endif
+
13590 /*//////////////////////////////////////////////////////////////////////////////
13592 
-
13593 template<typename TSeq>
-
13594 class Tool;
-
13595 
-
13596 template<typename TSeq>
-
13597 class Tools;
+
13593  End of -include/epiworld/agent-meat-state.hpp-
+
13594 
+
13597 
13598 
-
13599 template<typename TSeq>
-
13600 class Tools_const;
+
13599 /*//////////////////////////////////////////////////////////////////////////////
13601 
-
13602 template<typename TSeq>
-
13603 class Queue;
-
13604 
-
13605 template<typename TSeq>
-
13606 struct Event;
+
13602  Start of -include/epiworld/agent-bones.hpp-
+
13603 
+
13606 
13607 
-
13608 template<typename TSeq>
-
13609 class Entity;
+
13608 #ifndef EPIWORLD_PERSON_BONES_HPP
+
13609 #define EPIWORLD_PERSON_BONES_HPP
13610 
13611 template<typename TSeq>
-
13612 class Entities;
+
13612 class Model;
13613 
13614 template<typename TSeq>
-
13615 inline void default_add_virus(Event<TSeq> & a, Model<TSeq> * m);
+
13615 class Virus;
13616 
13617 template<typename TSeq>
-
13618 inline void default_add_tool(Event<TSeq> & a, Model<TSeq> * m);
+
13618 class Viruses;
13619 
13620 template<typename TSeq>
-
13621 inline void default_add_entity(Event<TSeq> & a, Model<TSeq> * m);
+
13621 class Viruses_const;
13622 
13623 template<typename TSeq>
-
13624 inline void default_rm_virus(Event<TSeq> & a, Model<TSeq> * m);
+
13624 class Tool;
13625 
13626 template<typename TSeq>
-
13627 inline void default_rm_tool(Event<TSeq> & a, Model<TSeq> * m);
+
13627 class Tools;
13628 
13629 template<typename TSeq>
-
13630 inline void default_rm_entity(Event<TSeq> & a, Model<TSeq> * m);
+
13630 class Tools_const;
13631 
13632 template<typename TSeq>
-
13633 inline void default_change_state(Event<TSeq> & a, Model<TSeq> * m);
+
13633 class Queue;
13634 
-
13635 
-
13636 
-
13642 template<typename TSeq>
-
13643 class Agent {
-
13644  friend class Model<TSeq>;
-
13645  friend class Virus<TSeq>;
-
13646  friend class Tool<TSeq>;
-
13647  friend class Tools<TSeq>;
-
13648  friend class Tools_const<TSeq>;
-
13649  friend class Queue<TSeq>;
-
13650  friend class Entities<TSeq>;
-
13651  friend class AgentsSample<TSeq>;
-
13652  friend void default_add_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
13653  friend void default_add_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
13654  friend void default_add_entity<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
13655  friend void default_rm_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
13656  friend void default_rm_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
13657  friend void default_rm_entity<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
13658  friend void default_change_state<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
-
13659 private:
-
13660 
-
13661  Model<TSeq> * model;
-
13662 
-
13663  std::vector< size_t > neighbors;
-
13664  std::vector< size_t > neighbors_locations;
-
13665  size_t n_neighbors = 0u;
+
13635 template<typename TSeq>
+
13636 struct Event;
+
13637 
+
13638 template<typename TSeq>
+
13639 class Entity;
+
13640 
+
13641 template<typename TSeq>
+
13642 class Entities;
+
13643 
+
13644 template<typename TSeq>
+
13645 inline void default_add_virus(Event<TSeq> & a, Model<TSeq> * m);
+
13646 
+
13647 template<typename TSeq>
+
13648 inline void default_add_tool(Event<TSeq> & a, Model<TSeq> * m);
+
13649 
+
13650 template<typename TSeq>
+
13651 inline void default_add_entity(Event<TSeq> & a, Model<TSeq> * m);
+
13652 
+
13653 template<typename TSeq>
+
13654 inline void default_rm_virus(Event<TSeq> & a, Model<TSeq> * m);
+
13655 
+
13656 template<typename TSeq>
+
13657 inline void default_rm_tool(Event<TSeq> & a, Model<TSeq> * m);
+
13658 
+
13659 template<typename TSeq>
+
13660 inline void default_rm_entity(Event<TSeq> & a, Model<TSeq> * m);
+
13661 
+
13662 template<typename TSeq>
+
13663 inline void default_change_state(Event<TSeq> & a, Model<TSeq> * m);
+
13664 
+
13665 
13666 
-
13667  std::vector< size_t > entities;
-
13668  std::vector< size_t > entities_locations;
-
13669  size_t n_entities = 0u;
-
13670 
-
13671  epiworld_fast_uint state = 0u;
-
13672  epiworld_fast_uint state_prev = 0u; ///< For accounting, if need to undo a change.
-
13673 
-
13674  int state_last_changed = -1; ///< Last time the agent was updated.
-
13675  int id = -1;
-
13676 
-
13677  VirusPtr<TSeq> virus = nullptr;
-
13678 
-
13679  std::vector< ToolPtr<TSeq> > tools;
-
13680  epiworld_fast_uint n_tools = 0u;
-
13681 
-
13682  std::vector< Agent<TSeq> * > sampled_agents = {};
-
13683  size_t sampled_agents_n = 0u;
-
13684  std::vector< size_t > sampled_agents_left = {};
-
13685  size_t sampled_agents_left_n = 0u;
-
13686  int date_last_build_sample = -99;
-
13687 
-
13688 public:
-
13689 
-
13690  Agent();
-
13691  Agent(Agent<TSeq> && p);
-
13692  Agent(const Agent<TSeq> & p);
-
13693  Agent<TSeq> & operator=(const Agent<TSeq> & other_agent);
-
13694 
-
13706  void add_tool(
-
13707  ToolPtr<TSeq> tool,
-
13708  Model<TSeq> * model,
-
13709  epiworld_fast_int state_new = -99,
-
13710  epiworld_fast_int queue = -99
-
13711  );
-
13712 
-
13713  void add_tool(
-
13714  Tool<TSeq> tool,
-
13715  Model<TSeq> * model,
-
13716  epiworld_fast_int state_new = -99,
-
13717  epiworld_fast_int queue = -99
-
13718  );
+
13672 template<typename TSeq>
+
13673 class Agent {
+
13674  friend class Model<TSeq>;
+
13675  friend class Virus<TSeq>;
+
13676  friend class Tool<TSeq>;
+
13677  friend class Tools<TSeq>;
+
13678  friend class Tools_const<TSeq>;
+
13679  friend class Queue<TSeq>;
+
13680  friend class Entities<TSeq>;
+
13681  friend class AgentsSample<TSeq>;
+
13682  friend void default_add_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
13683  friend void default_add_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
13684  friend void default_add_entity<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
13685  friend void default_rm_virus<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
13686  friend void default_rm_tool<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
13687  friend void default_rm_entity<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
13688  friend void default_change_state<TSeq>(Event<TSeq> & a, Model<TSeq> * m);
+
13689 private:
+
13690 
+
13691  Model<TSeq> * model;
+
13692 
+
13693  std::vector< size_t > neighbors;
+
13694  std::vector< size_t > neighbors_locations;
+
13695  size_t n_neighbors = 0u;
+
13696 
+
13697  std::vector< size_t > entities;
+
13698  std::vector< size_t > entities_locations;
+
13699  size_t n_entities = 0u;
+
13700 
+
13701  epiworld_fast_uint state = 0u;
+
13702  epiworld_fast_uint state_prev = 0u; ///< For accounting, if need to undo a change.
+
13703 
+
13704  int state_last_changed = -1; ///< Last time the agent was updated.
+
13705  int id = -1;
+
13706 
+
13707  VirusPtr<TSeq> virus = nullptr;
+
13708 
+
13709  std::vector< ToolPtr<TSeq> > tools;
+
13710  epiworld_fast_uint n_tools = 0u;
+
13711 
+
13712  std::vector< Agent<TSeq> * > sampled_agents = {};
+
13713  size_t sampled_agents_n = 0u;
+
13714  std::vector< size_t > sampled_agents_left = {};
+
13715  size_t sampled_agents_left_n = 0u;
+
13716  int date_last_build_sample = -99;
+
13717 
+
13718 public:
13719 
-
13720  void set_virus(
-
13721  VirusPtr<TSeq> virus,
-
13722  Model<TSeq> * model,
-
13723  epiworld_fast_int state_new = -99,
-
13724  epiworld_fast_int queue = -99
-
13725  );
-
13726 
-
13727  void set_virus(
-
13728  Virus<TSeq> virus,
-
13729  Model<TSeq> * model,
-
13730  epiworld_fast_int state_new = -99,
-
13731  epiworld_fast_int queue = -99
-
13732  );
-
13733 
-
13734  void add_entity(
-
13735  Entity<TSeq> & entity,
-
13736  Model<TSeq> * model,
-
13737  epiworld_fast_int state_new = -99,
-
13738  epiworld_fast_int queue = -99
-
13739  );
-
13740 
-
13741  void rm_tool(
-
13742  epiworld_fast_uint tool_idx,
-
13743  Model<TSeq> * model,
-
13744  epiworld_fast_int state_new = -99,
-
13745  epiworld_fast_int queue = -99
-
13746  );
-
13747 
-
13748  void rm_tool(
-
13749  ToolPtr<TSeq> & tool,
-
13750  Model<TSeq> * model,
-
13751  epiworld_fast_int state_new = -99,
-
13752  epiworld_fast_int queue = -99
-
13753  );
-
13754 
-
13755  void rm_virus(
-
13756  Model<TSeq> * model,
-
13757  epiworld_fast_int state_new = -99,
-
13758  epiworld_fast_int queue = -99
-
13759  );
-
13760 
-
13761  void rm_entity(
-
13762  epiworld_fast_uint entity_idx,
-
13763  Model<TSeq> * model,
-
13764  epiworld_fast_int state_new = -99,
-
13765  epiworld_fast_int queue = -99
-
13766  );
-
13767 
-
13768  void rm_entity(
-
13769  Entity<TSeq> & entity,
-
13770  Model<TSeq> * model,
-
13771  epiworld_fast_int state_new = -99,
-
13772  epiworld_fast_int queue = -99
-
13773  );
-
13774 
-
13775  void rm_agent_by_virus(
-
13776  Model<TSeq> * model,
-
13777  epiworld_fast_int state_new = -99,
-
13778  epiworld_fast_int queue = -99
-
13779  ); ///< Agent removed by virus
-
13781 
-
13789  epiworld_double get_susceptibility_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
-
13790  epiworld_double get_transmission_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
-
13791  epiworld_double get_recovery_enhancer(VirusPtr<TSeq> v, Model<TSeq> * model);
-
13792  epiworld_double get_death_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
-
13794 
-
13795  int get_id() const; ///< Id of the individual
-
13796 
-
13797  VirusPtr<TSeq> & get_virus();
-
13798  const VirusPtr<TSeq> & get_virus() const;
-
13799 
-
13800  ToolPtr<TSeq> & get_tool(int i);
-
13801  Tools<TSeq> get_tools();
-
13802  const Tools_const<TSeq> get_tools() const;
-
13803  size_t get_n_tools() const noexcept;
+
13720  Agent();
+
13721  Agent(Agent<TSeq> && p);
+
13722  Agent(const Agent<TSeq> & p);
+
13723  Agent<TSeq> & operator=(const Agent<TSeq> & other_agent);
+
13724 
+
13736  void add_tool(
+
13737  ToolPtr<TSeq> tool,
+
13738  Model<TSeq> * model,
+
13739  epiworld_fast_int state_new = -99,
+
13740  epiworld_fast_int queue = -99
+
13741  );
+
13742 
+
13743  void add_tool(
+
13744  Tool<TSeq> tool,
+
13745  Model<TSeq> * model,
+
13746  epiworld_fast_int state_new = -99,
+
13747  epiworld_fast_int queue = -99
+
13748  );
+
13749 
+
13750  void set_virus(
+
13751  VirusPtr<TSeq> virus,
+
13752  Model<TSeq> * model,
+
13753  epiworld_fast_int state_new = -99,
+
13754  epiworld_fast_int queue = -99
+
13755  );
+
13756 
+
13757  void set_virus(
+
13758  Virus<TSeq> virus,
+
13759  Model<TSeq> * model,
+
13760  epiworld_fast_int state_new = -99,
+
13761  epiworld_fast_int queue = -99
+
13762  );
+
13763 
+
13764  void add_entity(
+
13765  Entity<TSeq> & entity,
+
13766  Model<TSeq> * model,
+
13767  epiworld_fast_int state_new = -99,
+
13768  epiworld_fast_int queue = -99
+
13769  );
+
13770 
+
13771  void rm_tool(
+
13772  epiworld_fast_uint tool_idx,
+
13773  Model<TSeq> * model,
+
13774  epiworld_fast_int state_new = -99,
+
13775  epiworld_fast_int queue = -99
+
13776  );
+
13777 
+
13778  void rm_tool(
+
13779  ToolPtr<TSeq> & tool,
+
13780  Model<TSeq> * model,
+
13781  epiworld_fast_int state_new = -99,
+
13782  epiworld_fast_int queue = -99
+
13783  );
+
13784 
+
13785  void rm_virus(
+
13786  Model<TSeq> * model,
+
13787  epiworld_fast_int state_new = -99,
+
13788  epiworld_fast_int queue = -99
+
13789  );
+
13790 
+
13791  void rm_entity(
+
13792  epiworld_fast_uint entity_idx,
+
13793  Model<TSeq> * model,
+
13794  epiworld_fast_int state_new = -99,
+
13795  epiworld_fast_int queue = -99
+
13796  );
+
13797 
+
13798  void rm_entity(
+
13799  Entity<TSeq> & entity,
+
13800  Model<TSeq> * model,
+
13801  epiworld_fast_int state_new = -99,
+
13802  epiworld_fast_int queue = -99
+
13803  );
13804 
-
13805  void mutate_virus();
-
13806  void add_neighbor(
-
13807  Agent<TSeq> & p,
-
13808  bool check_source = true,
-
13809  bool check_target = true
-
13810  );
-
13811 
-
13819  void swap_neighbors(
-
13820  Agent<TSeq> & other,
-
13821  size_t n_this,
-
13822  size_t n_other
-
13823  );
+
13805  void rm_agent_by_virus(
+
13806  Model<TSeq> * model,
+
13807  epiworld_fast_int state_new = -99,
+
13808  epiworld_fast_int queue = -99
+
13809  ); ///< Agent removed by virus
+
13811 
+
13819  epiworld_double get_susceptibility_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
+
13820  epiworld_double get_transmission_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
+
13821  epiworld_double get_recovery_enhancer(VirusPtr<TSeq> v, Model<TSeq> * model);
+
13822  epiworld_double get_death_reduction(VirusPtr<TSeq> v, Model<TSeq> * model);
13824 
-
13825  std::vector< Agent<TSeq> * > get_neighbors();
-
13826  size_t get_n_neighbors() const;
-
13827 
-
13828  void change_state(
-
13829  Model<TSeq> * model,
-
13830  epiworld_fast_uint new_state,
-
13831  epiworld_fast_int queue = 0
-
13832  );
-
13833 
-
13834  const epiworld_fast_uint & get_state() const;
-
13835 
-
13836  void reset();
-
13837 
-
13838  bool has_tool(epiworld_fast_uint t) const;
-
13839  bool has_tool(std::string name) const;
-
13840  bool has_tool(const Tool<TSeq> & t) const;
-
13841  bool has_virus(epiworld_fast_uint t) const;
-
13842  bool has_virus(std::string name) const;
-
13843  bool has_virus(const Virus<TSeq> & v) const;
-
13844  bool has_entity(epiworld_fast_uint t) const;
-
13845  bool has_entity(std::string name) const;
-
13846 
-
13847  void print(Model<TSeq> * model, bool compressed = false) const;
-
13848 
-
13865  double & operator()(size_t j);
-
13866  double & operator[](size_t j);
-
13867  double operator()(size_t j) const;
-
13868  double operator[](size_t j) const;
-
13870 
-
13871  Entities<TSeq> get_entities();
-
13872  const Entities_const<TSeq> get_entities() const;
-
13873  const Entity<TSeq> & get_entity(size_t i) const;
-
13874  Entity<TSeq> & get_entity(size_t i);
-
13875  size_t get_n_entities() const;
+
13825  int get_id() const; ///< Id of the individual
+
13826 
+
13827  VirusPtr<TSeq> & get_virus();
+
13828  const VirusPtr<TSeq> & get_virus() const;
+
13829 
+
13830  ToolPtr<TSeq> & get_tool(int i);
+
13831  Tools<TSeq> get_tools();
+
13832  const Tools_const<TSeq> get_tools() const;
+
13833  size_t get_n_tools() const noexcept;
+
13834 
+
13835  void mutate_virus();
+
13836  void add_neighbor(
+
13837  Agent<TSeq> & p,
+
13838  bool check_source = true,
+
13839  bool check_target = true
+
13840  );
+
13841 
+
13849  void swap_neighbors(
+
13850  Agent<TSeq> & other,
+
13851  size_t n_this,
+
13852  size_t n_other
+
13853  );
+
13854 
+
13855  std::vector< Agent<TSeq> * > get_neighbors();
+
13856  size_t get_n_neighbors() const;
+
13857 
+
13858  void change_state(
+
13859  Model<TSeq> * model,
+
13860  epiworld_fast_uint new_state,
+
13861  epiworld_fast_int queue = 0
+
13862  );
+
13863 
+
13864  const epiworld_fast_uint & get_state() const;
+
13865 
+
13866  void reset();
+
13867 
+
13868  bool has_tool(epiworld_fast_uint t) const;
+
13869  bool has_tool(std::string name) const;
+
13870  bool has_tool(const Tool<TSeq> & t) const;
+
13871  bool has_virus(epiworld_fast_uint t) const;
+
13872  bool has_virus(std::string name) const;
+
13873  bool has_virus(const Virus<TSeq> & v) const;
+
13874  bool has_entity(epiworld_fast_uint t) const;
+
13875  bool has_entity(std::string name) const;
13876 
-
13877  bool operator==(const Agent<TSeq> & other) const;
-
13878  bool operator!=(const Agent<TSeq> & other) const {return !operator==(other);};
-
13879 
-
13880 };
-
13881 
-
13882 
-
13883 
-
13884 #endif
-
13885 /*//////////////////////////////////////////////////////////////////////////////
-
13887 
-
13888  End of -include/epiworld/agent-bones.hpp-
-
13889 
-
13892 
-
13893 
-
13894 /*//////////////////////////////////////////////////////////////////////////////
-
13896 
-
13897  Start of -include/epiworld/agent-meat.hpp-
-
13898 
-
13901 
-
13902 
-
13903 #ifndef EPIWORLD_PERSON_MEAT_HPP
-
13904 #define EPIWORLD_PERSON_MEAT_HPP
-
13905 
-
13906 #define CHECK_COALESCE_(proposed_, virus_tool_, alt_) \
-
13907  if (static_cast<int>(proposed_) == -99) {\
-
13908  if (static_cast<int>(virus_tool_) == -99) \
-
13909  (proposed_) = (alt_);\
-
13910  else (proposed_) = (virus_tool_);}
+
13877  void print(Model<TSeq> * model, bool compressed = false) const;
+
13878 
+
13895  double & operator()(size_t j);
+
13896  double & operator[](size_t j);
+
13897  double operator()(size_t j) const;
+
13898  double operator[](size_t j) const;
+
13900 
+
13901  Entities<TSeq> get_entities();
+
13902  const Entities_const<TSeq> get_entities() const;
+
13903  const Entity<TSeq> & get_entity(size_t i) const;
+
13904  Entity<TSeq> & get_entity(size_t i);
+
13905  size_t get_n_entities() const;
+
13906 
+
13907  bool operator==(const Agent<TSeq> & other) const;
+
13908  bool operator!=(const Agent<TSeq> & other) const {return !operator==(other);};
+
13909 
+
13910 };
13911 
-
13912 // To large to add directly here
-
13913 /*//////////////////////////////////////////////////////////////////////////////
-
13915 
-
13916  Start of -include/epiworld//agent-events-meat.hpp-
+
13912 
+
13913 
+
13914 #endif
+
13915 /*//////////////////////////////////////////////////////////////////////////////
13917 
-
13920 
-
13921 
-
13922 #ifndef EPIWORLD_AGENT_EVENTS_MEAT_HPP
-
13923 #define EPIWORLD_AGENT_EVENTS_MEAT_HPP
-
13924 
-
13925 template<typename TSeq>
-
13926 inline void default_add_virus(Event<TSeq> & a, Model<TSeq> * m)
-
13927 {
+
13918  End of -include/epiworld/agent-bones.hpp-
+
13919 
+
13922 
+
13923 
+
13924 /*//////////////////////////////////////////////////////////////////////////////
+
13926 
+
13927  Start of -include/epiworld/agent-meat.hpp-
13928 
-
13929  Agent<TSeq> * p = a.agent;
-
13930  VirusPtr<TSeq> v = a.virus;
13931 
-
13932  // Has a agent? If so, we need to register the transmission
-
13933  if (v->get_agent())
-
13934  {
+
13932 
+
13933 #ifndef EPIWORLD_PERSON_MEAT_HPP
+
13934 #define EPIWORLD_PERSON_MEAT_HPP
13935 
-
13936  // ... only if not the same agent
-
13937  if (v->get_agent()->get_id() != p->get_id())
-
13938  m->get_db().record_transmission(
-
13939  v->get_agent()->get_id(),
-
13940  p->get_id(),
-
13941  v->get_id(),
-
13942  v->get_date()
-
13943  );
-
13944 
-
13945  }
-
13946 
-
13947  p->virus = std::make_shared< Virus<TSeq> >(*v);
-
13948  p->virus->set_date(m->today());
-
13949  p->virus->set_agent(p);
+
13936 #define CHECK_COALESCE_(proposed_, virus_tool_, alt_) \
+
13937  if (static_cast<int>(proposed_) == -99) {\
+
13938  if (static_cast<int>(virus_tool_) == -99) \
+
13939  (proposed_) = (alt_);\
+
13940  else (proposed_) = (virus_tool_);}
+
13941 
+
13942 // To large to add directly here
+
13943 /*//////////////////////////////////////////////////////////////////////////////
+
13945 
+
13946  Start of -include/epiworld//agent-events-meat.hpp-
+
13947 
13950 
-
13951  // Change of state needs to be recorded and updated on the
-
13952  // tools.
-
13953  if (p->state_prev != p->state)
-
13954  {
-
13955  auto & db = m->get_db();
-
13956  db.update_state(p->state_prev, p->state);
-
13957 
-
13958  for (size_t i = 0u; i < p->n_tools; ++i)
-
13959  db.update_tool(p->tools[i]->get_id(), p->state_prev, p->state);
-
13960  }
+
13951 
+
13952 #ifndef EPIWORLD_AGENT_EVENTS_MEAT_HPP
+
13953 #define EPIWORLD_AGENT_EVENTS_MEAT_HPP
+
13954 
+
13955 template<typename TSeq>
+
13956 inline void default_add_virus(Event<TSeq> & a, Model<TSeq> * m)
+
13957 {
+
13958 
+
13959  Agent<TSeq> * p = a.agent;
+
13960  VirusPtr<TSeq> v = a.virus;
13961 
-
13962  // Lastly, we increase the daily count of the virus
-
13963  #ifdef EPI_DEBUG
-
13964  m->get_db().today_virus.at(v->get_id()).at(p->state)++;
-
13965  #else
-
13966  m->get_db().today_virus[v->get_id()][p->state]++;
-
13967  #endif
-
13968 
-
13969 }
-
13970 
-
13971 template<typename TSeq>
-
13972 inline void default_add_tool(Event<TSeq> & a, Model<TSeq> * m)
-
13973 {
+
13962  // Has a agent? If so, we need to register the transmission
+
13963  if (v->get_agent())
+
13964  {
+
13965 
+
13966  // ... only if not the same agent
+
13967  if (v->get_agent()->get_id() != p->get_id())
+
13968  m->get_db().record_transmission(
+
13969  v->get_agent()->get_id(),
+
13970  p->get_id(),
+
13971  v->get_id(),
+
13972  v->get_date()
+
13973  );
13974 
-
13975  Agent<TSeq> * p = a.agent;
-
13976  ToolPtr<TSeq> t = a.tool;
-
13977 
-
13978  // Update tool accounting
-
13979  p->n_tools++;
-
13980  size_t n_tools = p->n_tools;
-
13981 
-
13982  if (n_tools <= p->tools.size())
-
13983  p->tools[n_tools - 1] = std::make_shared< Tool<TSeq> >(*t);
-
13984  else
-
13985  p->tools.push_back(std::make_shared< Tool<TSeq> >(*t));
-
13986 
-
13987  n_tools--;
-
13988 
-
13989  p->tools[n_tools]->set_date(m->today());
-
13990  p->tools[n_tools]->set_agent(p, n_tools);
+
13975  }
+
13976 
+
13977  p->virus = std::make_shared< Virus<TSeq> >(*v);
+
13978  p->virus->set_date(m->today());
+
13979  p->virus->set_agent(p);
+
13980 
+
13981  // Change of state needs to be recorded and updated on the
+
13982  // tools.
+
13983  if (p->state_prev != p->state)
+
13984  {
+
13985  auto & db = m->get_db();
+
13986  db.update_state(p->state_prev, p->state);
+
13987 
+
13988  for (size_t i = 0u; i < p->n_tools; ++i)
+
13989  db.update_tool(p->tools[i]->get_id(), p->state_prev, p->state);
+
13990  }
13991 
-
13992  // Change of state needs to be recorded and updated on the
-
13993  // tools.
-
13994  if (p->state_prev != p->state)
-
13995  {
-
13996  auto & db = m->get_db();
-
13997  db.update_state(p->state_prev, p->state);
+
13992  // Lastly, we increase the daily count of the virus
+
13993  #ifdef EPI_DEBUG
+
13994  m->get_db().today_virus.at(v->get_id()).at(p->state)++;
+
13995  #else
+
13996  m->get_db().today_virus[v->get_id()][p->state]++;
+
13997  #endif
13998 
-
13999  if (p->virus)
-
14000  db.update_virus(p->virus->get_id(), p->state_prev, p->state);
-
14001  }
-
14002 
-
14003  m->get_db().today_tool[t->get_id()][p->state]++;
+
13999 }
+
14000 
+
14001 template<typename TSeq>
+
14002 inline void default_add_tool(Event<TSeq> & a, Model<TSeq> * m)
+
14003 {
14004 
-
14005 
-
14006 }
-
14007 
-
14008 template<typename TSeq>
-
14009 inline void default_rm_virus(Event<TSeq> & a, Model<TSeq> * model)
-
14010 {
+
14005  Agent<TSeq> * p = a.agent;
+
14006  ToolPtr<TSeq> t = a.tool;
+
14007 
+
14008  // Update tool accounting
+
14009  p->n_tools++;
+
14010  size_t n_tools = p->n_tools;
14011 
-
14012  Agent<TSeq> * p = a.agent;
-
14013  VirusPtr<TSeq> & v = a.virus;
-
14014 
-
14015  // Calling the virus action over the removed virus
-
14016  v->post_recovery(model);
-
14017 
-
14018  p->virus = nullptr;
-
14019 
-
14020  // Change of state needs to be recorded and updated on the
-
14021  // tools.
-
14022  if (p->state_prev != p->state)
-
14023  {
-
14024  auto & db = model->get_db();
-
14025  db.update_state(p->state_prev, p->state);
-
14026 
-
14027  for (size_t i = 0u; i < p->n_tools; ++i)
-
14028  db.update_tool(p->tools[i]->get_id(), p->state_prev, p->state);
-
14029  }
-
14030 
-
14031  // The counters of the virus only needs to decrease
-
14032  #ifdef EPI_DEBUG
-
14033  model->get_db().today_virus.at(v->get_id()).at(p->state_prev)--;
-
14034  #else
-
14035  model->get_db().today_virus[v->get_id()][p->state_prev]--;
-
14036  #endif
+
14012  if (n_tools <= p->tools.size())
+
14013  p->tools[n_tools - 1] = std::make_shared< Tool<TSeq> >(*t);
+
14014  else
+
14015  p->tools.push_back(std::make_shared< Tool<TSeq> >(*t));
+
14016 
+
14017  n_tools--;
+
14018 
+
14019  p->tools[n_tools]->set_date(m->today());
+
14020  p->tools[n_tools]->set_agent(p, n_tools);
+
14021 
+
14022  // Change of state needs to be recorded and updated on the
+
14023  // tools.
+
14024  if (p->state_prev != p->state)
+
14025  {
+
14026  auto & db = m->get_db();
+
14027  db.update_state(p->state_prev, p->state);
+
14028 
+
14029  if (p->virus)
+
14030  db.update_virus(p->virus->get_id(), p->state_prev, p->state);
+
14031  }
+
14032 
+
14033  m->get_db().today_tool[t->get_id()][p->state]++;
+
14034 
+
14035 
+
14036 }
14037 
-
14038 
-
14039  return;
-
14040 
-
14041 }
-
14042 
-
14043 template<typename TSeq>
-
14044 inline void default_rm_tool(Event<TSeq> & a, Model<TSeq> * m)
-
14045 {
-
14046 
-
14047  Agent<TSeq> * p = a.agent;
-
14048  ToolPtr<TSeq> & t = a.agent->tools[a.tool->pos_in_agent];
+
14038 template<typename TSeq>
+
14039 inline void default_rm_virus(Event<TSeq> & a, Model<TSeq> * model)
+
14040 {
+
14041 
+
14042  Agent<TSeq> * p = a.agent;
+
14043  VirusPtr<TSeq> & v = a.virus;
+
14044 
+
14045  // Calling the virus action over the removed virus
+
14046  v->post_recovery(model);
+
14047 
+
14048  p->virus = nullptr;
14049 
-
14050  if (--p->n_tools > 0)
-
14051  {
-
14052  p->tools[p->n_tools]->pos_in_agent = t->pos_in_agent;
-
14053  std::swap(
-
14054  p->tools[t->pos_in_agent],
-
14055  p->tools[p->n_tools]
-
14056  );
-
14057  }
-
14058 
-
14059  // Change of state needs to be recorded and updated on the
-
14060  // tools.
-
14061  if (p->state_prev != p->state)
-
14062  {
-
14063  auto & db = m->get_db();
-
14064  db.update_state(p->state_prev, p->state);
-
14065 
-
14066  if (p->virus)
-
14067  db.update_virus(p->virus->get_id(), p->state_prev, p->state);
-
14068  }
-
14069 
-
14070  // Lastly, we increase the daily count of the tool
-
14071  #ifdef EPI_DEBUG
-
14072  m->get_db().today_tool.at(t->get_id()).at(p->state_prev)--;
-
14073  #else
-
14074  m->get_db().today_tool[t->get_id()][p->state_prev]--;
-
14075  #endif
+
14050  // Change of state needs to be recorded and updated on the
+
14051  // tools.
+
14052  if (p->state_prev != p->state)
+
14053  {
+
14054  auto & db = model->get_db();
+
14055  db.update_state(p->state_prev, p->state);
+
14056 
+
14057  for (size_t i = 0u; i < p->n_tools; ++i)
+
14058  db.update_tool(p->tools[i]->get_id(), p->state_prev, p->state);
+
14059  }
+
14060 
+
14061  // The counters of the virus only needs to decrease
+
14062  #ifdef EPI_DEBUG
+
14063  model->get_db().today_virus.at(v->get_id()).at(p->state_prev)--;
+
14064  #else
+
14065  model->get_db().today_virus[v->get_id()][p->state_prev]--;
+
14066  #endif
+
14067 
+
14068 
+
14069  return;
+
14070 
+
14071 }
+
14072 
+
14073 template<typename TSeq>
+
14074 inline void default_rm_tool(Event<TSeq> & a, Model<TSeq> * m)
+
14075 {
14076 
-
14077  return;
-
14078 
-
14079 }
-
14080 
-
14081 template<typename TSeq>
-
14082 inline void default_change_state(Event<TSeq> & a, Model<TSeq> * m)
-
14083 {
-
14084 
-
14085  Agent<TSeq> * p = a.agent;
-
14086 
-
14087  if (p->state_prev != p->state)
-
14088  {
-
14089  auto & db = m->get_db();
-
14090  db.update_state(p->state_prev, p->state);
-
14091 
-
14092  if (p->virus)
-
14093  db.update_virus(p->virus->get_id(), p->state_prev, p->state);
-
14094 
-
14095  for (size_t i = 0u; i < p->n_tools; ++i)
-
14096  db.update_tool(p->tools[i]->get_id(), p->state_prev, p->state);
-
14097 
+
14077  Agent<TSeq> * p = a.agent;
+
14078  ToolPtr<TSeq> & t = a.agent->tools[a.tool->pos_in_agent];
+
14079 
+
14080  if (--p->n_tools > 0)
+
14081  {
+
14082  p->tools[p->n_tools]->pos_in_agent = t->pos_in_agent;
+
14083  std::swap(
+
14084  p->tools[t->pos_in_agent],
+
14085  p->tools[p->n_tools]
+
14086  );
+
14087  }
+
14088 
+
14089  // Change of state needs to be recorded and updated on the
+
14090  // tools.
+
14091  if (p->state_prev != p->state)
+
14092  {
+
14093  auto & db = m->get_db();
+
14094  db.update_state(p->state_prev, p->state);
+
14095 
+
14096  if (p->virus)
+
14097  db.update_virus(p->virus->get_id(), p->state_prev, p->state);
14098  }
14099 
-
14100 }
-
14101 
-
14102 template<typename TSeq>
-
14103 inline void default_add_entity(Event<TSeq> & a, Model<TSeq> *)
-
14104 {
-
14105 
-
14106  Agent<TSeq> * p = a.agent;
-
14107  Entity<TSeq> * e = a.entity;
+
14100  // Lastly, we increase the daily count of the tool
+
14101  #ifdef EPI_DEBUG
+
14102  m->get_db().today_tool.at(t->get_id()).at(p->state_prev)--;
+
14103  #else
+
14104  m->get_db().today_tool[t->get_id()][p->state_prev]--;
+
14105  #endif
+
14106 
+
14107  return;
14108 
-
14109  // Checking the agent and the entity are not linked
-
14110  if ((p->get_n_entities() > 0) && (e->size() > 0))
-
14111  {
-
14112 
-
14113  if (p->get_n_entities() > e->size()) // Slower search through the agent
-
14114  {
-
14115  for (size_t i = 0u; i < e->size(); ++i)
-
14116  if(static_cast<int>(e->operator[](i)) == p->get_id())
-
14117  throw std::logic_error("An entity cannot be reassigned to an agent.");
-
14118  }
-
14119  else // Slower search through the entity
-
14120  {
-
14121  for (size_t i = 0u; i < p->get_n_entities(); ++i)
-
14122  if(p->get_entity(i).get_id() == e->get_id())
-
14123  throw std::logic_error("An entity cannot be reassigned to an agent.");
-
14124  }
-
14125 
-
14126  // It means that agent and entity were not associated.
-
14127  }
-
14128 
-
14129  // Adding the entity to the agent
-
14130  if (++p->n_entities <= p->entities.size())
-
14131  {
-
14132 
-
14133  p->entities[p->n_entities - 1] = e->get_id();
-
14134  p->entities_locations[p->n_entities - 1] = e->n_agents;
+
14109 }
+
14110 
+
14111 template<typename TSeq>
+
14112 inline void default_change_state(Event<TSeq> & a, Model<TSeq> * m)
+
14113 {
+
14114 
+
14115  Agent<TSeq> * p = a.agent;
+
14116 
+
14117  if (p->state_prev != p->state)
+
14118  {
+
14119  auto & db = m->get_db();
+
14120  db.update_state(p->state_prev, p->state);
+
14121 
+
14122  if (p->virus)
+
14123  db.update_virus(p->virus->get_id(), p->state_prev, p->state);
+
14124 
+
14125  for (size_t i = 0u; i < p->n_tools; ++i)
+
14126  db.update_tool(p->tools[i]->get_id(), p->state_prev, p->state);
+
14127 
+
14128  }
+
14129 
+
14130 }
+
14131 
+
14132 template<typename TSeq>
+
14133 inline void default_add_entity(Event<TSeq> & a, Model<TSeq> *)
+
14134 {
14135 
-
14136  } else
-
14137  {
-
14138  p->entities.push_back(e->get_id());
-
14139  p->entities_locations.push_back(e->n_agents);
-
14140  }
-
14141 
-
14142  // Adding the agent to the entity
-
14143  // Adding the entity to the agent
-
14144  if (++e->n_agents <= e->agents.size())
-
14145  {
-
14146 
-
14147  e->agents[e->n_agents - 1] = p->get_id();
-
14148  // Adjusted by '-1' since the list of entities in the agent just grew.
-
14149  e->agents_location[e->n_agents - 1] = p->n_entities - 1;
-
14150 
-
14151  } else
-
14152  {
-
14153  e->agents.push_back(p->get_id());
-
14154  e->agents_location.push_back(p->n_entities - 1);
-
14155  }
-
14156 
-
14157  // Today was the last modification
-
14158  // e->date_last_add_or_remove = m->today();
-
14159 
-
14160 }
-
14161 
-
14162 template<typename TSeq>
-
14163 inline void default_rm_entity(Event<TSeq> & a, Model<TSeq> * m)
-
14164 {
-
14165 
-
14166  Agent<TSeq> * p = a.agent;
-
14167  Entity<TSeq> * e = a.entity;
-
14168  size_t idx_agent_in_entity = a.idx_agent;
-
14169  size_t idx_entity_in_agent = a.idx_object;
-
14170 
-
14171  if (--p->n_entities > 0)
-
14172  {
-
14173 
-
14174  // When we move the end entity to the new location, the
-
14175  // moved entity needs to reflect the change, i.e., where the
-
14176  // entity will now be located in the agent
-
14177  size_t agent_location_in_last_entity =
-
14178  p->entities_locations[p->n_entities];
-
14179 
-
14180  Entity<TSeq> * last_entity =
-
14181  &m->get_entity(p->entities[p->n_entities]); ///< Last entity of the agent
-
14182 
-
14183  // The end entity will be located where the removed was
-
14184  last_entity->agents_location[agent_location_in_last_entity] =
-
14185  idx_entity_in_agent;
+
14136  Agent<TSeq> * p = a.agent;
+
14137  Entity<TSeq> * e = a.entity;
+
14138 
+
14139  // Checking the agent and the entity are not linked
+
14140  if ((p->get_n_entities() > 0) && (e->size() > 0))
+
14141  {
+
14142 
+
14143  if (p->get_n_entities() > e->size()) // Slower search through the agent
+
14144  {
+
14145  for (size_t i = 0u; i < e->size(); ++i)
+
14146  if(static_cast<int>(e->operator[](i)) == p->get_id())
+
14147  throw std::logic_error("An entity cannot be reassigned to an agent.");
+
14148  }
+
14149  else // Slower search through the entity
+
14150  {
+
14151  for (size_t i = 0u; i < p->get_n_entities(); ++i)
+
14152  if(p->get_entity(i).get_id() == e->get_id())
+
14153  throw std::logic_error("An entity cannot be reassigned to an agent.");
+
14154  }
+
14155 
+
14156  // It means that agent and entity were not associated.
+
14157  }
+
14158 
+
14159  // Adding the entity to the agent
+
14160  if (++p->n_entities <= p->entities.size())
+
14161  {
+
14162 
+
14163  p->entities[p->n_entities - 1] = e->get_id();
+
14164  p->entities_locations[p->n_entities - 1] = e->n_agents;
+
14165 
+
14166  } else
+
14167  {
+
14168  p->entities.push_back(e->get_id());
+
14169  p->entities_locations.push_back(e->n_agents);
+
14170  }
+
14171 
+
14172  // Adding the agent to the entity
+
14173  // Adding the entity to the agent
+
14174  if (++e->n_agents <= e->agents.size())
+
14175  {
+
14176 
+
14177  e->agents[e->n_agents - 1] = p->get_id();
+
14178  // Adjusted by '-1' since the list of entities in the agent just grew.
+
14179  e->agents_location[e->n_agents - 1] = p->n_entities - 1;
+
14180 
+
14181  } else
+
14182  {
+
14183  e->agents.push_back(p->get_id());
+
14184  e->agents_location.push_back(p->n_entities - 1);
+
14185  }
14186 
-
14187  // We now make the swap
-
14188  std::swap(
-
14189  p->entities[p->n_entities],
-
14190  p->entities[idx_entity_in_agent]
-
14191  );
-
14192 
-
14193  }
-
14194 
-
14195  if (--e->n_agents > 0)
-
14196  {
-
14197 
-
14198  // When we move the end agent to the new location, the
-
14199  // moved agent needs to reflect the change, i.e., where the
-
14200  // agent will now be located in the entity
-
14201  size_t entity_location_in_last_agent = e->agents_location[e->n_agents];
-
14202 
-
14203  Agent<TSeq> * last_agent =
-
14204  &m->get_agents()[e->agents[e->n_agents]]; ///< Last agent of the entity
-
14205 
-
14206  // The end entity will be located where the removed was
-
14207  last_agent->entities_locations[entity_location_in_last_agent] =
-
14208  idx_agent_in_entity;
+
14187  // Today was the last modification
+
14188  // e->date_last_add_or_remove = m->today();
+
14189 
+
14190 }
+
14191 
+
14192 template<typename TSeq>
+
14193 inline void default_rm_entity(Event<TSeq> & a, Model<TSeq> * m)
+
14194 {
+
14195 
+
14196  Agent<TSeq> * p = a.agent;
+
14197  Entity<TSeq> * e = a.entity;
+
14198  size_t idx_agent_in_entity = a.idx_agent;
+
14199  size_t idx_entity_in_agent = a.idx_object;
+
14200 
+
14201  if (--p->n_entities > 0)
+
14202  {
+
14203 
+
14204  // When we move the end entity to the new location, the
+
14205  // moved entity needs to reflect the change, i.e., where the
+
14206  // entity will now be located in the agent
+
14207  size_t agent_location_in_last_entity =
+
14208  p->entities_locations[p->n_entities];
14209 
-
14210  // We now make the swap
-
14211  std::swap(
-
14212  e->agents[e->n_agents],
-
14213  e->agents[idx_agent_in_entity]
-
14214  );
-
14215 
-
14216  }
-
14217 
-
14218  // Setting the date of the last removal
-
14219  // e->date_last_add_or_remove = m->today();
-
14220 
-
14221  return;
+
14210  Entity<TSeq> * last_entity =
+
14211  &m->get_entity(p->entities[p->n_entities]); ///< Last entity of the agent
+
14212 
+
14213  // The end entity will be located where the removed was
+
14214  last_entity->agents_location[agent_location_in_last_entity] =
+
14215  idx_entity_in_agent;
+
14216 
+
14217  // We now make the swap
+
14218  std::swap(
+
14219  p->entities[p->n_entities],
+
14220  p->entities[idx_entity_in_agent]
+
14221  );
14222 
-
14223 }
-
14224 #endif
-
14225 /*//////////////////////////////////////////////////////////////////////////////
+
14223  }
+
14224 
+
14225  if (--e->n_agents > 0)
+
14226  {
14227 
-
14228  End of -include/epiworld//agent-events-meat.hpp-
-
14229 
-
14232 
-
14233 
-
14234 
-
14235 template<typename TSeq>
-
14236 inline Agent<TSeq>::Agent() {}
-
14237 
-
14238 template<typename TSeq>
-
14239 inline Agent<TSeq>::Agent(Agent<TSeq> && p) :
-
14240  model(p.model),
-
14241  neighbors(std::move(p.neighbors)),
-
14242  neighbors_locations(std::move(p.neighbors_locations)),
-
14243  n_neighbors(p.n_neighbors),
-
14244  entities(std::move(p.entities)),
-
14245  entities_locations(std::move(p.entities_locations)),
-
14246  n_entities(p.n_entities),
-
14247  state(p.state),
-
14248  state_prev(p.state_prev),
-
14249  state_last_changed(p.state_last_changed),
-
14250  id(p.id),
-
14251  tools(std::move(p.tools)), /// Needs to be adjusted
-
14252  n_tools(p.n_tools)
-
14253 {
-
14254 
-
14255  state = p.state;
-
14256  id = p.id;
-
14257 
-
14258  // Dealing with the virus
-
14259  if (p.virus != nullptr)
-
14260  {
-
14261  virus = std::move(p.virus);
-
14262  virus->set_agent(this);
-
14263  }
+
14228  // When we move the end agent to the new location, the
+
14229  // moved agent needs to reflect the change, i.e., where the
+
14230  // agent will now be located in the entity
+
14231  size_t entity_location_in_last_agent = e->agents_location[e->n_agents];
+
14232 
+
14233  Agent<TSeq> * last_agent =
+
14234  &m->get_agents()[e->agents[e->n_agents]]; ///< Last agent of the entity
+
14235 
+
14236  // The end entity will be located where the removed was
+
14237  last_agent->entities_locations[entity_location_in_last_agent] =
+
14238  idx_agent_in_entity;
+
14239 
+
14240  // We now make the swap
+
14241  std::swap(
+
14242  e->agents[e->n_agents],
+
14243  e->agents[idx_agent_in_entity]
+
14244  );
+
14245 
+
14246  }
+
14247 
+
14248  // Setting the date of the last removal
+
14249  // e->date_last_add_or_remove = m->today();
+
14250 
+
14251  return;
+
14252 
+
14253 }
+
14254 #endif
+
14255 /*//////////////////////////////////////////////////////////////////////////////
+
14257 
+
14258  End of -include/epiworld//agent-events-meat.hpp-
+
14259 
+
14262 
+
14263 
14264 
-
14265  int loc = 0;
-
14266  for (auto & t : tools)
-
14267  {
-
14268 
-
14269  // Will create a copy of the virus, with the exeption of
-
14270  // the virus code
-
14271  t->agent = this;
-
14272  t->pos_in_agent = loc++;
-
14273 
-
14274  }
-
14275 
-
14276 }
-
14277 
-
14278 template<typename TSeq>
-
14279 inline Agent<TSeq>::Agent(const Agent<TSeq> & p) :
-
14280  model(p.model),
-
14281  neighbors(p.neighbors),
-
14282  neighbors_locations(p.neighbors_locations),
-
14283  n_neighbors(p.n_neighbors),
-
14284  entities(p.entities),
-
14285  entities_locations(p.entities_locations),
-
14286  n_entities(p.n_entities),
-
14287  sampled_agents(0u),
-
14288  sampled_agents_n(0u),
-
14289  sampled_agents_left_n(0u),
-
14290  date_last_build_sample(-99)
-
14291 {
-
14292 
-
14293  state = p.state;
-
14294  id = p.id;
-
14295 
-
14296  // Dealing with the virus
-
14297  if (p.virus != nullptr)
-
14298  {
-
14299  virus = std::make_shared<Virus<TSeq>>(*p.virus);
-
14300  virus->set_agent(this);
-
14301  }
-
14302 
+
14265 template<typename TSeq>
+
14266 inline Agent<TSeq>::Agent() {}
+
14267 
+
14268 template<typename TSeq>
+
14269 inline Agent<TSeq>::Agent(Agent<TSeq> && p) :
+
14270  model(p.model),
+
14271  neighbors(std::move(p.neighbors)),
+
14272  neighbors_locations(std::move(p.neighbors_locations)),
+
14273  n_neighbors(p.n_neighbors),
+
14274  entities(std::move(p.entities)),
+
14275  entities_locations(std::move(p.entities_locations)),
+
14276  n_entities(p.n_entities),
+
14277  state(p.state),
+
14278  state_prev(p.state_prev),
+
14279  state_last_changed(p.state_last_changed),
+
14280  id(p.id),
+
14281  tools(std::move(p.tools)), /// Needs to be adjusted
+
14282  n_tools(p.n_tools)
+
14283 {
+
14284 
+
14285  state = p.state;
+
14286  id = p.id;
+
14287 
+
14288  // Dealing with the virus
+
14289  if (p.virus != nullptr)
+
14290  {
+
14291  virus = std::move(p.virus);
+
14292  virus->set_agent(this);
+
14293  }
+
14294 
+
14295  int loc = 0;
+
14296  for (auto & t : tools)
+
14297  {
+
14298 
+
14299  // Will create a copy of the virus, with the exeption of
+
14300  // the virus code
+
14301  t->agent = this;
+
14302  t->pos_in_agent = loc++;
14303 
-
14304  tools.reserve(p.get_n_tools());
-
14305  n_tools = tools.size();
-
14306  for (size_t i = 0u; i < n_tools; ++i)
-
14307  {
-
14308 
-
14309  // Will create a copy of the virus, with the exeption of
-
14310  // the virus code
-
14311  tools.emplace_back(std::make_shared<Tool<TSeq>>(*p.tools[i]));
-
14312  tools.back()->set_agent(this, i);
-
14313 
-
14314  }
-
14315 
-
14316 }
-
14317 
-
14318 template<typename TSeq>
-
14319 inline Agent<TSeq> & Agent<TSeq>::operator=(
-
14320  const Agent<TSeq> & other_agent
-
14321 )
-
14322 {
-
14323 
-
14324  model = other_agent.model;
-
14325 
-
14326  neighbors = other_agent.neighbors;
-
14327  neighbors_locations = other_agent.neighbors_locations;
-
14328  n_neighbors = other_agent.n_neighbors;
-
14329 
-
14330  entities = other_agent.entities;
-
14331  entities_locations = other_agent.entities_locations;
-
14332  n_entities = other_agent.n_entities;
+
14304  }
+
14305 
+
14306 }
+
14307 
+
14308 template<typename TSeq>
+
14309 inline Agent<TSeq>::Agent(const Agent<TSeq> & p) :
+
14310  model(p.model),
+
14311  neighbors(p.neighbors),
+
14312  neighbors_locations(p.neighbors_locations),
+
14313  n_neighbors(p.n_neighbors),
+
14314  entities(p.entities),
+
14315  entities_locations(p.entities_locations),
+
14316  n_entities(p.n_entities),
+
14317  sampled_agents(0u),
+
14318  sampled_agents_n(0u),
+
14319  sampled_agents_left_n(0u),
+
14320  date_last_build_sample(-99)
+
14321 {
+
14322 
+
14323  state = p.state;
+
14324  id = p.id;
+
14325 
+
14326  // Dealing with the virus
+
14327  if (p.virus != nullptr)
+
14328  {
+
14329  virus = std::make_shared<Virus<TSeq>>(*p.virus);
+
14330  virus->set_agent(this);
+
14331  }
+
14332 
14333 
-
14334  sampled_agents.clear();
-
14335  sampled_agents_n = 0;
-
14336  sampled_agents_left_n = 0;
-
14337  date_last_build_sample = -99;
-
14338 
-
14339  // neighbors = other_agent.neighbors;
-
14340  // entities = other_agent.entities;
-
14341  // entities_locations = other_agent.entities_locations;
-
14342  // n_entities = other_agent.n_entities;
-
14343  state = other_agent.state;
-
14344  state_prev = other_agent.state_prev;
-
14345  state_last_changed = other_agent.state_last_changed;
-
14346  id = other_agent.id;
-
14347 
-
14348  if (other_agent.virus != nullptr)
-
14349  {
-
14350  virus = std::make_shared<Virus<TSeq>>(*other_agent.virus);
-
14351  virus->set_agent(this);
-
14352  } else
-
14353  virus = nullptr;
-
14354 
-
14355  // tools = other_agent.tools;
-
14356  n_tools = other_agent.n_tools;
-
14357  for (size_t i = 0u; i < n_tools; ++i)
-
14358  {
-
14359  tools[i] = std::make_shared<Tool<TSeq>>(*other_agent.tools[i]);
-
14360  tools[i]->set_agent(this, i);
-
14361  }
-
14362 
-
14363  return *this;
-
14364 
-
14365 }
-
14366 
-
14367 template<typename TSeq>
-
14368 inline void Agent<TSeq>::add_tool(
-
14369  ToolPtr<TSeq> tool,
-
14370  Model<TSeq> * model,
-
14371  epiworld_fast_int state_new,
-
14372  epiworld_fast_int queue
-
14373 ) {
-
14374 
-
14375  // Checking the virus exists
-
14376  if (tool->get_id() >= static_cast<int>(model->get_db().get_n_tools()))
-
14377  throw std::range_error("The tool with id: " + std::to_string(tool->get_id()) +
-
14378  " has not been registered. There are only " + std::to_string(model->get_n_tools()) +
-
14379  " included in the model.");
-
14380 
-
14381  CHECK_COALESCE_(state_new, tool->state_init, state);
-
14382  CHECK_COALESCE_(queue, tool->queue_init, Queue<TSeq>::NoOne);
-
14383 
-
14384  model->events_add(
-
14385  this, nullptr, tool, nullptr, state_new, queue, default_add_tool<TSeq>, -1, -1
-
14386  );
-
14387 
-
14388 }
-
14389 
-
14390 template<typename TSeq>
-
14391 inline void Agent<TSeq>::add_tool(
-
14392  Tool<TSeq> tool,
-
14393  Model<TSeq> * model,
-
14394  epiworld_fast_int state_new,
-
14395  epiworld_fast_int queue
-
14396 )
-
14397 {
-
14398  ToolPtr<TSeq> tool_ptr = std::make_shared< Tool<TSeq> >(tool);
-
14399  add_tool(tool_ptr, model, state_new, queue);
-
14400 }
-
14401 
-
14402 template<typename TSeq>
-
14403 inline void Agent<TSeq>::set_virus(
-
14404  VirusPtr<TSeq> virus,
-
14405  Model<TSeq> * model,
-
14406  epiworld_fast_int state_new,
-
14407  epiworld_fast_int queue
-
14408 )
-
14409 {
+
14334  tools.reserve(p.get_n_tools());
+
14335  n_tools = tools.size();
+
14336  for (size_t i = 0u; i < n_tools; ++i)
+
14337  {
+
14338 
+
14339  // Will create a copy of the virus, with the exeption of
+
14340  // the virus code
+
14341  tools.emplace_back(std::make_shared<Tool<TSeq>>(*p.tools[i]));
+
14342  tools.back()->set_agent(this, i);
+
14343 
+
14344  }
+
14345 
+
14346 }
+
14347 
+
14348 template<typename TSeq>
+
14349 inline Agent<TSeq> & Agent<TSeq>::operator=(
+
14350  const Agent<TSeq> & other_agent
+
14351 )
+
14352 {
+
14353 
+
14354  model = other_agent.model;
+
14355 
+
14356  neighbors = other_agent.neighbors;
+
14357  neighbors_locations = other_agent.neighbors_locations;
+
14358  n_neighbors = other_agent.n_neighbors;
+
14359 
+
14360  entities = other_agent.entities;
+
14361  entities_locations = other_agent.entities_locations;
+
14362  n_entities = other_agent.n_entities;
+
14363 
+
14364  sampled_agents.clear();
+
14365  sampled_agents_n = 0;
+
14366  sampled_agents_left_n = 0;
+
14367  date_last_build_sample = -99;
+
14368 
+
14369  // neighbors = other_agent.neighbors;
+
14370  // entities = other_agent.entities;
+
14371  // entities_locations = other_agent.entities_locations;
+
14372  // n_entities = other_agent.n_entities;
+
14373  state = other_agent.state;
+
14374  state_prev = other_agent.state_prev;
+
14375  state_last_changed = other_agent.state_last_changed;
+
14376  id = other_agent.id;
+
14377 
+
14378  if (other_agent.virus != nullptr)
+
14379  {
+
14380  virus = std::make_shared<Virus<TSeq>>(*other_agent.virus);
+
14381  virus->set_agent(this);
+
14382  } else
+
14383  virus = nullptr;
+
14384 
+
14385  // tools = other_agent.tools;
+
14386  n_tools = other_agent.n_tools;
+
14387  for (size_t i = 0u; i < n_tools; ++i)
+
14388  {
+
14389  tools[i] = std::make_shared<Tool<TSeq>>(*other_agent.tools[i]);
+
14390  tools[i]->set_agent(this, i);
+
14391  }
+
14392 
+
14393  return *this;
+
14394 
+
14395 }
+
14396 
+
14397 template<typename TSeq>
+
14398 inline void Agent<TSeq>::add_tool(
+
14399  ToolPtr<TSeq> tool,
+
14400  Model<TSeq> * model,
+
14401  epiworld_fast_int state_new,
+
14402  epiworld_fast_int queue
+
14403 ) {
+
14404 
+
14405  // Checking the virus exists
+
14406  if (tool->get_id() >= static_cast<int>(model->get_db().get_n_tools()))
+
14407  throw std::range_error("The tool with id: " + std::to_string(tool->get_id()) +
+
14408  " has not been registered. There are only " + std::to_string(model->get_n_tools()) +
+
14409  " included in the model.");
14410 
-
14411  // Checking the virus exists
-
14412  if (virus->get_id() >= static_cast<int>(model->get_db().get_n_viruses()))
-
14413  throw std::range_error("The virus with id: " + std::to_string(virus->get_id()) +
-
14414  " has not been registered. There are only " + std::to_string(model->get_n_viruses()) +
-
14415  " included in the model.");
-
14416 
-
14417  CHECK_COALESCE_(state_new, virus->state_init, state);
-
14418  CHECK_COALESCE_(queue, virus->queue_init, Queue<TSeq>::NoOne);
+
14411  CHECK_COALESCE_(state_new, tool->state_init, state);
+
14412  CHECK_COALESCE_(queue, tool->queue_init, Queue<TSeq>::NoOne);
+
14413 
+
14414  model->events_add(
+
14415  this, nullptr, tool, nullptr, state_new, queue, default_add_tool<TSeq>, -1, -1
+
14416  );
+
14417 
+
14418 }
14419 
-
14420  model->events_add(
-
14421  this, virus, nullptr, nullptr, state_new, queue, default_add_virus<TSeq>, -1, -1
-
14422  );
-
14423 
-
14424 }
-
14425 
-
14426 template<typename TSeq>
-
14427 inline void Agent<TSeq>::set_virus(
-
14428  Virus<TSeq> virus,
-
14429  Model<TSeq> * model,
-
14430  epiworld_fast_int state_new,
-
14431  epiworld_fast_int queue
-
14432 )
-
14433 {
-
14434  VirusPtr<TSeq> virus_ptr = std::make_shared< Virus<TSeq> >(virus);
-
14435  set_virus(virus_ptr, model, state_new, queue);
-
14436 }
-
14437 
-
14438 template<typename TSeq>
-
14439 inline void Agent<TSeq>::add_entity(
-
14440  Entity<TSeq> & entity,
-
14441  Model<TSeq> * model,
-
14442  epiworld_fast_int state_new,
-
14443  epiworld_fast_int queue
-
14444 )
-
14445 {
+
14420 template<typename TSeq>
+
14421 inline void Agent<TSeq>::add_tool(
+
14422  Tool<TSeq> tool,
+
14423  Model<TSeq> * model,
+
14424  epiworld_fast_int state_new,
+
14425  epiworld_fast_int queue
+
14426 )
+
14427 {
+
14428  ToolPtr<TSeq> tool_ptr = std::make_shared< Tool<TSeq> >(tool);
+
14429  add_tool(tool_ptr, model, state_new, queue);
+
14430 }
+
14431 
+
14432 template<typename TSeq>
+
14433 inline void Agent<TSeq>::set_virus(
+
14434  VirusPtr<TSeq> virus,
+
14435  Model<TSeq> * model,
+
14436  epiworld_fast_int state_new,
+
14437  epiworld_fast_int queue
+
14438 )
+
14439 {
+
14440 
+
14441  // Checking the virus exists
+
14442  if (virus->get_id() >= static_cast<int>(model->get_db().get_n_viruses()))
+
14443  throw std::range_error("The virus with id: " + std::to_string(virus->get_id()) +
+
14444  " has not been registered. There are only " + std::to_string(model->get_n_viruses()) +
+
14445  " included in the model.");
14446 
-
14447  CHECK_COALESCE_(state_new, entity.state_init, state);
-
14448  CHECK_COALESCE_(queue, entity.queue_init, Queue<TSeq>::NoOne);
+
14447  CHECK_COALESCE_(state_new, virus->state_init, state);
+
14448  CHECK_COALESCE_(queue, virus->queue_init, Queue<TSeq>::NoOne);
14449 
-
14450  if (model != nullptr)
-
14451  {
-
14452 
-
14453  model->events_add(
-
14454  this, nullptr, nullptr, &entity, state_new, queue, default_add_entity<TSeq>, -1, -1
-
14455  );
-
14456 
-
14457  }
-
14458  else // If no model is passed, then we assume that we only need to add the
-
14459  // model entity
-
14460  {
-
14461 
-
14462  Event<TSeq> a(
-
14463  this, nullptr, nullptr, &entity, state_new, queue, default_add_entity<TSeq>,
-
14464  -1, -1
-
14465  );
-
14466 
-
14467  default_add_entity(a, model); /* passing model makes nothing */
-
14468 
-
14469  }
-
14470 
-
14471 }
-
14472 
-
14473 template<typename TSeq>
-
14474 inline void Agent<TSeq>::rm_tool(
-
14475  epiworld_fast_uint tool_idx,
-
14476  Model<TSeq> * model,
-
14477  epiworld_fast_int state_new,
-
14478  epiworld_fast_int queue
-
14479 )
-
14480 {
-
14481 
-
14482  CHECK_COALESCE_(state_new, tools[tool_idx]->state_post, state);
-
14483  CHECK_COALESCE_(queue, tools[tool_idx]->queue_post, Queue<TSeq>::NoOne);
-
14484 
-
14485  if (tool_idx >= n_tools)
-
14486  throw std::range_error(
-
14487  "The Tool you want to remove is out of range. This Agent only has " +
-
14488  std::to_string(n_tools) + " tools."
-
14489  );
-
14490 
-
14491  model->events_add(
-
14492  this, nullptr, tools[tool_idx], nullptr, state_new, queue, default_rm_tool<TSeq>, -1, -1
-
14493  );
-
14494 
-
14495 }
-
14496 
-
14497 template<typename TSeq>
-
14498 inline void Agent<TSeq>::rm_tool(
-
14499  ToolPtr<TSeq> & tool,
-
14500  Model<TSeq> * model,
-
14501  epiworld_fast_int state_new,
-
14502  epiworld_fast_int queue
-
14503 )
-
14504 {
-
14505 
-
14506  if (tool->agent != this)
-
14507  throw std::logic_error("Cannot remove a virus from another agent!");
-
14508 
-
14509  model->events_add(
-
14510  this, nullptr, tool, nullptr, state_new, queue, default_rm_tool<TSeq>, -1, -1
-
14511  );
-
14512 
-
14513 }
+
14450  model->events_add(
+
14451  this, virus, nullptr, nullptr, state_new, queue, default_add_virus<TSeq>, -1, -1
+
14452  );
+
14453 
+
14454 }
+
14455 
+
14456 template<typename TSeq>
+
14457 inline void Agent<TSeq>::set_virus(
+
14458  Virus<TSeq> virus,
+
14459  Model<TSeq> * model,
+
14460  epiworld_fast_int state_new,
+
14461  epiworld_fast_int queue
+
14462 )
+
14463 {
+
14464  VirusPtr<TSeq> virus_ptr = std::make_shared< Virus<TSeq> >(virus);
+
14465  set_virus(virus_ptr, model, state_new, queue);
+
14466 }
+
14467 
+
14468 template<typename TSeq>
+
14469 inline void Agent<TSeq>::add_entity(
+
14470  Entity<TSeq> & entity,
+
14471  Model<TSeq> * model,
+
14472  epiworld_fast_int state_new,
+
14473  epiworld_fast_int queue
+
14474 )
+
14475 {
+
14476 
+
14477  CHECK_COALESCE_(state_new, entity.state_init, state);
+
14478  CHECK_COALESCE_(queue, entity.queue_init, Queue<TSeq>::NoOne);
+
14479 
+
14480  if (model != nullptr)
+
14481  {
+
14482 
+
14483  model->events_add(
+
14484  this, nullptr, nullptr, &entity, state_new, queue, default_add_entity<TSeq>, -1, -1
+
14485  );
+
14486 
+
14487  }
+
14488  else // If no model is passed, then we assume that we only need to add the
+
14489  // model entity
+
14490  {
+
14491 
+
14492  Event<TSeq> a(
+
14493  this, nullptr, nullptr, &entity, state_new, queue, default_add_entity<TSeq>,
+
14494  -1, -1
+
14495  );
+
14496 
+
14497  default_add_entity(a, model); /* passing model makes nothing */
+
14498 
+
14499  }
+
14500 
+
14501 }
+
14502 
+
14503 template<typename TSeq>
+
14504 inline void Agent<TSeq>::rm_tool(
+
14505  epiworld_fast_uint tool_idx,
+
14506  Model<TSeq> * model,
+
14507  epiworld_fast_int state_new,
+
14508  epiworld_fast_int queue
+
14509 )
+
14510 {
+
14511 
+
14512  CHECK_COALESCE_(state_new, tools[tool_idx]->state_post, state);
+
14513  CHECK_COALESCE_(queue, tools[tool_idx]->queue_post, Queue<TSeq>::NoOne);
14514 
-
14515 template<typename TSeq>
-
14516 inline void Agent<TSeq>::rm_virus(
-
14517  Model<TSeq> * model,
-
14518  epiworld_fast_int state_new,
-
14519  epiworld_fast_int queue
-
14520 )
-
14521 {
-
14522 
-
14523  if (virus == nullptr)
-
14524  throw std::logic_error(
-
14525  "There is no virus to remove here!"
-
14526  );
-
14527 
-
14528  CHECK_COALESCE_(state_new, virus->state_post, state);
-
14529  CHECK_COALESCE_(queue, virus->queue_post, Queue<TSeq>::Everyone);
-
14530 
-
14531  model->events_add(
-
14532  this, virus, nullptr, nullptr, state_new, queue,
-
14533  default_rm_virus<TSeq>, -1, -1
-
14534  );
-
14535 
-
14536 }
-
14537 
-
14538 template<typename TSeq>
-
14539 inline void Agent<TSeq>::rm_entity(
-
14540  epiworld_fast_uint entity_idx,
-
14541  Model<TSeq> * model,
-
14542  epiworld_fast_int state_new,
-
14543  epiworld_fast_int queue
-
14544 )
-
14545 {
-
14546 
-
14547  if (entity_idx >= n_entities)
-
14548  throw std::range_error(
-
14549  "The Entity you want to remove is out of range. This Agent only has " +
-
14550  std::to_string(n_entities) + " entitites."
-
14551  );
-
14552  else if (n_entities == 0u)
-
14553  throw std::logic_error(
-
14554  "There is entity to remove here!"
-
14555  );
-
14556 
-
14557  CHECK_COALESCE_(state_new, model->get_entity(entity_idx).state_post, state);
-
14558  CHECK_COALESCE_(queue, model->get_entity(entity_idx).queue_post, Queue<TSeq>::NoOne);
-
14559 
-
14560  model->events_add(
-
14561  this,
-
14562  nullptr,
-
14563  nullptr,
-
14564  &model->get_entity(entity_idx),
-
14565  state_new,
-
14566  queue,
-
14567  default_rm_entity<TSeq>,
-
14568  entities_locations[entity_idx],
-
14569  entity_idx
-
14570  );
-
14571 }
-
14572 
-
14573 template<typename TSeq>
-
14574 inline void Agent<TSeq>::rm_entity(
-
14575  Entity<TSeq> & entity,
-
14576  Model<TSeq> * model,
-
14577  epiworld_fast_int state_new,
-
14578  epiworld_fast_int queue
-
14579 )
-
14580 {
-
14581 
-
14582  // Looking for entity location in the agent
-
14583  int entity_idx = -1;
-
14584  for (size_t i = 0u; i < n_entities; ++i)
-
14585  {
-
14586  if (static_cast<int>(entities[i]) == entity.get_id())
-
14587  {
-
14588  entity_idx = i;
-
14589  break;
-
14590  }
-
14591  }
-
14592 
-
14593  if (entity_idx == -1)
-
14594  throw std::logic_error(
-
14595  std::string("The agent ") +
-
14596  std::to_string(id) +
-
14597  std::string(" is not associated with entity \"") +
-
14598  entity.get_name() +
-
14599  std::string("\".")
-
14600  );
-
14601 
-
14602  CHECK_COALESCE_(state_new, entity.state_post, state);
-
14603  CHECK_COALESCE_(queue, entity.queue_post, Queue<TSeq>::NoOne);
-
14604 
-
14605  model->events_add(
-
14606  this,
-
14607  nullptr,
-
14608  nullptr,
-
14609  &model->entities[entity.get_id()],
-
14610  state_new,
-
14611  queue,
-
14612  default_rm_entity<TSeq>,
-
14613  entities_locations[entity_idx],
-
14614  entity_idx
-
14615  );
-
14616 }
-
14617 
-
14618 template<typename TSeq>
- -
14620  Model<TSeq> * model,
-
14621  epiworld_fast_int state_new,
-
14622  epiworld_fast_int queue
-
14623 )
-
14624 {
-
14625 
-
14626  CHECK_COALESCE_(state_new, virus->state_removed, state);
-
14627  CHECK_COALESCE_(queue, virus->queue_removed, Queue<TSeq>::Everyone);
-
14628 
-
14629  model->events_add(
-
14630  this, virus, nullptr, nullptr, state_new, queue,
-
14631  default_rm_virus<TSeq>, -1, -1
-
14632  );
-
14633 
-
14634 }
-
14635 
-
14636 template<typename TSeq>
-
14637 inline epiworld_double Agent<TSeq>::get_susceptibility_reduction(
-
14638  VirusPtr<TSeq> v,
-
14639  Model<TSeq> * model
-
14640 ) {
-
14641 
-
14642  return model->susceptibility_reduction_mixer(this, v, model);
-
14643 }
-
14644 
-
14645 template<typename TSeq>
-
14646 inline epiworld_double Agent<TSeq>::get_transmission_reduction(
-
14647  VirusPtr<TSeq> v,
-
14648  Model<TSeq> * model
-
14649 ) {
-
14650  return model->transmission_reduction_mixer(this, v, model);
-
14651 }
-
14652 
-
14653 template<typename TSeq>
-
14654 inline epiworld_double Agent<TSeq>::get_recovery_enhancer(
-
14655  VirusPtr<TSeq> v,
-
14656  Model<TSeq> * model
-
14657 ) {
-
14658  return model->recovery_enhancer_mixer(this, v, model);
-
14659 }
-
14660 
-
14661 template<typename TSeq>
-
14662 inline epiworld_double Agent<TSeq>::get_death_reduction(
-
14663  VirusPtr<TSeq> v,
-
14664  Model<TSeq> * model
-
14665 ) {
-
14666  return model->death_reduction_mixer(this, v, model);
-
14667 }
-
14668 
-
14669 template<typename TSeq>
-
14670 inline int Agent<TSeq>::get_id() const
-
14671 {
-
14672  return id;
+
14515  if (tool_idx >= n_tools)
+
14516  throw std::range_error(
+
14517  "The Tool you want to remove is out of range. This Agent only has " +
+
14518  std::to_string(n_tools) + " tools."
+
14519  );
+
14520 
+
14521  model->events_add(
+
14522  this, nullptr, tools[tool_idx], nullptr, state_new, queue, default_rm_tool<TSeq>, -1, -1
+
14523  );
+
14524 
+
14525 }
+
14526 
+
14527 template<typename TSeq>
+
14528 inline void Agent<TSeq>::rm_tool(
+
14529  ToolPtr<TSeq> & tool,
+
14530  Model<TSeq> * model,
+
14531  epiworld_fast_int state_new,
+
14532  epiworld_fast_int queue
+
14533 )
+
14534 {
+
14535 
+
14536  if (tool->agent != this)
+
14537  throw std::logic_error("Cannot remove a virus from another agent!");
+
14538 
+
14539  model->events_add(
+
14540  this, nullptr, tool, nullptr, state_new, queue, default_rm_tool<TSeq>, -1, -1
+
14541  );
+
14542 
+
14543 }
+
14544 
+
14545 template<typename TSeq>
+
14546 inline void Agent<TSeq>::rm_virus(
+
14547  Model<TSeq> * model,
+
14548  epiworld_fast_int state_new,
+
14549  epiworld_fast_int queue
+
14550 )
+
14551 {
+
14552 
+
14553  if (virus == nullptr)
+
14554  throw std::logic_error(
+
14555  "There is no virus to remove here!"
+
14556  );
+
14557 
+
14558  CHECK_COALESCE_(state_new, virus->state_post, state);
+
14559  CHECK_COALESCE_(queue, virus->queue_post, Queue<TSeq>::Everyone);
+
14560 
+
14561  model->events_add(
+
14562  this, virus, nullptr, nullptr, state_new, queue,
+
14563  default_rm_virus<TSeq>, -1, -1
+
14564  );
+
14565 
+
14566 }
+
14567 
+
14568 template<typename TSeq>
+
14569 inline void Agent<TSeq>::rm_entity(
+
14570  epiworld_fast_uint entity_idx,
+
14571  Model<TSeq> * model,
+
14572  epiworld_fast_int state_new,
+
14573  epiworld_fast_int queue
+
14574 )
+
14575 {
+
14576 
+
14577  if (entity_idx >= n_entities)
+
14578  throw std::range_error(
+
14579  "The Entity you want to remove is out of range. This Agent only has " +
+
14580  std::to_string(n_entities) + " entitites."
+
14581  );
+
14582  else if (n_entities == 0u)
+
14583  throw std::logic_error(
+
14584  "There is entity to remove here!"
+
14585  );
+
14586 
+
14587  CHECK_COALESCE_(state_new, model->get_entity(entity_idx).state_post, state);
+
14588  CHECK_COALESCE_(queue, model->get_entity(entity_idx).queue_post, Queue<TSeq>::NoOne);
+
14589 
+
14590  model->events_add(
+
14591  this,
+
14592  nullptr,
+
14593  nullptr,
+
14594  &model->get_entity(entity_idx),
+
14595  state_new,
+
14596  queue,
+
14597  default_rm_entity<TSeq>,
+
14598  entities_locations[entity_idx],
+
14599  entity_idx
+
14600  );
+
14601 }
+
14602 
+
14603 template<typename TSeq>
+
14604 inline void Agent<TSeq>::rm_entity(
+
14605  Entity<TSeq> & entity,
+
14606  Model<TSeq> * model,
+
14607  epiworld_fast_int state_new,
+
14608  epiworld_fast_int queue
+
14609 )
+
14610 {
+
14611 
+
14612  // Looking for entity location in the agent
+
14613  int entity_idx = -1;
+
14614  for (size_t i = 0u; i < n_entities; ++i)
+
14615  {
+
14616  if (static_cast<int>(entities[i]) == entity.get_id())
+
14617  {
+
14618  entity_idx = i;
+
14619  break;
+
14620  }
+
14621  }
+
14622 
+
14623  if (entity_idx == -1)
+
14624  throw std::logic_error(
+
14625  std::string("The agent ") +
+
14626  std::to_string(id) +
+
14627  std::string(" is not associated with entity \"") +
+
14628  entity.get_name() +
+
14629  std::string("\".")
+
14630  );
+
14631 
+
14632  CHECK_COALESCE_(state_new, entity.state_post, state);
+
14633  CHECK_COALESCE_(queue, entity.queue_post, Queue<TSeq>::NoOne);
+
14634 
+
14635  model->events_add(
+
14636  this,
+
14637  nullptr,
+
14638  nullptr,
+
14639  &model->entities[entity.get_id()],
+
14640  state_new,
+
14641  queue,
+
14642  default_rm_entity<TSeq>,
+
14643  entities_locations[entity_idx],
+
14644  entity_idx
+
14645  );
+
14646 }
+
14647 
+
14648 template<typename TSeq>
+ +
14650  Model<TSeq> * model,
+
14651  epiworld_fast_int state_new,
+
14652  epiworld_fast_int queue
+
14653 )
+
14654 {
+
14655 
+
14656  CHECK_COALESCE_(state_new, virus->state_removed, state);
+
14657  CHECK_COALESCE_(queue, virus->queue_removed, Queue<TSeq>::Everyone);
+
14658 
+
14659  model->events_add(
+
14660  this, virus, nullptr, nullptr, state_new, queue,
+
14661  default_rm_virus<TSeq>, -1, -1
+
14662  );
+
14663 
+
14664 }
+
14665 
+
14666 template<typename TSeq>
+
14667 inline epiworld_double Agent<TSeq>::get_susceptibility_reduction(
+
14668  VirusPtr<TSeq> v,
+
14669  Model<TSeq> * model
+
14670 ) {
+
14671 
+
14672  return model->susceptibility_reduction_mixer(this, v, model);
14673 }
14674 
14675 template<typename TSeq>
-
14676 inline VirusPtr<TSeq> & Agent<TSeq>::get_virus() {
-
14677  return virus;
-
14678 }
-
14679 
-
14680 template<typename TSeq>
-
14681 inline const VirusPtr<TSeq> & Agent<TSeq>::get_virus() const {
-
14682  return virus;
-
14683 }
-
14684 
-
14685 
-
14686 template<typename TSeq>
- -
14688  return Tools<TSeq>(*this);
+
14676 inline epiworld_double Agent<TSeq>::get_transmission_reduction(
+
14677  VirusPtr<TSeq> v,
+
14678  Model<TSeq> * model
+
14679 ) {
+
14680  return model->transmission_reduction_mixer(this, v, model);
+
14681 }
+
14682 
+
14683 template<typename TSeq>
+
14684 inline epiworld_double Agent<TSeq>::get_recovery_enhancer(
+
14685  VirusPtr<TSeq> v,
+
14686  Model<TSeq> * model
+
14687 ) {
+
14688  return model->recovery_enhancer_mixer(this, v, model);
14689 }
14690 
14691 template<typename TSeq>
-
14692 inline const Tools_const<TSeq> Agent<TSeq>::get_tools() const {
-
14693  return Tools_const<TSeq>(*this);
-
14694 }
-
14695 
-
14696 template<typename TSeq>
-
14697 inline ToolPtr<TSeq> & Agent<TSeq>::get_tool(int i)
-
14698 {
-
14699  return tools.at(i);
-
14700 }
-
14701 
-
14702 template<typename TSeq>
-
14703 inline size_t Agent<TSeq>::get_n_tools() const noexcept
-
14704 {
-
14705  return n_tools;
-
14706 }
-
14707 
-
14708 template<typename TSeq>
-
14709 inline void Agent<TSeq>::mutate_virus()
-
14710 {
-
14711 
-
14712  virus->mutate();
-
14713 
-
14714 }
+
14692 inline epiworld_double Agent<TSeq>::get_death_reduction(
+
14693  VirusPtr<TSeq> v,
+
14694  Model<TSeq> * model
+
14695 ) {
+
14696  return model->death_reduction_mixer(this, v, model);
+
14697 }
+
14698 
+
14699 template<typename TSeq>
+
14700 inline int Agent<TSeq>::get_id() const
+
14701 {
+
14702  return id;
+
14703 }
+
14704 
+
14705 template<typename TSeq>
+
14706 inline VirusPtr<TSeq> & Agent<TSeq>::get_virus() {
+
14707  return virus;
+
14708 }
+
14709 
+
14710 template<typename TSeq>
+
14711 inline const VirusPtr<TSeq> & Agent<TSeq>::get_virus() const {
+
14712  return virus;
+
14713 }
+
14714 
14715 
14716 template<typename TSeq>
-
14717 inline void Agent<TSeq>::add_neighbor(
-
14718  Agent<TSeq> & p,
-
14719  bool check_source,
-
14720  bool check_target
-
14721 ) {
-
14722  // Can we find the neighbor?
-
14723  bool found = false;
-
14724  if (check_source)
-
14725  {
-
14726 
-
14727  for (auto & n: neighbors)
-
14728  if (static_cast<int>(n) == p.get_id())
-
14729  {
-
14730  found = true;
-
14731  break;
-
14732  }
-
14733 
-
14734  }
-
14735 
-
14736  // Three things going on here:
-
14737  // - Where in the neighbor will this be
-
14738  // - What is the neighbor's id
-
14739  // - Increasing the number of neighbors
-
14740  if (!found)
-
14741  {
-
14742 
-
14743  neighbors_locations.push_back(p.get_n_neighbors());
-
14744  neighbors.push_back(p.get_id());
-
14745  n_neighbors++;
-
14746 
-
14747  }
-
14748 
-
14749 
-
14750  found = false;
-
14751  if (check_target)
-
14752  {
-
14753 
-
14754  for (auto & n: p.neighbors)
-
14755  if (static_cast<int>(n) == id)
-
14756  {
-
14757  found = true;
-
14758  break;
-
14759  }
-
14760 
-
14761  }
-
14762 
-
14763  if (!found)
-
14764  {
+ +
14718  return Tools<TSeq>(*this);
+
14719 }
+
14720 
+
14721 template<typename TSeq>
+
14722 inline const Tools_const<TSeq> Agent<TSeq>::get_tools() const {
+
14723  return Tools_const<TSeq>(*this);
+
14724 }
+
14725 
+
14726 template<typename TSeq>
+
14727 inline ToolPtr<TSeq> & Agent<TSeq>::get_tool(int i)
+
14728 {
+
14729  return tools.at(i);
+
14730 }
+
14731 
+
14732 template<typename TSeq>
+
14733 inline size_t Agent<TSeq>::get_n_tools() const noexcept
+
14734 {
+
14735  return n_tools;
+
14736 }
+
14737 
+
14738 template<typename TSeq>
+
14739 inline void Agent<TSeq>::mutate_virus()
+
14740 {
+
14741 
+
14742  virus->mutate();
+
14743 
+
14744 }
+
14745 
+
14746 template<typename TSeq>
+
14747 inline void Agent<TSeq>::add_neighbor(
+
14748  Agent<TSeq> & p,
+
14749  bool check_source,
+
14750  bool check_target
+
14751 ) {
+
14752  // Can we find the neighbor?
+
14753  bool found = false;
+
14754  if (check_source)
+
14755  {
+
14756 
+
14757  for (auto & n: neighbors)
+
14758  if (static_cast<int>(n) == p.get_id())
+
14759  {
+
14760  found = true;
+
14761  break;
+
14762  }
+
14763 
+
14764  }
14765 
-
14766  p.neighbors_locations.push_back(n_neighbors - 1);
-
14767  p.neighbors.push_back(id);
-
14768  p.n_neighbors++;
-
14769 
-
14770  }
-
14771 
+
14766  // Three things going on here:
+
14767  // - Where in the neighbor will this be
+
14768  // - What is the neighbor's id
+
14769  // - Increasing the number of neighbors
+
14770  if (!found)
+
14771  {
14772 
-
14773 }
-
14774 
-
14775 template<typename TSeq>
- -
14777  Agent<TSeq> & other,
-
14778  size_t n_this,
-
14779  size_t n_other
-
14780 )
-
14781 {
-
14782 
-
14783  // Getting the agents
-
14784  auto & pop = model->population;
-
14785  auto & neigh_this = pop[neighbors[n_this]];
-
14786  auto & neigh_other = pop[other.neighbors[n_other]];
-
14787 
-
14788  // Getting the locations in the neighbors
-
14789  size_t loc_this_in_neigh = neighbors_locations[n_this];
-
14790  size_t loc_other_in_neigh = other.neighbors_locations[n_other];
-
14791 
-
14792  // Changing ids
-
14793  std::swap(neighbors[n_this], other.neighbors[n_other]);
-
14794 
-
14795  if (!model->directed)
-
14796  {
-
14797  std::swap(
-
14798  neigh_this.neighbors[loc_this_in_neigh],
-
14799  neigh_other.neighbors[loc_other_in_neigh]
-
14800  );
-
14801 
-
14802  // Changing the locations
-
14803  std::swap(neighbors_locations[n_this], other.neighbors_locations[n_other]);
-
14804 
-
14805  std::swap(
-
14806  neigh_this.neighbors_locations[loc_this_in_neigh],
-
14807  neigh_other.neighbors_locations[loc_other_in_neigh]
-
14808  );
-
14809  }
-
14810 
-
14811 }
+
14773  neighbors_locations.push_back(p.get_n_neighbors());
+
14774  neighbors.push_back(p.get_id());
+
14775  n_neighbors++;
+
14776 
+
14777  }
+
14778 
+
14779 
+
14780  found = false;
+
14781  if (check_target)
+
14782  {
+
14783 
+
14784  for (auto & n: p.neighbors)
+
14785  if (static_cast<int>(n) == id)
+
14786  {
+
14787  found = true;
+
14788  break;
+
14789  }
+
14790 
+
14791  }
+
14792 
+
14793  if (!found)
+
14794  {
+
14795 
+
14796  p.neighbors_locations.push_back(n_neighbors - 1);
+
14797  p.neighbors.push_back(id);
+
14798  p.n_neighbors++;
+
14799 
+
14800  }
+
14801 
+
14802 
+
14803 }
+
14804 
+
14805 template<typename TSeq>
+ +
14807  Agent<TSeq> & other,
+
14808  size_t n_this,
+
14809  size_t n_other
+
14810 )
+
14811 {
14812 
-
14813 template<typename TSeq>
-
14814 inline std::vector< Agent<TSeq> *> Agent<TSeq>::get_neighbors()
-
14815 {
-
14816  std::vector< Agent<TSeq> * > res(n_neighbors, nullptr);
-
14817  for (size_t i = 0u; i < n_neighbors; ++i)
-
14818  res[i] = &model->population[neighbors[i]];
-
14819 
-
14820  return res;
-
14821 }
-
14822 
-
14823 template<typename TSeq>
-
14824 inline size_t Agent<TSeq>::get_n_neighbors() const
-
14825 {
-
14826  return n_neighbors;
-
14827 }
-
14828 
-
14829 template<typename TSeq>
-
14830 inline void Agent<TSeq>::change_state(
-
14831  Model<TSeq> * model,
-
14832  epiworld_fast_uint new_state,
-
14833  epiworld_fast_int queue
-
14834  )
-
14835 {
-
14836 
-
14837  model->events_add(
-
14838  this, nullptr, nullptr, nullptr, new_state, queue,
-
14839  default_change_state<TSeq>, -1, -1
-
14840  );
-
14841 
-
14842  return;
-
14843 
-
14844 }
-
14845 
-
14846 template<typename TSeq>
-
14847 inline const epiworld_fast_uint & Agent<TSeq>::get_state() const {
-
14848  return state;
-
14849 }
-
14850 
-
14851 template<typename TSeq>
-
14852 inline void Agent<TSeq>::reset()
-
14853 {
-
14854 
-
14855  this->virus = nullptr;
-
14856 
-
14857  this->tools.clear();
-
14858  n_tools = 0u;
-
14859 
-
14860  this->entities.clear();
-
14861  this->entities_locations.clear();
-
14862  this->n_entities = 0u;
-
14863 
-
14864  this->state = 0u;
-
14865  this->state_prev = 0u;
+
14813  // Getting the agents
+
14814  auto & pop = model->population;
+
14815  auto & neigh_this = pop[neighbors[n_this]];
+
14816  auto & neigh_other = pop[other.neighbors[n_other]];
+
14817 
+
14818  // Getting the locations in the neighbors
+
14819  size_t loc_this_in_neigh = neighbors_locations[n_this];
+
14820  size_t loc_other_in_neigh = other.neighbors_locations[n_other];
+
14821 
+
14822  // Changing ids
+
14823  std::swap(neighbors[n_this], other.neighbors[n_other]);
+
14824 
+
14825  if (!model->directed)
+
14826  {
+
14827  std::swap(
+
14828  neigh_this.neighbors[loc_this_in_neigh],
+
14829  neigh_other.neighbors[loc_other_in_neigh]
+
14830  );
+
14831 
+
14832  // Changing the locations
+
14833  std::swap(neighbors_locations[n_this], other.neighbors_locations[n_other]);
+
14834 
+
14835  std::swap(
+
14836  neigh_this.neighbors_locations[loc_this_in_neigh],
+
14837  neigh_other.neighbors_locations[loc_other_in_neigh]
+
14838  );
+
14839  }
+
14840 
+
14841 }
+
14842 
+
14843 template<typename TSeq>
+
14844 inline std::vector< Agent<TSeq> *> Agent<TSeq>::get_neighbors()
+
14845 {
+
14846  std::vector< Agent<TSeq> * > res(n_neighbors, nullptr);
+
14847  for (size_t i = 0u; i < n_neighbors; ++i)
+
14848  res[i] = &model->population[neighbors[i]];
+
14849 
+
14850  return res;
+
14851 }
+
14852 
+
14853 template<typename TSeq>
+
14854 inline size_t Agent<TSeq>::get_n_neighbors() const
+
14855 {
+
14856  return n_neighbors;
+
14857 }
+
14858 
+
14859 template<typename TSeq>
+
14860 inline void Agent<TSeq>::change_state(
+
14861  Model<TSeq> * model,
+
14862  epiworld_fast_uint new_state,
+
14863  epiworld_fast_int queue
+
14864  )
+
14865 {
14866 
-
14867  this->state_last_changed = -1;
-
14868 
-
14869 }
-
14870 
-
14871 template<typename TSeq>
-
14872 inline bool Agent<TSeq>::has_tool(epiworld_fast_uint t) const
-
14873 {
-
14874 
-
14875  for (auto & tool : tools)
-
14876  if (tool->get_id() == static_cast<int>(t))
-
14877  return true;
-
14878 
-
14879  return false;
+
14867  model->events_add(
+
14868  this, nullptr, nullptr, nullptr, new_state, queue,
+
14869  default_change_state<TSeq>, -1, -1
+
14870  );
+
14871 
+
14872  return;
+
14873 
+
14874 }
+
14875 
+
14876 template<typename TSeq>
+
14877 inline const epiworld_fast_uint & Agent<TSeq>::get_state() const {
+
14878  return state;
+
14879 }
14880 
-
14881 }
-
14882 
-
14883 template<typename TSeq>
-
14884 inline bool Agent<TSeq>::has_tool(std::string name) const
-
14885 {
+
14881 template<typename TSeq>
+
14882 inline void Agent<TSeq>::reset()
+
14883 {
+
14884 
+
14885  this->virus = nullptr;
14886 
-
14887  for (auto & tool : tools)
-
14888  if (tool->get_name() == name)
-
14889  return true;
-
14890 
-
14891  return false;
-
14892 
-
14893 }
-
14894 
-
14895 template<typename TSeq>
-
14896 inline bool Agent<TSeq>::has_tool(const Tool<TSeq> & tool) const
-
14897 {
-
14898 
-
14899  return has_tool(tool.get_id());
+
14887  this->tools.clear();
+
14888  n_tools = 0u;
+
14889 
+
14890  this->entities.clear();
+
14891  this->entities_locations.clear();
+
14892  this->n_entities = 0u;
+
14893 
+
14894  this->state = 0u;
+
14895  this->state_prev = 0u;
+
14896 
+
14897  this->state_last_changed = -1;
+
14898 
+
14899 }
14900 
-
14901 }
-
14902 
-
14903 template<typename TSeq>
-
14904 inline bool Agent<TSeq>::has_virus(epiworld_fast_uint t) const
-
14905 {
-
14906  if (virus->get_id() == static_cast<int>(t))
-
14907  return true;
+
14901 template<typename TSeq>
+
14902 inline bool Agent<TSeq>::has_tool(epiworld_fast_uint t) const
+
14903 {
+
14904 
+
14905  for (auto & tool : tools)
+
14906  if (tool->get_id() == static_cast<int>(t))
+
14907  return true;
14908 
14909  return false;
-
14910 }
-
14911 
-
14912 template<typename TSeq>
-
14913 inline bool Agent<TSeq>::has_virus(std::string name) const
-
14914 {
-
14915 
-
14916  if (virus->get_name() == name)
-
14917  return true;
-
14918 
-
14919  return false;
+
14910 
+
14911 }
+
14912 
+
14913 template<typename TSeq>
+
14914 inline bool Agent<TSeq>::has_tool(std::string name) const
+
14915 {
+
14916 
+
14917  for (auto & tool : tools)
+
14918  if (tool->get_name() == name)
+
14919  return true;
14920 
-
14921 }
+
14921  return false;
14922 
-
14923 template<typename TSeq>
-
14924 inline bool Agent<TSeq>::has_virus(const Virus<TSeq> & virus) const
-
14925 {
-
14926 
-
14927  return has_virus(virus.get_id());
+
14923 }
+
14924 
+
14925 template<typename TSeq>
+
14926 inline bool Agent<TSeq>::has_tool(const Tool<TSeq> & tool) const
+
14927 {
14928 
-
14929 }
+
14929  return has_tool(tool.get_id());
14930 
-
14931 template<typename TSeq>
-
14932 inline bool Agent<TSeq>::has_entity(epiworld_fast_uint t) const
-
14933 {
-
14934 
-
14935  for (auto & entity : entities)
-
14936  if (entity == t)
-
14937  return true;
+
14931 }
+
14932 
+
14933 template<typename TSeq>
+
14934 inline bool Agent<TSeq>::has_virus(epiworld_fast_uint t) const
+
14935 {
+
14936  if (virus->get_id() == static_cast<int>(t))
+
14937  return true;
14938 
14939  return false;
-
14940 
-
14941 }
-
14942 
-
14943 template<typename TSeq>
-
14944 inline bool Agent<TSeq>::has_entity(std::string name) const
-
14945 {
-
14946 
-
14947  for (auto & entity : entities)
-
14948  if (model->get_entity(entity).get_name() == name)
-
14949  return true;
+
14940 }
+
14941 
+
14942 template<typename TSeq>
+
14943 inline bool Agent<TSeq>::has_virus(std::string name) const
+
14944 {
+
14945 
+
14946  if (virus->get_name() == name)
+
14947  return true;
+
14948 
+
14949  return false;
14950 
-
14951  return false;
+
14951 }
14952 
-
14953 }
-
14954 
-
14955 template<typename TSeq>
-
14956 inline void Agent<TSeq>::print(
-
14957  Model<TSeq> * model,
-
14958  bool compressed
-
14959  ) const
-
14960 {
-
14961 
-
14962  if (compressed)
-
14963  {
-
14964  printf_epiworld(
-
14965  "Agent: %i, state: %s (%i), Has virus: %s, NTools: %ii NNeigh: %i\n",
-
14966  static_cast<int>(id),
-
14967  model->states_labels[state].c_str(),
-
14968  static_cast<int>(state),
-
14969  virus == nullptr ? std::string("no").c_str() : std::string("yes").c_str(),
-
14970  static_cast<int>(n_tools),
-
14971  static_cast<int>(neighbors.size())
-
14972  );
-
14973  }
-
14974  else {
-
14975 
-
14976  printf_epiworld("Information about agent id %i\n",
-
14977  static_cast<int>(this->id));
-
14978  printf_epiworld(" State : %s (%i)\n",
-
14979  model->states_labels[state].c_str(), static_cast<int>(state));
-
14980  printf_epiworld(" Has virus : %s\n", virus == nullptr ?
-
14981  std::string("no").c_str() : std::string("yes").c_str());
-
14982  printf_epiworld(" Tool count : %i\n", static_cast<int>(n_tools));
-
14983  printf_epiworld(" Neigh. count : %i\n", static_cast<int>(neighbors.size()));
+
14953 template<typename TSeq>
+
14954 inline bool Agent<TSeq>::has_virus(const Virus<TSeq> & virus) const
+
14955 {
+
14956 
+
14957  return has_virus(virus.get_id());
+
14958 
+
14959 }
+
14960 
+
14961 template<typename TSeq>
+
14962 inline bool Agent<TSeq>::has_entity(epiworld_fast_uint t) const
+
14963 {
+
14964 
+
14965  for (auto & entity : entities)
+
14966  if (entity == t)
+
14967  return true;
+
14968 
+
14969  return false;
+
14970 
+
14971 }
+
14972 
+
14973 template<typename TSeq>
+
14974 inline bool Agent<TSeq>::has_entity(std::string name) const
+
14975 {
+
14976 
+
14977  for (auto & entity : entities)
+
14978  if (model->get_entity(entity).get_name() == name)
+
14979  return true;
+
14980 
+
14981  return false;
+
14982 
+
14983 }
14984 
-
14985  size_t nfeats = model->get_agents_data_ncols();
-
14986  if (nfeats > 0)
-
14987  {
-
14988 
-
14989  printf_epiworld(
-
14990  "This model includes features (%i): [ ",
-
14991  static_cast<int>(nfeats)
-
14992  );
-
14993 
-
14994  int max_to_show = static_cast<int>((nfeats > 10)? 10 : nfeats);
-
14995 
-
14996  for (int k = 0; k < max_to_show; ++k)
-
14997  {
-
14998  printf_epiworld("%.2f", this->operator[](k));
-
14999 
-
15000  if (k != (max_to_show - 1))
-
15001  {
-
15002  printf_epiworld(", ");
-
15003  } else {
-
15004  printf_epiworld(" ]\n");
-
15005  }
-
15006 
-
15007  }
-
15008 
-
15009  }
-
15010 
-
15011  }
-
15012 
-
15013  return;
+
14985 template<typename TSeq>
+
14986 inline void Agent<TSeq>::print(
+
14987  Model<TSeq> * model,
+
14988  bool compressed
+
14989  ) const
+
14990 {
+
14991 
+
14992  if (compressed)
+
14993  {
+
14994  printf_epiworld(
+
14995  "Agent: %i, state: %s (%i), Has virus: %s, NTools: %ii NNeigh: %i\n",
+
14996  static_cast<int>(id),
+
14997  model->states_labels[state].c_str(),
+
14998  static_cast<int>(state),
+
14999  virus == nullptr ? std::string("no").c_str() : std::string("yes").c_str(),
+
15000  static_cast<int>(n_tools),
+
15001  static_cast<int>(neighbors.size())
+
15002  );
+
15003  }
+
15004  else {
+
15005 
+
15006  printf_epiworld("Information about agent id %i\n",
+
15007  static_cast<int>(this->id));
+
15008  printf_epiworld(" State : %s (%i)\n",
+
15009  model->states_labels[state].c_str(), static_cast<int>(state));
+
15010  printf_epiworld(" Has virus : %s\n", virus == nullptr ?
+
15011  std::string("no").c_str() : std::string("yes").c_str());
+
15012  printf_epiworld(" Tool count : %i\n", static_cast<int>(n_tools));
+
15013  printf_epiworld(" Neigh. count : %i\n", static_cast<int>(neighbors.size()));
15014 
-
15015 }
-
15016 
-
15017 template<typename TSeq>
-
15018 inline double & Agent<TSeq>::operator()(size_t j)
-
15019 {
-
15020 
-
15021  if (model->agents_data_ncols <= j)
-
15022  throw std::logic_error("The requested feature of the agent is out of range.");
+
15015  size_t nfeats = model->get_agents_data_ncols();
+
15016  if (nfeats > 0)
+
15017  {
+
15018 
+
15019  printf_epiworld(
+
15020  "This model includes features (%i): [ ",
+
15021  static_cast<int>(nfeats)
+
15022  );
15023 
-
15024  return *(model->agents_data + j * model->size() + id);
+
15024  int max_to_show = static_cast<int>((nfeats > 10)? 10 : nfeats);
15025 
-
15026 }
-
15027 
-
15028 template<typename TSeq>
-
15029 inline double & Agent<TSeq>::operator[](size_t j)
-
15030 {
-
15031  return *(model->agents_data + j * model->size() + id);
-
15032 }
-
15033 
-
15034 template<typename TSeq>
-
15035 inline double Agent<TSeq>::operator()(size_t j) const
-
15036 {
-
15037 
-
15038  if (model->agents_data_ncols <= j)
-
15039  throw std::logic_error("The requested feature of the agent is out of range.");
+
15026  for (int k = 0; k < max_to_show; ++k)
+
15027  {
+
15028  printf_epiworld("%.2f", this->operator[](k));
+
15029 
+
15030  if (k != (max_to_show - 1))
+
15031  {
+
15032  printf_epiworld(", ");
+
15033  } else {
+
15034  printf_epiworld(" ]\n");
+
15035  }
+
15036 
+
15037  }
+
15038 
+
15039  }
15040 
-
15041  return *(model->agents_data + j * model->size() + id);
+
15041  }
15042 
-
15043 }
+
15043  return;
15044 
-
15045 template<typename TSeq>
-
15046 inline double Agent<TSeq>::operator[](size_t j) const
-
15047 {
-
15048  return *(model->agents_data + j * model->size() + id);
-
15049 }
+
15045 }
+
15046 
+
15047 template<typename TSeq>
+
15048 inline double & Agent<TSeq>::operator()(size_t j)
+
15049 {
15050 
-
15051 template<typename TSeq>
- -
15053 {
-
15054  return Entities<TSeq>(*this);
-
15055 }
-
15056 
-
15057 template<typename TSeq>
- -
15059 {
-
15060  return Entities_const<TSeq>(*this);
-
15061 }
-
15062 
-
15063 template<typename TSeq>
-
15064 inline const Entity<TSeq> & Agent<TSeq>::get_entity(size_t i) const
-
15065 {
-
15066  if (n_entities == 0)
-
15067  throw std::range_error("Agent id " + std::to_string(id) + " has no entities.");
-
15068 
-
15069  if (i >= n_entities)
-
15070  throw std::range_error("Trying to get to an agent's entity outside of the range.");
-
15071 
-
15072  return model->get_entity(entities[i]);
+
15051  if (model->agents_data_ncols <= j)
+
15052  throw std::logic_error("The requested feature of the agent is out of range.");
+
15053 
+
15054  return *(model->agents_data + j * model->size() + id);
+
15055 
+
15056 }
+
15057 
+
15058 template<typename TSeq>
+
15059 inline double & Agent<TSeq>::operator[](size_t j)
+
15060 {
+
15061  return *(model->agents_data + j * model->size() + id);
+
15062 }
+
15063 
+
15064 template<typename TSeq>
+
15065 inline double Agent<TSeq>::operator()(size_t j) const
+
15066 {
+
15067 
+
15068  if (model->agents_data_ncols <= j)
+
15069  throw std::logic_error("The requested feature of the agent is out of range.");
+
15070 
+
15071  return *(model->agents_data + j * model->size() + id);
+
15072 
15073 }
15074 
15075 template<typename TSeq>
-
15076 inline Entity<TSeq> & Agent<TSeq>::get_entity(size_t i)
-
15077 {
-
15078  if (n_entities == 0)
-
15079  throw std::range_error("Agent id " + std::to_string(id) + " has no entities.");
+
15076 inline double Agent<TSeq>::operator[](size_t j) const
+
15077 {
+
15078  return *(model->agents_data + j * model->size() + id);
+
15079 }
15080 
-
15081  if (i >= n_entities)
-
15082  throw std::range_error("Trying to get to an agent's entity outside of the range.");
-
15083 
-
15084  return model->get_entity(entities[i]);
+
15081 template<typename TSeq>
+ +
15083 {
+
15084  return Entities<TSeq>(*this);
15085 }
15086 
15087 template<typename TSeq>
-
15088 inline size_t Agent<TSeq>::get_n_entities() const
+
15089 {
-
15090  return n_entities;
+
15090  return Entities_const<TSeq>(*this);
15091 }
15092 
15093 template<typename TSeq>
-
15094 inline bool Agent<TSeq>::operator==(const Agent<TSeq> & other) const
+
15094 inline const Entity<TSeq> & Agent<TSeq>::get_entity(size_t i) const
15095 {
-
15096 
-
15097  EPI_DEBUG_FAIL_AT_TRUE(
-
15098  n_neighbors != other.n_neighbors,
-
15099  "Agent:: n_eighbors don't match"
-
15100  )
+
15096  if (n_entities == 0)
+
15097  throw std::range_error("Agent id " + std::to_string(id) + " has no entities.");
+
15098 
+
15099  if (i >= n_entities)
+
15100  throw std::range_error("Trying to get to an agent's entity outside of the range.");
15101 
-
15102 
-
15103  for (size_t i = 0u; i < n_neighbors; ++i)
-
15104  {
-
15105  EPI_DEBUG_FAIL_AT_TRUE(
-
15106  neighbors[i] != other.neighbors[i],
-
15107  "Agent:: neighbor[i] don't match"
-
15108  )
-
15109  }
-
15110 
-
15111  EPI_DEBUG_FAIL_AT_TRUE(
-
15112  n_entities != other.n_entities,
-
15113  "Agent:: n_entities don't match"
-
15114  )
-
15115 
-
15116 
-
15117  for (size_t i = 0u; i < n_entities; ++i)
-
15118  {
-
15119  EPI_DEBUG_FAIL_AT_TRUE(
-
15120  entities[i] != other.entities[i],
-
15121  "Agent:: entities[i] don't match"
-
15122  )
-
15123  }
-
15124 
-
15125  EPI_DEBUG_FAIL_AT_TRUE(
-
15126  state != other.state,
-
15127  "Agent:: state don't match"
-
15128  )
-
15129 
-
15130 
-
15131  EPI_DEBUG_FAIL_AT_TRUE(
-
15132  state_prev != other.state_prev,
-
15133  "Agent:: state_prev don't match"
-
15134  )
-
15135 
-
15136 
-
15137  // EPI_DEBUG_FAIL_AT_TRUE(
-
15138  // state_last_changed != other.state_last_changed,
-
15139  // "Agent:: state_last_changed don't match"
-
15140  // ) ///< Last time the agent was updated.
-
15141 
-
15142  EPI_DEBUG_FAIL_AT_TRUE(
-
15143  ((virus == nullptr) && (other.virus != nullptr)) ||
-
15144  ((virus != nullptr) && (other.virus == nullptr)),
-
15145  "Agent:: virus don't match"
-
15146  )
-
15147 
-
15148  if ((virus != nullptr) && (other.virus != nullptr))
-
15149  {
-
15150  EPI_DEBUG_FAIL_AT_TRUE(
-
15151  *virus != *other.virus,
-
15152  "Agent:: virus doesn't match"
-
15153  )
-
15154  }
-
15155 
-
15156  EPI_DEBUG_FAIL_AT_TRUE(n_tools != other.n_tools, "Agent:: n_tools don't match")
-
15157 
-
15158  for (size_t i = 0u; i < n_tools; ++i)
-
15159  {
-
15160 
-
15161  EPI_DEBUG_FAIL_AT_TRUE(
-
15162  tools[i] != other.tools[i],
-
15163  "Agent:: tools[i] don't match"
+
15102  return model->get_entity(entities[i]);
+
15103 }
+
15104 
+
15105 template<typename TSeq>
+
15106 inline Entity<TSeq> & Agent<TSeq>::get_entity(size_t i)
+
15107 {
+
15108  if (n_entities == 0)
+
15109  throw std::range_error("Agent id " + std::to_string(id) + " has no entities.");
+
15110 
+
15111  if (i >= n_entities)
+
15112  throw std::range_error("Trying to get to an agent's entity outside of the range.");
+
15113 
+
15114  return model->get_entity(entities[i]);
+
15115 }
+
15116 
+
15117 template<typename TSeq>
+
15118 inline size_t Agent<TSeq>::get_n_entities() const
+
15119 {
+
15120  return n_entities;
+
15121 }
+
15122 
+
15123 template<typename TSeq>
+
15124 inline bool Agent<TSeq>::operator==(const Agent<TSeq> & other) const
+
15125 {
+
15126 
+
15127  EPI_DEBUG_FAIL_AT_TRUE(
+
15128  n_neighbors != other.n_neighbors,
+
15129  "Agent:: n_eighbors don't match"
+
15130  )
+
15131 
+
15132 
+
15133  for (size_t i = 0u; i < n_neighbors; ++i)
+
15134  {
+
15135  EPI_DEBUG_FAIL_AT_TRUE(
+
15136  neighbors[i] != other.neighbors[i],
+
15137  "Agent:: neighbor[i] don't match"
+
15138  )
+
15139  }
+
15140 
+
15141  EPI_DEBUG_FAIL_AT_TRUE(
+
15142  n_entities != other.n_entities,
+
15143  "Agent:: n_entities don't match"
+
15144  )
+
15145 
+
15146 
+
15147  for (size_t i = 0u; i < n_entities; ++i)
+
15148  {
+
15149  EPI_DEBUG_FAIL_AT_TRUE(
+
15150  entities[i] != other.entities[i],
+
15151  "Agent:: entities[i] don't match"
+
15152  )
+
15153  }
+
15154 
+
15155  EPI_DEBUG_FAIL_AT_TRUE(
+
15156  state != other.state,
+
15157  "Agent:: state don't match"
+
15158  )
+
15159 
+
15160 
+
15161  EPI_DEBUG_FAIL_AT_TRUE(
+
15162  state_prev != other.state_prev,
+
15163  "Agent:: state_prev don't match"
15164  )
-
15165 
-
15166  }
-
15167 
-
15168  return true;
-
15169 
-
15170 }
+
15165 
+
15166 
+
15167  // EPI_DEBUG_FAIL_AT_TRUE(
+
15168  // state_last_changed != other.state_last_changed,
+
15169  // "Agent:: state_last_changed don't match"
+
15170  // ) ///< Last time the agent was updated.
15171 
-
15172 #undef CHECK_COALESCE_
-
15173 
-
15174 #endif
-
15175 /*//////////////////////////////////////////////////////////////////////////////
-
15177 
-
15178  End of -include/epiworld/agent-meat.hpp-
-
15179 
-
15182 
-
15183 
-
15184 
-
15185 /*//////////////////////////////////////////////////////////////////////////////
-
15187 
-
15188  Start of -include/epiworld/agentssample-bones.hpp-
-
15189 
-
15192 
-
15193 
-
15194 #ifndef EPIWORLD_AGENTS_BONES_HPP
-
15195 #define EPIWORLD_AGENTS_BONES_HPP
-
15196 
-
15197 class SAMPLETYPE {
-
15198 public:
-
15199  static const int MODEL = 0;
-
15200  static const int ENTITY = 1;
-
15201  static const int AGENT = 2;
-
15202 };
-
15203 
-
15204 // template<typename TSeq>
-
15205 // class Agent;
-
15206 
-
15207 // template<typename TSeq>
-
15208 // class Model;
+
15172  EPI_DEBUG_FAIL_AT_TRUE(
+
15173  ((virus == nullptr) && (other.virus != nullptr)) ||
+
15174  ((virus != nullptr) && (other.virus == nullptr)),
+
15175  "Agent:: virus don't match"
+
15176  )
+
15177 
+
15178  if ((virus != nullptr) && (other.virus != nullptr))
+
15179  {
+
15180  EPI_DEBUG_FAIL_AT_TRUE(
+
15181  *virus != *other.virus,
+
15182  "Agent:: virus doesn't match"
+
15183  )
+
15184  }
+
15185 
+
15186  EPI_DEBUG_FAIL_AT_TRUE(n_tools != other.n_tools, "Agent:: n_tools don't match")
+
15187 
+
15188  for (size_t i = 0u; i < n_tools; ++i)
+
15189  {
+
15190 
+
15191  EPI_DEBUG_FAIL_AT_TRUE(
+
15192  tools[i] != other.tools[i],
+
15193  "Agent:: tools[i] don't match"
+
15194  )
+
15195 
+
15196  }
+
15197 
+
15198  return true;
+
15199 
+
15200 }
+
15201 
+
15202 #undef CHECK_COALESCE_
+
15203 
+
15204 #endif
+
15205 /*//////////////////////////////////////////////////////////////////////////////
+
15207 
+
15208  End of -include/epiworld/agent-meat.hpp-
15209 
-
15210 // template<typename TSeq>
-
15211 // class Entity;
15212 
-
15220 template<typename TSeq>
-
15221 class AgentsSample {
-
15222 private:
+
15213 
+
15214 
+
15215 /*//////////////////////////////////////////////////////////////////////////////
+
15217 
+
15218  Start of -include/epiworld/agentssample-bones.hpp-
+
15219 
+
15222 
15223 
-
15224  size_t sample_size = 0u;
-
15225 
-
15226  std::vector< Agent<TSeq>* >* agents = nullptr; ///< Pointer to sample of agents
-
15227  size_t * agents_n = nullptr; ///< Size of sample of agents
-
15228 
-
15229  std::vector< size_t >* agents_left = nullptr; ///< Pointer to agents left (iota)
-
15230  size_t * agents_left_n = nullptr; ///< Size of agents left
-
15231 
-
15232  Model<TSeq> * model = nullptr; ///< Extracts runif() and (if the case) population.
-
15233  Entity<TSeq> * entity = nullptr; ///
-
15234  Agent<TSeq> * agent = nullptr;
-
15235 
-
15236  int sample_type = SAMPLETYPE::AGENT;
-
15237  std::vector< size_t > states = {};
-
15238 
-
15239  void sample_n(size_t n); ///< Backbone function for sampling
-
15240 
-
15241 
-
15242 public:
-
15243 
-
15244  // Not available (for now)
-
15245  AgentsSample() = delete; ///< Default constructor
-
15246  AgentsSample(const AgentsSample<TSeq> & a) = delete; ///< Copy constructor
-
15247  AgentsSample(AgentsSample<TSeq> && a) = delete; ///< Move constructor
-
15248 
-
15249  AgentsSample(
-
15250  Model<TSeq> & model_, size_t n,
-
15251  std::vector< size_t > states_ = {},
-
15252  bool truncate = false
-
15253  );
-
15254 
-
15255  AgentsSample(
-
15256  Model<TSeq> * model,
-
15257  Entity<TSeq> & entity_,
-
15258  size_t n,
-
15259  std::vector< size_t > states_ = {},
-
15260  bool truncate = false
-
15261  );
-
15262 
-
15263  AgentsSample(
-
15264  Model<TSeq> * model,
-
15265  Agent<TSeq> & agent_,
-
15266  size_t n,
-
15267  std::vector< size_t > states_ = {},
-
15268  bool truncate = false
-
15269  );
+
15224 #ifndef EPIWORLD_AGENTS_BONES_HPP
+
15225 #define EPIWORLD_AGENTS_BONES_HPP
+
15226 
+
15227 class SAMPLETYPE {
+
15228 public:
+
15229  static const int MODEL = 0;
+
15230  static const int ENTITY = 1;
+
15231  static const int AGENT = 2;
+
15232 };
+
15233 
+
15234 // template<typename TSeq>
+
15235 // class Agent;
+
15236 
+
15237 // template<typename TSeq>
+
15238 // class Model;
+
15239 
+
15240 // template<typename TSeq>
+
15241 // class Entity;
+
15242 
+
15250 template<typename TSeq>
+
15251 class AgentsSample {
+
15252 private:
+
15253 
+
15254  size_t sample_size = 0u;
+
15255 
+
15256  std::vector< Agent<TSeq>* >* agents = nullptr; ///< Pointer to sample of agents
+
15257  size_t * agents_n = nullptr; ///< Size of sample of agents
+
15258 
+
15259  std::vector< size_t >* agents_left = nullptr; ///< Pointer to agents left (iota)
+
15260  size_t * agents_left_n = nullptr; ///< Size of agents left
+
15261 
+
15262  Model<TSeq> * model = nullptr; ///< Extracts runif() and (if the case) population.
+
15263  Entity<TSeq> * entity = nullptr; ///
+
15264  Agent<TSeq> * agent = nullptr;
+
15265 
+
15266  int sample_type = SAMPLETYPE::AGENT;
+
15267  std::vector< size_t > states = {};
+
15268 
+
15269  void sample_n(size_t n); ///< Backbone function for sampling
15270 
-
15271  ~AgentsSample();
-
15272 
-
15273  typename std::vector< Agent<TSeq> * >::iterator begin();
-
15274  typename std::vector< Agent<TSeq> * >::iterator end();
-
15275 
-
15276  Agent<TSeq> * operator[](size_t n);
-
15277  Agent<TSeq> * operator()(size_t n);
-
15278  size_t size() const noexcept;
-
15279 
-
15280 };
-
15281 
-
15282 template<typename TSeq>
-
15283 inline AgentsSample<TSeq>::AgentsSample(
-
15284  Model<TSeq> & model_,
-
15285  size_t n,
-
15286  std::vector< size_t > states_,
-
15287  bool truncate
-
15288  ) {
-
15289 
-
15290  states = states_;
-
15291 
-
15292  if (truncate)
-
15293  {
-
15294 
-
15295  if (n > model_.size())
-
15296  n = model_.size();
-
15297 
-
15298  } else if (n > model_.size())
-
15299  throw std::logic_error(
-
15300  "There are only " + std::to_string(model_.size()) + " agents. You cannot " +
-
15301  "sample " + std::to_string(n));
+
15271 
+
15272 public:
+
15273 
+
15274  // Not available (for now)
+
15275  AgentsSample() = delete; ///< Default constructor
+
15276  AgentsSample(const AgentsSample<TSeq> & a) = delete; ///< Copy constructor
+
15277  AgentsSample(AgentsSample<TSeq> && a) = delete; ///< Move constructor
+
15278 
+
15279  AgentsSample(
+
15280  Model<TSeq> & model_, size_t n,
+
15281  std::vector< size_t > states_ = {},
+
15282  bool truncate = false
+
15283  );
+
15284 
+
15285  AgentsSample(
+
15286  Model<TSeq> * model,
+
15287  Entity<TSeq> & entity_,
+
15288  size_t n,
+
15289  std::vector< size_t > states_ = {},
+
15290  bool truncate = false
+
15291  );
+
15292 
+
15293  AgentsSample(
+
15294  Model<TSeq> * model,
+
15295  Agent<TSeq> & agent_,
+
15296  size_t n,
+
15297  std::vector< size_t > states_ = {},
+
15298  bool truncate = false
+
15299  );
+
15300 
+
15301  ~AgentsSample();
15302 
-
15303  sample_size = n;
-
15304  model = &model_;
-
15305  sample_type = SAMPLETYPE::MODEL;
-
15306 
-
15307  agents = &model_.sampled_population;
-
15308  agents_n = &model_.sampled_population_n;
+
15303  typename std::vector< Agent<TSeq> * >::iterator begin();
+
15304  typename std::vector< Agent<TSeq> * >::iterator end();
+
15305 
+
15306  Agent<TSeq> * operator[](size_t n);
+
15307  Agent<TSeq> * operator()(size_t n);
+
15308  size_t size() const noexcept;
15309 
-
15310  agents_left = &model_.population_left;
-
15311  agents_left_n = &model_.population_left_n;
-
15312 
-
15313  sample_n(n);
-
15314 
-
15315  return;
-
15316 
-
15317 }
-
15318 
-
15319 template<typename TSeq>
-
15320 inline AgentsSample<TSeq>::AgentsSample(
-
15321  Model<TSeq> * model,
-
15322  Entity<TSeq> & entity_,
-
15323  size_t n,
-
15324  std::vector< size_t > states_,
-
15325  bool truncate
-
15326  ) {
+
15310 };
+
15311 
+
15312 template<typename TSeq>
+
15313 inline AgentsSample<TSeq>::AgentsSample(
+
15314  Model<TSeq> & model_,
+
15315  size_t n,
+
15316  std::vector< size_t > states_,
+
15317  bool truncate
+
15318  ) {
+
15319 
+
15320  states = states_;
+
15321 
+
15322  if (truncate)
+
15323  {
+
15324 
+
15325  if (n > model_.size())
+
15326  n = model_.size();
15327 
-
15328  states = states_;
-
15329 
-
15330  if (truncate)
-
15331  {
+
15328  } else if (n > model_.size())
+
15329  throw std::logic_error(
+
15330  "There are only " + std::to_string(model_.size()) + " agents. You cannot " +
+
15331  "sample " + std::to_string(n));
15332 
-
15333  if (n > entity_.size())
-
15334  n = entity_.size();
-
15335 
-
15336  } else if (n > entity_.size())
-
15337  throw std::logic_error(
-
15338  "There are only " + std::to_string(entity_.size()) + " agents. You cannot " +
-
15339  "sample " + std::to_string(n));
-
15340 
-
15341  sample_size = n;
-
15342  model = &entity_.model;
-
15343  sample_type = SAMPLETYPE::ENTITY;
-
15344 
-
15345  agents = &entity_.sampled_agents;
-
15346  agents_n = &entity_.sampled_agents_n;
-
15347 
-
15348  agents_left = &entity_.sampled_agents_left;
-
15349  agents_left_n = &entity_.sampled_agents_left_n;
-
15350 
-
15351  sample_n(n);
-
15352 
-
15353  return;
-
15354 
-
15355 }
-
15356 
-
15369 template<typename TSeq>
-
15370 inline AgentsSample<TSeq>::AgentsSample(
-
15371  Model<TSeq> * model,
-
15372  Agent<TSeq> & agent_,
-
15373  size_t n,
-
15374  std::vector< size_t > states_,
-
15375  bool truncate
-
15376  )
-
15377 {
-
15378 
-
15379  states = states_;
-
15380  sample_type = SAMPLETYPE::AGENT;
-
15381 
-
15382  agent = &agent_;
-
15383 
-
15384  agents = &agent_.sampled_agents;
-
15385  agents_n = &agent_.sampled_agents_n;
+
15333  sample_size = n;
+
15334  model = &model_;
+
15335  sample_type = SAMPLETYPE::MODEL;
+
15336 
+
15337  agents = &model_.sampled_population;
+
15338  agents_n = &model_.sampled_population_n;
+
15339 
+
15340  agents_left = &model_.population_left;
+
15341  agents_left_n = &model_.population_left_n;
+
15342 
+
15343  sample_n(n);
+
15344 
+
15345  return;
+
15346 
+
15347 }
+
15348 
+
15349 template<typename TSeq>
+
15350 inline AgentsSample<TSeq>::AgentsSample(
+
15351  Model<TSeq> * model,
+
15352  Entity<TSeq> & entity_,
+
15353  size_t n,
+
15354  std::vector< size_t > states_,
+
15355  bool truncate
+
15356  ) {
+
15357 
+
15358  states = states_;
+
15359 
+
15360  if (truncate)
+
15361  {
+
15362 
+
15363  if (n > entity_.size())
+
15364  n = entity_.size();
+
15365 
+
15366  } else if (n > entity_.size())
+
15367  throw std::logic_error(
+
15368  "There are only " + std::to_string(entity_.size()) + " agents. You cannot " +
+
15369  "sample " + std::to_string(n));
+
15370 
+
15371  sample_size = n;
+
15372  model = &entity_.model;
+
15373  sample_type = SAMPLETYPE::ENTITY;
+
15374 
+
15375  agents = &entity_.sampled_agents;
+
15376  agents_n = &entity_.sampled_agents_n;
+
15377 
+
15378  agents_left = &entity_.sampled_agents_left;
+
15379  agents_left_n = &entity_.sampled_agents_left_n;
+
15380 
+
15381  sample_n(n);
+
15382 
+
15383  return;
+
15384 
+
15385 }
15386 
-
15387  // Computing the cumulative sum of counts across entities
-
15388  size_t agents_in_entities = 0;
-
15389  Entities<TSeq> entities_a = agent->get_entities();
-
15390 
-
15391  std::vector< size_t > cum_agents_count(entities_a.size(), 0);
-
15392  int idx = -1;
-
15393  for (auto & e : entities_a)
-
15394  {
-
15395  if (++idx == 0)
-
15396  cum_agents_count[idx] = (e->size() - 1u);
-
15397  else
-
15398  cum_agents_count[idx] = (
-
15399  (e->size() - 1u) +
-
15400  cum_agents_count[idx - 1]
-
15401  );
-
15402 
-
15403  agents_in_entities += (e->size() - 1u);
-
15404  }
-
15405 
-
15406  if (truncate)
-
15407  {
-
15408 
-
15409  if (n > agents_in_entities)
-
15410  n = agents_in_entities;
-
15411 
-
15412  } else if (n > agents_in_entities)
-
15413  throw std::logic_error(
-
15414  "There are only " + std::to_string(agents_in_entities) +
-
15415  " agents. You cannot " +
-
15416  "sample " + std::to_string(n)
-
15417  );
-
15418 
-
15419  sample_size = n;
+
15399 template<typename TSeq>
+
15400 inline AgentsSample<TSeq>::AgentsSample(
+
15401  Model<TSeq> * model,
+
15402  Agent<TSeq> & agent_,
+
15403  size_t n,
+
15404  std::vector< size_t > states_,
+
15405  bool truncate
+
15406  )
+
15407 {
+
15408 
+
15409  states = states_;
+
15410  sample_type = SAMPLETYPE::AGENT;
+
15411 
+
15412  agent = &agent_;
+
15413 
+
15414  agents = &agent_.sampled_agents;
+
15415  agents_n = &agent_.sampled_agents_n;
+
15416 
+
15417  // Computing the cumulative sum of counts across entities
+
15418  size_t agents_in_entities = 0;
+
15419  Entities<TSeq> entities_a = agent->get_entities();
15420 
-
15421  if (agents->size() < n)
-
15422  agents->resize(n);
-
15423 
-
15424  size_t i_obs = 0u;
-
15425  for (size_t i = 0u; i < sample_size; ++i)
-
15426  {
-
15427 
-
15428  // Sampling a single agent from the set of entities
-
15429  int jth = std::floor(model->runif() * agents_in_entities);
-
15430  for (size_t e = 0u; e < cum_agents_count.size(); ++e)
-
15431  {
-
15432 
-
15433  // Are we in the limit?
-
15434  if (jth <= cum_agents_count[e])
-
15435  {
-
15436  size_t agent_idx = 0u;
-
15437  if (e == 0) // From the first group
-
15438  agent_idx = entities_a[e][jth]->get_id();
-
15439  else
-
15440  agent_idx = entities_a[e][jth - cum_agents_count[e - 1]]->get_id();
+
15421  std::vector< size_t > cum_agents_count(entities_a.size(), 0);
+
15422  int idx = -1;
+
15423  for (auto & e : entities_a)
+
15424  {
+
15425  if (++idx == 0)
+
15426  cum_agents_count[idx] = (e->size() - 1u);
+
15427  else
+
15428  cum_agents_count[idx] = (
+
15429  (e->size() - 1u) +
+
15430  cum_agents_count[idx - 1]
+
15431  );
+
15432 
+
15433  agents_in_entities += (e->size() - 1u);
+
15434  }
+
15435 
+
15436  if (truncate)
+
15437  {
+
15438 
+
15439  if (n > agents_in_entities)
+
15440  n = agents_in_entities;
15441 
-
15442 
-
15443  // Checking if states was specified
-
15444  if (states.size())
-
15445  {
-
15446 
-
15447  // Getting the state
-
15448  size_t state = model->population[agent_idx].get_state();
-
15449 
-
15450  if (std::find(states.begin(), states.end(), state) != states.end())
-
15451  continue;
-
15452 
-
15453  }
-
15454 
-
15455  agents->operator[](i_obs++) = &(model->population[agent_idx]);
-
15456 
-
15457  break;
-
15458  }
-
15459 
-
15460  }
-
15461  }
-
15462 
-
15463  return;
-
15464 
-
15465 }
-
15466 
-
15467 template<typename TSeq>
-
15468 inline AgentsSample<TSeq>::~AgentsSample() {}
-
15469 
-
15470 template<typename TSeq>
-
15471 inline size_t AgentsSample<TSeq>::size() const noexcept
-
15472 {
-
15473  return this->sample_size;
-
15474 }
-
15475 
-
15476 template<typename TSeq>
-
15477 inline Agent<TSeq> * AgentsSample<TSeq>::operator[](size_t i)
-
15478 {
+
15442  } else if (n > agents_in_entities)
+
15443  throw std::logic_error(
+
15444  "There are only " + std::to_string(agents_in_entities) +
+
15445  " agents. You cannot " +
+
15446  "sample " + std::to_string(n)
+
15447  );
+
15448 
+
15449  sample_size = n;
+
15450 
+
15451  if (agents->size() < n)
+
15452  agents->resize(n);
+
15453 
+
15454  size_t i_obs = 0u;
+
15455  for (size_t i = 0u; i < sample_size; ++i)
+
15456  {
+
15457 
+
15458  // Sampling a single agent from the set of entities
+
15459  int jth = std::floor(model->runif() * agents_in_entities);
+
15460  for (size_t e = 0u; e < cum_agents_count.size(); ++e)
+
15461  {
+
15462 
+
15463  // Are we in the limit?
+
15464  if (jth <= cum_agents_count[e])
+
15465  {
+
15466  size_t agent_idx = 0u;
+
15467  if (e == 0) // From the first group
+
15468  agent_idx = entities_a[e][jth]->get_id();
+
15469  else
+
15470  agent_idx = entities_a[e][jth - cum_agents_count[e - 1]]->get_id();
+
15471 
+
15472 
+
15473  // Checking if states was specified
+
15474  if (states.size())
+
15475  {
+
15476 
+
15477  // Getting the state
+
15478  size_t state = model->population[agent_idx].get_state();
15479 
-
15480  return agents->operator[](i);
-
15481 
-
15482 }
-
15483 
-
15484 template<typename TSeq>
-
15485 inline Agent<TSeq> * AgentsSample<TSeq>::operator()(size_t i)
-
15486 {
-
15487 
-
15488  if (i >= this->sample_size)
-
15489  throw std::range_error("The requested agent is out of range.");
-
15490 
-
15491  return agents->operator[](i);
+
15480  if (std::find(states.begin(), states.end(), state) != states.end())
+
15481  continue;
+
15482 
+
15483  }
+
15484 
+
15485  agents->operator[](i_obs++) = &(model->population[agent_idx]);
+
15486 
+
15487  break;
+
15488  }
+
15489 
+
15490  }
+
15491  }
15492 
-
15493 }
+
15493  return;
15494 
-
15495 template<typename TSeq>
-
15496 inline typename std::vector< Agent<TSeq> * >::iterator AgentsSample<TSeq>::begin()
-
15497 {
-
15498 
-
15499  if (sample_size > 0u)
-
15500  return agents->begin();
-
15501  else
-
15502  return agents->end();
-
15503 
+
15495 }
+
15496 
+
15497 template<typename TSeq>
+
15498 inline AgentsSample<TSeq>::~AgentsSample() {}
+
15499 
+
15500 template<typename TSeq>
+
15501 inline size_t AgentsSample<TSeq>::size() const noexcept
+
15502 {
+
15503  return this->sample_size;
15504 }
15505 
15506 template<typename TSeq>
-
15507 inline typename std::vector< Agent<TSeq> * >::iterator AgentsSample<TSeq>::end()
+
15507 inline Agent<TSeq> * AgentsSample<TSeq>::operator[](size_t i)
15508 {
15509 
-
15510  return agents->begin() + sample_size;
+
15510  return agents->operator[](i);
15511 
15512 }
15513 
15514 template<typename TSeq>
-
15515 inline void AgentsSample<TSeq>::sample_n(size_t n)
+
15515 inline Agent<TSeq> * AgentsSample<TSeq>::operator()(size_t i)
15516 {
15517 
-
15518  // Reducing size
-
15519  if (states.size())
-
15520  {
-
15521 
-
15522  // Getting the number of agents left
-
15523  agents_left->clear();
+
15518  if (i >= this->sample_size)
+
15519  throw std::range_error("The requested agent is out of range.");
+
15520 
+
15521  return agents->operator[](i);
+
15522 
+
15523 }
15524 
-
15525  if (sample_type == SAMPLETYPE::MODEL)
-
15526  {
-
15527 
-
15528  // Making some room
-
15529  agents_left->reserve(model->size());
-
15530 
-
15531  // Iterating through the agents in the population
-
15532  for (size_t a_i = 0u; a_i < model->population.size(); ++a_i)
-
15533  {
-
15534 
-
15535  // If the agent is within the selected set of states,
-
15536  // then we add it to the list of agents left
-
15537  size_t s = model->population[a_i].get_state();
-
15538  if (std::find(states.begin(), states.end(), s) != states.end())
-
15539  agents_left->push_back(a_i);
-
15540 
-
15541  }
-
15542 
-
15543  }
-
15544  else if (sample_type == SAMPLETYPE::ENTITY)
-
15545  {
-
15546 
-
15547  // Making room
-
15548  agents_left->reserve(entity->size());
-
15549 
-
15550  // Iterating through the agents in the entity
-
15551  for (size_t a_i = 0u; a_i < entity->size(); ++a_i)
-
15552  {
-
15553  size_t s = model->population[entity->agents[a_i]].get_state();
-
15554  if (std::find(states.begin(), states.end(), s) != states.end())
-
15555  agents_left->push_back(a_i);
-
15556 
-
15557  }
-
15558 
-
15559  }
+
15525 template<typename TSeq>
+
15526 inline typename std::vector< Agent<TSeq> * >::iterator AgentsSample<TSeq>::begin()
+
15527 {
+
15528 
+
15529  if (sample_size > 0u)
+
15530  return agents->begin();
+
15531  else
+
15532  return agents->end();
+
15533 
+
15534 }
+
15535 
+
15536 template<typename TSeq>
+
15537 inline typename std::vector< Agent<TSeq> * >::iterator AgentsSample<TSeq>::end()
+
15538 {
+
15539 
+
15540  return agents->begin() + sample_size;
+
15541 
+
15542 }
+
15543 
+
15544 template<typename TSeq>
+
15545 inline void AgentsSample<TSeq>::sample_n(size_t n)
+
15546 {
+
15547 
+
15548  // Reducing size
+
15549  if (states.size())
+
15550  {
+
15551 
+
15552  // Getting the number of agents left
+
15553  agents_left->clear();
+
15554 
+
15555  if (sample_type == SAMPLETYPE::MODEL)
+
15556  {
+
15557 
+
15558  // Making some room
+
15559  agents_left->reserve(model->size());
15560 
-
15561  } else {
-
15562 
-
15563  // Checking if the size of the entity has changed (or hasn't been initialized)
-
15564  if (sample_type == SAMPLETYPE::MODEL)
-
15565  {
-
15566 
-
15567  if (model->size() != agents_left->size())
-
15568  {
-
15569  agents_left->resize(model->size(), 0u);
-
15570  std::iota(agents_left->begin(), agents_left->end(), 0u);
+
15561  // Iterating through the agents in the population
+
15562  for (size_t a_i = 0u; a_i < model->population.size(); ++a_i)
+
15563  {
+
15564 
+
15565  // If the agent is within the selected set of states,
+
15566  // then we add it to the list of agents left
+
15567  size_t s = model->population[a_i].get_state();
+
15568  if (std::find(states.begin(), states.end(), s) != states.end())
+
15569  agents_left->push_back(a_i);
+
15570 
15571  }
15572 
-
15573  } else if (sample_type == SAMPLETYPE::ENTITY) {
-
15574 
-
15575  if (entity->size() != agents_left->size())
-
15576  {
-
15577 
-
15578  agents_left->resize(entity->size(), 0u);
-
15579  std::iota(agents_left->begin(), agents_left->end(), 0u);
-
15580 
-
15581  }
-
15582 
-
15583  }
-
15584 
-
15585  }
+
15573  }
+
15574  else if (sample_type == SAMPLETYPE::ENTITY)
+
15575  {
+
15576 
+
15577  // Making room
+
15578  agents_left->reserve(entity->size());
+
15579 
+
15580  // Iterating through the agents in the entity
+
15581  for (size_t a_i = 0u; a_i < entity->size(); ++a_i)
+
15582  {
+
15583  size_t s = model->population[entity->agents[a_i]].get_state();
+
15584  if (std::find(states.begin(), states.end(), s) != states.end())
+
15585  agents_left->push_back(a_i);
15586 
-
15587  // Restart the counter of agents left
-
15588  *agents_left_n = agents_left->size();
-
15589 
-
15590  // Making sure we have enough room for the sample of agents
-
15591  if (agents->size() < sample_size)
-
15592  agents->resize(sample_size, nullptr);
-
15593 
-
15594  if (sample_type == SAMPLETYPE::MODEL)
-
15595  {
+
15587  }
+
15588 
+
15589  }
+
15590 
+
15591  } else {
+
15592 
+
15593  // Checking if the size of the entity has changed (or hasn't been initialized)
+
15594  if (sample_type == SAMPLETYPE::MODEL)
+
15595  {
15596 
-
15597  #ifdef EPI_DEBUG
-
15598  std::vector< bool > __sampled(model->size(), true);
-
15599  for (auto & a_i: *agents_left)
-
15600  __sampled[a_i] = false;
-
15601  #endif
+
15597  if (model->size() != agents_left->size())
+
15598  {
+
15599  agents_left->resize(model->size(), 0u);
+
15600  std::iota(agents_left->begin(), agents_left->end(), 0u);
+
15601  }
15602 
-
15603  for (size_t i = 0u; i < n; ++i)
-
15604  {
-
15605 
-
15606  // Sampling from 0 to (agents_left_n - 1)
-
15607  size_t ith_ = static_cast<size_t>(model->runif() * ((*agents_left_n)--));
-
15608 
-
15609  // Getting the id of the agent and adding it to the list of agents
-
15610  size_t ith = agents_left->operator[](ith_);
-
15611  agents->operator[](i) = &model->population[ith];
+
15603  } else if (sample_type == SAMPLETYPE::ENTITY) {
+
15604 
+
15605  if (entity->size() != agents_left->size())
+
15606  {
+
15607 
+
15608  agents_left->resize(entity->size(), 0u);
+
15609  std::iota(agents_left->begin(), agents_left->end(), 0u);
+
15610 
+
15611  }
15612 
-
15613  #ifdef EPI_DEBUG
-
15614  if (__sampled[ith])
-
15615  throw std::logic_error("The same agent was sampled twice.");
-
15616  else
-
15617  __sampled[ith] = true;
-
15618  #endif
+
15613  }
+
15614 
+
15615  }
+
15616 
+
15617  // Restart the counter of agents left
+
15618  *agents_left_n = agents_left->size();
15619 
-
15620  // Updating list
-
15621  std::swap(
-
15622  agents_left->operator[](ith_),
-
15623  agents_left->operator[](*agents_left_n)
-
15624  );
-
15625 
-
15626  }
-
15627 
-
15628 
-
15629  }
-
15630  else if (sample_type == SAMPLETYPE::ENTITY)
-
15631  {
+
15620  // Making sure we have enough room for the sample of agents
+
15621  if (agents->size() < sample_size)
+
15622  agents->resize(sample_size, nullptr);
+
15623 
+
15624  if (sample_type == SAMPLETYPE::MODEL)
+
15625  {
+
15626 
+
15627  #ifdef EPI_DEBUG
+
15628  std::vector< bool > __sampled(model->size(), true);
+
15629  for (auto & a_i: *agents_left)
+
15630  __sampled[a_i] = false;
+
15631  #endif
15632 
-
15633  #ifdef EPI_DEBUG
-
15634  std::vector< bool > __sampled(entity->size(), true);
-
15635  for (auto & a_i: *agents_left)
-
15636  __sampled[a_i] = false;
-
15637  #endif
-
15638 
-
15639  for (size_t i = 0u; i < n; ++i)
-
15640  {
-
15641 
-
15642  size_t ith_ = static_cast<size_t>(model->runif() * ((*agents_left_n)--));
-
15643  size_t ith = agents_left->operator[](ith_);
-
15644  agents->operator[](i) = &model->population[entity->agents[ith]];
-
15645 
-
15646  #ifdef EPI_DEBUG
-
15647  if (__sampled[ith])
-
15648  throw std::logic_error("The same agent was sampled twice.");
-
15649  else
-
15650  __sampled[ith] = true;
-
15651  #endif
-
15652 
-
15653  // Updating list
-
15654  std::swap(agents_left->operator[](ith_), agents_left->operator[](*agents_left_n));
+
15633  for (size_t i = 0u; i < n; ++i)
+
15634  {
+
15635 
+
15636  // Sampling from 0 to (agents_left_n - 1)
+
15637  size_t ith_ = static_cast<size_t>(model->runif() * ((*agents_left_n)--));
+
15638 
+
15639  // Getting the id of the agent and adding it to the list of agents
+
15640  size_t ith = agents_left->operator[](ith_);
+
15641  agents->operator[](i) = &model->population[ith];
+
15642 
+
15643  #ifdef EPI_DEBUG
+
15644  if (__sampled[ith])
+
15645  throw std::logic_error("The same agent was sampled twice.");
+
15646  else
+
15647  __sampled[ith] = true;
+
15648  #endif
+
15649 
+
15650  // Updating list
+
15651  std::swap(
+
15652  agents_left->operator[](ith_),
+
15653  agents_left->operator[](*agents_left_n)
+
15654  );
15655 
15656  }
15657 
-
15658  }
-
15659 
-
15660  return;
-
15661 
-
15662 }
-
15663 
-
15664 #endif
-
15665 /*//////////////////////////////////////////////////////////////////////////////
-
15667 
-
15668  End of -include/epiworld/agentssample-bones.hpp-
-
15669 
-
15672 
-
15673 
-
15674 
-
15675 /*//////////////////////////////////////////////////////////////////////////////
-
15677 
-
15678  Start of -include/epiworld/groupsampler-bones.hpp-
-
15679 
+
15658 
+
15659  }
+
15660  else if (sample_type == SAMPLETYPE::ENTITY)
+
15661  {
+
15662 
+
15663  #ifdef EPI_DEBUG
+
15664  std::vector< bool > __sampled(entity->size(), true);
+
15665  for (auto & a_i: *agents_left)
+
15666  __sampled[a_i] = false;
+
15667  #endif
+
15668 
+
15669  for (size_t i = 0u; i < n; ++i)
+
15670  {
+
15671 
+
15672  size_t ith_ = static_cast<size_t>(model->runif() * ((*agents_left_n)--));
+
15673  size_t ith = agents_left->operator[](ith_);
+
15674  agents->operator[](i) = &model->population[entity->agents[ith]];
+
15675 
+
15676  #ifdef EPI_DEBUG
+
15677  if (__sampled[ith])
+
15678  throw std::logic_error("The same agent was sampled twice.");
+
15679  else
+
15680  __sampled[ith] = true;
+
15681  #endif
15682 
-
15683 
-
15684 #ifndef GROUPSAMPLER_BONES_HPP
-
15685 #define GROUPSAMPLER_BONES_HPP
-
15686 
-
15690 template<typename TSeq>
-
15691 class GroupSampler {
-
15692 
-
15693 private:
-
15694 
-
15695  std::vector< double > contact_matrix; ///< Contact matrix between groups
-
15696  std::vector< size_t > group_sizes; ///< Sizes of the groups
-
15697  std::vector< double > cumulate; ///< Cumulative sum of the contact matrix (row-major for faster access)
-
15698 
-
15708  inline int idx(const int i, const int j, bool rowmajor = false) const
-
15709  {
-
15710 
-
15711  if (rowmajor)
-
15712  return i * group_sizes.size() + j;
-
15713 
-
15714  return j * group_sizes.size() + i;
-
15715 
-
15716  }
-
15717 
-
15718 public:
-
15719 
-
15720  GroupSampler() {};
-
15721 
-
15722  GroupSampler(
-
15723  const std::vector< double > & contact_matrix_,
-
15724  const std::vector< size_t > & group_sizes_,
-
15725  bool normalize = true
-
15726  );
-
15727 
-
15728  int sample_1(
-
15729  Model<TSeq> * model,
-
15730  const int origin_group
-
15731  );
-
15732 
-
15733  void sample_n(
-
15734  Model<TSeq> * model,
-
15735  std::vector< int > & sample,
-
15736  const int origin_group,
-
15737  const int nsamples
-
15738  );
-
15739 
-
15740 };
-
15741 
-
15742 #endif
-
15743 /*//////////////////////////////////////////////////////////////////////////////
+
15683  // Updating list
+
15684  std::swap(agents_left->operator[](ith_), agents_left->operator[](*agents_left_n));
+
15685 
+
15686  }
+
15687 
+
15688  }
+
15689 
+
15690  return;
+
15691 
+
15692 }
+
15693 
+
15694 #endif
+
15695 /*//////////////////////////////////////////////////////////////////////////////
+
15697 
+
15698  End of -include/epiworld/agentssample-bones.hpp-
+
15699 
+
15702 
+
15703 
+
15704 
+
15705 /*//////////////////////////////////////////////////////////////////////////////
+
15707 
+
15708  Start of -include/epiworld/groupsampler-bones.hpp-
+
15709 
+
15712 
+
15713 
+
15714 #ifndef GROUPSAMPLER_BONES_HPP
+
15715 #define GROUPSAMPLER_BONES_HPP
+
15716 
+
15720 template<typename TSeq>
+
15721 class GroupSampler {
+
15722 
+
15723 private:
+
15724 
+
15725  std::vector< double > contact_matrix; ///< Contact matrix between groups
+
15726  std::vector< size_t > group_sizes; ///< Sizes of the groups
+
15727  std::vector< double > cumulate; ///< Cumulative sum of the contact matrix (row-major for faster access)
+
15728 
+
15738  inline int idx(const int i, const int j, bool rowmajor = false) const
+
15739  {
+
15740 
+
15741  if (rowmajor)
+
15742  return i * group_sizes.size() + j;
+
15743 
+
15744  return j * group_sizes.size() + i;
15745 
-
15746  End of -include/epiworld/groupsampler-bones.hpp-
+
15746  }
15747 
-
15750 
+
15748 public:
+
15749 
+
15750  GroupSampler() {};
15751 
-
15752 /*//////////////////////////////////////////////////////////////////////////////
-
15754 
-
15755  Start of -include/epiworld/groupsampler-meat.hpp-
-
15756 
-
15759 
-
15760 
-
15761 #ifndef GROUPSAMPLER_MEAT_HPP
-
15762 #define GROUPSAMPLER_MEAT_HPP
-
15763 
-
15764 template<typename TSeq>
-
15765 inline GroupSampler<TSeq>::GroupSampler(
-
15766  const std::vector< double > & contact_matrix_,
-
15767  const std::vector< size_t > & group_sizes_,
-
15768  bool normalize
-
15769  ): contact_matrix(contact_matrix_), group_sizes(group_sizes_) {
-
15770 
+
15752  GroupSampler(
+
15753  const std::vector< double > & contact_matrix_,
+
15754  const std::vector< size_t > & group_sizes_,
+
15755  bool normalize = true
+
15756  );
+
15757 
+
15758  int sample_1(
+
15759  Model<TSeq> * model,
+
15760  const int origin_group
+
15761  );
+
15762 
+
15763  void sample_n(
+
15764  Model<TSeq> * model,
+
15765  std::vector< int > & sample,
+
15766  const int origin_group,
+
15767  const int nsamples
+
15768  );
+
15769 
+
15770 };
15771 
-
15772  this->cumulate.resize(contact_matrix.size());
-
15773  std::fill(cumulate.begin(), cumulate.end(), 0.0);
-
15774 
-
15775  // Cumulative sum
-
15776  for (size_t j = 0; j < group_sizes.size(); ++j)
-
15777  {
-
15778  for (size_t i = 0; i < group_sizes.size(); ++i)
-
15779  cumulate[idx(i, j, true)] +=
-
15780  cumulate[idx(i, j - 1, true)] +
-
15781  contact_matrix[idx(i, j)];
-
15782  }
-
15783 
-
15784  if (normalize)
-
15785  {
-
15786  for (size_t i = 0; i < group_sizes.size(); ++i)
-
15787  {
-
15788  double sum = 0.0;
-
15789  for (size_t j = 0; j < group_sizes.size(); ++j)
-
15790  sum += contact_matrix[idx(i, j, true)];
-
15791  for (size_t j = 0; j < group_sizes.size(); ++j)
-
15792  contact_matrix[idx(i, j, true)] /= sum;
-
15793  }
-
15794  }
-
15795 
-
15796  };
-
15797 
-
15798 template<typename TSeq>
-
15799 int GroupSampler<TSeq>::sample_1(
-
15800  Model<TSeq> * model,
-
15801  const int origin_group
-
15802  )
-
15803 {
+
15772 #endif
+
15773 /*//////////////////////////////////////////////////////////////////////////////
+
15775 
+
15776  End of -include/epiworld/groupsampler-bones.hpp-
+
15777 
+
15780 
+
15781 
+
15782 /*//////////////////////////////////////////////////////////////////////////////
+
15784 
+
15785  Start of -include/epiworld/groupsampler-meat.hpp-
+
15786 
+
15789 
+
15790 
+
15791 #ifndef GROUPSAMPLER_MEAT_HPP
+
15792 #define GROUPSAMPLER_MEAT_HPP
+
15793 
+
15794 template<typename TSeq>
+
15795 inline GroupSampler<TSeq>::GroupSampler(
+
15796  const std::vector< double > & contact_matrix_,
+
15797  const std::vector< size_t > & group_sizes_,
+
15798  bool normalize
+
15799  ): contact_matrix(contact_matrix_), group_sizes(group_sizes_) {
+
15800 
+
15801 
+
15802  this->cumulate.resize(contact_matrix.size());
+
15803  std::fill(cumulate.begin(), cumulate.end(), 0.0);
15804 
-
15805  // Random number
-
15806  double r = model->runif();
-
15807 
-
15808  // Finding the group
-
15809  size_t j = 0;
-
15810  while (r > cumulate[idx(origin_group, j, true)])
-
15811  ++j;
-
15812 
-
15813  // Adjusting the prob
-
15814  r = r - (j == 0 ? 0.0 : cumulate[idx(origin_group, j - 1, true)]);
-
15815 
-
15816  int res = static_cast<int>(
-
15817  std::floor(r * group_sizes[j])
-
15818  );
-
15819 
-
15820  // Making sure we are not picking outside of the group
-
15821  if (res >= static_cast<int>(group_sizes[j]))
-
15822  res = static_cast<int>(group_sizes[j]) - 1;
-
15823 
-
15824  return model->get_entities()[j][res]->get_id();
+
15805  // Cumulative sum
+
15806  for (size_t j = 0; j < group_sizes.size(); ++j)
+
15807  {
+
15808  for (size_t i = 0; i < group_sizes.size(); ++i)
+
15809  cumulate[idx(i, j, true)] +=
+
15810  cumulate[idx(i, j - 1, true)] +
+
15811  contact_matrix[idx(i, j)];
+
15812  }
+
15813 
+
15814  if (normalize)
+
15815  {
+
15816  for (size_t i = 0; i < group_sizes.size(); ++i)
+
15817  {
+
15818  double sum = 0.0;
+
15819  for (size_t j = 0; j < group_sizes.size(); ++j)
+
15820  sum += contact_matrix[idx(i, j, true)];
+
15821  for (size_t j = 0; j < group_sizes.size(); ++j)
+
15822  contact_matrix[idx(i, j, true)] /= sum;
+
15823  }
+
15824  }
15825 
-
15826 }
+
15826  };
15827 
15828 template<typename TSeq>
-
15829 void GroupSampler<TSeq>::sample_n(
+
15829 int GroupSampler<TSeq>::sample_1(
15830  Model<TSeq> * model,
-
15831  std::vector< int > & sample,
-
15832  const int origin_group,
-
15833  const int nsamples
-
15834 )
-
15835 {
-
15836 
-
15837  for (int i = 0; i < nsamples; ++i)
-
15838  sample[i] = sample_1(model, origin_group);
-
15839 
-
15840  return;
-
15841 
-
15842 }
-
15843 
-
15844 #endif
-
15845 /*//////////////////////////////////////////////////////////////////////////////
-
15847 
-
15848  End of -include/epiworld/groupsampler-meat.hpp-
+
15831  const int origin_group
+
15832  )
+
15833 {
+
15834 
+
15835  // Random number
+
15836  double r = model->runif();
+
15837 
+
15838  // Finding the group
+
15839  size_t j = 0;
+
15840  while (r > cumulate[idx(origin_group, j, true)])
+
15841  ++j;
+
15842 
+
15843  // Adjusting the prob
+
15844  r = r - (j == 0 ? 0.0 : cumulate[idx(origin_group, j - 1, true)]);
+
15845 
+
15846  int res = static_cast<int>(
+
15847  std::floor(r * group_sizes[j])
+
15848  );
15849 
-
15852 
+
15850  // Making sure we are not picking outside of the group
+
15851  if (res >= static_cast<int>(group_sizes[j]))
+
15852  res = static_cast<int>(group_sizes[j]) - 1;
15853 
-
15854 
-
15855 /*//////////////////////////////////////////////////////////////////////////////
+
15854  return model->get_entities()[j][res]->get_id();
+
15855 
+
15856 }
15857 
-
15858  Start of -include/epiworld/models/models.hpp-
-
15859 
-
15862 
-
15863 
-
15864 #ifndef EPIWORLD_MODELS_HPP
-
15865 #define EPIWORLD_MODELS_HPP
+
15858 template<typename TSeq>
+
15859 void GroupSampler<TSeq>::sample_n(
+
15860  Model<TSeq> * model,
+
15861  std::vector< int > & sample,
+
15862  const int origin_group,
+
15863  const int nsamples
+
15864 )
+
15865 {
15866 
-
15867 namespace epimodels {
-
15868 
-
15869 /*//////////////////////////////////////////////////////////////////////////////
+
15867  for (int i = 0; i < nsamples; ++i)
+
15868  sample[i] = sample_1(model, origin_group);
+
15869 
+
15870  return;
15871 
-
15872  Start of -include/epiworld//models/init-functions.hpp-
+
15872 }
15873 
-
15876 
+
15874 #endif
+
15875 /*//////////////////////////////////////////////////////////////////////////////
15877 
-
15878 #ifndef EPIWORLD_MODELS_INIT_FUNCTIONS_HPP
-
15879 #define EPIWORLD_MODELS_INIT_FUNCTIONS_HPP
-
15880 
-
15885 template<typename TSeq>
-
15886 inline std::function<void(epiworld::Model<TSeq>*)> create_init_function_sir(
-
15887  std::vector< double > proportions_
-
15888 ) {
+
15878  End of -include/epiworld/groupsampler-meat.hpp-
+
15879 
+
15882 
+
15883 
+
15884 
+
15885 /*//////////////////////////////////////////////////////////////////////////////
+
15887 
+
15888  Start of -include/epiworld/models/models.hpp-
15889 
-
15890  // Checking widths
-
15891  if (proportions_.size() != 1u)
-
15892  throw std::invalid_argument(
-
15893  "The vector of proportions must have a single element."
-
15894  );
-
15895 
-
15896  // Proportion should be within [0, 1]
-
15897  if ((proportions_[0] < 0.0) || (proportions_[0] > 1.0))
-
15898  throw std::invalid_argument(
-
15899  "The proportion must be within (0, 1)."
-
15900  );
+
15892 
+
15893 
+
15894 #ifndef EPIWORLD_MODELS_HPP
+
15895 #define EPIWORLD_MODELS_HPP
+
15896 
+
15897 namespace epimodels {
+
15898 
+
15899 /*//////////////////////////////////////////////////////////////////////////////
15901 
-
15902  double prop = proportions_[0u];
+
15902  Start of -include/epiworld//models/init-functions.hpp-
15903 
-
15904  std::function<void(epiworld::Model<TSeq>*)> fun =
-
15905  [prop] (epiworld::Model<TSeq> * model) -> void {
15906 
-
15907  // Figuring out information about the viruses
-
15908  double tot = 0.0;
-
15909  double n = static_cast<double>(model->size());
-
15910  for (const auto & agent: model->get_agents())
-
15911  {
-
15912  if (agent.get_virus() != nullptr)
-
15913  tot += 1.0;
-
15914  }
-
15915  tot /= n;
-
15916 
-
15917  // Putting the total into context
-
15918  double tot_left = 1.0 - tot;
+
15907 
+
15908 #ifndef EPIWORLD_MODELS_INIT_FUNCTIONS_HPP
+
15909 #define EPIWORLD_MODELS_INIT_FUNCTIONS_HPP
+
15910 
+
15915 template<typename TSeq>
+
15916 inline std::function<void(epiworld::Model<TSeq>*)> create_init_function_sir(
+
15917  std::vector< double > proportions_
+
15918 ) {
15919 
-
15920  // Since susceptible and infected are "fixed,"
-
15921  // we only need to change recovered
-
15922  size_t nrecovered = prop * tot_left * n;
-
15923 
-
15924  epiworld::AgentsSample<TSeq> sample(
-
15925  *model,
-
15926  nrecovered,
-
15927  {0u},
-
15928  true
-
15929  );
-
15930 
-
15931  // Setting up the initial states
-
15932  for (auto & agent : sample)
-
15933  agent->change_state(model, 2, Queue<TSeq>::NoOne);
-
15934 
-
15935  // Running the events
-
15936  model->events_run();
-
15937 
-
15938  return;
-
15939 
-
15940  };
-
15941 
-
15942  return fun;
-
15943 
-
15944 }
-
15945 
-
15950 template<typename TSeq>
-
15951 inline std::function<void(epiworld::Model<TSeq>*)> create_init_function_sird(
-
15952  std::vector< double > prop
-
15953 ) {
-
15954 
-
15955  // Check length of prop equals two
-
15956  if (prop.size() != 2u)
-
15957  throw std::invalid_argument(
-
15958  "The vector of proportions must have two elements."
+
15920  // Checking widths
+
15921  if (proportions_.size() != 1u)
+
15922  throw std::invalid_argument(
+
15923  "The vector of proportions must have a single element."
+
15924  );
+
15925 
+
15926  // Proportion should be within [0, 1]
+
15927  if ((proportions_[0] < 0.0) || (proportions_[0] > 1.0))
+
15928  throw std::invalid_argument(
+
15929  "The proportion must be within (0, 1)."
+
15930  );
+
15931 
+
15932  double prop = proportions_[0u];
+
15933 
+
15934  std::function<void(epiworld::Model<TSeq>*)> fun =
+
15935  [prop] (epiworld::Model<TSeq> * model) -> void {
+
15936 
+
15937  // Figuring out information about the viruses
+
15938  double tot = 0.0;
+
15939  double n = static_cast<double>(model->size());
+
15940  for (const auto & agent: model->get_agents())
+
15941  {
+
15942  if (agent.get_virus() != nullptr)
+
15943  tot += 1.0;
+
15944  }
+
15945  tot /= n;
+
15946 
+
15947  // Putting the total into context
+
15948  double tot_left = 1.0 - tot;
+
15949 
+
15950  // Since susceptible and infected are "fixed,"
+
15951  // we only need to change recovered
+
15952  size_t nrecovered = prop * tot_left * n;
+
15953 
+
15954  epiworld::AgentsSample<TSeq> sample(
+
15955  *model,
+
15956  nrecovered,
+
15957  {0u},
+
15958  true
15959  );
15960 
-
15961  // Check elements in prop are within [0, 1] and sum up to 1
-
15962  double tot = 0.0;
-
15963  for (auto & v : prop)
-
15964  {
-
15965  if ((v < 0.0) || (v > 1.0))
-
15966  throw std::invalid_argument(
-
15967  "The proportion must be within (0, 1)."
-
15968  );
-
15969  tot += v;
-
15970  }
+
15961  // Setting up the initial states
+
15962  for (auto & agent : sample)
+
15963  agent->change_state(model, 2, Queue<TSeq>::NoOne);
+
15964 
+
15965  // Running the events
+
15966  model->events_run();
+
15967 
+
15968  return;
+
15969 
+
15970  };
15971 
-
15972  if (tot >= 1.0)
-
15973  throw std::invalid_argument(
-
15974  "The proportions must sum up to 1."
-
15975  );
-
15976 
-
15977  std::function<void(epiworld::Model<TSeq>*)> fun =
-
15978  [prop] (epiworld::Model<TSeq> * model) -> void {
-
15979 
-
15980  // Figuring out information about the viruses
-
15981  double tot = 0.0;
-
15982  double n = static_cast<double>(model->size());
-
15983  for (const auto & agent: model->get_agents())
-
15984  {
-
15985  if (agent.get_virus() != nullptr)
-
15986  tot += 1.0;
-
15987  }
-
15988  tot /= n;
-
15989 
-
15990  // Putting the total into context
-
15991  double tot_left = 1.0 - tot;
-
15992 
-
15993  // Since susceptible and infected are "fixed,"
-
15994  // we only need to change recovered
-
15995  size_t nrecovered = prop[0u] * tot_left * n;
-
15996  size_t ndeceased = prop[01] * tot_left * n;
-
15997 
-
15998  epiworld::AgentsSample<TSeq> sample_recover(
-
15999  *model,
-
16000  nrecovered,
-
16001  {0u},
-
16002  true
-
16003  );
-
16004 
-
16005  // Setting up the initial states
-
16006  for (auto & agent : sample_recover)
-
16007  agent->change_state(model, 2, Queue<TSeq>::NoOne);
-
16008 
-
16009  epiworld::AgentsSample<TSeq> sample_deceased(
-
16010  *model,
-
16011  ndeceased,
-
16012  {0u},
-
16013  true
-
16014  );
-
16015 
-
16016  // Setting up the initial states
-
16017  for (auto & agent : sample_deceased)
-
16018  agent->change_state(model, 3, Queue<TSeq>::NoOne);
-
16019 
-
16020  // Running the events
-
16021  model->events_run();
+
15972  return fun;
+
15973 
+
15974 }
+
15975 
+
15980 template<typename TSeq>
+
15981 inline std::function<void(epiworld::Model<TSeq>*)> create_init_function_sird(
+
15982  std::vector< double > prop
+
15983 ) {
+
15984 
+
15985  // Check length of prop equals two
+
15986  if (prop.size() != 2u)
+
15987  throw std::invalid_argument(
+
15988  "The vector of proportions must have two elements."
+
15989  );
+
15990 
+
15991  // Check elements in prop are within [0, 1] and sum up to 1
+
15992  double tot = 0.0;
+
15993  for (auto & v : prop)
+
15994  {
+
15995  if ((v < 0.0) || (v > 1.0))
+
15996  throw std::invalid_argument(
+
15997  "The proportion must be within (0, 1)."
+
15998  );
+
15999  tot += v;
+
16000  }
+
16001 
+
16002  if (tot >= 1.0)
+
16003  throw std::invalid_argument(
+
16004  "The proportions must sum up to 1."
+
16005  );
+
16006 
+
16007  std::function<void(epiworld::Model<TSeq>*)> fun =
+
16008  [prop] (epiworld::Model<TSeq> * model) -> void {
+
16009 
+
16010  // Figuring out information about the viruses
+
16011  double tot = 0.0;
+
16012  double n = static_cast<double>(model->size());
+
16013  for (const auto & agent: model->get_agents())
+
16014  {
+
16015  if (agent.get_virus() != nullptr)
+
16016  tot += 1.0;
+
16017  }
+
16018  tot /= n;
+
16019 
+
16020  // Putting the total into context
+
16021  double tot_left = 1.0 - tot;
16022 
-
16023  return;
-
16024 
-
16025  };
-
16026 
-
16027  return fun;
-
16028 
-
16029 }
-
16030 
-
16031 
-
16036 template<typename TSeq>
-
16037 inline std::function<void(epiworld::Model<TSeq>*)> create_init_function_seir(
-
16038  std::vector< double > proportions_
-
16039 ) {
-
16040 
-
16041  // Checking widths
-
16042  if (proportions_.size() != 2u) {
-
16043  throw std::invalid_argument("-proportions_- must have two entries.");
-
16044  }
+
16023  // Since susceptible and infected are "fixed,"
+
16024  // we only need to change recovered
+
16025  size_t nrecovered = prop[0u] * tot_left * n;
+
16026  size_t ndeceased = prop[01] * tot_left * n;
+
16027 
+
16028  epiworld::AgentsSample<TSeq> sample_recover(
+
16029  *model,
+
16030  nrecovered,
+
16031  {0u},
+
16032  true
+
16033  );
+
16034 
+
16035  // Setting up the initial states
+
16036  for (auto & agent : sample_recover)
+
16037  agent->change_state(model, 2, Queue<TSeq>::NoOne);
+
16038 
+
16039  epiworld::AgentsSample<TSeq> sample_deceased(
+
16040  *model,
+
16041  ndeceased,
+
16042  {0u},
+
16043  true
+
16044  );
16045 
-
16046  // proportions_ are values between 0 and 1, otherwise error
-
16047  for (auto & v : proportions_)
-
16048  if ((v < 0.0) || (v > 1.0))
-
16049  throw std::invalid_argument(
-
16050  "-proportions_- must have values between 0 and 1."
-
16051  );
+
16046  // Setting up the initial states
+
16047  for (auto & agent : sample_deceased)
+
16048  agent->change_state(model, 3, Queue<TSeq>::NoOne);
+
16049 
+
16050  // Running the events
+
16051  model->events_run();
16052 
-
16053 
-
16054  std::function<void(epiworld::Model<TSeq>*)> fun =
-
16055  [proportions_] (epiworld::Model<TSeq> * model) -> void {
+
16053  return;
+
16054 
+
16055  };
16056 
-
16057  // Figuring out information about the viruses
-
16058  double tot = 0.0;
-
16059  double n = static_cast<double>(model->size());
-
16060  for (const auto & agent: model->get_agents())
-
16061  {
-
16062  if (agent.get_virus() != nullptr)
-
16063  tot += 1.0;
-
16064  }
-
16065  tot /= n;
-
16066 
-
16067  // Putting the total into context
-
16068  double tot_left = 1.0 - tot;
-
16069 
-
16070  // Since susceptible and infected are "fixed,"
-
16071  // we only need to change recovered
-
16072  size_t nexposed = proportions_[0u] * tot * n;
-
16073  size_t nrecovered = proportions_[1u] * tot_left * n;
-
16074 
-
16075  epiworld::AgentsSample<TSeq> sample_suscept(
-
16076  *model,
-
16077  nrecovered,
-
16078  {0u},
-
16079  true
-
16080  );
-
16081 
-
16082  // Setting up the initial states
-
16083  for (auto & agent : sample_suscept)
-
16084  agent->change_state(model, 3, Queue<TSeq>::NoOne);
-
16085 
-
16086  epiworld::AgentsSample<TSeq> sample_exposed(
-
16087  *model,
-
16088  nexposed,
-
16089  {1u},
-
16090  true
-
16091  );
-
16092 
-
16093  // Setting up the initial states
-
16094  for (auto & agent : sample_exposed)
-
16095  agent->change_state(model, 2, Queue<TSeq>::NoOne);
-
16096 
-
16097  // Running the events
-
16098  model->events_run();
+
16057  return fun;
+
16058 
+
16059 }
+
16060 
+
16061 
+
16066 template<typename TSeq>
+
16067 inline std::function<void(epiworld::Model<TSeq>*)> create_init_function_seir(
+
16068  std::vector< double > proportions_
+
16069 ) {
+
16070 
+
16071  // Checking widths
+
16072  if (proportions_.size() != 2u) {
+
16073  throw std::invalid_argument("-proportions_- must have two entries.");
+
16074  }
+
16075 
+
16076  // proportions_ are values between 0 and 1, otherwise error
+
16077  for (auto & v : proportions_)
+
16078  if ((v < 0.0) || (v > 1.0))
+
16079  throw std::invalid_argument(
+
16080  "-proportions_- must have values between 0 and 1."
+
16081  );
+
16082 
+
16083 
+
16084  std::function<void(epiworld::Model<TSeq>*)> fun =
+
16085  [proportions_] (epiworld::Model<TSeq> * model) -> void {
+
16086 
+
16087  // Figuring out information about the viruses
+
16088  double tot = 0.0;
+
16089  double n = static_cast<double>(model->size());
+
16090  for (const auto & agent: model->get_agents())
+
16091  {
+
16092  if (agent.get_virus() != nullptr)
+
16093  tot += 1.0;
+
16094  }
+
16095  tot /= n;
+
16096 
+
16097  // Putting the total into context
+
16098  double tot_left = 1.0 - tot;
16099 
-
16100  return;
-
16101 
-
16102  };
-
16103 
-
16104  return fun;
-
16105 
-
16106 }
-
16107 
-
16112 template<typename TSeq>
-
16113 inline std::function<void(epiworld::Model<TSeq>*)> create_init_function_seird(
-
16114  std::vector< double > proportions_
-
16115 ) {
-
16116 
-
16117  // Checking widths
-
16118  if (proportions_.size() != 3u) {
-
16119  throw std::invalid_argument("-proportions_- must have three entries.");
-
16120  }
-
16121 
-
16122  // proportions_ are values between 0 and 1, otherwise error
-
16123  for (auto & v : proportions_)
-
16124  if ((v < 0.0) || (v > 1.0))
-
16125  throw std::invalid_argument(
-
16126  "-proportions_- must have values between 0 and 1."
-
16127  );
-
16128 
-
16129  // Last first two terms shouldn't add up to more than 1
-
16130  if ((proportions_[1u] + proportions_[2u]) > 1.0)
-
16131  throw std::invalid_argument(
-
16132  "The last two terms of -proportions_- must add up to less than 1."
-
16133  );
-
16134 
-
16135  std::function<void(epiworld::Model<TSeq>*)> fun =
-
16136  [proportions_] (epiworld::Model<TSeq> * model) -> void {
+
16100  // Since susceptible and infected are "fixed,"
+
16101  // we only need to change recovered
+
16102  size_t nexposed = proportions_[0u] * tot * n;
+
16103  size_t nrecovered = proportions_[1u] * tot_left * n;
+
16104 
+
16105  epiworld::AgentsSample<TSeq> sample_suscept(
+
16106  *model,
+
16107  nrecovered,
+
16108  {0u},
+
16109  true
+
16110  );
+
16111 
+
16112  // Setting up the initial states
+
16113  for (auto & agent : sample_suscept)
+
16114  agent->change_state(model, 3, Queue<TSeq>::NoOne);
+
16115 
+
16116  epiworld::AgentsSample<TSeq> sample_exposed(
+
16117  *model,
+
16118  nexposed,
+
16119  {1u},
+
16120  true
+
16121  );
+
16122 
+
16123  // Setting up the initial states
+
16124  for (auto & agent : sample_exposed)
+
16125  agent->change_state(model, 2, Queue<TSeq>::NoOne);
+
16126 
+
16127  // Running the events
+
16128  model->events_run();
+
16129 
+
16130  return;
+
16131 
+
16132  };
+
16133 
+
16134  return fun;
+
16135 
+
16136 }
16137 
-
16138  // Figuring out information about the viruses
-
16139  double tot = 0.0;
-
16140  double n = static_cast<double>(model->size());
-
16141 
-
16142  for (const auto & agent: model->get_agents())
-
16143  {
-
16144  if (agent.get_virus() != nullptr)
-
16145  tot += 1.0;
-
16146  }
-
16147  tot /= n;
-
16148 
-
16149  // Putting the total into context
-
16150  double tot_left = 1.0 - tot;
+
16142 template<typename TSeq>
+
16143 inline std::function<void(epiworld::Model<TSeq>*)> create_init_function_seird(
+
16144  std::vector< double > proportions_
+
16145 ) {
+
16146 
+
16147  // Checking widths
+
16148  if (proportions_.size() != 3u) {
+
16149  throw std::invalid_argument("-proportions_- must have three entries.");
+
16150  }
16151 
-
16152  // Since susceptible and infected are "fixed,"
-
16153  // we only need to change recovered
-
16154  size_t nexposed = proportions_[0u] * tot * n;
-
16155  size_t nrecovered = proportions_[1u] * tot_left * n;
-
16156  size_t ndeceased = proportions_[2u] * tot_left * n;
-
16157 
-
16158  epiworld::AgentsSample<TSeq> sample_suscept(
-
16159  *model,
-
16160  nrecovered,
-
16161  {0u},
-
16162  true
+
16152  // proportions_ are values between 0 and 1, otherwise error
+
16153  for (auto & v : proportions_)
+
16154  if ((v < 0.0) || (v > 1.0))
+
16155  throw std::invalid_argument(
+
16156  "-proportions_- must have values between 0 and 1."
+
16157  );
+
16158 
+
16159  // Last first two terms shouldn't add up to more than 1
+
16160  if ((proportions_[1u] + proportions_[2u]) > 1.0)
+
16161  throw std::invalid_argument(
+
16162  "The last two terms of -proportions_- must add up to less than 1."
16163  );
16164 
-
16165  // Setting up the initial states
-
16166  for (auto & agent : sample_suscept)
-
16167  agent->change_state(model, 3, Queue<TSeq>::NoOne);
-
16168 
-
16169  epiworld::AgentsSample<TSeq> sample_exposed(
-
16170  *model,
-
16171  nexposed,
-
16172  {1u},
-
16173  true
-
16174  );
-
16175 
-
16176  // Setting up the initial states
-
16177  for (auto & agent : sample_exposed)
-
16178  agent->change_state(model, 2, Queue<TSeq>::NoOne);
-
16179 
-
16180  // Running the events
-
16181  model->events_run();
-
16182 
-
16183  // Setting the initial states for the deceased
-
16184  epiworld::AgentsSample<TSeq> sample_deceased(
-
16185  *model,
-
16186  ndeceased,
-
16187  {0u},
-
16188  true
-
16189  );
-
16190 
-
16191  // Setting up the initial states
-
16192  for (auto & agent : sample_deceased)
-
16193  agent->change_state(model, 4, Queue<TSeq>::NoOne);
-
16194 
-
16195  // Running the events
-
16196  model->events_run();
-
16197 
-
16198  return;
-
16199 
-
16200  };
-
16201 
-
16202  return fun;
-
16203 
-
16204 }
+
16165  std::function<void(epiworld::Model<TSeq>*)> fun =
+
16166  [proportions_] (epiworld::Model<TSeq> * model) -> void {
+
16167 
+
16168  // Figuring out information about the viruses
+
16169  double tot = 0.0;
+
16170  double n = static_cast<double>(model->size());
+
16171 
+
16172  for (const auto & agent: model->get_agents())
+
16173  {
+
16174  if (agent.get_virus() != nullptr)
+
16175  tot += 1.0;
+
16176  }
+
16177  tot /= n;
+
16178 
+
16179  // Putting the total into context
+
16180  double tot_left = 1.0 - tot;
+
16181 
+
16182  // Since susceptible and infected are "fixed,"
+
16183  // we only need to change recovered
+
16184  size_t nexposed = proportions_[0u] * tot * n;
+
16185  size_t nrecovered = proportions_[1u] * tot_left * n;
+
16186  size_t ndeceased = proportions_[2u] * tot_left * n;
+
16187 
+
16188  epiworld::AgentsSample<TSeq> sample_suscept(
+
16189  *model,
+
16190  nrecovered,
+
16191  {0u},
+
16192  true
+
16193  );
+
16194 
+
16195  // Setting up the initial states
+
16196  for (auto & agent : sample_suscept)
+
16197  agent->change_state(model, 3, Queue<TSeq>::NoOne);
+
16198 
+
16199  epiworld::AgentsSample<TSeq> sample_exposed(
+
16200  *model,
+
16201  nexposed,
+
16202  {1u},
+
16203  true
+
16204  );
16205 
-
16206 
-
16207 #endif
-
16208 /*//////////////////////////////////////////////////////////////////////////////
-
16210 
-
16211  End of -include/epiworld//models/init-functions.hpp-
+
16206  // Setting up the initial states
+
16207  for (auto & agent : sample_exposed)
+
16208  agent->change_state(model, 2, Queue<TSeq>::NoOne);
+
16209 
+
16210  // Running the events
+
16211  model->events_run();
16212 
-
16215 
-
16216 
-
16217 
-
16218 /*//////////////////////////////////////////////////////////////////////////////
-
16220 
-
16221  Start of -include/epiworld//models/globalevents.hpp-
-
16222 
-
16225 
-
16226 
-
16227 #ifndef EPIWORLD_GLOBALEVENTS_HPP
-
16228 #define EPIWORLD_GLOBALEVENTS_HPP
+
16213  // Setting the initial states for the deceased
+
16214  epiworld::AgentsSample<TSeq> sample_deceased(
+
16215  *model,
+
16216  ndeceased,
+
16217  {0u},
+
16218  true
+
16219  );
+
16220 
+
16221  // Setting up the initial states
+
16222  for (auto & agent : sample_deceased)
+
16223  agent->change_state(model, 4, Queue<TSeq>::NoOne);
+
16224 
+
16225  // Running the events
+
16226  model->events_run();
+
16227 
+
16228  return;
16229 
-
16230 // This function creates a global action that distributes a tool
-
16231 // to agents with probability p.
-
16240 template<typename TSeq>
-
16241 inline std::function<void(Model<TSeq>*)> globalevent_tool(
-
16242  Tool<TSeq> & tool,
-
16243  double p
-
16244 ) {
+
16230  };
+
16231 
+
16232  return fun;
+
16233 
+
16234 }
+
16235 
+
16236 
+
16237 #endif
+
16238 /*//////////////////////////////////////////////////////////////////////////////
+
16240 
+
16241  End of -include/epiworld//models/init-functions.hpp-
+
16242 
16245 
-
16246  std::function<void(Model<TSeq>*)> fun = [p,&tool](
-
16247  Model<TSeq> * model
-
16248  ) -> void {
-
16249 
-
16250  for (auto & agent : model->get_agents())
-
16251  {
+
16246 
+
16247 
+
16248 /*//////////////////////////////////////////////////////////////////////////////
+
16250 
+
16251  Start of -include/epiworld//models/globalevents.hpp-
16252 
-
16253  // Check if the agent has the tool
-
16254  if (agent.has_tool(tool))
-
16255  continue;
+
16255 
16256 
-
16257  // Adding the tool
-
16258  if (model->runif() < p)
-
16259  agent.add_tool(tool, model);
-
16260 
-
16261 
-
16262  }
-
16263 
-
16264  #ifdef EPIWORLD_DEBUG
-
16265  tool.print();
-
16266  #endif
-
16267 
-
16268  return;
-
16269 
-
16270 
-
16271  };
-
16272 
-
16273  return fun;
-
16274 
-
16275 }
-
16276 
-
16277 // Same function as above, but p is now a function of a vector of coefficients
-
16278 // and a vector of variables.
-
16289 template<typename TSeq>
-
16290 inline std::function<void(Model<TSeq>*)> globalevent_tool_logit(
-
16291  Tool<TSeq> & tool,
-
16292  std::vector< size_t > vars,
-
16293  std::vector< double > coefs
-
16294 ) {
-
16295 
-
16296  std::function<void(Model<TSeq>*)> fun = [coefs,vars,&tool](
-
16297  Model<TSeq> * model
-
16298  ) -> void {
-
16299 
-
16300  for (auto & agent : model->get_agents())
-
16301  {
+
16257 #ifndef EPIWORLD_GLOBALEVENTS_HPP
+
16258 #define EPIWORLD_GLOBALEVENTS_HPP
+
16259 
+
16260 // This function creates a global action that distributes a tool
+
16261 // to agents with probability p.
+
16270 template<typename TSeq>
+
16271 inline std::function<void(Model<TSeq>*)> globalevent_tool(
+
16272  Tool<TSeq> & tool,
+
16273  double p
+
16274 ) {
+
16275 
+
16276  std::function<void(Model<TSeq>*)> fun = [p,&tool](
+
16277  Model<TSeq> * model
+
16278  ) -> void {
+
16279 
+
16280  for (auto & agent : model->get_agents())
+
16281  {
+
16282 
+
16283  // Check if the agent has the tool
+
16284  if (agent.has_tool(tool))
+
16285  continue;
+
16286 
+
16287  // Adding the tool
+
16288  if (model->runif() < p)
+
16289  agent.add_tool(tool, model);
+
16290 
+
16291 
+
16292  }
+
16293 
+
16294  #ifdef EPIWORLD_DEBUG
+
16295  tool.print();
+
16296  #endif
+
16297 
+
16298  return;
+
16299 
+
16300 
+
16301  };
16302 
-
16303  // Check if the agent has the tool
-
16304  if (agent.has_tool(tool))
-
16305  continue;
+
16303  return fun;
+
16304 
+
16305 }
16306 
-
16307  // Computing the probability using a logit. Uses OpenMP reduction
-
16308  // to sum the coefficients.
-
16309  double p = 0.0;
-
16310  #if defined(__OPENMP) || defined(_OPENMP)
-
16311  #pragma omp parallel for reduction(+:p)
-
16312  #endif
-
16313  for (size_t i = 0u; i < coefs.size(); ++i)
-
16314  p += coefs.at(i) * agent(vars[i]);
-
16315 
-
16316  p = 1.0 / (1.0 + std::exp(-p));
-
16317 
-
16318  // Adding the tool
-
16319  if (model->runif() < p)
-
16320  agent.add_tool(tool, model);
-
16321 
-
16322 
-
16323  }
-
16324 
-
16325  #ifdef EPIWORLD_DEBUG
-
16326  tool.print();
-
16327  #endif
-
16328 
-
16329  return;
-
16330 
-
16331 
-
16332  };
-
16333 
-
16334  return fun;
-
16335 
-
16336 }
-
16337 
-
16338 // A global action that updates a parameter in the model.
-
16347 template<typename TSeq>
-
16348 inline std::function<void(Model<TSeq>*)> globalevent_set_param(
-
16349  std::string param,
-
16350  double value
-
16351 ) {
-
16352 
-
16353  std::function<void(Model<TSeq>*)> fun = [value,param](
-
16354  Model<TSeq> * model
-
16355  ) -> void {
-
16356 
-
16357  model->set_param(param, value);
+
16307 // Same function as above, but p is now a function of a vector of coefficients
+
16308 // and a vector of variables.
+
16319 template<typename TSeq>
+
16320 inline std::function<void(Model<TSeq>*)> globalevent_tool_logit(
+
16321  Tool<TSeq> & tool,
+
16322  std::vector< size_t > vars,
+
16323  std::vector< double > coefs
+
16324 ) {
+
16325 
+
16326  std::function<void(Model<TSeq>*)> fun = [coefs,vars,&tool](
+
16327  Model<TSeq> * model
+
16328  ) -> void {
+
16329 
+
16330  for (auto & agent : model->get_agents())
+
16331  {
+
16332 
+
16333  // Check if the agent has the tool
+
16334  if (agent.has_tool(tool))
+
16335  continue;
+
16336 
+
16337  // Computing the probability using a logit. Uses OpenMP reduction
+
16338  // to sum the coefficients.
+
16339  double p = 0.0;
+
16340  #if defined(__OPENMP) || defined(_OPENMP)
+
16341  #pragma omp parallel for reduction(+:p)
+
16342  #endif
+
16343  for (size_t i = 0u; i < coefs.size(); ++i)
+
16344  p += coefs.at(i) * agent(vars[i]);
+
16345 
+
16346  p = 1.0 / (1.0 + std::exp(-p));
+
16347 
+
16348  // Adding the tool
+
16349  if (model->runif() < p)
+
16350  agent.add_tool(tool, model);
+
16351 
+
16352 
+
16353  }
+
16354 
+
16355  #ifdef EPIWORLD_DEBUG
+
16356  tool.print();
+
16357  #endif
16358 
16359  return;
16360 
@@ -14974,4307 +14982,4329 @@
16364  return fun;
16365 
16366 }
-
16367 #endif
-
16368 /*//////////////////////////////////////////////////////////////////////////////
-
16370 
-
16371  End of -include/epiworld//models/globalevents.hpp-
-
16372 
-
16375 
-
16376 
-
16377 /*//////////////////////////////////////////////////////////////////////////////
-
16379 
-
16380  Start of -include/epiworld//models/sis.hpp-
-
16381 
-
16384 
-
16385 
-
16386 #ifndef EPIWORLD_MODELS_SIS_HPP
-
16387 #define EPIWORLD_MODELS_SIS_HPP
+
16367 
+
16368 // A global action that updates a parameter in the model.
+
16377 template<typename TSeq>
+
16378 inline std::function<void(Model<TSeq>*)> globalevent_set_param(
+
16379  std::string param,
+
16380  double value
+
16381 ) {
+
16382 
+
16383  std::function<void(Model<TSeq>*)> fun = [value,param](
+
16384  Model<TSeq> * model
+
16385  ) -> void {
+
16386 
+
16387  model->set_param(param, value);
16388 
-
16397 template<typename TSeq = int>
-
16398 class ModelSIS : public epiworld::Model<TSeq>
-
16399 {
+
16389  return;
+
16390 
+
16391 
+
16392  };
+
16393 
+
16394  return fun;
+
16395 
+
16396 }
+
16397 #endif
+
16398 /*//////////////////////////////////////////////////////////////////////////////
16400 
-
16401 public:
+
16401  End of -include/epiworld//models/globalevents.hpp-
16402 
-
16403  static const int SUSCEPTIBLE = 0;
-
16404  static const int INFECTED = 1;
16405 
-
16406  ModelSIS() {};
-
16407 
-
16408  ModelSIS(
-
16409  ModelSIS<TSeq> & model,
-
16410  const std::string & vname,
-
16411  epiworld_double prevalence,
-
16412  epiworld_double transmission_rate,
-
16413  epiworld_double recovery_rate
-
16414  );
+
16406 
+
16407 /*//////////////////////////////////////////////////////////////////////////////
+
16409 
+
16410  Start of -include/epiworld//models/sis.hpp-
+
16411 
+
16414 
16415 
-
16416  ModelSIS(
-
16417  const std::string & vname,
-
16418  epiworld_double prevalence,
-
16419  epiworld_double transmission_rate,
-
16420  epiworld_double recovery_rate
-
16421  );
-
16422 
-
16423 };
-
16424 
-
16425 template<typename TSeq>
-
16426 inline ModelSIS<TSeq>::ModelSIS(
-
16427  ModelSIS<TSeq> & model,
-
16428  const std::string & vname,
-
16429  epiworld_double prevalence,
-
16430  epiworld_double transmission_rate,
-
16431  epiworld_double recovery_rate
-
16432  )
-
16433 {
-
16434 
-
16435  model.set_name("Susceptible-Infected-Susceptible (SIS)");
-
16436 
-
16437  // Adding statuses
-
16438  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
-
16439  model.add_state("Infected", epiworld::default_update_exposed<TSeq>);
-
16440 
-
16441  // Setting up parameters
-
16442  model.add_param(transmission_rate, "Transmission rate");
-
16443  model.add_param(recovery_rate, "Recovery rate");
-
16444 
-
16445  // Preparing the virus -------------------------------------------
-
16446  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
16447  virus.set_state(ModelSIS<TSeq>::INFECTED, ModelSIS<TSeq>::SUSCEPTIBLE, ModelSIS<TSeq>::SUSCEPTIBLE);
-
16448 
-
16449  virus.set_prob_infecting(&model("Transmission rate"));
-
16450  virus.set_prob_recovery(&model("Recovery rate"));
-
16451  virus.set_prob_death(0.0);
-
16452 
-
16453  model.add_virus(virus);
+
16416 #ifndef EPIWORLD_MODELS_SIS_HPP
+
16417 #define EPIWORLD_MODELS_SIS_HPP
+
16418 
+
16427 template<typename TSeq = int>
+
16428 class ModelSIS : public epiworld::Model<TSeq>
+
16429 {
+
16430 
+
16431 public:
+
16432 
+
16433  static const int SUSCEPTIBLE = 0;
+
16434  static const int INFECTED = 1;
+
16435 
+
16436  ModelSIS() {};
+
16437 
+
16438  ModelSIS(
+
16439  ModelSIS<TSeq> & model,
+
16440  const std::string & vname,
+
16441  epiworld_double prevalence,
+
16442  epiworld_double transmission_rate,
+
16443  epiworld_double recovery_rate
+
16444  );
+
16445 
+
16446  ModelSIS(
+
16447  const std::string & vname,
+
16448  epiworld_double prevalence,
+
16449  epiworld_double transmission_rate,
+
16450  epiworld_double recovery_rate
+
16451  );
+
16452 
+
16453 };
16454 
-
16455  return;
-
16456 
-
16457 }
-
16458 
-
16459 template<typename TSeq>
-
16460 inline ModelSIS<TSeq>::ModelSIS(
-
16461  const std::string & vname,
-
16462  epiworld_double prevalence,
-
16463  epiworld_double transmission_rate,
-
16464  epiworld_double recovery_rate
-
16465  )
-
16466 {
-
16467 
-
16468  ModelSIS<TSeq>(
-
16469  *this,
-
16470  vname,
-
16471  prevalence,
-
16472  transmission_rate,
-
16473  recovery_rate
-
16474  );
-
16475 
-
16476  return;
-
16477 
-
16478 }
-
16479 
-
16480 #endif
-
16481 /*//////////////////////////////////////////////////////////////////////////////
-
16483 
-
16484  End of -include/epiworld//models/sis.hpp-
-
16485 
+
16455 template<typename TSeq>
+
16456 inline ModelSIS<TSeq>::ModelSIS(
+
16457  ModelSIS<TSeq> & model,
+
16458  const std::string & vname,
+
16459  epiworld_double prevalence,
+
16460  epiworld_double transmission_rate,
+
16461  epiworld_double recovery_rate
+
16462  )
+
16463 {
+
16464 
+
16465  model.set_name("Susceptible-Infected-Susceptible (SIS)");
+
16466 
+
16467  // Adding statuses
+
16468  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
+
16469  model.add_state("Infected", epiworld::default_update_exposed<TSeq>);
+
16470 
+
16471  // Setting up parameters
+
16472  model.add_param(transmission_rate, "Transmission rate");
+
16473  model.add_param(recovery_rate, "Recovery rate");
+
16474 
+
16475  // Preparing the virus -------------------------------------------
+
16476  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
16477  virus.set_state(ModelSIS<TSeq>::INFECTED, ModelSIS<TSeq>::SUSCEPTIBLE, ModelSIS<TSeq>::SUSCEPTIBLE);
+
16478 
+
16479  virus.set_prob_infecting(&model("Transmission rate"));
+
16480  virus.set_prob_recovery(&model("Recovery rate"));
+
16481  virus.set_prob_death(0.0);
+
16482 
+
16483  model.add_virus(virus);
+
16484 
+
16485  return;
+
16486 
+
16487 }
16488 
-
16489 
-
16490 /*//////////////////////////////////////////////////////////////////////////////
-
16492 
-
16493  Start of -include/epiworld//models/sir.hpp-
-
16494 
+
16489 template<typename TSeq>
+
16490 inline ModelSIS<TSeq>::ModelSIS(
+
16491  const std::string & vname,
+
16492  epiworld_double prevalence,
+
16493  epiworld_double transmission_rate,
+
16494  epiworld_double recovery_rate
+
16495  )
+
16496 {
16497 
-
16498 
-
16499 #ifndef EPIWORLD_SIR_H
-
16500 #define EPIWORLD_SIR_H
-
16501 
-
16511 template<typename TSeq = int>
-
16512 class ModelSIR : public epiworld::Model<TSeq>
-
16513 {
-
16514 public:
+
16498  ModelSIS<TSeq>(
+
16499  *this,
+
16500  vname,
+
16501  prevalence,
+
16502  transmission_rate,
+
16503  recovery_rate
+
16504  );
+
16505 
+
16506  return;
+
16507 
+
16508 }
+
16509 
+
16510 #endif
+
16511 /*//////////////////////////////////////////////////////////////////////////////
+
16513 
+
16514  End of -include/epiworld//models/sis.hpp-
16515 
-
16516  ModelSIR() {};
-
16517 
-
16518  ModelSIR(
-
16519  ModelSIR<TSeq> & model,
-
16520  const std::string & vname,
-
16521  epiworld_double prevalence,
-
16522  epiworld_double transmission_rate,
-
16523  epiworld_double recovery_rate
-
16524  );
-
16525 
-
16526  ModelSIR(
-
16527  const std::string & vname,
-
16528  epiworld_double prevalence,
-
16529  epiworld_double transmission_rate,
-
16530  epiworld_double recovery_rate
-
16531  );
-
16532 
-
16538  ModelSIR<TSeq> & initial_states(
-
16539  std::vector< double > proportions_,
-
16540  std::vector< int > queue_ = {}
-
16541  );
-
16542 
-
16543 };
-
16544 
-
16545 template<typename TSeq>
-
16546 inline ModelSIR<TSeq>::ModelSIR(
-
16547  ModelSIR<TSeq> & model,
-
16548  const std::string & vname,
-
16549  epiworld_double prevalence,
-
16550  epiworld_double transmission_rate,
-
16551  epiworld_double recovery_rate
-
16552  )
-
16553 {
-
16554 
-
16555  // Adding statuses
-
16556  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
-
16557  model.add_state("Infected", epiworld::default_update_exposed<TSeq>);
-
16558  model.add_state("Recovered");
-
16559 
-
16560  // Setting up parameters
-
16561  model.add_param(recovery_rate, "Recovery rate");
-
16562  model.add_param(transmission_rate, "Transmission rate");
-
16563 
-
16564  // Preparing the virus -------------------------------------------
-
16565  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
16566  virus.set_state(1,2,2);
-
16567 
-
16568  virus.set_prob_recovery(&model("Recovery rate"));
-
16569  virus.set_prob_infecting(&model("Transmission rate"));
-
16570 
-
16571  model.add_virus(virus);
-
16572 
-
16573  model.set_name("Susceptible-Infected-Recovered (SIR)");
+
16518 
+
16519 
+
16520 /*//////////////////////////////////////////////////////////////////////////////
+
16522 
+
16523  Start of -include/epiworld//models/sir.hpp-
+
16524 
+
16527 
+
16528 
+
16529 #ifndef EPIWORLD_SIR_H
+
16530 #define EPIWORLD_SIR_H
+
16531 
+
16541 template<typename TSeq = int>
+
16542 class ModelSIR : public epiworld::Model<TSeq>
+
16543 {
+
16544 public:
+
16545 
+
16546  ModelSIR() {};
+
16547 
+
16548  ModelSIR(
+
16549  ModelSIR<TSeq> & model,
+
16550  const std::string & vname,
+
16551  epiworld_double prevalence,
+
16552  epiworld_double transmission_rate,
+
16553  epiworld_double recovery_rate
+
16554  );
+
16555 
+
16556  ModelSIR(
+
16557  const std::string & vname,
+
16558  epiworld_double prevalence,
+
16559  epiworld_double transmission_rate,
+
16560  epiworld_double recovery_rate
+
16561  );
+
16562 
+
16568  ModelSIR<TSeq> & initial_states(
+
16569  std::vector< double > proportions_,
+
16570  std::vector< int > queue_ = {}
+
16571  );
+
16572 
+
16573 };
16574 
-
16575  return;
-
16576 
-
16577 }
-
16578 
-
16579 template<typename TSeq>
-
16580 inline ModelSIR<TSeq>::ModelSIR(
-
16581  const std::string & vname,
-
16582  epiworld_double prevalence,
-
16583  epiworld_double transmission_rate,
-
16584  epiworld_double recovery_rate
-
16585  )
-
16586 {
-
16587 
-
16588  ModelSIR<TSeq>(
-
16589  *this,
-
16590  vname,
-
16591  prevalence,
-
16592  transmission_rate,
-
16593  recovery_rate
-
16594  );
-
16595 
-
16596  return;
-
16597 
-
16598 }
-
16599 
-
16600 template<typename TSeq>
-
16601 inline ModelSIR<TSeq> & ModelSIR<TSeq>::initial_states(
-
16602  std::vector< double > proportions_,
-
16603  std::vector< int > /* queue_ */
-
16604 ) {
-
16605 
- -
16607  create_init_function_sir<TSeq>(proportions_)
-
16608  ;
-
16609 
-
16610  return *this;
-
16611 
-
16612 }
-
16613 
-
16614 #endif
-
16615 /*//////////////////////////////////////////////////////////////////////////////
+
16575 template<typename TSeq>
+
16576 inline ModelSIR<TSeq>::ModelSIR(
+
16577  ModelSIR<TSeq> & model,
+
16578  const std::string & vname,
+
16579  epiworld_double prevalence,
+
16580  epiworld_double transmission_rate,
+
16581  epiworld_double recovery_rate
+
16582  )
+
16583 {
+
16584 
+
16585  // Adding statuses
+
16586  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
+
16587  model.add_state("Infected", epiworld::default_update_exposed<TSeq>);
+
16588  model.add_state("Recovered");
+
16589 
+
16590  // Setting up parameters
+
16591  model.add_param(recovery_rate, "Recovery rate");
+
16592  model.add_param(transmission_rate, "Transmission rate");
+
16593 
+
16594  // Preparing the virus -------------------------------------------
+
16595  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
16596  virus.set_state(1,2,2);
+
16597 
+
16598  virus.set_prob_recovery(&model("Recovery rate"));
+
16599  virus.set_prob_infecting(&model("Transmission rate"));
+
16600 
+
16601  model.add_virus(virus);
+
16602 
+
16603  model.set_name("Susceptible-Infected-Recovered (SIR)");
+
16604 
+
16605  return;
+
16606 
+
16607 }
+
16608 
+
16609 template<typename TSeq>
+
16610 inline ModelSIR<TSeq>::ModelSIR(
+
16611  const std::string & vname,
+
16612  epiworld_double prevalence,
+
16613  epiworld_double transmission_rate,
+
16614  epiworld_double recovery_rate
+
16615  )
+
16616 {
16617 
-
16618  End of -include/epiworld//models/sir.hpp-
-
16619 
-
16622 
-
16623 
-
16624 /*//////////////////////////////////////////////////////////////////////////////
-
16626 
-
16627  Start of -include/epiworld//models/seir.hpp-
-
16628 
-
16631 
-
16632 
-
16633 #ifndef EPIWORLD_MODELS_SEIR_HPP
-
16634 #define EPIWORLD_MODELS_SEIR_HPP
-
16635 
-
16646 template<typename TSeq = int>
-
16647 class ModelSEIR : public epiworld::Model<TSeq>
-
16648 {
+
16618  ModelSIR<TSeq>(
+
16619  *this,
+
16620  vname,
+
16621  prevalence,
+
16622  transmission_rate,
+
16623  recovery_rate
+
16624  );
+
16625 
+
16626  return;
+
16627 
+
16628 }
+
16629 
+
16630 template<typename TSeq>
+
16631 inline ModelSIR<TSeq> & ModelSIR<TSeq>::initial_states(
+
16632  std::vector< double > proportions_,
+
16633  std::vector< int > /* queue_ */
+
16634 ) {
+
16635 
+ +
16637  create_init_function_sir<TSeq>(proportions_)
+
16638  ;
+
16639 
+
16640  return *this;
+
16641 
+
16642 }
+
16643 
+
16644 #endif
+
16645 /*//////////////////////////////////////////////////////////////////////////////
+
16647 
+
16648  End of -include/epiworld//models/sir.hpp-
16649 
-
16650 public:
-
16651  static const int SUSCEPTIBLE = 0;
-
16652  static const int EXPOSED = 1;
-
16653  static const int INFECTED = 2;
-
16654  static const int REMOVED = 3;
-
16655 
-
16656  ModelSEIR() {};
-
16657 
-
16658  ModelSEIR(
-
16659  ModelSEIR<TSeq> & model,
-
16660  const std::string & vname,
-
16661  epiworld_double prevalence,
-
16662  epiworld_double transmission_rate,
-
16663  epiworld_double avg_incubation_days,
-
16664  epiworld_double recovery_rate
-
16665  );
-
16666 
-
16667  ModelSEIR(
-
16668  const std::string & vname,
-
16669  epiworld_double prevalence,
-
16670  epiworld_double transmission_rate,
-
16671  epiworld_double avg_incubation_days,
-
16672  epiworld_double recovery_rate
-
16673  );
-
16674 
-
16675  epiworld::UpdateFun<TSeq> update_exposed_seir = [](
-
16676  epiworld::Agent<TSeq> * p,
-
16677  epiworld::Model<TSeq> * m
-
16678  ) -> void {
+
16652 
+
16653 
+
16654 /*//////////////////////////////////////////////////////////////////////////////
+
16656 
+
16657  Start of -include/epiworld//models/seir.hpp-
+
16658 
+
16661 
+
16662 
+
16663 #ifndef EPIWORLD_MODELS_SEIR_HPP
+
16664 #define EPIWORLD_MODELS_SEIR_HPP
+
16665 
+
16676 template<typename TSeq = int>
+
16677 class ModelSEIR : public epiworld::Model<TSeq>
+
16678 {
16679 
-
16680  // Getting the virus
-
16681  auto v = p->get_virus();
-
16682 
-
16683  // Does the agent become infected?
-
16684  if (m->runif() < 1.0/(v->get_incubation(m)))
-
16685  p->change_state(m, ModelSEIR<TSeq>::INFECTED);
-
16686 
-
16687  return;
-
16688  };
-
16689 
-
16690 
-
16691  epiworld::UpdateFun<TSeq> update_infected_seir = [](
-
16692  epiworld::Agent<TSeq> * p,
-
16693  epiworld::Model<TSeq> * m
-
16694  ) -> void {
-
16695  // Does the agent recover?
-
16696  if (m->runif() < (m->par("Recovery rate")))
-
16697  p->rm_virus(m);
-
16698 
-
16699  return;
-
16700  };
-
16701 
-
16708  ModelSEIR<TSeq> & initial_states(
-
16709  std::vector< double > proportions_,
-
16710  std::vector< int > queue_ = {}
-
16711  );
+
16680 public:
+
16681  static const int SUSCEPTIBLE = 0;
+
16682  static const int EXPOSED = 1;
+
16683  static const int INFECTED = 2;
+
16684  static const int REMOVED = 3;
+
16685 
+
16686  ModelSEIR() {};
+
16687 
+
16688  ModelSEIR(
+
16689  ModelSEIR<TSeq> & model,
+
16690  const std::string & vname,
+
16691  epiworld_double prevalence,
+
16692  epiworld_double transmission_rate,
+
16693  epiworld_double avg_incubation_days,
+
16694  epiworld_double recovery_rate
+
16695  );
+
16696 
+
16697  ModelSEIR(
+
16698  const std::string & vname,
+
16699  epiworld_double prevalence,
+
16700  epiworld_double transmission_rate,
+
16701  epiworld_double avg_incubation_days,
+
16702  epiworld_double recovery_rate
+
16703  );
+
16704 
+
16705  epiworld::UpdateFun<TSeq> update_exposed_seir = [](
+
16706  epiworld::Agent<TSeq> * p,
+
16707  epiworld::Model<TSeq> * m
+
16708  ) -> void {
+
16709 
+
16710  // Getting the virus
+
16711  auto v = p->get_virus();
16712 
-
16713 };
-
16714 
-
16715 
-
16716 template<typename TSeq>
-
16717 inline ModelSEIR<TSeq>::ModelSEIR(
-
16718  ModelSEIR<TSeq> & model,
-
16719  const std::string & vname,
-
16720  epiworld_double prevalence,
-
16721  epiworld_double transmission_rate,
-
16722  epiworld_double avg_incubation_days,
-
16723  epiworld_double recovery_rate
-
16724  )
-
16725 {
-
16726 
-
16727  // Adding statuses
-
16728  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
-
16729  model.add_state("Exposed", model.update_exposed_seir);
-
16730  model.add_state("Infected", model.update_infected_seir);
-
16731  model.add_state("Removed");
-
16732 
-
16733  // Setting up parameters
-
16734  model.add_param(transmission_rate, "Transmission rate");
-
16735  model.add_param(avg_incubation_days, "Incubation days");
-
16736  model.add_param(recovery_rate, "Recovery rate");
-
16737 
-
16738  // Preparing the virus -------------------------------------------
-
16739  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
16740  virus.set_state(ModelSEIR<TSeq>::EXPOSED, ModelSEIR<TSeq>::REMOVED, ModelSEIR<TSeq>::REMOVED);
-
16741 
-
16742  virus.set_prob_infecting(&model("Transmission rate"));
-
16743  virus.set_incubation(&model("Incubation days"));
-
16744  virus.set_prob_recovery(&model("Recovery rate"));
-
16745 
-
16746  // Adding the tool and the virus
-
16747  model.add_virus(virus);
-
16748 
-
16749  model.set_name("Susceptible-Exposed-Infected-Removed (SEIR)");
-
16750 
-
16751  return;
-
16752 
-
16753 }
-
16754 
-
16755 template<typename TSeq>
-
16756 inline ModelSEIR<TSeq>::ModelSEIR(
-
16757  const std::string & vname,
-
16758  epiworld_double prevalence,
-
16759  epiworld_double transmission_rate,
-
16760  epiworld_double avg_incubation_days,
-
16761  epiworld_double recovery_rate
-
16762  )
-
16763 {
-
16764 
-
16765  ModelSEIR<TSeq>(
-
16766  *this,
-
16767  vname,
-
16768  prevalence,
-
16769  transmission_rate,
-
16770  avg_incubation_days,
-
16771  recovery_rate
-
16772  );
-
16773 
-
16774  return;
-
16775 
-
16776 }
-
16777 
-
16778 template<typename TSeq>
-
16779 inline ModelSEIR<TSeq> & ModelSEIR<TSeq>::initial_states(
-
16780  std::vector< double > proportions_,
-
16781  std::vector< int > /**/
-
16782 ) {
-
16783 
- -
16785  create_init_function_seir<TSeq>(proportions_)
-
16786  ;
-
16787 
-
16788  return *this;
-
16789 
-
16790 }
-
16791 
-
16792 #endif
-
16793 /*//////////////////////////////////////////////////////////////////////////////
-
16795 
-
16796  End of -include/epiworld//models/seir.hpp-
-
16797 
-
16800 
-
16801 
-
16802 /*//////////////////////////////////////////////////////////////////////////////
-
16804 
-
16805  Start of -include/epiworld//models/surveillance.hpp-
-
16806 
-
16809 
-
16810 
-
16811 #ifndef EPIWORLD_MODELS_SURVEILLANCE_HPP
-
16812 #define EPIWORLD_MODELS_SURVEILLANCE_HPP
-
16813 
-
16814 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
16815 class ModelSURV : public epiworld::Model<TSeq> {
-
16816 
-
16817 private:
-
16818  // state
-
16819  static const int SUSCEPTIBLE = 0;
-
16820  static const int LATENT = 1;
-
16821  static const int SYMPTOMATIC = 2;
-
16822  static const int SYMPTOMATIC_ISOLATED = 3; // sampled and discovered
-
16823  static const int ASYMPTOMATIC = 4;
-
16824  static const int ASYMPTOMATIC_ISOLATED = 5;
-
16825  static const int RECOVERED = 6;
-
16826  static const int REMOVED = 7;
+
16713  // Does the agent become infected?
+
16714  if (m->runif() < 1.0/(v->get_incubation(m)))
+
16715  p->change_state(m, ModelSEIR<TSeq>::INFECTED);
+
16716 
+
16717  return;
+
16718  };
+
16719 
+
16720 
+
16721  epiworld::UpdateFun<TSeq> update_infected_seir = [](
+
16722  epiworld::Agent<TSeq> * p,
+
16723  epiworld::Model<TSeq> * m
+
16724  ) -> void {
+
16725  // Does the agent recover?
+
16726  if (m->runif() < (m->par("Recovery rate")))
+
16727  p->rm_virus(m);
+
16728 
+
16729  return;
+
16730  };
+
16731 
+
16738  ModelSEIR<TSeq> & initial_states(
+
16739  std::vector< double > proportions_,
+
16740  std::vector< int > queue_ = {}
+
16741  );
+
16742 
+
16743 };
+
16744 
+
16745 
+
16746 template<typename TSeq>
+
16747 inline ModelSEIR<TSeq>::ModelSEIR(
+
16748  ModelSEIR<TSeq> & model,
+
16749  const std::string & vname,
+
16750  epiworld_double prevalence,
+
16751  epiworld_double transmission_rate,
+
16752  epiworld_double avg_incubation_days,
+
16753  epiworld_double recovery_rate
+
16754  )
+
16755 {
+
16756 
+
16757  // Adding statuses
+
16758  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
+
16759  model.add_state("Exposed", model.update_exposed_seir);
+
16760  model.add_state("Infected", model.update_infected_seir);
+
16761  model.add_state("Removed");
+
16762 
+
16763  // Setting up parameters
+
16764  model.add_param(transmission_rate, "Transmission rate");
+
16765  model.add_param(avg_incubation_days, "Incubation days");
+
16766  model.add_param(recovery_rate, "Recovery rate");
+
16767 
+
16768  // Preparing the virus -------------------------------------------
+
16769  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
16770  virus.set_state(ModelSEIR<TSeq>::EXPOSED, ModelSEIR<TSeq>::REMOVED, ModelSEIR<TSeq>::REMOVED);
+
16771 
+
16772  virus.set_prob_infecting(&model("Transmission rate"));
+
16773  virus.set_incubation(&model("Incubation days"));
+
16774  virus.set_prob_recovery(&model("Recovery rate"));
+
16775 
+
16776  // Adding the tool and the virus
+
16777  model.add_virus(virus);
+
16778 
+
16779  model.set_name("Susceptible-Exposed-Infected-Removed (SEIR)");
+
16780 
+
16781  return;
+
16782 
+
16783 }
+
16784 
+
16785 template<typename TSeq>
+
16786 inline ModelSEIR<TSeq>::ModelSEIR(
+
16787  const std::string & vname,
+
16788  epiworld_double prevalence,
+
16789  epiworld_double transmission_rate,
+
16790  epiworld_double avg_incubation_days,
+
16791  epiworld_double recovery_rate
+
16792  )
+
16793 {
+
16794 
+
16795  ModelSEIR<TSeq>(
+
16796  *this,
+
16797  vname,
+
16798  prevalence,
+
16799  transmission_rate,
+
16800  avg_incubation_days,
+
16801  recovery_rate
+
16802  );
+
16803 
+
16804  return;
+
16805 
+
16806 }
+
16807 
+
16808 template<typename TSeq>
+
16809 inline ModelSEIR<TSeq> & ModelSEIR<TSeq>::initial_states(
+
16810  std::vector< double > proportions_,
+
16811  std::vector< int > /**/
+
16812 ) {
+
16813 
+ +
16815  create_init_function_seir<TSeq>(proportions_)
+
16816  ;
+
16817 
+
16818  return *this;
+
16819 
+
16820 }
+
16821 
+
16822 #endif
+
16823 /*//////////////////////////////////////////////////////////////////////////////
+
16825 
+
16826  End of -include/epiworld//models/seir.hpp-
16827 
-
16828 public:
-
16829 
-
16871  ModelSURV() {};
-
16872 
-
16873  ModelSURV(
-
16874  ModelSURV<TSeq> & model,
-
16875  const std::string & vname,
-
16876  epiworld_fast_uint prevalence = 50,
-
16877  epiworld_double efficacy_vax = 0.9,
-
16878  epiworld_double latent_period = 3u,
-
16879  epiworld_double infect_period = 6u,
-
16880  epiworld_double prob_symptoms = 0.6,
-
16881  epiworld_double prop_vaccinated = 0.25,
-
16882  epiworld_double prop_vax_redux_transm = 0.5,
-
16883  epiworld_double prop_vax_redux_infect = 0.5,
-
16884  epiworld_double surveillance_prob = 0.001,
-
16885  epiworld_double prob_transmission = 1.0,
-
16886  epiworld_double prob_death = 0.001,
-
16887  epiworld_double prob_noreinfect = 0.9
-
16888  );
-
16889 
-
16890  ModelSURV(
-
16891  const std::string & vname,
-
16892  epiworld_fast_uint prevalence = 50,
-
16893  epiworld_double efficacy_vax = 0.9,
-
16894  epiworld_double latent_period = 3u,
-
16895  epiworld_double infect_period = 6u,
-
16896  epiworld_double prob_symptoms = 0.6,
-
16897  epiworld_double prop_vaccinated = 0.25,
-
16898  epiworld_double prop_vax_redux_transm = 0.5,
-
16899  epiworld_double prop_vax_redux_infect = 0.5,
-
16900  epiworld_double surveillance_prob = 0.001,
-
16901  epiworld_double prob_transmission = 1.0,
-
16902  epiworld_double prob_death = 0.001,
-
16903  epiworld_double prob_noreinfect = 0.9
-
16904  );
-
16906 
-
16907 };
-
16908 
-
16909 template<typename TSeq>
-
16910 inline ModelSURV<TSeq>::ModelSURV(
-
16911  ModelSURV<TSeq> & model,
-
16912  const std::string & vname,
-
16913  epiworld_fast_uint prevalence,
-
16914  epiworld_double efficacy_vax,
-
16915  epiworld_double latent_period,
-
16916  epiworld_double infect_period,
-
16917  epiworld_double prob_symptoms,
-
16918  epiworld_double prop_vaccinated,
-
16919  epiworld_double prop_vax_redux_transm,
-
16920  epiworld_double prop_vax_redux_infect,
-
16921  epiworld_double surveillance_prob,
-
16922  epiworld_double prob_transmission,
-
16923  epiworld_double prob_death,
-
16924  epiworld_double prob_noreinfect
-
16925  )
-
16926 {
-
16927 
-
16928  EPI_NEW_UPDATEFUN_LAMBDA(surveillance_update_susceptible, TSeq) {
-
16929 
-
16930  // This computes the prob of getting any neighbor variant
-
16931  epiworld_fast_uint nviruses_tmp = 0u;
-
16932  for (auto & neighbor: p->get_neighbors())
-
16933  {
-
16934 
-
16935  auto & v = neighbor->get_virus();
+
16830 
+
16831 
+
16832 /*//////////////////////////////////////////////////////////////////////////////
+
16834 
+
16835  Start of -include/epiworld//models/surveillance.hpp-
+
16836 
+
16839 
+
16840 
+
16841 #ifndef EPIWORLD_MODELS_SURVEILLANCE_HPP
+
16842 #define EPIWORLD_MODELS_SURVEILLANCE_HPP
+
16843 
+
16844 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
16845 class ModelSURV : public epiworld::Model<TSeq> {
+
16846 
+
16847 private:
+
16848  // state
+
16849  static const int SUSCEPTIBLE = 0;
+
16850  static const int LATENT = 1;
+
16851  static const int SYMPTOMATIC = 2;
+
16852  static const int SYMPTOMATIC_ISOLATED = 3; // sampled and discovered
+
16853  static const int ASYMPTOMATIC = 4;
+
16854  static const int ASYMPTOMATIC_ISOLATED = 5;
+
16855  static const int RECOVERED = 6;
+
16856  static const int REMOVED = 7;
+
16857 
+
16858 public:
+
16859 
+
16901  ModelSURV() {};
+
16902 
+
16903  ModelSURV(
+
16904  ModelSURV<TSeq> & model,
+
16905  const std::string & vname,
+
16906  epiworld_fast_uint prevalence = 50,
+
16907  epiworld_double efficacy_vax = 0.9,
+
16908  epiworld_double latent_period = 3u,
+
16909  epiworld_double infect_period = 6u,
+
16910  epiworld_double prob_symptoms = 0.6,
+
16911  epiworld_double prop_vaccinated = 0.25,
+
16912  epiworld_double prop_vax_redux_transm = 0.5,
+
16913  epiworld_double prop_vax_redux_infect = 0.5,
+
16914  epiworld_double surveillance_prob = 0.001,
+
16915  epiworld_double prob_transmission = 1.0,
+
16916  epiworld_double prob_death = 0.001,
+
16917  epiworld_double prob_noreinfect = 0.9
+
16918  );
+
16919 
+
16920  ModelSURV(
+
16921  const std::string & vname,
+
16922  epiworld_fast_uint prevalence = 50,
+
16923  epiworld_double efficacy_vax = 0.9,
+
16924  epiworld_double latent_period = 3u,
+
16925  epiworld_double infect_period = 6u,
+
16926  epiworld_double prob_symptoms = 0.6,
+
16927  epiworld_double prop_vaccinated = 0.25,
+
16928  epiworld_double prop_vax_redux_transm = 0.5,
+
16929  epiworld_double prop_vax_redux_infect = 0.5,
+
16930  epiworld_double surveillance_prob = 0.001,
+
16931  epiworld_double prob_transmission = 1.0,
+
16932  epiworld_double prob_death = 0.001,
+
16933  epiworld_double prob_noreinfect = 0.9
+
16934  );
16936 
-
16937  if (v == nullptr)
-
16938  continue;
-
16939 
-
16940  /* And it is a function of susceptibility_reduction as well */
-
16941  epiworld_double tmp_transmission =
-
16942  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
16943  v->get_prob_infecting(m) *
-
16944  (1.0 - neighbor->get_transmission_reduction(v, m))
-
16945  ;
-
16946 
-
16947  m->array_double_tmp[nviruses_tmp] = tmp_transmission;
-
16948  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
16949  }
-
16950 
-
16951  // No virus to compute on
-
16952  if (nviruses_tmp == 0)
-
16953  return;
-
16954 
-
16955  // Running the roulette
-
16956  int which = roulette(nviruses_tmp, m);
-
16957 
-
16958  if (which < 0)
-
16959  return;
-
16960 
-
16961  p->set_virus(*m->array_virus_tmp[which], m);
-
16962  return;
-
16963 
-
16964  };
-
16965 
-
16966 
-
16967  epiworld::UpdateFun<TSeq> surveillance_update_exposed =
-
16968  [](epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m) -> void
-
16969  {
-
16970 
-
16971  epiworld::VirusPtr<TSeq> & v = p->get_virus();
-
16972  epiworld_double p_die = v->get_prob_death(m) * (1.0 - p->get_death_reduction(v, m));
-
16973 
-
16974  epiworld_fast_uint days_since_exposed = m->today() - v->get_date();
-
16975  epiworld_fast_uint state = p->get_state();
-
16976 
-
16977  // Figuring out latent period
-
16978  if (v->get_data().size() == 0u)
-
16979  {
-
16980  epiworld_double latent_days = m->rgamma(m->par("Latent period"), 1.0);
-
16981  v->get_data().push_back(latent_days);
-
16982 
-
16983  v->get_data().push_back(
-
16984  m->rgamma(m->par("Infect period"), 1.0) + latent_days
-
16985  );
-
16986  }
-
16987 
-
16988  // If still latent, nothing happens
-
16989  if (days_since_exposed <= v->get_data()[0u])
-
16990  return;
-
16991 
-
16992  // If past days infected + latent, then bye.
-
16993  if (days_since_exposed >= v->get_data()[1u])
-
16994  {
-
16995  p->rm_virus(m);
-
16996  return;
-
16997  }
-
16998 
-
16999  // If it is infected, then it can be asymptomatic or symptomatic
-
17000  if (state == ModelSURV<TSeq>::LATENT)
-
17001  {
-
17002 
-
17003  // Will be symptomatic?
-
17004  if (EPI_RUNIF() < m->par("Prob of symptoms"))
-
17005  p->change_state(m, ModelSURV<TSeq>::SYMPTOMATIC);
-
17006  else
-
17007  p->change_state(m, ModelSURV<TSeq>::ASYMPTOMATIC);
-
17008 
-
17009  return;
-
17010 
-
17011  }
-
17012 
-
17013  // Otherwise, it can be removed
-
17014  if (EPI_RUNIF() < p_die)
-
17015  {
-
17016  p->change_state(m, ModelSURV<TSeq>::REMOVED, -1);
-
17017  return;
-
17018  }
-
17019 
-
17020  return;
+
16937 };
+
16938 
+
16939 template<typename TSeq>
+
16940 inline ModelSURV<TSeq>::ModelSURV(
+
16941  ModelSURV<TSeq> & model,
+
16942  const std::string & vname,
+
16943  epiworld_fast_uint prevalence,
+
16944  epiworld_double efficacy_vax,
+
16945  epiworld_double latent_period,
+
16946  epiworld_double infect_period,
+
16947  epiworld_double prob_symptoms,
+
16948  epiworld_double prop_vaccinated,
+
16949  epiworld_double prop_vax_redux_transm,
+
16950  epiworld_double prop_vax_redux_infect,
+
16951  epiworld_double surveillance_prob,
+
16952  epiworld_double prob_transmission,
+
16953  epiworld_double prob_death,
+
16954  epiworld_double prob_noreinfect
+
16955  )
+
16956 {
+
16957 
+
16958  EPI_NEW_UPDATEFUN_LAMBDA(surveillance_update_susceptible, TSeq) {
+
16959 
+
16960  // This computes the prob of getting any neighbor variant
+
16961  epiworld_fast_uint nviruses_tmp = 0u;
+
16962  for (auto & neighbor: p->get_neighbors())
+
16963  {
+
16964 
+
16965  auto & v = neighbor->get_virus();
+
16966 
+
16967  if (v == nullptr)
+
16968  continue;
+
16969 
+
16970  /* And it is a function of susceptibility_reduction as well */
+
16971  epiworld_double tmp_transmission =
+
16972  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
16973  v->get_prob_infecting(m) *
+
16974  (1.0 - neighbor->get_transmission_reduction(v, m))
+
16975  ;
+
16976 
+
16977  m->array_double_tmp[nviruses_tmp] = tmp_transmission;
+
16978  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
16979  }
+
16980 
+
16981  // No virus to compute on
+
16982  if (nviruses_tmp == 0)
+
16983  return;
+
16984 
+
16985  // Running the roulette
+
16986  int which = roulette(nviruses_tmp, m);
+
16987 
+
16988  if (which < 0)
+
16989  return;
+
16990 
+
16991  p->set_virus(*m->array_virus_tmp[which], m);
+
16992  return;
+
16993 
+
16994  };
+
16995 
+
16996 
+
16997  epiworld::UpdateFun<TSeq> surveillance_update_exposed =
+
16998  [](epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m) -> void
+
16999  {
+
17000 
+
17001  epiworld::VirusPtr<TSeq> & v = p->get_virus();
+
17002  epiworld_double p_die = v->get_prob_death(m) * (1.0 - p->get_death_reduction(v, m));
+
17003 
+
17004  epiworld_fast_uint days_since_exposed = m->today() - v->get_date();
+
17005  epiworld_fast_uint state = p->get_state();
+
17006 
+
17007  // Figuring out latent period
+
17008  if (v->get_data().size() == 0u)
+
17009  {
+
17010  epiworld_double latent_days = m->rgamma(m->par("Latent period"), 1.0);
+
17011  v->get_data().push_back(latent_days);
+
17012 
+
17013  v->get_data().push_back(
+
17014  m->rgamma(m->par("Infect period"), 1.0) + latent_days
+
17015  );
+
17016  }
+
17017 
+
17018  // If still latent, nothing happens
+
17019  if (days_since_exposed <= v->get_data()[0u])
+
17020  return;
17021 
-
17022  };
-
17023 
-
17024  std::vector< epiworld_fast_uint > exposed_state = {
-
17025  SYMPTOMATIC,
-
17026  SYMPTOMATIC_ISOLATED,
-
17027  ASYMPTOMATIC,
-
17028  ASYMPTOMATIC_ISOLATED,
-
17029  LATENT
-
17030  };
-
17031 
-
17032  epiworld::GlobalFun<TSeq> surveillance_program =
-
17033  [exposed_state](
- -
17035  ) -> void
-
17036  {
-
17037 
-
17038  // How many will we find
-
17039  std::binomial_distribution<> bdist(m->size(), m->par("Surveilance prob."));
-
17040  int nsampled = bdist(*m->get_rand_endgine());
-
17041 
-
17042  int to_go = nsampled + 1;
-
17043 
-
17044  epiworld_double ndetected = 0.0;
-
17045  epiworld_double ndetected_asympt = 0.0;
-
17046 
-
17047  auto & pop = m->get_agents();
-
17048  std::vector< bool > sampled(m->size(), false);
+
17022  // If past days infected + latent, then bye.
+
17023  if (days_since_exposed >= v->get_data()[1u])
+
17024  {
+
17025  p->rm_virus(m);
+
17026  return;
+
17027  }
+
17028 
+
17029  // If it is infected, then it can be asymptomatic or symptomatic
+
17030  if (state == ModelSURV<TSeq>::LATENT)
+
17031  {
+
17032 
+
17033  // Will be symptomatic?
+
17034  if (EPI_RUNIF() < m->par("Prob of symptoms"))
+
17035  p->change_state(m, ModelSURV<TSeq>::SYMPTOMATIC);
+
17036  else
+
17037  p->change_state(m, ModelSURV<TSeq>::ASYMPTOMATIC);
+
17038 
+
17039  return;
+
17040 
+
17041  }
+
17042 
+
17043  // Otherwise, it can be removed
+
17044  if (EPI_RUNIF() < p_die)
+
17045  {
+
17046  p->change_state(m, ModelSURV<TSeq>::REMOVED, -1);
+
17047  return;
+
17048  }
17049 
-
17050  while (to_go-- > 0)
-
17051  {
-
17052 
-
17053  // Who is the lucky one
-
17054  epiworld_fast_uint i = static_cast<epiworld_fast_uint>(std::floor(EPI_RUNIF() * m->size()));
-
17055 
-
17056  if (sampled[i])
-
17057  continue;
-
17058 
-
17059  sampled[i] = true;
-
17060  epiworld::Agent<TSeq> * p = &pop[i];
-
17061 
-
17062  // If still exposed for the next term
-
17063  if (epiworld::IN(p->get_state(), exposed_state ))
-
17064  {
-
17065 
-
17066  ndetected += 1.0;
-
17067  if (p->get_state() == ModelSURV<TSeq>::ASYMPTOMATIC)
-
17068  {
-
17069  ndetected_asympt += 1.0;
-
17070  p->change_state(m, ModelSURV<TSeq>::ASYMPTOMATIC_ISOLATED);
-
17071  }
-
17072  else
-
17073  {
-
17074  p->change_state(m, ModelSURV<TSeq>::SYMPTOMATIC_ISOLATED);
-
17075  }
-
17076 
-
17077  }
-
17078 
-
17079  }
-
17080 
-
17081  // Writing the user data
-
17082  std::vector< int > totals;
-
17083  m->get_db().get_today_total(nullptr,&totals);
-
17084  m->add_user_data(
-
17085  {
-
17086  static_cast<epiworld_double>(nsampled),
-
17087  ndetected,
-
17088  ndetected_asympt,
-
17089  static_cast<epiworld_double>(totals[ModelSURV<TSeq>::ASYMPTOMATIC])
-
17090  }
-
17091  );
-
17092 
-
17093 
-
17094  };
+
17050  return;
+
17051 
+
17052  };
+
17053 
+
17054  std::vector< epiworld_fast_uint > exposed_state = {
+
17055  SYMPTOMATIC,
+
17056  SYMPTOMATIC_ISOLATED,
+
17057  ASYMPTOMATIC,
+
17058  ASYMPTOMATIC_ISOLATED,
+
17059  LATENT
+
17060  };
+
17061 
+
17062  epiworld::GlobalFun<TSeq> surveillance_program =
+
17063  [exposed_state](
+ +
17065  ) -> void
+
17066  {
+
17067 
+
17068  // How many will we find
+
17069  std::binomial_distribution<> bdist(m->size(), m->par("Surveilance prob."));
+
17070  int nsampled = bdist(*m->get_rand_endgine());
+
17071 
+
17072  int to_go = nsampled + 1;
+
17073 
+
17074  epiworld_double ndetected = 0.0;
+
17075  epiworld_double ndetected_asympt = 0.0;
+
17076 
+
17077  auto & pop = m->get_agents();
+
17078  std::vector< bool > sampled(m->size(), false);
+
17079 
+
17080  while (to_go-- > 0)
+
17081  {
+
17082 
+
17083  // Who is the lucky one
+
17084  epiworld_fast_uint i = static_cast<epiworld_fast_uint>(std::floor(EPI_RUNIF() * m->size()));
+
17085 
+
17086  if (sampled[i])
+
17087  continue;
+
17088 
+
17089  sampled[i] = true;
+
17090  epiworld::Agent<TSeq> * p = &pop[i];
+
17091 
+
17092  // If still exposed for the next term
+
17093  if (epiworld::IN(p->get_state(), exposed_state ))
+
17094  {
17095 
-
17096  model.add_state("Susceptible", surveillance_update_susceptible);
-
17097  model.add_state("Latent", surveillance_update_exposed);
-
17098  model.add_state("Symptomatic", surveillance_update_exposed);
-
17099  model.add_state("Symptomatic isolated", surveillance_update_exposed);
-
17100  model.add_state("Asymptomatic", surveillance_update_exposed);
-
17101  model.add_state("Asymptomatic isolated", surveillance_update_exposed);
-
17102  model.add_state("Recovered");
-
17103  model.add_state("Removed");
-
17104 
-
17105  // General model parameters
-
17106  model.add_param(latent_period, "Latent period");
-
17107  model.add_param(infect_period, "Infect period");
-
17108  model.add_param(prob_symptoms, "Prob of symptoms");
-
17109  model.add_param(surveillance_prob, "Surveilance prob.");
-
17110  model.add_param(efficacy_vax, "Vax efficacy");
-
17111  model.add_param(prop_vax_redux_transm, "Vax redux transmission");
-
17112  model.add_param(prob_transmission, "Prob of transmission");
-
17113  model.add_param(prob_death, "Prob. death");
-
17114  model.add_param(prob_noreinfect, "Prob. no reinfect");
-
17115 
-
17116  // Virus ------------------------------------------------------------------
-
17117  epiworld::Virus<TSeq> covid("Covid19", prevalence, false);
-
17118  covid.set_state(LATENT, RECOVERED, REMOVED);
-
17119  covid.set_post_immunity(&model("Prob. no reinfect"));
-
17120  covid.set_prob_death(&model("Prob. death"));
-
17121 
-
17122  epiworld::VirusFun<TSeq> ptransmitfun = [](
- - - -
17126  ) -> epiworld_double
-
17127  {
-
17128  // No chance of infecting
-
17129  epiworld_fast_uint s = p->get_state();
-
17130  if (s == ModelSURV<TSeq>::LATENT)
-
17131  return static_cast<epiworld_double>(0.0);
- -
17133  return static_cast<epiworld_double>(0.0);
- -
17135  return static_cast<epiworld_double>(0.0);
-
17136 
-
17137  // Otherwise
-
17138  return m->par("Prob of transmission");
-
17139  };
-
17140 
-
17141  covid.set_prob_infecting_fun(ptransmitfun);
-
17142 
-
17143  model.add_virus(covid);
-
17144 
-
17145  model.set_user_data({"nsampled", "ndetected", "ndetected_asympt", "nasymptomatic"});
-
17146  model.add_globalevent(surveillance_program, "Surveilance program", -1);
-
17147 
-
17148  // Vaccine tool -----------------------------------------------------------
-
17149  epiworld::Tool<TSeq> vax("Vaccine", prop_vaccinated, true);
-
17150  vax.set_susceptibility_reduction(&model("Vax efficacy"));
-
17151  vax.set_transmission_reduction(&model("Vax redux transmission"));
-
17152 
-
17153  model.add_tool(vax);
-
17154 
-
17155  model.set_name("Surveillance");
-
17156 
-
17157  return;
-
17158 
-
17159 }
-
17160 
-
17161 template<typename TSeq>
- -
17163  const std::string & vname,
-
17164  epiworld_fast_uint prevalence,
-
17165  epiworld_double efficacy_vax,
-
17166  epiworld_double latent_period,
-
17167  epiworld_double infect_period,
-
17168  epiworld_double prob_symptoms,
-
17169  epiworld_double prop_vaccinated,
-
17170  epiworld_double prop_vax_redux_transm,
-
17171  epiworld_double prop_vax_redux_infect,
-
17172  epiworld_double surveillance_prob,
-
17173  epiworld_double prob_transmission,
-
17174  epiworld_double prob_death,
-
17175  epiworld_double prob_noreinfect
-
17176  )
-
17177 {
-
17178 
-
17179  ModelSURV(
-
17180  *this,
-
17181  vname,
-
17182  prevalence,
-
17183  efficacy_vax,
-
17184  latent_period,
-
17185  infect_period,
-
17186  prob_symptoms,
-
17187  prop_vaccinated,
-
17188  prop_vax_redux_transm,
-
17189  prop_vax_redux_infect,
-
17190  surveillance_prob,
-
17191  prob_transmission,
-
17192  prob_death,
-
17193  prob_noreinfect
-
17194  );
-
17195 
-
17196  return;
-
17197 
-
17198 }
-
17199 
-
17200 #endif
-
17201 /*//////////////////////////////////////////////////////////////////////////////
-
17203 
-
17204  End of -include/epiworld//models/surveillance.hpp-
-
17205 
-
17208 
-
17209 
-
17210 /*//////////////////////////////////////////////////////////////////////////////
-
17212 
-
17213  Start of -include/epiworld//models/sirconnected.hpp-
-
17214 
-
17217 
-
17218 
-
17219 #ifndef EPIWORLD_MODELS_SIRCONNECTED_HPP
-
17220 #define EPIWORLD_MODELS_SIRCONNECTED_HPP
-
17221 
-
17222 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
17223 class ModelSIRCONN : public epiworld::Model<TSeq>
-
17224 {
-
17225 
-
17226 private:
-
17227 
-
17228  std::vector< epiworld::Agent<TSeq> * > infected;
-
17229  void update_infected();
-
17230 
-
17231 public:
-
17232 
-
17233  static const int SUSCEPTIBLE = 0;
-
17234  static const int INFECTED = 1;
-
17235  static const int RECOVERED = 2;
-
17236 
-
17237 
-
17238  ModelSIRCONN() {};
+
17096  ndetected += 1.0;
+
17097  if (p->get_state() == ModelSURV<TSeq>::ASYMPTOMATIC)
+
17098  {
+
17099  ndetected_asympt += 1.0;
+
17100  p->change_state(m, ModelSURV<TSeq>::ASYMPTOMATIC_ISOLATED);
+
17101  }
+
17102  else
+
17103  {
+
17104  p->change_state(m, ModelSURV<TSeq>::SYMPTOMATIC_ISOLATED);
+
17105  }
+
17106 
+
17107  }
+
17108 
+
17109  }
+
17110 
+
17111  // Writing the user data
+
17112  std::vector< int > totals;
+
17113  m->get_db().get_today_total(nullptr,&totals);
+
17114  m->add_user_data(
+
17115  {
+
17116  static_cast<epiworld_double>(nsampled),
+
17117  ndetected,
+
17118  ndetected_asympt,
+
17119  static_cast<epiworld_double>(totals[ModelSURV<TSeq>::ASYMPTOMATIC])
+
17120  }
+
17121  );
+
17122 
+
17123 
+
17124  };
+
17125 
+
17126  model.add_state("Susceptible", surveillance_update_susceptible);
+
17127  model.add_state("Latent", surveillance_update_exposed);
+
17128  model.add_state("Symptomatic", surveillance_update_exposed);
+
17129  model.add_state("Symptomatic isolated", surveillance_update_exposed);
+
17130  model.add_state("Asymptomatic", surveillance_update_exposed);
+
17131  model.add_state("Asymptomatic isolated", surveillance_update_exposed);
+
17132  model.add_state("Recovered");
+
17133  model.add_state("Removed");
+
17134 
+
17135  // General model parameters
+
17136  model.add_param(latent_period, "Latent period");
+
17137  model.add_param(infect_period, "Infect period");
+
17138  model.add_param(prob_symptoms, "Prob of symptoms");
+
17139  model.add_param(surveillance_prob, "Surveilance prob.");
+
17140  model.add_param(efficacy_vax, "Vax efficacy");
+
17141  model.add_param(prop_vax_redux_transm, "Vax redux transmission");
+
17142  model.add_param(prob_transmission, "Prob of transmission");
+
17143  model.add_param(prob_death, "Prob. death");
+
17144  model.add_param(prob_noreinfect, "Prob. no reinfect");
+
17145 
+
17146  // Virus ------------------------------------------------------------------
+
17147  epiworld::Virus<TSeq> covid("Covid19", prevalence, false);
+
17148  covid.set_state(LATENT, RECOVERED, REMOVED);
+
17149  covid.set_post_immunity(&model("Prob. no reinfect"));
+
17150  covid.set_prob_death(&model("Prob. death"));
+
17151 
+
17152  epiworld::VirusFun<TSeq> ptransmitfun = [](
+ + + +
17156  ) -> epiworld_double
+
17157  {
+
17158  // No chance of infecting
+
17159  epiworld_fast_uint s = p->get_state();
+
17160  if (s == ModelSURV<TSeq>::LATENT)
+
17161  return static_cast<epiworld_double>(0.0);
+ +
17163  return static_cast<epiworld_double>(0.0);
+ +
17165  return static_cast<epiworld_double>(0.0);
+
17166 
+
17167  // Otherwise
+
17168  return m->par("Prob of transmission");
+
17169  };
+
17170 
+
17171  covid.set_prob_infecting_fun(ptransmitfun);
+
17172 
+
17173  model.add_virus(covid);
+
17174 
+
17175  model.set_user_data({"nsampled", "ndetected", "ndetected_asympt", "nasymptomatic"});
+
17176  model.add_globalevent(surveillance_program, "Surveilance program", -1);
+
17177 
+
17178  // Vaccine tool -----------------------------------------------------------
+
17179  epiworld::Tool<TSeq> vax("Vaccine", prop_vaccinated, true);
+
17180  vax.set_susceptibility_reduction(&model("Vax efficacy"));
+
17181  vax.set_transmission_reduction(&model("Vax redux transmission"));
+
17182 
+
17183  model.add_tool(vax);
+
17184 
+
17185  model.set_name("Surveillance");
+
17186 
+
17187  return;
+
17188 
+
17189 }
+
17190 
+
17191 template<typename TSeq>
+ +
17193  const std::string & vname,
+
17194  epiworld_fast_uint prevalence,
+
17195  epiworld_double efficacy_vax,
+
17196  epiworld_double latent_period,
+
17197  epiworld_double infect_period,
+
17198  epiworld_double prob_symptoms,
+
17199  epiworld_double prop_vaccinated,
+
17200  epiworld_double prop_vax_redux_transm,
+
17201  epiworld_double prop_vax_redux_infect,
+
17202  epiworld_double surveillance_prob,
+
17203  epiworld_double prob_transmission,
+
17204  epiworld_double prob_death,
+
17205  epiworld_double prob_noreinfect
+
17206  )
+
17207 {
+
17208 
+
17209  ModelSURV(
+
17210  *this,
+
17211  vname,
+
17212  prevalence,
+
17213  efficacy_vax,
+
17214  latent_period,
+
17215  infect_period,
+
17216  prob_symptoms,
+
17217  prop_vaccinated,
+
17218  prop_vax_redux_transm,
+
17219  prop_vax_redux_infect,
+
17220  surveillance_prob,
+
17221  prob_transmission,
+
17222  prob_death,
+
17223  prob_noreinfect
+
17224  );
+
17225 
+
17226  return;
+
17227 
+
17228 }
+
17229 
+
17230 #endif
+
17231 /*//////////////////////////////////////////////////////////////////////////////
+
17233 
+
17234  End of -include/epiworld//models/surveillance.hpp-
+
17235 
+
17238 
17239 
-
17240  ModelSIRCONN(
-
17241  ModelSIRCONN<TSeq> & model,
-
17242  const std::string & vname,
-
17243  epiworld_fast_uint n,
-
17244  epiworld_double prevalence,
-
17245  epiworld_double contact_rate,
-
17246  epiworld_double transmission_rate,
-
17247  epiworld_double recovery_rate
-
17248  );
-
17249 
-
17250  ModelSIRCONN(
-
17251  const std::string & vname,
-
17252  epiworld_fast_uint n,
-
17253  epiworld_double prevalence,
-
17254  epiworld_double contact_rate,
-
17255  epiworld_double transmission_rate,
-
17256  epiworld_double recovery_rate
-
17257  );
-
17258 
-
17259  ModelSIRCONN<TSeq> & run(
-
17260  epiworld_fast_uint ndays,
-
17261  int seed = -1
-
17262  );
-
17263 
-
17264  void reset();
-
17265 
-
17266  Model<TSeq> * clone_ptr();
-
17267 
-
17273  ModelSIRCONN<TSeq> & initial_states(
-
17274  std::vector< double > proportions_,
-
17275  std::vector< int > queue_ = {}
-
17276  );
-
17277 
-
17282  size_t get_n_infected() const
-
17283  {
-
17284  return infected.size();
-
17285  }
-
17286 
-
17287  /***
-
17288  * @brief Compute expected generation time
-
17289  * @param max_days Maximum number of days.
-
17290  * @param max_contacts Maximum number of contacts.
-
17291  */
-
17292  std::vector< double > generation_time_expected(
-
17293  int max_days = 200,
-
17294  int max_contacts = 200
-
17295  ) const;
-
17296 
-
17297 };
-
17298 
-
17299 template<typename TSeq>
- -
17301 {
-
17302 
-
17303  infected.clear();
-
17304  infected.reserve(this->size());
-
17305 
-
17306  for (auto & p : this->get_agents())
-
17307  {
-
17308  if (p.get_state() == ModelSIRCONN<TSeq>::INFECTED)
-
17309  {
-
17310  infected.push_back(&p);
-
17311  }
-
17312  }
-
17313 
- -
17315  this->get_n_infected(),
-
17316  static_cast<double>(Model<TSeq>::par("Contact rate"))/
-
17317  static_cast<double>(Model<TSeq>::size())
-
17318  );
-
17319 
-
17320  return;
-
17321 
-
17322 }
-
17323 
-
17324 template<typename TSeq>
- -
17326  epiworld_fast_uint ndays,
-
17327  int seed
-
17328 )
-
17329 {
-
17330 
-
17331  Model<TSeq>::run(ndays, seed);
-
17332  return *this;
-
17333 
-
17334 }
+
17240 /*//////////////////////////////////////////////////////////////////////////////
+
17242 
+
17243  Start of -include/epiworld//models/sirconnected.hpp-
+
17244 
+
17247 
+
17248 
+
17249 #ifndef EPIWORLD_MODELS_SIRCONNECTED_HPP
+
17250 #define EPIWORLD_MODELS_SIRCONNECTED_HPP
+
17251 
+
17252 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
17253 class ModelSIRCONN : public epiworld::Model<TSeq>
+
17254 {
+
17255 
+
17256 private:
+
17257 
+
17258  std::vector< epiworld::Agent<TSeq> * > infected;
+
17259  void update_infected();
+
17260 
+
17261 public:
+
17262 
+
17263  static const int SUSCEPTIBLE = 0;
+
17264  static const int INFECTED = 1;
+
17265  static const int RECOVERED = 2;
+
17266 
+
17267 
+
17268  ModelSIRCONN() {};
+
17269 
+
17270  ModelSIRCONN(
+
17271  ModelSIRCONN<TSeq> & model,
+
17272  const std::string & vname,
+
17273  epiworld_fast_uint n,
+
17274  epiworld_double prevalence,
+
17275  epiworld_double contact_rate,
+
17276  epiworld_double transmission_rate,
+
17277  epiworld_double recovery_rate
+
17278  );
+
17279 
+
17280  ModelSIRCONN(
+
17281  const std::string & vname,
+
17282  epiworld_fast_uint n,
+
17283  epiworld_double prevalence,
+
17284  epiworld_double contact_rate,
+
17285  epiworld_double transmission_rate,
+
17286  epiworld_double recovery_rate
+
17287  );
+
17288 
+
17289  ModelSIRCONN<TSeq> & run(
+
17290  epiworld_fast_uint ndays,
+
17291  int seed = -1
+
17292  );
+
17293 
+
17294  void reset();
+
17295 
+
17296  Model<TSeq> * clone_ptr();
+
17297 
+
17303  ModelSIRCONN<TSeq> & initial_states(
+
17304  std::vector< double > proportions_,
+
17305  std::vector< int > queue_ = {}
+
17306  );
+
17307 
+
17312  size_t get_n_infected() const
+
17313  {
+
17314  return infected.size();
+
17315  }
+
17316 
+
17317  /***
+
17318  * @brief Compute expected generation time
+
17319  * @param max_days Maximum number of days.
+
17320  * @param max_contacts Maximum number of contacts.
+
17321  */
+
17322  std::vector< double > generation_time_expected(
+
17323  int max_days = 200,
+
17324  int max_contacts = 200
+
17325  ) const;
+
17326 
+
17327 };
+
17328 
+
17329 template<typename TSeq>
+ +
17331 {
+
17332 
+
17333  infected.clear();
+
17334  infected.reserve(this->size());
17335 
-
17336 template<typename TSeq>
- -
17338 {
-
17339 
- -
17341 
-
17342  this->update_infected();
+
17336  for (auto & p : this->get_agents())
+
17337  {
+
17338  if (p.get_state() == ModelSIRCONN<TSeq>::INFECTED)
+
17339  {
+
17340  infected.push_back(&p);
+
17341  }
+
17342  }
17343 
-
17344  return;
-
17345 
-
17346 }
-
17347 
-
17348 template<typename TSeq>
- -
17350 {
-
17351 
- -
17353  *dynamic_cast<const ModelSIRCONN<TSeq>*>(this)
-
17354  );
-
17355 
-
17356  return dynamic_cast< Model<TSeq> *>(ptr);
-
17357 
-
17358 }
-
17359 
-
17370 template<typename TSeq>
- -
17372  ModelSIRCONN<TSeq> & model,
-
17373  const std::string & vname,
-
17374  epiworld_fast_uint n,
-
17375  epiworld_double prevalence,
-
17376  epiworld_double contact_rate,
-
17377  epiworld_double transmission_rate,
-
17378  epiworld_double recovery_rate
-
17379  // epiworld_double prob_reinfection
-
17380  )
-
17381 {
-
17382 
-
17383  epiworld::UpdateFun<TSeq> update_susceptible = [](
- -
17385  ) -> void
-
17386  {
+ +
17345  this->get_n_infected(),
+
17346  static_cast<double>(Model<TSeq>::par("Contact rate"))/
+
17347  static_cast<double>(Model<TSeq>::size())
+
17348  );
+
17349 
+
17350  return;
+
17351 
+
17352 }
+
17353 
+
17354 template<typename TSeq>
+ +
17356  epiworld_fast_uint ndays,
+
17357  int seed
+
17358 )
+
17359 {
+
17360 
+
17361  Model<TSeq>::run(ndays, seed);
+
17362  return *this;
+
17363 
+
17364 }
+
17365 
+
17366 template<typename TSeq>
+ +
17368 {
+
17369 
+ +
17371 
+
17372  this->update_infected();
+
17373 
+
17374  return;
+
17375 
+
17376 }
+
17377 
+
17378 template<typename TSeq>
+ +
17380 {
+
17381 
+ +
17383  *dynamic_cast<const ModelSIRCONN<TSeq>*>(this)
+
17384  );
+
17385 
+
17386  return dynamic_cast< Model<TSeq> *>(ptr);
17387 
-
17388  int ndraw = m->rbinom();
+
17388 }
17389 
-
17390  if (ndraw == 0)
-
17391  return;
-
17392 
-
17393  ModelSIRCONN<TSeq> * model = dynamic_cast<ModelSIRCONN<TSeq> *>(m);
-
17394  size_t ninfected = model->get_n_infected();
-
17395 
-
17396  // Drawing from the set
-
17397  int nviruses_tmp = 0;
-
17398  for (int i = 0; i < ndraw; ++i)
-
17399  {
-
17400  // Now selecting who is transmitting the disease
-
17401  int which = static_cast<int>(
-
17402  std::floor(ninfected * m->runif())
-
17403  );
-
17404 
-
17405  /* There is a bug in which runif() returns 1.0. It is rare, but
-
17406  * we saw it here. See the Notes section in the C++ manual
-
17407  * https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/random/uniform_real_distribution&oldid=133329
-
17408  * And the reported bug in GCC:
-
17409  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
-
17410  *
-
17411  */
-
17412  if (which == static_cast<int>(ninfected))
-
17413  --which;
-
17414 
-
17415  epiworld::Agent<TSeq> & neighbor = *model->infected[which];
-
17416 
-
17417  // Can't sample itself
-
17418  if (neighbor.get_id() == p->get_id())
-
17419  continue;
-
17420 
-
17421  // The neighbor is infected because it is on the list!
-
17422  if (neighbor.get_virus() == nullptr)
-
17423  continue;
-
17424 
-
17425  auto & v = neighbor.get_virus();
-
17426 
-
17427  #ifdef EPI_DEBUG
-
17428  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
-
17429  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
17430  #endif
-
17431 
-
17432  /* And it is a function of susceptibility_reduction as well */
-
17433  m->array_double_tmp[nviruses_tmp] =
-
17434  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
17435  v->get_prob_infecting(m) *
-
17436  (1.0 - neighbor.get_transmission_reduction(v, m))
-
17437  ;
-
17438 
-
17439  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
17440 
-
17441  }
-
17442 
-
17443  // No virus to compute
-
17444  if (nviruses_tmp == 0u)
-
17445  return;
+
17400 template<typename TSeq>
+ +
17402  ModelSIRCONN<TSeq> & model,
+
17403  const std::string & vname,
+
17404  epiworld_fast_uint n,
+
17405  epiworld_double prevalence,
+
17406  epiworld_double contact_rate,
+
17407  epiworld_double transmission_rate,
+
17408  epiworld_double recovery_rate
+
17409  // epiworld_double prob_reinfection
+
17410  )
+
17411 {
+
17412 
+
17413  epiworld::UpdateFun<TSeq> update_susceptible = [](
+ +
17415  ) -> void
+
17416  {
+
17417 
+
17418  int ndraw = m->rbinom();
+
17419 
+
17420  if (ndraw == 0)
+
17421  return;
+
17422 
+
17423  ModelSIRCONN<TSeq> * model = dynamic_cast<ModelSIRCONN<TSeq> *>(m);
+
17424  size_t ninfected = model->get_n_infected();
+
17425 
+
17426  // Drawing from the set
+
17427  int nviruses_tmp = 0;
+
17428  for (int i = 0; i < ndraw; ++i)
+
17429  {
+
17430  // Now selecting who is transmitting the disease
+
17431  int which = static_cast<int>(
+
17432  std::floor(ninfected * m->runif())
+
17433  );
+
17434 
+
17435  /* There is a bug in which runif() returns 1.0. It is rare, but
+
17436  * we saw it here. See the Notes section in the C++ manual
+
17437  * https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/random/uniform_real_distribution&oldid=133329
+
17438  * And the reported bug in GCC:
+
17439  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
+
17440  *
+
17441  */
+
17442  if (which == static_cast<int>(ninfected))
+
17443  --which;
+
17444 
+
17445  epiworld::Agent<TSeq> & neighbor = *model->infected[which];
17446 
-
17447  // Running the roulette
-
17448  int which = roulette(nviruses_tmp, m);
-
17449 
-
17450  if (which < 0)
-
17451  return;
-
17452 
-
17453  p->set_virus(*m->array_virus_tmp[which], m);
+
17447  // Can't sample itself
+
17448  if (neighbor.get_id() == p->get_id())
+
17449  continue;
+
17450 
+
17451  // The neighbor is infected because it is on the list!
+
17452  if (neighbor.get_virus() == nullptr)
+
17453  continue;
17454 
-
17455  return;
+
17455  auto & v = neighbor.get_virus();
17456 
-
17457  };
-
17458 
-
17459 
-
17460  epiworld::UpdateFun<TSeq> update_infected = [](
- -
17462  ) -> void {
-
17463 
-
17464  auto state = p->get_state();
-
17465 
-
17466  if (state == ModelSIRCONN<TSeq>::INFECTED)
-
17467  {
-
17468 
-
17469 
-
17470  // Odd: Die, Even: Recover
-
17471  epiworld_fast_uint n_events = 0u;
-
17472  // Recover
-
17473  m->array_double_tmp[n_events++] =
-
17474  1.0 - (1.0 - p->get_virus()->get_prob_recovery(m)) *
-
17475  (1.0 - p->get_recovery_enhancer(p->get_virus(), m));
+
17457  #ifdef EPI_DEBUG
+
17458  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
+
17459  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
17460  #endif
+
17461 
+
17462  /* And it is a function of susceptibility_reduction as well */
+
17463  m->array_double_tmp[nviruses_tmp] =
+
17464  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
17465  v->get_prob_infecting(m) *
+
17466  (1.0 - neighbor.get_transmission_reduction(v, m))
+
17467  ;
+
17468 
+
17469  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
17470 
+
17471  }
+
17472 
+
17473  // No virus to compute
+
17474  if (nviruses_tmp == 0u)
+
17475  return;
17476 
-
17477  #ifdef EPI_DEBUG
-
17478  if (n_events == 0u)
-
17479  {
-
17480  printf_epiworld(
-
17481  "[epi-debug] agent %i has 0 possible events!!\n",
-
17482  static_cast<int>(p->get_id())
-
17483  );
-
17484  throw std::logic_error("Zero events in exposed.");
-
17485  }
-
17486  #else
-
17487  if (n_events == 0u)
-
17488  return;
-
17489  #endif
-
17490 
-
17491 
-
17492  // Running the roulette
-
17493  int which = roulette(n_events, m);
-
17494 
-
17495  if (which < 0)
-
17496  return;
-
17497 
-
17498  // Which roulette happen?
-
17499  p->rm_virus(m);
-
17500 
-
17501  return ;
-
17502 
-
17503  } else
-
17504  throw std::logic_error(
-
17505  "This function can only be applied to infected individuals. (SIR)"
-
17506  ) ;
-
17507 
-
17508  return;
-
17509 
-
17510  };
-
17511 
-
17512  // state
-
17513  model.add_state("Susceptible", update_susceptible);
-
17514  model.add_state("Infected", update_infected);
-
17515  model.add_state("Recovered");
-
17516 
-
17517  // Setting up parameters
-
17518  model.add_param(contact_rate, "Contact rate");
-
17519  model.add_param(transmission_rate, "Transmission rate");
-
17520  model.add_param(recovery_rate, "Recovery rate");
-
17521  // model.add_param(prob_reinfection, "Prob. Reinfection");
-
17522 
-
17523  // Adding update function
-
17524  epiworld::GlobalFun<TSeq> update = [](epiworld::Model<TSeq> * m) -> void
-
17525  {
-
17526  ModelSIRCONN<TSeq> * model = dynamic_cast<ModelSIRCONN<TSeq> *>(m);
-
17527  model->update_infected();
-
17528 
-
17529  return;
-
17530  };
-
17531 
-
17532  model.add_globalevent(update, "Update infected individuals");
-
17533 
-
17534  // Preparing the virus -------------------------------------------
-
17535  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
17536  virus.set_state(1, 2, 2);
-
17537  virus.set_prob_infecting(&model("Transmission rate"));
-
17538  virus.set_prob_recovery(&model("Recovery rate"));
+
17477  // Running the roulette
+
17478  int which = roulette(nviruses_tmp, m);
+
17479 
+
17480  if (which < 0)
+
17481  return;
+
17482 
+
17483  p->set_virus(*m->array_virus_tmp[which], m);
+
17484 
+
17485  return;
+
17486 
+
17487  };
+
17488 
+
17489 
+
17490  epiworld::UpdateFun<TSeq> update_infected = [](
+ +
17492  ) -> void {
+
17493 
+
17494  auto state = p->get_state();
+
17495 
+
17496  if (state == ModelSIRCONN<TSeq>::INFECTED)
+
17497  {
+
17498 
+
17499 
+
17500  // Odd: Die, Even: Recover
+
17501  epiworld_fast_uint n_events = 0u;
+
17502  // Recover
+
17503  m->array_double_tmp[n_events++] =
+
17504  1.0 - (1.0 - p->get_virus()->get_prob_recovery(m)) *
+
17505  (1.0 - p->get_recovery_enhancer(p->get_virus(), m));
+
17506 
+
17507  #ifdef EPI_DEBUG
+
17508  if (n_events == 0u)
+
17509  {
+
17510  printf_epiworld(
+
17511  "[epi-debug] agent %i has 0 possible events!!\n",
+
17512  static_cast<int>(p->get_id())
+
17513  );
+
17514  throw std::logic_error("Zero events in exposed.");
+
17515  }
+
17516  #else
+
17517  if (n_events == 0u)
+
17518  return;
+
17519  #endif
+
17520 
+
17521 
+
17522  // Running the roulette
+
17523  int which = roulette(n_events, m);
+
17524 
+
17525  if (which < 0)
+
17526  return;
+
17527 
+
17528  // Which roulette happen?
+
17529  p->rm_virus(m);
+
17530 
+
17531  return ;
+
17532 
+
17533  } else
+
17534  throw std::logic_error(
+
17535  "This function can only be applied to infected individuals. (SIR)"
+
17536  ) ;
+
17537 
+
17538  return;
17539 
-
17540  model.add_virus(virus);
+
17540  };
17541 
-
17542  model.queuing_off(); // No queuing need
-
17543 
-
17544  model.agents_empty_graph(n);
-
17545 
-
17546  model.set_name("Susceptible-Infected-Removed (SIR) (connected)");
-
17547 
-
17548  return;
-
17549 
-
17550 }
-
17551 
-
17552 template<typename TSeq>
- -
17554  const std::string & vname,
-
17555  epiworld_fast_uint n,
-
17556  epiworld_double prevalence,
-
17557  epiworld_double contact_rate,
-
17558  epiworld_double transmission_rate,
-
17559  epiworld_double recovery_rate
-
17560  )
-
17561 {
-
17562 
-
17563  ModelSIRCONN(
-
17564  *this,
-
17565  vname,
-
17566  n,
-
17567  prevalence,
-
17568  contact_rate,
-
17569  transmission_rate,
-
17570  recovery_rate
-
17571  );
-
17572 
-
17573  return;
-
17574 
-
17575 }
-
17576 
-
17577 template<typename TSeq>
- -
17579  std::vector< double > proportions_,
-
17580  std::vector< int >
-
17581 ) {
-
17582 
- -
17584  create_init_function_sir<TSeq>(proportions_)
-
17585  ;
-
17586 
-
17587  return *this;
-
17588 
-
17589 }
-
17590 
-
17591 template<typename TSeq>
-
17592 inline std::vector< double > ModelSIRCONN<TSeq>::generation_time_expected(
-
17593  int max_days,
-
17594  int max_contacts
-
17595 ) const
-
17596 {
-
17597 
-
17598  // Retrieving total counts
-
17599  std::vector< int > h_date;
-
17600  std::vector< std::string > h_state;
-
17601  std::vector< int > h_counts;
-
17602  const auto this_const = dynamic_cast<const ModelSIRCONN<TSeq> *>(this);
-
17603  this_const->get_db().get_hist_total(
-
17604  &h_date,
-
17605  &h_state,
-
17606  &h_counts
-
17607  );
-
17608 
-
17609  // Retrieving information on susceptibles
-
17610  std::vector< double > S(this_const->get_ndays(), 0.0);
-
17611  for (size_t i = 0; i < h_date.size(); ++i)
-
17612  {
-
17613  if (h_state[i] == "Susceptible")
-
17614  S[h_date[i]] += h_counts[i];
-
17615  }
+
17542  // state
+
17543  model.add_state("Susceptible", update_susceptible);
+
17544  model.add_state("Infected", update_infected);
+
17545  model.add_state("Recovered");
+
17546 
+
17547  // Setting up parameters
+
17548  model.add_param(contact_rate, "Contact rate");
+
17549  model.add_param(transmission_rate, "Transmission rate");
+
17550  model.add_param(recovery_rate, "Recovery rate");
+
17551  // model.add_param(prob_reinfection, "Prob. Reinfection");
+
17552 
+
17553  // Adding update function
+
17554  epiworld::GlobalFun<TSeq> update = [](epiworld::Model<TSeq> * m) -> void
+
17555  {
+
17556  ModelSIRCONN<TSeq> * model = dynamic_cast<ModelSIRCONN<TSeq> *>(m);
+
17557  model->update_infected();
+
17558 
+
17559  return;
+
17560  };
+
17561 
+
17562  model.add_globalevent(update, "Update infected individuals");
+
17563 
+
17564  // Preparing the virus -------------------------------------------
+
17565  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
17566  virus.set_state(1, 2, 2);
+
17567  virus.set_prob_infecting(&model("Transmission rate"));
+
17568  virus.set_prob_recovery(&model("Recovery rate"));
+
17569 
+
17570  model.add_virus(virus);
+
17571 
+
17572  model.queuing_off(); // No queuing need
+
17573 
+
17574  model.agents_empty_graph(n);
+
17575 
+
17576  model.set_name("Susceptible-Infected-Removed (SIR) (connected)");
+
17577 
+
17578  return;
+
17579 
+
17580 }
+
17581 
+
17582 template<typename TSeq>
+ +
17584  const std::string & vname,
+
17585  epiworld_fast_uint n,
+
17586  epiworld_double prevalence,
+
17587  epiworld_double contact_rate,
+
17588  epiworld_double transmission_rate,
+
17589  epiworld_double recovery_rate
+
17590  )
+
17591 {
+
17592 
+
17593  ModelSIRCONN(
+
17594  *this,
+
17595  vname,
+
17596  n,
+
17597  prevalence,
+
17598  contact_rate,
+
17599  transmission_rate,
+
17600  recovery_rate
+
17601  );
+
17602 
+
17603  return;
+
17604 
+
17605 }
+
17606 
+
17607 template<typename TSeq>
+ +
17609  std::vector< double > proportions_,
+
17610  std::vector< int >
+
17611 ) {
+
17612 
+ +
17614  create_init_function_sir<TSeq>(proportions_)
+
17615  ;
17616 
-
17617  // The generation time in the SIR model starts from 1, as agents
-
17618  // spend at least one day in the infected state before starting
-
17619  // transmitting.
-
17620  std::vector< double > gen_times(this_const->get_ndays(), 1.0);
-
17621  double p_c = this_const->par("Contact rate")/this_const->size();
-
17622  double p_i = this_const->par("Transmission rate");
-
17623  double p_r = this_const->par("Recovery rate");
-
17624  for (size_t i = 0u; i < this_const->get_ndays(); ++i)
-
17625  {
-
17626  gen_times[i] = gen_int_mean(
-
17627  S[i],
-
17628  p_c,
-
17629  p_i,
-
17630  p_r,
-
17631  max_days,
-
17632  max_contacts
-
17633  );
-
17634 
-
17635  }
-
17636 
-
17637  return gen_times;
+
17617  return *this;
+
17618 
+
17619 }
+
17620 
+
17621 template<typename TSeq>
+
17622 inline std::vector< double > ModelSIRCONN<TSeq>::generation_time_expected(
+
17623  int max_days,
+
17624  int max_contacts
+
17625 ) const
+
17626 {
+
17627 
+
17628  // Retrieving total counts
+
17629  std::vector< int > h_date;
+
17630  std::vector< std::string > h_state;
+
17631  std::vector< int > h_counts;
+
17632  const auto this_const = dynamic_cast<const ModelSIRCONN<TSeq> *>(this);
+
17633  this_const->get_db().get_hist_total(
+
17634  &h_date,
+
17635  &h_state,
+
17636  &h_counts
+
17637  );
17638 
-
17639 }
-
17640 
-
17641 #endif
-
17642 /*//////////////////////////////////////////////////////////////////////////////
-
17644 
-
17645  End of -include/epiworld//models/sirconnected.hpp-
-
17646 
-
17649 
-
17650 
-
17651 /*//////////////////////////////////////////////////////////////////////////////
-
17653 
-
17654  Start of -include/epiworld//models/seirconnected.hpp-
-
17655 
-
17658 
-
17659 
-
17660 #ifndef EPIWORLD_MODELS_SEIRCONNECTED_HPP
-
17661 #define EPIWORLD_MODELS_SEIRCONNECTED_HPP
-
17662 
-
17663 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
17664 class ModelSEIRCONN : public epiworld::Model<TSeq>
-
17665 {
-
17666 private:
-
17667  std::vector< epiworld::Agent<TSeq> * > infected;
-
17668  void update_infected();
-
17669 
-
17670 public:
-
17671 
-
17672  static const int SUSCEPTIBLE = 0;
-
17673  static const int EXPOSED = 1;
-
17674  static const int INFECTED = 2;
-
17675  static const int RECOVERED = 3;
+
17639  // Retrieving information on susceptibles
+
17640  std::vector< double > S(this_const->get_ndays(), 0.0);
+
17641  for (size_t i = 0; i < h_date.size(); ++i)
+
17642  {
+
17643  if (h_state[i] == "Susceptible")
+
17644  S[h_date[i]] += h_counts[i];
+
17645  }
+
17646 
+
17647  // The generation time in the SIR model starts from 1, as agents
+
17648  // spend at least one day in the infected state before starting
+
17649  // transmitting.
+
17650  std::vector< double > gen_times(this_const->get_ndays(), 1.0);
+
17651  double p_c = this_const->par("Contact rate")/this_const->size();
+
17652  double p_i = this_const->par("Transmission rate");
+
17653  double p_r = this_const->par("Recovery rate");
+
17654  for (size_t i = 0u; i < this_const->get_ndays(); ++i)
+
17655  {
+
17656  gen_times[i] = gen_int_mean(
+
17657  S[i],
+
17658  p_c,
+
17659  p_i,
+
17660  p_r,
+
17661  max_days,
+
17662  max_contacts
+
17663  );
+
17664 
+
17665  }
+
17666 
+
17667  return gen_times;
+
17668 
+
17669 }
+
17670 
+
17671 #endif
+
17672 /*//////////////////////////////////////////////////////////////////////////////
+
17674 
+
17675  End of -include/epiworld//models/sirconnected.hpp-
17676 
-
17677 
-
17678  ModelSEIRCONN() {};
17679 
-
17680  ModelSEIRCONN(
-
17681  ModelSEIRCONN<TSeq> & model,
-
17682  const std::string & vname,
-
17683  epiworld_fast_uint n,
-
17684  epiworld_double prevalence,
-
17685  epiworld_double contact_rate,
-
17686  epiworld_double transmission_rate,
-
17687  epiworld_double avg_incubation_days,
-
17688  epiworld_double recovery_rate
-
17689  );
-
17690 
-
17691  ModelSEIRCONN(
-
17692  const std::string & vname,
-
17693  epiworld_fast_uint n,
-
17694  epiworld_double prevalence,
-
17695  epiworld_double contact_rate,
-
17696  epiworld_double transmission_rate,
-
17697  epiworld_double avg_incubation_days,
-
17698  epiworld_double recovery_rate
-
17699  );
-
17700 
-
17701  ModelSEIRCONN<TSeq> & run(
-
17702  epiworld_fast_uint ndays,
-
17703  int seed = -1
-
17704  );
-
17705 
-
17706  void reset();
+
17680 
+
17681 /*//////////////////////////////////////////////////////////////////////////////
+
17683 
+
17684  Start of -include/epiworld//models/seirconnected.hpp-
+
17685 
+
17688 
+
17689 
+
17690 #ifndef EPIWORLD_MODELS_SEIRCONNECTED_HPP
+
17691 #define EPIWORLD_MODELS_SEIRCONNECTED_HPP
+
17692 
+
17693 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
17694 class ModelSEIRCONN : public epiworld::Model<TSeq>
+
17695 {
+
17696 private:
+
17697  std::vector< epiworld::Agent<TSeq> * > infected;
+
17698  void update_infected();
+
17699 
+
17700 public:
+
17701 
+
17702  static const int SUSCEPTIBLE = 0;
+
17703  static const int EXPOSED = 1;
+
17704  static const int INFECTED = 2;
+
17705  static const int RECOVERED = 3;
+
17706 
17707 
-
17708  Model<TSeq> * clone_ptr();
+
17708  ModelSEIRCONN() {};
17709 
-
17715  ModelSEIRCONN<TSeq> & initial_states(
-
17716  std::vector< double > proportions_,
-
17717  std::vector< int > queue_ = {}
-
17718  );
-
17719 
-
17720  size_t get_n_infected() const { return infected.size(); }
-
17721 
-
17722  /***
-
17723  * @brief Compute expected generation time
-
17724  * @param max_days Maximum number of days.
-
17725  * @param max_contacts Maximum number of contacts.
-
17726  */
-
17727  std::vector< double > generation_time_expected(
-
17728  int max_days = 200,
-
17729  int max_contacts = 200
-
17730  ) const;
-
17731 
-
17732 };
-
17733 
-
17734 template<typename TSeq>
- -
17736 {
-
17737 
-
17738  infected.clear();
-
17739  infected.reserve(this->size());
-
17740 
-
17741  for (auto & p : this->get_agents())
-
17742  {
-
17743  if (p.get_state() == ModelSEIRCONN<TSeq>::INFECTED)
-
17744  {
-
17745  infected.push_back(&p);
-
17746  }
-
17747  }
-
17748 
- -
17750  this->get_n_infected(),
-
17751  static_cast<double>(Model<TSeq>::par("Contact rate"))/
-
17752  static_cast<double>(Model<TSeq>::size())
-
17753  );
-
17754 
-
17755  return;
-
17756 
-
17757 }
-
17758 
-
17759 template<typename TSeq>
- -
17761  epiworld_fast_uint ndays,
-
17762  int seed
-
17763 )
-
17764 {
-
17765 
-
17766  Model<TSeq>::run(ndays, seed);
+
17710  ModelSEIRCONN(
+
17711  ModelSEIRCONN<TSeq> & model,
+
17712  const std::string & vname,
+
17713  epiworld_fast_uint n,
+
17714  epiworld_double prevalence,
+
17715  epiworld_double contact_rate,
+
17716  epiworld_double transmission_rate,
+
17717  epiworld_double avg_incubation_days,
+
17718  epiworld_double recovery_rate
+
17719  );
+
17720 
+
17721  ModelSEIRCONN(
+
17722  const std::string & vname,
+
17723  epiworld_fast_uint n,
+
17724  epiworld_double prevalence,
+
17725  epiworld_double contact_rate,
+
17726  epiworld_double transmission_rate,
+
17727  epiworld_double avg_incubation_days,
+
17728  epiworld_double recovery_rate
+
17729  );
+
17730 
+
17731  ModelSEIRCONN<TSeq> & run(
+
17732  epiworld_fast_uint ndays,
+
17733  int seed = -1
+
17734  );
+
17735 
+
17736  void reset();
+
17737 
+
17738  Model<TSeq> * clone_ptr();
+
17739 
+
17745  ModelSEIRCONN<TSeq> & initial_states(
+
17746  std::vector< double > proportions_,
+
17747  std::vector< int > queue_ = {}
+
17748  );
+
17749 
+
17750  size_t get_n_infected() const { return infected.size(); }
+
17751 
+
17752  /***
+
17753  * @brief Compute expected generation time
+
17754  * @param max_days Maximum number of days.
+
17755  * @param max_contacts Maximum number of contacts.
+
17756  */
+
17757  std::vector< double > generation_time_expected(
+
17758  int max_days = 200,
+
17759  int max_contacts = 200
+
17760  ) const;
+
17761 
+
17762 };
+
17763 
+
17764 template<typename TSeq>
+ +
17766 {
17767 
-
17768  return *this;
-
17769 
-
17770 }
-
17771 
-
17772 template<typename TSeq>
- -
17774 {
-
17775 
- -
17777  this->update_infected();
+
17768  infected.clear();
+
17769  infected.reserve(this->size());
+
17770 
+
17771  for (auto & p : this->get_agents())
+
17772  {
+
17773  if (p.get_state() == ModelSEIRCONN<TSeq>::INFECTED)
+
17774  {
+
17775  infected.push_back(&p);
+
17776  }
+
17777  }
17778 
-
17779  return;
-
17780 
-
17781 }
-
17782 
-
17783 template<typename TSeq>
- -
17785 {
-
17786 
- -
17788  *dynamic_cast<const ModelSEIRCONN<TSeq>*>(this)
-
17789  );
-
17790 
-
17791  return dynamic_cast< Model<TSeq> *>(ptr);
-
17792 
-
17793 }
-
17794 
-
17805 template<typename TSeq>
- -
17807  ModelSEIRCONN<TSeq> & model,
-
17808  const std::string & vname,
-
17809  epiworld_fast_uint n,
-
17810  epiworld_double prevalence,
-
17811  epiworld_double contact_rate,
-
17812  epiworld_double transmission_rate,
-
17813  epiworld_double avg_incubation_days,
-
17814  epiworld_double recovery_rate
-
17815  // epiworld_double prob_reinfection
-
17816  )
-
17817 {
-
17818 
-
17819  epiworld::UpdateFun<TSeq> update_susceptible = [](
- -
17821  ) -> void
-
17822  {
-
17823 
-
17824  // Sampling how many individuals
-
17825  int ndraw = m->rbinom();
-
17826 
-
17827  if (ndraw == 0)
-
17828  return;
-
17829 
-
17830  ModelSEIRCONN<TSeq> * model = dynamic_cast<ModelSEIRCONN<TSeq> *>(m);
-
17831  size_t ninfected = model->get_n_infected();
-
17832 
-
17833  // Drawing from the set
-
17834  int nviruses_tmp = 0;
-
17835  for (int i = 0; i < ndraw; ++i)
-
17836  {
-
17837  // Now selecting who is transmitting the disease
-
17838  int which = static_cast<int>(
-
17839  std::floor(ninfected * m->runif())
-
17840  );
-
17841 
-
17842  /* There is a bug in which runif() returns 1.0. It is rare, but
-
17843  * we saw it here. See the Notes section in the C++ manual
-
17844  * https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/random/uniform_real_distribution&oldid=133329
-
17845  * And the reported bug in GCC:
-
17846  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
-
17847  *
-
17848  */
-
17849  if (which == static_cast<int>(ninfected))
-
17850  --which;
-
17851 
-
17852  epiworld::Agent<TSeq> & neighbor = *model->infected[which];
+ +
17780  this->get_n_infected(),
+
17781  static_cast<double>(Model<TSeq>::par("Contact rate"))/
+
17782  static_cast<double>(Model<TSeq>::size())
+
17783  );
+
17784 
+
17785  return;
+
17786 
+
17787 }
+
17788 
+
17789 template<typename TSeq>
+ +
17791  epiworld_fast_uint ndays,
+
17792  int seed
+
17793 )
+
17794 {
+
17795 
+
17796  Model<TSeq>::run(ndays, seed);
+
17797 
+
17798  return *this;
+
17799 
+
17800 }
+
17801 
+
17802 template<typename TSeq>
+ +
17804 {
+
17805 
+ +
17807  this->update_infected();
+
17808 
+
17809  return;
+
17810 
+
17811 }
+
17812 
+
17813 template<typename TSeq>
+ +
17815 {
+
17816 
+ +
17818  *dynamic_cast<const ModelSEIRCONN<TSeq>*>(this)
+
17819  );
+
17820 
+
17821  return dynamic_cast< Model<TSeq> *>(ptr);
+
17822 
+
17823 }
+
17824 
+
17835 template<typename TSeq>
+ +
17837  ModelSEIRCONN<TSeq> & model,
+
17838  const std::string & vname,
+
17839  epiworld_fast_uint n,
+
17840  epiworld_double prevalence,
+
17841  epiworld_double contact_rate,
+
17842  epiworld_double transmission_rate,
+
17843  epiworld_double avg_incubation_days,
+
17844  epiworld_double recovery_rate
+
17845  // epiworld_double prob_reinfection
+
17846  )
+
17847 {
+
17848 
+
17849  epiworld::UpdateFun<TSeq> update_susceptible = [](
+ +
17851  ) -> void
+
17852  {
17853 
-
17854  // Can't sample itself
-
17855  if (neighbor.get_id() == p->get_id())
-
17856  continue;
-
17857 
-
17858  // The neighbor is infected by construction
-
17859  auto & v = neighbor.get_virus();
-
17860 
-
17861  #ifdef EPI_DEBUG
-
17862  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
-
17863  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
17864  #endif
-
17865 
-
17866  /* And it is a function of susceptibility_reduction as well */
-
17867  m->array_double_tmp[nviruses_tmp] =
-
17868  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
17869  v->get_prob_infecting(m) *
-
17870  (1.0 - neighbor.get_transmission_reduction(v, m))
-
17871  ;
-
17872 
-
17873  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
17874 
-
17875  }
-
17876 
-
17877  // No virus to compute
-
17878  if (nviruses_tmp == 0u)
-
17879  return;
-
17880 
-
17881  // Running the roulette
-
17882  int which = roulette(nviruses_tmp, m);
+
17854  // Sampling how many individuals
+
17855  int ndraw = m->rbinom();
+
17856 
+
17857  if (ndraw == 0)
+
17858  return;
+
17859 
+
17860  ModelSEIRCONN<TSeq> * model = dynamic_cast<ModelSEIRCONN<TSeq> *>(m);
+
17861  size_t ninfected = model->get_n_infected();
+
17862 
+
17863  // Drawing from the set
+
17864  int nviruses_tmp = 0;
+
17865  for (int i = 0; i < ndraw; ++i)
+
17866  {
+
17867  // Now selecting who is transmitting the disease
+
17868  int which = static_cast<int>(
+
17869  std::floor(ninfected * m->runif())
+
17870  );
+
17871 
+
17872  /* There is a bug in which runif() returns 1.0. It is rare, but
+
17873  * we saw it here. See the Notes section in the C++ manual
+
17874  * https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/random/uniform_real_distribution&oldid=133329
+
17875  * And the reported bug in GCC:
+
17876  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
+
17877  *
+
17878  */
+
17879  if (which == static_cast<int>(ninfected))
+
17880  --which;
+
17881 
+
17882  epiworld::Agent<TSeq> & neighbor = *model->infected[which];
17883 
-
17884  if (which < 0)
-
17885  return;
-
17886 
-
17887  p->set_virus(
-
17888  *m->array_virus_tmp[which],
-
17889  m,
- -
17891  );
-
17892 
-
17893  return;
-
17894 
-
17895  };
-
17896 
-
17897  epiworld::UpdateFun<TSeq> update_infected = [](
- -
17899  ) -> void {
-
17900 
-
17901  auto state = p->get_state();
-
17902 
-
17903  if (state == ModelSEIRCONN<TSeq>::EXPOSED)
-
17904  {
-
17905 
-
17906  // Getting the virus
-
17907  auto & v = p->get_virus();
-
17908 
-
17909  // Does the agent become infected?
-
17910  if (m->runif() < 1.0/(v->get_incubation(m)))
-
17911  {
-
17912 
-
17913  p->change_state(m, ModelSEIRCONN<TSeq>::INFECTED);
-
17914  return;
-
17915 
-
17916  }
-
17917 
-
17918 
-
17919  } else if (state == ModelSEIRCONN<TSeq>::INFECTED)
-
17920  {
-
17921 
+
17884  // Can't sample itself
+
17885  if (neighbor.get_id() == p->get_id())
+
17886  continue;
+
17887 
+
17888  // The neighbor is infected by construction
+
17889  auto & v = neighbor.get_virus();
+
17890 
+
17891  #ifdef EPI_DEBUG
+
17892  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
+
17893  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
17894  #endif
+
17895 
+
17896  /* And it is a function of susceptibility_reduction as well */
+
17897  m->array_double_tmp[nviruses_tmp] =
+
17898  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
17899  v->get_prob_infecting(m) *
+
17900  (1.0 - neighbor.get_transmission_reduction(v, m))
+
17901  ;
+
17902 
+
17903  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
17904 
+
17905  }
+
17906 
+
17907  // No virus to compute
+
17908  if (nviruses_tmp == 0u)
+
17909  return;
+
17910 
+
17911  // Running the roulette
+
17912  int which = roulette(nviruses_tmp, m);
+
17913 
+
17914  if (which < 0)
+
17915  return;
+
17916 
+
17917  p->set_virus(
+
17918  *m->array_virus_tmp[which],
+
17919  m,
+ +
17921  );
17922 
-
17923  // Odd: Die, Even: Recover
-
17924  epiworld_fast_uint n_events = 0u;
-
17925  const auto & v = p->get_virus();
+
17923  return;
+
17924 
+
17925  };
17926 
-
17927  // Recover
-
17928  m->array_double_tmp[n_events++] =
-
17929  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
+
17927  epiworld::UpdateFun<TSeq> update_infected = [](
+ +
17929  ) -> void {
17930 
-
17931  #ifdef EPI_DEBUG
-
17932  if (n_events == 0u)
-
17933  {
-
17934  printf_epiworld(
-
17935  "[epi-debug] agent %i has 0 possible events!!\n",
-
17936  static_cast<int>(p->get_id())
-
17937  );
-
17938  throw std::logic_error("Zero events in exposed.");
-
17939  }
-
17940  #else
-
17941  if (n_events == 0u)
-
17942  return;
-
17943  #endif
-
17944 
+
17931  auto state = p->get_state();
+
17932 
+
17933  if (state == ModelSEIRCONN<TSeq>::EXPOSED)
+
17934  {
+
17935 
+
17936  // Getting the virus
+
17937  auto & v = p->get_virus();
+
17938 
+
17939  // Does the agent become infected?
+
17940  if (m->runif() < 1.0/(v->get_incubation(m)))
+
17941  {
+
17942 
+
17943  p->change_state(m, ModelSEIRCONN<TSeq>::INFECTED);
+
17944  return;
17945 
-
17946  // Running the roulette
-
17947  int which = roulette(n_events, m);
+
17946  }
+
17947 
17948 
-
17949  if (which < 0)
-
17950  return;
+
17949  } else if (state == ModelSEIRCONN<TSeq>::INFECTED)
+
17950  {
17951 
-
17952  // Which roulette happen?
-
17953  p->rm_virus(m);
-
17954 
-
17955  return ;
+
17952 
+
17953  // Odd: Die, Even: Recover
+
17954  epiworld_fast_uint n_events = 0u;
+
17955  const auto & v = p->get_virus();
17956 
-
17957  } else
-
17958  throw std::logic_error("This function can only be applied to exposed or infected individuals. (SEIR)") ;
-
17959 
-
17960  return;
-
17961 
-
17962  };
-
17963 
-
17964  // Setting up parameters
-
17965  model.add_param(contact_rate, "Contact rate");
-
17966  model.add_param(transmission_rate, "Prob. Transmission");
-
17967  model.add_param(recovery_rate, "Prob. Recovery");
-
17968  model.add_param(avg_incubation_days, "Avg. Incubation days");
-
17969 
-
17970  // state
-
17971  model.add_state("Susceptible", update_susceptible);
-
17972  model.add_state("Exposed", update_infected);
-
17973  model.add_state("Infected", update_infected);
-
17974  model.add_state("Recovered");
+
17957  // Recover
+
17958  m->array_double_tmp[n_events++] =
+
17959  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
+
17960 
+
17961  #ifdef EPI_DEBUG
+
17962  if (n_events == 0u)
+
17963  {
+
17964  printf_epiworld(
+
17965  "[epi-debug] agent %i has 0 possible events!!\n",
+
17966  static_cast<int>(p->get_id())
+
17967  );
+
17968  throw std::logic_error("Zero events in exposed.");
+
17969  }
+
17970  #else
+
17971  if (n_events == 0u)
+
17972  return;
+
17973  #endif
+
17974 
17975 
-
17976  // Adding update function
-
17977  epiworld::GlobalFun<TSeq> update = [](
- -
17979  ) -> void
-
17980  {
+
17976  // Running the roulette
+
17977  int which = roulette(n_events, m);
+
17978 
+
17979  if (which < 0)
+
17980  return;
17981 
-
17982  ModelSEIRCONN<TSeq> * model = dynamic_cast<ModelSEIRCONN<TSeq> *>(m);
-
17983 
-
17984  model->update_infected();
-
17985 
-
17986  return;
-
17987 
-
17988  };
+
17982  // Which roulette happen?
+
17983  p->rm_virus(m);
+
17984 
+
17985  return ;
+
17986 
+
17987  } else
+
17988  throw std::logic_error("This function can only be applied to exposed or infected individuals. (SEIR)") ;
17989 
-
17990  model.add_globalevent(update, "Update infected individuals");
+
17990  return;
17991 
-
17992 
-
17993  // Preparing the virus -------------------------------------------
-
17994  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
17995  virus.set_state(
- - - -
17999  );
-
18000 
-
18001  virus.set_prob_infecting(&model("Prob. Transmission"));
-
18002  virus.set_prob_recovery(&model("Prob. Recovery"));
-
18003  virus.set_incubation(&model("Avg. Incubation days"));
-
18004 
-
18005  model.add_virus(virus);
-
18006 
-
18007  model.queuing_off(); // No queuing need
-
18008 
-
18009  // Adding the empty population
-
18010  model.agents_empty_graph(n);
+
17992  };
+
17993 
+
17994  // Setting up parameters
+
17995  model.add_param(contact_rate, "Contact rate");
+
17996  model.add_param(transmission_rate, "Prob. Transmission");
+
17997  model.add_param(recovery_rate, "Prob. Recovery");
+
17998  model.add_param(avg_incubation_days, "Avg. Incubation days");
+
17999 
+
18000  // state
+
18001  model.add_state("Susceptible", update_susceptible);
+
18002  model.add_state("Exposed", update_infected);
+
18003  model.add_state("Infected", update_infected);
+
18004  model.add_state("Recovered");
+
18005 
+
18006  // Adding update function
+
18007  epiworld::GlobalFun<TSeq> update = [](
+ +
18009  ) -> void
+
18010  {
18011 
-
18012  model.set_name("Susceptible-Exposed-Infected-Removed (SEIR) (connected)");
+
18012  ModelSEIRCONN<TSeq> * model = dynamic_cast<ModelSEIRCONN<TSeq> *>(m);
18013 
-
18014  return;
+
18014  model->update_infected();
18015 
-
18016 }
+
18016  return;
18017 
-
18018 template<typename TSeq>
- -
18020  const std::string & vname,
-
18021  epiworld_fast_uint n,
-
18022  epiworld_double prevalence,
-
18023  epiworld_double contact_rate,
-
18024  epiworld_double transmission_rate,
-
18025  epiworld_double avg_incubation_days,
-
18026  epiworld_double recovery_rate
-
18027  )
-
18028 {
-
18029 
-
18030  ModelSEIRCONN(
-
18031  *this,
-
18032  vname,
-
18033  n,
-
18034  prevalence,
-
18035  contact_rate,
-
18036  transmission_rate,
-
18037  avg_incubation_days,
-
18038  recovery_rate
-
18039  );
-
18040 
-
18041  return;
-
18042 
-
18043 }
-
18044 
-
18045 template<typename TSeq>
- -
18047  std::vector< double > proportions_,
-
18048  std::vector< int > /* queue_ */
-
18049 )
-
18050 {
-
18051 
- -
18053  create_init_function_seir<TSeq>(proportions_)
-
18054  ;
-
18055 
-
18056  return *this;
-
18057 
-
18058 }
+
18018  };
+
18019 
+
18020  model.add_globalevent(update, "Update infected individuals");
+
18021 
+
18022 
+
18023  // Preparing the virus -------------------------------------------
+
18024  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
18025  virus.set_state(
+ + + +
18029  );
+
18030 
+
18031  virus.set_prob_infecting(&model("Prob. Transmission"));
+
18032  virus.set_prob_recovery(&model("Prob. Recovery"));
+
18033  virus.set_incubation(&model("Avg. Incubation days"));
+
18034 
+
18035  model.add_virus(virus);
+
18036 
+
18037  model.queuing_off(); // No queuing need
+
18038 
+
18039  // Adding the empty population
+
18040  model.agents_empty_graph(n);
+
18041 
+
18042  model.set_name("Susceptible-Exposed-Infected-Removed (SEIR) (connected)");
+
18043 
+
18044  return;
+
18045 
+
18046 }
+
18047 
+
18048 template<typename TSeq>
+ +
18050  const std::string & vname,
+
18051  epiworld_fast_uint n,
+
18052  epiworld_double prevalence,
+
18053  epiworld_double contact_rate,
+
18054  epiworld_double transmission_rate,
+
18055  epiworld_double avg_incubation_days,
+
18056  epiworld_double recovery_rate
+
18057  )
+
18058 {
18059 
-
18060 template<typename TSeq>
-
18061 inline std::vector< double > ModelSEIRCONN<TSeq>::generation_time_expected(
-
18062  int max_days,
-
18063  int max_contacts
-
18064 ) const
-
18065 {
-
18066 
-
18067  // Retrieving total counts
-
18068  std::vector< int > h_date;
-
18069  std::vector< std::string > h_state;
-
18070  std::vector< int > h_counts;
-
18071  const auto this_const = dynamic_cast<const ModelSEIRCONN<TSeq> *>(this);
-
18072  this_const->get_db().get_hist_total(
-
18073  &h_date,
-
18074  &h_state,
-
18075  &h_counts
-
18076  );
-
18077 
-
18078  // Retrieving information on susceptibles
-
18079  std::vector< double > S(this_const->get_ndays(), 0.0);
-
18080  for (size_t i = 0; i < h_date.size(); ++i)
-
18081  {
-
18082  if (h_state[i] == "Susceptible")
-
18083  S[h_date[i]] += h_counts[i];
-
18084  }
+
18060  ModelSEIRCONN(
+
18061  *this,
+
18062  vname,
+
18063  n,
+
18064  prevalence,
+
18065  contact_rate,
+
18066  transmission_rate,
+
18067  avg_incubation_days,
+
18068  recovery_rate
+
18069  );
+
18070 
+
18071  return;
+
18072 
+
18073 }
+
18074 
+
18075 template<typename TSeq>
+ +
18077  std::vector< double > proportions_,
+
18078  std::vector< int > /* queue_ */
+
18079 )
+
18080 {
+
18081 
+ +
18083  create_init_function_seir<TSeq>(proportions_)
+
18084  ;
18085 
-
18086  // Computing the expected number of days in exposed
-
18087  double days_exposed = this_const->par("Avg. Incubation days");
-
18088 
-
18089  // The generation time in the SEIR model starts from 2, as agents
-
18090  // spend at least one day in the exposed state, and 1 day in the
-
18091  // infectious state before starting transmitting.
-
18092  std::vector< double > gen_times(
-
18093  this_const->get_ndays(), 1.0 + days_exposed
-
18094  );
-
18095 
-
18096  double p_c = this_const->par("Contact rate")/this_const->size();
-
18097  double p_i = this_const->par("Prob. Transmission");
-
18098  double p_r = this_const->par("Prob. Recovery");
-
18099 
-
18100  for (size_t i = 0u; i < this_const->get_ndays(); ++i)
-
18101  {
-
18102  gen_times[i] += gen_int_mean(
-
18103  S[i],
-
18104  p_c,
-
18105  p_i,
-
18106  p_r,
-
18107  max_days,
-
18108  max_contacts
-
18109  );
-
18110 
-
18111  }
-
18112 
-
18113  return gen_times;
-
18114 
-
18115 }
-
18116 
-
18117 #endif
-
18118 /*//////////////////////////////////////////////////////////////////////////////
-
18120 
-
18121  End of -include/epiworld//models/seirconnected.hpp-
-
18122 
-
18125 
-
18126 
-
18127 /*//////////////////////////////////////////////////////////////////////////////
-
18129 
-
18130  Start of -include/epiworld//models/sird.hpp-
-
18131 
-
18134 
-
18135 
-
18136 #ifndef EPIWORLD_SIRD_H
-
18137 #define EPIWORLD_SIRD_H
-
18138 
-
18142 template<typename TSeq = int>
-
18143 class ModelSIRD : public epiworld::Model<TSeq>
-
18144 {
-
18145 public:
-
18146 
-
18147  ModelSIRD() {};
-
18148 
-
18149 
-
18161  ModelSIRD(
-
18162  ModelSIRD<TSeq> & model,
-
18163  const std::string & vname,
-
18164  epiworld_double prevalence,
-
18165  epiworld_double transmission_rate,
-
18166  epiworld_double recovery_rate,
-
18167  epiworld_double death_rate
-
18168  );
-
18169 
-
18170  ModelSIRD(
-
18171  const std::string & vname,
-
18172  epiworld_double prevalence,
-
18173  epiworld_double transmission_rate,
-
18174  epiworld_double recovery_rate,
-
18175  epiworld_double death_rate
-
18176  );
+
18086  return *this;
+
18087 
+
18088 }
+
18089 
+
18090 template<typename TSeq>
+
18091 inline std::vector< double > ModelSEIRCONN<TSeq>::generation_time_expected(
+
18092  int max_days,
+
18093  int max_contacts
+
18094 ) const
+
18095 {
+
18096 
+
18097  // Retrieving total counts
+
18098  std::vector< int > h_date;
+
18099  std::vector< std::string > h_state;
+
18100  std::vector< int > h_counts;
+
18101  const auto this_const = dynamic_cast<const ModelSEIRCONN<TSeq> *>(this);
+
18102  this_const->get_db().get_hist_total(
+
18103  &h_date,
+
18104  &h_state,
+
18105  &h_counts
+
18106  );
+
18107 
+
18108  // Retrieving information on susceptibles
+
18109  std::vector< double > S(this_const->get_ndays(), 0.0);
+
18110  for (size_t i = 0; i < h_date.size(); ++i)
+
18111  {
+
18112  if (h_state[i] == "Susceptible")
+
18113  S[h_date[i]] += h_counts[i];
+
18114  }
+
18115 
+
18116  // Computing the expected number of days in exposed
+
18117  double days_exposed = this_const->par("Avg. Incubation days");
+
18118 
+
18119  // The generation time in the SEIR model starts from 2, as agents
+
18120  // spend at least one day in the exposed state, and 1 day in the
+
18121  // infectious state before starting transmitting.
+
18122  std::vector< double > gen_times(
+
18123  this_const->get_ndays(), 1.0 + days_exposed
+
18124  );
+
18125 
+
18126  double p_c = this_const->par("Contact rate")/this_const->size();
+
18127  double p_i = this_const->par("Prob. Transmission");
+
18128  double p_r = this_const->par("Prob. Recovery");
+
18129 
+
18130  for (size_t i = 0u; i < this_const->get_ndays(); ++i)
+
18131  {
+
18132  gen_times[i] += gen_int_mean(
+
18133  S[i],
+
18134  p_c,
+
18135  p_i,
+
18136  p_r,
+
18137  max_days,
+
18138  max_contacts
+
18139  );
+
18140 
+
18141  }
+
18142 
+
18143  return gen_times;
+
18144 
+
18145 }
+
18146 
+
18147 #endif
+
18148 /*//////////////////////////////////////////////////////////////////////////////
+
18150 
+
18151  End of -include/epiworld//models/seirconnected.hpp-
+
18152 
+
18155 
+
18156 
+
18157 /*//////////////////////////////////////////////////////////////////////////////
+
18159 
+
18160  Start of -include/epiworld//models/sird.hpp-
+
18161 
+
18164 
+
18165 
+
18166 #ifndef EPIWORLD_SIRD_H
+
18167 #define EPIWORLD_SIRD_H
+
18168 
+
18172 template<typename TSeq = int>
+
18173 class ModelSIRD : public epiworld::Model<TSeq>
+
18174 {
+
18175 public:
+
18176 
+
18177  ModelSIRD() {};
18178 
-
18185  ModelSIRD<TSeq> & initial_states(
-
18186  std::vector< double > proportions_,
-
18187  std::vector< int > queue_ = {}
-
18188  );
-
18189 
-
18190 };
-
18191 
-
18192 template<typename TSeq>
-
18193 inline ModelSIRD<TSeq>::ModelSIRD(
-
18194  ModelSIRD<TSeq> & model,
-
18195  const std::string & vname,
-
18196  epiworld_double prevalence,
-
18197  epiworld_double transmission_rate,
-
18198  epiworld_double recovery_rate,
-
18199  epiworld_double death_rate
-
18200  )
-
18201 {
-
18202 
-
18203  // Adding statuses
-
18204  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
-
18205  model.add_state("Infected", epiworld::default_update_exposed<TSeq>);
-
18206  model.add_state("Recovered"),
-
18207  model.add_state("Deceased")
-
18208  ;
-
18209 
-
18210  // Setting up parameters
-
18211  model.add_param(recovery_rate, "Recovery rate");
-
18212  model.add_param(transmission_rate, "Transmission rate"),
-
18213  model.add_param(death_rate, "Death rate");
-
18214 
-
18215  // Preparing the virus -------------------------------------------
-
18216  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
18217  virus.set_state(1,2,3);
-
18218  virus.set_prob_recovery(&model("Recovery rate"));
-
18219  virus.set_prob_infecting(&model("Transmission rate"));
-
18220  virus.set_prob_death(&model("Death rate"));
-
18221 
-
18222  model.add_virus(virus);
-
18223 
-
18224  model.set_name("Susceptible-Infected-Recovered-Deceased (SIRD)");
-
18225 
-
18226  return;
-
18227 
-
18228 }
-
18229 
-
18230 template<typename TSeq>
-
18231 inline ModelSIRD<TSeq>::ModelSIRD(
-
18232  const std::string & vname,
-
18233  epiworld_double prevalence,
-
18234  epiworld_double transmission_rate,
-
18235  epiworld_double recovery_rate,
-
18236  epiworld_double death_rate
-
18237  )
-
18238 {
+
18179 
+
18191  ModelSIRD(
+
18192  ModelSIRD<TSeq> & model,
+
18193  const std::string & vname,
+
18194  epiworld_double prevalence,
+
18195  epiworld_double transmission_rate,
+
18196  epiworld_double recovery_rate,
+
18197  epiworld_double death_rate
+
18198  );
+
18199 
+
18200  ModelSIRD(
+
18201  const std::string & vname,
+
18202  epiworld_double prevalence,
+
18203  epiworld_double transmission_rate,
+
18204  epiworld_double recovery_rate,
+
18205  epiworld_double death_rate
+
18206  );
+
18208 
+
18215  ModelSIRD<TSeq> & initial_states(
+
18216  std::vector< double > proportions_,
+
18217  std::vector< int > queue_ = {}
+
18218  );
+
18219 
+
18220 };
+
18221 
+
18222 template<typename TSeq>
+
18223 inline ModelSIRD<TSeq>::ModelSIRD(
+
18224  ModelSIRD<TSeq> & model,
+
18225  const std::string & vname,
+
18226  epiworld_double prevalence,
+
18227  epiworld_double transmission_rate,
+
18228  epiworld_double recovery_rate,
+
18229  epiworld_double death_rate
+
18230  )
+
18231 {
+
18232 
+
18233  // Adding statuses
+
18234  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
+
18235  model.add_state("Infected", epiworld::default_update_exposed<TSeq>);
+
18236  model.add_state("Recovered"),
+
18237  model.add_state("Deceased")
+
18238  ;
18239 
-
18240  ModelSIRD<TSeq>(
-
18241  *this,
-
18242  vname,
-
18243  prevalence,
-
18244  transmission_rate,
-
18245  recovery_rate,
-
18246  death_rate
-
18247  );
-
18248 
-
18249  return;
-
18250 
-
18251 }
-
18252 
-
18253 template<typename TSeq>
-
18254 inline ModelSIRD<TSeq> & ModelSIRD<TSeq>::initial_states(
-
18255  std::vector< double > proportions_,
-
18256  std::vector< int > /**/
-
18257 ) {
-
18258 
- -
18260  create_init_function_sird<TSeq>(proportions_)
-
18261  ;
-
18262 
-
18263  return *this;
-
18264 
-
18265 }
-
18266 
-
18267 #endif
-
18268 /*//////////////////////////////////////////////////////////////////////////////
-
18270 
-
18271  End of -include/epiworld//models/sird.hpp-
-
18272 
-
18275 
-
18276 
-
18277 /*//////////////////////////////////////////////////////////////////////////////
-
18279 
-
18280  Start of -include/epiworld//models/sisd.hpp-
-
18281 
-
18284 
-
18285 
-
18286 #ifndef EPIWORLD_MODELS_SISD_HPP
-
18287 #define EPIWORLD_MODELS_SISD_HPP
-
18288 
-
18298 template<typename TSeq = int>
-
18299 class ModelSISD : public epiworld::Model<TSeq>
-
18300 {
-
18301 
-
18302 public:
-
18303 
-
18304  ModelSISD() {};
+
18240  // Setting up parameters
+
18241  model.add_param(recovery_rate, "Recovery rate");
+
18242  model.add_param(transmission_rate, "Transmission rate"),
+
18243  model.add_param(death_rate, "Death rate");
+
18244 
+
18245  // Preparing the virus -------------------------------------------
+
18246  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
18247  virus.set_state(1,2,3);
+
18248  virus.set_prob_recovery(&model("Recovery rate"));
+
18249  virus.set_prob_infecting(&model("Transmission rate"));
+
18250  virus.set_prob_death(&model("Death rate"));
+
18251 
+
18252  model.add_virus(virus);
+
18253 
+
18254  model.set_name("Susceptible-Infected-Recovered-Deceased (SIRD)");
+
18255 
+
18256  return;
+
18257 
+
18258 }
+
18259 
+
18260 template<typename TSeq>
+
18261 inline ModelSIRD<TSeq>::ModelSIRD(
+
18262  const std::string & vname,
+
18263  epiworld_double prevalence,
+
18264  epiworld_double transmission_rate,
+
18265  epiworld_double recovery_rate,
+
18266  epiworld_double death_rate
+
18267  )
+
18268 {
+
18269 
+
18270  ModelSIRD<TSeq>(
+
18271  *this,
+
18272  vname,
+
18273  prevalence,
+
18274  transmission_rate,
+
18275  recovery_rate,
+
18276  death_rate
+
18277  );
+
18278 
+
18279  return;
+
18280 
+
18281 }
+
18282 
+
18283 template<typename TSeq>
+
18284 inline ModelSIRD<TSeq> & ModelSIRD<TSeq>::initial_states(
+
18285  std::vector< double > proportions_,
+
18286  std::vector< int > /**/
+
18287 ) {
+
18288 
+ +
18290  create_init_function_sird<TSeq>(proportions_)
+
18291  ;
+
18292 
+
18293  return *this;
+
18294 
+
18295 }
+
18296 
+
18297 #endif
+
18298 /*//////////////////////////////////////////////////////////////////////////////
+
18300 
+
18301  End of -include/epiworld//models/sird.hpp-
+
18302 
18305 
-
18306  ModelSISD(
-
18307  ModelSISD<TSeq> & model,
-
18308  const std::string & vname,
-
18309  epiworld_double prevalence,
-
18310  epiworld_double transmission_rate,
-
18311  epiworld_double recovery_rate,
-
18312  epiworld_double death_rate
-
18313  );
+
18306 
+
18307 /*//////////////////////////////////////////////////////////////////////////////
+
18309 
+
18310  Start of -include/epiworld//models/sisd.hpp-
+
18311 
18314 
-
18315  ModelSISD(
-
18316  const std::string & vname,
-
18317  epiworld_double prevalence,
-
18318  epiworld_double transmission_rate,
-
18319  epiworld_double recovery_rate,
-
18320  epiworld_double death_rate
-
18321  );
-
18322 
-
18323 };
-
18324 
-
18325 template<typename TSeq>
-
18326 inline ModelSISD<TSeq>::ModelSISD(
-
18327  ModelSISD<TSeq> & model,
-
18328  const std::string & vname,
-
18329  epiworld_double prevalence,
-
18330  epiworld_double transmission_rate,
-
18331  epiworld_double recovery_rate,
-
18332  epiworld_double death_rate
-
18333  )
-
18334 {
+
18315 
+
18316 #ifndef EPIWORLD_MODELS_SISD_HPP
+
18317 #define EPIWORLD_MODELS_SISD_HPP
+
18318 
+
18328 template<typename TSeq = int>
+
18329 class ModelSISD : public epiworld::Model<TSeq>
+
18330 {
+
18331 
+
18332 public:
+
18333 
+
18334  ModelSISD() {};
18335 
-
18336  model.set_name("Susceptible-Infected-Susceptible-Deceased (SISD)");
-
18337 
-
18338  // Adding statuses
-
18339  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
-
18340  model.add_state("Infected", epiworld::default_update_exposed<TSeq>);
-
18341  model.add_state("Deceased");
-
18342 
-
18343  // Setting up parameters
-
18344  model.add_param(transmission_rate, "Transmission rate");
-
18345  model.add_param(recovery_rate, "Recovery rate");
-
18346  model.add_param(death_rate, "Death rate");
-
18347 
-
18348  // Preparing the virus -------------------------------------------
-
18349  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
18350  virus.set_state(1,0,2);
-
18351 
-
18352  virus.set_prob_infecting(&model("Transmission rate"));
-
18353  virus.set_prob_recovery(&model("Recovery rate"));
-
18354  virus.set_prob_death(0.01);
-
18355 
-
18356  model.add_virus(virus);
-
18357 
-
18358  return;
-
18359 
-
18360 }
-
18361 
-
18362 template<typename TSeq>
-
18363 inline ModelSISD<TSeq>::ModelSISD(
-
18364  const std::string & vname,
-
18365  epiworld_double prevalence,
-
18366  epiworld_double transmission_rate,
-
18367  epiworld_double recovery_rate,
-
18368  epiworld_double death_rate
-
18369  )
-
18370 {
-
18371 
-
18372  ModelSISD<TSeq>(
-
18373  *this,
-
18374  vname,
-
18375  prevalence,
-
18376  transmission_rate,
-
18377  recovery_rate,
-
18378  death_rate
-
18379  );
-
18380 
-
18381  return;
-
18382 
-
18383 }
-
18384 
-
18385 #endif
-
18386 /*//////////////////////////////////////////////////////////////////////////////
-
18388 
-
18389  End of -include/epiworld//models/sisd.hpp-
-
18390 
-
18393 
-
18394 
-
18395 /*//////////////////////////////////////////////////////////////////////////////
-
18397 
-
18398  Start of -include/epiworld//models/seird.hpp-
-
18399 
-
18402 
-
18403 
-
18404 #ifndef EPIWORLD_MODELS_SEIRD_HPP
-
18405 #define EPIWORLD_MODELS_SEIRD_HPP
-
18406 
-
18410 template<typename TSeq = int>
-
18411 class ModelSEIRD : public epiworld::Model<TSeq>
-
18412 {
-
18413 
-
18414 public:
-
18415  static const int SUSCEPTIBLE = 0;
-
18416  static const int EXPOSED = 1;
-
18417  static const int INFECTED = 2;
-
18418  static const int REMOVED = 3;
-
18419  static const int DECEASED = 4;
-
18420 
-
18421  ModelSEIRD() {};
-
18422 
-
18435  ModelSEIRD(
-
18436  ModelSEIRD<TSeq> & model,
-
18437  const std::string & vname,
-
18438  epiworld_double prevalence,
-
18439  epiworld_double transmission_rate,
-
18440  epiworld_double avg_incubation_days,
-
18441  epiworld_double recovery_rate,
-
18442  epiworld_double death_rate
-
18443  );
-
18444 
-
18455  ModelSEIRD(
-
18456  const std::string & vname,
-
18457  epiworld_double prevalence,
-
18458  epiworld_double transmission_rate,
-
18459  epiworld_double avg_incubation_days,
-
18460  epiworld_double recovery_rate,
-
18461  epiworld_double death_rate
-
18462  );
-
18463 
-
18464  epiworld::UpdateFun<TSeq> update_exposed_seir = [](
-
18465  epiworld::Agent<TSeq> * p,
-
18466  epiworld::Model<TSeq> * m
-
18467  ) -> void {
-
18468 
-
18469  // Getting the virus
-
18470  auto v = p->get_virus();
-
18471 
-
18472  // Does the agent become infected?
-
18473  if (m->runif() < 1.0/(v->get_incubation(m)))
-
18474  p->change_state(m, ModelSEIRD<TSeq>::INFECTED);
-
18475 
-
18476  return;
-
18477  };
-
18478 
-
18479 
-
18480  epiworld::UpdateFun<TSeq> update_infected = [](
-
18481  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
-
18482  ) -> void {
-
18483 
-
18484  // Odd: Die, Even: Recover
-
18485  epiworld_fast_uint n_events = 0u;
-
18486 
-
18487  const auto & v = p->get_virus();
-
18488 
-
18489  // Die
-
18490  m->array_double_tmp[n_events++] =
-
18491  v->get_prob_death(m) * (1.0 - p->get_death_reduction(v, m));
-
18492 
-
18493  // Recover
-
18494  m->array_double_tmp[n_events++] =
-
18495  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
-
18496 
-
18497 
-
18498 #ifdef EPI_DEBUG
-
18499  if (n_events == 0u)
-
18500  {
-
18501  printf_epiworld(
-
18502  "[epi-debug] agent %i has 0 possible events!!\n",
-
18503  static_cast<int>(p->get_id())
-
18504  );
-
18505  throw std::logic_error("Zero events in exposed.");
-
18506  }
-
18507 #else
-
18508  if (n_events == 0u)
-
18509  return;
-
18510 #endif
-
18511 
-
18512 
-
18513  // Running the roulette
-
18514  int which = roulette(n_events, m);
-
18515 
-
18516  if (which < 0)
-
18517  return;
-
18518 
-
18519  // Which roulette happen?
-
18520  if ((which % 2) == 0) // If odd
-
18521  {
-
18522 
-
18523  p->rm_agent_by_virus(m);
-
18524 
-
18525  } else {
-
18526 
-
18527  p->rm_virus(m);
-
18528 
-
18529  }
-
18530 
-
18531  return ;
-
18532 
-
18533 
-
18534 
-
18535  return;
-
18536 
-
18537  };
-
18538 
-
18539  ModelSEIRD<TSeq> & initial_states(
-
18540  std::vector< double > proportions_,
-
18541  std::vector< int > queue_ = {}
-
18542  );
-
18543 
-
18544 };
-
18545 
-
18546 
-
18547 
-
18548 template<typename TSeq>
-
18549 inline ModelSEIRD<TSeq>::ModelSEIRD(
-
18550  ModelSEIRD<TSeq> & model,
-
18551  const std::string & vname,
-
18552  epiworld_double prevalence,
-
18553  epiworld_double transmission_rate,
-
18554  epiworld_double avg_incubation_days,
-
18555  epiworld_double recovery_rate,
-
18556  epiworld_double death_rate
-
18557 )
-
18558 {
-
18559 
-
18560  // Adding statuses
-
18561  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
-
18562  model.add_state("Exposed", model.update_exposed_seir);
-
18563  model.add_state("Infected", model.update_infected);
-
18564  model.add_state("Removed");
-
18565  model.add_state("Deceased");
-
18566 
-
18567  // Setting up parameters
-
18568  model.add_param(transmission_rate, "Transmission rate");
-
18569  model.add_param(avg_incubation_days, "Incubation days");
-
18570  model.add_param(recovery_rate, "Recovery rate");
-
18571  model.add_param(death_rate, "Death rate");
-
18572 
-
18573  // Preparing the virus -------------------------------------------
-
18574  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
18575  virus.set_state(ModelSEIRD<TSeq>::EXPOSED, ModelSEIRD<TSeq>::REMOVED, ModelSEIRD<TSeq>::DECEASED);
-
18576 
-
18577  virus.set_prob_infecting(&model("Transmission rate"));
-
18578  virus.set_incubation(&model("Incubation days"));
-
18579  virus.set_prob_death(&model("Death rate"));
-
18580  virus.set_prob_recovery(&model("Recovery rate"));
-
18581 
-
18582  // Adding the tool and the virus
-
18583  model.add_virus(virus);
-
18584 
-
18585  model.set_name("Susceptible-Exposed-Infected-Removed-Deceased (SEIRD)");
-
18586 
-
18587  return;
-
18588 
-
18589 }
-
18590 
-
18591 template<typename TSeq>
-
18592 inline ModelSEIRD<TSeq>::ModelSEIRD(
-
18593  const std::string & vname,
-
18594  epiworld_double prevalence,
-
18595  epiworld_double transmission_rate,
-
18596  epiworld_double avg_incubation_days,
-
18597  epiworld_double recovery_rate,
-
18598  epiworld_double death_rate
-
18599 )
-
18600 {
-
18601 
-
18602  ModelSEIRD<TSeq>(
-
18603  *this,
-
18604  vname,
-
18605  prevalence,
-
18606  transmission_rate,
-
18607  avg_incubation_days,
-
18608  recovery_rate,
-
18609  death_rate
-
18610  );
+
18336  ModelSISD(
+
18337  ModelSISD<TSeq> & model,
+
18338  const std::string & vname,
+
18339  epiworld_double prevalence,
+
18340  epiworld_double transmission_rate,
+
18341  epiworld_double recovery_rate,
+
18342  epiworld_double death_rate
+
18343  );
+
18344 
+
18345  ModelSISD(
+
18346  const std::string & vname,
+
18347  epiworld_double prevalence,
+
18348  epiworld_double transmission_rate,
+
18349  epiworld_double recovery_rate,
+
18350  epiworld_double death_rate
+
18351  );
+
18352 
+
18353 };
+
18354 
+
18355 template<typename TSeq>
+
18356 inline ModelSISD<TSeq>::ModelSISD(
+
18357  ModelSISD<TSeq> & model,
+
18358  const std::string & vname,
+
18359  epiworld_double prevalence,
+
18360  epiworld_double transmission_rate,
+
18361  epiworld_double recovery_rate,
+
18362  epiworld_double death_rate
+
18363  )
+
18364 {
+
18365 
+
18366  model.set_name("Susceptible-Infected-Susceptible-Deceased (SISD)");
+
18367 
+
18368  // Adding statuses
+
18369  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
+
18370  model.add_state("Infected", epiworld::default_update_exposed<TSeq>);
+
18371  model.add_state("Deceased");
+
18372 
+
18373  // Setting up parameters
+
18374  model.add_param(transmission_rate, "Transmission rate");
+
18375  model.add_param(recovery_rate, "Recovery rate");
+
18376  model.add_param(death_rate, "Death rate");
+
18377 
+
18378  // Preparing the virus -------------------------------------------
+
18379  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
18380  virus.set_state(1,0,2);
+
18381 
+
18382  virus.set_prob_infecting(&model("Transmission rate"));
+
18383  virus.set_prob_recovery(&model("Recovery rate"));
+
18384  virus.set_prob_death(0.01);
+
18385 
+
18386  model.add_virus(virus);
+
18387 
+
18388  return;
+
18389 
+
18390 }
+
18391 
+
18392 template<typename TSeq>
+
18393 inline ModelSISD<TSeq>::ModelSISD(
+
18394  const std::string & vname,
+
18395  epiworld_double prevalence,
+
18396  epiworld_double transmission_rate,
+
18397  epiworld_double recovery_rate,
+
18398  epiworld_double death_rate
+
18399  )
+
18400 {
+
18401 
+
18402  ModelSISD<TSeq>(
+
18403  *this,
+
18404  vname,
+
18405  prevalence,
+
18406  transmission_rate,
+
18407  recovery_rate,
+
18408  death_rate
+
18409  );
+
18410 
+
18411  return;
+
18412 
+
18413 }
+
18414 
+
18415 #endif
+
18416 /*//////////////////////////////////////////////////////////////////////////////
+
18418 
+
18419  End of -include/epiworld//models/sisd.hpp-
+
18420 
+
18423 
+
18424 
+
18425 /*//////////////////////////////////////////////////////////////////////////////
+
18427 
+
18428  Start of -include/epiworld//models/seird.hpp-
+
18429 
+
18432 
+
18433 
+
18434 #ifndef EPIWORLD_MODELS_SEIRD_HPP
+
18435 #define EPIWORLD_MODELS_SEIRD_HPP
+
18436 
+
18440 template<typename TSeq = int>
+
18441 class ModelSEIRD : public epiworld::Model<TSeq>
+
18442 {
+
18443 
+
18444 public:
+
18445  static const int SUSCEPTIBLE = 0;
+
18446  static const int EXPOSED = 1;
+
18447  static const int INFECTED = 2;
+
18448  static const int REMOVED = 3;
+
18449  static const int DECEASED = 4;
+
18450 
+
18451  ModelSEIRD() {};
+
18452 
+
18465  ModelSEIRD(
+
18466  ModelSEIRD<TSeq> & model,
+
18467  const std::string & vname,
+
18468  epiworld_double prevalence,
+
18469  epiworld_double transmission_rate,
+
18470  epiworld_double avg_incubation_days,
+
18471  epiworld_double recovery_rate,
+
18472  epiworld_double death_rate
+
18473  );
+
18474 
+
18485  ModelSEIRD(
+
18486  const std::string & vname,
+
18487  epiworld_double prevalence,
+
18488  epiworld_double transmission_rate,
+
18489  epiworld_double avg_incubation_days,
+
18490  epiworld_double recovery_rate,
+
18491  epiworld_double death_rate
+
18492  );
+
18493 
+
18494  epiworld::UpdateFun<TSeq> update_exposed_seir = [](
+
18495  epiworld::Agent<TSeq> * p,
+
18496  epiworld::Model<TSeq> * m
+
18497  ) -> void {
+
18498 
+
18499  // Getting the virus
+
18500  auto v = p->get_virus();
+
18501 
+
18502  // Does the agent become infected?
+
18503  if (m->runif() < 1.0/(v->get_incubation(m)))
+
18504  p->change_state(m, ModelSEIRD<TSeq>::INFECTED);
+
18505 
+
18506  return;
+
18507  };
+
18508 
+
18509 
+
18510  epiworld::UpdateFun<TSeq> update_infected = [](
+
18511  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
+
18512  ) -> void {
+
18513 
+
18514  // Odd: Die, Even: Recover
+
18515  epiworld_fast_uint n_events = 0u;
+
18516 
+
18517  const auto & v = p->get_virus();
+
18518 
+
18519  // Die
+
18520  m->array_double_tmp[n_events++] =
+
18521  v->get_prob_death(m) * (1.0 - p->get_death_reduction(v, m));
+
18522 
+
18523  // Recover
+
18524  m->array_double_tmp[n_events++] =
+
18525  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
+
18526 
+
18527 
+
18528 #ifdef EPI_DEBUG
+
18529  if (n_events == 0u)
+
18530  {
+
18531  printf_epiworld(
+
18532  "[epi-debug] agent %i has 0 possible events!!\n",
+
18533  static_cast<int>(p->get_id())
+
18534  );
+
18535  throw std::logic_error("Zero events in exposed.");
+
18536  }
+
18537 #else
+
18538  if (n_events == 0u)
+
18539  return;
+
18540 #endif
+
18541 
+
18542 
+
18543  // Running the roulette
+
18544  int which = roulette(n_events, m);
+
18545 
+
18546  if (which < 0)
+
18547  return;
+
18548 
+
18549  // Which roulette happen?
+
18550  if ((which % 2) == 0) // If odd
+
18551  {
+
18552 
+
18553  p->rm_agent_by_virus(m);
+
18554 
+
18555  } else {
+
18556 
+
18557  p->rm_virus(m);
+
18558 
+
18559  }
+
18560 
+
18561  return ;
+
18562 
+
18563 
+
18564 
+
18565  return;
+
18566 
+
18567  };
+
18568 
+
18569  ModelSEIRD<TSeq> & initial_states(
+
18570  std::vector< double > proportions_,
+
18571  std::vector< int > queue_ = {}
+
18572  );
+
18573 
+
18574 };
+
18575 
+
18576 
+
18577 
+
18578 template<typename TSeq>
+
18579 inline ModelSEIRD<TSeq>::ModelSEIRD(
+
18580  ModelSEIRD<TSeq> & model,
+
18581  const std::string & vname,
+
18582  epiworld_double prevalence,
+
18583  epiworld_double transmission_rate,
+
18584  epiworld_double avg_incubation_days,
+
18585  epiworld_double recovery_rate,
+
18586  epiworld_double death_rate
+
18587 )
+
18588 {
+
18589 
+
18590  // Adding statuses
+
18591  model.add_state("Susceptible", epiworld::default_update_susceptible<TSeq>);
+
18592  model.add_state("Exposed", model.update_exposed_seir);
+
18593  model.add_state("Infected", model.update_infected);
+
18594  model.add_state("Removed");
+
18595  model.add_state("Deceased");
+
18596 
+
18597  // Setting up parameters
+
18598  model.add_param(transmission_rate, "Transmission rate");
+
18599  model.add_param(avg_incubation_days, "Incubation days");
+
18600  model.add_param(recovery_rate, "Recovery rate");
+
18601  model.add_param(death_rate, "Death rate");
+
18602 
+
18603  // Preparing the virus -------------------------------------------
+
18604  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
18605  virus.set_state(ModelSEIRD<TSeq>::EXPOSED, ModelSEIRD<TSeq>::REMOVED, ModelSEIRD<TSeq>::DECEASED);
+
18606 
+
18607  virus.set_prob_infecting(&model("Transmission rate"));
+
18608  virus.set_incubation(&model("Incubation days"));
+
18609  virus.set_prob_death(&model("Death rate"));
+
18610  virus.set_prob_recovery(&model("Recovery rate"));
18611 
-
18612  return;
-
18613 
-
18614 }
-
18615 
-
18616 template<typename TSeq>
-
18617 inline ModelSEIRD<TSeq> & ModelSEIRD<TSeq>::initial_states(
-
18618  std::vector< double > proportions_,
-
18619  std::vector< int > /**/
-
18620 ) {
-
18621 
- -
18623  create_init_function_seird<TSeq>(proportions_)
-
18624  ;
-
18625 
-
18626  return *this;
-
18627 
-
18628 }
-
18629 
-
18630 
-
18631 #endif
-
18632 /*//////////////////////////////////////////////////////////////////////////////
-
18634 
-
18635  End of -include/epiworld//models/seird.hpp-
-
18636 
-
18639 
-
18640 
-
18641 /*//////////////////////////////////////////////////////////////////////////////
-
18643 
-
18644  Start of -include/epiworld//models/sirdconnected.hpp-
+
18612  // Adding the tool and the virus
+
18613  model.add_virus(virus);
+
18614 
+
18615  model.set_name("Susceptible-Exposed-Infected-Removed-Deceased (SEIRD)");
+
18616 
+
18617  return;
+
18618 
+
18619 }
+
18620 
+
18621 template<typename TSeq>
+
18622 inline ModelSEIRD<TSeq>::ModelSEIRD(
+
18623  const std::string & vname,
+
18624  epiworld_double prevalence,
+
18625  epiworld_double transmission_rate,
+
18626  epiworld_double avg_incubation_days,
+
18627  epiworld_double recovery_rate,
+
18628  epiworld_double death_rate
+
18629 )
+
18630 {
+
18631 
+
18632  ModelSEIRD<TSeq>(
+
18633  *this,
+
18634  vname,
+
18635  prevalence,
+
18636  transmission_rate,
+
18637  avg_incubation_days,
+
18638  recovery_rate,
+
18639  death_rate
+
18640  );
+
18641 
+
18642  return;
+
18643 
+
18644 }
18645 
-
18648 
-
18649 
-
18650 #ifndef EPIWORLD_MODELS_SIRDCONNECTED_HPP
-
18651 #define EPIWORLD_MODELS_SIRDCONNECTED_HPP
-
18652 
-
18653 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
18654 class ModelSIRDCONN : public epiworld::Model<TSeq>
-
18655 {
-
18656 public:
-
18657  static const int SUSCEPTIBLE = 0;
-
18658  static const int INFECTED = 1;
-
18659  static const int RECOVERED = 2;
-
18660  static const int DECEASED = 3;
-
18661 
-
18662  ModelSIRDCONN() {
-
18663 
-
18664  // tracked_agents_infected.reserve(1e4);
-
18665  // tracked_agents_infected_next.reserve(1e4);
+
18646 template<typename TSeq>
+
18647 inline ModelSEIRD<TSeq> & ModelSEIRD<TSeq>::initial_states(
+
18648  std::vector< double > proportions_,
+
18649  std::vector< int > /**/
+
18650 ) {
+
18651 
+ +
18653  create_init_function_seird<TSeq>(proportions_)
+
18654  ;
+
18655 
+
18656  return *this;
+
18657 
+
18658 }
+
18659 
+
18660 
+
18661 #endif
+
18662 /*//////////////////////////////////////////////////////////////////////////////
+
18664 
+
18665  End of -include/epiworld//models/seird.hpp-
18666 
-
18667  };
-
18668 
-
18669  ModelSIRDCONN(
-
18670  ModelSIRDCONN<TSeq> & model,
-
18671  const std::string & vname,
-
18672  epiworld_fast_uint n,
-
18673  epiworld_double prevalence,
-
18674  epiworld_double contact_rate,
-
18675  epiworld_double transmission_rate,
-
18676  epiworld_double recovery_rate,
-
18677  epiworld_double death_rate
-
18678  );
+
18669 
+
18670 
+
18671 /*//////////////////////////////////////////////////////////////////////////////
+
18673 
+
18674  Start of -include/epiworld//models/sirdconnected.hpp-
+
18675 
+
18678 
18679 
-
18680  ModelSIRDCONN(
-
18681  const std::string & vname,
-
18682  epiworld_fast_uint n,
-
18683  epiworld_double prevalence,
-
18684  epiworld_double contact_rate,
-
18685  epiworld_double transmission_rate,
-
18686  epiworld_double recovery_rate,
-
18687  epiworld_double death_rate
-
18688  );
-
18689 
-
18690  // Tracking who is infected and who is not
-
18691  // std::vector< epiworld::Agent<TSeq>* > tracked_agents_infected = {};
-
18692  // std::vector< epiworld::Agent<TSeq>* > tracked_agents_infected_next = {};
-
18693  // std::vector< epiworld_double > tracked_agents_weight = {};
-
18694  // std::vector< epiworld_double > tracked_agents_weight_next = {};
-
18695 
-
18696  // int tracked_ninfected = 0;
-
18697  // int tracked_ninfected_next = 0;
-
18698  // epiworld_double tracked_current_infect_prob = 0.0;
-
18699 
-
18700  ModelSIRDCONN<TSeq> & run(
-
18701  epiworld_fast_uint ndays,
-
18702  int seed = -1
-
18703  );
-
18704 
-
18705  void reset();
-
18706 
-
18707  Model<TSeq> * clone_ptr();
-
18708 
+
18680 #ifndef EPIWORLD_MODELS_SIRDCONNECTED_HPP
+
18681 #define EPIWORLD_MODELS_SIRDCONNECTED_HPP
+
18682 
+
18683 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
18684 class ModelSIRDCONN : public epiworld::Model<TSeq>
+
18685 {
+
18686 public:
+
18687  static const int SUSCEPTIBLE = 0;
+
18688  static const int INFECTED = 1;
+
18689  static const int RECOVERED = 2;
+
18690  static const int DECEASED = 3;
+
18691 
+
18692  ModelSIRDCONN() {
+
18693 
+
18694  // tracked_agents_infected.reserve(1e4);
+
18695  // tracked_agents_infected_next.reserve(1e4);
+
18696 
+
18697  };
+
18698 
+
18699  ModelSIRDCONN(
+
18700  ModelSIRDCONN<TSeq> & model,
+
18701  const std::string & vname,
+
18702  epiworld_fast_uint n,
+
18703  epiworld_double prevalence,
+
18704  epiworld_double contact_rate,
+
18705  epiworld_double transmission_rate,
+
18706  epiworld_double recovery_rate,
+
18707  epiworld_double death_rate
+
18708  );
18709 
-
18710 };
-
18711 
-
18712 template<typename TSeq>
-
18713 inline ModelSIRDCONN<TSeq> & ModelSIRDCONN<TSeq>::run(
-
18714  epiworld_fast_uint ndays,
-
18715  int seed
-
18716 )
-
18717 {
-
18718 
-
18719  Model<TSeq>::run(ndays, seed);
-
18720 
-
18721  return *this;
-
18722 
-
18723 }
-
18724 
-
18725 template<typename TSeq>
-
18726 inline void ModelSIRDCONN<TSeq>::reset()
-
18727 {
-
18728 
-
18729  Model<TSeq>::reset();
-
18730 
-
18731  // Model<TSeq>::set_rand_binom(
-
18732  // Model<TSeq>::size(),
-
18733  // static_cast<double>(
-
18734  // Model<TSeq>::par("Contact rate"))/
-
18735  // static_cast<double>(Model<TSeq>::size())
-
18736  // );
-
18737 
-
18738  return;
+
18710  ModelSIRDCONN(
+
18711  const std::string & vname,
+
18712  epiworld_fast_uint n,
+
18713  epiworld_double prevalence,
+
18714  epiworld_double contact_rate,
+
18715  epiworld_double transmission_rate,
+
18716  epiworld_double recovery_rate,
+
18717  epiworld_double death_rate
+
18718  );
+
18719 
+
18720  // Tracking who is infected and who is not
+
18721  // std::vector< epiworld::Agent<TSeq>* > tracked_agents_infected = {};
+
18722  // std::vector< epiworld::Agent<TSeq>* > tracked_agents_infected_next = {};
+
18723  // std::vector< epiworld_double > tracked_agents_weight = {};
+
18724  // std::vector< epiworld_double > tracked_agents_weight_next = {};
+
18725 
+
18726  // int tracked_ninfected = 0;
+
18727  // int tracked_ninfected_next = 0;
+
18728  // epiworld_double tracked_current_infect_prob = 0.0;
+
18729 
+
18730  ModelSIRDCONN<TSeq> & run(
+
18731  epiworld_fast_uint ndays,
+
18732  int seed = -1
+
18733  );
+
18734 
+
18735  void reset();
+
18736 
+
18737  Model<TSeq> * clone_ptr();
+
18738 
18739 
-
18740 }
+
18740 };
18741 
18742 template<typename TSeq>
-
18743 inline Model<TSeq> * ModelSIRDCONN<TSeq>::clone_ptr()
-
18744 {
-
18745 
-
18746  ModelSIRDCONN<TSeq> * ptr = new ModelSIRDCONN<TSeq>(
-
18747  *dynamic_cast<const ModelSIRDCONN<TSeq>*>(this)
-
18748  );
-
18749 
-
18750  return dynamic_cast< Model<TSeq> *>(ptr);
-
18751 
-
18752 }
-
18753 
-
18765 template<typename TSeq>
-
18766 inline ModelSIRDCONN<TSeq>::ModelSIRDCONN(
-
18767  ModelSIRDCONN<TSeq> & model,
-
18768  const std::string & vname,
-
18769  epiworld_fast_uint n,
-
18770  epiworld_double prevalence,
-
18771  epiworld_double contact_rate,
-
18772  epiworld_double transmission_rate,
-
18773  epiworld_double recovery_rate,
-
18774  epiworld_double death_rate
-
18775  // epiworld_double prob_reinfection
-
18776  )
-
18777 {
-
18778 
+
18743 inline ModelSIRDCONN<TSeq> & ModelSIRDCONN<TSeq>::run(
+
18744  epiworld_fast_uint ndays,
+
18745  int seed
+
18746 )
+
18747 {
+
18748 
+
18749  Model<TSeq>::run(ndays, seed);
+
18750 
+
18751  return *this;
+
18752 
+
18753 }
+
18754 
+
18755 template<typename TSeq>
+
18756 inline void ModelSIRDCONN<TSeq>::reset()
+
18757 {
+
18758 
+
18759  Model<TSeq>::reset();
+
18760 
+
18761  // Model<TSeq>::set_rand_binom(
+
18762  // Model<TSeq>::size(),
+
18763  // static_cast<double>(
+
18764  // Model<TSeq>::par("Contact rate"))/
+
18765  // static_cast<double>(Model<TSeq>::size())
+
18766  // );
+
18767 
+
18768  return;
+
18769 
+
18770 }
+
18771 
+
18772 template<typename TSeq>
+
18773 inline Model<TSeq> * ModelSIRDCONN<TSeq>::clone_ptr()
+
18774 {
+
18775 
+
18776  ModelSIRDCONN<TSeq> * ptr = new ModelSIRDCONN<TSeq>(
+
18777  *dynamic_cast<const ModelSIRDCONN<TSeq>*>(this)
+
18778  );
18779 
-
18780 
-
18781  epiworld::UpdateFun<TSeq> update_susceptible = [](
-
18782  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
-
18783  ) -> void
-
18784  {
-
18785 
-
18786  // Sampling how many individuals
-
18787  m->set_rand_binom(
-
18788  m->size(),
-
18789  static_cast<double>(
-
18790  m->par("Contact rate"))/
-
18791  static_cast<double>(m->size())
-
18792  );
-
18793 
-
18794  int ndraw = m->rbinom();
-
18795 
-
18796  if (ndraw == 0)
-
18797  return;
-
18798 
-
18799  // Drawing from the set
-
18800  int nviruses_tmp = 0;
-
18801  for (int i = 0; i < ndraw; ++i)
-
18802  {
-
18803  // Now selecting who is transmitting the disease
-
18804  int which = static_cast<int>(
-
18805  std::floor(m->size() * m->runif())
-
18806  );
-
18807 
-
18808  /* There is a bug in which runif() returns 1.0. It is rare, but
-
18809  * we saw it here. See the Notes section in the C++ manual
-
18810  * https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/random/uniform_real_distribution&oldid=133329
-
18811  * And the reported bug in GCC:
-
18812  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
-
18813  *
-
18814  */
-
18815  if (which == static_cast<int>(m->size()))
-
18816  --which;
-
18817 
-
18818  // Can't sample itself
-
18819  if (which == static_cast<int>(p->get_id()))
-
18820  continue;
-
18821 
-
18822  // If the neighbor is infected, then proceed
-
18823  auto & neighbor = m->get_agents()[which];
-
18824  if (neighbor.get_state() == ModelSIRDCONN<TSeq>::INFECTED)
-
18825  {
-
18826 
-
18827  const auto & v = neighbor.get_virus();
-
18828 
-
18829  #ifdef EPI_DEBUG
-
18830  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
-
18831  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
18832  #endif
-
18833 
-
18834  /* And it is a function of susceptibility_reduction as well */
-
18835  m->array_double_tmp[nviruses_tmp] =
-
18836  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
18837  v->get_prob_infecting(m) *
-
18838  (1.0 - neighbor.get_transmission_reduction(v, m))
-
18839  ;
-
18840 
-
18841  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
18842 
-
18843  }
-
18844  }
-
18845 
-
18846  // No virus to compute
-
18847  if (nviruses_tmp == 0u)
-
18848  return;
-
18849 
-
18850  // Running the roulette
-
18851  int which = roulette(nviruses_tmp, m);
-
18852 
-
18853  if (which < 0)
-
18854  return;
-
18855 
-
18856  p->set_virus(*m->array_virus_tmp[which], m);
-
18857 
-
18858  return;
-
18859 
-
18860  };
-
18861 
-
18862 
-
18863  epiworld::UpdateFun<TSeq> update_infected = [](
- -
18865  ) -> void {
-
18866 
-
18867  auto state = p->get_state();
-
18868 
-
18869  if (state == ModelSIRDCONN<TSeq>::INFECTED)
-
18870  {
-
18871 
+
18780  return dynamic_cast< Model<TSeq> *>(ptr);
+
18781 
+
18782 }
+
18783 
+
18795 template<typename TSeq>
+
18796 inline ModelSIRDCONN<TSeq>::ModelSIRDCONN(
+
18797  ModelSIRDCONN<TSeq> & model,
+
18798  const std::string & vname,
+
18799  epiworld_fast_uint n,
+
18800  epiworld_double prevalence,
+
18801  epiworld_double contact_rate,
+
18802  epiworld_double transmission_rate,
+
18803  epiworld_double recovery_rate,
+
18804  epiworld_double death_rate
+
18805  // epiworld_double prob_reinfection
+
18806  )
+
18807 {
+
18808 
+
18809 
+
18810 
+
18811  epiworld::UpdateFun<TSeq> update_susceptible = [](
+
18812  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
+
18813  ) -> void
+
18814  {
+
18815 
+
18816  // Sampling how many individuals
+
18817  m->set_rand_binom(
+
18818  m->size(),
+
18819  static_cast<double>(
+
18820  m->par("Contact rate"))/
+
18821  static_cast<double>(m->size())
+
18822  );
+
18823 
+
18824  int ndraw = m->rbinom();
+
18825 
+
18826  if (ndraw == 0)
+
18827  return;
+
18828 
+
18829  // Drawing from the set
+
18830  int nviruses_tmp = 0;
+
18831  for (int i = 0; i < ndraw; ++i)
+
18832  {
+
18833  // Now selecting who is transmitting the disease
+
18834  int which = static_cast<int>(
+
18835  std::floor(m->size() * m->runif())
+
18836  );
+
18837 
+
18838  /* There is a bug in which runif() returns 1.0. It is rare, but
+
18839  * we saw it here. See the Notes section in the C++ manual
+
18840  * https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/random/uniform_real_distribution&oldid=133329
+
18841  * And the reported bug in GCC:
+
18842  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
+
18843  *
+
18844  */
+
18845  if (which == static_cast<int>(m->size()))
+
18846  --which;
+
18847 
+
18848  // Can't sample itself
+
18849  if (which == static_cast<int>(p->get_id()))
+
18850  continue;
+
18851 
+
18852  // If the neighbor is infected, then proceed
+
18853  auto & neighbor = m->get_agents()[which];
+
18854  if (neighbor.get_state() == ModelSIRDCONN<TSeq>::INFECTED)
+
18855  {
+
18856 
+
18857  const auto & v = neighbor.get_virus();
+
18858 
+
18859  #ifdef EPI_DEBUG
+
18860  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
+
18861  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
18862  #endif
+
18863 
+
18864  /* And it is a function of susceptibility_reduction as well */
+
18865  m->array_double_tmp[nviruses_tmp] =
+
18866  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
18867  v->get_prob_infecting(m) *
+
18868  (1.0 - neighbor.get_transmission_reduction(v, m))
+
18869  ;
+
18870 
+
18871  m->array_virus_tmp[nviruses_tmp++] = &(*v);
18872 
-
18873  // Odd: Die, Even: Recover
-
18874  epiworld_fast_uint n_events = 0u;
-
18875  const auto & v = p->get_virus();
-
18876 
-
18877  // Die
-
18878  m->array_double_tmp[n_events++] =
-
18879  v->get_prob_death(m) * (1.0 - p->get_death_reduction(v, m));
-
18880 
-
18881  // Recover
-
18882  m->array_double_tmp[n_events++] =
-
18883  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
-
18884 
-
18885  #ifdef EPI_DEBUG
-
18886  if (n_events == 0u)
-
18887  {
-
18888  printf_epiworld(
-
18889  "[epi-debug] agent %i has 0 possible events!!\n",
-
18890  static_cast<int>(p->get_id())
-
18891  );
-
18892  throw std::logic_error("Zero events in exposed.");
-
18893  }
-
18894  #else
-
18895  if (n_events == 0u)
-
18896  return;
-
18897  #endif
-
18898 
-
18899 
-
18900  // Running the roulette
-
18901  int which = roulette(n_events, m);
-
18902 
-
18903  if (which < 0)
-
18904  return;
-
18905 
-
18906  // Which roulette happen?
-
18907  if ((which % 2) == 0) // If odd
-
18908  {
-
18909 
-
18910  p->rm_agent_by_virus(m);
-
18911 
-
18912  } else {
-
18913 
-
18914  p->rm_virus(m);
-
18915 
-
18916  }
-
18917 
-
18918  return ;
-
18919 
-
18920  } else
-
18921  throw std::logic_error("This function can only be applied to infected individuals. (SIR)") ;
-
18922 
-
18923  return;
-
18924 
-
18925  };
-
18926 
-
18927  // state
-
18928  model.add_state("Susceptible", update_susceptible);
-
18929  model.add_state("Infected", update_infected);
-
18930  model.add_state("Recovered");
-
18931  model.add_state("Deceased");
-
18932 
-
18933 
-
18934  // Setting up parameters
-
18935  model.add_param(contact_rate, "Contact rate");
-
18936  model.add_param(transmission_rate, "Transmission rate");
-
18937  model.add_param(recovery_rate, "Recovery rate");
-
18938  model.add_param(death_rate, "Death rate");
-
18939  // model.add_param(prob_reinfection, "Prob. Reinfection");
-
18940 
-
18941  // Preparing the virus -------------------------------------------
-
18942  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
18943  virus.set_state(1, 2, 3);
-
18944  virus.set_prob_infecting(&model("Transmission rate"));
-
18945  virus.set_prob_recovery(&model("Recovery rate"));
-
18946  virus.set_prob_death(&model("Death rate"));
-
18947 
-
18948  model.add_virus(virus);
+
18873  }
+
18874  }
+
18875 
+
18876  // No virus to compute
+
18877  if (nviruses_tmp == 0u)
+
18878  return;
+
18879 
+
18880  // Running the roulette
+
18881  int which = roulette(nviruses_tmp, m);
+
18882 
+
18883  if (which < 0)
+
18884  return;
+
18885 
+
18886  p->set_virus(*m->array_virus_tmp[which], m);
+
18887 
+
18888  return;
+
18889 
+
18890  };
+
18891 
+
18892 
+
18893  epiworld::UpdateFun<TSeq> update_infected = [](
+ +
18895  ) -> void {
+
18896 
+
18897  auto state = p->get_state();
+
18898 
+
18899  if (state == ModelSIRDCONN<TSeq>::INFECTED)
+
18900  {
+
18901 
+
18902 
+
18903  // Odd: Die, Even: Recover
+
18904  epiworld_fast_uint n_events = 0u;
+
18905  const auto & v = p->get_virus();
+
18906 
+
18907  // Die
+
18908  m->array_double_tmp[n_events++] =
+
18909  v->get_prob_death(m) * (1.0 - p->get_death_reduction(v, m));
+
18910 
+
18911  // Recover
+
18912  m->array_double_tmp[n_events++] =
+
18913  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
+
18914 
+
18915  #ifdef EPI_DEBUG
+
18916  if (n_events == 0u)
+
18917  {
+
18918  printf_epiworld(
+
18919  "[epi-debug] agent %i has 0 possible events!!\n",
+
18920  static_cast<int>(p->get_id())
+
18921  );
+
18922  throw std::logic_error("Zero events in exposed.");
+
18923  }
+
18924  #else
+
18925  if (n_events == 0u)
+
18926  return;
+
18927  #endif
+
18928 
+
18929 
+
18930  // Running the roulette
+
18931  int which = roulette(n_events, m);
+
18932 
+
18933  if (which < 0)
+
18934  return;
+
18935 
+
18936  // Which roulette happen?
+
18937  if ((which % 2) == 0) // If odd
+
18938  {
+
18939 
+
18940  p->rm_agent_by_virus(m);
+
18941 
+
18942  } else {
+
18943 
+
18944  p->rm_virus(m);
+
18945 
+
18946  }
+
18947 
+
18948  return ;
18949 
-
18950  model.queuing_off(); // No queuing need
-
18951 
-
18952  model.agents_empty_graph(n);
-
18953 
-
18954  model.set_name("Susceptible-Infected-Removed-Deceased (SIRD) (connected)");
-
18955 
-
18956  return;
-
18957 
-
18958 }
-
18959 
-
18960 template<typename TSeq>
- -
18962  const std::string & vname,
-
18963  epiworld_fast_uint n,
-
18964  epiworld_double prevalence,
-
18965  epiworld_double contact_rate,
-
18966  epiworld_double transmission_rate,
-
18967  epiworld_double recovery_rate,
-
18968  epiworld_double death_rate
-
18969  )
-
18970 {
-
18971 
-
18972  ModelSIRDCONN(
-
18973  *this,
-
18974  vname,
-
18975  n,
-
18976  prevalence,
-
18977  contact_rate,
-
18978  transmission_rate,
-
18979  recovery_rate,
-
18980  death_rate
-
18981  );
-
18982 
-
18983  return;
-
18984 
-
18985 }
-
18986 
+
18950  } else
+
18951  throw std::logic_error("This function can only be applied to infected individuals. (SIR)") ;
+
18952 
+
18953  return;
+
18954 
+
18955  };
+
18956 
+
18957  // state
+
18958  model.add_state("Susceptible", update_susceptible);
+
18959  model.add_state("Infected", update_infected);
+
18960  model.add_state("Recovered");
+
18961  model.add_state("Deceased");
+
18962 
+
18963 
+
18964  // Setting up parameters
+
18965  model.add_param(contact_rate, "Contact rate");
+
18966  model.add_param(transmission_rate, "Transmission rate");
+
18967  model.add_param(recovery_rate, "Recovery rate");
+
18968  model.add_param(death_rate, "Death rate");
+
18969  // model.add_param(prob_reinfection, "Prob. Reinfection");
+
18970 
+
18971  // Preparing the virus -------------------------------------------
+
18972  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
18973  virus.set_state(1, 2, 3);
+
18974  virus.set_prob_infecting(&model("Transmission rate"));
+
18975  virus.set_prob_recovery(&model("Recovery rate"));
+
18976  virus.set_prob_death(&model("Death rate"));
+
18977 
+
18978  model.add_virus(virus);
+
18979 
+
18980  model.queuing_off(); // No queuing need
+
18981 
+
18982  model.agents_empty_graph(n);
+
18983 
+
18984  model.set_name("Susceptible-Infected-Removed-Deceased (SIRD) (connected)");
+
18985 
+
18986  return;
18987 
-
18988 #endif
-
18989 /*//////////////////////////////////////////////////////////////////////////////
-
18991 
-
18992  End of -include/epiworld//models/sirdconnected.hpp-
-
18993 
-
18996 
-
18997 
-
18998 /*//////////////////////////////////////////////////////////////////////////////
-
19000 
-
19001  Start of -include/epiworld//models/seirdconnected.hpp-
-
19002 
-
19005 
-
19006 
-
19007 #ifndef EPIWORLD_MODELS_SEIRDCONNECTED_HPP
-
19008 #define EPIWORLD_MODELS_SEIRDCONNECTED_HPP
-
19009 
-
19010 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
19011 class ModelSEIRDCONN : public epiworld::Model<TSeq>
-
19012 {
-
19013 private:
-
19014  std::vector< epiworld::Agent<TSeq> * > infected;
-
19015  void update_infected();
-
19016 
-
19017 public:
-
19018 
-
19019  static const int SUSCEPTIBLE = 0;
-
19020  static const int EXPOSED = 1;
-
19021  static const int INFECTED = 2;
-
19022  static const int REMOVED = 3;
-
19023  static const int DECEASED = 4;
-
19024 
-
19025  ModelSEIRDCONN() {};
+
18988 }
+
18989 
+
18990 template<typename TSeq>
+ +
18992  const std::string & vname,
+
18993  epiworld_fast_uint n,
+
18994  epiworld_double prevalence,
+
18995  epiworld_double contact_rate,
+
18996  epiworld_double transmission_rate,
+
18997  epiworld_double recovery_rate,
+
18998  epiworld_double death_rate
+
18999  )
+
19000 {
+
19001 
+
19002  ModelSIRDCONN(
+
19003  *this,
+
19004  vname,
+
19005  n,
+
19006  prevalence,
+
19007  contact_rate,
+
19008  transmission_rate,
+
19009  recovery_rate,
+
19010  death_rate
+
19011  );
+
19012 
+
19013  return;
+
19014 
+
19015 }
+
19016 
+
19017 
+
19018 #endif
+
19019 /*//////////////////////////////////////////////////////////////////////////////
+
19021 
+
19022  End of -include/epiworld//models/sirdconnected.hpp-
+
19023 
19026 
-
19027  ModelSEIRDCONN(
-
19028  ModelSEIRDCONN<TSeq> & model,
-
19029  const std::string & vname,
-
19030  epiworld_fast_uint n,
-
19031  epiworld_double prevalence,
-
19032  epiworld_double contact_rate,
-
19033  epiworld_double transmission_rate,
-
19034  epiworld_double avg_incubation_days,
-
19035  epiworld_double recovery_rate,
-
19036  epiworld_double death_rate
-
19037  );
-
19038 
-
19039  ModelSEIRDCONN(
-
19040  const std::string & vname,
-
19041  epiworld_fast_uint n,
-
19042  epiworld_double prevalence,
-
19043  epiworld_double contact_rate,
-
19044  epiworld_double transmission_rate,
-
19045  epiworld_double avg_incubation_days,
-
19046  epiworld_double recovery_rate,
-
19047  epiworld_double death_rate
-
19048  );
-
19049 
-
19050  ModelSEIRDCONN<TSeq> & run(
-
19051  epiworld_fast_uint ndays,
-
19052  int seed = -1
-
19053  );
+
19027 
+
19028 /*//////////////////////////////////////////////////////////////////////////////
+
19030 
+
19031  Start of -include/epiworld//models/seirdconnected.hpp-
+
19032 
+
19035 
+
19036 
+
19037 #ifndef EPIWORLD_MODELS_SEIRDCONNECTED_HPP
+
19038 #define EPIWORLD_MODELS_SEIRDCONNECTED_HPP
+
19039 
+
19040 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
19041 class ModelSEIRDCONN : public epiworld::Model<TSeq>
+
19042 {
+
19043 private:
+
19044  std::vector< epiworld::Agent<TSeq> * > infected;
+
19045  void update_infected();
+
19046 
+
19047 public:
+
19048 
+
19049  static const int SUSCEPTIBLE = 0;
+
19050  static const int EXPOSED = 1;
+
19051  static const int INFECTED = 2;
+
19052  static const int REMOVED = 3;
+
19053  static const int DECEASED = 4;
19054 
-
19055  void reset();
+
19055  ModelSEIRDCONN() {};
19056 
-
19057  Model<TSeq> * clone_ptr();
-
19058 
-
19065  ModelSEIRDCONN<TSeq> & initial_states(
-
19066  std::vector< double > proportions_,
-
19067  std::vector< int > queue_ = {}
-
19068  );
-
19069 
-
19070  size_t get_n_infected() const
-
19071  {
-
19072  return infected.size();
-
19073  }
-
19074 
-
19075 };
-
19076 
-
19077 template<typename TSeq>
-
19078 inline void ModelSEIRDCONN<TSeq>::update_infected()
-
19079 {
-
19080  infected.clear();
-
19081  infected.reserve(this->size());
-
19082 
-
19083  for (auto & p : this->get_agents())
-
19084  {
-
19085  if (p.get_state() == ModelSEIRDCONN<TSeq>::INFECTED)
-
19086  {
-
19087  infected.push_back(&p);
-
19088  }
-
19089  }
-
19090 
-
19091  Model<TSeq>::set_rand_binom(
-
19092  this->get_n_infected(),
-
19093  static_cast<double>(Model<TSeq>::par("Contact rate"))/
-
19094  static_cast<double>(Model<TSeq>::size())
-
19095  );
-
19096 
-
19097  return;
-
19098 }
+
19057  ModelSEIRDCONN(
+
19058  ModelSEIRDCONN<TSeq> & model,
+
19059  const std::string & vname,
+
19060  epiworld_fast_uint n,
+
19061  epiworld_double prevalence,
+
19062  epiworld_double contact_rate,
+
19063  epiworld_double transmission_rate,
+
19064  epiworld_double avg_incubation_days,
+
19065  epiworld_double recovery_rate,
+
19066  epiworld_double death_rate
+
19067  );
+
19068 
+
19069  ModelSEIRDCONN(
+
19070  const std::string & vname,
+
19071  epiworld_fast_uint n,
+
19072  epiworld_double prevalence,
+
19073  epiworld_double contact_rate,
+
19074  epiworld_double transmission_rate,
+
19075  epiworld_double avg_incubation_days,
+
19076  epiworld_double recovery_rate,
+
19077  epiworld_double death_rate
+
19078  );
+
19079 
+
19080  ModelSEIRDCONN<TSeq> & run(
+
19081  epiworld_fast_uint ndays,
+
19082  int seed = -1
+
19083  );
+
19084 
+
19085  void reset();
+
19086 
+
19087  Model<TSeq> * clone_ptr();
+
19088 
+
19095  ModelSEIRDCONN<TSeq> & initial_states(
+
19096  std::vector< double > proportions_,
+
19097  std::vector< int > queue_ = {}
+
19098  );
19099 
-
19100 template<typename TSeq>
-
19101 inline ModelSEIRDCONN<TSeq> & ModelSEIRDCONN<TSeq>::run(
-
19102  epiworld_fast_uint ndays,
-
19103  int seed
-
19104 )
-
19105 {
-
19106 
-
19107  Model<TSeq>::run(ndays, seed);
-
19108 
-
19109  return *this;
-
19110 
-
19111 }
+
19100  size_t get_n_infected() const
+
19101  {
+
19102  return infected.size();
+
19103  }
+
19104 
+
19105 };
+
19106 
+
19107 template<typename TSeq>
+
19108 inline void ModelSEIRDCONN<TSeq>::update_infected()
+
19109 {
+
19110  infected.clear();
+
19111  infected.reserve(this->size());
19112 
-
19113 template<typename TSeq>
-
19114 inline void ModelSEIRDCONN<TSeq>::reset()
-
19115 {
-
19116 
-
19117  Model<TSeq>::reset();
-
19118 
-
19119  this->update_infected();
+
19113  for (auto & p : this->get_agents())
+
19114  {
+
19115  if (p.get_state() == ModelSEIRDCONN<TSeq>::INFECTED)
+
19116  {
+
19117  infected.push_back(&p);
+
19118  }
+
19119  }
19120 
-
19121  return;
-
19122 
-
19123 }
-
19124 
-
19125 template<typename TSeq>
-
19126 inline Model<TSeq> * ModelSEIRDCONN<TSeq>::clone_ptr()
-
19127 {
-
19128 
-
19129  ModelSEIRDCONN<TSeq> * ptr = new ModelSEIRDCONN<TSeq>(
-
19130  *dynamic_cast<const ModelSEIRDCONN<TSeq>*>(this)
-
19131  );
-
19132 
-
19133  return dynamic_cast< Model<TSeq> *>(ptr);
-
19134 
-
19135 }
-
19136 
-
19148 template<typename TSeq>
-
19149 inline ModelSEIRDCONN<TSeq>::ModelSEIRDCONN(
-
19150  ModelSEIRDCONN<TSeq> & model,
-
19151  const std::string & vname,
-
19152  epiworld_fast_uint n,
-
19153  epiworld_double prevalence,
-
19154  epiworld_double contact_rate,
-
19155  epiworld_double transmission_rate,
-
19156  epiworld_double avg_incubation_days,
-
19157  epiworld_double recovery_rate,
-
19158  epiworld_double death_rate
-
19159  // epiworld_double prob_reinfection
-
19160  )
-
19161 {
+
19121  Model<TSeq>::set_rand_binom(
+
19122  this->get_n_infected(),
+
19123  static_cast<double>(Model<TSeq>::par("Contact rate"))/
+
19124  static_cast<double>(Model<TSeq>::size())
+
19125  );
+
19126 
+
19127  return;
+
19128 }
+
19129 
+
19130 template<typename TSeq>
+
19131 inline ModelSEIRDCONN<TSeq> & ModelSEIRDCONN<TSeq>::run(
+
19132  epiworld_fast_uint ndays,
+
19133  int seed
+
19134 )
+
19135 {
+
19136 
+
19137  Model<TSeq>::run(ndays, seed);
+
19138 
+
19139  return *this;
+
19140 
+
19141 }
+
19142 
+
19143 template<typename TSeq>
+
19144 inline void ModelSEIRDCONN<TSeq>::reset()
+
19145 {
+
19146 
+
19147  Model<TSeq>::reset();
+
19148 
+
19149  this->update_infected();
+
19150 
+
19151  return;
+
19152 
+
19153 }
+
19154 
+
19155 template<typename TSeq>
+
19156 inline Model<TSeq> * ModelSEIRDCONN<TSeq>::clone_ptr()
+
19157 {
+
19158 
+
19159  ModelSEIRDCONN<TSeq> * ptr = new ModelSEIRDCONN<TSeq>(
+
19160  *dynamic_cast<const ModelSEIRDCONN<TSeq>*>(this)
+
19161  );
19162 
-
19163  epiworld::UpdateFun<TSeq> update_susceptible = [](
-
19164  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
-
19165  ) -> void
-
19166  {
-
19167 
-
19168  // Sampling how many individuals
-
19169  int ndraw = m->rbinom();
-
19170 
-
19171  if (ndraw == 0)
-
19172  return;
-
19173 
-
19174  ModelSEIRDCONN<TSeq> * model = dynamic_cast<ModelSEIRDCONN<TSeq> *>(
-
19175  m
-
19176  );
-
19177 
-
19178  size_t ninfected = model->get_n_infected();
-
19179 
-
19180  // Drawing from the set
-
19181  int nviruses_tmp = 0;
-
19182  for (int i = 0; i < ndraw; ++i)
-
19183  {
-
19184  // Now selecting who is transmitting the disease
-
19185  int which = static_cast<int>(
-
19186  std::floor(ninfected * m->runif())
-
19187  );
-
19188 
-
19189  /* There is a bug in which runif() returns 1.0. It is rare, but
-
19190  * we saw it here. See the Notes section in the C++ manual
-
19191  * https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/random/uniform_real_distribution&oldid=133329
-
19192  * And the reported bug in GCC:
-
19193  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
-
19194  *
-
19195  */
-
19196  if (which == static_cast<int>(ninfected))
-
19197  --which;
-
19198 
-
19199  epiworld::Agent<TSeq> & neighbor = *model->infected[which];
-
19200 
-
19201  // Can't sample itself
-
19202  if (neighbor.get_id() == p->get_id())
-
19203  continue;
-
19204 
-
19205  // All neighbors in this set are infected by construction
-
19206  const auto & v = neighbor.get_virus();
-
19207 
-
19208  #ifdef EPI_DEBUG
-
19209  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
-
19210  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
19211  #endif
-
19212 
-
19213  /* And it is a function of susceptibility_reduction as well */
-
19214  m->array_double_tmp[nviruses_tmp] =
-
19215  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
19216  v->get_prob_infecting(m) *
-
19217  (1.0 - neighbor.get_transmission_reduction(v, m))
-
19218  ;
-
19219 
-
19220  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
19221  }
-
19222 
-
19223  // No virus to compute
-
19224  if (nviruses_tmp == 0u)
-
19225  return;
-
19226 
-
19227  // Running the roulette
-
19228  int which = roulette(nviruses_tmp, m);
-
19229 
-
19230  if (which < 0)
-
19231  return;
-
19232 
-
19233  p->set_virus(
-
19234  *m->array_virus_tmp[which],
-
19235  m,
- -
19237  );
-
19238 
-
19239  return;
-
19240 
-
19241  };
-
19242 
-
19243  epiworld::UpdateFun<TSeq> update_infected = [](
- -
19245  ) -> void {
-
19246 
-
19247  auto state = p->get_state();
-
19248 
-
19249  if (state == ModelSEIRDCONN<TSeq>::EXPOSED)
-
19250  {
-
19251 
-
19252  // Getting the virus
-
19253  auto & v = p->get_virus();
-
19254 
-
19255  // Does the agent become infected?
-
19256  if (m->runif() < 1.0/(v->get_incubation(m)))
-
19257  {
-
19258 
-
19259  p->change_state(m, ModelSEIRDCONN<TSeq>::INFECTED);
-
19260  return;
-
19261 
-
19262  }
-
19263 
-
19264 
-
19265  } else if (state == ModelSEIRDCONN<TSeq>::INFECTED)
-
19266  {
-
19267 
-
19268  // Odd: Die, Even: Recover
-
19269  epiworld_fast_uint n_events = 0u;
-
19270  const auto & v = p->get_virus();
-
19271 
-
19272  // Die
-
19273  m->array_double_tmp[n_events++] =
-
19274  v->get_prob_death(m) * (1.0 - p->get_death_reduction(v, m));
-
19275 
-
19276  // Recover
-
19277  m->array_double_tmp[n_events++] =
-
19278  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
-
19279 
-
19280  #ifdef EPI_DEBUG
-
19281  if (n_events == 0u)
-
19282  {
-
19283  printf_epiworld(
-
19284  "[epi-debug] agent %i has 0 possible events!!\n",
-
19285  static_cast<int>(p->get_id())
-
19286  );
-
19287  throw std::logic_error("Zero events in exposed.");
-
19288  }
-
19289  #else
-
19290  if (n_events == 0u)
-
19291  return;
-
19292  #endif
-
19293 
-
19294 
-
19295  // Running the roulette
-
19296  int which = roulette(n_events, m);
-
19297 
-
19298  if (which < 0)
-
19299  return;
-
19300 
-
19301  // Which roulette happen?
-
19302  if ((which % 2) == 0) // If odd
-
19303  {
-
19304 
-
19305  p->rm_agent_by_virus(m);
-
19306 
-
19307  } else {
-
19308 
-
19309  p->rm_virus(m);
-
19310 
-
19311  }
-
19312 
-
19313  return ;
-
19314 
-
19315  } else
-
19316  throw std::logic_error("This function can only be applied to exposed or infected individuals. (SEIRD)") ;
-
19317 
-
19318  return;
-
19319 
-
19320  };
-
19321 
-
19322  // Setting up parameters
-
19323  model.add_param(contact_rate, "Contact rate");
-
19324  model.add_param(transmission_rate, "Prob. Transmission");
-
19325  model.add_param(recovery_rate, "Prob. Recovery");
-
19326  model.add_param(avg_incubation_days, "Avg. Incubation days");
-
19327  model.add_param(death_rate, "Death rate");
-
19328 
-
19329  // state
-
19330  model.add_state("Susceptible", update_susceptible);
-
19331  model.add_state("Exposed", update_infected);
-
19332  model.add_state("Infected", update_infected);
-
19333  model.add_state("Removed");
-
19334  model.add_state("Deceased");
-
19335 
-
19336 
-
19337  // Adding update function
-
19338  epiworld::GlobalFun<TSeq> update = [](epiworld::Model<TSeq> * m) -> void
-
19339  {
-
19340  ModelSEIRDCONN<TSeq> * model = dynamic_cast<ModelSEIRDCONN<TSeq> *>(m);
-
19341  model->update_infected();
-
19342 
-
19343  return;
-
19344  };
-
19345 
-
19346  model.add_globalevent(update, "Update infected individuals");
+
19163  return dynamic_cast< Model<TSeq> *>(ptr);
+
19164 
+
19165 }
+
19166 
+
19178 template<typename TSeq>
+
19179 inline ModelSEIRDCONN<TSeq>::ModelSEIRDCONN(
+
19180  ModelSEIRDCONN<TSeq> & model,
+
19181  const std::string & vname,
+
19182  epiworld_fast_uint n,
+
19183  epiworld_double prevalence,
+
19184  epiworld_double contact_rate,
+
19185  epiworld_double transmission_rate,
+
19186  epiworld_double avg_incubation_days,
+
19187  epiworld_double recovery_rate,
+
19188  epiworld_double death_rate
+
19189  // epiworld_double prob_reinfection
+
19190  )
+
19191 {
+
19192 
+
19193  epiworld::UpdateFun<TSeq> update_susceptible = [](
+
19194  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
+
19195  ) -> void
+
19196  {
+
19197 
+
19198  // Sampling how many individuals
+
19199  int ndraw = m->rbinom();
+
19200 
+
19201  if (ndraw == 0)
+
19202  return;
+
19203 
+
19204  ModelSEIRDCONN<TSeq> * model = dynamic_cast<ModelSEIRDCONN<TSeq> *>(
+
19205  m
+
19206  );
+
19207 
+
19208  size_t ninfected = model->get_n_infected();
+
19209 
+
19210  // Drawing from the set
+
19211  int nviruses_tmp = 0;
+
19212  for (int i = 0; i < ndraw; ++i)
+
19213  {
+
19214  // Now selecting who is transmitting the disease
+
19215  int which = static_cast<int>(
+
19216  std::floor(ninfected * m->runif())
+
19217  );
+
19218 
+
19219  /* There is a bug in which runif() returns 1.0. It is rare, but
+
19220  * we saw it here. See the Notes section in the C++ manual
+
19221  * https://en.cppreference.com/mwiki/index.php?title=cpp/numeric/random/uniform_real_distribution&oldid=133329
+
19222  * And the reported bug in GCC:
+
19223  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63176
+
19224  *
+
19225  */
+
19226  if (which == static_cast<int>(ninfected))
+
19227  --which;
+
19228 
+
19229  epiworld::Agent<TSeq> & neighbor = *model->infected[which];
+
19230 
+
19231  // Can't sample itself
+
19232  if (neighbor.get_id() == p->get_id())
+
19233  continue;
+
19234 
+
19235  // All neighbors in this set are infected by construction
+
19236  const auto & v = neighbor.get_virus();
+
19237 
+
19238  #ifdef EPI_DEBUG
+
19239  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
+
19240  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
19241  #endif
+
19242 
+
19243  /* And it is a function of susceptibility_reduction as well */
+
19244  m->array_double_tmp[nviruses_tmp] =
+
19245  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
19246  v->get_prob_infecting(m) *
+
19247  (1.0 - neighbor.get_transmission_reduction(v, m))
+
19248  ;
+
19249 
+
19250  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
19251  }
+
19252 
+
19253  // No virus to compute
+
19254  if (nviruses_tmp == 0u)
+
19255  return;
+
19256 
+
19257  // Running the roulette
+
19258  int which = roulette(nviruses_tmp, m);
+
19259 
+
19260  if (which < 0)
+
19261  return;
+
19262 
+
19263  p->set_virus(
+
19264  *m->array_virus_tmp[which],
+
19265  m,
+ +
19267  );
+
19268 
+
19269  return;
+
19270 
+
19271  };
+
19272 
+
19273  epiworld::UpdateFun<TSeq> update_infected = [](
+ +
19275  ) -> void {
+
19276 
+
19277  auto state = p->get_state();
+
19278 
+
19279  if (state == ModelSEIRDCONN<TSeq>::EXPOSED)
+
19280  {
+
19281 
+
19282  // Getting the virus
+
19283  auto & v = p->get_virus();
+
19284 
+
19285  // Does the agent become infected?
+
19286  if (m->runif() < 1.0/(v->get_incubation(m)))
+
19287  {
+
19288 
+
19289  p->change_state(m, ModelSEIRDCONN<TSeq>::INFECTED);
+
19290  return;
+
19291 
+
19292  }
+
19293 
+
19294 
+
19295  } else if (state == ModelSEIRDCONN<TSeq>::INFECTED)
+
19296  {
+
19297 
+
19298  // Odd: Die, Even: Recover
+
19299  epiworld_fast_uint n_events = 0u;
+
19300  const auto & v = p->get_virus();
+
19301 
+
19302  // Die
+
19303  m->array_double_tmp[n_events++] =
+
19304  v->get_prob_death(m) * (1.0 - p->get_death_reduction(v, m));
+
19305 
+
19306  // Recover
+
19307  m->array_double_tmp[n_events++] =
+
19308  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
+
19309 
+
19310  #ifdef EPI_DEBUG
+
19311  if (n_events == 0u)
+
19312  {
+
19313  printf_epiworld(
+
19314  "[epi-debug] agent %i has 0 possible events!!\n",
+
19315  static_cast<int>(p->get_id())
+
19316  );
+
19317  throw std::logic_error("Zero events in exposed.");
+
19318  }
+
19319  #else
+
19320  if (n_events == 0u)
+
19321  return;
+
19322  #endif
+
19323 
+
19324 
+
19325  // Running the roulette
+
19326  int which = roulette(n_events, m);
+
19327 
+
19328  if (which < 0)
+
19329  return;
+
19330 
+
19331  // Which roulette happen?
+
19332  if ((which % 2) == 0) // If odd
+
19333  {
+
19334 
+
19335  p->rm_agent_by_virus(m);
+
19336 
+
19337  } else {
+
19338 
+
19339  p->rm_virus(m);
+
19340 
+
19341  }
+
19342 
+
19343  return ;
+
19344 
+
19345  } else
+
19346  throw std::logic_error("This function can only be applied to exposed or infected individuals. (SEIRD)") ;
19347 
-
19348 
-
19349  // Preparing the virus -------------------------------------------
-
19350  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
19351  virus.set_state(
- - - -
19355  );
-
19356 
-
19357  virus.set_prob_infecting(&model("Prob. Transmission"));
-
19358  virus.set_prob_recovery(&model("Prob. Recovery"));
-
19359  virus.set_incubation(&model("Avg. Incubation days"));
-
19360  virus.set_prob_death(&model("Death rate"));
-
19361  model.add_virus(virus);
-
19362 
-
19363  model.queuing_off(); // No queuing need
-
19364 
-
19365  // Adding the empty population
-
19366  model.agents_empty_graph(n);
-
19367 
-
19368  model.set_name("Susceptible-Exposed-Infected-Removed-Deceased (SEIRD) (connected)");
-
19369 
-
19370  return;
-
19371 
-
19372 }
-
19373 
-
19374 template<typename TSeq>
- -
19376  const std::string & vname,
-
19377  epiworld_fast_uint n,
-
19378  epiworld_double prevalence,
-
19379  epiworld_double contact_rate,
-
19380  epiworld_double transmission_rate,
-
19381  epiworld_double avg_incubation_days,
-
19382  epiworld_double recovery_rate,
-
19383  epiworld_double death_rate
-
19384  )
-
19385 {
+
19348  return;
+
19349 
+
19350  };
+
19351 
+
19352  // Setting up parameters
+
19353  model.add_param(contact_rate, "Contact rate");
+
19354  model.add_param(transmission_rate, "Prob. Transmission");
+
19355  model.add_param(recovery_rate, "Prob. Recovery");
+
19356  model.add_param(avg_incubation_days, "Avg. Incubation days");
+
19357  model.add_param(death_rate, "Death rate");
+
19358 
+
19359  // state
+
19360  model.add_state("Susceptible", update_susceptible);
+
19361  model.add_state("Exposed", update_infected);
+
19362  model.add_state("Infected", update_infected);
+
19363  model.add_state("Removed");
+
19364  model.add_state("Deceased");
+
19365 
+
19366 
+
19367  // Adding update function
+
19368  epiworld::GlobalFun<TSeq> update = [](epiworld::Model<TSeq> * m) -> void
+
19369  {
+
19370  ModelSEIRDCONN<TSeq> * model = dynamic_cast<ModelSEIRDCONN<TSeq> *>(m);
+
19371  model->update_infected();
+
19372 
+
19373  return;
+
19374  };
+
19375 
+
19376  model.add_globalevent(update, "Update infected individuals");
+
19377 
+
19378 
+
19379  // Preparing the virus -------------------------------------------
+
19380  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
19381  virus.set_state(
+ + + +
19385  );
19386 
- -
19388  *this,
-
19389  vname,
-
19390  n,
-
19391  prevalence,
-
19392  contact_rate,
-
19393  transmission_rate,
-
19394  avg_incubation_days,
-
19395  recovery_rate,
-
19396  death_rate
-
19397  );
-
19398 
-
19399  return;
-
19400 
-
19401 }
-
19402 
-
19403 template<typename TSeq>
- -
19405  std::vector< double > proportions_,
-
19406  std::vector< int >
-
19407 ) {
-
19408 
- -
19410  create_init_function_seird<TSeq>(proportions_)
-
19411  ;
-
19412 
-
19413  return *this;
-
19414 
-
19415 }
+
19387  virus.set_prob_infecting(&model("Prob. Transmission"));
+
19388  virus.set_prob_recovery(&model("Prob. Recovery"));
+
19389  virus.set_incubation(&model("Avg. Incubation days"));
+
19390  virus.set_prob_death(&model("Death rate"));
+
19391  model.add_virus(virus);
+
19392 
+
19393  model.queuing_off(); // No queuing need
+
19394 
+
19395  // Adding the empty population
+
19396  model.agents_empty_graph(n);
+
19397 
+
19398  model.set_name("Susceptible-Exposed-Infected-Removed-Deceased (SEIRD) (connected)");
+
19399 
+
19400  return;
+
19401 
+
19402 }
+
19403 
+
19404 template<typename TSeq>
+ +
19406  const std::string & vname,
+
19407  epiworld_fast_uint n,
+
19408  epiworld_double prevalence,
+
19409  epiworld_double contact_rate,
+
19410  epiworld_double transmission_rate,
+
19411  epiworld_double avg_incubation_days,
+
19412  epiworld_double recovery_rate,
+
19413  epiworld_double death_rate
+
19414  )
+
19415 {
19416 
-
19417 #endif
-
19418 /*//////////////////////////////////////////////////////////////////////////////
-
19420 
-
19421  End of -include/epiworld//models/seirdconnected.hpp-
-
19422 
-
19425 
-
19426 
-
19427 /*//////////////////////////////////////////////////////////////////////////////
-
19429 
-
19430  Start of -include/epiworld//models/sirlogit.hpp-
-
19431 
-
19434 
-
19435 
-
19436 // #include "../epiworld.hpp"
-
19437 
-
19438 #ifndef EPIWORLD_MODELS_SIRLOGIT_HPP
-
19439 #define EPIWORLD_MODELS_SIRLOGIT_HPP
-
19440 
-
19441 
-
19469 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
19470 class ModelSIRLogit : public epiworld::Model<TSeq>
-
19471 {
-
19472 private:
-
19473  static const int SUSCEPTIBLE = 0;
-
19474  static const int INFECTED = 1;
-
19475  static const int RECOVERED = 2;
-
19476 
-
19477 public:
-
19478 
-
19479  ModelSIRLogit() {};
-
19480 
-
19490  ModelSIRLogit(
-
19491  ModelSIRLogit<TSeq> & model,
-
19492  const std::string & vname,
-
19493  double * data,
-
19494  size_t ncols,
-
19495  std::vector< double > coefs_infect,
-
19496  std::vector< double > coefs_recover,
-
19497  std::vector< size_t > coef_infect_cols,
-
19498  std::vector< size_t > coef_recover_cols,
-
19499  epiworld_double transmission_rate,
-
19500  epiworld_double recovery_rate,
-
19501  epiworld_double prevalence
-
19502  );
-
19503 
-
19504  ModelSIRLogit(
-
19505  const std::string & vname,
-
19506  double * data,
-
19507  size_t ncols,
-
19508  std::vector< double > coefs_infect,
-
19509  std::vector< double > coefs_recover,
-
19510  std::vector< size_t > coef_infect_cols,
-
19511  std::vector< size_t > coef_recover_cols,
-
19512  epiworld_double transmission_rate,
-
19513  epiworld_double recovery_rate,
-
19514  epiworld_double prevalence
-
19515  );
-
19516 
-
19517  ModelSIRLogit<TSeq> & run(
-
19518  epiworld_fast_uint ndays,
-
19519  int seed = -1
-
19520  );
-
19521 
-
19522  Model<TSeq> * clone_ptr();
-
19523 
-
19524  void reset();
-
19525 
-
19526  std::vector< double > coefs_infect;
-
19527  std::vector< double > coefs_recover;
-
19528  std::vector< size_t > coef_infect_cols;
-
19529  std::vector< size_t > coef_recover_cols;
-
19530 
-
19531 };
-
19532 
+ +
19418  *this,
+
19419  vname,
+
19420  n,
+
19421  prevalence,
+
19422  contact_rate,
+
19423  transmission_rate,
+
19424  avg_incubation_days,
+
19425  recovery_rate,
+
19426  death_rate
+
19427  );
+
19428 
+
19429  return;
+
19430 
+
19431 }
+
19432 
+
19433 template<typename TSeq>
+ +
19435  std::vector< double > proportions_,
+
19436  std::vector< int >
+
19437 ) {
+
19438 
+ +
19440  create_init_function_seird<TSeq>(proportions_)
+
19441  ;
+
19442 
+
19443  return *this;
+
19444 
+
19445 }
+
19446 
+
19447 #endif
+
19448 /*//////////////////////////////////////////////////////////////////////////////
+
19450 
+
19451  End of -include/epiworld//models/seirdconnected.hpp-
+
19452 
+
19455 
+
19456 
+
19457 /*//////////////////////////////////////////////////////////////////////////////
+
19459 
+
19460  Start of -include/epiworld//models/sirlogit.hpp-
+
19461 
+
19464 
+
19465 
+
19466 // #include "../epiworld.hpp"
+
19467 
+
19468 #ifndef EPIWORLD_MODELS_SIRLOGIT_HPP
+
19469 #define EPIWORLD_MODELS_SIRLOGIT_HPP
+
19470 
+
19471 
+
19499 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
19500 class ModelSIRLogit : public epiworld::Model<TSeq>
+
19501 {
+
19502 private:
+
19503  static const int SUSCEPTIBLE = 0;
+
19504  static const int INFECTED = 1;
+
19505  static const int RECOVERED = 2;
+
19506 
+
19507 public:
+
19508 
+
19509  ModelSIRLogit() {};
+
19510 
+
19520  ModelSIRLogit(
+
19521  ModelSIRLogit<TSeq> & model,
+
19522  const std::string & vname,
+
19523  double * data,
+
19524  size_t ncols,
+
19525  std::vector< double > coefs_infect,
+
19526  std::vector< double > coefs_recover,
+
19527  std::vector< size_t > coef_infect_cols,
+
19528  std::vector< size_t > coef_recover_cols,
+
19529  epiworld_double transmission_rate,
+
19530  epiworld_double recovery_rate,
+
19531  epiworld_double prevalence
+
19532  );
19533 
-
19534 
-
19535 template<typename TSeq>
-
19536 inline ModelSIRLogit<TSeq> & ModelSIRLogit<TSeq>::run(
-
19537  epiworld_fast_uint ndays,
-
19538  int seed
-
19539 )
-
19540 {
-
19541 
-
19542  Model<TSeq>::run(ndays, seed);
-
19543  return *this;
-
19544 
-
19545 }
+
19534  ModelSIRLogit(
+
19535  const std::string & vname,
+
19536  double * data,
+
19537  size_t ncols,
+
19538  std::vector< double > coefs_infect,
+
19539  std::vector< double > coefs_recover,
+
19540  std::vector< size_t > coef_infect_cols,
+
19541  std::vector< size_t > coef_recover_cols,
+
19542  epiworld_double transmission_rate,
+
19543  epiworld_double recovery_rate,
+
19544  epiworld_double prevalence
+
19545  );
19546 
-
19547 template<typename TSeq>
-
19548 inline Model<TSeq> * ModelSIRLogit<TSeq>::clone_ptr()
-
19549 {
-
19550 
-
19551  ModelSIRLogit<TSeq> * ptr = new ModelSIRLogit<TSeq>(
-
19552  *dynamic_cast<const ModelSIRLogit<TSeq>*>(this)
-
19553  );
-
19554 
-
19555  return dynamic_cast< Model<TSeq> *>(ptr);
-
19556 
-
19557 }
-
19558 
-
19559 template<typename TSeq>
-
19560 inline void ModelSIRLogit<TSeq>::reset()
-
19561 {
+
19547  ModelSIRLogit<TSeq> & run(
+
19548  epiworld_fast_uint ndays,
+
19549  int seed = -1
+
19550  );
+
19551 
+
19552  Model<TSeq> * clone_ptr();
+
19553 
+
19554  void reset();
+
19555 
+
19556  std::vector< double > coefs_infect;
+
19557  std::vector< double > coefs_recover;
+
19558  std::vector< size_t > coef_infect_cols;
+
19559  std::vector< size_t > coef_recover_cols;
+
19560 
+
19561 };
19562 
-
19563  /* Checking specified columns in the model */
-
19564  for (const auto & c : coef_infect_cols)
-
19565  {
- -
19567  throw std::range_error("Columns specified in coef_infect_cols out of range.");
-
19568  }
-
19569 
-
19570  for (const auto & c : coef_recover_cols)
-
19571  {
- -
19573  throw std::range_error("Columns specified in coef_recover_cols out of range.");
-
19574  }
-
19575 
-
19576  /* Checking attributes */
-
19577  if (coefs_infect.size() != (coef_infect_cols.size() + 1u))
-
19578  throw std::logic_error(
-
19579  "The number of coefficients (infection) doesn't match the number of features. It must be as many features of the agents plus 1 (exposure.)"
-
19580  );
-
19581 
-
19582  if (coefs_recover.size() != coef_recover_cols.size())
-
19583  throw std::logic_error(
-
19584  "The number of coefficients (recovery) doesn't match the number of features. It must be as many features of the agents."
-
19585  );
-
19586 
- -
19588 
-
19589  return;
-
19590 
-
19591 }
-
19592 
-
19603 template<typename TSeq>
- -
19605  ModelSIRLogit<TSeq> & model,
-
19606  const std::string & vname,
-
19607  double * data,
-
19608  size_t ncols,
-
19609  std::vector< double > coefs_infect,
-
19610  std::vector< double > coefs_recover,
-
19611  std::vector< size_t > coef_infect_cols,
-
19612  std::vector< size_t > coef_recover_cols,
-
19613  epiworld_double transmission_rate,
-
19614  epiworld_double recovery_rate,
-
19615  epiworld_double prevalence
-
19616  )
-
19617 {
+
19563 
+
19564 
+
19565 template<typename TSeq>
+
19566 inline ModelSIRLogit<TSeq> & ModelSIRLogit<TSeq>::run(
+
19567  epiworld_fast_uint ndays,
+
19568  int seed
+
19569 )
+
19570 {
+
19571 
+
19572  Model<TSeq>::run(ndays, seed);
+
19573  return *this;
+
19574 
+
19575 }
+
19576 
+
19577 template<typename TSeq>
+
19578 inline Model<TSeq> * ModelSIRLogit<TSeq>::clone_ptr()
+
19579 {
+
19580 
+
19581  ModelSIRLogit<TSeq> * ptr = new ModelSIRLogit<TSeq>(
+
19582  *dynamic_cast<const ModelSIRLogit<TSeq>*>(this)
+
19583  );
+
19584 
+
19585  return dynamic_cast< Model<TSeq> *>(ptr);
+
19586 
+
19587 }
+
19588 
+
19589 template<typename TSeq>
+
19590 inline void ModelSIRLogit<TSeq>::reset()
+
19591 {
+
19592 
+
19593  /* Checking specified columns in the model */
+
19594  for (const auto & c : coef_infect_cols)
+
19595  {
+ +
19597  throw std::range_error("Columns specified in coef_infect_cols out of range.");
+
19598  }
+
19599 
+
19600  for (const auto & c : coef_recover_cols)
+
19601  {
+ +
19603  throw std::range_error("Columns specified in coef_recover_cols out of range.");
+
19604  }
+
19605 
+
19606  /* Checking attributes */
+
19607  if (coefs_infect.size() != (coef_infect_cols.size() + 1u))
+
19608  throw std::logic_error(
+
19609  "The number of coefficients (infection) doesn't match the number of features. It must be as many features of the agents plus 1 (exposure.)"
+
19610  );
+
19611 
+
19612  if (coefs_recover.size() != coef_recover_cols.size())
+
19613  throw std::logic_error(
+
19614  "The number of coefficients (recovery) doesn't match the number of features. It must be as many features of the agents."
+
19615  );
+
19616 
+
19618 
-
19619  if (coef_infect_cols.size() == 0u)
-
19620  throw std::logic_error("No columns specified for coef_infect_cols.");
-
19621 
-
19622  if (coef_recover_cols.size() == 0u)
-
19623  throw std::logic_error("No columns specified for coef_recover_cols.");
-
19624 
-
19625  // Saving the variables
-
19626  model.set_agents_data(
-
19627  data, ncols
-
19628  );
-
19629 
-
19630  model.coefs_infect = coefs_infect;
-
19631  model.coefs_recover = coefs_recover;
-
19632  model.coef_infect_cols = coef_infect_cols;
-
19633  model.coef_recover_cols = coef_recover_cols;
-
19634 
-
19635  epiworld::UpdateFun<TSeq> update_susceptible = [](
- -
19637  ) -> void
-
19638  {
-
19639 
-
19640  // Getting the right type
-
19641  ModelSIRLogit<TSeq> * _m = dynamic_cast<ModelSIRLogit<TSeq>*>(m);
-
19642 
-
19643  // Exposure coefficient
-
19644  const double coef_exposure = _m->coefs_infect[0u];
-
19645 
-
19646  // This computes the prob of getting any neighbor variant
-
19647  size_t nviruses_tmp = 0u;
+
19619  return;
+
19620 
+
19621 }
+
19622 
+
19633 template<typename TSeq>
+ +
19635  ModelSIRLogit<TSeq> & model,
+
19636  const std::string & vname,
+
19637  double * data,
+
19638  size_t ncols,
+
19639  std::vector< double > coefs_infect,
+
19640  std::vector< double > coefs_recover,
+
19641  std::vector< size_t > coef_infect_cols,
+
19642  std::vector< size_t > coef_recover_cols,
+
19643  epiworld_double transmission_rate,
+
19644  epiworld_double recovery_rate,
+
19645  epiworld_double prevalence
+
19646  )
+
19647 {
19648 
-
19649  double baseline = 0.0;
-
19650  for (size_t k = 0u; k < _m->coef_infect_cols.size(); ++k)
-
19651  baseline += p->operator[](k) * _m->coefs_infect[k + 1u];
-
19652 
-
19653  for (auto & neighbor: p->get_neighbors())
-
19654  {
-
19655 
-
19656  if (neighbor->get_virus() == nullptr)
-
19657  continue;
-
19658 
-
19659  auto & v = neighbor->get_virus();
-
19660 
-
19661  #ifdef EPI_DEBUG
-
19662  if (nviruses_tmp >= m->array_virus_tmp.size())
-
19663  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
19664  #endif
-
19665 
-
19666  /* And it is a function of susceptibility_reduction as well */
-
19667  m->array_double_tmp[nviruses_tmp] =
-
19668  baseline +
-
19669  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
19670  v->get_prob_infecting(m) *
-
19671  (1.0 - neighbor->get_transmission_reduction(v, m)) *
-
19672  coef_exposure
-
19673  ;
-
19674 
-
19675  // Applying the plogis function
-
19676  m->array_double_tmp[nviruses_tmp] = 1.0/
-
19677  (1.0 + std::exp(-m->array_double_tmp[nviruses_tmp]));
-
19678 
-
19679  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
19680 
-
19681  }
+
19649  if (coef_infect_cols.size() == 0u)
+
19650  throw std::logic_error("No columns specified for coef_infect_cols.");
+
19651 
+
19652  if (coef_recover_cols.size() == 0u)
+
19653  throw std::logic_error("No columns specified for coef_recover_cols.");
+
19654 
+
19655  // Saving the variables
+
19656  model.set_agents_data(
+
19657  data, ncols
+
19658  );
+
19659 
+
19660  model.coefs_infect = coefs_infect;
+
19661  model.coefs_recover = coefs_recover;
+
19662  model.coef_infect_cols = coef_infect_cols;
+
19663  model.coef_recover_cols = coef_recover_cols;
+
19664 
+
19665  epiworld::UpdateFun<TSeq> update_susceptible = [](
+ +
19667  ) -> void
+
19668  {
+
19669 
+
19670  // Getting the right type
+
19671  ModelSIRLogit<TSeq> * _m = dynamic_cast<ModelSIRLogit<TSeq>*>(m);
+
19672 
+
19673  // Exposure coefficient
+
19674  const double coef_exposure = _m->coefs_infect[0u];
+
19675 
+
19676  // This computes the prob of getting any neighbor variant
+
19677  size_t nviruses_tmp = 0u;
+
19678 
+
19679  double baseline = 0.0;
+
19680  for (size_t k = 0u; k < _m->coef_infect_cols.size(); ++k)
+
19681  baseline += p->operator[](k) * _m->coefs_infect[k + 1u];
19682 
-
19683  // No virus to compute
-
19684  if (nviruses_tmp == 0u)
-
19685  return;
-
19686 
-
19687  // Running the roulette
-
19688  int which = roulette(nviruses_tmp, m);
-
19689 
-
19690  if (which < 0)
-
19691  return;
-
19692 
-
19693  p->set_virus(*m->array_virus_tmp[which], m);
-
19694 
-
19695  return;
-
19696 
-
19697  };
-
19698 
-
19699  epiworld::UpdateFun<TSeq> update_infected = [](
- -
19701  ) -> void
-
19702  {
-
19703 
-
19704  // Getting the right type
-
19705  ModelSIRLogit<TSeq> * _m = dynamic_cast<ModelSIRLogit<TSeq>*>(m);
-
19706 
-
19707  // Computing recovery probability once
-
19708  double prob = 0.0;
-
19709  #if defined(__OPENMP) || defined(_OPENMP)
-
19710  #pragma omp simd reduction(+:prob)
-
19711  #endif
-
19712  for (size_t i = 0u; i < _m->coefs_recover.size(); ++i)
-
19713  prob += p->operator[](i) * _m->coefs_recover[i];
-
19714 
-
19715  // Computing logis
-
19716  prob = 1.0/(1.0 + std::exp(-prob));
-
19717 
-
19718  if (prob > m->runif())
-
19719  p->rm_virus(m);
-
19720 
-
19721  return;
+
19683  for (auto & neighbor: p->get_neighbors())
+
19684  {
+
19685 
+
19686  if (neighbor->get_virus() == nullptr)
+
19687  continue;
+
19688 
+
19689  auto & v = neighbor->get_virus();
+
19690 
+
19691  #ifdef EPI_DEBUG
+
19692  if (nviruses_tmp >= m->array_virus_tmp.size())
+
19693  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
19694  #endif
+
19695 
+
19696  /* And it is a function of susceptibility_reduction as well */
+
19697  m->array_double_tmp[nviruses_tmp] =
+
19698  baseline +
+
19699  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
19700  v->get_prob_infecting(m) *
+
19701  (1.0 - neighbor->get_transmission_reduction(v, m)) *
+
19702  coef_exposure
+
19703  ;
+
19704 
+
19705  // Applying the plogis function
+
19706  m->array_double_tmp[nviruses_tmp] = 1.0/
+
19707  (1.0 + std::exp(-m->array_double_tmp[nviruses_tmp]));
+
19708 
+
19709  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
19710 
+
19711  }
+
19712 
+
19713  // No virus to compute
+
19714  if (nviruses_tmp == 0u)
+
19715  return;
+
19716 
+
19717  // Running the roulette
+
19718  int which = roulette(nviruses_tmp, m);
+
19719 
+
19720  if (which < 0)
+
19721  return;
19722 
-
19723  };
+
19723  p->set_virus(*m->array_virus_tmp[which], m);
19724 
-
19725  // state
-
19726  model.add_state("Susceptible", update_susceptible);
-
19727  model.add_state("Infected", update_infected);
-
19728  model.add_state("Recovered");
-
19729 
-
19730  // Setting up parameters
-
19731  // model.add_param(contact_rate, "Contact rate");
-
19732  model.add_param(transmission_rate, "Transmission rate");
-
19733  model.add_param(recovery_rate, "Recovery rate");
-
19734  // model.add_param(prob_reinfection, "Prob. Reinfection");
-
19735 
-
19736  // Preparing the virus -------------------------------------------
-
19737  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
19738  virus.set_state(
- - - -
19742  );
-
19743 
-
19744  virus.set_prob_infecting(&model("Transmission rate"));
-
19745  virus.set_prob_recovery(&model("Recovery rate"));
-
19746 
-
19747  // virus.set_prob
-
19748 
-
19749  model.add_virus(virus);
-
19750 
-
19751  model.set_name("Susceptible-Infected-Removed (SIR) (logit)");
+
19725  return;
+
19726 
+
19727  };
+
19728 
+
19729  epiworld::UpdateFun<TSeq> update_infected = [](
+ +
19731  ) -> void
+
19732  {
+
19733 
+
19734  // Getting the right type
+
19735  ModelSIRLogit<TSeq> * _m = dynamic_cast<ModelSIRLogit<TSeq>*>(m);
+
19736 
+
19737  // Computing recovery probability once
+
19738  double prob = 0.0;
+
19739  #if defined(__OPENMP) || defined(_OPENMP)
+
19740  #pragma omp simd reduction(+:prob)
+
19741  #endif
+
19742  for (size_t i = 0u; i < _m->coefs_recover.size(); ++i)
+
19743  prob += p->operator[](i) * _m->coefs_recover[i];
+
19744 
+
19745  // Computing logis
+
19746  prob = 1.0/(1.0 + std::exp(-prob));
+
19747 
+
19748  if (prob > m->runif())
+
19749  p->rm_virus(m);
+
19750 
+
19751  return;
19752 
-
19753  return;
+
19753  };
19754 
-
19755 }
-
19756 
-
19757 template<typename TSeq>
- -
19759  const std::string & vname,
-
19760  double * data,
-
19761  size_t ncols,
-
19762  std::vector< double > coefs_infect,
-
19763  std::vector< double > coefs_recover,
-
19764  std::vector< size_t > coef_infect_cols,
-
19765  std::vector< size_t > coef_recover_cols,
-
19766  epiworld_double transmission_rate,
-
19767  epiworld_double recovery_rate,
-
19768  epiworld_double prevalence
-
19769  )
-
19770 {
-
19771 
-
19772  ModelSIRLogit(
-
19773  *this,
-
19774  vname,
-
19775  data,
-
19776  ncols,
-
19777  coefs_infect,
-
19778  coefs_recover,
-
19779  coef_infect_cols,
-
19780  coef_recover_cols,
-
19781  transmission_rate,
-
19782  recovery_rate,
-
19783  prevalence
-
19784  );
-
19785 
-
19786  return;
-
19787 
-
19788 }
-
19789 
-
19790 
-
19791 #endif
-
19792 /*//////////////////////////////////////////////////////////////////////////////
-
19794 
-
19795  End of -include/epiworld//models/sirlogit.hpp-
-
19796 
-
19799 
-
19800 
-
19801 /*//////////////////////////////////////////////////////////////////////////////
-
19803 
-
19804  Start of -include/epiworld//models/diffnet.hpp-
-
19805 
-
19808 
-
19809 
-
19810 #ifndef EPIWORLD_DIFFNET_H
-
19811 #define EPIWORLD_DIFFNET_H
-
19812 
-
19822 template<typename TSeq = int>
-
19823 class ModelDiffNet : public epiworld::Model<TSeq>
-
19824 {
-
19825 private:
-
19826 public:
-
19827 
-
19828  ModelDiffNet() {};
+
19755  // state
+
19756  model.add_state("Susceptible", update_susceptible);
+
19757  model.add_state("Infected", update_infected);
+
19758  model.add_state("Recovered");
+
19759 
+
19760  // Setting up parameters
+
19761  // model.add_param(contact_rate, "Contact rate");
+
19762  model.add_param(transmission_rate, "Transmission rate");
+
19763  model.add_param(recovery_rate, "Recovery rate");
+
19764  // model.add_param(prob_reinfection, "Prob. Reinfection");
+
19765 
+
19766  // Preparing the virus -------------------------------------------
+
19767  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
19768  virus.set_state(
+ + + +
19772  );
+
19773 
+
19774  virus.set_prob_infecting(&model("Transmission rate"));
+
19775  virus.set_prob_recovery(&model("Recovery rate"));
+
19776 
+
19777  // virus.set_prob
+
19778 
+
19779  model.add_virus(virus);
+
19780 
+
19781  model.set_name("Susceptible-Infected-Removed (SIR) (logit)");
+
19782 
+
19783  return;
+
19784 
+
19785 }
+
19786 
+
19787 template<typename TSeq>
+ +
19789  const std::string & vname,
+
19790  double * data,
+
19791  size_t ncols,
+
19792  std::vector< double > coefs_infect,
+
19793  std::vector< double > coefs_recover,
+
19794  std::vector< size_t > coef_infect_cols,
+
19795  std::vector< size_t > coef_recover_cols,
+
19796  epiworld_double transmission_rate,
+
19797  epiworld_double recovery_rate,
+
19798  epiworld_double prevalence
+
19799  )
+
19800 {
+
19801 
+
19802  ModelSIRLogit(
+
19803  *this,
+
19804  vname,
+
19805  data,
+
19806  ncols,
+
19807  coefs_infect,
+
19808  coefs_recover,
+
19809  coef_infect_cols,
+
19810  coef_recover_cols,
+
19811  transmission_rate,
+
19812  recovery_rate,
+
19813  prevalence
+
19814  );
+
19815 
+
19816  return;
+
19817 
+
19818 }
+
19819 
+
19820 
+
19821 #endif
+
19822 /*//////////////////////////////////////////////////////////////////////////////
+
19824 
+
19825  End of -include/epiworld//models/sirlogit.hpp-
+
19826 
19829 
-
19830  ModelDiffNet(
-
19831  ModelDiffNet<TSeq> & model,
-
19832  const std::string & innovation_name,
-
19833  epiworld_double prevalence,
-
19834  epiworld_double prob_adopt,
-
19835  bool normalize_exposure = true,
-
19836  double * agents_data = nullptr,
-
19837  size_t data_ncols = 0u,
-
19838  std::vector< size_t > data_cols = {},
-
19839  std::vector< double > params = {}
-
19840  );
-
19841 
-
19842  ModelDiffNet(
-
19843  const std::string & innovation_name,
-
19844  epiworld_double prevalence,
-
19845  epiworld_double prob_adopt,
-
19846  bool normalize_exposure = true,
-
19847  double * agents_data = nullptr,
-
19848  size_t data_ncols = 0u,
-
19849  std::vector< size_t > data_cols = {},
-
19850  std::vector< double > params = {}
-
19851  );
-
19852 
-
19853  static const int NONADOPTER = 0;
-
19854  static const int ADOPTER = 1;
-
19855 
-
19856  bool normalize_exposure = true;
-
19857  std::vector< size_t > data_cols;
-
19858  std::vector< double > params;
-
19859 };
-
19860 
-
19861 template<typename TSeq>
-
19862 inline ModelDiffNet<TSeq>::ModelDiffNet(
-
19863  ModelDiffNet<TSeq> & model,
-
19864  const std::string & innovation_name,
-
19865  epiworld_double prevalence,
-
19866  epiworld_double prob_adopt,
-
19867  bool normalize_exposure,
-
19868  double * agents_data,
-
19869  size_t data_ncols,
-
19870  std::vector< size_t > data_cols,
-
19871  std::vector< double > params
-
19872  )
-
19873 {
-
19874 
-
19875  // Adding additional parameters
-
19876  this->normalize_exposure = normalize_exposure;
-
19877  this->data_cols = data_cols;
-
19878  this->params = params;
-
19879 
-
19880  epiworld::UpdateFun<TSeq> update_non_adopters = [](
-
19881  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
-
19882  ) -> void {
-
19883 
-
19884  // Measuring exposure
-
19885  // If the neighbor is infected, then proceed
-
19886  size_t nviruses = m->get_n_viruses();
-
19887  std::vector< Virus<TSeq>* > innovations(nviruses, {});
-
19888  std::vector< bool > stored(nviruses, false);
-
19889  std::vector< double > exposure(nviruses, 0.0);
+
19830 
+
19831 /*//////////////////////////////////////////////////////////////////////////////
+
19833 
+
19834  Start of -include/epiworld//models/diffnet.hpp-
+
19835 
+
19838 
+
19839 
+
19840 #ifndef EPIWORLD_DIFFNET_H
+
19841 #define EPIWORLD_DIFFNET_H
+
19842 
+
19852 template<typename TSeq = int>
+
19853 class ModelDiffNet : public epiworld::Model<TSeq>
+
19854 {
+
19855 private:
+
19856 public:
+
19857 
+
19858  ModelDiffNet() {};
+
19859 
+
19860  ModelDiffNet(
+
19861  ModelDiffNet<TSeq> & model,
+
19862  const std::string & innovation_name,
+
19863  epiworld_double prevalence,
+
19864  epiworld_double prob_adopt,
+
19865  bool normalize_exposure = true,
+
19866  double * agents_data = nullptr,
+
19867  size_t data_ncols = 0u,
+
19868  std::vector< size_t > data_cols = {},
+
19869  std::vector< double > params = {}
+
19870  );
+
19871 
+
19872  ModelDiffNet(
+
19873  const std::string & innovation_name,
+
19874  epiworld_double prevalence,
+
19875  epiworld_double prob_adopt,
+
19876  bool normalize_exposure = true,
+
19877  double * agents_data = nullptr,
+
19878  size_t data_ncols = 0u,
+
19879  std::vector< size_t > data_cols = {},
+
19880  std::vector< double > params = {}
+
19881  );
+
19882 
+
19883  static const int NONADOPTER = 0;
+
19884  static const int ADOPTER = 1;
+
19885 
+
19886  bool normalize_exposure = true;
+
19887  std::vector< size_t > data_cols;
+
19888  std::vector< double > params;
+
19889 };
19890 
-
19891  ModelDiffNet<TSeq> * diffmodel = dynamic_cast<ModelDiffNet<TSeq>*>(m);
-
19892 
-
19893  Agent<TSeq> & agent = *p;
-
19894 
-
19895  // For each one of the possible innovations, we have to compute
-
19896  // the adoption probability, which is a function of exposure
-
19897  for (auto & neighbor: agent.get_neighbors())
-
19898  {
-
19899 
-
19900  if (neighbor->get_state() == ModelDiffNet<TSeq>::ADOPTER)
-
19901  {
-
19902 
-
19903  auto & v = neighbor->get_virus();
-
19904 
-
19905  if (v == nullptr)
-
19906  continue;
-
19907 
-
19908  /* And it is a function of susceptibility_reduction as well */
-
19909  double p_i =
-
19910  (1.0 - agent.get_susceptibility_reduction(v, m)) *
-
19911  (1.0 - agent.get_transmission_reduction(v, m))
-
19912  ;
-
19913 
-
19914  size_t vid = v->get_id();
-
19915  if (!stored[vid])
-
19916  {
-
19917  stored[vid] = true;
-
19918  innovations[vid] = &(*v);
-
19919  }
-
19920  exposure[vid] += p_i;
-
19921 
-
19922 
-
19923  }
-
19924 
-
19925  }
-
19926 
-
19927  // Computing probability of adoption
-
19928  for (size_t i = 0u; i < nviruses; ++i)
-
19929  {
-
19930 
-
19931  if (diffmodel->normalize_exposure)
-
19932  exposure.at(i) /= agent.get_n_neighbors();
-
19933 
-
19934  for (auto & j: diffmodel->data_cols)
-
19935  exposure.at(i) += agent(j) * diffmodel->params.at(j);
-
19936 
-
19937  // Baseline probability of adoption
-
19938  double p = m->get_viruses()[i]->get_prob_infecting(m);
-
19939  exposure.at(i) += std::log(p) - std::log(1.0 - p);
-
19940 
-
19941  // Computing as log
-
19942  exposure.at(i) = 1.0/(1.0 + std::exp(-exposure.at(i)));
-
19943 
-
19944  }
-
19945 
-
19946  // Running the roulette to see is an innovation is adopted
-
19947  int which = roulette<int>(exposure, m);
-
19948 
-
19949  // No innovation was adopted
-
19950  if (which < 0)
-
19951  return;
+
19891 template<typename TSeq>
+
19892 inline ModelDiffNet<TSeq>::ModelDiffNet(
+
19893  ModelDiffNet<TSeq> & model,
+
19894  const std::string & innovation_name,
+
19895  epiworld_double prevalence,
+
19896  epiworld_double prob_adopt,
+
19897  bool normalize_exposure,
+
19898  double * agents_data,
+
19899  size_t data_ncols,
+
19900  std::vector< size_t > data_cols,
+
19901  std::vector< double > params
+
19902  )
+
19903 {
+
19904 
+
19905  // Adding additional parameters
+
19906  this->normalize_exposure = normalize_exposure;
+
19907  this->data_cols = data_cols;
+
19908  this->params = params;
+
19909 
+
19910  epiworld::UpdateFun<TSeq> update_non_adopters = [](
+
19911  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
+
19912  ) -> void {
+
19913 
+
19914  // Measuring exposure
+
19915  // If the neighbor is infected, then proceed
+
19916  size_t nviruses = m->get_n_viruses();
+
19917  std::vector< Virus<TSeq>* > innovations(nviruses, {});
+
19918  std::vector< bool > stored(nviruses, false);
+
19919  std::vector< double > exposure(nviruses, 0.0);
+
19920 
+
19921  ModelDiffNet<TSeq> * diffmodel = dynamic_cast<ModelDiffNet<TSeq>*>(m);
+
19922 
+
19923  Agent<TSeq> & agent = *p;
+
19924 
+
19925  // For each one of the possible innovations, we have to compute
+
19926  // the adoption probability, which is a function of exposure
+
19927  for (auto & neighbor: agent.get_neighbors())
+
19928  {
+
19929 
+
19930  if (neighbor->get_state() == ModelDiffNet<TSeq>::ADOPTER)
+
19931  {
+
19932 
+
19933  auto & v = neighbor->get_virus();
+
19934 
+
19935  if (v == nullptr)
+
19936  continue;
+
19937 
+
19938  /* And it is a function of susceptibility_reduction as well */
+
19939  double p_i =
+
19940  (1.0 - agent.get_susceptibility_reduction(v, m)) *
+
19941  (1.0 - agent.get_transmission_reduction(v, m))
+
19942  ;
+
19943 
+
19944  size_t vid = v->get_id();
+
19945  if (!stored[vid])
+
19946  {
+
19947  stored[vid] = true;
+
19948  innovations[vid] = &(*v);
+
19949  }
+
19950  exposure[vid] += p_i;
+
19951 
19952 
-
19953  // Otherwise, it is adopted from any of the neighbors
-
19954  agent.set_virus(
-
19955  *innovations.at(which),
-
19956  m,
-
19957  ModelDiffNet::ADOPTER
-
19958  );
-
19959 
-
19960  return;
-
19961 
-
19962  };
+
19953  }
+
19954 
+
19955  }
+
19956 
+
19957  // Computing probability of adoption
+
19958  for (size_t i = 0u; i < nviruses; ++i)
+
19959  {
+
19960 
+
19961  if (diffmodel->normalize_exposure)
+
19962  exposure.at(i) /= agent.get_n_neighbors();
19963 
-
19964  // Adding agents data
-
19965  model.set_agents_data(agents_data, data_ncols);
-
19966 
-
19967  // Adding statuses
-
19968  model.add_state("Non adopters", update_non_adopters);
-
19969  model.add_state("Adopters");
+
19964  for (auto & j: diffmodel->data_cols)
+
19965  exposure.at(i) += agent(j) * diffmodel->params.at(j);
+
19966 
+
19967  // Baseline probability of adoption
+
19968  double p = m->get_viruses()[i]->get_prob_infecting(m);
+
19969  exposure.at(i) += std::log(p) - std::log(1.0 - p);
19970 
-
19971  // Adding parameters
-
19972  std::string parname = std::string("Prob. Adopting ") + innovation_name;
-
19973  model.add_param(prob_adopt, parname);
-
19974 
-
19975  // Preparing the virus -------------------------------------------
-
19976  epiworld::Virus<TSeq> innovation(innovation_name, prevalence, true);
-
19977  innovation.set_state(1,1,1);
-
19978 
-
19979  innovation.set_prob_infecting(&model(parname));
-
19980 
-
19981  model.add_virus(innovation);
+
19971  // Computing as log
+
19972  exposure.at(i) = 1.0/(1.0 + std::exp(-exposure.at(i)));
+
19973 
+
19974  }
+
19975 
+
19976  // Running the roulette to see is an innovation is adopted
+
19977  int which = roulette<int>(exposure, m);
+
19978 
+
19979  // No innovation was adopted
+
19980  if (which < 0)
+
19981  return;
19982 
-
19983  model.set_name(
-
19984  std::string("Diffusion of Innovations - ") + innovation_name);
-
19985 
-
19986  return;
-
19987 
-
19988 }
+
19983  // Otherwise, it is adopted from any of the neighbors
+
19984  agent.set_virus(
+
19985  *innovations.at(which),
+
19986  m,
+
19987  ModelDiffNet::ADOPTER
+
19988  );
19989 
-
19990 template<typename TSeq>
- -
19992  const std::string & innovation_name,
-
19993  epiworld_double prevalence,
-
19994  epiworld_double prob_adopt,
-
19995  bool normalize_exposure,
-
19996  double * agents_data,
-
19997  size_t data_ncols,
-
19998  std::vector< size_t > data_cols,
-
19999  std::vector< double > params
-
20000  )
-
20001 {
-
20002 
- -
20004  *this,
-
20005  innovation_name,
-
20006  prevalence,
-
20007  prob_adopt,
-
20008  normalize_exposure,
-
20009  agents_data,
-
20010  data_ncols,
-
20011  data_cols,
-
20012  params
-
20013  );
-
20014 
-
20015  return;
-
20016 
-
20017 }
-
20018 
-
20019 #endif
-
20020 /*//////////////////////////////////////////////////////////////////////////////
-
20022 
-
20023  End of -include/epiworld//models/diffnet.hpp-
-
20024 
-
20027 
-
20028 
-
20029 /*//////////////////////////////////////////////////////////////////////////////
-
20031 
-
20032  Start of -include/epiworld//models/seirmixing.hpp-
-
20033 
-
20036 
-
20037 
-
20038 #ifndef EPIWORLD_MODELS_SEIRMIXING_HPP
-
20039 #define EPIWORLD_MODELS_SEIRMIXING_HPP
-
20040 
-
20045 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
20046 class ModelSEIRMixing : public epiworld::Model<TSeq>
-
20047 {
-
20048 private:
-
20049  std::vector< std::vector< epiworld::Agent<TSeq> * > > infected;
-
20050  void update_infected();
-
20051  std::vector< epiworld::Agent<TSeq> * > sampled_agents;
-
20052  size_t sample_agents(
-
20053  epiworld::Agent<TSeq> * agent,
-
20054  std::vector< epiworld::Agent<TSeq> * > & sampled_agents
-
20055  );
-
20056  double adjusted_contact_rate;
-
20057  std::vector< double > contact_matrix;
+
19990  return;
+
19991 
+
19992  };
+
19993 
+
19994  // Adding agents data
+
19995  model.set_agents_data(agents_data, data_ncols);
+
19996 
+
19997  // Adding statuses
+
19998  model.add_state("Non adopters", update_non_adopters);
+
19999  model.add_state("Adopters");
+
20000 
+
20001  // Adding parameters
+
20002  std::string parname = std::string("Prob. Adopting ") + innovation_name;
+
20003  model.add_param(prob_adopt, parname);
+
20004 
+
20005  // Preparing the virus -------------------------------------------
+
20006  epiworld::Virus<TSeq> innovation(innovation_name, prevalence, true);
+
20007  innovation.set_state(1,1,1);
+
20008 
+
20009  innovation.set_prob_infecting(&model(parname));
+
20010 
+
20011  model.add_virus(innovation);
+
20012 
+
20013  model.set_name(
+
20014  std::string("Diffusion of Innovations - ") + innovation_name);
+
20015 
+
20016  return;
+
20017 
+
20018 }
+
20019 
+
20020 template<typename TSeq>
+ +
20022  const std::string & innovation_name,
+
20023  epiworld_double prevalence,
+
20024  epiworld_double prob_adopt,
+
20025  bool normalize_exposure,
+
20026  double * agents_data,
+
20027  size_t data_ncols,
+
20028  std::vector< size_t > data_cols,
+
20029  std::vector< double > params
+
20030  )
+
20031 {
+
20032 
+ +
20034  *this,
+
20035  innovation_name,
+
20036  prevalence,
+
20037  prob_adopt,
+
20038  normalize_exposure,
+
20039  agents_data,
+
20040  data_ncols,
+
20041  data_cols,
+
20042  params
+
20043  );
+
20044 
+
20045  return;
+
20046 
+
20047 }
+
20048 
+
20049 #endif
+
20050 /*//////////////////////////////////////////////////////////////////////////////
+
20052 
+
20053  End of -include/epiworld//models/diffnet.hpp-
+
20054 
+
20057 
20058 
-
20059  size_t index(size_t i, size_t j, size_t n) {
-
20060  return j * n + i;
-
20061  }
-
20062 
-
20063 public:
-
20064 
-
20065  static const int SUSCEPTIBLE = 0;
-
20066  static const int EXPOSED = 1;
-
20067  static const int INFECTED = 2;
-
20068  static const int RECOVERED = 3;
-
20069 
-
20070  ModelSEIRMixing() {};
-
20071 
-
20086  ModelSEIRMixing(
-
20087  ModelSEIRMixing<TSeq> & model,
-
20088  const std::string & vname,
-
20089  epiworld_fast_uint n,
-
20090  epiworld_double prevalence,
-
20091  epiworld_double contact_rate,
-
20092  epiworld_double transmission_rate,
-
20093  epiworld_double avg_incubation_days,
-
20094  epiworld_double recovery_rate,
-
20095  std::vector< double > contact_matrix
-
20096  );
-
20097 
-
20110  ModelSEIRMixing(
-
20111  const std::string & vname,
-
20112  epiworld_fast_uint n,
-
20113  epiworld_double prevalence,
-
20114  epiworld_double contact_rate,
-
20115  epiworld_double transmission_rate,
-
20116  epiworld_double avg_incubation_days,
-
20117  epiworld_double recovery_rate,
-
20118  std::vector< double > contact_matrix
-
20119  );
-
20120 
-
20121  ModelSEIRMixing<TSeq> & run(
-
20122  epiworld_fast_uint ndays,
-
20123  int seed = -1
-
20124  );
-
20125 
-
20126  void reset();
-
20127 
-
20128  Model<TSeq> * clone_ptr();
-
20129 
-
20135  ModelSEIRMixing<TSeq> & initial_states(
-
20136  std::vector< double > proportions_,
-
20137  std::vector< int > queue_ = {}
-
20138  );
-
20139 
-
20140  size_t get_n_infected(size_t group) const
-
20141  {
-
20142  return infected[group].size();
-
20143  }
-
20144 
-
20145  void set_contact_matrix(std::vector< double > cmat)
-
20146  {
-
20147  contact_matrix = cmat;
-
20148  return;
-
20149  };
+
20059 /*//////////////////////////////////////////////////////////////////////////////
+
20061 
+
20062  Start of -include/epiworld//models/seirmixing.hpp-
+
20063 
+
20066 
+
20067 
+
20068 #ifndef EPIWORLD_MODELS_SEIRMIXING_HPP
+
20069 #define EPIWORLD_MODELS_SEIRMIXING_HPP
+
20070 
+
20075 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
20076 class ModelSEIRMixing : public epiworld::Model<TSeq>
+
20077 {
+
20078 private:
+
20079  std::vector< std::vector< epiworld::Agent<TSeq> * > > infected;
+
20080  void update_infected();
+
20081  std::vector< epiworld::Agent<TSeq> * > sampled_agents;
+
20082  size_t sample_agents(
+
20083  epiworld::Agent<TSeq> * agent,
+
20084  std::vector< epiworld::Agent<TSeq> * > & sampled_agents
+
20085  );
+
20086  double adjusted_contact_rate;
+
20087  std::vector< double > contact_matrix;
+
20088 
+
20089  size_t index(size_t i, size_t j, size_t n) {
+
20090  return j * n + i;
+
20091  }
+
20092 
+
20093 public:
+
20094 
+
20095  static const int SUSCEPTIBLE = 0;
+
20096  static const int EXPOSED = 1;
+
20097  static const int INFECTED = 2;
+
20098  static const int RECOVERED = 3;
+
20099 
+
20100  ModelSEIRMixing() {};
+
20101 
+
20116  ModelSEIRMixing(
+
20117  ModelSEIRMixing<TSeq> & model,
+
20118  const std::string & vname,
+
20119  epiworld_fast_uint n,
+
20120  epiworld_double prevalence,
+
20121  epiworld_double contact_rate,
+
20122  epiworld_double transmission_rate,
+
20123  epiworld_double avg_incubation_days,
+
20124  epiworld_double recovery_rate,
+
20125  std::vector< double > contact_matrix
+
20126  );
+
20127 
+
20140  ModelSEIRMixing(
+
20141  const std::string & vname,
+
20142  epiworld_fast_uint n,
+
20143  epiworld_double prevalence,
+
20144  epiworld_double contact_rate,
+
20145  epiworld_double transmission_rate,
+
20146  epiworld_double avg_incubation_days,
+
20147  epiworld_double recovery_rate,
+
20148  std::vector< double > contact_matrix
+
20149  );
20150 
-
20151 };
-
20152 
-
20153 template<typename TSeq>
-
20154 inline void ModelSEIRMixing<TSeq>::update_infected()
-
20155 {
-
20156 
-
20157  auto & agents = Model<TSeq>::get_agents();
-
20158  auto & entities = Model<TSeq>::get_entities();
+
20151  ModelSEIRMixing<TSeq> & run(
+
20152  epiworld_fast_uint ndays,
+
20153  int seed = -1
+
20154  );
+
20155 
+
20156  void reset();
+
20157 
+
20158  Model<TSeq> * clone_ptr();
20159 
-
20160  infected.resize(entities.size());
-
20161  sampled_agents.resize(agents.size());
-
20162 
-
20163  // Checking contact matrix's rows add to one
-
20164  size_t nentities = entities.size();
-
20165  if (this->contact_matrix.size() != nentities*nentities)
-
20166  throw std::length_error(
-
20167  std::string("The contact matrix must be a square matrix of size ") +
-
20168  std::string("nentities x nentities. ") +
-
20169  std::to_string(this->contact_matrix.size()) +
-
20170  std::string(" != ") + std::to_string(nentities*nentities) +
-
20171  std::string(".")
-
20172  );
-
20173 
-
20174  for (size_t i = 0u; i < entities.size(); ++i)
-
20175  {
-
20176  double sum = 0.0;
-
20177  for (size_t j = 0u; j < entities.size(); ++j)
-
20178  {
-
20179  if (this->contact_matrix[index(i, j, nentities)] < 0.0)
-
20180  throw std::range_error(
-
20181  std::string("The contact matrix must be non-negative. ") +
-
20182  std::to_string(this->contact_matrix[index(i, j, nentities)]) +
-
20183  std::string(" < 0.")
-
20184  );
-
20185  sum += this->contact_matrix[index(i, j, nentities)];
-
20186  }
-
20187  if (sum < 0.999 || sum > 1.001)
-
20188  throw std::range_error(
-
20189  std::string("The contact matrix must have rows that add to one. ") +
-
20190  std::to_string(sum) +
-
20191  std::string(" != 1.")
-
20192  );
-
20193  }
-
20194 
-
20195  for (size_t i = 0; i < entities.size(); ++i)
-
20196  {
-
20197  infected[i].clear();
-
20198  infected[i].reserve(agents.size());
-
20199  }
-
20200 
-
20201  for (auto & a : agents)
-
20202  {
+
20165  ModelSEIRMixing<TSeq> & initial_states(
+
20166  std::vector< double > proportions_,
+
20167  std::vector< int > queue_ = {}
+
20168  );
+
20169 
+
20170  size_t get_n_infected(size_t group) const
+
20171  {
+
20172  return infected[group].size();
+
20173  }
+
20174 
+
20175  void set_contact_matrix(std::vector< double > cmat)
+
20176  {
+
20177  contact_matrix = cmat;
+
20178  return;
+
20179  };
+
20180 
+
20181 };
+
20182 
+
20183 template<typename TSeq>
+
20184 inline void ModelSEIRMixing<TSeq>::update_infected()
+
20185 {
+
20186 
+
20187  auto & agents = Model<TSeq>::get_agents();
+
20188  auto & entities = Model<TSeq>::get_entities();
+
20189 
+
20190  infected.resize(entities.size());
+
20191  sampled_agents.resize(agents.size());
+
20192 
+
20193  // Checking contact matrix's rows add to one
+
20194  size_t nentities = entities.size();
+
20195  if (this->contact_matrix.size() != nentities*nentities)
+
20196  throw std::length_error(
+
20197  std::string("The contact matrix must be a square matrix of size ") +
+
20198  std::string("nentities x nentities. ") +
+
20199  std::to_string(this->contact_matrix.size()) +
+
20200  std::string(" != ") + std::to_string(nentities*nentities) +
+
20201  std::string(".")
+
20202  );
20203 
-
20204  if (a.get_state() == ModelSEIRMixing<TSeq>::INFECTED)
-
20205  {
-
20206  if (a.get_n_entities() > 0u)
-
20207  infected[a.get_entity(0u).get_id()].push_back(&a);
-
20208  }
-
20209 
-
20210  }
-
20211 
-
20212  // Adjusting contact rate
-
20213  adjusted_contact_rate = Model<TSeq>::get_param("Contact rate") /
-
20214  agents.size();
-
20215 
-
20216  return;
-
20217 
-
20218 }
-
20219 
-
20220 template<typename TSeq>
-
20221 inline size_t ModelSEIRMixing<TSeq>::sample_agents(
-
20222  epiworld::Agent<TSeq> * agent,
-
20223  std::vector< epiworld::Agent<TSeq> * > & sampled_agents
-
20224  )
-
20225 {
-
20226 
-
20227  size_t agent_group_id = agent->get_entity(0u).get_id();
-
20228  size_t ngroups = infected.size();
-
20229 
-
20230  int samp_id = 0;
-
20231  for (size_t g = 0; g < infected.size(); ++g)
+
20204  for (size_t i = 0u; i < entities.size(); ++i)
+
20205  {
+
20206  double sum = 0.0;
+
20207  for (size_t j = 0u; j < entities.size(); ++j)
+
20208  {
+
20209  if (this->contact_matrix[index(i, j, nentities)] < 0.0)
+
20210  throw std::range_error(
+
20211  std::string("The contact matrix must be non-negative. ") +
+
20212  std::to_string(this->contact_matrix[index(i, j, nentities)]) +
+
20213  std::string(" < 0.")
+
20214  );
+
20215  sum += this->contact_matrix[index(i, j, nentities)];
+
20216  }
+
20217  if (sum < 0.999 || sum > 1.001)
+
20218  throw std::range_error(
+
20219  std::string("The contact matrix must have rows that add to one. ") +
+
20220  std::to_string(sum) +
+
20221  std::string(" != 1.")
+
20222  );
+
20223  }
+
20224 
+
20225  for (size_t i = 0; i < entities.size(); ++i)
+
20226  {
+
20227  infected[i].clear();
+
20228  infected[i].reserve(agents.size());
+
20229  }
+
20230 
+
20231  for (auto & a : agents)
20232  {
20233 
-
20234  // How many from this entity?
-
20235  int nsamples = epiworld::Model<TSeq>::rbinom(
-
20236  infected[g].size(),
-
20237  adjusted_contact_rate * contact_matrix[
-
20238  index(agent_group_id, g, ngroups)
-
20239  ]
-
20240  );
+
20234  if (a.get_state() == ModelSEIRMixing<TSeq>::INFECTED)
+
20235  {
+
20236  if (a.get_n_entities() > 0u)
+
20237  infected[a.get_entity(0u).get_id()].push_back(&a);
+
20238  }
+
20239 
+
20240  }
20241 
-
20242  if (nsamples == 0)
-
20243  continue;
-
20244 
-
20245  // Sampling from the entity
-
20246  for (int s = 0; s < nsamples; ++s)
-
20247  {
-
20248 
-
20249  // Randomly selecting an agent
-
20250  int which = epiworld::Model<TSeq>::runif() * infected[g].size();
-
20251 
-
20252  // Correcting overflow error
-
20253  if (which >= static_cast<int>(infected[g].size()))
-
20254  which = static_cast<int>(infected[g].size()) - 1;
-
20255 
-
20256  auto & a = infected[g][which];
-
20257 
-
20258  // Can't sample itself
-
20259  if (a->get_id() == agent->get_id())
-
20260  continue;
-
20261 
-
20262  sampled_agents[samp_id++] = a;
-
20263 
-
20264  }
-
20265 
-
20266  }
-
20267 
-
20268  return samp_id;
-
20269 
-
20270 }
+
20242  // Adjusting contact rate
+
20243  adjusted_contact_rate = Model<TSeq>::get_param("Contact rate") /
+
20244  agents.size();
+
20245 
+
20246  return;
+
20247 
+
20248 }
+
20249 
+
20250 template<typename TSeq>
+
20251 inline size_t ModelSEIRMixing<TSeq>::sample_agents(
+
20252  epiworld::Agent<TSeq> * agent,
+
20253  std::vector< epiworld::Agent<TSeq> * > & sampled_agents
+
20254  )
+
20255 {
+
20256 
+
20257  size_t agent_group_id = agent->get_entity(0u).get_id();
+
20258  size_t ngroups = infected.size();
+
20259 
+
20260  int samp_id = 0;
+
20261  for (size_t g = 0; g < infected.size(); ++g)
+
20262  {
+
20263 
+
20264  // How many from this entity?
+
20265  int nsamples = epiworld::Model<TSeq>::rbinom(
+
20266  infected[g].size(),
+
20267  adjusted_contact_rate * contact_matrix[
+
20268  index(agent_group_id, g, ngroups)
+
20269  ]
+
20270  );
20271 
-
20272 template<typename TSeq>
-
20273 inline ModelSEIRMixing<TSeq> & ModelSEIRMixing<TSeq>::run(
-
20274  epiworld_fast_uint ndays,
-
20275  int seed
-
20276 )
-
20277 {
+
20272  if (nsamples == 0)
+
20273  continue;
+
20274 
+
20275  // Sampling from the entity
+
20276  for (int s = 0; s < nsamples; ++s)
+
20277  {
20278 
-
20279  Model<TSeq>::run(ndays, seed);
-
20280  return *this;
+
20279  // Randomly selecting an agent
+
20280  int which = epiworld::Model<TSeq>::runif() * infected[g].size();
20281 
-
20282 }
-
20283 
-
20284 template<typename TSeq>
-
20285 inline void ModelSEIRMixing<TSeq>::reset()
-
20286 {
+
20282  // Correcting overflow error
+
20283  if (which >= static_cast<int>(infected[g].size()))
+
20284  which = static_cast<int>(infected[g].size()) - 1;
+
20285 
+
20286  auto & a = infected[g][which];
20287 
-
20288  Model<TSeq>::reset();
-
20289  this->update_infected();
-
20290 
-
20291  return;
-
20292 
-
20293 }
-
20294 
-
20295 template<typename TSeq>
-
20296 inline Model<TSeq> * ModelSEIRMixing<TSeq>::clone_ptr()
-
20297 {
-
20298 
-
20299  ModelSEIRMixing<TSeq> * ptr = new ModelSEIRMixing<TSeq>(
-
20300  *dynamic_cast<const ModelSEIRMixing<TSeq>*>(this)
-
20301  );
-
20302 
-
20303  return dynamic_cast< Model<TSeq> *>(ptr);
-
20304 
-
20305 }
-
20306 
-
20307 
-
20318 template<typename TSeq>
-
20319 inline ModelSEIRMixing<TSeq>::ModelSEIRMixing(
-
20320  ModelSEIRMixing<TSeq> & model,
-
20321  const std::string & vname,
-
20322  epiworld_fast_uint n,
-
20323  epiworld_double prevalence,
-
20324  epiworld_double contact_rate,
-
20325  epiworld_double transmission_rate,
-
20326  epiworld_double avg_incubation_days,
-
20327  epiworld_double recovery_rate,
-
20328  std::vector< double > contact_matrix
-
20329  )
-
20330 {
-
20331 
-
20332  // Setting up the contact matrix
-
20333  this->contact_matrix = contact_matrix;
+
20288  // Can't sample itself
+
20289  if (a->get_id() == agent->get_id())
+
20290  continue;
+
20291 
+
20292  sampled_agents[samp_id++] = a;
+
20293 
+
20294  }
+
20295 
+
20296  }
+
20297 
+
20298  return samp_id;
+
20299 
+
20300 }
+
20301 
+
20302 template<typename TSeq>
+
20303 inline ModelSEIRMixing<TSeq> & ModelSEIRMixing<TSeq>::run(
+
20304  epiworld_fast_uint ndays,
+
20305  int seed
+
20306 )
+
20307 {
+
20308 
+
20309  Model<TSeq>::run(ndays, seed);
+
20310  return *this;
+
20311 
+
20312 }
+
20313 
+
20314 template<typename TSeq>
+
20315 inline void ModelSEIRMixing<TSeq>::reset()
+
20316 {
+
20317 
+
20318  Model<TSeq>::reset();
+
20319  this->update_infected();
+
20320 
+
20321  return;
+
20322 
+
20323 }
+
20324 
+
20325 template<typename TSeq>
+
20326 inline Model<TSeq> * ModelSEIRMixing<TSeq>::clone_ptr()
+
20327 {
+
20328 
+
20329  ModelSEIRMixing<TSeq> * ptr = new ModelSEIRMixing<TSeq>(
+
20330  *dynamic_cast<const ModelSEIRMixing<TSeq>*>(this)
+
20331  );
+
20332 
+
20333  return dynamic_cast< Model<TSeq> *>(ptr);
20334 
-
20335  epiworld::UpdateFun<TSeq> update_susceptible = [](
-
20336  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
-
20337  ) -> void
-
20338  {
-
20339 
-
20340  if (p->get_n_entities() == 0)
-
20341  return;
-
20342 
-
20343  // Downcasting to retrieve the sampler attached to the
-
20344  // class
-
20345  ModelSEIRMixing<TSeq> * m_down =
-
20346  dynamic_cast<ModelSEIRMixing<TSeq> *>(m);
-
20347 
-
20348  size_t ndraws = m_down->sample_agents(p, m_down->sampled_agents);
-
20349 
-
20350  if (ndraws == 0u)
-
20351  return;
-
20352 
-
20353 
-
20354  // Drawing from the set
-
20355  int nviruses_tmp = 0;
-
20356  for (size_t n = 0u; n < ndraws; ++n)
-
20357  {
-
20358 
-
20359  auto & neighbor = m_down->sampled_agents[n];
-
20360 
-
20361  auto & v = neighbor->get_virus();
-
20362 
-
20363  #ifdef EPI_DEBUG
-
20364  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
-
20365  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
20366  #endif
-
20367 
-
20368  /* And it is a function of susceptibility_reduction as well */
-
20369  m->array_double_tmp[nviruses_tmp] =
-
20370  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
20371  v->get_prob_infecting(m) *
-
20372  (1.0 - neighbor->get_transmission_reduction(v, m))
-
20373  ;
-
20374 
-
20375  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
20376 
-
20377  }
-
20378 
-
20379  // Running the roulette
-
20380  int which = roulette(nviruses_tmp, m);
-
20381 
-
20382  if (which < 0)
-
20383  return;
-
20384 
-
20385  p->set_virus(
-
20386  *m->array_virus_tmp[which],
-
20387  m,
- -
20389  );
-
20390 
-
20391  return;
-
20392 
-
20393  };
-
20394 
-
20395  epiworld::UpdateFun<TSeq> update_infected = [](
- -
20397  ) -> void {
-
20398 
-
20399  auto state = p->get_state();
-
20400 
-
20401  if (state == ModelSEIRMixing<TSeq>::EXPOSED)
-
20402  {
-
20403 
-
20404  // Getting the virus
-
20405  auto & v = p->get_virus();
+
20335 }
+
20336 
+
20337 
+
20348 template<typename TSeq>
+
20349 inline ModelSEIRMixing<TSeq>::ModelSEIRMixing(
+
20350  ModelSEIRMixing<TSeq> & model,
+
20351  const std::string & vname,
+
20352  epiworld_fast_uint n,
+
20353  epiworld_double prevalence,
+
20354  epiworld_double contact_rate,
+
20355  epiworld_double transmission_rate,
+
20356  epiworld_double avg_incubation_days,
+
20357  epiworld_double recovery_rate,
+
20358  std::vector< double > contact_matrix
+
20359  )
+
20360 {
+
20361 
+
20362  // Setting up the contact matrix
+
20363  this->contact_matrix = contact_matrix;
+
20364 
+
20365  epiworld::UpdateFun<TSeq> update_susceptible = [](
+
20366  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
+
20367  ) -> void
+
20368  {
+
20369 
+
20370  if (p->get_n_entities() == 0)
+
20371  return;
+
20372 
+
20373  // Downcasting to retrieve the sampler attached to the
+
20374  // class
+
20375  ModelSEIRMixing<TSeq> * m_down =
+
20376  dynamic_cast<ModelSEIRMixing<TSeq> *>(m);
+
20377 
+
20378  size_t ndraws = m_down->sample_agents(p, m_down->sampled_agents);
+
20379 
+
20380  if (ndraws == 0u)
+
20381  return;
+
20382 
+
20383 
+
20384  // Drawing from the set
+
20385  int nviruses_tmp = 0;
+
20386  for (size_t n = 0u; n < ndraws; ++n)
+
20387  {
+
20388 
+
20389  auto & neighbor = m_down->sampled_agents[n];
+
20390 
+
20391  auto & v = neighbor->get_virus();
+
20392 
+
20393  #ifdef EPI_DEBUG
+
20394  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
+
20395  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
20396  #endif
+
20397 
+
20398  /* And it is a function of susceptibility_reduction as well */
+
20399  m->array_double_tmp[nviruses_tmp] =
+
20400  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
20401  v->get_prob_infecting(m) *
+
20402  (1.0 - neighbor->get_transmission_reduction(v, m))
+
20403  ;
+
20404 
+
20405  m->array_virus_tmp[nviruses_tmp++] = &(*v);
20406 
-
20407  // Does the agent become infected?
-
20408  if (m->runif() < 1.0/(v->get_incubation(m)))
-
20409  {
-
20410 
-
20411  p->change_state(m, ModelSEIRMixing<TSeq>::INFECTED);
-
20412  return;
-
20413 
-
20414  }
-
20415 
-
20416 
-
20417  } else if (state == ModelSEIRMixing<TSeq>::INFECTED)
-
20418  {
-
20419 
+
20407  }
+
20408 
+
20409  // Running the roulette
+
20410  int which = roulette(nviruses_tmp, m);
+
20411 
+
20412  if (which < 0)
+
20413  return;
+
20414 
+
20415  p->set_virus(
+
20416  *m->array_virus_tmp[which],
+
20417  m,
+ +
20419  );
20420 
-
20421  // Odd: Die, Even: Recover
-
20422  epiworld_fast_uint n_events = 0u;
-
20423  const auto & v = p->get_virus();
+
20421  return;
+
20422 
+
20423  };
20424 
-
20425  // Recover
-
20426  m->array_double_tmp[n_events++] =
-
20427  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
+
20425  epiworld::UpdateFun<TSeq> update_infected = [](
+ +
20427  ) -> void {
20428 
-
20429  #ifdef EPI_DEBUG
-
20430  if (n_events == 0u)
-
20431  {
-
20432  printf_epiworld(
-
20433  "[epi-debug] agent %i has 0 possible events!!\n",
-
20434  static_cast<int>(p->get_id())
-
20435  );
-
20436  throw std::logic_error("Zero events in exposed.");
-
20437  }
-
20438  #else
-
20439  if (n_events == 0u)
-
20440  return;
-
20441  #endif
-
20442 
+
20429  auto state = p->get_state();
+
20430 
+
20431  if (state == ModelSEIRMixing<TSeq>::EXPOSED)
+
20432  {
+
20433 
+
20434  // Getting the virus
+
20435  auto & v = p->get_virus();
+
20436 
+
20437  // Does the agent become infected?
+
20438  if (m->runif() < 1.0/(v->get_incubation(m)))
+
20439  {
+
20440 
+
20441  p->change_state(m, ModelSEIRMixing<TSeq>::INFECTED);
+
20442  return;
20443 
-
20444  // Running the roulette
-
20445  int which = roulette(n_events, m);
+
20444  }
+
20445 
20446 
-
20447  if (which < 0)
-
20448  return;
+
20447  } else if (state == ModelSEIRMixing<TSeq>::INFECTED)
+
20448  {
20449 
-
20450  // Which roulette happen?
-
20451  p->rm_virus(m);
-
20452 
-
20453  return ;
+
20450 
+
20451  // Odd: Die, Even: Recover
+
20452  epiworld_fast_uint n_events = 0u;
+
20453  const auto & v = p->get_virus();
20454 
-
20455  } else
-
20456  throw std::logic_error("This function can only be applied to exposed or infected individuals. (SEIR)") ;
-
20457 
-
20458  return;
-
20459 
-
20460  };
-
20461 
-
20462  // Setting up parameters
-
20463  model.add_param(contact_rate, "Contact rate");
-
20464  model.add_param(transmission_rate, "Prob. Transmission");
-
20465  model.add_param(recovery_rate, "Prob. Recovery");
-
20466  model.add_param(avg_incubation_days, "Avg. Incubation days");
-
20467 
-
20468  // state
-
20469  model.add_state("Susceptible", update_susceptible);
-
20470  model.add_state("Exposed", update_infected);
-
20471  model.add_state("Infected", update_infected);
-
20472  model.add_state("Recovered");
+
20455  // Recover
+
20456  m->array_double_tmp[n_events++] =
+
20457  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
+
20458 
+
20459  #ifdef EPI_DEBUG
+
20460  if (n_events == 0u)
+
20461  {
+
20462  printf_epiworld(
+
20463  "[epi-debug] agent %i has 0 possible events!!\n",
+
20464  static_cast<int>(p->get_id())
+
20465  );
+
20466  throw std::logic_error("Zero events in exposed.");
+
20467  }
+
20468  #else
+
20469  if (n_events == 0u)
+
20470  return;
+
20471  #endif
+
20472 
20473 
-
20474  // Global function
-
20475  epiworld::GlobalFun<TSeq> update = [](epiworld::Model<TSeq> * m) -> void
-
20476  {
-
20477 
-
20478  ModelSEIRMixing<TSeq> * m_down =
-
20479  dynamic_cast<ModelSEIRMixing<TSeq> *>(m);
-
20480 
-
20481  m_down->update_infected();
+
20474  // Running the roulette
+
20475  int which = roulette(n_events, m);
+
20476 
+
20477  if (which < 0)
+
20478  return;
+
20479 
+
20480  // Which roulette happen?
+
20481  p->rm_virus(m);
20482 
-
20483  return;
+
20483  return ;
20484 
-
20485  };
-
20486 
-
20487  model.add_globalevent(update, "Update infected individuals");
-
20488 
+
20485  } else
+
20486  throw std::logic_error("This function can only be applied to exposed or infected individuals. (SEIR)") ;
+
20487 
+
20488  return;
20489 
-
20490  // Preparing the virus -------------------------------------------
-
20491  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
20492  virus.set_state(
- - - -
20496  );
-
20497 
-
20498  virus.set_prob_infecting(&model("Prob. Transmission"));
-
20499  virus.set_prob_recovery(&model("Prob. Recovery"));
-
20500  virus.set_incubation(&model("Avg. Incubation days"));
-
20501 
-
20502  model.add_virus(virus);
+
20490  };
+
20491 
+
20492  // Setting up parameters
+
20493  model.add_param(contact_rate, "Contact rate");
+
20494  model.add_param(transmission_rate, "Prob. Transmission");
+
20495  model.add_param(recovery_rate, "Prob. Recovery");
+
20496  model.add_param(avg_incubation_days, "Avg. Incubation days");
+
20497 
+
20498  // state
+
20499  model.add_state("Susceptible", update_susceptible);
+
20500  model.add_state("Exposed", update_infected);
+
20501  model.add_state("Infected", update_infected);
+
20502  model.add_state("Recovered");
20503 
-
20504  model.queuing_off(); // No queuing need
-
20505 
-
20506  // Adding the empty population
-
20507  model.agents_empty_graph(n);
-
20508 
-
20509  model.set_name("Susceptible-Exposed-Infected-Removed (SEIR) with Mixing");
+
20504  // Global function
+
20505  epiworld::GlobalFun<TSeq> update = [](epiworld::Model<TSeq> * m) -> void
+
20506  {
+
20507 
+
20508  ModelSEIRMixing<TSeq> * m_down =
+
20509  dynamic_cast<ModelSEIRMixing<TSeq> *>(m);
20510 
-
20511  return;
+
20511  m_down->update_infected();
20512 
-
20513 }
+
20513  return;
20514 
-
20515 template<typename TSeq>
- -
20517  const std::string & vname,
-
20518  epiworld_fast_uint n,
-
20519  epiworld_double prevalence,
-
20520  epiworld_double contact_rate,
-
20521  epiworld_double transmission_rate,
-
20522  epiworld_double avg_incubation_days,
-
20523  epiworld_double recovery_rate,
-
20524  std::vector< double > contact_matrix
-
20525  )
-
20526 {
+
20515  };
+
20516 
+
20517  model.add_globalevent(update, "Update infected individuals");
+
20518 
+
20519 
+
20520  // Preparing the virus -------------------------------------------
+
20521  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
20522  virus.set_state(
+ + + +
20526  );
20527 
-
20528  this->contact_matrix = contact_matrix;
-
20529 
- -
20531  *this,
-
20532  vname,
-
20533  n,
-
20534  prevalence,
-
20535  contact_rate,
-
20536  transmission_rate,
-
20537  avg_incubation_days,
-
20538  recovery_rate,
-
20539  contact_matrix
-
20540  );
-
20541 
-
20542  return;
-
20543 
-
20544 }
-
20545 
-
20546 template<typename TSeq>
- -
20548  std::vector< double > proportions_,
-
20549  std::vector< int > /* queue_ */
-
20550 )
-
20551 {
-
20552 
- -
20554  create_init_function_seir<TSeq>(proportions_)
-
20555  ;
-
20556 
-
20557  return *this;
-
20558 
-
20559 }
-
20560 
-
20561 #endif
-
20562 /*//////////////////////////////////////////////////////////////////////////////
-
20564 
-
20565  End of -include/epiworld//models/seirmixing.hpp-
-
20566 
-
20569 
-
20570 
-
20571 /*//////////////////////////////////////////////////////////////////////////////
-
20573 
-
20574  Start of -include/epiworld//models/sirmixing.hpp-
-
20575 
-
20578 
-
20579 
-
20580 #ifndef EPIWORLD_MODELS_SIRMIXING_HPP
-
20581 #define EPIWORLD_MODELS_SIRMIXING_HPP
-
20582 
-
20587 template<typename TSeq = EPI_DEFAULT_TSEQ>
-
20588 class ModelSIRMixing : public epiworld::Model<TSeq>
-
20589 {
-
20590 private:
-
20591  std::vector< std::vector< epiworld::Agent<TSeq> * > > infected;
-
20592  void update_infected_list();
-
20593  std::vector< epiworld::Agent<TSeq> * > sampled_agents;
-
20594  size_t sample_agents(
-
20595  epiworld::Agent<TSeq> * agent,
-
20596  std::vector< epiworld::Agent<TSeq> * > & sampled_agents
-
20597  );
-
20598  double adjusted_contact_rate;
-
20599  std::vector< double > contact_matrix;
+
20528  virus.set_prob_infecting(&model("Prob. Transmission"));
+
20529  virus.set_prob_recovery(&model("Prob. Recovery"));
+
20530  virus.set_incubation(&model("Avg. Incubation days"));
+
20531 
+
20532  model.add_virus(virus);
+
20533 
+
20534  model.queuing_off(); // No queuing need
+
20535 
+
20536  // Adding the empty population
+
20537  model.agents_empty_graph(n);
+
20538 
+
20539  model.set_name("Susceptible-Exposed-Infected-Removed (SEIR) with Mixing");
+
20540 
+
20541  return;
+
20542 
+
20543 }
+
20544 
+
20545 template<typename TSeq>
+ +
20547  const std::string & vname,
+
20548  epiworld_fast_uint n,
+
20549  epiworld_double prevalence,
+
20550  epiworld_double contact_rate,
+
20551  epiworld_double transmission_rate,
+
20552  epiworld_double avg_incubation_days,
+
20553  epiworld_double recovery_rate,
+
20554  std::vector< double > contact_matrix
+
20555  )
+
20556 {
+
20557 
+
20558  this->contact_matrix = contact_matrix;
+
20559 
+ +
20561  *this,
+
20562  vname,
+
20563  n,
+
20564  prevalence,
+
20565  contact_rate,
+
20566  transmission_rate,
+
20567  avg_incubation_days,
+
20568  recovery_rate,
+
20569  contact_matrix
+
20570  );
+
20571 
+
20572  return;
+
20573 
+
20574 }
+
20575 
+
20576 template<typename TSeq>
+ +
20578  std::vector< double > proportions_,
+
20579  std::vector< int > /* queue_ */
+
20580 )
+
20581 {
+
20582 
+ +
20584  create_init_function_seir<TSeq>(proportions_)
+
20585  ;
+
20586 
+
20587  return *this;
+
20588 
+
20589 }
+
20590 
+
20591 #endif
+
20592 /*//////////////////////////////////////////////////////////////////////////////
+
20594 
+
20595  End of -include/epiworld//models/seirmixing.hpp-
+
20596 
+
20599 
20600 
-
20601  size_t index(size_t i, size_t j, size_t n) {
-
20602  return j * n + i;
-
20603  }
-
20604 
-
20605 public:
-
20606 
-
20607  static const int SUSCEPTIBLE = 0;
-
20608  static const int INFECTED = 1;
-
20609  static const int RECOVERED = 2;
-
20610 
-
20611  ModelSIRMixing() {};
-
20612 
-
20625  ModelSIRMixing(
-
20626  ModelSIRMixing<TSeq> & model,
-
20627  const std::string & vname,
-
20628  epiworld_fast_uint n,
-
20629  epiworld_double prevalence,
-
20630  epiworld_double contact_rate,
-
20631  epiworld_double transmission_rate,
-
20632  epiworld_double recovery_rate,
-
20633  std::vector< double > contact_matrix
-
20634  );
-
20635 
-
20647  ModelSIRMixing(
-
20648  const std::string & vname,
-
20649  epiworld_fast_uint n,
-
20650  epiworld_double prevalence,
-
20651  epiworld_double contact_rate,
-
20652  epiworld_double transmission_rate,
-
20653  epiworld_double recovery_rate,
-
20654  std::vector< double > contact_matrix
-
20655  );
-
20656 
-
20657  ModelSIRMixing<TSeq> & run(
-
20658  epiworld_fast_uint ndays,
-
20659  int seed = -1
-
20660  );
-
20661 
-
20662  void reset();
-
20663 
-
20664  Model<TSeq> * clone_ptr();
-
20665 
-
20671  ModelSIRMixing<TSeq> & initial_states(
-
20672  std::vector< double > proportions_,
-
20673  std::vector< int > queue_ = {}
-
20674  );
-
20675 
-
20676  size_t get_n_infected(size_t group) const
-
20677  {
-
20678  return infected[group].size();
-
20679  }
-
20680 
-
20681  void set_contact_matrix(std::vector< double > cmat)
-
20682  {
-
20683  contact_matrix = cmat;
-
20684  return;
-
20685  };
+
20601 /*//////////////////////////////////////////////////////////////////////////////
+
20603 
+
20604  Start of -include/epiworld//models/sirmixing.hpp-
+
20605 
+
20608 
+
20609 
+
20610 #ifndef EPIWORLD_MODELS_SIRMIXING_HPP
+
20611 #define EPIWORLD_MODELS_SIRMIXING_HPP
+
20612 
+
20617 template<typename TSeq = EPI_DEFAULT_TSEQ>
+
20618 class ModelSIRMixing : public epiworld::Model<TSeq>
+
20619 {
+
20620 private:
+
20621  std::vector< std::vector< epiworld::Agent<TSeq> * > > infected;
+
20622  void update_infected_list();
+
20623  std::vector< epiworld::Agent<TSeq> * > sampled_agents;
+
20624  size_t sample_agents(
+
20625  epiworld::Agent<TSeq> * agent,
+
20626  std::vector< epiworld::Agent<TSeq> * > & sampled_agents
+
20627  );
+
20628  double adjusted_contact_rate;
+
20629  std::vector< double > contact_matrix;
+
20630 
+
20631  size_t index(size_t i, size_t j, size_t n) {
+
20632  return j * n + i;
+
20633  }
+
20634 
+
20635 public:
+
20636 
+
20637  static const int SUSCEPTIBLE = 0;
+
20638  static const int INFECTED = 1;
+
20639  static const int RECOVERED = 2;
+
20640 
+
20641  ModelSIRMixing() {};
+
20642 
+
20655  ModelSIRMixing(
+
20656  ModelSIRMixing<TSeq> & model,
+
20657  const std::string & vname,
+
20658  epiworld_fast_uint n,
+
20659  epiworld_double prevalence,
+
20660  epiworld_double contact_rate,
+
20661  epiworld_double transmission_rate,
+
20662  epiworld_double recovery_rate,
+
20663  std::vector< double > contact_matrix
+
20664  );
+
20665 
+
20677  ModelSIRMixing(
+
20678  const std::string & vname,
+
20679  epiworld_fast_uint n,
+
20680  epiworld_double prevalence,
+
20681  epiworld_double contact_rate,
+
20682  epiworld_double transmission_rate,
+
20683  epiworld_double recovery_rate,
+
20684  std::vector< double > contact_matrix
+
20685  );
20686 
-
20687 };
-
20688 
-
20689 template<typename TSeq>
-
20690 inline void ModelSIRMixing<TSeq>::update_infected_list()
-
20691 {
-
20692 
-
20693  auto & agents = Model<TSeq>::get_agents();
-
20694  auto & entities = Model<TSeq>::get_entities();
+
20687  ModelSIRMixing<TSeq> & run(
+
20688  epiworld_fast_uint ndays,
+
20689  int seed = -1
+
20690  );
+
20691 
+
20692  void reset();
+
20693 
+
20694  Model<TSeq> * clone_ptr();
20695 
-
20696  infected.resize(entities.size());
-
20697  sampled_agents.resize(agents.size());
-
20698 
-
20699  // Checking contact matrix's rows add to one
-
20700  size_t nentities = entities.size();
-
20701  if (this->contact_matrix.size() != nentities*nentities)
-
20702  throw std::length_error(
-
20703  std::string("The contact matrix must be a square matrix of size ") +
-
20704  std::string("nentities x nentities. ") +
-
20705  std::to_string(this->contact_matrix.size()) +
-
20706  std::string(" != ") + std::to_string(nentities*nentities) +
-
20707  std::string(".")
-
20708  );
-
20709 
-
20710  for (size_t i = 0u; i < entities.size(); ++i)
-
20711  {
-
20712  double sum = 0.0;
-
20713  for (size_t j = 0u; j < entities.size(); ++j)
-
20714  {
-
20715  if (this->contact_matrix[index(i, j, nentities)] < 0.0)
-
20716  throw std::range_error(
-
20717  std::string("The contact matrix must be non-negative. ") +
-
20718  std::to_string(this->contact_matrix[index(i, j, nentities)]) +
-
20719  std::string(" < 0.")
-
20720  );
-
20721  sum += this->contact_matrix[index(i, j, nentities)];
-
20722  }
-
20723  if (sum < 0.999 || sum > 1.001)
-
20724  throw std::range_error(
-
20725  std::string("The contact matrix must have rows that add to one. ") +
-
20726  std::to_string(sum) +
-
20727  std::string(" != 1.")
-
20728  );
-
20729  }
-
20730 
-
20731  for (size_t i = 0; i < entities.size(); ++i)
-
20732  {
-
20733  infected[i].clear();
-
20734  infected[i].reserve(agents.size());
-
20735  }
-
20736 
-
20737  for (auto & a : agents)
-
20738  {
+
20701  ModelSIRMixing<TSeq> & initial_states(
+
20702  std::vector< double > proportions_,
+
20703  std::vector< int > queue_ = {}
+
20704  );
+
20705 
+
20706  size_t get_n_infected(size_t group) const
+
20707  {
+
20708  return infected[group].size();
+
20709  }
+
20710 
+
20711  void set_contact_matrix(std::vector< double > cmat)
+
20712  {
+
20713  contact_matrix = cmat;
+
20714  return;
+
20715  };
+
20716 
+
20717 };
+
20718 
+
20719 template<typename TSeq>
+
20720 inline void ModelSIRMixing<TSeq>::update_infected_list()
+
20721 {
+
20722 
+
20723  auto & agents = Model<TSeq>::get_agents();
+
20724  auto & entities = Model<TSeq>::get_entities();
+
20725 
+
20726  infected.resize(entities.size());
+
20727  sampled_agents.resize(agents.size());
+
20728 
+
20729  // Checking contact matrix's rows add to one
+
20730  size_t nentities = entities.size();
+
20731  if (this->contact_matrix.size() != nentities*nentities)
+
20732  throw std::length_error(
+
20733  std::string("The contact matrix must be a square matrix of size ") +
+
20734  std::string("nentities x nentities. ") +
+
20735  std::to_string(this->contact_matrix.size()) +
+
20736  std::string(" != ") + std::to_string(nentities*nentities) +
+
20737  std::string(".")
+
20738  );
20739 
-
20740  if (a.get_state() == ModelSIRMixing<TSeq>::INFECTED)
-
20741  {
-
20742  if (a.get_n_entities() > 0u)
-
20743  infected[a.get_entity(0u).get_id()].push_back(&a);
-
20744  }
-
20745 
-
20746  }
-
20747 
-
20748  // Adjusting contact rate
-
20749  adjusted_contact_rate = Model<TSeq>::get_param("Contact rate") /
-
20750  agents.size();
-
20751 
-
20752  return;
-
20753 
-
20754 }
-
20755 
-
20756 template<typename TSeq>
-
20757 inline size_t ModelSIRMixing<TSeq>::sample_agents(
-
20758  epiworld::Agent<TSeq> * agent,
-
20759  std::vector< epiworld::Agent<TSeq> * > & sampled_agents
-
20760  )
-
20761 {
-
20762 
-
20763  size_t agent_group_id = agent->get_entity(0u).get_id();
-
20764  size_t ngroups = infected.size();
-
20765 
-
20766  int samp_id = 0;
-
20767  for (size_t g = 0; g < infected.size(); ++g)
+
20740  for (size_t i = 0u; i < entities.size(); ++i)
+
20741  {
+
20742  double sum = 0.0;
+
20743  for (size_t j = 0u; j < entities.size(); ++j)
+
20744  {
+
20745  if (this->contact_matrix[index(i, j, nentities)] < 0.0)
+
20746  throw std::range_error(
+
20747  std::string("The contact matrix must be non-negative. ") +
+
20748  std::to_string(this->contact_matrix[index(i, j, nentities)]) +
+
20749  std::string(" < 0.")
+
20750  );
+
20751  sum += this->contact_matrix[index(i, j, nentities)];
+
20752  }
+
20753  if (sum < 0.999 || sum > 1.001)
+
20754  throw std::range_error(
+
20755  std::string("The contact matrix must have rows that add to one. ") +
+
20756  std::to_string(sum) +
+
20757  std::string(" != 1.")
+
20758  );
+
20759  }
+
20760 
+
20761  for (size_t i = 0; i < entities.size(); ++i)
+
20762  {
+
20763  infected[i].clear();
+
20764  infected[i].reserve(agents.size());
+
20765  }
+
20766 
+
20767  for (auto & a : agents)
20768  {
20769 
-
20770  // How many from this entity?
-
20771  int nsamples = epiworld::Model<TSeq>::rbinom(
-
20772  infected[g].size(),
-
20773  adjusted_contact_rate * contact_matrix[
-
20774  index(agent_group_id, g, ngroups)
-
20775  ]
-
20776  );
+
20770  if (a.get_state() == ModelSIRMixing<TSeq>::INFECTED)
+
20771  {
+
20772  if (a.get_n_entities() > 0u)
+
20773  infected[a.get_entity(0u).get_id()].push_back(&a);
+
20774  }
+
20775 
+
20776  }
20777 
-
20778  if (nsamples == 0)
-
20779  continue;
-
20780 
-
20781  // Sampling from the entity
-
20782  for (int s = 0; s < nsamples; ++s)
-
20783  {
-
20784 
-
20785  // Randomly selecting an agent
-
20786  int which = epiworld::Model<TSeq>::runif() * infected[g].size();
-
20787 
-
20788  // Correcting overflow error
-
20789  if (which >= static_cast<int>(infected[g].size()))
-
20790  which = static_cast<int>(infected[g].size()) - 1;
-
20791 
-
20792  auto & a = infected[g][which];
-
20793 
-
20794  // Can't sample itself
-
20795  if (a->get_id() == agent->get_id())
-
20796  continue;
-
20797 
-
20798  sampled_agents[samp_id++] = a;
-
20799 
-
20800  }
-
20801 
-
20802  }
-
20803 
-
20804  return samp_id;
-
20805 
-
20806 }
+
20778  // Adjusting contact rate
+
20779  adjusted_contact_rate = Model<TSeq>::get_param("Contact rate") /
+
20780  agents.size();
+
20781 
+
20782  return;
+
20783 
+
20784 }
+
20785 
+
20786 template<typename TSeq>
+
20787 inline size_t ModelSIRMixing<TSeq>::sample_agents(
+
20788  epiworld::Agent<TSeq> * agent,
+
20789  std::vector< epiworld::Agent<TSeq> * > & sampled_agents
+
20790  )
+
20791 {
+
20792 
+
20793  size_t agent_group_id = agent->get_entity(0u).get_id();
+
20794  size_t ngroups = infected.size();
+
20795 
+
20796  int samp_id = 0;
+
20797  for (size_t g = 0; g < infected.size(); ++g)
+
20798  {
+
20799 
+
20800  // How many from this entity?
+
20801  int nsamples = epiworld::Model<TSeq>::rbinom(
+
20802  infected[g].size(),
+
20803  adjusted_contact_rate * contact_matrix[
+
20804  index(agent_group_id, g, ngroups)
+
20805  ]
+
20806  );
20807 
-
20808 template<typename TSeq>
-
20809 inline ModelSIRMixing<TSeq> & ModelSIRMixing<TSeq>::run(
-
20810  epiworld_fast_uint ndays,
-
20811  int seed
-
20812 )
-
20813 {
-
20814 
-
20815  Model<TSeq>::run(ndays, seed);
-
20816  return *this;
+
20808  if (nsamples == 0)
+
20809  continue;
+
20810 
+
20811  // Sampling from the entity
+
20812  for (int s = 0; s < nsamples; ++s)
+
20813  {
+
20814 
+
20815  // Randomly selecting an agent
+
20816  int which = epiworld::Model<TSeq>::runif() * infected[g].size();
20817 
-
20818 }
-
20819 
-
20820 template<typename TSeq>
-
20821 inline void ModelSIRMixing<TSeq>::reset()
-
20822 {
+
20818  // Correcting overflow error
+
20819  if (which >= static_cast<int>(infected[g].size()))
+
20820  which = static_cast<int>(infected[g].size()) - 1;
+
20821 
+
20822  auto & a = infected[g][which];
20823 
-
20824  Model<TSeq>::reset();
-
20825  this->update_infected_list();
-
20826 
-
20827  return;
-
20828 
-
20829 }
-
20830 
-
20831 template<typename TSeq>
-
20832 inline Model<TSeq> * ModelSIRMixing<TSeq>::clone_ptr()
-
20833 {
-
20834 
-
20835  ModelSIRMixing<TSeq> * ptr = new ModelSIRMixing<TSeq>(
-
20836  *dynamic_cast<const ModelSIRMixing<TSeq>*>(this)
-
20837  );
-
20838 
-
20839  return dynamic_cast< Model<TSeq> *>(ptr);
-
20840 
-
20841 }
-
20842 
-
20843 
-
20854 template<typename TSeq>
-
20855 inline ModelSIRMixing<TSeq>::ModelSIRMixing(
-
20856  ModelSIRMixing<TSeq> & model,
-
20857  const std::string & vname,
-
20858  epiworld_fast_uint n,
-
20859  epiworld_double prevalence,
-
20860  epiworld_double contact_rate,
-
20861  epiworld_double transmission_rate,
-
20862  epiworld_double recovery_rate,
-
20863  std::vector< double > contact_matrix
-
20864  )
-
20865 {
-
20866 
-
20867  // Setting up the contact matrix
-
20868  this->contact_matrix = contact_matrix;
-
20869 
-
20870  epiworld::UpdateFun<TSeq> update_susceptible = [](
-
20871  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
-
20872  ) -> void
-
20873  {
-
20874 
-
20875  if (p->get_n_entities() == 0)
-
20876  return;
-
20877 
-
20878  // Downcasting to retrieve the sampler attached to the
-
20879  // class
-
20880  ModelSIRMixing<TSeq> * m_down =
-
20881  dynamic_cast<ModelSIRMixing<TSeq> *>(m);
-
20882 
-
20883  size_t ndraws = m_down->sample_agents(p, m_down->sampled_agents);
-
20884 
-
20885  if (ndraws == 0u)
-
20886  return;
-
20887 
-
20888 
-
20889  // Drawing from the set
-
20890  int nviruses_tmp = 0;
-
20891  for (size_t n = 0u; n < ndraws; ++n)
-
20892  {
-
20893 
-
20894  auto & neighbor = m_down->sampled_agents[n];
-
20895 
-
20896  auto & v = neighbor->get_virus();
-
20897 
-
20898  #ifdef EPI_DEBUG
-
20899  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
-
20900  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
-
20901  #endif
-
20902 
-
20903  /* And it is a function of susceptibility_reduction as well */
-
20904  m->array_double_tmp[nviruses_tmp] =
-
20905  (1.0 - p->get_susceptibility_reduction(v, m)) *
-
20906  v->get_prob_infecting(m) *
-
20907  (1.0 - neighbor->get_transmission_reduction(v, m))
-
20908  ;
-
20909 
-
20910  m->array_virus_tmp[nviruses_tmp++] = &(*v);
-
20911 
-
20912  }
-
20913 
-
20914  // Running the roulette
-
20915  int which = roulette(nviruses_tmp, m);
-
20916 
-
20917  if (which < 0)
-
20918  return;
-
20919 
-
20920  p->set_virus(
-
20921  *m->array_virus_tmp[which],
-
20922  m,
- -
20924  );
-
20925 
-
20926  return;
-
20927 
-
20928  };
-
20929 
-
20930  epiworld::UpdateFun<TSeq> update_infected = [](
- -
20932  ) -> void {
-
20933 
-
20934  auto state = p->get_state();
-
20935 
-
20936  if (state == ModelSIRMixing<TSeq>::INFECTED)
-
20937  {
-
20938 
-
20939 
-
20940  // Odd: Die, Even: Recover
-
20941  epiworld_fast_uint n_events = 0u;
-
20942  const auto & v = p->get_virus();
+
20824  // Can't sample itself
+
20825  if (a->get_id() == agent->get_id())
+
20826  continue;
+
20827 
+
20828  sampled_agents[samp_id++] = a;
+
20829 
+
20830  }
+
20831 
+
20832  }
+
20833 
+
20834  return samp_id;
+
20835 
+
20836 }
+
20837 
+
20838 template<typename TSeq>
+
20839 inline ModelSIRMixing<TSeq> & ModelSIRMixing<TSeq>::run(
+
20840  epiworld_fast_uint ndays,
+
20841  int seed
+
20842 )
+
20843 {
+
20844 
+
20845  Model<TSeq>::run(ndays, seed);
+
20846  return *this;
+
20847 
+
20848 }
+
20849 
+
20850 template<typename TSeq>
+
20851 inline void ModelSIRMixing<TSeq>::reset()
+
20852 {
+
20853 
+
20854  Model<TSeq>::reset();
+
20855  this->update_infected_list();
+
20856 
+
20857  return;
+
20858 
+
20859 }
+
20860 
+
20861 template<typename TSeq>
+
20862 inline Model<TSeq> * ModelSIRMixing<TSeq>::clone_ptr()
+
20863 {
+
20864 
+
20865  ModelSIRMixing<TSeq> * ptr = new ModelSIRMixing<TSeq>(
+
20866  *dynamic_cast<const ModelSIRMixing<TSeq>*>(this)
+
20867  );
+
20868 
+
20869  return dynamic_cast< Model<TSeq> *>(ptr);
+
20870 
+
20871 }
+
20872 
+
20873 
+
20884 template<typename TSeq>
+
20885 inline ModelSIRMixing<TSeq>::ModelSIRMixing(
+
20886  ModelSIRMixing<TSeq> & model,
+
20887  const std::string & vname,
+
20888  epiworld_fast_uint n,
+
20889  epiworld_double prevalence,
+
20890  epiworld_double contact_rate,
+
20891  epiworld_double transmission_rate,
+
20892  epiworld_double recovery_rate,
+
20893  std::vector< double > contact_matrix
+
20894  )
+
20895 {
+
20896 
+
20897  // Setting up the contact matrix
+
20898  this->contact_matrix = contact_matrix;
+
20899 
+
20900  epiworld::UpdateFun<TSeq> update_susceptible = [](
+
20901  epiworld::Agent<TSeq> * p, epiworld::Model<TSeq> * m
+
20902  ) -> void
+
20903  {
+
20904 
+
20905  if (p->get_n_entities() == 0)
+
20906  return;
+
20907 
+
20908  // Downcasting to retrieve the sampler attached to the
+
20909  // class
+
20910  ModelSIRMixing<TSeq> * m_down =
+
20911  dynamic_cast<ModelSIRMixing<TSeq> *>(m);
+
20912 
+
20913  size_t ndraws = m_down->sample_agents(p, m_down->sampled_agents);
+
20914 
+
20915  if (ndraws == 0u)
+
20916  return;
+
20917 
+
20918 
+
20919  // Drawing from the set
+
20920  int nviruses_tmp = 0;
+
20921  for (size_t n = 0u; n < ndraws; ++n)
+
20922  {
+
20923 
+
20924  auto & neighbor = m_down->sampled_agents[n];
+
20925 
+
20926  auto & v = neighbor->get_virus();
+
20927 
+
20928  #ifdef EPI_DEBUG
+
20929  if (nviruses_tmp >= static_cast<int>(m->array_virus_tmp.size()))
+
20930  throw std::logic_error("Trying to add an extra element to a temporal array outside of the range.");
+
20931  #endif
+
20932 
+
20933  /* And it is a function of susceptibility_reduction as well */
+
20934  m->array_double_tmp[nviruses_tmp] =
+
20935  (1.0 - p->get_susceptibility_reduction(v, m)) *
+
20936  v->get_prob_infecting(m) *
+
20937  (1.0 - neighbor->get_transmission_reduction(v, m))
+
20938  ;
+
20939 
+
20940  m->array_virus_tmp[nviruses_tmp++] = &(*v);
+
20941 
+
20942  }
20943 
-
20944  // Recover
-
20945  m->array_double_tmp[n_events++] =
-
20946  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
-
20947 
-
20948  #ifdef EPI_DEBUG
-
20949  if (n_events == 0u)
-
20950  {
-
20951  printf_epiworld(
-
20952  "[epi-debug] agent %i has 0 possible events!!\n",
-
20953  static_cast<int>(p->get_id())
-
20954  );
-
20955  throw std::logic_error("Zero events in infected.");
-
20956  }
-
20957  #else
-
20958  if (n_events == 0u)
-
20959  return;
-
20960  #endif
-
20961 
-
20962 
-
20963  // Running the roulette
-
20964  int which = roulette(n_events, m);
+
20944  // Running the roulette
+
20945  int which = roulette(nviruses_tmp, m);
+
20946 
+
20947  if (which < 0)
+
20948  return;
+
20949 
+
20950  p->set_virus(
+
20951  *m->array_virus_tmp[which],
+
20952  m,
+ +
20954  );
+
20955 
+
20956  return;
+
20957 
+
20958  };
+
20959 
+
20960  epiworld::UpdateFun<TSeq> update_infected = [](
+ +
20962  ) -> void {
+
20963 
+
20964  auto state = p->get_state();
20965 
-
20966  if (which < 0)
-
20967  return;
+
20966  if (state == ModelSIRMixing<TSeq>::INFECTED)
+
20967  {
20968 
-
20969  // Which roulette happen?
-
20970  p->rm_virus(m);
-
20971 
-
20972  return ;
+
20969 
+
20970  // Odd: Die, Even: Recover
+
20971  epiworld_fast_uint n_events = 0u;
+
20972  const auto & v = p->get_virus();
20973 
-
20974  } else
-
20975  throw std::logic_error("This function can only be applied to infected individuals. (SIR)") ;
-
20976 
-
20977  return;
-
20978 
-
20979  };
-
20980 
-
20981  // Setting up parameters
-
20982  model.add_param(contact_rate, "Contact rate");
-
20983  model.add_param(transmission_rate, "Prob. Transmission");
-
20984  model.add_param(recovery_rate, "Prob. Recovery");
-
20985 
-
20986  // state
-
20987  model.add_state("Susceptible", update_susceptible);
-
20988  model.add_state("Infected", update_infected);
-
20989  model.add_state("Recovered");
-
20990 
-
20991  // Global function
-
20992  epiworld::GlobalFun<TSeq> update = [](epiworld::Model<TSeq> * m) -> void
-
20993  {
-
20994 
-
20995  ModelSIRMixing<TSeq> * m_down =
-
20996  dynamic_cast<ModelSIRMixing<TSeq> *>(m);
-
20997 
-
20998  m_down->update_infected_list();
-
20999 
-
21000  return;
+
20974  // Recover
+
20975  m->array_double_tmp[n_events++] =
+
20976  1.0 - (1.0 - v->get_prob_recovery(m)) * (1.0 - p->get_recovery_enhancer(v, m));
+
20977 
+
20978  #ifdef EPI_DEBUG
+
20979  if (n_events == 0u)
+
20980  {
+
20981  printf_epiworld(
+
20982  "[epi-debug] agent %i has 0 possible events!!\n",
+
20983  static_cast<int>(p->get_id())
+
20984  );
+
20985  throw std::logic_error("Zero events in infected.");
+
20986  }
+
20987  #else
+
20988  if (n_events == 0u)
+
20989  return;
+
20990  #endif
+
20991 
+
20992 
+
20993  // Running the roulette
+
20994  int which = roulette(n_events, m);
+
20995 
+
20996  if (which < 0)
+
20997  return;
+
20998 
+
20999  // Which roulette happen?
+
21000  p->rm_virus(m);
21001 
-
21002  };
+
21002  return ;
21003 
-
21004  model.add_globalevent(update, "Update infected individuals");
-
21005 
+
21004  } else
+
21005  throw std::logic_error("This function can only be applied to infected individuals. (SIR)") ;
21006 
-
21007  // Preparing the virus -------------------------------------------
-
21008  epiworld::Virus<TSeq> virus(vname, prevalence, true);
-
21009  virus.set_state(
- - - -
21013  );
-
21014 
-
21015  virus.set_prob_infecting(&model("Prob. Transmission"));
-
21016  virus.set_prob_recovery(&model("Prob. Recovery"));
-
21017 
-
21018  model.add_virus(virus);
-
21019 
-
21020  model.queuing_off(); // No queuing need
-
21021 
-
21022  // Adding the empty population
-
21023  model.agents_empty_graph(n);
+
21007  return;
+
21008 
+
21009  };
+
21010 
+
21011  // Setting up parameters
+
21012  model.add_param(contact_rate, "Contact rate");
+
21013  model.add_param(transmission_rate, "Prob. Transmission");
+
21014  model.add_param(recovery_rate, "Prob. Recovery");
+
21015 
+
21016  // state
+
21017  model.add_state("Susceptible", update_susceptible);
+
21018  model.add_state("Infected", update_infected);
+
21019  model.add_state("Recovered");
+
21020 
+
21021  // Global function
+
21022  epiworld::GlobalFun<TSeq> update = [](epiworld::Model<TSeq> * m) -> void
+
21023  {
21024 
-
21025  model.set_name("Susceptible-Infected-Removed (SIR) with Mixing");
-
21026 
-
21027  return;
-
21028 
-
21029 }
-
21030 
-
21031 template<typename TSeq>
- -
21033  const std::string & vname,
-
21034  epiworld_fast_uint n,
-
21035  epiworld_double prevalence,
-
21036  epiworld_double contact_rate,
-
21037  epiworld_double transmission_rate,
-
21038  epiworld_double recovery_rate,
-
21039  std::vector< double > contact_matrix
-
21040  )
-
21041 {
-
21042 
-
21043  this->contact_matrix = contact_matrix;
+
21025  ModelSIRMixing<TSeq> * m_down =
+
21026  dynamic_cast<ModelSIRMixing<TSeq> *>(m);
+
21027 
+
21028  m_down->update_infected_list();
+
21029 
+
21030  return;
+
21031 
+
21032  };
+
21033 
+
21034  model.add_globalevent(update, "Update infected individuals");
+
21035 
+
21036 
+
21037  // Preparing the virus -------------------------------------------
+
21038  epiworld::Virus<TSeq> virus(vname, prevalence, true);
+
21039  virus.set_state(
+ + + +
21043  );
21044 
- -
21046  *this,
-
21047  vname,
-
21048  n,
-
21049  prevalence,
-
21050  contact_rate,
-
21051  transmission_rate,
-
21052  recovery_rate,
-
21053  contact_matrix
-
21054  );
-
21055 
-
21056  return;
-
21057 
-
21058 }
-
21059 
-
21060 template<typename TSeq>
- -
21062  std::vector< double > proportions_,
-
21063  std::vector< int > /* queue_ */
-
21064 )
-
21065 {
-
21066 
- -
21068  create_init_function_sir<TSeq>(proportions_)
-
21069  ;
-
21070 
-
21071  return *this;
+
21045  virus.set_prob_infecting(&model("Prob. Transmission"));
+
21046  virus.set_prob_recovery(&model("Prob. Recovery"));
+
21047 
+
21048  model.add_virus(virus);
+
21049 
+
21050  model.queuing_off(); // No queuing need
+
21051 
+
21052  // Adding the empty population
+
21053  model.agents_empty_graph(n);
+
21054 
+
21055  model.set_name("Susceptible-Infected-Removed (SIR) with Mixing");
+
21056 
+
21057  return;
+
21058 
+
21059 }
+
21060 
+
21061 template<typename TSeq>
+ +
21063  const std::string & vname,
+
21064  epiworld_fast_uint n,
+
21065  epiworld_double prevalence,
+
21066  epiworld_double contact_rate,
+
21067  epiworld_double transmission_rate,
+
21068  epiworld_double recovery_rate,
+
21069  std::vector< double > contact_matrix
+
21070  )
+
21071 {
21072 
-
21073 }
+
21073  this->contact_matrix = contact_matrix;
21074 
-
21075 #endif
-
21076 /*//////////////////////////////////////////////////////////////////////////////
-
21078 
-
21079  End of -include/epiworld//models/sirmixing.hpp-
-
21080 
-
21083 
-
21084 
-
21085 
-
21086 
-
21087 }
-
21088 
-
21089 #endif
-
21090 /*//////////////////////////////////////////////////////////////////////////////
-
21092 
-
21093  End of -include/epiworld/models/models.hpp-
-
21094 
-
21097 
-
21098 
-
21099 
-
21100 }
-
21101 
-
21102 #endif
+ +
21076  *this,
+
21077  vname,
+
21078  n,
+
21079  prevalence,
+
21080  contact_rate,
+
21081  transmission_rate,
+
21082  recovery_rate,
+
21083  contact_matrix
+
21084  );
+
21085 
+
21086  return;
+
21087 
+
21088 }
+
21089 
+
21090 template<typename TSeq>
+ +
21092  std::vector< double > proportions_,
+
21093  std::vector< int > /* queue_ */
+
21094 )
+
21095 {
+
21096 
+ +
21098  create_init_function_sir<TSeq>(proportions_)
+
21099  ;
+
21100 
+
21101  return *this;
+
21102 
+
21103 }
+
21104 
+
21105 #endif
+
21106 /*//////////////////////////////////////////////////////////////////////////////
+
21108 
+
21109  End of -include/epiworld//models/sirmixing.hpp-
+
21110 
+
21113 
+
21114 
+
21115 
+
21116 
+
21117 }
+
21118 
+
21119 #endif
+
21120 /*//////////////////////////////////////////////////////////////////////////////
+
21122 
+
21123  End of -include/epiworld/models/models.hpp-
+
21124 
+
21127 
+
21128 
+
21129 
+
21130 }
+
21131 
+
21132 #endif
Definition: adjlist-bones.hpp:4
size_t vcount() const
Number of vertices/nodes in the network.
Definition: adjlist-meat.hpp:203
void read_edgelist(std::string fn, int size, int skip=0, bool directed=true)
Read an edgelist.
Definition: adjlist-meat.hpp:92
@@ -19317,56 +19347,56 @@
Set of Tools (const) (useful for iterators)
Definition: tools-bones.hpp:117
Set of tools (useful for building iterators)
Definition: tools-bones.hpp:18
Virus.
Definition: virus-bones.hpp:24
-
Definition: epiworld.hpp:5019
-
Agent (agents)
Definition: epiworld.hpp:13643
-
int get_id() const
Id of the individual.
Definition: epiworld.hpp:14670
-
void rm_agent_by_virus(Model< TSeq > *model, epiworld_fast_int state_new=-99, epiworld_fast_int queue=-99)
Agent removed by virus.
Definition: epiworld.hpp:14619
-
Statistical data about the process.
Definition: epiworld.hpp:2890
-
Definition: epiworld.hpp:12218
-
Template for a Global Event.
Definition: epiworld.hpp:6052
-
Core class of epiworld.
Definition: epiworld.hpp:6296
-
std::vector< Agent< TSeq > > & get_agents()
Returns a reference to the vector of agents.
Definition: epiworld.hpp:7517
-
void load_agents_entities_ties(const std::vector< int > &agents_ids, const std::vector< int > &entities_ids)
Associate agents-entities from data.
Definition: epiworld.hpp:8030
-
void rm_globalevent(size_t i)
Remove a global action by index.
Definition: epiworld.hpp:9537
-
std::vector< Viruses_const< TSeq > > get_agents_viruses() const
Returns a const vector with the viruses of the agents.
Definition: epiworld.hpp:7539
-
void set_agents_data(double *data_, size_t ncols_)
Set the agents data object.
Definition: epiworld.hpp:9622
-
void queuing_on()
Activates the queuing system (default.)
Definition: epiworld.hpp:9562
-
bool is_queuing_on() const
Query if the queuing system is on.
Definition: epiworld.hpp:9575
-
void run_multiple(epiworld_fast_uint ndays, epiworld_fast_uint nexperiments, int seed_=-1, std::function< void(size_t, Model< TSeq > *)> fun=make_save_run< TSeq >(), bool reset=true, bool verbose=true, int nthreads=1)
Definition: epiworld.hpp:8334
-
Queue< TSeq > & get_queue()
Retrieve the Queue object.
Definition: epiworld.hpp:9581
-
void set_name(std::string name)
Set the name object.
Definition: epiworld.hpp:9640
-
void load_agents_entities_ties(std::string fn, int skip)
Associate agents-entities from a file.
Definition: epiworld.hpp:7972
-
size_t get_n_tools() const
Number of tools in the model.
Definition: epiworld.hpp:8603
-
void add_globalevent(std::function< void(Model< TSeq > *)> fun, std::string name="A global action", int date=-99)
Set a global action.
Definition: epiworld.hpp:9463
-
void write_data(std::string fn_virus_info, std::string fn_virus_hist, std::string fn_tool_info, std::string fn_tool_hist, std::string fn_total_hist, std::string fn_transmission, std::string fn_transition, std::string fn_reproductive_number, std::string fn_generation_time) const
Wrapper of DataBase::write_data
Definition: epiworld.hpp:8674
-
void events_run()
Executes the stored action.
Definition: epiworld.hpp:7151
-
Model< TSeq > & queuing_off()
Deactivates the queuing system.
Definition: epiworld.hpp:9568
-
virtual void reset()
Reset the model.
Definition: epiworld.hpp:8778
-
std::vector< epiworld_fast_uint > get_agents_states() const
Returns a vector with the states of the agents.
Definition: epiworld.hpp:7529
-
GlobalEvent< TSeq > & get_globalevent(size_t i)
Retrieve a global action by index.
Definition: epiworld.hpp:9503
-
int today() const
The current time of the model.
Definition: epiworld.hpp:8200
-
virtual Model< TSeq > & run(epiworld_fast_uint ndays, int seed=-1)
Runs the simulation (after initialization)
Definition: epiworld.hpp:8222
-
size_t get_n_viruses() const
Number of viruses in the model.
Definition: epiworld.hpp:8598
-
void rm_globalevent(std::string name)
Remove a global action by name.
Definition: epiworld.hpp:9517
-
std::vector< Viruses< TSeq > > get_agents_viruses()
Returns a vector with the viruses of the agents.
Definition: epiworld.hpp:7552
-
void set_user_data(std::vector< std::string > names)
[@
Definition: epiworld.hpp:9439
-
GlobalEvent< TSeq > & get_globalevent(std::string name)
Retrieve a global action by name.
Definition: epiworld.hpp:9489
-
void events_add(Agent< TSeq > *agent_, VirusPtr< TSeq > virus_, ToolPtr< TSeq > tool_, Entity< TSeq > *entity_, epiworld_fast_int new_state_, epiworld_fast_int queue_, EventFun< TSeq > call_, int idx_agent_, int idx_object_)
Construct a new Event object.
Definition: epiworld.hpp:7100
-
virtual Model< TSeq > * clone_ptr()
Advanced usage: Makes a copy of data and returns it as undeleted pointer.
Definition: epiworld.hpp:7301
+
Definition: epiworld.hpp:5049
+
Agent (agents)
Definition: epiworld.hpp:13673
+
int get_id() const
Id of the individual.
Definition: epiworld.hpp:14700
+
void rm_agent_by_virus(Model< TSeq > *model, epiworld_fast_int state_new=-99, epiworld_fast_int queue=-99)
Agent removed by virus.
Definition: epiworld.hpp:14649
+
Statistical data about the process.
Definition: epiworld.hpp:2920
+
Definition: epiworld.hpp:12248
+
Template for a Global Event.
Definition: epiworld.hpp:6082
+
Core class of epiworld.
Definition: epiworld.hpp:6326
+
std::vector< Agent< TSeq > > & get_agents()
Returns a reference to the vector of agents.
Definition: epiworld.hpp:7547
+
void load_agents_entities_ties(const std::vector< int > &agents_ids, const std::vector< int > &entities_ids)
Associate agents-entities from data.
Definition: epiworld.hpp:8060
+
void rm_globalevent(size_t i)
Remove a global action by index.
Definition: epiworld.hpp:9567
+
std::vector< Viruses_const< TSeq > > get_agents_viruses() const
Returns a const vector with the viruses of the agents.
Definition: epiworld.hpp:7569
+
void set_agents_data(double *data_, size_t ncols_)
Set the agents data object.
Definition: epiworld.hpp:9652
+
void queuing_on()
Activates the queuing system (default.)
Definition: epiworld.hpp:9592
+
bool is_queuing_on() const
Query if the queuing system is on.
Definition: epiworld.hpp:9605
+
void run_multiple(epiworld_fast_uint ndays, epiworld_fast_uint nexperiments, int seed_=-1, std::function< void(size_t, Model< TSeq > *)> fun=make_save_run< TSeq >(), bool reset=true, bool verbose=true, int nthreads=1)
Definition: epiworld.hpp:8364
+
Queue< TSeq > & get_queue()
Retrieve the Queue object.
Definition: epiworld.hpp:9611
+
void set_name(std::string name)
Set the name object.
Definition: epiworld.hpp:9670
+
void load_agents_entities_ties(std::string fn, int skip)
Associate agents-entities from a file.
Definition: epiworld.hpp:8002
+
size_t get_n_tools() const
Number of tools in the model.
Definition: epiworld.hpp:8633
+
void add_globalevent(std::function< void(Model< TSeq > *)> fun, std::string name="A global action", int date=-99)
Set a global action.
Definition: epiworld.hpp:9493
+
void write_data(std::string fn_virus_info, std::string fn_virus_hist, std::string fn_tool_info, std::string fn_tool_hist, std::string fn_total_hist, std::string fn_transmission, std::string fn_transition, std::string fn_reproductive_number, std::string fn_generation_time) const
Wrapper of DataBase::write_data
Definition: epiworld.hpp:8704
+
void events_run()
Executes the stored action.
Definition: epiworld.hpp:7181
+
Model< TSeq > & queuing_off()
Deactivates the queuing system.
Definition: epiworld.hpp:9598
+
virtual void reset()
Reset the model.
Definition: epiworld.hpp:8808
+
std::vector< epiworld_fast_uint > get_agents_states() const
Returns a vector with the states of the agents.
Definition: epiworld.hpp:7559
+
GlobalEvent< TSeq > & get_globalevent(size_t i)
Retrieve a global action by index.
Definition: epiworld.hpp:9533
+
int today() const
The current time of the model.
Definition: epiworld.hpp:8230
+
virtual Model< TSeq > & run(epiworld_fast_uint ndays, int seed=-1)
Runs the simulation (after initialization)
Definition: epiworld.hpp:8252
+
size_t get_n_viruses() const
Number of viruses in the model.
Definition: epiworld.hpp:8628
+
void rm_globalevent(std::string name)
Remove a global action by name.
Definition: epiworld.hpp:9547
+
std::vector< Viruses< TSeq > > get_agents_viruses()
Returns a vector with the viruses of the agents.
Definition: epiworld.hpp:7582
+
void set_user_data(std::vector< std::string > names)
[@
Definition: epiworld.hpp:9469
+
GlobalEvent< TSeq > & get_globalevent(std::string name)
Retrieve a global action by name.
Definition: epiworld.hpp:9519
+
void events_add(Agent< TSeq > *agent_, VirusPtr< TSeq > virus_, ToolPtr< TSeq > tool_, Entity< TSeq > *entity_, epiworld_fast_int new_state_, epiworld_fast_int queue_, EventFun< TSeq > call_, int idx_agent_, int idx_object_)
Construct a new Event object.
Definition: epiworld.hpp:7130
+
virtual Model< TSeq > * clone_ptr()
Advanced usage: Makes a copy of data and returns it as undeleted pointer.
Definition: epiworld.hpp:7331
A simple progress bar.
Definition: epiworld.hpp:765
-
Controls which agents are verified at each step.
Definition: epiworld.hpp:5912
-
Tools for defending the agent against the virus.
Definition: epiworld.hpp:11409
-
Personalized data by the user.
Definition: epiworld.hpp:2406
-
Virus.
Definition: epiworld.hpp:10105
-
Definition: epiworld.hpp:17665
-
Definition: epiworld.hpp:19012
-
Definition: epiworld.hpp:20047
-
Definition: epiworld.hpp:17224
-
Definition: epiworld.hpp:18655
-
Template for a Susceptible-Infected-Removed (SIR) model.
Definition: epiworld.hpp:19471
-
Definition: epiworld.hpp:20589
-
Virus< TSeq > * sample_virus_single(Agent< TSeq > *p, Model< TSeq > *m)
Sample from neighbors pool of viruses (at most one)
Definition: epiworld.hpp:13409
-
std::function< Virus< TSeq > *(Agent< TSeq > *, Model< TSeq > *)> make_sample_virus_neighbors(std::vector< epiworld_fast_uint > exclude={})
Make a function to sample from neighbors.
Definition: epiworld.hpp:13241
+
Controls which agents are verified at each step.
Definition: epiworld.hpp:5942
+
Tools for defending the agent against the virus.
Definition: epiworld.hpp:11439
+
Personalized data by the user.
Definition: epiworld.hpp:2436
+
Virus.
Definition: epiworld.hpp:10135
+
Definition: epiworld.hpp:17695
+
Definition: epiworld.hpp:19042
+
Definition: epiworld.hpp:20077
+
Definition: epiworld.hpp:17254
+
Definition: epiworld.hpp:18685
+
Template for a Susceptible-Infected-Removed (SIR) model.
Definition: epiworld.hpp:19501
+
Definition: epiworld.hpp:20619
+
Virus< TSeq > * sample_virus_single(Agent< TSeq > *p, Model< TSeq > *m)
Sample from neighbors pool of viruses (at most one)
Definition: epiworld.hpp:13439
+
std::function< Virus< TSeq > *(Agent< TSeq > *, Model< TSeq > *)> make_sample_virus_neighbors(std::vector< epiworld_fast_uint > exclude={})
Make a function to sample from neighbors.
Definition: epiworld.hpp:13271
Functions for sampling viruses.
Definition: agent-meat-virus-sampling.hpp:8
diff --git a/include_2epiworld_2epiworld_8hpp_source.html b/include_2epiworld_2epiworld_8hpp_source.html index 88a64f881..5c50d572e 100644 --- a/include_2epiworld_2epiworld_8hpp_source.html +++ b/include_2epiworld_2epiworld_8hpp_source.html @@ -90,8 +90,8 @@
18 
19 /* Versioning */
20 #define EPIWORLD_VERSION_MAJOR 0
-
21 #define EPIWORLD_VERSION_MINOR 4
-
22 #define EPIWORLD_VERSION_PATCH 3
+
21 #define EPIWORLD_VERSION_MINOR 5
+
22 #define EPIWORLD_VERSION_PATCH 0
23 
24 static const int epiworld_version_major = EPIWORLD_VERSION_MAJOR;
25 static const int epiworld_version_minor = EPIWORLD_VERSION_MINOR;
diff --git a/init-functions_8hpp_source.html b/init-functions_8hpp_source.html index d57ec2c24..5ef9349c1 100644 --- a/init-functions_8hpp_source.html +++ b/init-functions_8hpp_source.html @@ -385,8 +385,8 @@
329 
330 #endif
Controls which agents are verified at each step.
Definition: queue-bones.hpp:16
-
Sample of agents.
Definition: epiworld.hpp:15221
-
Core class of epiworld.
Definition: epiworld.hpp:6296
+
Sample of agents.
Definition: epiworld.hpp:15251
+
Core class of epiworld.
Definition: epiworld.hpp:6326