/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/neatogen/circuit.c

Go to the documentation of this file.
00001 /* $Id: circuit.c,v 1.1.1.1 2004/12/23 04:05:10 ellson Exp $ $Revision: 1.1.1.1 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 /*
00018  * this implements the resistor circuit current model for
00019  * computing node distance, as an alternative to shortest-path.
00020  * likely it could be improved by using edge weights, somehow.
00021  * Return 1 if successful; 0 otherwise (e.g., graph is disconnected).
00022  */
00023 #include        "neato.h"
00024 
00025 int solveCircuit(int nG, double **Gm, double **Gm_inv)
00026 {
00027     double sum;
00028     int i, j;
00029 
00030     if (Verbose)
00031         fprintf(stderr, "Calculating circuit model");
00032 
00033     /* set diagonal entries to sum of conductances but ignore nth node */
00034     for (i = 0; i < nG; i++) {
00035         sum = 0.0;
00036         for (j = 0; j < nG; j++)
00037             if (i != j)
00038                 sum += Gm[i][j];
00039         Gm[i][i] = -sum;
00040     }
00041     return matinv(Gm, Gm_inv, nG - 1);
00042 }
00043 
00044 int circuit_model(graph_t * g, int nG)
00045 {
00046     double **Gm;
00047     double **Gm_inv;
00048     int rv, i, j;
00049     node_t *v;
00050     edge_t *e;
00051 
00052     Gm = new_array(nG, nG, 0.0);
00053     Gm_inv = new_array(nG, nG, 0.0);
00054 
00055     /* set non-diagonal entries */
00056     for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
00057         for (e = agfstedge(g, v); e; e = agnxtedge(g, e, v)) {
00058             i = ND_id(e->tail);
00059             j = ND_id(e->head);
00060             if (i == j)
00061                 continue;
00062             /* conductance is 1/resistance */
00063             Gm[i][j] = Gm[j][i] = -1.0 / ED_dist(e);    /* negate */
00064         }
00065     }
00066 
00067     rv = solveCircuit(nG, Gm, Gm_inv);
00068 
00069     if (rv)
00070         for (i = 0; i < nG; i++) {
00071             for (j = 0; j < nG; j++) {
00072                 GD_dist(g)[i][j] =
00073                     Gm_inv[i][i] + Gm_inv[j][j] - 2.0 * Gm_inv[i][j];
00074             }
00075         }
00076     free_array(Gm);
00077     free_array(Gm_inv);
00078     return rv;
00079 }

Generated on Mon Mar 31 19:03:27 2008 for Graphviz by  doxygen 1.5.1