Commit bad74126 authored by Tiago Peixoto's avatar Tiago Peixoto

Generalize "probabilistic" random graph generation/rewiring to a blockmodel

This implements a general "blockmodel" generation / rewiring algorithm,
using Gibbs acceptence / rejection sampling (a.k.a Metropolis-Hastings).

This also implements some optimizations in the rewiring code, which
makes it more efficient on filtered graphs.
parent 8240714e
......@@ -32,15 +32,15 @@ class PythonFuncWrap
public:
PythonFuncWrap(python::object o): _o(o) {}
pair<size_t, size_t> operator()() const
pair<size_t, size_t> operator()(size_t i) const
{
python::object ret = _o();
python::object ret = _o(i);
return python::extract<pair<size_t,size_t> >(ret);
}
size_t operator()(bool) const
size_t operator()(size_t i, bool) const
{
python::object ret = _o();
python::object ret = _o(i);
return python::extract<size_t>(ret);
}
......@@ -48,11 +48,9 @@ private:
python::object _o;
};
void generate_graph(GraphInterface& gi, size_t N,
python::object deg_sample,
bool uncorrelated, bool no_parallel,
bool no_self_loops, bool undirected,
size_t seed, bool verbose, bool verify)
void generate_graph(GraphInterface& gi, size_t N, python::object deg_sample,
bool uncorrelated, bool no_parallel, bool no_self_loops,
bool undirected, size_t seed, bool verbose, bool verify)
{
typedef graph_tool::detail::get_all_graph_views::apply<
graph_tool::detail::scalar_pairs, mpl::bool_<false>,
......@@ -83,7 +81,8 @@ void generate_graph(GraphInterface& gi, size_t N,
size_t random_rewire(GraphInterface& gi, string strat, size_t niter,
bool no_sweep, bool self_loops, bool parallel_edges,
python::object corr_prob, size_t seed, bool verbose);
python::object corr_prob, boost::any block,
size_t seed, bool verbose);
void predecessor_graph(GraphInterface& gi, GraphInterface& gpi,
boost::any pred_map);
void line_graph(GraphInterface& gi, GraphInterface& lgi,
......
......@@ -185,7 +185,7 @@ public:
dvertex_t& v = vertices[i];
do
{
tie(v.in_degree, v.out_degree) = deg_sample();
tie(v.in_degree, v.out_degree) = deg_sample(i);
}
while (_no_parallel &&
(v.in_degree > _max_deg || v.out_degree > _max_deg));
......@@ -209,7 +209,8 @@ public:
(_no_self_loops && !_no_parallel &&
!is_graphical_parallel(_deg_seq)))
{
dvertex_t& v = vertices[vertex_sample(rng)];
size_t i = vertex_sample(rng);
dvertex_t& v = vertices[i];
if (_no_parallel || _no_self_loops)
{
typeof(_deg_seq.begin()) iter =
......@@ -223,7 +224,7 @@ public:
sum_k -= v.out_degree;
do
{
tie(v.in_degree, v.out_degree) = deg_sample();
tie(v.in_degree, v.out_degree) = deg_sample(i);
}
while (_no_parallel &&
(v.in_degree > _max_deg || v.out_degree > _max_deg));
......@@ -326,7 +327,7 @@ public:
dvertex_t& v = vertices[i];
do
{
v.out_degree = deg_sample(true);
v.out_degree = deg_sample(i, true);
}
while (_no_parallel && v.out_degree > _max_deg);
sum_k += v.out_degree;
......@@ -349,7 +350,8 @@ public:
(_no_self_loops && !_no_parallel &&
!is_graphical_parallel(_deg_seq)))
{
dvertex_t& v = vertices[vertex_sample(rng)];
size_t i = vertex_sample(rng);
dvertex_t& v = vertices[i];
if (_no_parallel || _no_self_loops)
{
typeof(_deg_seq.begin()) iter = _deg_seq.find(v.out_degree);
......@@ -360,7 +362,7 @@ public:
sum_k -= v.out_degree;
do
{
v.out_degree = deg_sample(true);
v.out_degree = deg_sample(i, true);
}
while (_no_parallel && (v.out_degree > _max_deg));
sum_k += v.out_degree;
......
......@@ -44,13 +44,38 @@ public:
return python::extract<double>(ret);
}
template <class Type>
double operator()(const Type& deg1, const Type& deg2) const
{
python::object ret = _o(python::object(deg1),
python::object(deg2));
return python::extract<double>(ret);
}
private:
python::object _o;
};
struct graph_rewire_block
{
template <class Graph, class EdgeIndexMap, class CorrProb, class BlockProp>
void operator()(Graph& g, EdgeIndexMap edge_index, CorrProb corr_prob,
pair<bool, bool> rest, BlockProp block_prop,
pair<size_t, bool> iter_sweep, bool verbose, size_t& pcount,
rng_t& rng) const
{
graph_rewire<ProbabilisticRewireStrategy>()
(g, edge_index, corr_prob, rest.first, rest.second, iter_sweep,
verbose, pcount, rng, PropertyBlock<BlockProp>(block_prop));
}
};
size_t random_rewire(GraphInterface& gi, string strat, size_t niter,
bool no_sweep, bool self_loops, bool parallel_edges,
python::object corr_prob, size_t seed, bool verbose)
python::object corr_prob, boost::any block,
size_t seed, bool verbose)
{
rng_t rng(static_cast<rng_t::result_type>(seed));
PythonFuncWrap corr(corr_prob);
......@@ -84,6 +109,14 @@ size_t random_rewire(GraphInterface& gi, string strat, size_t niter,
self_loops, parallel_edges,
make_pair(niter, no_sweep), verbose,
boost::ref(pcount), boost::ref(rng)))();
else if (strat == "blockmodel")
run_action<>()
(gi, boost::bind<void>(graph_rewire_block(),
_1, gi.GetEdgeIndex(), boost::ref(corr),
make_pair(self_loops, parallel_edges), _2,
make_pair(niter, no_sweep), verbose,
boost::ref(pcount), boost::ref(rng)),
vertex_properties())(block);
else
throw ValueException("invalid random rewire strategy: " + strat);
return pcount;
......
This diff is collapsed.
......@@ -196,6 +196,25 @@ def _python_type(type_name):
return object
def _gt_type(obj):
t = type(obj)
if t is numpy.longlong or t is numpy.uint64:
return "long long"
if t is int or issubclass(t, numpy.int):
return "int"
if t is numpy.float128:
return "long double"
if t is float or issubclass(t, numpy.float):
return "double"
if t is str:
return "string"
if t is bool:
return "bool"
if issubclass(t, list) or issubclass(t, numpy.ndarray):
return "vector<%s>" % _gt_type(obj[0])
return "object"
def _convert(prop, val):
# attempt to convert to a compatible python type. This is useful,
# for instance, when dealing with numpy types.
......
......@@ -132,23 +132,23 @@ def pagerank(g, damping=0.85, pers=None, weight=None, prop=None, epsilon=1e-6,
>>> g = gt.random_graph(100, lambda: (poisson(3), poisson(3)))
>>> pr = gt.pagerank(g)
>>> print pr.a
[ 0.00865316 0.0054067 0.00406312 0.00426668 0.0015 0.00991696
0.00550065 0.00936397 0.00347917 0.00731864 0.00689843 0.00286274
0.00508731 0.01020047 0.00562247 0.00584915 0.02457086 0.00438568
0.0057385 0.00621745 0.001755 0.0045073 0.0015 0.00225167
0.00698342 0.00206302 0.01094466 0.001925 0.00710093 0.00519877
0.00460646 0.00994648 0.01005248 0.00904629 0.00676221 0.00789208
0.00933103 0.00301154 0.00264951 0.00842812 0.0015 0.00191034
0.00594069 0.00884372 0.00453417 0.00388987 0.00317433 0.0086067
0.00385394 0.00672702 0.00258411 0.01468262 0.00454 0.00381159
0.00402607 0.00451133 0.00480966 0.00811557 0.00571949 0.00317433
0.00856838 0.00280517 0.00280563 0.00906324 0.00614421 0.0015
0.00292034 0.00479769 0.00552694 0.00604799 0.0115922 0.0015
0.00676183 0.00695336 0.01023352 0.01737541 0.00451443 0.00197688
0.00553866 0.00486233 0.0078653 0.00867599 0.01248092 0.0015
0.00399605 0.00399605 0.00881571 0.00638008 0.01056944 0.00353724
0.00249869 0.00684919 0.00241374 0.01061397 0.00673569 0.00590937
0.01004638 0.00331612 0.00926359 0.00460809]
[ 0.00867754 0.00729246 0.00363279 0.00668265 0.0015 0.00859964
0.00449637 0.00961946 0.01295288 0.00882362 0.00719256 0.00280697
0.00518114 0.01047904 0.00569656 0.00519058 0.00759745 0.00700835
0.00870244 0.00522561 0.00233159 0.00236035 0.0015 0.00255374
0.00872139 0.00227483 0.00686341 0.001755 0.00488567 0.01045994
0.00393206 0.00988283 0.01376133 0.00721883 0.01429166 0.00752748
0.01846797 0.00674401 0.00412138 0.00842639 0.0015 0.00233159
0.00306271 0.01902149 0.0099247 0.00428981 0.00215072 0.01123842
0.00236035 0.00768803 0.00463719 0.01130437 0.00392423 0.00491263
0.00899519 0.00680983 0.0091988 0.00459334 0.00809094 0.00881614
0.01381946 0.00489171 0.00425249 0.01957383 0.00708763 0.0015
0.00418613 0.00607306 0.01287535 0.00639268 0.01578391 0.0015
0.01541987 0.00860721 0.01378758 0.0173314 0.00775072 0.00247939
0.00524088 0.00686587 0.00436895 0.00755964 0.00708251 0.0015
0.00226438 0.00184085 0.00555171 0.01159494 0.01297596 0.00460887
0.00406717 0.00578091 0.00548516 0.01197071 0.00674202 0.01011666
0.01072786 0.00646937 0.01430012 0.01483996]
Now with a personalization vector, and edge weights:
......@@ -159,23 +159,23 @@ def pagerank(g, damping=0.85, pers=None, weight=None, prop=None, epsilon=1e-6,
>>> p.a /= p.a.sum()
>>> pr = gt.pagerank(g, pers=p, weight=w)
>>> print pr.a
[ 0.00712999 0.00663336 0.00685722 0.00402663 0.00092715 0.01021926
0.00269502 0.0073301 0.00449892 0.00582793 0.00580542 0.00275149
0.00676363 0.01157972 0.00486918 0.00616345 0.02506695 0.00607967
0.00553375 0.00359075 0.00293808 0.00362247 0.00250025 0.00186946
0.00895516 0.00318147 0.01489786 0.00312436 0.0074751 0.0040342
0.006254 0.00687051 0.0098073 0.01076278 0.00887077 0.00806759
0.00969532 0.00252648 0.00278688 0.00972144 0.00148972 0.00215428
0.00713602 0.00559849 0.00495517 0.00457118 0.00323767 0.01257406
0.00120179 0.00514838 0.00130655 0.01724465 0.00343819 0.00420962
0.00297617 0.00588287 0.00657206 0.00775082 0.00758217 0.00433776
0.00576829 0.00464595 0.00307274 0.00585795 0.00745881 0.00238803
0.00230431 0.00437046 0.00492464 0.00275414 0.01524646 0.00300867
0.00816665 0.00548853 0.00874738 0.01871498 0.00216776 0.00245196
0.00308878 0.00646323 0.01287978 0.00911384 0.01628604 0.0009367
0.00222119 0.00864202 0.01199119 0.01126539 0.01086846 0.00309224
0.0020319 0.00659422 0.00226965 0.0134399 0.01094141 0.00732916
0.00489314 0.0030402 0.00783914 0.00278588]
[ 0.00761942 0.00761689 0.00418938 0.00947758 0.00092715 0.00349991
0.00811226 0.00448968 0.01209889 0.01384828 0.00600036 0.00221745
0.00432908 0.01036427 0.00536132 0.00692364 0.00575216 0.00750936
0.00924536 0.00461255 0.00422277 0.00055639 0.00250025 0.00289125
0.00925617 0.003356 0.00642017 0.00298276 0.00571097 0.01115541
0.00452616 0.01670105 0.01788592 0.00580217 0.01350007 0.00837655
0.01535733 0.00497981 0.00436008 0.01324374 0.00148972 0.00287379
0.00408663 0.02785282 0.00790422 0.00491795 0.00070143 0.00789247
0.00033551 0.00777089 0.00278393 0.00801468 0.00452296 0.00378295
0.00642244 0.00698618 0.01069855 0.0019177 0.00742151 0.00872767
0.01868187 0.00442359 0.00593616 0.01517386 0.00712472 0.00238803
0.00468324 0.0024983 0.011788 0.00577489 0.01242015 0.00300867
0.01390361 0.00796192 0.00822753 0.01062897 0.00815637 0.00332914
0.00911336 0.00915715 0.00945334 0.00880299 0.00758402 0.0009367
0.00378413 0.00174124 0.00283594 0.00929262 0.01090867 0.00460206
0.00341061 0.00699703 0.00232131 0.01244958 0.00731098 0.01288061
0.00820259 0.00430521 0.01633379 0.0119308 ]
References
----------
......@@ -259,23 +259,23 @@ def betweenness(g, vprop=None, eprop=None, weight=None, norm=True):
>>> g = gt.random_graph(100, lambda: (poisson(3), poisson(3)))
>>> vb, eb = gt.betweenness(g)
>>> print vb.a
[ 0.04889806 0.07181892 0.0256799 0.02885791 0. 0.05060927
0.04490836 0.03763462 0.02033383 0.03163202 0.02641248 0.03171598
0.03771112 0.02194663 0.0374907 0.01072567 0. 0.03079281
0.05409258 0.00163434 0.00051978 0.01045902 0. 0.00796784
0.0494527 0.00647576 0.03708252 0.00304503 0.0663657 0.03903257
0.03305169 0. 0.07787098 0.03938866 0.08577116 0.020183
0.06024004 0.01004935 0.0443127 0.06397736 0. 0.00363548
0.01742486 0.03216543 0.01918144 0.02059159 0. 0.01476213
0. 0.0466751 0.01072612 0.10288046 0.00563973 0.03850413
0.00629595 0.01292137 0.0537963 0.04454985 0.01227018 0.00729488
0.02092959 0.02308238 0.00712703 0.02193975 0.03823342 0.
0.00995364 0.04023839 0.0312708 0.0111312 0.00228516 0.
0.09659583 0.01327402 0.05792071 0.08606828 0.0143541 0.00221604
0.02144698 0. 0.04023879 0.00715758 0. 0.
0.02348452 0.00760922 0.01486521 0.08132792 0.0382674 0.03078318
0.00430209 0.01772787 0.02280666 0.0373011 0.03077511 0.02871265
0. 0.01044655 0.04415432 0.04447525]
[ 0.02412512 0.08233748 0.01789612 0.03997773 0. 0.03476439
0.03490215 0.02812729 0.05385124 0.01614861 0.01894254 0.03552189
0.01648793 0.02743878 0.02243743 0.0052126 0. 0.02648145
0.05045875 0.01670867 0.00027069 0.00235053 0. 0.00424986
0.02153982 0.01635659 0.03177692 0.00152088 0.02099129 0.05311383
0.00802715 0. 0.06129706 0.03148129 0.10265395 0.02762436
0.05323276 0.028209 0.01641328 0.03547918 0. 0.00998142
0.01043084 0.06810444 0.01435047 0.02884138 0. 0.02336079
0. 0.09098673 0.02911358 0.05909676 0.01314448 0.0304931
0.01315283 0.03795536 0.02756845 0.020655 0.00268182 0.0151298
0.05597887 0.04095171 0.00853146 0.06176456 0.03165429 0. 0.0114488
0.05435076 0.04046437 0.0122299 0.03417369 0. 0.05979601
0.01502672 0.05908044 0.09567821 0.01206665 0.01259951 0.02381255
0. 0.01840359 0.00708731 0. 0. 0.01274922
0.00385357 0. 0.11470908 0.04903743 0.03336991 0.01270614
0.00448173 0.02163365 0.06685948 0.01032924 0.02400925 0. 0.0300603
0.03220004 0.03932736]
References
----------
......@@ -341,7 +341,7 @@ def central_point_dominance(g, betweenness):
>>> g = gt.random_graph(100, lambda: (poisson(3), poisson(3)))
>>> vb, eb = gt.betweenness(g)
>>> print gt.central_point_dominance(g, vb)
0.0766473408634
0.0888588565184
References
----------
......@@ -419,25 +419,25 @@ def eigenvector(g, weight=None, vprop=None, epsilon=1e-6, max_iter=None):
>>> w.a = random(g.num_edges()) * 42
>>> x = gt.eigenvector(g, w)
>>> print x[0]
0.0160851991895
0.0144966901652
>>> print x[1].a
[ 0.1376411 0.07207366 0.02727508 0.05805304 0. 0.10690994
0.04315491 0.01040908 0.02300252 0.08874163 0.04968119 0.06718114
0.05526028 0.20449371 0.02337425 0.07581173 0.19993899 0.14718912
0.08464664 0.08474977 0. 0.04843894 0. 0.0089388
0.16831573 0.00138653 0.11741616 0. 0.13455019 0.03642682
0.06729803 0.06229526 0.08937098 0.05693976 0.0793375 0.04076743
0.22176891 0.07717256 0.00518048 0.05722748 0. 0.00055799
0.04541778 0.06420469 0.06189998 0.08011859 0.05377224 0.29979873
0.01211309 0.15503588 0.02804072 0.1692873 0.01420732 0.02507
0.02959899 0.02702304 0.1652933 0.01434992 0.1073001 0.04582697
0.04618913 0.0220902 0.01421926 0.09891276 0.04522928 0.
0.00236599 0.07686829 0.03243909 0.00346715 0.1954776 0.
0.25583217 0.11710921 0.07804282 0.21188464 0.04800656 0.00321866
0.0552824 0.11204116 0.11420818 0.24071304 0.15451676 0.
0.00475456 0.10680434 0.17054333 0.18945499 0.15673649 0.03405238
0.01653319 0.02563015 0.00186129 0.12061027 0.11449362 0.11114196
0.06779788 0.00595725 0.09127559 0.02380386]
[ 0.06930562 0.15259089 0.02186899 0.16605389 0. 0.03329417
0.15389839 0.05956241 0.02364241 0.14555449 0.12223866 0.04284837
0.02930074 0.12362235 0.08914056 0.06613553 0.04127041 0.06894616
0.11768146 0.10576438 0.03184658 0.01097733 0. 0.00244834
0.12373674 0.04521477 0.06729261 0. 0.0119752 0.09613809
0.05371652 0.0760725 0.26342747 0.06901843 0.12261332 0.07428021
0.16074381 0.04316101 0.01382325 0.07976272 0. 0.02358784
0.04087066 0.22404933 0.05037626 0.07311321 0.00118498 0.10162138
0.00695398 0.15475802 0.03601454 0.12771193 0.00204537 0.00850904
0.06338004 0.11785637 0.171928 0.00577511 0.08163299 0.02358024
0.25112631 0.05618482 0.00868661 0.15998601 0.11513557 0.
0.07307991 0.06984483 0.1043859 0.15786829 0.12612902 0.
0.11247494 0.06210605 0.07547538 0.09774456 0.01932 0.01132741
0.07459586 0.14437367 0.06477981 0.13211211 0.04886609 0.
0.09043424 0.00644994 0.0112379 0.10472704 0.2077468 0.04146317
0.04745921 0.07442587 0.00757032 0.18575827 0.09975438 0.11682436
0.22233397 0.08072367 0.13527766 0.16050936]
References
----------
......@@ -525,31 +525,23 @@ def eigentrust(g, trust_map, vprop=None, norm=False, epsilon=1e-6, max_iter=0,
>>> trust.a = random(g.num_edges())*42
>>> t = gt.eigentrust(g, trust, norm=True)
>>> print t.a
[ 1.12095562e-02 3.97280231e-03 1.31675503e-02 9.61282478e-03
0.00000000e+00 1.73295741e-02 3.53395497e-03 1.06203582e-02
1.36906165e-03 8.64587777e-03 1.12049516e-02 3.18891993e-03
9.28265221e-03 2.25294315e-02 3.24795656e-03 9.16555333e-03
5.68412465e-02 6.79686311e-03 6.37474649e-03 6.04696712e-03
0.00000000e+00 8.51131034e-03 0.00000000e+00 1.09336777e-03
1.49885187e-02 1.09327367e-04 3.73928902e-02 0.00000000e+00
1.74638522e-02 8.21101864e-03 5.79876899e-03 1.34905262e-02
1.71525132e-02 2.25425503e-02 1.04184903e-02 1.05537922e-02
1.34096247e-02 2.82760533e-03 4.31713918e-04 7.39114668e-03
0.00000000e+00 2.21328121e-05 8.79050007e-03 7.08148889e-03
5.88651144e-03 7.45401425e-03 5.66098580e-03 2.80738199e-02
2.41472197e-03 1.00673881e-02 2.29910658e-03 3.23790630e-02
3.02136064e-03 2.25030440e-03 3.53325357e-03 6.90672383e-03
1.01692058e-02 1.03783022e-02 1.22476413e-02 4.82453065e-03
1.15878890e-02 3.41943633e-03 1.57958469e-03 6.56648121e-03
1.28152141e-02 0.00000000e+00 1.29192164e-03 9.35867476e-03
3.89329603e-03 1.78002682e-03 2.81987911e-02 0.00000000e+00
1.74943514e-02 6.24079508e-03 1.57572103e-02 3.77119257e-02
4.78552984e-03 3.30463136e-04 5.60118687e-03 5.75656186e-03
2.65412905e-02 1.59663210e-02 2.88844192e-02 0.00000000e+00
7.87754853e-04 1.76957899e-02 3.19907905e-02 1.94650690e-02
1.32052233e-02 3.57577093e-03 7.09968545e-04 8.70787481e-03
1.24901391e-04 2.61215462e-02 2.25923034e-02 1.10928239e-02
9.39210737e-03 5.61073138e-04 1.59987179e-02 3.02799309e-03]
[ 0.01047704 0.00916079 0.00329728 0.02183509 0. 0.00570515
0.01795154 0.00745325 0.01556352 0.02103068 0.00766733 0.0017898
0.00477604 0.02075469 0.00596795 0.00777273 0.00486571 0.00922539
0.00947171 0.00808096 0.00159634 0.00039577 0. 0.00170102
0.01221233 0.00105577 0.00499953 0. 0.00104692 0.02124238
0.00460677 0.02377163 0.03682221 0.00788995 0.01588396 0.01090949
0.01738658 0.00629269 0.00252249 0.01494837 0. 0.00118236
0.00086828 0.04746846 0.01541295 0.00777287 0.00014366 0.01079173
0.00025071 0.0110701 0.0041122 0.00931269 0.0003396 0.00085525
0.00715489 0.01178172 0.01968206 0.00086696 0.01155932 0.01291423
0.03650986 0.00409654 0.00635913 0.02706258 0.01329375 0. 0.004781
0.00393831 0.0159743 0.01175119 0.01924371 0. 0.01624875
0.01213196 0.01327894 0.02122698 0.01120801 0.00261826 0.01197119
0.01071532 0.01065604 0.00891656 0.00394593 0. 0.00519856
0.00013063 0.00206336 0.01471883 0.02029324 0.00793793 0.00560927
0.00944371 0.00205155 0.01610597 0.009506 0.0211548 0.01688137
0.00731456 0.0175582 0.02643281]
References
----------
......@@ -651,31 +643,23 @@ def trust_transitivity(g, trust_map, source=None, target=None, vprop=None):
>>> trust.a = random(g.num_edges())
>>> t = gt.trust_transitivity(g, trust, source=g.vertex(0))
>>> print t.a
[ 1.00000000e+00 9.59916062e-02 4.27717883e-02 7.70755875e-02
0.00000000e+00 2.04476926e-01 5.55315822e-02 2.82854665e-02
5.08479257e-02 1.68128402e-01 3.28567434e-02 7.39525583e-02
1.34463196e-01 8.83740756e-02 1.79990535e-01 7.08809615e-02
6.37757645e-02 7.24187957e-02 4.83082241e-02 9.90676983e-02
0.00000000e+00 6.50497060e-02 0.00000000e+00 1.77344948e-02
1.08677897e-01 1.00958718e-03 4.49524961e-02 0.00000000e+00
1.64902280e-01 4.31492976e-02 2.19446085e-01 3.00890381e-02
6.86750847e-02 2.72460575e-02 3.57314594e-02 4.87776483e-02
4.11748930e-01 7.91396467e-02 2.54835127e-03 3.01711432e-01
0.00000000e+00 4.14406224e-04 4.24794624e-02 9.14096554e-02
4.17528677e-01 3.79112573e-02 1.16489950e-01 5.18112902e-02
8.49111259e-03 5.26399996e-02 2.45690139e-02 7.51435125e-02
5.62381854e-02 2.90115777e-02 2.72543383e-02 1.46877163e-01
7.81446822e-02 1.24417763e-02 1.01337976e-01 9.92776442e-02
3.14622176e-02 1.20097319e-01 3.30335980e-02 4.61757040e-02
1.01085599e-01 0.00000000e+00 4.44660446e-03 6.31066845e-02
1.94702084e-02 8.45343379e-04 4.82190327e-02 0.00000000e+00
6.60346087e-02 7.44581695e-02 6.19535229e-02 1.82072422e-01
1.45366611e-02 2.59020075e-02 2.52208295e-02 6.80519730e-02
6.74671969e-02 1.14198914e-01 5.12493343e-02 0.00000000e+00
6.33427008e-03 1.42290348e-01 6.90459437e-02 1.00565411e-01
5.88966867e-02 3.28157280e-02 2.80046903e-02 2.41520032e-01
8.45879329e-04 6.76633672e-02 6.05080467e-02 9.12575826e-02
1.97789973e-02 6.40885493e-02 4.80934526e-02 1.28787181e-02]
[ 1. 0.05067451 0.0289009 0.08405839 0. 0.03545782
0.07538031 0.22379499 0.05854478 0.07125532 0.05587198 0.02518448
0.02466963 0.15362921 0.06018343 0.05567524 0.27358358 0.05275904
0.03729045 0.09492006 0.05238415 0.00737096 0. 0.00510552
0.08817629 0.03785795 0.02446122 0. 0.00738919 0.05119031
0.34527065 0.03114924 0.07197484 0.47425602 0.03472084 0.04662672
0.05560849 0.02364994 0.01215894 0.31788601 0. 0.03879942
0.01857147 0.06889803 0.04377159 0.08730759 0.00246369 0.39098931
0.0046694 0.04502054 0.02463968 0.02645761 0.00707666 0.00472783
0.02984028 0.1148617 0.0572029 0.00675625 0.02800698 0.12556046
0.08124247 0.05626964 0.06027068 0.04269226 0.07518783 0.
0.02654427 0.013547 0.35126413 0.05338214 0.02683736 0.
0.03967174 0.15764245 0.03434911 0.06712879 0.01081633 0.01438191
0.22453002 0.13426137 0.11622003 0.18696878 0.02270863 0.
0.09096154 0.00622639 0.01807092 0.06891202 0.05429632 0.03123112
0.04239384 0.06347529 0.00980117 0.08103904 0.06022526 0.09774797
0.0442361 0.03511221 0.09291923 0.10395899]
References
----------
......
......@@ -115,7 +115,7 @@ def local_clustering(g, prop=None, undirected=True):
>>> g = gt.random_graph(1000, lambda: (5,5))
>>> clust = gt.local_clustering(g)
>>> print gt.vertex_average(g, clust)
(0.00908888888888889, 0.0004449824521439575)
(0.008338888888888889, 0.0004126098432127491)
References
----------
......@@ -172,7 +172,7 @@ def global_clustering(g):
>>> seed(42)
>>> g = gt.random_graph(1000, lambda: (5,5))
>>> print gt.global_clustering(g)
(0.009114059777509717, 0.0004464454368899158)
(0.008353381448810478, 0.00041351594365452094)
References
----------
......@@ -247,11 +247,11 @@ def extended_clustering(g, props=None, max_depth=3, undirected=False):
>>> for i in xrange(0, 5):
... print gt.vertex_average(g, clusts[i])
...
(0.0058850000000000005, 0.0004726257592782405)
(0.026346666666666668, 0.0009562588213100747)
(0.11638833333333333, 0.002086419787711849)
(0.3862533333333333, 0.003020064612995335)
(0.44685499999999995, 0.003124572962377774)
(0.0061200000000000004, 0.0004859481453817887)
(0.024368333333333332, 0.0009455588573842338)
(0.11548333333333334, 0.0020091290954595783)
(0.3999433333333333, 0.0030720255912562527)
(0.43571666666666664, 0.0031127199163718177)
References
----------
......@@ -324,7 +324,7 @@ def motifs(g, k, p=1.0, motif_list=None):
>>> print len(motifs)
11
>>> print counts
[115104, 389090, 724, 820, 1828, 3208, 791, 4, 12, 12, 3]
[116256, 392719, 335, 380, 2954, 850, 808, 1, 11, 4, 1]
References
......@@ -489,7 +489,7 @@ def motif_significance(g, k, n_shuffles=100, p=1.0, motif_list=None,
>>> print len(motifs)
11
>>> print zscores
[0.014875553792545083, 0.016154998074953769, 0.002455801898331304, -1.9579019397305546, 0.83542298414538518, 0.84715258999068244, -0.93385230436820643, -0.11, -0.1, -0.31, -0.14]
[0.37033485499317503, 0.2502032768488251, 0.11813557960717248, -0.64062741073137097, -0.6280946022901569, -0.36863102213820809, 0.54809736376108453, 1.89, 0.87, -0.48, -0.19]
"""
s_ms, counts = motifs(g, k, p, motif_list)
......
......@@ -109,7 +109,7 @@ def assortativity(g, deg):
... lambda i,k: 1.0 / (1 + abs(i - k)), directed=False,
... mix_time=100)
>>> gt.assortativity(g, "out")
(0.12973425402803934, 0.004896761863480971)
(0.15024063611634234, 0.0051996387349654925)
References
----------
......@@ -179,12 +179,13 @@ def scalar_assortativity(g, deg):
>>> g = gt.random_graph(1000, lambda: sample_k(40), lambda i,k: abs(i-k),
... directed=False, mix_time=100)
>>> gt.scalar_assortativity(g, "out")
(-0.3786743856734846, 0.01193890427539548)
(-0.4569707008340512, 0.010227503673605132)
>>> g = gt.random_graph(1000, lambda: sample_k(40),
... lambda i, k: 1.0 / (1 + abs(i - k)),
... directed=False, mix_time=100)
>>> gt.scalar_assortativity(g, "out")
(0.551341394873777, 0.012430151900034204)
(0.5921961942149022, 0.011625836226217939)
References
----------
......
......@@ -45,8 +45,10 @@ Contents
from .. dl_import import dl_import
dl_import("import libgraph_tool_generation")
from .. import Graph, GraphView, _check_prop_scalar, _prop, _limit_args
from .. import Graph, GraphView, _check_prop_scalar, _prop, _limit_args, _gt_type
from .. stats import label_parallel_edges, label_self_loops
import inspect
import types
import sys, numpy, numpy.random
__all__ = ["random_graph", "random_rewire", "predecessor_tree", "line_graph",
......@@ -55,8 +57,8 @@ __all__ = ["random_graph", "random_rewire", "predecessor_tree", "line_graph",
def random_graph(N, deg_sampler, deg_corr=None, directed=True,
parallel_edges=False, self_loops=False, random=True,
mix_time=10, verbose=False):
parallel_edges=False, self_loops=False, blockmodel=None,
random=True, mix_time=10, verbose=False):
r"""
Generate a random graph, with a given degree distribution and correlation.
......@@ -70,32 +72,54 @@ def random_graph(N, deg_sampler, deg_corr=None, directed=True,
a single int for undirected graphs, representing the out-degree). This
function is called once per vertex, but may be called more times, if the
degree sequence cannot be used to build a graph.
deg_corr : function (optional, default: None)
Optionally, you can also pass a function which receives one argument. In
this case the argument passed will be the index of the vertex which will
receive the degree. If ``blockmodel != None``, the value passed will be
the block value of the respective vertex instead.
deg_corr : function (optional, default: ``None``)
A function which gives the degree correlation of the graph. It should be
callable with two parameters: the in,out-degree pair of the source
vertex an edge, and the in,out-degree pair of the target of the same
edge (for undirected graphs, both parameters are single values). The
function should return a number proportional to the probability of such
an edge existing in the generated graph.
directed : bool (optional, default: True)
If ``blockmodel != None``, the value passed to the function will be the
block value of the respective vertices, not the in/out-degree pairs.
directed : bool (optional, default: ``True``)
Whether the generated graph should be directed.
parallel_edges : bool (optional, default: False)
If True, parallel edges are allowed.
self_loops : bool (optional, default: False)
If True, self-loops are allowed.
random : bool (optional, default: True)
If True, the returned graph is randomized.
mix_time : int (optional, default: 10)
parallel_edges : bool (optional, default: ``False``)
If ``True``, parallel edges are allowed.
self_loops : bool (optional, default: ``False``)
If ``True``, self-loops are allowed.
blockmodel : list or :class:`~numpy.ndarray` or function (optional, default: ``None``)
If supplied, the graph will be sampled from a blockmodel ensemble. If
the value is a list or a :class:`~numpy.ndarray`, it must have
``len(block_model) == N``, and the values will define to which block
each vertex belongs.
If this value is a function, it will be used to sample the block
types. It must be callable either with no arguments or with a single
argument which will be the vertex index. In either case it must return
an integer.
random : bool (optional, default: ``True``)
If ``True``, the returned graph is randomized. Otherwise a deterministic
placement of the edges will be used.
mix_time : int (optional, default: ``10``)
Number of edge sweeps to perform in order to mix the graph. This value
is ignored if ``parallel_edges == self_loops == True`` and
``strat != "probabilistic"``.
verbose : bool (optional, default: False)