Skip to content

Commit ef0659d

Browse files
committed
Merge branch '0.7-prpack' into develop
Conflicts: interfaces/R/types-C.def interfaces/R/types-R.def src/Makefile.am
2 parents 873cee1 + 2589450 commit ef0659d

File tree

4 files changed

+91
-16
lines changed

4 files changed

+91
-16
lines changed

igraph/__init__.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,8 @@ def path_length_hist(self, directed=True):
768768
return hist
769769

770770
def pagerank(self, vertices=None, directed=True, damping=0.85,
771-
weights=None, arpack_options=None):
771+
weights=None, arpack_options=None, implementation="prpack",
772+
niter=1000, eps=0.001):
772773
"""Calculates the Google PageRank values of a graph.
773774
774775
@param vertices: the indices of the vertices being queried.
@@ -781,13 +782,30 @@ def pagerank(self, vertices=None, directed=True, damping=0.85,
781782
or even an edge attribute name.
782783
@param arpack_options: an L{ARPACKOptions} object used to fine-tune
783784
the ARPACK eigenvector calculation. If omitted, the module-level
784-
variable called C{arpack_options} is used.
785+
variable called C{arpack_options} is used. This argument is
786+
ignored if not the ARPACK implementation is used, see the
787+
I{implementation} argument.
788+
@param implementation: which implementation to use to solve the
789+
PageRank eigenproblem. Possible values are:
790+
- C{"prpack"}: use the PRPACK library. This is a new
791+
implementation in igraph 0.7
792+
- C{"arpack"}: use the ARPACK library. This implementation
793+
was used from version 0.5, until version 0.7.
794+
- C{"power"}: use a simple power method. This is the
795+
implementation that was used before igraph version 0.5.
796+
@param niter: The number of iterations to use in the power method
797+
implementation. It is ignored in the other implementations
798+
@param eps: The power method implementation will consider the
799+
calculation as complete if the difference of PageRank values between
800+
iterations change less than this value for every node. It is
801+
ignored by the other implementations.
785802
@return: a list with the Google PageRank values of the specified
786803
vertices."""
787804
if arpack_options is None:
788805
arpack_options = _igraph.arpack_options
789-
return self.personalized_pagerank(vertices, directed, damping, None, \
790-
None, weights, arpack_options)
806+
return self.personalized_pagerank(vertices, directed, damping, None,\
807+
None, weights, arpack_options, \
808+
implementation, niter, eps)
791809

