/*
* this implements the resistor circuit current model for
* computing node distance, as an alternative to shortest-path.
* likely it could be improved by using edge weights, somehow.
* Return 1 if successful; 0 otherwise (e.g., graph is disconnected).
*/
#include "neato.h"
int circuit_model(graph_t *g, int nG)
{
double **Gm, **Gm_inv, sum;
int i, j;
node_t *v;
edge_t *e;
if (Verbose) fprintf (stderr, "Calculating circuit model\n");
Gm = new_array(nG, nG, 0.0);
Gm_inv = new_array(nG, nG, 0.0);
/* set non-diagonal entries */
for (v = agfstnode(g); v; v = agnxtnode(g,v)) {
for (e = agfstedge(g,v); e; e = agnxtedge(g,e,v)) {
i = ND_id(e->tail);
j = ND_id(e->head);
if (i == j) continue;
/* conductance is 1/resistance */
Gm[i][j] = Gm[j][i] = -1.0 / ED_dist(e); /* negate */
}
}
/* set diagonal entries to sum of conductances but ignore nth node */
for (i = 0; i < nG ; i++) {
sum = 0.0;
for (j = 0; j < nG ; j++)
if (i != j) sum += Gm[i][j];
Gm[i][i] = -sum;
}
if (!matinv(Gm, Gm_inv, nG - 1)) return 0;
for (i = 0; i < nG ; i++) {
for (j = 0; j < nG ; j++) {
GD_dist(g)[i][j] = Gm_inv[i][i] + Gm_inv[j][j] - 2.0 * Gm_inv[i][j];
}
}
return 1;
}
|