Graphviz 14.1.3~dev.20260207.0611
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
18#include "config.h"
19
20#include <neatogen/neato.h>
21
22int solveCircuit(int nG, double **Gm, double **Gm_inv)
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 (int i = 0; i < nG; i++) {
29 double sum = 0;
30 for (int 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 **const Gm = new_array(nG, nG, 0.0);
41 double **const Gm_inv = new_array(nG, nG, 0.0);
42
43 /* set non-diagonal entries */
44 for (node_t *v = agfstnode(g); v; v = agnxtnode(g, v)) {
45 for (edge_t *e = agfstedge(g, v); e; e = agnxtedge(g, e, v)) {
46 const long i = AGSEQ(agtail(e));
47 const long j = AGSEQ(aghead(e));
48 if (i == j)
49 continue;
50 /* conductance is 1/resistance */
51 Gm[i][j] = Gm[j][i] = -1.0 / ED_dist(e); /* negate */
52 }
53 }
54
55 const int rv = solveCircuit(nG, Gm, Gm_inv);
56
57 if (rv)
58 for (int i = 0; i < nG; i++) {
59 for (int j = 0; j < nG; j++) {
60 GD_dist(g)[i][j] =
61 Gm_inv[i][i] + Gm_inv[j][j] - 2.0 * Gm_inv[i][j];
62 }
63 }
64 free_array(Gm);
65 free_array(Gm_inv);
66 return rv;
67}
int circuit_model(graph_t *g, int nG)
Definition circuit.c:38
int solveCircuit(int nG, double **Gm, double **Gm_inv)
Definition circuit.c:22
static bool Verbose
Definition gml2gv.c:26
#define ED_dist(e)
Definition types.h:602
#define agtail(e)
Definition cgraph.h:977
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Definition edge.c:98
#define aghead(e)
Definition cgraph.h:978
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Definition edge.c:89
#define GD_dist(g)
Definition types.h:357
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:50
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:43
#define AGSEQ(obj)
Definition cgraph.h:225
int matinv(double **A, double **Ainv, int n)
Definition matinv.c:40
NEATOPROCS_API void free_array(double **rv)
Definition stuff.c:54
NEATOPROCS_API double ** new_array(int i, int j, double val)
Definition stuff.c:39
graph or subgraph
Definition cgraph.h:424