Commit 3445d826 authored by Tiago Peixoto's avatar Tiago Peixoto

* added GetAverageCombinedVertexCorrelation()

* put combined degree correlation stuff in src/graph/graph_correlations_combined.cc
* some code cleanups in src/graph-tool


git-svn-id: https://svn.forked.de/graph-tool/trunk@29 d4600afd-f417-0410-95de-beed9576f240
parent 4eb835ec
......@@ -100,6 +100,7 @@ statistics.add_option("--average-edge-property", action="callback", callback=pus
correlations = parser.add_option_group("Correlations")
correlations.add_option("--average-combined-vertex-correlation", action="callback", callback=push_option, type="string", metavar="DEGREE1|DEGREE2|FILE", help="get the average of DEGREE2 in function of DEGREE1. Scalar properties are also accepted as DEGREE1 or DEGREE2")
correlations.add_option("--vertex-correlation-histogram", action="callback", callback=push_option, type="string", metavar="DEGREE1|DEGREE2|FILE", help="get the degree correlation histogram. Scalar properties are also accepted in place of DEGREE")
correlations.add_option("--average-nearest-neighbours-correlation", action="callback", callback=push_option, type="string", metavar="ORIGIN-DEGREE|DEGREE|FILE", help="get the average nearest neighbours correlation")
correlations.add_option("--edge-vertex-correlation-histogram", action="callback", callback=push_option, type="string", metavar="DEGREE1|EDGE-PROP|DEGREE2|FILE", help="get the source degree vs. edge scalar vs. target degree correlation histogram. Scalar properties are also accepted in place of DEGREE-TYPE")
......@@ -157,6 +158,107 @@ class OptionError(Exception):
def __str__(self):
return self.what
def generate_graph(parameters):
"this option will generate a graph with the given parameters"
seed = int(time())
N = 10000
pjk = "1.0"
pjk_ceil = "pjk(j,k)"
m_pjk = "1.0"
inv_pjk_ceil = ""
corr = "1.0"
corr_ceil = "corr(jl,kl,j,k)"
m_corr = "1.0"
inv_corr_ceil = "inv_pjk_ceil(p,r)"
try:
if get_suboption("N",parameters) != False:
N = int(get_suboption("N",parameters))
if get_suboption("pjk",parameters) != False:
pjk = get_suboption("pjk",parameters)
corr = "pjk(j,k)"
if get_suboption("pjk_ceil",parameters) != False:
pjk_ceil = get_suboption("pjk_ceil",parameters)
if get_suboption("pjk_m",parameters) != False:
m_pjk = get_suboption("pjk_m",parameters)
m_corr = m_pjk
if get_suboption("inv_pjk_ceil",parameters) != False:
inv_pjk_ceil = get_suboption("inv_pjk_ceil",parameters)
if get_suboption("corr",parameters) != False:
corr = get_suboption("corr",parameters)
if get_suboption("corr_ceil",parameters) != False:
corr_ceil = get_suboption("corr_ceil",parameters)
if get_suboption("corr_m",parameters) != False:
corr_m = get_suboption("corr_m",parameters)
if get_suboption("inv_corr_ceil",parameters) != False:
inv_corr_ceil = get_suboption("inv_corr_ceil",parameters)
undirected = get_suboption("undirected",parameters)
verbose = get_suboption("progress", parameters)
if get_suboption("seed",parameters) != False:
seed = int(get_suboption("seed",parameters))
except ValueError, e:
raise OptionError(opt.name, e)
variables = dict()
# default packages to be included
exec """
try:
from math import *
from scipy import *
from scipy.special import *
from scipy.optimize import *
from scipy.optimize.minpack import *
import psyco
except ImportError:
pass
""" in variables
# some predefined functions
exec """
def inv_poisson(p,m):
return round(fsolve(lambda k,l: gammaincc(k,l)-p, m, (m))-0.5+1e-15)
""" in variables
exec """
def inv_exponential(p,m):
return round(log(1-p)/log(float(m)/(m+1))-0.5+1e-15)
""" in variables
exec """
def inv_power_law(p,b):
return round((1-p)**(-1/(b-1)) - 1)
""" in variables
exec """
def step(x):
if x >= 0:
return 1.0
else:
return 0.0
""" in variables
# read main funtions
exec "def pjk(j,k):\n return %s\n" % pjk in variables
exec "def pjk_ceil(j,k):\n return %s\n" % pjk_ceil in variables
exec "m_pjk = %s" % m_pjk in variables
m_pjk = float(variables["m_pjk"])
if "file:" in inv_pjk_ceil:
exec open(inv_pjk_ceil.replace("file:","").strip()).read() in variables
else:
exec """
def inv_pjk_ceil(p,r):
retval = %s
return (int(round(retval[0])),int(round(retval[1])))
""" % inv_pjk_ceil in variables
exec "def corr(jl,kl,j,k):\n return %s\n" % corr in variables
exec "def corr_ceil(jl,kl,j,k):\n return %s\n" % corr_ceil in variables
exec "m_corr = %s" % m_corr in variables
m_corr = float(variables["m_corr"])
if "file:" in inv_corr_ceil:
exec open(inv_corr_ceil.replace("file:","").strip()).read() in variables
else:
exec """
def inv_corr_ceil(p,r,j,k):
retval = %s
return (int(round(retval[0])),int(round(retval[1])))
""" % inv_corr_ceil in variables
graph.GenerateCorrelatedConfigurationalModel(N, variables["pjk"], variables["pjk_ceil"], variables["inv_pjk_ceil"], m_pjk, variables["corr"],
variables["corr_ceil"], variables["inv_corr_ceil"], m_corr, undirected, seed, verbose)
def parse_option(opt, just_file=False):
"this will execute an aption, and return either None, or a tuple with the result and the respective file name, if it exists"
if opt.name == "load":
......@@ -168,70 +270,9 @@ def parse_option(opt, just_file=False):
return None
graph.WriteToFile(opt.value)
elif opt.name == "correlated-configurational-model":
seed = int(time())
N = 10000
m = 4.0
pjk = "1.0"
pjk_ceil = "pjk(j,k)"
m_pjk = "1.0"
inv_pjk_ceil = ""
corr = "1.0"
corr_ceil = "corr(jl,kl,j,k)"
m_corr = "1.0"
inv_corr_ceil = "inv_pjk_ceil(p,r)"
try:
if get_suboption("N",opt.value) != False:
N = int(get_suboption("N",opt.value))
if get_suboption("pjk",opt.value) != False:
pjk = get_suboption("pjk",opt.value)
corr = "pjk(j,k)"
if get_suboption("pjk_ceil",opt.value) != False:
pjk_ceil = get_suboption("pjk_ceil",opt.value)
if get_suboption("pjk_m",opt.value) != False:
m_pjk = get_suboption("pjk_m",opt.value)
m_corr = m_pjk
if get_suboption("inv_pjk_ceil",opt.value) != False:
inv_pjk_ceil = get_suboption("inv_pjk_ceil",opt.value)
if get_suboption("corr",opt.value) != False:
corr = get_suboption("corr",opt.value)
if get_suboption("corr_ceil",opt.value) != False:
corr_ceil = get_suboption("corr_ceil",opt.value)
if get_suboption("corr_m",opt.value) != False:
corr_m = get_suboption("corr_m",opt.value)
if get_suboption("inv_corr_ceil",opt.value) != False:
inv_corr_ceil = get_suboption("inv_corr_ceil",opt.value)
undirected = get_suboption("undirected",opt.value)
verbose = get_suboption("progress", opt.value)
if get_suboption("seed",opt.value) != False:
seed = int(get_suboption("seed",opt.value))
except ValueError, e:
raise OptionError(opt.name, e)
variables = dict()
exec "try:\n from math import *\n from scipy import *\n from scipy.special import *\n from scipy.optimize import *\n from scipy.optimize.minpack import *\n import psyco\nexcept ImportError:\n pass " in variables;
exec "def inv_poisson(p,m):\n return round(fsolve(lambda k,l: gammaincc(k,l)-p, m, (m))-0.5+1e-15)" in variables;
exec "def inv_exponential(p,m):\n return round(log(1-p)/log(float(m)/(m+1))-0.5+1e-15)" in variables;
exec "def inv_power_law(p,b):\n return round((1-p)**(-1/(b-1)) - 1)" in variables;
exec "def step(x):\n if x >= 0:\n return 1.0\n else:\n return 0.0\n" in variables;
exec "def pjk(j,k):\n return %s" % pjk in variables
exec "def pjk_ceil(j,k):\n return %s" % pjk_ceil in variables
exec "m_pjk = %s" % m_pjk in variables
m_pjk = float(variables["m_pjk"])
if "file:" in inv_pjk_ceil:
exec open(inv_pjk_ceil.replace("file:","").strip()).read() in variables
else:
exec "def inv_pjk_ceil(p,r):\n retval = %s; return (int(round(retval[0])),int(round(retval[1])))" % inv_pjk_ceil in variables
exec "def corr(jl,kl,j,k):\n return %s" % corr in variables
exec "def corr_ceil(jl,kl,j,k):\n return %s" % corr_ceil in variables
exec "m_corr = %s" % m_corr in variables
m_corr = float(variables["m_corr"])
if "file:" in inv_corr_ceil:
exec open(inv_corr_ceil.replace("file:","").strip()).read() in variables
else:
exec "def inv_corr_ceil(p,r,j,k):\n retval = %s; return (int(round(retval[0])),int(round(retval[1])))" % inv_corr_ceil in variables
if just_file:
return None
graph.GenerateCorrelatedConfigurationalModel(N, variables["pjk"], variables["pjk_ceil"], variables["inv_pjk_ceil"], m_pjk, variables["corr"],
variables["corr_ceil"], variables["inv_corr_ceil"], m_corr, undirected, seed, verbose)
generate_graph(opt.value)
elif opt.name == "number-of-vertices":
if just_file:
return opt.value
......@@ -247,6 +288,13 @@ def parse_option(opt, just_file=False):
if just_file:
return values[2]
return (graph.GetCombinedVertexHistogram(degree(values[0]),degree(values[1])), values[2])
elif opt.name == "average-combined-vertex-correlation":
values = parse_values(opt.value)
if len(values) != 3:
raise OptionError(opt.name, "invalid value '%s'" % opt.value)
if just_file:
return values[2]
return (graph.GetAverageCombinedVertexCorrelation(degree(values[0]),degree(values[1])), values[2])
elif opt.name == "average-distance":
values = parse_values(opt.value)
if len(values) > 2 or len(values) < 1:
......
......@@ -25,6 +25,7 @@ libgraph_tool_la_SOURCES = \
graph_properties.hh\
graph_properties.cc\
graph_correlations.cc\
graph_correlations_combined.cc\
graph_correlations_neighbours.cc\
graph_assortativity.cc\
graph_clustering.cc\
......
......@@ -74,6 +74,7 @@ public:
//correlations
hist2d_t GetCombinedVertexHistogram(deg_t degree1, deg_t degree2) const;
avg_corr_t GetAverageCombinedVertexCorrelation(deg_t degree1, deg_t degree2) const;
hist2d_t GetVertexCorrelationHistogram(deg_t degree1, deg_t degree2) const;
hist3d_t GetEdgeVertexCorrelationHistogram(deg_t deg1, std::string scalar, deg_t deg2) const;
avg_corr_t GetAverageNearestNeighboursCorrelation(deg_t origin_degree, deg_t neighbour_degree) const;
......
......@@ -216,7 +216,8 @@ BOOST_PYTHON_MODULE(libgraph_tool)
.def("GetVertexHistogram", &GraphInterfaceWrap::GetVertexHistogram)
.def("GetEdgeHistogram", &GraphInterfaceWrap::GetEdgeHistogram)
.def("GetComponentSizeHistogram", &GraphInterfaceWrap::GetComponentSizeHistogram)
.def("GetCombinedVertexHistogram", &GraphInterfaceWrap::GetCombinedVertexHistogram)
.def("GetCombinedVertexHistogram", &GraphInterfaceWrap::GetCombinedVertexHistogram)
.def("GetAverageCombinedVertexCorrelation", &GraphInterfaceWrap::GetAverageCombinedVertexCorrelation)
.def("GetVertexCorrelationHistogram", &GraphInterfaceWrap::GetVertexCorrelationHistogram)
.def("GetEdgeVertexCorrelationHistogram", &GraphInterfaceWrap::GetEdgeVertexCorrelationHistogram)
.def("GetAverageNearestNeighboursCorrelation", &GraphInterfaceWrap::GetAverageNearestNeighboursCorrelation)
......
......@@ -33,91 +33,6 @@ using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
//==============================================================================
// GetCombinedVertexHistogram()
// retrieves the distribution of combined (deg1,deg2) degrees
//==============================================================================
template <class DegreeSelector1, class DegreeSelector2>
struct get_combined_degree_histogram
{
get_combined_degree_histogram(DegreeSelector1& deg1, DegreeSelector2& deg2): _deg1(deg1), _deg2(deg2) {}
template <class Graph, class Hist>
void operator()(Graph &g, Hist &hist) const
{
typedef typename Hist::key_type::first_type first_type;
typedef typename Hist::key_type::second_type second_type;
typename graph_traits<Graph>::vertex_iterator v, v_begin, v_end;
tie(v_begin, v_end) = vertices(g);
for(v = v_begin; v != v_end; ++v)
hist[make_pair(first_type(_deg1(*v,g)), second_type(_deg2(*v,g)))]++;
}
DegreeSelector1& _deg1;
DegreeSelector2& _deg2;
};
template <class SecondDegreeSelectors>
struct choose_combined_degree_histogram
{
choose_combined_degree_histogram(const GraphInterface &g, GraphInterface::deg_t deg1,
GraphInterface::deg_t deg2, GraphInterface::hist2d_t &hist)
: _g(g), _hist(hist)
{
tie(_deg1, _deg_name1) = get_degree_type(deg1);
tie(_deg2, _deg_name2) = get_degree_type(deg2);
}
template <class DegreeSelector1>
struct check_second_degree
{
check_second_degree(choose_combined_degree_histogram<SecondDegreeSelectors> &parent):_parent(parent) {}
template <class DegreeSelector2>
void operator()(DegreeSelector2)
{
if (mpl::at<degree_selector_index,DegreeSelector2>::type::value == _parent._deg2)
{
DegreeSelector1 deg1(_parent._deg_name1, _parent._g);
DegreeSelector2 deg2(_parent._deg_name2, _parent._g);
check_filter(_parent._g, bind<void>(get_combined_degree_histogram<DegreeSelector1,DegreeSelector2>(deg1,deg2), _1, var(_parent._hist)),
reverse_check(),directed_check());
}
}
choose_combined_degree_histogram<SecondDegreeSelectors> _parent;
};
template <class DegreeSelector>
void operator()(DegreeSelector)
{
if (mpl::at<degree_selector_index,DegreeSelector>::type::value == _deg1)
mpl::for_each<SecondDegreeSelectors>(check_second_degree<DegreeSelector>(*this));
}
const GraphInterface &_g;
GraphInterface::hist2d_t &_hist;
GraphInterface::degree_t _deg1;
string _deg_name1;
GraphInterface::degree_t _deg2;
string _deg_name2;
};
GraphInterface::hist2d_t
GraphInterface::GetCombinedVertexHistogram(deg_t deg1, deg_t deg2) const
{
hist2d_t hist;
typedef mpl::vector<in_degreeS, out_degreeS, total_degreeS, scalarS> degree_selectors;
try
{
mpl::for_each<degree_selectors>(choose_combined_degree_histogram<degree_selectors>(*this, deg1, deg2, hist));
}
catch (dynamic_get_failure &e)
{
throw GraphException("error getting scalar property: " + string(e.what()));
}
return hist;
}
//==============================================================================
// get_correlation_histogram
// retrieves the generalized vertex-vertex correlation histogram
......
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006 Tiago de Paula Peixoto <tiago@forked.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 2
// 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, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <algorithm>
#include <tr1/unordered_set>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/random.hpp>
#include "graph.hh"
#include "histogram.hh"
#include "graph_filtering.hh"
#include "graph_selectors.hh"
#include "graph_properties.hh"
using namespace std;
using namespace boost;
using namespace boost::lambda;
using namespace graph_tool;
//==============================================================================
// GetCombinedVertexHistogram()
// retrieves the distribution of combined (deg1,deg2) degrees
//==============================================================================
template <class DegreeSelector1, class DegreeSelector2>
struct get_combined_degree_histogram
{
get_combined_degree_histogram(DegreeSelector1& deg1, DegreeSelector2& deg2): _deg1(deg1), _deg2(deg2) {}
template <class Graph, class Hist>
void operator()(Graph &g, Hist &hist) const
{
typedef typename Hist::key_type::first_type first_type;
typedef typename Hist::key_type::second_type second_type;
typename graph_traits<Graph>::vertex_iterator v, v_begin, v_end;
tie(v_begin, v_end) = vertices(g);
for(v = v_begin; v != v_end; ++v)
hist[make_pair(first_type(_deg1(*v,g)), second_type(_deg2(*v,g)))]++;
}
DegreeSelector1& _deg1;
DegreeSelector2& _deg2;
};
template <class SecondDegreeSelectors>
struct choose_combined_degree_histogram
{
choose_combined_degree_histogram(const GraphInterface &g, GraphInterface::deg_t deg1,
GraphInterface::deg_t deg2, GraphInterface::hist2d_t &hist)
: _g(g), _hist(hist)
{
tie(_deg1, _deg_name1) = get_degree_type(deg1);
tie(_deg2, _deg_name2) = get_degree_type(deg2);
}
template <class DegreeSelector1>
struct check_second_degree
{
check_second_degree(choose_combined_degree_histogram<SecondDegreeSelectors> &parent):_parent(parent) {}
template <class DegreeSelector2>
void operator()(DegreeSelector2)
{
if (mpl::at<degree_selector_index,DegreeSelector2>::type::value == _parent._deg2)
{
DegreeSelector1 deg1(_parent._deg_name1, _parent._g);
DegreeSelector2 deg2(_parent._deg_name2, _parent._g);
check_filter(_parent._g, bind<void>(get_combined_degree_histogram<DegreeSelector1,DegreeSelector2>(deg1,deg2), _1, var(_parent._hist)),
reverse_check(),directed_check());
}
}
choose_combined_degree_histogram<SecondDegreeSelectors>& _parent;
};
template <class DegreeSelector>
void operator()(DegreeSelector)
{
if (mpl::at<degree_selector_index,DegreeSelector>::type::value == _deg1)
mpl::for_each<SecondDegreeSelectors>(check_second_degree<DegreeSelector>(*this));
}
const GraphInterface &_g;
GraphInterface::hist2d_t &_hist;
GraphInterface::degree_t _deg1;
string _deg_name1;
GraphInterface::degree_t _deg2;
string _deg_name2;
};
GraphInterface::hist2d_t
GraphInterface::GetCombinedVertexHistogram(deg_t deg1, deg_t deg2) const
{
hist2d_t hist;
typedef mpl::vector<in_degreeS, out_degreeS, total_degreeS, scalarS> degree_selectors;
try
{
mpl::for_each<degree_selectors>(choose_combined_degree_histogram<degree_selectors>(*this, deg1, deg2, hist));
}
catch (dynamic_get_failure &e)
{
throw GraphException("error getting scalar property: " + string(e.what()));
}
return hist;
}
//==============================================================================
// GetAverageCombinedVertexCorrelation()
// retrieves the average of deg2 in function of deg1
//==============================================================================
template <class DegreeSelector1, class DegreeSelector2>
struct get_average_combined_degree_correlation
{
get_average_combined_degree_correlation(DegreeSelector1& deg1, DegreeSelector2& deg2): _deg1(deg1), _deg2(deg2) {}
template <class Graph, class AvgDeg>
void operator()(Graph &g, AvgDeg &avg_deg) const
{
tr1::unordered_map<double,size_t> count;
typename graph_traits<Graph>::vertex_iterator v, v_begin, v_end;
tie(v_begin, v_end) = vertices(g);
for(v = v_begin; v != v_end; ++v)
{
typename AvgDeg::key_type d1 = _deg1(*v,g);
typename AvgDeg::value_type::second_type::first_type d2 = _deg2(*v,g);
avg_deg[d1].first += d2;
avg_deg[d1].second += d2*d2;
count[d1]++;
}
for (typeof(avg_deg.begin()) iter = avg_deg.begin(); iter != avg_deg.end(); ++iter)
{
size_t N = count[iter->first];
iter->second.first /= N;
if (N > 1)
iter->second.second = sqrt((iter->second.second - N*iter->second.first*iter->second.first)/(N*(N-1)));
else
iter->second.second = 0.0;
}
}
DegreeSelector1& _deg1;
DegreeSelector2& _deg2;
};
template <class SecondDegreeSelectors>
struct choose_average_combined_degree_correlation
{
choose_average_combined_degree_correlation(const GraphInterface &g, GraphInterface::deg_t deg1,
GraphInterface::deg_t deg2, GraphInterface::avg_corr_t &avg_corr)
: _g(g), _avg_corr(avg_corr)
{
tie(_deg1, _deg_name1) = get_degree_type(deg1);
tie(_deg2, _deg_name2) = get_degree_type(deg2);
}
template <class DegreeSelector1>
struct check_second_degree
{
check_second_degree(choose_average_combined_degree_correlation<SecondDegreeSelectors> &parent):_parent(parent) {}
template <class DegreeSelector2>
void operator()(DegreeSelector2)
{
if (mpl::at<degree_selector_index,DegreeSelector2>::type::value == _parent._deg2)
{
DegreeSelector1 deg1(_parent._deg_name1, _parent._g);
DegreeSelector2 deg2(_parent._deg_name2, _parent._g);
check_filter(_parent._g, bind<void>(get_average_combined_degree_correlation<DegreeSelector1,DegreeSelector2>(deg1,deg2),
_1, var(_parent._avg_corr)),
reverse_check(),directed_check());
}
}
choose_average_combined_degree_correlation<SecondDegreeSelectors>& _parent;
};
template <class DegreeSelector>
void operator()(DegreeSelector)
{
if (mpl::at<degree_selector_index,DegreeSelector>::type::value == _deg1)
mpl::for_each<SecondDegreeSelectors>(check_second_degree<DegreeSelector>(*this));
}
const GraphInterface &_g;
GraphInterface::avg_corr_t &_avg_corr;
GraphInterface::degree_t _deg1;
string _deg_name1;
GraphInterface::degree_t _deg2;
string _deg_name2;
};
GraphInterface::avg_corr_t
GraphInterface::GetAverageCombinedVertexCorrelation(deg_t deg1, deg_t deg2) const
{
avg_corr_t avg_corr;
typedef mpl::vector<in_degreeS, out_degreeS, total_degreeS, scalarS> degree_selectors;
try
{
mpl::for_each<degree_selectors>(choose_average_combined_degree_correlation<degree_selectors>(*this, deg1, deg2, avg_corr));
}
catch (dynamic_get_failure &e)
{
throw GraphException("error getting scalar property: " + string(e.what()));
}
return avg_corr;
}
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