Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
circuit.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11/*
12 * this implements the resistor circuit current model for
13 * computing node distance, as an alternative to shortest-path.
14 * likely it could be improved by using edge weights, somehow.
15 * Return 1 if successful; 0 otherwise (e.g., graph is disconnected).
16 */
17#include <neatogen/neato.h>
18
19int solveCircuit(int nG, double **Gm, double **Gm_inv)
20{
21 double sum;
22 int i, j;
23
24 if (Verbose)
25 fprintf(stderr, "Calculating circuit model");
26
27 /* set diagonal entries to sum of conductances but ignore nth node */
28 for (i = 0; i < nG; i++) {
29 sum = 0.0;
30 for (j = 0; j < nG; j++)
31 if (i != j)
32 sum += Gm[i][j];
33 Gm[i][i] = -sum;
34 }
35 return matinv(Gm, Gm_inv, nG - 1);
36}
37
38int circuit_model(graph_t * g, int nG)
39{
40 double **Gm;
41 double **Gm_inv;
42 int rv;
43 long i, j;
44 node_t *v;
45 edge_t *e;
46
47 Gm = new_array(nG, nG, 0.0);
48 Gm_inv = new_array(nG, nG, 0.0);
49
50 /* set non-diagonal entries */
51 for (v = agfstnode(g); v; v = agnxtnode(g, v)) {
52 for (e = agfstedge(g, v); e; e = agnxtedge(g, e, v)) {
53 i = AGSEQ(agtail(e));
54 j = AGSEQ(aghead(e));
55 if (i == j)
56 continue;
57 /* conductance is 1/resistance */
58 Gm[i][j] = Gm[j][i] = -1.0 / ED_dist(e); /* negate */
59 }
60 }
61
62 rv = solveCircuit(nG, Gm, Gm_inv);
63
64 if (rv)
65 for (i = 0; i < nG; i++) {
66 for (j = 0; j < nG; j++) {
67 GD_dist(g)[i][j] =
68 Gm_inv[i][i] + Gm_inv[j][j] - 2.0 * Gm_inv[i][j];
69 }
70 }
71 free_array(Gm);
72 free_array(Gm_inv);
73 return rv;
74}
int circuit_model(graph_t *g, int nG)
Definition circuit.c:38
int solveCircuit(int nG, double **Gm, double **Gm_inv)
Definition circuit.c:19
static bool Verbose
Definition gml2gv.c:23
#define ED_dist(e)
Definition types.h:602
#define agtail(e)
Definition cgraph.h:880
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Definition edge.c:94
#define aghead(e)
Definition cgraph.h:881
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Definition edge.c:85
#define GD_dist(g)
Definition types.h:357
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
#define AGSEQ(obj)
Definition cgraph.h:225
int matinv(double **A, double **Ainv, int n)
Definition matinv.c:39
NEATOPROCS_API void free_array(double **rv)
Definition stuff.c:62
NEATOPROCS_API double ** new_array(int i, int j, double val)
Definition stuff.c:47
graph or subgraph
Definition cgraph.h:425