Graphviz  2.29.20120523.0446
lib/neatogen/embed_graph.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 
00015 /************************************************
00016 
00017         Functions for computing the high-dimensional
00018         embedding and the PCA projection.
00019 
00020 ************************************************/
00021 
00022 
00023 #include "dijkstra.h"
00024 #include "bfs.h"
00025 #include "kkutils.h"
00026 #include "embed_graph.h"
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <time.h>
00030 /* #include <math.h> */
00031 
00032 void embed_graph(vtx_data * graph, int n, int dim, DistType *** Coords,
00033                  int reweight_graph)
00034 {
00035 /* Compute 'dim'-dimensional high-dimensional embedding (HDE) for the 'n' nodes
00036   The embedding is based on chossing 'dim' pivots, and associating each
00037   coordinate with a unique pivot, assigning it to the graph-theoretic distances 
00038   of all nodes from the pivots
00039 */
00040 
00041     int i, j;
00042     int node;
00043     DistType *storage = N_GNEW(n * dim, DistType);
00044     DistType **coords = *Coords;
00045     DistType *dist = N_GNEW(n, DistType);       /* this vector stores  the distances of
00046                                                    each nodes to the selected "pivots" */
00047     float *old_weights = graph[0].ewgts;
00048     Queue Q;
00049     DistType max_dist = 0;
00050 
00051     if (coords != NULL) {
00052         free(coords[0]);
00053         free(coords);
00054     }
00055 
00056     /* this matrix stores the distance between each node and each "pivot" */
00057     *Coords = coords = N_GNEW(dim, DistType *);
00058     for (i = 0; i < dim; i++)
00059         coords[i] = storage + i * n;
00060 
00061     if (reweight_graph) {
00062         compute_new_weights(graph, n);
00063     }
00064 
00065     /* select the first pivot */
00066     node = rand() % n;
00067 
00068     mkQueue(&Q, n);
00069     if (reweight_graph) {
00070         dijkstra(node, graph, n, coords[0]);
00071     } else {
00072         bfs(node, graph, n, coords[0], &Q);
00073     }
00074 
00075     for (i = 0; i < n; i++) {
00076         dist[i] = coords[0][i];
00077         if (dist[i] > max_dist) {
00078             node = i;
00079             max_dist = dist[i];
00080         }
00081     }
00082 
00083     /* select other dim-1 nodes as pivots */
00084     for (i = 1; i < dim; i++) {
00085         if (reweight_graph) {
00086             dijkstra(node, graph, n, coords[i]);
00087         } else {
00088             bfs(node, graph, n, coords[i], &Q);
00089         }
00090         max_dist = 0;
00091         for (j = 0; j < n; j++) {
00092             dist[j] = MIN(dist[j], coords[i][j]);
00093             if (dist[j] > max_dist) {
00094                 node = j;
00095                 max_dist = dist[j];
00096             }
00097         }
00098 
00099     }
00100 
00101     free(dist);
00102 
00103     if (reweight_graph) {
00104         restore_old_weights(graph, n, old_weights);
00105     }
00106 
00107 }
00108 
00109  /* Make each axis centered around 0 */
00110 void center_coordinate(DistType ** coords, int n, int dim)
00111 {
00112     int i, j;
00113     double sum, avg;
00114     for (i = 0; i < dim; i++) {
00115         sum = 0;
00116         for (j = 0; j < n; j++) {
00117             sum += coords[i][j];
00118         }
00119         avg = sum / n;
00120         for (j = 0; j < n; j++) {
00121             coords[i][j] -= (DistType) avg;
00122         }
00123     }
00124 }