Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
embed_graph.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/************************************************
13
14 Functions for computing the high-dimensional
15 embedding and the PCA projection.
16
17************************************************/
18
19#include <neatogen/dijkstra.h>
20#include <neatogen/bfs.h>
21#include <neatogen/kkutils.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <time.h>
26#include <util/alloc.h>
27
28void embed_graph(vtx_data * graph, int n, int dim, DistType *** Coords,
29 int reweight_graph)
30{
31/* Compute 'dim'-dimensional high-dimensional embedding (HDE) for the 'n' nodes
32 The embedding is based on choosing 'dim' pivots, and associating each
33 coordinate with a unique pivot, assigning it to the graph-theoretic distances
34 of all nodes from the pivots
35*/
36
37 int i, j;
38 int node;
39 DistType *storage = gv_calloc(n * dim, sizeof(DistType));
40 DistType **coords = *Coords;
41 DistType *dist = gv_calloc(n, sizeof(DistType)); // this vector stores the
42 // distances of each nodes
43 // to the selected “pivots”
44 float *old_weights = graph[0].ewgts;
45 DistType max_dist = 0;
46
47 /* this matrix stores the distance between each node and each "pivot" */
48 *Coords = coords = gv_calloc(dim, sizeof(DistType *));
49 for (i = 0; i < dim; i++)
50 coords[i] = storage + i * n;
51
52 if (reweight_graph) {
54 }
55
56 /* select the first pivot */
57 node = rand() % n;
58
59 if (reweight_graph) {
60 dijkstra(node, graph, n, coords[0]);
61 } else {
62 bfs(node, graph, n, coords[0]);
63 }
64
65 for (i = 0; i < n; i++) {
66 dist[i] = coords[0][i];
67 if (dist[i] > max_dist) {
68 node = i;
69 max_dist = dist[i];
70 }
71 }
72
73 /* select other dim-1 nodes as pivots */
74 for (i = 1; i < dim; i++) {
75 if (reweight_graph) {
76 dijkstra(node, graph, n, coords[i]);
77 } else {
78 bfs(node, graph, n, coords[i]);
79 }
80 max_dist = 0;
81 for (j = 0; j < n; j++) {
82 dist[j] = MIN(dist[j], coords[i][j]);
83 if (dist[j] > max_dist) {
84 node = j;
85 max_dist = dist[j];
86 }
87 }
88
89 }
90
91 free(dist);
92
93 if (reweight_graph) {
94 restore_old_weights(graph, n, old_weights);
95 }
96
97}
98
99 /* Make each axis centered around 0 */
100void center_coordinate(DistType ** coords, int n, int dim)
101{
102 int i, j;
103 double sum, avg;
104 for (i = 0; i < dim; i++) {
105 sum = 0;
106 for (j = 0; j < n; j++) {
107 sum += coords[i][j];
108 }
109 avg = sum / n;
110 for (j = 0; j < n; j++) {
111 coords[i][j] -= (DistType) avg;
112 }
113 }
114}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
#define MIN(a, b)
Definition arith.h:28
void bfs(int vertex, vtx_data *graph, int n, DistType *dist)
Definition bfs.c:25
static void dijkstra(Dict_t *Q, Agraph_t *G, Agnode_t *n)
Definition dijkstra.c:188
void embed_graph(vtx_data *graph, int n, int dim, DistType ***Coords, int reweight_graph)
Definition embed_graph.c:28
void center_coordinate(DistType **coords, int n, int dim)
static double dist(int dim, double *x, double *y)
void free(void *)
Agraph_t * graph(char *name)
Definition gv.cpp:30
void compute_new_weights(vtx_data *graph, int n)
Definition kkutils.c:165
void restore_old_weights(vtx_data *graph, int n, float *old_weights)
Definition kkutils.c:196
static const int dim
int DistType
Definition sparsegraph.h:37