/* -*- mode: C -*- */
/*
IGraph R package.
Copyright (C) 2005 Gabor Csardi <csardi@rmki.kfki.hu>
MTA RMKI, Konkoly-Thege Miklos st. 29-33, Budapest 1121, Hungary
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 "igraph.h"
#include "memory.h"
int igraph_cocitation_real(const igraph_t *graph, igraph_matrix_t *res,
igraph_vs_t vids,
igraph_neimode_t mode);
/**
* \ingroup structural
* \function igraph_cocitation
* \brief Cocitation coupling.
*
* </para><para>
* Two vertices are cocited if there is another vertex citing both of
* them. \ref igraph_cocitation() simply counts how many types two vertices are
* cocited.
* The cocitation score for each given vertex and all other vertices
* in the graph will be calculated.
* \param graph The graph object to analyze.
* \param res Pointer to a matrix, the result of the calculation will
* be stored here. The number of its rows is the same as the
* number of vertex ids in \p vids, the number of
* columns is the number of vertices in the graph.
* \param vids The vertex ids of the vertices for which the
* calculation will be done.
* \return Error code:
* \c IGRAPH_EINVVID: invalid vertex id.
*
* Time complexity: O(|V|d^2), |V| is
* the number of vertices in the graph,
* d is the (maximum) degree of
* the vertices in the graph.
*
* \sa \ref igraph_bibcoupling()
*/
int igraph_cocitation(const igraph_t *graph, igraph_matrix_t *res,
igraph_vs_t vids) {
return igraph_cocitation_real(graph, res, vids, IGRAPH_OUT);
}
/**
* \ingroup structural
* \function igraph_bibcoupling
* \brief Bibliographic coupling.
*
* </para><para>
* The bibliographic coupling of two vertices is the number
* of other vertices they both cite, \ref igraph_bibcoupling() calculates
* this.
* The bibliographic coupling score for each given vertex and all
* other vertices in the graph will be calculated.
* \param graph The graph object to analyze.
* \param res Pointer to a matrix, the result of the calculation will
* be stored here. The number of its rows is the same as the
* number of vertex ids in \p vids, the number of
* columns is the number of vertices in the graph.
* \param vids The vertex ids of the vertices for which the
* calculation will be done.
* \return Error code:
* \c IGRAPH_EINVVID: invalid vertex id.
*
* Time complexity: O(|V|d^2),
* |V| is the number of vertices in
* the graph, d is the (maximum)
* degree of the vertices in the graph.
*
* \sa \ref igraph_cocitation()
*/
int igraph_bibcoupling(const igraph_t *graph, igraph_matrix_t *res,
igraph_vs_t vids) {
return igraph_cocitation_real(graph, res, vids, IGRAPH_IN);
}
int igraph_cocitation_real(const igraph_t *graph, igraph_matrix_t *res,
igraph_vs_t vids,
igraph_neimode_t mode) {
long int no_of_nodes=igraph_vcount(graph);
long int from, i, j;
igraph_bool_t *calc;
igraph_matrix_t tmpres=IGRAPH_MATRIX_NULL;
igraph_vector_t neis=IGRAPH_VECTOR_NULL;
igraph_vit_t vit;
IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit));
IGRAPH_FINALLY(igraph_vit_destroy, &vit);
calc=Calloc(no_of_nodes, igraph_bool_t);
if (calc==0) {
IGRAPH_ERROR("cannot calculate cocitation/bibcoupling", IGRAPH_ENOMEM);
}
IGRAPH_FINALLY(free, calc); /* TODO: hack */
for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) {
calc[ (long int) IGRAPH_VIT_GET(vit) ] = 1;
}
IGRAPH_MATRIX_INIT_FINALLY(&tmpres, no_of_nodes, no_of_nodes);
IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);
IGRAPH_CHECK(igraph_matrix_resize(res, IGRAPH_VIT_SIZE(vit), no_of_nodes));
/* The result */
for (from=0; from<no_of_nodes; from++) {
IGRAPH_ALLOW_INTERRUPTION();
IGRAPH_CHECK(igraph_neighbors(graph, &neis, from, mode));
for (i=0; i < igraph_vector_size(&neis)-1; i++) {
if (calc[ (long int)VECTOR(neis)[i] ]) {
for (j=i+1; j<igraph_vector_size(&neis); j++) {
MATRIX(tmpres, (long int)VECTOR(neis)[i],
(long int)VECTOR(neis)[j]) += 1;
MATRIX(tmpres, (long int)VECTOR(neis)[j],
(long int)VECTOR(neis)[i]) += 1;
}
}
}
}
/* Copy result */
for (IGRAPH_VIT_RESET(vit), i=0;
!IGRAPH_VIT_END(vit);
IGRAPH_VIT_NEXT(vit), i++) {
for (j=0; j<no_of_nodes; j++) {
MATRIX(*res, i, j) = MATRIX(tmpres, (long int) IGRAPH_VIT_GET(vit), j);
}
}
/* Clean up */
igraph_matrix_destroy(&tmpres);
igraph_vector_destroy(&neis);
Free(calc);
igraph_vit_destroy(&vit);
IGRAPH_FINALLY_CLEAN(4);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1