embed_graph.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. Functions for computing the high-dimensional
  12. embedding and the PCA projection.
  13. ************************************************/
  14. #include <neatogen/dijkstra.h>
  15. #include <neatogen/bfs.h>
  16. #include <neatogen/kkutils.h>
  17. #include <neatogen/embed_graph.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <time.h>
  21. #include <util/alloc.h>
  22. void embed_graph(vtx_data * graph, int n, int dim, DistType *** Coords,
  23. int reweight_graph)
  24. {
  25. /* Compute 'dim'-dimensional high-dimensional embedding (HDE) for the 'n' nodes
  26. The embedding is based on choosing 'dim' pivots, and associating each
  27. coordinate with a unique pivot, assigning it to the graph-theoretic distances
  28. of all nodes from the pivots
  29. */
  30. int i, j;
  31. int node;
  32. DistType *storage = gv_calloc(n * dim, sizeof(DistType));
  33. DistType **coords = *Coords;
  34. DistType *dist = gv_calloc(n, sizeof(DistType)); // this vector stores the
  35. // distances of each nodes
  36. // to the selected “pivots”
  37. float *old_weights = graph[0].ewgts;
  38. DistType max_dist = 0;
  39. /* this matrix stores the distance between each node and each "pivot" */
  40. *Coords = coords = gv_calloc(dim, sizeof(DistType *));
  41. for (i = 0; i < dim; i++)
  42. coords[i] = storage + i * n;
  43. if (reweight_graph) {
  44. compute_new_weights(graph, n);
  45. }
  46. /* select the first pivot */
  47. node = rand() % n;
  48. if (reweight_graph) {
  49. dijkstra(node, graph, n, coords[0]);
  50. } else {
  51. bfs(node, graph, n, coords[0]);
  52. }
  53. for (i = 0; i < n; i++) {
  54. dist[i] = coords[0][i];
  55. if (dist[i] > max_dist) {
  56. node = i;
  57. max_dist = dist[i];
  58. }
  59. }
  60. /* select other dim-1 nodes as pivots */
  61. for (i = 1; i < dim; i++) {
  62. if (reweight_graph) {
  63. dijkstra(node, graph, n, coords[i]);
  64. } else {
  65. bfs(node, graph, n, coords[i]);
  66. }
  67. max_dist = 0;
  68. for (j = 0; j < n; j++) {
  69. dist[j] = MIN(dist[j], coords[i][j]);
  70. if (dist[j] > max_dist) {
  71. node = j;
  72. max_dist = dist[j];
  73. }
  74. }
  75. }
  76. free(dist);
  77. if (reweight_graph) {
  78. restore_old_weights(graph, n, old_weights);
  79. }
  80. }
  81. /* Make each axis centered around 0 */
  82. void center_coordinate(DistType ** coords, int n, int dim)
  83. {
  84. int i, j;
  85. double sum, avg;
  86. for (i = 0; i < dim; i++) {
  87. sum = 0;
  88. for (j = 0; j < n; j++) {
  89. sum += coords[i][j];
  90. }
  91. avg = sum / n;
  92. for (j = 0; j < n; j++) {
  93. coords[i][j] -= (DistType) avg;
  94. }
  95. }
  96. }