Skip to content

Commit

Permalink
added and test markov SIS on model
Browse files Browse the repository at this point in the history
  • Loading branch information
benmaier committed Dec 19, 2018
1 parent ef6d572 commit 7c3b753
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 32 deletions.
11 changes: 6 additions & 5 deletions _tacoma/Markov_SIS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ void MARKOV_SIS::step(
double P_INF = dt * infection_rate;
double P_REC = dt * recovery_rate;

//cout << "P_INF = " << P_INF << endl;
//cout << "P_REC = " << P_REC << endl;


current_I = 0.0;
for(auto const &neighbors: *G)
{
Expand All @@ -85,6 +81,11 @@ void MARKOV_SIS::step(
+ _p * (1 - P_REC);

//cout << "node_status : " << stat << endl;
if (this_new_p < 0.0)
this_new_p = 0.0;
else if (this_new_p > 1.0)
this_new_p = 1.0;

}

new_p->push_back(this_new_p);
Expand All @@ -110,7 +111,7 @@ void MARKOV_SIS::update_observables(
{
if (sampling_dt > 0.0)
{
if ((t >= next_sampling_time) and (time.back()!=t))
if ((t >= next_sampling_time))
{
double _R0 = infection_rate * mean_degree / recovery_rate;
R0.push_back(_R0);
Expand Down
11 changes: 10 additions & 1 deletion _tacoma/_tacoma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "eSIS.h"
#include "Markov_SIS.h"
#include "markov_dynamics.h"
#include "model_markov.h"
#include "SIS_node_based.h"
#include "SIR.h"
#include "SI.h"
Expand Down Expand Up @@ -795,7 +796,7 @@ PYBIND11_MODULE(_tacoma, m)
py::arg("verbose") = false);

m.def("gillespie_SI_on_EdgeActivityModel", &gillespie_on_model<EdgeActivityModel,SI>,
"Perform a Gillespie SIRS simulation on the edge activity model.",
"Perform a Gillespie SI simulation on the edge activity model.",
py::arg("activity_model"),
py::arg("SI"),
py::arg("reset_simulation_objects") = true,
Expand All @@ -808,6 +809,14 @@ PYBIND11_MODULE(_tacoma, m)
py::arg("reset_simulation_objects") = true,
py::arg("verbose") = false);

m.def("markov_SIS_on_EdgeActivityModel", &markov_on_model<EdgeActivityModel,MARKOV_SIS>,
"Perform a mixed Markov-Gillespie SIS simulation on the edge activity model.",
py::arg("activity_model"),
py::arg("MARKOV_SIS"),
py::arg("max_dt"),
py::arg("reset_simulation_objects") = true,
py::arg("verbose") = false);


py::class_<edge_changes>(m, "edge_changes", R"pbdoc(Description of a temporal network by listing the changes of edges at a certain time.)pbdoc")
.def(py::init<>())
Expand Down
28 changes: 2 additions & 26 deletions _tacoma/markov_dynamics.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ void
// reset the simulation object
this_markov_object.reset();

// deal with random numbers
mt19937_64 &generator = this_markov_object.generator;
exponential_distribution<double> randexp(1.0);
uniform_real_distribution<double> randuni(0.0,1.0);

// initialize time variables
double t0 = edg_lst.t[0];
double tmax = edg_lst.tmax;
Expand All @@ -83,18 +78,11 @@ void
size_t N = edg_lst.N;
vector < set < size_t > > G(N);

// inititalize rate containers
vector < double > rates;
double Lambda;

// create iterators
auto next_edges = (edg_lst.edges).end();
auto next_time = (edg_lst.t).end();
long loop_count = -1;

// draw time to first event
double tau = randexp(generator);

if (verbose)
{
cout << "initialized simulation with t-t0 = " << t-t0 << endl;
Expand Down Expand Up @@ -194,8 +182,8 @@ void
if ((t-t0+dt_to_next_change < t_simulation) and (not this_markov_object.simulation_ended()))
{
this_markov_object.step(t, dt_to_next_change);
t += dt_to_next_change;
}
t += dt_to_next_change;

if (verbose)
{
Expand Down Expand Up @@ -224,11 +212,6 @@ void
// reset the simulation object
this_markov_object.reset();

// deal with random numbers
mt19937_64 &generator = this_markov_object.generator;
exponential_distribution<double> randexp(1.0);
uniform_real_distribution<double> randuni(0.0,1.0);

// initialize time variables
double t0 = edg_chg.t0;
double tmax = edg_chg.tmax;
Expand All @@ -244,19 +227,12 @@ void
size_t N = edg_chg.N;
vector < set < size_t > > G(N);

// inititalize rate containers
vector < double > rates;
double Lambda;

// create iterators
auto next_edges_in = (edg_chg.edges_in).end();
auto next_edges_out = (edg_chg.edges_out).end();
auto next_time = (edg_chg.t).end();
long loop_count = -1;

// draw time to first event
double tau = randexp(generator);

while ( (t-t0 < t_simulation) and (not this_markov_object.simulation_ended()) )
{

Expand Down Expand Up @@ -376,8 +352,8 @@ void
if ((t-t0+dt_to_next_change < t_simulation) and (not this_markov_object.simulation_ended()))
{
this_markov_object.step(t, dt_to_next_change);
t += dt_to_next_change;
}
t += dt_to_next_change;
}
}

Expand Down
165 changes: 165 additions & 0 deletions _tacoma/model_markov.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* The MIT License (MIT)
* Copyright (c) 2018, Benjamin Maier
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall
* be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
* INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#ifndef __MODEL_MARKOV_H__
#define __MODEL_MARKOV_H__

#include "Utilities.h"

#include <iostream>
#include <algorithm>
#include <stdexcept>
#include <vector>
#include <set>
#include <utility>
#include <random>
#include <cmath>
#include <numeric>
#include <random>
#include <ctime>
#include <tuple>
#include <assert.h>

using namespace std;

template <typename T1, typename T2>
void
markov_on_model(
T1 & this_model_object,
T2 & this_markov_object,
double max_dt,
bool reset_simulation_objects = true,
bool verbose = false
)
{

if (this_model_object.N != this_markov_object.N)
throw domain_error("Both model and markov object need to have the same node number.");

if (verbose)
cout << "started markov integration on model." << endl;

// deal with random numbers
mt19937_64 &generator = this_markov_object.generator;
uniform_real_distribution<double> randuni(0.0,1.0);
this_model_object.set_generator(this_markov_object.generator);


// reset the simulation objects
if (reset_simulation_objects)
{
if (verbose)
cout << "Resetting models..." << endl;

this_markov_object.reset();
this_model_object.reset();

if (verbose)
cout << "Done." << endl;
}

// initialize time variables
double t0 = this_model_object.t0;
double t = t0;

double t_simulation = this_markov_object.t_simulation;
this_model_object.edg_chg.tmax = t_simulation;

// initialize a graph and pass it to the markov object
this_markov_object.update_network(this_model_object.G,t);

if (verbose)
cout << "Start integration" << endl;

while ( (t-t0 < t_simulation) and (not this_markov_object.simulation_ended()) )
{

// inititalize rate containers
vector < double > rates_model;
double Lambda_model;

// get the updated rates and lambda
this_model_object.get_rates_and_Lambda(rates_model,Lambda_model);

if (verbose)
{
cout << "Lambda_model = " << Lambda_model << endl;
for(auto const &rate: rates_model)
cout << " rate = " << rate << endl;
}

double rProduct = randuni(generator) * Lambda_model;

vector<double>::iterator this_rate;
size_t n_rates;

this_rate = rates_model.begin();
n_rates = rates_model.size();

double sum_event = 0.0;
size_t event = 0;

while ( (event < n_rates) and not ( (sum_event < rProduct) and (rProduct <= sum_event + (*this_rate)) ) )
{
sum_event += (*this_rate);
++this_rate;
++event;
}

if (verbose)
{
cout << "rProduct = " << rProduct << endl;
cout << "event = " << event << endl;
cout << "this_rate = " << *this_rate << endl;
}

double tau = log(1.0/randuni(generator)) / Lambda_model;

while ((tau > max_dt) and (t-t0+max_dt < t_simulation) and (not this_markov_object.simulation_ended()) )
{
this_markov_object.step(t,max_dt);
tau -= max_dt;
t += max_dt;
}

if ((t-t0+tau < t_simulation) and (not this_markov_object.simulation_ended()))
{
this_markov_object.step(t, tau);

vector < pair < size_t, size_t > > edges_in;
vector < pair < size_t, size_t > > edges_out;

this_model_object.make_event(event,t,edges_in,edges_out);
this_markov_object.update_network(this_model_object.G,t+tau);
}
t += tau;

if (verbose)
cout << "new time: " << t << " / " << t_simulation << endl;

}
}

#endif
84 changes: 84 additions & 0 deletions sandbox/test_model_markov_SIS.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import sys

import tacoma as tc
import matplotlib.pyplot as pl
import numpy as np

import _tacoma as _tc

N = 100

t_run_total = 10000/N
recovery_rate = 1.0

seed = 12

R0s = [0.5,1.0,1.2,1.5,2,4,6]

for k in range(1,8,3):
pl.figure()
pl.title('$k={0:d}$'.format(k))
for omega in np.logspace(-2,0,4,base=N):
pl.figure()
curve_1 = []
curve_2 = []
for R0 in R0s:

print(k, omega, R0)
AM = _tc.EdgeActivityModel(N,
k/(N-1.),
omega,
verbose = False,
)
infection_rate = R0 / k * recovery_rate


SIS = _tc.SIS(N,t_run_total,infection_rate,recovery_rate,
number_of_initially_infected=N,
verbose=False,
seed=seed,
sampling_dt=1,
)

_tc.gillespie_SIS_on_EdgeActivityModel(AM,SIS,verbose=False)

t = np.array(SIS.time)
I = np.array(SIS.I)

this_pl, = pl.plot(t,I,'s',ms=2,alpha=0.5,mfc='None')
mean_I_1 = tc.time_average(t, I, tmax=t_run_total)

AM = _tc.EdgeActivityModel(N,
k/(N-1.),
omega,
verbose =False,
)

print("generated new AM")

SIS = _tc.MARKOV_SIS(N,
t_run_total,
infection_rate,
recovery_rate,
minimum_I=0.01,
number_of_initially_infected=N,
sampling_dt=1)

print("starting integration")

_tc.markov_SIS_on_EdgeActivityModel(AM,SIS,max_dt=1.0,verbose=False)

t = np.array(SIS.time)
I = np.array(SIS.I)

mean_I_2 = tc.time_average(t, I, tmax=t_run_total)

curve_1.append(mean_I_1)
curve_2.append(mean_I_2)
this_pl, = pl.plot(t,I,'-',lw=1,alpha=0.5,c=this_pl.get_color())

#this_pl, = pl.plot(R0s,curve_1,'s',ms=2,alpha=0.5,mfc='None')
#this_pl, = pl.plot(R0s,curve_2,'-',lw=1,alpha=0.5,c=this_pl.get_color())

pl.show()

0 comments on commit 7c3b753

Please sign in to comment.