Graphviz 14.1.2~dev.20251224.0902
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 *dist = gv_calloc(n, sizeof(DistType)); // this vector stores the
41 // distances of each nodes
42 // to the selected “pivots”
43 float *old_weights = graph[0].ewgts;
44 DistType max_dist = 0;
45
46 /* this matrix stores the distance between each node and each "pivot" */
47 DistType **coords = *Coords = gv_calloc(dim, sizeof(DistType *));
48 for (i = 0; i < dim; i++)
49 coords[i] = storage + i * n;
50
51 if (reweight_graph) {
53 }
54
55 /* select the first pivot */
56 node = rand() % n;
57
58 if (reweight_graph) {
59 ngdijkstra(node, graph, n, coords[0]);
60 } else {
61 bfs(node, graph, n, coords[0]);
62 }
63
64 for (i = 0; i < n; i++) {
65 dist[i] = coords[0][i];
66 if (dist[i] > max_dist) {
67 node = i;
68 max_dist = dist[i];
69 }
70 }
71
72 /* select other dim-1 nodes as pivots */
73 for (i = 1; i < dim; i++) {
74 if (reweight_graph) {
75 ngdijkstra(node, graph, n, coords[i]);
76 } else {
77 bfs(node, graph, n, coords[i]);
78 }
79 max_dist = 0;
80 for (j = 0; j < n; j++) {
81 dist[j] = MIN(dist[j], coords[i][j]);
82 if (dist[j] > max_dist) {
83 node = j;
84 max_dist = dist[j];
85 }
86 }
87
88 }
89
90 free(dist);
91
92 if (reweight_graph) {
93 restore_old_weights(graph, n, old_weights);
94 }
95
96}
97
98 /* Make each axis centered around 0 */
99void center_coordinate(DistType ** coords, int n, int dim)
100{
101 int i, j;
102 double sum, avg;
103 for (i = 0; i < dim; i++) {
104 sum = 0;
105 for (j = 0; j < n; j++) {
106 sum += coords[i][j];
107 }
108 avg = sum / n;
109 for (j = 0; j < n; j++) {
110 coords[i][j] -= (DistType) avg;
111 }
112 }
113}
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)
compute vector dist of distances of all nodes from vertex
Definition bfs.c:22
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)
Definition embed_graph.c:99
static double dist(int dim, double *x, double *y)
void free(void *)
Agraph_t * graph(char *name)
Definition gv.cpp:32
void compute_new_weights(vtx_data *graph, int n)
Definition kkutils.c:163
void restore_old_weights(vtx_data *graph, int n, float *old_weights)
Definition kkutils.c:194
void ngdijkstra(int vertex, vtx_data *graph, int n, DistType *dist)
Definition dijkstra.c:153
static const int dim
int DistType
Definition sparsegraph.h:38