|
Graphviz
2.31.20130618.0446
|
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 #include "digcola.h" 00015 #ifdef DIGCOLA 00016 #include "matrix_ops.h" 00017 #include "conjgrad.h" 00018 00019 static void construct_b(vtx_data * graph, int n, double *b) 00020 { 00021 /* construct a vector - b s.t. -b[i]=\sum_j -w_{ij}*\delta_{ij} 00022 * (the "balance vector") 00023 * Note that we build -b and not b, since our matrix is not the 00024 * real laplacian L, but its negation: -L. 00025 * So instead of solving Lx=b, we will solve -Lx=-b 00026 */ 00027 int i, j; 00028 00029 double b_i = 0; 00030 00031 for (i = 0; i < n; i++) { 00032 b_i = 0; 00033 if (graph[0].edists == NULL) { 00034 continue; 00035 } 00036 for (j = 1; j < graph[i].nedges; j++) { /* skip the self loop */ 00037 b_i += graph[i].ewgts[j] * graph[i].edists[j]; 00038 } 00039 b[i] = b_i; 00040 } 00041 } 00042 00043 #define hierarchy_cg_tol 1e-3 00044 00045 int 00046 compute_y_coords(vtx_data * graph, int n, double *y_coords, 00047 int max_iterations) 00048 { 00049 /* Find y coords of a directed graph by solving L*x = b */ 00050 int i, j, rv = 0; 00051 double *b = N_NEW(n, double); 00052 double tol = hierarchy_cg_tol; 00053 int nedges = 0; 00054 float *uniform_weights; 00055 float *old_ewgts = graph[0].ewgts; 00056 00057 construct_b(graph, n, b); 00058 00059 init_vec_orth1(n, y_coords); 00060 00061 for (i = 0; i < n; i++) { 00062 nedges += graph[i].nedges; 00063 } 00064 00065 /* replace original edge weights (which are lengths) with uniform weights */ 00066 /* for computing the optimal arrangement */ 00067 uniform_weights = N_GNEW(nedges, float); 00068 for (i = 0; i < n; i++) { 00069 graph[i].ewgts = uniform_weights; 00070 uniform_weights[0] = (float) -(graph[i].nedges - 1); 00071 for (j = 1; j < graph[i].nedges; j++) { 00072 uniform_weights[j] = 1; 00073 } 00074 uniform_weights += graph[i].nedges; 00075 } 00076 00077 if (conjugate_gradient(graph, y_coords, b, n, tol, max_iterations) < 0) { 00078 rv = 1; 00079 } 00080 00081 /* restore original edge weights */ 00082 free(graph[0].ewgts); 00083 for (i = 0; i < n; i++) { 00084 graph[i].ewgts = old_ewgts; 00085 old_ewgts += graph[i].nedges; 00086 } 00087 00088 free(b); 00089 return rv; 00090 } 00091 00092 #endif /* DIGCOLA */
1.7.5