792810
def spanning_tree(self, weights=None, return_tree=True):
793811
"""Calculates a minimum spanning tree for a graph.

src/convert.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2880,3 +2880,19 @@ int igraphmodule_PyObject_to_attribute_combination_t(PyObject* object,
28802880
return 0;
28812881
}
28822882

2883+
/**
2884+
* \ingroup python_interface_conversion
2885+
* \brief Converts a Python object to an igraph \c igraph_pagerank_algo_t
2886+
*/
2887+
int igraphmodule_PyObject_to_pagerank_algo_t(PyObject *o,
2888+
igraph_pagerank_algo_t *result) {
2889+
static igraphmodule_enum_translation_table_entry_t pagerank_algo_tt[] = {
2890+
{"prpack", IGRAPH_PAGERANK_ALGO_PRPACK},
2891+
{"arpack", IGRAPH_PAGERANK_ALGO_ARPACK},
2892+
{"power", IGRAPH_PAGERANK_ALGO_POWER},
2893+
{0,0}
2894+
};
2895+
2896+
return igraphmodule_PyObject_to_enum(o, pagerank_algo_tt, (int*)result);
2897+
}
2898+

src/convert.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ int igraphmodule_PyObject_to_connectedness_t(PyObject *o, igraph_connectedness_t
6161
int igraphmodule_PyObject_to_degseq_t(PyObject *o, igraph_degseq_t *result);
6262
int igraphmodule_PyObject_to_fas_algorithm_t(PyObject *o, igraph_fas_algorithm_t *result);
6363
int igraphmodule_PyObject_to_neimode_t(PyObject *o, igraph_neimode_t *result);
64+
int igraphmodule_PyObject_to_pagerank_algo_t(PyObject *o, igraph_pagerank_algo_t *result);
6465
int igraphmodule_PyObject_to_reciprocity_t(PyObject *o, igraph_reciprocity_t *result);
6566
int igraphmodule_PyObject_to_rewiring_t(PyObject *o, igraph_rewiring_t *result);
6667
int igraphmodule_PyObject_to_spinglass_implementation_t(PyObject *o, igraph_spinglass_implementation_t *result);

src/graphobject.c

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4784,7 +4784,7 @@ PyObject *igraphmodule_Graph_personalized_pagerank(igraphmodule_GraphObject *sel
47844784
{
47854785
static char *kwlist[] =
47864786
{ "vertices", "directed", "damping", "reset", "reset_vertices", "weights",
4787-
"arpack_options", NULL };
4787+
"arpack_options", "implementation", "niter", "eps", NULL };
47884788
PyObject *directed = Py_True;
47894789
PyObject *vobj = Py_None, *wobj = Py_None, *robj = Py_None, *rvsobj = Py_None;
47904790
PyObject *list;
@@ -4796,12 +4796,21 @@ PyObject *igraphmodule_Graph_personalized_pagerank(igraphmodule_GraphObject *sel
47964796
igraph_vector_t weights;
47974797
igraph_bool_t return_single = 0;
47984798
igraph_vs_t vs, reset_vs;
4799+
igraph_pagerank_algo_t algo=IGRAPH_PAGERANK_ALGO_PRPACK;
4800+
PyObject *algo_o = Py_None;
4801+
long niter=1000;
4802+
float eps=0.001f;
4803+
igraph_pagerank_power_options_t popts;
4804+
void *opts;
47994805
int retval;
48004806

4801-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOdOOOO!", kwlist, &vobj,
4802-
&directed, &damping, &robj, &rvsobj, &wobj,
4807+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOdOOOO!Oid", kwlist, &vobj,
4808+
&directed, &damping, &robj,
4809+
&rvsobj, &wobj,
48034810
&igraphmodule_ARPACKOptionsType,
4804-
&arpack_options_o))
4811+
&arpack_options_o, &algo_o, &niter, &eps))
4812+
4813+
48054814
return NULL;
48064815

48074816
if (robj != Py_None && rvsobj != Py_None) {
@@ -4814,6 +4823,7 @@ PyObject *igraphmodule_Graph_personalized_pagerank(igraphmodule_GraphObject *sel
48144823
return NULL;
48154824
}
48164825

4826+
arpack_options = (igraphmodule_ARPACKOptionsObject*)arpack_options_o;
48174827
if (robj != Py_None) {
48184828
if (igraphmodule_attrib_to_vector_t(robj, self, &reset, ATTRIBUTE_TYPE_VERTEX)) {
48194829
igraph_vs_destroy(&vs);
@@ -4845,13 +4855,25 @@ PyObject *igraphmodule_Graph_personalized_pagerank(igraphmodule_GraphObject *sel
48454855
return igraphmodule_handle_igraph_error();
48464856
}
48474857

4848-
arpack_options = (igraphmodule_ARPACKOptionsObject*)arpack_options_o;
4858+
if (igraphmodule_PyObject_to_pagerank_algo_t(algo_o, &algo))
4859+
return NULL;
4860+
4861+
popts.niter = (igraph_integer_t) niter; popts.eps = eps;
4862+
4863+
if (algo == IGRAPH_PAGERANK_ALGO_POWER) {
4864+
opts = &popts;
4865+
} else if (algo == IGRAPH_PAGERANK_ALGO_ARPACK) {
4866+
opts = igraphmodule_ARPACKOptions_get(arpack_options);
4867+
} else {
4868+
opts = 0;
4869+
}
4870+
48494871
if (rvsobj != Py_None)
4850-
retval = igraph_personalized_pagerank_vs(&self->g, &res, 0, vs, PyObject_IsTrue(directed),
4851-
damping, reset_vs, &weights, igraphmodule_ARPACKOptions_get(arpack_options));
4872+
retval = igraph_personalized_pagerank_vs(&self->g, algo, &res, 0, vs,
4873+
PyObject_IsTrue(directed), damping, reset_vs, &weights, opts);
48524874
else
4853-
retval = igraph_personalized_pagerank(&self->g, &res, 0, vs, PyObject_IsTrue(directed),
4854-
damping, reset, &weights, igraphmodule_ARPACKOptions_get(arpack_options));
4875+
retval = igraph_personalized_pagerank(&self->g, algo, &res, 0, vs,
4876+
PyObject_IsTrue(directed), damping, reset, &weights, opts);
48554877

48564878
if (retval) {
48574879
igraphmodule_handle_igraph_error();
@@ -12892,8 +12914,10 @@ struct PyMethodDef igraphmodule_Graph_methods[] = {
1289212914
/* interface to igraph_personalized_pagerank */
1289312915
{"personalized_pagerank", (PyCFunction) igraphmodule_Graph_personalized_pagerank,
1289412916
METH_VARARGS | METH_KEYWORDS,
12895-
"personalized_pagerank(vertices=None, directed=True, damping=0.85, "
12896-
"reset=None, reset_vertices=None, weights=None, arpack_options=None)\n\n"
12917+
"personalized_pagerank(vertices=None, directed=True, damping=0.85,\n"
12918+
" reset=None, reset_vertices=None, weights=None, \n"
12919+
" arpack_options=None, implementation=\"prpack\", niter=1000,\n"
12920+
" eps=0.001)\n\n"
1289712921
"Calculates the personalized PageRank values of a graph.\n\n"
1289812922
"The personalized PageRank calculation is similar to the PageRank\n"
1289912923
"calculation, but the random walk is reset to a non-uniform distribution\n"
@@ -12919,7 +12943,23 @@ struct PyMethodDef igraphmodule_Graph_methods[] = {
1291912943
" even an edge attribute name.\n"
1292012944
"@param arpack_options: an L{ARPACKOptions} object used to fine-tune\n"
1292112945
" the ARPACK eigenvector calculation. If omitted, the module-level\n"
12922-
" variable called C{arpack_options} is used.\n"
12946+
" variable called C{arpack_options} is used. This argument is\n"
12947+
" ignored if not the ARPACK implementation is used, see the \n"
12948+
" I{implementation} argument.\n"
12949+
"@param implementation: which implementation to use to solve the \n"
12950+
" PageRank eigenproblem. Possible values are:\n\n"
12951+
" - C{\"prpack\"}: use the PRPACK library. This is a new \n"
12952+
" implementation in igraph 0.7\n\n"
12953+
" - C{\"arpack\"}: use the ARPACK library. This implementation\n"
12954+
" was used from version 0.5, until version 0.7.\n\n"
12955+
" - C{\"power\"}: use a simple power method. This is the\n"
12956+
" implementation that was used before igraph version 0.5.\n\n"
12957+
"@param niter: The number of iterations to use in the power method\n"
12958+
" implementation. It is ignored in the other implementations.\n"
12959+
"@param eps: The power method implementation will consider the\n"
12960+
" calculation as complete if the difference of PageRank values between\n"
12961+
" iterations change less than this value for every node. It is \n"
12962+
" ignored by the other implementations.\n"
1292312963
"@return: a list with the personalized PageRank values of the specified\n"
1292412964
" vertices.\n"},
1292512965

0 commit comments

Comments
 (0)