Skip to content

Commit

Permalink
Add iindex function
Browse files Browse the repository at this point in the history
  • Loading branch information
russellfunk committed Jul 20, 2017
1 parent a781dcc commit c17a25f
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 73 deletions.
25 changes: 25 additions & 0 deletions cdindex/cdindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,31 @@ def mcdindex(self, name, t_delta):
self._vertex_name_crosswalk[name],
t_delta)

def iindex(self, name, t_delta):
"""Compute the I index.
This function computes the I index for a specified vertex at a given
t_delta, where t_delta is an integer that gives the positive distance in
time from the timestamp of the focal node when the index should be
calculated. The I index is the in degree of the focal node at time t.
Parameters
----------
t_delta : int
A time delta.
Returns
-------
double
The I index.
"""
if isinstance(t_delta, (long, int)) is False:
raise ValueError("Time delta (t_delta) must be an integer or long")
return _cdindex.iindex(self._graph,
self._vertex_name_crosswalk[name],
t_delta)


def _is_graph_sane(self):
"""Test graph sanity.
Expand Down
77 changes: 49 additions & 28 deletions cdindex/pycdindex.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ static PyObject *py_free_graph(PyObject *self, PyObject *args) {
* Add a vertex to the graph *
******************************************************************************/
static PyObject *py_add_vertex(PyObject *self, PyObject *args) {
int ID;
long long int ID;
long long int TIMESTAMP;
Graph *g;
PyObject *py_g;

if (!PyArg_ParseTuple(args,"OiL",&py_g, &ID, &TIMESTAMP))
if (!PyArg_ParseTuple(args,"OLL",&py_g, &ID, &TIMESTAMP))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;
Expand All @@ -100,11 +100,11 @@ static PyObject *py_add_vertex(PyObject *self, PyObject *args) {
* Add an edge to the graph *
******************************************************************************/
static PyObject *py_add_edge(PyObject *self, PyObject *args) {
int SOURCE_ID, TARGET_ID;
long long int SOURCE_ID, TARGET_ID;
Graph *g;
PyObject *py_g;

if (!PyArg_ParseTuple(args,"Oii",&py_g, &SOURCE_ID, &TARGET_ID))
if (!PyArg_ParseTuple(args,"OLL",&py_g, &SOURCE_ID, &TARGET_ID))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;
Expand All @@ -126,7 +126,7 @@ static PyObject *py_get_vcount(PyObject *self, PyObject *args) {
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;

return Py_BuildValue("i", g->vcount);
return Py_BuildValue("L", g->vcount);
}

/*******************************************************************************
Expand All @@ -144,8 +144,8 @@ static PyObject *py_get_vertices(PyObject *self, PyObject *args) {

PyObject *vs_list = PyList_New(g->vcount);

for (int i = 0; i < g->vcount; i++) {
id = Py_BuildValue("i", g->vs[i].id);
for (long long int i = 0; i < g->vcount; i++) {
id = Py_BuildValue("L", g->vs[i].id);
PyList_SetItem(vs_list, i, id);
}

Expand All @@ -165,19 +165,19 @@ static PyObject *py_get_ecount(PyObject *self, PyObject *args) {
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;

return Py_BuildValue("i", g->ecount);
return Py_BuildValue("L", g->ecount);
}

/*******************************************************************************
* Get a vertex timestamp *
******************************************************************************/
static PyObject *py_get_vertex_timestamp(PyObject *self, PyObject *args) {
int ID;
long long int ID;

Graph *g;
PyObject *py_g;

if (!PyArg_ParseTuple(args,"Oi",&py_g, &ID))
if (!PyArg_ParseTuple(args,"OL",&py_g, &ID))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;
Expand All @@ -189,37 +189,37 @@ static PyObject *py_get_vertex_timestamp(PyObject *self, PyObject *args) {
* Get a vertex in degree *
******************************************************************************/
static PyObject *py_get_vertex_in_degree(PyObject *self, PyObject *args) {
int ID;
long long int ID;

Graph *g;
PyObject *py_g;

if (!PyArg_ParseTuple(args,"Oi",&py_g, &ID))
if (!PyArg_ParseTuple(args,"OL",&py_g, &ID))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;

return Py_BuildValue("i", g->vs[ID].in_degree);
return Py_BuildValue("L", g->vs[ID].in_degree);
}

/*******************************************************************************
* Get the in edges of a vertex *
******************************************************************************/
static PyObject *py_get_vertex_in_edges(PyObject *self, PyObject *args) {

int ID;
long long int ID;
Graph *g;
PyObject *py_g, *source_id;

if (!PyArg_ParseTuple(args,"Oi",&py_g, &ID))
if (!PyArg_ParseTuple(args,"OL",&py_g, &ID))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;

PyObject *vs_list = PyList_New(g->vs[ID].in_degree);

for (int i = 0; i < g->vs[ID].in_degree; i++) {
source_id = Py_BuildValue("i", g->vs[ID].in_edges[i]);
for (long long int i = 0; i < g->vs[ID].in_degree; i++) {
source_id = Py_BuildValue("L", g->vs[ID].in_edges[i]);
PyList_SetItem(vs_list, i, source_id);
}

Expand All @@ -230,37 +230,37 @@ static PyObject *py_get_vertex_in_edges(PyObject *self, PyObject *args) {
* Get a vertex out degree *
******************************************************************************/
static PyObject *py_get_vertex_out_degree(PyObject *self, PyObject *args) {
int ID;
long long int ID;

Graph *g;
PyObject *py_g;

if (!PyArg_ParseTuple(args,"Oi",&py_g, &ID))
if (!PyArg_ParseTuple(args,"OL",&py_g, &ID))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;

return Py_BuildValue("i", g->vs[ID].out_degree);
return Py_BuildValue("L", g->vs[ID].out_degree);
}

/*******************************************************************************
* Get the out edges of a vertex *
******************************************************************************/
static PyObject *py_get_vertex_out_edges(PyObject *self, PyObject *args) {

int ID;
long long int ID;
Graph *g;
PyObject *py_g, *target_id;

if (!PyArg_ParseTuple(args,"Oi",&py_g, &ID))
if (!PyArg_ParseTuple(args,"OL",&py_g, &ID))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;

PyObject *vs_list = PyList_New(g->vs[ID].out_degree);

for (int i = 0; i < g->vs[ID].out_degree; i++) {
target_id = Py_BuildValue("i", g->vs[ID].out_edges[i]);
for (long long int i = 0; i < g->vs[ID].out_degree; i++) {
target_id = Py_BuildValue("L", g->vs[ID].out_edges[i]);
PyList_SetItem(vs_list, i, target_id);
}

Expand All @@ -271,14 +271,14 @@ static PyObject *py_get_vertex_out_edges(PyObject *self, PyObject *args) {
* Compute the CD index *
******************************************************************************/
static PyObject *py_cdindex(PyObject *self, PyObject *args) {
int ID;
long long int ID;
long long int TIMESTAMP;

double result;
Graph *g;
PyObject *py_g;

if (!PyArg_ParseTuple(args,"OiL",&py_g, &ID, &TIMESTAMP))
if (!PyArg_ParseTuple(args,"OLL",&py_g, &ID, &TIMESTAMP))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;
Expand All @@ -291,13 +291,13 @@ static PyObject *py_cdindex(PyObject *self, PyObject *args) {
* Compute the mCD index *
******************************************************************************/
static PyObject *py_mcdindex(PyObject *self, PyObject *args) {
int ID;
long long int ID;
long long int TIMESTAMP;
double result;
Graph *g;
PyObject *py_g;

if (!PyArg_ParseTuple(args,"OiL",&py_g, &ID, &TIMESTAMP))
if (!PyArg_ParseTuple(args,"OLL",&py_g, &ID, &TIMESTAMP))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;
Expand All @@ -306,6 +306,26 @@ static PyObject *py_mcdindex(PyObject *self, PyObject *args) {
return Py_BuildValue("d", result);
}

/*******************************************************************************
* Compute the I index *
******************************************************************************/
static PyObject *py_iindex(PyObject *self, PyObject *args) {
long long int ID;
long long int TIMESTAMP;
double result;
Graph *g;
PyObject *py_g;

if (!PyArg_ParseTuple(args,"OLL",&py_g, &ID, &TIMESTAMP))
return NULL;
if (!(g = PyGraph_AsGraph(py_g)))
return NULL;

result = iindex(g, ID, TIMESTAMP);
return Py_BuildValue("d", result);
}


/*******************************************************************************
* Module method table *
******************************************************************************/
Expand All @@ -325,6 +345,7 @@ static PyMethodDef CDIndexMethods[] = {
{"get_vertex_out_edges", py_get_vertex_out_edges, METH_VARARGS, "Get the out edges of a vertex"},
{"cdindex", py_cdindex, METH_VARARGS, "Compute the CD index"},
{"mcdindex", py_mcdindex, METH_VARARGS, "Compute the mCD index"},
{"iindex", py_mcdindex, METH_VARARGS, "Compute the I index"},
{ NULL, NULL, 0, NULL}
};

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def __getattr__(cls, name):
# The short X.Y version.
version = u'1.0'
# The full version, including alpha/beta/rc tags.
release = u'1.0.5'
release = u'1.0.6'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from setuptools import setup, Extension, find_packages

setup(name="cdindex",
version="1.0.5",
version="1.0.6",
description="Package for computing the cdindex.",
author="Russell J. Funk",
author_email="russellfunk@gmail.com",
Expand Down
55 changes: 41 additions & 14 deletions src/cdindex.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,27 @@
*
* \return The value of the CD index.
*/
double cdindex(Graph *graph, int id, long long int time_delta){
double cdindex(Graph *graph, long long int id, long long int time_delta){

/* Build a list of "it" vertices that are "in_edges" of the focal vertex's
"out_edges" as of timestamp t. Vertices in the list are unique. */

int it_count = 0;
int *it = malloc(sizeof(int));
long long int it_count = 0;
long long int *it = malloc(sizeof(long long int));

/* check for malloc problems */
if (it==NULL) {
raise_error(0);
}

/* define i for multiple loops */
int i;
long long int i;

/* add unique "in_edges" of focal vertex "out_edges" */
for (i = 0; i < graph->vs[id].out_degree; i++) {
int out_edge_i = graph->vs[id].out_edges[i];
for (int j = 0; j < graph->vs[out_edge_i].in_degree; j++) {
int out_edge_i_in_edge_j = graph->vs[out_edge_i].in_edges[j];
long long int out_edge_i = graph->vs[id].out_edges[i];
for (long long int j = 0; j < graph->vs[out_edge_i].in_degree; j++) {
long long int out_edge_i_in_edge_j = graph->vs[out_edge_i].in_edges[j];
if (graph->vs[out_edge_i_in_edge_j].timestamp > graph->vs[id].timestamp &&
graph->vs[out_edge_i_in_edge_j].timestamp < (graph->vs[id].timestamp + time_delta) &&
!in_int_array(it, it_count, out_edge_i_in_edge_j)) {
Expand All @@ -62,7 +62,7 @@ double cdindex(Graph *graph, int id, long long int time_delta){

/* add unique "in_edges" of focal vertex */
for (i = 0; i < graph->vs[id].in_degree; i++) {
int in_edge_i = graph->vs[id].in_edges[i];
long long int in_edge_i = graph->vs[id].in_edges[i];
if (graph->vs[in_edge_i].timestamp > graph->vs[id].timestamp &&
graph->vs[in_edge_i].timestamp < (graph->vs[id].timestamp + time_delta) &&
!in_int_array(it, it_count, in_edge_i)) {
Expand All @@ -74,9 +74,9 @@ double cdindex(Graph *graph, int id, long long int time_delta){
/* compute the cd index */
double sum_i = 0.0;
for (i = 0; i < it_count; i++) {
int f_it = in_int_array(graph->vs[it[i]].out_edges, graph->vs[it[i]].out_degree, id);
int b_it = 0;
for (int j = 0; j < graph->vs[it[i]].out_degree; j++) {
long long int f_it = in_int_array(graph->vs[it[i]].out_edges, graph->vs[it[i]].out_degree, id);
long long int b_it = 0;
for (long long int j = 0; j < graph->vs[it[i]].out_degree; j++) {
if (in_int_array(graph->vs[id].out_edges, graph->vs[id].out_degree, graph->vs[it[i]].out_edges[j])) {
b_it = 1;
}
Expand All @@ -88,19 +88,46 @@ double cdindex(Graph *graph, int id, long long int time_delta){
return sum_i/it_count;
}

/**
* \function iindex
* \brief Computes the I Index (i.e., the in degree of the focal vertex at time t).
*
* \param graph The input graph.
* \param id The focal vertex id.
* \param time_delta Time beyond stamp of focal vertex to consider in computing the measure.
*
* \return The value of the I index.
*/
long long int iindex(Graph *graph, long long int id, long long int time_delta){

/* count mt vertices that are "in_edges" of the focal vertex as of timestamp t. */
long long int mt_count = 0;
for (long long int i = 0; i < graph->vs[id].in_degree; i++) {
long long int in_edge_i = graph->vs[id].in_edges[i];
if (graph->vs[in_edge_i].timestamp > graph->vs[id].timestamp &&
graph->vs[in_edge_i].timestamp < (graph->vs[id].timestamp + time_delta)) {
mt_count++;
}
}

return mt_count;
}

/**
* \function mcdindex
* \brief Computes the mCD Index.
*
* \param graph The input graph.
* \param id The focal vertex id.
* \param time_delta Time beyond stamp of focal vertex to consider in measure.
* \param time_delta Time beyond stamp of focal vertex to consider in computing the measure.
*
* \return The value of the mCD index.
*/
double mcdindex(Graph *graph, int id, long long int time_delta){
double mcdindex(Graph *graph, long long int id, long long int time_delta){

double cdindex_value = cdindex(graph, id, time_delta);
return cdindex_value * graph->vs[id].in_degree;
long long int iindex_value = iindex(graph, id, time_delta);

return cdindex_value * iindex_value;

}

0 comments on commit c17a25f

Please sign in to comment.