Skip to content

Commit

Permalink
major refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
benmaier committed Oct 22, 2019
1 parent 9b8c18d commit 0140f6b
Show file tree
Hide file tree
Showing 21 changed files with 1,055 additions and 766 deletions.
121 changes: 116 additions & 5 deletions _sixdegrees/Utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void add_random_subgraph(
size_t n,
double p,
vector < set < size_t > * > & G,
default_random_engine & generator,
mt19937_64 & generator,
uniform_real_distribution<double> & distribution,
size_t start_node
)
Expand Down Expand Up @@ -129,8 +129,8 @@ vector < set < size_t > * > get_components_from_edgelist(
return get_components(G);
}

// replace the graph in-place with the giant component
void get_giant_component(
// replace the graph in-place with the largest component
void get_largest_component(
vector < set < size_t > * > &G
)
{
Expand All @@ -148,7 +148,7 @@ void get_giant_component(
{
if ( components[max_comp]->find(node) == components[max_comp]->end() )
{
// if current node not in giant component, empty the neighbor set
// if current node not in largest component, empty the neighbor set
G[node]->clear();
}
}
Expand Down Expand Up @@ -222,7 +222,7 @@ vector < double > get_kleinberg_pmf(
}

void randomly_seed_engine(
default_random_engine &generator
mt19937_64 &generator
)
//taken from http://stackoverflow.com/a/29190957/4177832
{
Expand All @@ -234,3 +234,114 @@ void randomly_seed_engine(
seed_seq seed_value { time_seed, clock_seed, pid_seed };
generator.seed(seed_value);
}

size_t neighbor_set_to_coord_lists(
vector < set < size_t > * > &G,
vector < size_t > &rows,
vector < size_t > &cols,
bool use_largest_component,
bool delete_non_largest_component_nodes
)
{

size_t N = G.size();
rows.clear();
cols.clear();

size_t new_N = N;

if ( use_largest_component && delete_non_largest_component_nodes )
{
vector < size_t > map_to_new_ids(N);
size_t current_id = 0;
for(size_t u = 0; u < N; u++)
if (G[u]->size()>0)
{
map_to_new_ids[u] = current_id;
current_id++;
}

new_N = current_id;

for(size_t u = 0; u < N; u++)
{
for( auto const& v: *G[u] )
{
rows.push_back(map_to_new_ids[u]);
cols.push_back(map_to_new_ids[v]);
}
delete G[u];
}
}
else
{
for(size_t u = 0; u < N; u++)
{
for( auto const& v: *G[u] )
{
rows.push_back(u);
cols.push_back(v);
}
delete G[u];
}
}

return new_N;
}

size_t neighbor_set_to_edge_list(
vector < set < size_t > * > &G,
vector < pair < size_t, size_t > > &edge_list,
bool use_largest_component,
bool delete_non_largest_component_nodes
)
{
size_t N = G.size();
edge_list.clear();

size_t new_N = N;

if ( use_largest_component && delete_non_largest_component_nodes )
{
vector < size_t > map_to_new_ids(N);
size_t current_id = 0;
for(size_t u = 0; u < N; u++)
if (G[u]->size()>0)
{
map_to_new_ids[u] = current_id;
current_id++;
}

new_N = current_id;

for(size_t u = 0; u < N; u++)
{
size_t u_ = map_to_new_ids[u];
for( auto const& v: *G[u] )
{
size_t v_ = map_to_new_ids[v];
if (u_<v_)
{
edge_list.push_back( make_pair( u_, v_ ) );
}
}
delete G[u];
}
}
else
{
for(size_t u = 0; u < N; u++)
{
for( auto const& v: *G[u] )
{
if (u<v)
{
edge_list.push_back( make_pair(u,v) );
}
}
delete G[u];
}
}

return new_N;
}
25 changes: 20 additions & 5 deletions _sixdegrees/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef __MHRN_UTILITIES_H__
#define __MHRN_UTILITIES_H__
#ifndef __SIXDEGREES_UTILITIES_H__
#define __SIXDEGREES_UTILITIES_H__

#include <iostream>
#include <algorithm>
Expand All @@ -46,7 +46,7 @@ void add_random_subgraph(
size_t n,
double p,
vector < set < size_t > * > & G,
default_random_engine & generator,
mt19937_64 & generator,
uniform_real_distribution<double> & distribution,
size_t start_node = 0
);
Expand All @@ -62,7 +62,7 @@ vector < set < size_t > * > get_components(
const vector < set < size_t > * > &G
);

void get_giant_component(
void get_largest_component(
vector < set < size_t > * > &G
);

Expand All @@ -78,6 +78,21 @@ vector < double > get_kleinberg_pmf(
);

void randomly_seed_engine(
default_random_engine &generator
mt19937_64 &generator
);

size_t neighbor_set_to_edge_list(
vector < set < size_t > * > &G,
vector < pair < size_t, size_t > > &edge_list,
bool use_largest_component,
bool delete_non_largest_component_nodes
);

size_t neighbor_set_to_coord_lists(
vector < set < size_t > * > &G,
vector < size_t > &rows,
vector < size_t > &cols,
bool use_largest_component,
bool delete_non_largest_component_nodes
);
#endif
94 changes: 62 additions & 32 deletions _sixdegrees/_sixdegrees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "original_small_world.h"
#include "random_geometric_small_world.h"
#include "random_geometric_kleinberg.h"
#include "twoD_random_geometric_kleinberg.h"
//#include "ResultClasses.h"
//#include "test.h"

Expand All @@ -52,43 +53,43 @@ namespace py = pybind11;
PYBIND11_MODULE(_sixdegrees, m) {
m.doc() = "Generate generalized small-world networks, including self-similar modular hierarchical and modified Kleinberg networks.";

m.def("modular_hierarchical_network", &fast_ssmh_edge_list, "Returns a self-similar modular hierarchical network as an edge list. If you want to compare it to a 1d Kleinberg network, be reminded that mu = ",
m.def("_modular_hierarchical_network", &fast_ssmh_edge_list, "Returns a self-similar modular hierarchical network as an edge list. If you want to compare it to a 1d Kleinberg network, be reminded that mu = ",
py::arg("B"),
py::arg("L"),
py::arg("k"),
py::arg("xi"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("allow_probability_redistribution") = false,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("allow_probability_redistribution") = true,
py::arg("seed") = 0
);

m.def("modular_hierarchical_coord_lists", &fast_ssmh_coord_lists, "Returns a self-similar modular hierarchical network as lists of adjacency matrix coordinates.",
m.def("_modular_hierarchical_network_coord_lists", &fast_ssmh_coord_lists, "Returns a self-similar modular hierarchical network as lists of adjacency matrix coordinates.",
py::arg("B"),
py::arg("L"),
py::arg("k"),
py::arg("xi"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("allow_probability_redistribution") = false,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("allow_probability_redistribution") = true,
py::arg("seed") = 0
);

m.def("kleinberg_network", &kleinberg_edge_list, "Returns a 1d Kleinberg network (with periodic boundary conditions) as edge list. Connection probability of two nodes u and v is ~ d(u,v)^(mu-1) where d(u,v) is the pair's lattice distance. If you want to map from an ssmh, bear in mind that N=B^L and mu=log(xi)/log(B).",
py::arg("N"),
py::arg("k"),
py::arg("mu"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("seed") = 0
);

m.def("kleinberg_network_coord_lists", &kleinberg_coord_lists, "Returns a 1d Kleinberg network (with periodic boundary conditions) as lists of adjacency matrix coordinates. Connection probability of two nodes u and v is ~ d(u,v)^(mu-1) where d(u,v) is the pair's lattice distance. If you want to map from an ssmh, bear in mind that N=B^L and mu=log(xi)/log(B).",
py::arg("N"),
py::arg("k"),
py::arg("mu"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("seed") = 0
);

Expand All @@ -97,8 +98,8 @@ PYBIND11_MODULE(_sixdegrees, m) {
py::arg("k"),
py::arg("mu"),
py::arg("X"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("use_theory_algorithm") = false,
py::arg("seed") = 0,
py::arg("epsilon") = 0.0
Expand All @@ -109,47 +110,76 @@ PYBIND11_MODULE(_sixdegrees, m) {
py::arg("k"),
py::arg("mu"),
py::arg("X"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("use_theory_algorithm") = false,
py::arg("seed") = 0,
py::arg("epsilon") = 0.0
);

m.def("original_small_world_network", &original_small_world_edge_list, "Returns a Watts-Strogatz small world network as a pair of (number_of_nodes, edge_list). Note that at p = 1, the generated networks are not equal to Erdos-Renyi graphs. The degree k has to be an even integer.",
m.def("_twoD_random_geometric_kleinberg_network", &twoD_random_geometric_kleinberg_edge_list,
R"pydoc(Returns a 2d Kleinberg network (with or without periodic boundary conditions) as an edge list, where node positions are uniformly distributed in the real-valued unit square [0,1]^2. You need to provide two lists X, Y of N iid random numbers drawn uniformly from [0,1]. Connection probability of two nodes u and v is ~ d(u,v)^kappa where d(u,v) is the pair's Euclidean distance.)pydoc",
py::arg("N"),
py::arg("prefactor"),
py::arg("rmin"),
py::arg("kappa"),
py::arg("X"),
py::arg("Y"),
py::arg("periodic_boundary_conditions") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("seed") = 0
);

m.def("_twoD_random_geometric_kleinberg_network_coord_lists", &twoD_random_geometric_kleinberg_coord_lists,
R"pydoc(Returns a 2d Kleinberg network (with or without periodic boundary conditions) as lists of adjacency matrix coordinates, where node positions are uniformly distributed in the real-valued unit square [0,1]^2. You need to provide two lists X, Y of N iid random numbers drawn uniformly from [0,1]. Connection probability of two nodes u and v is ~ d(u,v)^kappa where d(u,v) is the pair's Euclidean distance.)pydoc",
py::arg("N"),
py::arg("prefactor"),
py::arg("rmin"),
py::arg("kappa"),
py::arg("X"),
py::arg("Y"),
py::arg("periodic_boundary_conditions") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("seed") = 0
);


m.def("_original_small_world_network", &original_small_world_edge_list, "Returns a Watts-Strogatz small world network as a pair of (number_of_nodes, edge_list). Note that at p = 1, the generated networks are not equal to Erdos-Renyi graphs. The degree k has to be an even integer.",
py::arg("N"),
py::arg("k"),
py::arg("p"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("seed") = 0
);

m.def("original_small_world_network_coord_lists", &original_small_world_coord_lists, "Returns a Watts-Strogatz small world network as lists of adjacency matrix coordinates. Note that at p = 1, the generated networks are not equal to Erdos-Renyi graphs. The degree k has to be an even integer",
m.def("_original_small_world_network_coord_lists", &original_small_world_coord_lists, "Returns a Watts-Strogatz small world network as lists of adjacency matrix coordinates. Note that at p = 1, the generated networks are not equal to Erdos-Renyi graphs. The degree k has to be an even integer",
py::arg("N"),
py::arg("k"),
py::arg("X"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("seed") = 0
);

m.def("modified_small_world_network", &modified_small_world_edge_list, "Returns a variant of the Watts-Strogatz small world network model as a pair of (number_of_nodes, edge_list). In this variant, at p = 1, the generated networks are equal to Erdos-Renyi graphs. The degree k has to be an even integer.",
m.def("_modified_small_world_network", &modified_small_world_edge_list, "Returns a variant of the Watts-Strogatz small world network model as a pair of (number_of_nodes, edge_list). In this variant, at p = 1, the generated networks are equal to Erdos-Renyi graphs. The degree k has to be an even integer.",
py::arg("N"),
py::arg("k"),
py::arg("beta"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("use_fast_algorithm") = true,
py::arg("seed") = 0
);

m.def("modified_small_world_network_coord_lists", &modified_small_world_coord_lists, "Returns a variant of the Watts-Strogatz small world network model as lists of adjacency matrix coordinates. In this variant, at p = 1, the generated networks are equal to Erdos-Renyi graphs. The degree k has to be an even integer",
m.def("_modified_small_world_network_coord_lists", &modified_small_world_coord_lists, "Returns a variant of the Watts-Strogatz small world network model as lists of adjacency matrix coordinates. In this variant, at p = 1, the generated networks are equal to Erdos-Renyi graphs. The degree k has to be an even integer",
py::arg("N"),
py::arg("k"),
py::arg("beta"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("use_fast_algorithm") = true,
py::arg("seed") = 0
);
Expand All @@ -160,8 +190,8 @@ PYBIND11_MODULE(_sixdegrees, m) {
py::arg("k"),
py::arg("beta"),
py::arg("X"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("seed") = 0
);

Expand All @@ -171,8 +201,8 @@ PYBIND11_MODULE(_sixdegrees, m) {
py::arg("k"),
py::arg("beta"),
py::arg("X"),
py::arg("use_giant_component") = false,
py::arg("delete_non_giant_component_nodes") = true,
py::arg("use_largest_component") = false,
py::arg("delete_non_largest_component_nodes") = true,
py::arg("seed") = 0
);

Expand Down
Loading

0 comments on commit 0140f6b

Please sign in to comment.