Commit 6ea36ec4 authored by Tiago Peixoto's avatar Tiago Peixoto

Dynamics submodule implementation

This adds the "dynamics" submodule, with implementation of several
dynamical processes.
parent 2b749c41
......@@ -393,6 +393,7 @@ src/graph/centrality/Makefile
src/graph/clustering/Makefile
src/graph/correlations/Makefile
src/graph/draw/Makefile
src/graph/dynamics/Makefile
src/graph/flow/Makefile
src/graph/generation/Makefile
src/graph/inference/Makefile
......
.. automodule:: graph_tool.dynamics
:members:
:undoc-members:
:show-inheritance:
......@@ -256,6 +256,7 @@ Available subpackages
clustering
collection
correlations
dynamics
draw
flow
generation
......
## Process this file with automake to produce Makefile.in
SUBDIRS = centrality clustering correlations draw flow generation inference layout search spectral stats topology util
SUBDIRS = centrality clustering correlations draw dynamics flow generation inference layout search spectral stats topology util
AM_CPPFLAGS = $(MOD_CPPFLAGS)
......
## Process this file with automake to produce Makefile.in
AM_CPPFLAGS = $(MOD_CPPFLAGS)
AM_CFLAGS = $(AM_CXXFLAGS)
libgraph_tool_dynamicsdir = $(MOD_DIR)/dynamics
libgraph_tool_dynamics_LTLIBRARIES = libgraph_tool_dynamics.la
libgraph_tool_dynamics_la_includedir = $(MOD_DIR)/include/dynamics
libgraph_tool_dynamics_la_LIBADD = $(MOD_LIBADD)
libgraph_tool_dynamics_la_LDFLAGS = $(MOD_LDFLAGS)
libgraph_tool_dynamics_la_SOURCES = \
graph_continuous.cc \
graph_discrete.cc \
graph_dynamics.cc
libgraph_tool_dynamics_la_include_HEADERS = \
graph_continuous.hh \
graph_discrete.hh
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <boost/python.hpp>
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_util.hh"
#include "numpy_bind.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include "graph_continuous.hh"
#include "random.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
template <class Graph, class State>
class WrappedCState
{
public:
typedef typename State::smap_t smap_t;
WrappedCState(Graph& g, smap_t s, smap_t s_diff,
python::dict params, rng_t& rng)
: _state(g, s, s_diff, params, rng), _g(g)
{
}
void get_diff_sync(double t, double dt, rng_t& rng)
{
graph_tool::get_diff_sync(_g, _state, t, dt, rng);
}
static void python_export()
{
python::class_<WrappedCState<Graph,State>>
(name_demangle(typeid(WrappedCState<Graph,State>).name()).c_str(),
python::init<Graph&, smap_t, smap_t, python::dict, rng_t&>())
.def("get_diff_sync", &WrappedCState<Graph,State>::get_diff_sync);
}
private:
State _state;
Graph& _g;
};
template <class State>
python::object make_state(GraphInterface& gi, boost::any as, boost::any as_diff,
python::dict params, rng_t& rng)
{
typedef typename State::smap_t::checked_t smap_t;
smap_t s = boost::any_cast<smap_t>(as);
smap_t s_diff = boost::any_cast<smap_t>(as_diff);
python::object state;
run_action<>()
(gi,
[&](auto& g)
{
typedef typename std::remove_reference<decltype(g)>::type g_t;
state =
python::object(WrappedCState<g_t,State>
(g, s.get_unchecked(num_vertices(g)),
s_diff.get_unchecked(num_vertices(g)), params,
rng));
})();
return state;
}
struct add_ptr
{
template <class T>
struct apply
{
typedef typename std::add_pointer<T>::type type;
};
};
template <class State>
void export_cstate()
{
mpl::for_each<all_graph_views, add_ptr>
([](auto g)
{
typedef typename std::remove_pointer<decltype(g)>::type g_t;
WrappedCState<g_t,State>::python_export();
});
}
void export_continuous()
{
export_cstate<kuramoto_state>();
def("make_kuramoto_state", &make_state<kuramoto_state>);
}
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef GRAPH_CONTINUOUS_HH
#define GRAPH_CONTINUOUS_HH
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_util.hh"
#ifdef _OPENMP
#include <omp.h>
#endif
#include "random.hh"
#include "parallel_rng.hh"
#include "../generation/sampler.hh"
#include "idx_map.hh"
namespace graph_tool
{
using namespace boost;
template <class Value = double>
class continuous_state_base
{
public:
typedef Value s_t;
typedef typename vprop_map_t<s_t>::type::unchecked_t smap_t;
continuous_state_base(smap_t s, smap_t s_diff)
: _s(s), _s_diff(s_diff) {}
template <class Graph, class RNG>
double get_node_diff(Graph&, size_t, RNG&) { return 0.; }
smap_t _s;
smap_t _s_diff;
};
class kuramoto_state: public continuous_state_base<>
{
public:
typedef vprop_map_t<double>::type::unchecked_t omap_t;
typedef eprop_map_t<double>::type::unchecked_t wmap_t;
template <class Graph, class RNG>
kuramoto_state(Graph&, smap_t s, smap_t s_diff, python::dict params, RNG&)
: continuous_state_base(s, s_diff),
_omega(any_cast<omap_t::checked_t>(python::extract<any>(params["omega"].attr("_get_any")())()).get_unchecked()),
_w(any_cast<wmap_t::checked_t>(python::extract<any>(params["w"].attr("_get_any")())()).get_unchecked()),
_sigma(python::extract<double>(params["sigma"])) {};
template <class Graph, class RNG>
double get_node_diff(Graph& g, size_t v, double, double dt, RNG& rng)
{
double diff = _omega[v];
auto sv = _s[v];
for (auto e : in_or_out_edges_range(v, g))
{
auto u = source(e, g);
diff += _w[e] * std::sin(_s[u] - sv);
}
if (_sigma > 0)
{
std::normal_distribution<> noise(0, sqrt(dt));
diff += _sigma * noise(rng);
}
return diff;
}
private:
omap_t _omega;
wmap_t _w;
double _sigma;
};
template <class Graph, class State, class RNG>
void get_diff_sync(Graph& g, State state, double t, double dt, RNG& rng_)
{
parallel_rng<rng_t>::init(rng_);
parallel_vertex_loop
(g,
[&] (auto v)
{
auto& rng = parallel_rng<rng_t>::get(rng_);
state._s_diff[v] = state.get_node_diff(g, v, t, dt, rng);
});
}
} // namespace graph_tool
#endif // GRAPH_CONTINUOUS_HH
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <boost/python.hpp>
#include "graph.hh"
#include "graph_filtering.hh"
#include "graph_util.hh"
#include "numpy_bind.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"
#include "graph_discrete.hh"
#include "random.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
template <class Graph, class State>
class WrappedState
{
public:
typedef typename State::smap_t smap_t;
WrappedState(Graph& g, smap_t s, smap_t s_temp,
python::dict params, rng_t& rng)
: _state(g, s, s_temp, params, rng), _g(g)
{
}
void reset_active(rng_t& rng)
{
auto& active = *_state._active;
active.clear();
for (auto v : vertices_range(_g))
{
if (_state.is_absorbing(_g, v))
continue;
active.push_back(v);
}
std::shuffle(active.begin(), active.end(), rng);
}
python::object get_active()
{
return wrap_vector_not_owned(*_state._active);
}
size_t iterate_sync(size_t niter, rng_t& rng)
{
return discrete_iter_sync(_g, _state, niter, rng);
}
size_t iterate_async(size_t niter, rng_t& rng)
{
return discrete_iter_async(_g, _state, niter, rng);
}
static void python_export()
{
python::class_<WrappedState<Graph,State>>
(name_demangle(typeid(WrappedState<Graph,State>).name()).c_str(),
python::init<Graph&, smap_t, smap_t, python::dict, rng_t&>())
.def("reset_active", &WrappedState<Graph,State>::reset_active)
.def("get_active", &WrappedState<Graph,State>::get_active)
.def("iterate_sync", &WrappedState<Graph,State>::iterate_sync)
.def("iterate_async", &WrappedState<Graph,State>::iterate_async);
}
private:
State _state;
Graph& _g;
};
template <class State>
python::object make_state(GraphInterface& gi, boost::any as, boost::any as_temp,
python::dict params, rng_t& rng)
{
typedef typename State::smap_t::checked_t smap_t;
smap_t s = boost::any_cast<smap_t>(as);
smap_t s_temp = boost::any_cast<smap_t>(as_temp);
python::object state;
run_action<>()
(gi,
[&](auto& g)
{
typedef typename std::remove_reference<decltype(g)>::type g_t;
state =
python::object(WrappedState<g_t,State>
(g, s.get_unchecked(num_vertices(g)),
s_temp.get_unchecked(num_vertices(g)), params,
rng));
})();
return state;
}
struct add_ptr
{
template <class T>
struct apply
{
typedef typename std::add_pointer<T>::type type;
};
};
template <class State>
void export_state()
{
mpl::for_each<all_graph_views, add_ptr>
([](auto g)
{
typedef typename std::remove_pointer<decltype(g)>::type g_t;
WrappedState<g_t,State>::python_export();
});
}
void export_discrete()
{
export_state<SI_state<false>>();
def("make_SI_state", &make_state<SI_state<false>>);
export_state<SIS_state<false,false>>();
def("make_SIS_state", &make_state<SIS_state<false,false>>);
export_state<SIS_state<false,true>>();
def("make_SIR_state", &make_state<SIS_state<false,true>>);
export_state<SIRS_state<false>>();
def("make_SIRS_state", &make_state<SIRS_state<false>>);
export_state<SI_state<true>>();
def("make_SEI_state", &make_state<SI_state<true>>);
export_state<SIS_state<true,false>>();
def("make_SEIS_state", &make_state<SIS_state<true,false>>);
export_state<SIS_state<true,true>>();
def("make_SEIR_state", &make_state<SIS_state<true,true>>);
export_state<SIRS_state<true>>();
def("make_SEIRS_state", &make_state<SIRS_state<true>>);
export_state<voter_state>();
def("make_voter_state", &make_state<voter_state>);
export_state<majority_voter_state>();
def("make_majority_voter_state", &make_state<majority_voter_state>);
export_state<binary_threshold_state>();
def("make_binary_threshold_state", &make_state<binary_threshold_state>);
export_state<ising_glauber_state>();
def("make_ising_glauber_state", &make_state<ising_glauber_state>);
export_state<cising_glauber_state>();
def("make_cising_glauber_state", &make_state<cising_glauber_state>);
export_state<ising_metropolis_state>();
def("make_ising_metropolis_state", &make_state<ising_metropolis_state>);
export_state<potts_glauber_state>();
def("make_potts_glauber_state", &make_state<potts_glauber_state>);
export_state<potts_metropolis_state>();
def("make_potts_metropolis_state", &make_state<potts_metropolis_state>);
export_state<axelrod_state>();
def("make_axelrod_state", &make_state<axelrod_state>);
export_state<boolean_state>();
def("make_boolean_state", &make_state<boolean_state>);
export_state<kirman_state>();
def("make_kirman_state", &make_state<kirman_state>);
}
This diff is collapsed.
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <boost/python.hpp>
#include "graph.hh"
using namespace std;
using namespace boost;
using namespace graph_tool;
extern void export_continuous();
extern void export_discrete();
BOOST_PYTHON_MODULE(libgraph_tool_dynamics)
{
export_continuous();
export_discrete();
}
......@@ -94,6 +94,10 @@ graph_tool_spectral_PYTHON = \
spectral/__init__.py
graph_tool_spectraldir = $(MOD_DIR)/spectral
graph_tool_dynamics_PYTHON = \
dynamics/__init__.py
graph_tool_dynamicsdir = $(MOD_DIR)/dynamics
graph_tool_search_PYTHON = \
search/__init__.py
graph_tool_searchdir = $(MOD_DIR)/search
......
......@@ -39,6 +39,8 @@ except ImportError as e:
msg = "Error importing draw module, proceeding nevertheless: " + str(e)
warnings.warn(msg, RuntimeWarning)
pass
from graph_tool.dynamics import *
import graph_tool.dynamics
from graph_tool.stats import *
import graph_tool.stats
from graph_tool.generation import *
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment