]> granicus.if.org Git - graphviz/commitdiff
Install original sfdp files, with development logs;
authorerg <devnull@localhost>
Wed, 30 Apr 2008 20:55:00 +0000 (20:55 +0000)
committererg <devnull@localhost>
Wed, 30 Apr 2008 20:55:00 +0000 (20:55 +0000)
recommit new sfdp files

lib/sfdpgen/Multilevel.c
lib/sfdpgen/Multilevel.h
lib/sfdpgen/QuadTree.c
lib/sfdpgen/QuadTree.h
lib/sfdpgen/post_process.c
lib/sfdpgen/post_process.h

index 7935c48d829cf7c87c330b18d3d649efeeb5acbc..ea719bbcd397fdf7b2eff4ae7628c8efd9a9a8e3 100644 (file)
-#include "general.h"
-#include "SparseMatrix.h"
-#include "Multilevel.h"
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
 
+#include "Multilevel.h"
+#include "memory.h"
+#include "logic.h"
+#include "assert.h"
+#include "arith.h"
+
+Multilevel_control *Multilevel_control_new()
+{
+    Multilevel_control *ctrl;
+
+    ctrl = GNEW(Multilevel_control);
+    ctrl->minsize = 4;
+    ctrl->min_coarsen_factor = 0.75;
+    ctrl->maxlevel = 1 << 30;
+    ctrl->randomize = TRUE;
+    ctrl->coarsen_scheme =
+       COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST;
+    ctrl->coarsen_scheme = COARSEN_HYBRID;
+    return ctrl;
+}
 
-Multilevel_control Multilevel_control_new(){
-  Multilevel_control ctrl;
+void Multilevel_control_delete(Multilevel_control * ctrl)
+{
+    free(ctrl);
+}
 
-  ctrl = MALLOC(sizeof(struct Multilevel_control_struct));
-  ctrl->minsize = 4;
-  ctrl->min_coarsen_factor = 0.75;
-  ctrl->maxlevel = 1<<30;
-  ctrl->randomize = TRUE;
-  ctrl->coarsen_scheme = COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST;
-  ctrl->coarsen_scheme = COARSEN_HYBRID;
-  return ctrl;
+static Multilevel *Multilevel_init(SparseMatrix * A, real * node_weights)
+{
+    Multilevel *grid;
+    if (!A)
+       return NULL;
+    assert(A->m == A->n);
+    grid = GNEW(Multilevel);
+    grid->level = 0;
+    grid->n = A->n;
+    grid->A = A;
+    grid->P = NULL;
+    grid->R = NULL;
+    grid->node_weights = node_weights;
+    grid->next = NULL;
+    grid->prev = NULL;
+    grid->delete_top_level_A = FALSE;
+    return grid;
 }
 
-void Multilevel_control_delete(Multilevel_control ctrl){
-  FREE(ctrl);
+void Multilevel_delete(Multilevel * grid)
+{
+    if (!grid)
+       return;
+    if (grid->A) {
+       if (grid->level == 0) {
+           if (grid->delete_top_level_A)
+               SparseMatrix_delete(grid->A);
+       } else {
+           SparseMatrix_delete(grid->A);
+       }
+    }
+    SparseMatrix_delete(grid->P);
+    SparseMatrix_delete(grid->R);
+    if (grid->node_weights && grid->level > 0)
+       free(grid->node_weights);
+    Multilevel_delete(grid->next);
+    free(grid);
 }
 
-static Multilevel Multilevel_init(SparseMatrix A, real *node_weights){
-  Multilevel grid;
-  if (!A) return NULL;
-  assert(A->m == A->n);
-  grid = MALLOC(sizeof(struct Multilevel_struct));
-  grid->level = 0;
-  grid->n = A->n;
-  grid->A = A;
-  grid->P = NULL;
-  grid->R = NULL;
-  grid->node_weights = node_weights;
-  grid->next = NULL;
-  grid->prev = NULL;
-  grid->delete_top_level_A = FALSE;
-  return grid;
+static int irand(int n){
+  /* 0, 1, ..., n-1 */
+  assert(n > 1);
+  /*return (int) MIN(floor(drand()*n),n-1);*/
+  return rand()%n;
 }
 
-void Multilevel_delete(Multilevel grid){
-  if (!grid) return;
-  if (grid->A){
-    if (grid->level == 0) {
-      if (grid->delete_top_level_A) SparseMatrix_delete(grid->A);
-    } else {
-      SparseMatrix_delete(grid->A);
+static int *random_permutation(int n)
+{
+    int *p;
+    int i, j, pp, len;
+    if (n <= 0)
+       return NULL;
+    p = N_GNEW(n, int);
+    for (i = 0; i < n; i++)
+       p[i] = i;
+
+    len = n;
+    while (len > 1) {
+       j = irand(len);
+       pp = p[len - 1];
+       p[len - 1] = p[j];
+       p[j] = pp;
+       len--;
     }
-  }
-  SparseMatrix_delete(grid->P);
-  SparseMatrix_delete(grid->R);
-  if (grid->node_weights && grid->level > 0) FREE(grid->node_weights);
-  Multilevel_delete(grid->next);
-  FREE(grid);
+    return p;
 }
 
-static void maximal_independent_vertex_set(SparseMatrix A, int randomize, int **vset, int *nvset, int *nzc){
-  int i, ii, j, *ia, *ja, m, n, *p = NULL;
-  assert(A);
-  assert(SparseMatrix_known_strucural_symmetric(A));
-  ia = A->ia;
-  ja = A->ja;
-  m = A->m;
-  n = A->n;
-  assert(n == m);
-  *vset = MALLOC(sizeof(int)*m);
-  for (i = 0; i < m; i++) (*vset)[i] = MAX_IND_VTX_SET_0;
-  *nvset = 0;
-  *nzc = 0;
-
-  if (!randomize){
-    for (i = 0; i < m; i++){
-      if ((*vset)[i] == MAX_IND_VTX_SET_0){
-       (*vset)[i] = (*nvset)++;
-       for (j = ia[i]; j < ia[i+1]; j++){
-         if (i == ja[j]) continue;
-         (*vset)[ja[j]] = MAX_IND_VTX_SET_U;
-         (*nzc)++;
-       }
-      }
-    }
-  } else {
-    p = random_permutation(m);
-    for (ii = 0; ii < m; ii++){
-      i = p[ii];
-      if ((*vset)[i] == MAX_IND_VTX_SET_0){
-       (*vset)[i] = (*nvset)++;
-       for (j = ia[i]; j < ia[i+1]; j++){
-         if (i == ja[j]) continue;
-         (*vset)[ja[j]] = MAX_IND_VTX_SET_U;
-         (*nzc)++;
-       }
-      }
+static void maximal_independent_vertex_set(SparseMatrix * A, int randomize,
+                                          int **vset, int *nvset,
+                                          int *nzc)
+{
+    int i, ii, j, *ia, *ja, m, n, *p = NULL;
+    assert(A);
+    assert(SparseMatrix_known_strucural_symmetric(A));
+    ia = A->ia;
+    ja = A->ja;
+    m = A->m;
+    n = A->n;
+    assert(n == m);
+    *vset = N_GNEW(m, int);
+    for (i = 0; i < m; i++)
+       (*vset)[i] = MAX_IND_VTX_SET_0;
+    *nvset = 0;
+    *nzc = 0;
+
+    if (!randomize) {
+       for (i = 0; i < m; i++) {
+           if ((*vset)[i] == MAX_IND_VTX_SET_0) {
+               (*vset)[i] = (*nvset)++;
+               for (j = ia[i]; j < ia[i + 1]; j++) {
+                   if (i == ja[j])
+                       continue;
+                   (*vset)[ja[j]] = MAX_IND_VTX_SET_U;
+                   (*nzc)++;
+               }
+           }
+       }
+    } else {
+       p = random_permutation(m);
+       for (ii = 0; ii < m; ii++) {
+           i = p[ii];
+           if ((*vset)[i] == MAX_IND_VTX_SET_0) {
+               (*vset)[i] = (*nvset)++;
+               for (j = ia[i]; j < ia[i + 1]; j++) {
+                   if (i == ja[j])
+                       continue;
+                   (*vset)[ja[j]] = MAX_IND_VTX_SET_U;
+                   (*nzc)++;
+               }
+           }
+       }
+       free(p);
     }
-    FREE(p);
-  }
-  (*nzc) += *nvset;
+    (*nzc) += *nvset;
 }
 
 
-static void maximal_independent_edge_set(SparseMatrix A, int randomize, int **matching, int *nmatch){
-  int i, ii, j, *ia, *ja, m, n, *p = NULL;
-  assert(A);
-  assert(SparseMatrix_known_strucural_symmetric(A));
-  ia = A->ia;
-  ja = A->ja;
-  m = A->m;
-  n = A->n;
-  assert(n == m);
-  *matching = MALLOC(sizeof(int)*m);
-  for (i = 0; i < m; i++) (*matching)[i] = i;
-  *nmatch = n;
-
-  if (!randomize){
-    for (i = 0; i < m; i++){
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
-         (*matching)[ja[j]] = i;
-         (*matching)[i] = ja[j];
-         (*nmatch)--;
-       }
-      }
-    }
-  } else {
-    p = random_permutation(m);
-    for (ii = 0; ii < m; ii++){
-      i = p[ii];
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
-         (*matching)[ja[j]] = i;
-         (*matching)[i] = ja[j];
-         (*nmatch)--;
-       }
-      }
+static void maximal_independent_edge_set(SparseMatrix * A, int randomize,
+                                        int **matching, int *nmatch)
+{
+    int i, ii, j, *ia, *ja, m, n, *p = NULL;
+    assert(A);
+    assert(SparseMatrix_known_strucural_symmetric(A));
+    ia = A->ia;
+    ja = A->ja;
+    m = A->m;
+    n = A->n;
+    assert(n == m);
+    *matching = N_GNEW(m, int);
+    for (i = 0; i < m; i++)
+       (*matching)[i] = i;
+    *nmatch = n;
+
+    if (!randomize) {
+       for (i = 0; i < m; i++) {
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i) {
+                   (*matching)[ja[j]] = i;
+                   (*matching)[i] = ja[j];
+                   (*nmatch)--;
+               }
+           }
+       }
+    } else {
+       p = random_permutation(m);
+       for (ii = 0; ii < m; ii++) {
+           i = p[ii];
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i) {
+                   (*matching)[ja[j]] = i;
+                   (*matching)[i] = ja[j];
+                   (*nmatch)--;
+               }
+           }
+       }
+       free(p);
     }
-    FREE(p);
-  }
 }
 
 
 
-static void maximal_independent_edge_set_heavest_edge_pernode(SparseMatrix A, int randomize, int **matching, int *nmatch){
-  int i, ii, j, *ia, *ja, m, n, *p = NULL;
-  real *a, amax = 0;
-  int first = TRUE, jamax = 0;
-
-  assert(A);
-  assert(SparseMatrix_known_strucural_symmetric(A));
-  ia = A->ia;
-  ja = A->ja;
-  m = A->m;
-  n = A->n;
-  assert(n == m);
-  *matching = MALLOC(sizeof(int)*m);
-  for (i = 0; i < m; i++) (*matching)[i] = i;
-  *nmatch = n;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
-  assert(A->type == MATRIX_TYPE_REAL);
-
-  a = (real*) A->a;
-  if (!randomize){
-    for (i = 0; i < m; i++){
-      first = TRUE;
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
-         if (first) {
-           amax = a[j];
-           jamax = ja[j];
-           first = FALSE;
-         } else {
-           if (a[j] > amax){
-             amax = a[j];
-             jamax = ja[j];
-           }
-         }
-       }
-      }
-      if (!first){
-         (*matching)[jamax] = i;
-         (*matching)[i] = jamax;
-         (*nmatch)--;
-      }
-    }
-  } else {
-    p = random_permutation(m);
-    for (ii = 0; ii < m; ii++){
-      i = p[ii];
-      if ((*matching)[i] != i) continue;
-      first = TRUE;
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
-         if (first) {
-           amax = a[j];
-           jamax = ja[j];
-           first = FALSE;
-         } else {
-           if (a[j] > amax){
-             amax = a[j];
-             jamax = ja[j];
-           }
-         }
-       }
-      }
-      if (!first){
-         (*matching)[jamax] = i;
-         (*matching)[i] = jamax;
-         (*nmatch)--;
-      }
+static void maximal_independent_edge_set_heavest_edge_pernode(SparseMatrix
+                                                             * A,
+                                                             int
+                                                             randomize,
+                                                             int
+                                                             **matching,
+                                                             int *nmatch)
+{
+    int i, ii, j, *ia, *ja, m, n, *p = NULL;
+    real *a, amax = 0;
+    int first = TRUE, jamax = 0;
+
+    assert(A);
+    assert(SparseMatrix_known_strucural_symmetric(A));
+    ia = A->ia;
+    ja = A->ja;
+    m = A->m;
+    n = A->n;
+    assert(n == m);
+    *matching = N_GNEW(m, int);
+    for (i = 0; i < m; i++)
+       (*matching)[i] = i;
+    *nmatch = n;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+    assert(A->type == MATRIX_TYPE_REAL);
+
+    a = (real *) A->a;
+    if (!randomize) {
+       for (i = 0; i < m; i++) {
+           first = TRUE;
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i) {
+                   if (first) {
+                       amax = a[j];
+                       jamax = ja[j];
+                       first = FALSE;
+                   } else {
+                       if (a[j] > amax) {
+                           amax = a[j];
+                           jamax = ja[j];
+                       }
+                   }
+               }
+           }
+           if (!first) {
+               (*matching)[jamax] = i;
+               (*matching)[i] = jamax;
+               (*nmatch)--;
+           }
+       }
+    } else {
+       p = random_permutation(m);
+       for (ii = 0; ii < m; ii++) {
+           i = p[ii];
+           if ((*matching)[i] != i)
+               continue;
+           first = TRUE;
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i) {
+                   if (first) {
+                       amax = a[j];
+                       jamax = ja[j];
+                       first = FALSE;
+                   } else {
+                       if (a[j] > amax) {
+                           amax = a[j];
+                           jamax = ja[j];
+                       }
+                   }
+               }
+           }
+           if (!first) {
+               (*matching)[jamax] = i;
+               (*matching)[i] = jamax;
+               (*nmatch)--;
+           }
+       }
+       free(p);
     }
-    FREE(p);
-  }
 }
 
 
@@ -221,775 +296,908 @@ static void maximal_independent_edge_set_heavest_edge_pernode(SparseMatrix A, in
 
 #define node_degree(i) (ia[(i)+1] - ia[(i)])
 
-static void maximal_independent_edge_set_heavest_edge_pernode_leaves_first(SparseMatrix A, int randomize, int **cluster, int **clusterp, int *ncluster){
-  int i, ii, j, *ia, *ja, m, n, *p = NULL, q;
-  real *a, amax = 0;
-  int first = TRUE, jamax = 0;
-  int *matched, nz, ncmax = 0, nz0, nzz,k ;
-  enum {UNMATCHED = -2, MATCHED = -1};
-
-  assert(A);
-  assert(SparseMatrix_known_strucural_symmetric(A));
-  ia = A->ia;
-  ja = A->ja;
-  m = A->m;
-  n = A->n;
-  assert(n == m);
-  *cluster = MALLOC(sizeof(int)*m);
-  *clusterp = MALLOC(sizeof(int)*(m+1));
-  matched = MALLOC(sizeof(int)*m);
-
-  for (i = 0; i < m; i++) matched[i] = i;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
-  assert(A->type == MATRIX_TYPE_REAL);
-
-  *ncluster = 0;
-  (*clusterp)[0] = 0;
-  nz = 0;
-  a = (real*) A->a;
-  if (!randomize){
-    for (i = 0; i < m; i++){
-      if (matched[i] == MATCHED || node_degree(i) != 1) continue;
-      q = ja[ia[i]];
-      assert(matched[q] != MATCHED);
-      matched[q] = MATCHED;
-      (*cluster)[nz++] = q;
-      for (j = ia[q]; j < ia[q+1]; j++){
-       if (q == ja[j]) continue;
-       if (node_degree(ja[j]) == 1){
-         matched[ja[j]] = MATCHED;
-         (*cluster)[nz++] = ja[j];
-       }
-      }
-      ncmax = MAX(ncmax, nz - (*clusterp)[*ncluster]);
-      nz0 = (*clusterp)[*ncluster];
-      if (nz - nz0 <= MAX_CLUSTER_SIZE){
-       (*clusterp)[++(*ncluster)] = nz;
-      } else {
-       (*clusterp)[++(*ncluster)] = ++nz0;     
-       nzz = nz0;
-       for (k = nz0; k < nz && nzz < nz; k++){
-         nzz += MAX_CLUSTER_SIZE - 1;
-         nzz = MIN(nz, nzz);
-         (*clusterp)[++(*ncluster)] = nzz;
-       }
-      }
+static void
+maximal_independent_edge_set_heavest_edge_pernode_leaves_first(SparseMatrix
+                                                              * A,
+                                                              int
+                                                              randomize,
+                                                              int
+                                                              **cluster,
+                                                              int
+                                                              **clusterp,
+                                                              int
+                                                              *ncluster)
+{
+    int i, ii, j, *ia, *ja, m, n, *p = NULL, q;
+    real *a, amax = 0;
+    int first = TRUE, jamax = 0;
+    int *matched, nz, ncmax = 0, nz0, nzz, k;
+    enum { UNMATCHED = -2, MATCHED = -1 };
+
+    assert(A);
+    assert(SparseMatrix_known_strucural_symmetric(A));
+    ia = A->ia;
+    ja = A->ja;
+    m = A->m;
+    n = A->n;
+    assert(n == m);
+    *cluster = N_GNEW(m, int);
+    *clusterp = N_GNEW(m + 1, int);
+    matched = N_GNEW(m, int);
+
+    for (i = 0; i < m; i++)
+       matched[i] = i;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+    assert(A->type == MATRIX_TYPE_REAL);
+
+    *ncluster = 0;
+    (*clusterp)[0] = 0;
+    nz = 0;
+    a = (real *) A->a;
+    if (!randomize) {
+       for (i = 0; i < m; i++) {
+           if (matched[i] == MATCHED || node_degree(i) != 1)
+               continue;
+           q = ja[ia[i]];
+           assert(matched[q] != MATCHED);
+           matched[q] = MATCHED;
+           (*cluster)[nz++] = q;
+           for (j = ia[q]; j < ia[q + 1]; j++) {
+               if (q == ja[j])
+                   continue;
+               if (node_degree(ja[j]) == 1) {
+                   matched[ja[j]] = MATCHED;
+                   (*cluster)[nz++] = ja[j];
+               }
+           }
+           ncmax = MAX(ncmax, nz - (*clusterp)[*ncluster]);
+           nz0 = (*clusterp)[*ncluster];
+           if (nz - nz0 <= MAX_CLUSTER_SIZE) {
+               (*clusterp)[++(*ncluster)] = nz;
+           } else {
+               (*clusterp)[++(*ncluster)] = ++nz0;
+               nzz = nz0;
+               for (k = nz0; k < nz && nzz < nz; k++) {
+                   nzz += MAX_CLUSTER_SIZE - 1;
+                   nzz = MIN(nz, nzz);
+                   (*clusterp)[++(*ncluster)] = nzz;
+               }
+           }
 
-    }
- #ifdef DEBUG_print
-   if (Verbose)
-     fprintf(stderr, "%d leaves and parents for %d clusters, largest cluster = %d\n",nz, *ncluster, ncmax);
+       }
+#ifdef DEBUG_print
+       if (Verbose)
+           fprintf(stderr,
+                   "%d leaves and parents for %d clusters, largest cluster = %d\n",
+                   nz, *ncluster, ncmax);
 #endif
-    for (i = 0; i < m; i++){
-      first = TRUE;
-      if (matched[i] == MATCHED) continue;
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
-         if (first) {
-           amax = a[j];
-           jamax = ja[j];
-           first = FALSE;
-         } else {
-           if (a[j] > amax){
-             amax = a[j];
-             jamax = ja[j];
-           }
-         }
-       }
-      }
-      if (!first){
-         matched[jamax] = MATCHED;
-         matched[i] = MATCHED;
-         (*cluster)[nz++] = i;
-         (*cluster)[nz++] = jamax;
-         (*clusterp)[++(*ncluster)] = nz;
-      }
-    }
+       for (i = 0; i < m; i++) {
+           first = TRUE;
+           if (matched[i] == MATCHED)
+               continue;
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if (matched[ja[j]] != MATCHED && matched[i] != MATCHED) {
+                   if (first) {
+                       amax = a[j];
+                       jamax = ja[j];
+                       first = FALSE;
+                   } else {
+                       if (a[j] > amax) {
+                           amax = a[j];
+                           jamax = ja[j];
+                       }
+                   }
+               }
+           }
+           if (!first) {
+               matched[jamax] = MATCHED;
+               matched[i] = MATCHED;
+               (*cluster)[nz++] = i;
+               (*cluster)[nz++] = jamax;
+               (*clusterp)[++(*ncluster)] = nz;
+           }
+       }
 
-    /* dan yi dian, wu ban */
-    for (i = 0; i < m; i++){
-      if (matched[i] == i){
-       (*cluster)[nz++] = i;
-       (*clusterp)[++(*ncluster)] = nz;
-      }
-    }
-    assert(nz == n);
-    
-  } else {
-    p = random_permutation(m);
-    for (ii = 0; ii < m; ii++){
-      i = p[ii];
-      if (matched[i] == MATCHED || node_degree(i) != 1) continue;
-      q = ja[ia[i]];
-      assert(matched[q] != MATCHED);
-      matched[q] = MATCHED;
-      (*cluster)[nz++] = q;
-      for (j = ia[q]; j < ia[q+1]; j++){
-       if (q == ja[j]) continue;
-       if (node_degree(ja[j]) == 1){
-         matched[ja[j]] = MATCHED;
-         (*cluster)[nz++] = ja[j];
-       }
-      }
-      ncmax = MAX(ncmax, nz - (*clusterp)[*ncluster]);
-      nz0 = (*clusterp)[*ncluster];
-      if (nz - nz0 <= MAX_CLUSTER_SIZE){
-       (*clusterp)[++(*ncluster)] = nz;
-      } else {
-       (*clusterp)[++(*ncluster)] = ++nz0;     
-       nzz = nz0;
-       for (k = nz0; k < nz && nzz < nz; k++){
-         nzz += MAX_CLUSTER_SIZE - 1;
-         nzz = MIN(nz, nzz);
-         (*clusterp)[++(*ncluster)] = nzz;
-       }
-      }
-    }
+       /* dan yi dian, wu ban */
+       for (i = 0; i < m; i++) {
+           if (matched[i] == i) {
+               (*cluster)[nz++] = i;
+               (*clusterp)[++(*ncluster)] = nz;
+           }
+       }
+       assert(nz == n);
+
+    } else {
+       p = random_permutation(m);
+       for (ii = 0; ii < m; ii++) {
+           i = p[ii];
+           if (matched[i] == MATCHED || node_degree(i) != 1)
+               continue;
+           q = ja[ia[i]];
+           assert(matched[q] != MATCHED);
+           matched[q] = MATCHED;
+           (*cluster)[nz++] = q;
+           for (j = ia[q]; j < ia[q + 1]; j++) {
+               if (q == ja[j])
+                   continue;
+               if (node_degree(ja[j]) == 1) {
+                   matched[ja[j]] = MATCHED;
+                   (*cluster)[nz++] = ja[j];
+               }
+           }
+           ncmax = MAX(ncmax, nz - (*clusterp)[*ncluster]);
+           nz0 = (*clusterp)[*ncluster];
+           if (nz - nz0 <= MAX_CLUSTER_SIZE) {
+               (*clusterp)[++(*ncluster)] = nz;
+           } else {
+               (*clusterp)[++(*ncluster)] = ++nz0;
+               nzz = nz0;
+               for (k = nz0; k < nz && nzz < nz; k++) {
+                   nzz += MAX_CLUSTER_SIZE - 1;
+                   nzz = MIN(nz, nzz);
+                   (*clusterp)[++(*ncluster)] = nzz;
+               }
+           }
+       }
 
- #ifdef DEBUG_print
-    if (Verbose)
-      fprintf(stderr, "%d leaves and parents for %d clusters, largest cluster = %d\n",nz, *ncluster, ncmax);
+#ifdef DEBUG_print
+       if (Verbose)
+           fprintf(stderr,
+                   "%d leaves and parents for %d clusters, largest cluster = %d\n",
+                   nz, *ncluster, ncmax);
 #endif
-    for (ii = 0; ii < m; ii++){
-      i = p[ii];
-      first = TRUE;
-      if (matched[i] == MATCHED) continue;
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
-         if (first) {
-           amax = a[j];
-           jamax = ja[j];
-           first = FALSE;
-         } else {
-           if (a[j] > amax){
-             amax = a[j];
-             jamax = ja[j];
-           }
-         }
-       }
-      }
-      if (!first){
-         matched[jamax] = MATCHED;
-         matched[i] = MATCHED;
-         (*cluster)[nz++] = i;
-         (*cluster)[nz++] = jamax;
-         (*clusterp)[++(*ncluster)] = nz;
-      }
-    }
+       for (ii = 0; ii < m; ii++) {
+           i = p[ii];
+           first = TRUE;
+           if (matched[i] == MATCHED)
+               continue;
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if (matched[ja[j]] != MATCHED && matched[i] != MATCHED) {
+                   if (first) {
+                       amax = a[j];
+                       jamax = ja[j];
+                       first = FALSE;
+                   } else {
+                       if (a[j] > amax) {
+                           amax = a[j];
+                           jamax = ja[j];
+                       }
+                   }
+               }
+           }
+           if (!first) {
+               matched[jamax] = MATCHED;
+               matched[i] = MATCHED;
+               (*cluster)[nz++] = i;
+               (*cluster)[nz++] = jamax;
+               (*clusterp)[++(*ncluster)] = nz;
+           }
+       }
 
-    /* dan yi dian, wu ban */
-    for (i = 0; i < m; i++){
-      if (matched[i] == i){
-       (*cluster)[nz++] = i;
-       (*clusterp)[++(*ncluster)] = nz;
-      }
-    }
+       /* dan yi dian, wu ban */
+       for (i = 0; i < m; i++) {
+           if (matched[i] == i) {
+               (*cluster)[nz++] = i;
+               (*clusterp)[++(*ncluster)] = nz;
+           }
+       }
 
-    FREE(p);
-  }
+       free(p);
+    }
 
-  FREE(matched);
+    free(matched);
 }
 
 
 
-static void maximal_independent_edge_set_heavest_edge_pernode_supernodes_first(SparseMatrix A, int randomize, int **cluster, int **clusterp, int *ncluster){
-  int i, ii, j, *ia, *ja, m, n, *p = NULL;
-  real *a, amax = 0;
-  int first = TRUE, jamax = 0;
-  int *matched, nz, nz0;
-  enum {UNMATCHED = -2, MATCHED = -1};
-  int  nsuper, *super = NULL, *superp = NULL;
-
-  assert(A);
-  assert(SparseMatrix_known_strucural_symmetric(A));
-  ia = A->ia;
-  ja = A->ja;
-  m = A->m;
-  n = A->n;
-  assert(n == m);
-  *cluster = MALLOC(sizeof(int)*m);
-  *clusterp = MALLOC(sizeof(int)*(m+1));
-  matched = MALLOC(sizeof(int)*m);
-
-  for (i = 0; i < m; i++) matched[i] = i;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
-  assert(A->type == MATRIX_TYPE_REAL);
-
-  SparseMatrix_decompose_to_supervariables(A, &nsuper, &super, &superp);
-
-  *ncluster = 0;
-  (*clusterp)[0] = 0;
-  nz = 0;
-  a = (real*) A->a;
-
-  for (i = 0; i < nsuper; i++){
-    if (superp[i+1] - superp[i] <= 1) continue;
-    nz0 = (*clusterp)[*ncluster];
-    for (j = superp[i]; j < superp[i+1]; j++){
-      matched[super[j]] = MATCHED;
-      (*cluster)[nz++] = super[j];
-      if (nz - nz0 >= MAX_CLUSTER_SIZE){
-       (*clusterp)[++(*ncluster)] = nz;
-       nz0 = nz;
-      }
-    }
-    if (nz > nz0) (*clusterp)[++(*ncluster)] = nz;
-  }
-
-  if (!randomize){
-    for (i = 0; i < m; i++){
-      first = TRUE;
-      if (matched[i] == MATCHED) continue;
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
-         if (first) {
-           amax = a[j];
-           jamax = ja[j];
-           first = FALSE;
-         } else {
-           if (a[j] > amax){
-             amax = a[j];
-             jamax = ja[j];
-           }
-         }
-       }
-      }
-      if (!first){
-         matched[jamax] = MATCHED;
-         matched[i] = MATCHED;
-         (*cluster)[nz++] = i;
-         (*cluster)[nz++] = jamax;
-         (*clusterp)[++(*ncluster)] = nz;
-      }
-    }
+static void
+maximal_independent_edge_set_heavest_edge_pernode_supernodes_first
+(SparseMatrix * A, int randomize, int **cluster, int **clusterp, int *ncluster)
+{
+    int i, ii, j, *ia, *ja, m, n, *p = NULL;
+    real *a, amax = 0;
+    int first = TRUE, jamax = 0;
+    int *matched, nz, nz0;
+    enum { UNMATCHED = -2, MATCHED = -1 };
+    int nsuper, *super = NULL, *superp = NULL;
 
-    /* dan yi dian, wu ban */
-    for (i = 0; i < m; i++){
-      if (matched[i] == i){
-       (*cluster)[nz++] = i;
-       (*clusterp)[++(*ncluster)] = nz;
-      }
-    }
-    assert(nz == n);
-    
-  } else {
-    p = random_permutation(m);
-    for (ii = 0; ii < m; ii++){
-      i = p[ii];
-      first = TRUE;
-      if (matched[i] == MATCHED) continue;
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
-         if (first) {
-           amax = a[j];
-           jamax = ja[j];
-           first = FALSE;
-         } else {
-           if (a[j] > amax){
-             amax = a[j];
-             jamax = ja[j];
-           }
-         }
-       }
-      }
-      if (!first){
-         matched[jamax] = MATCHED;
-         matched[i] = MATCHED;
-         (*cluster)[nz++] = i;
-         (*cluster)[nz++] = jamax;
-         (*clusterp)[++(*ncluster)] = nz;
-      }
+    assert(A);
+    assert(SparseMatrix_known_strucural_symmetric(A));
+    ia = A->ia;
+    ja = A->ja;
+    m = A->m;
+    n = A->n;
+    assert(n == m);
+    *cluster = N_GNEW(m, int);
+    *clusterp = N_GNEW(m + 1, int);
+    matched = N_GNEW(m, int);
+
+    for (i = 0; i < m; i++)
+       matched[i] = i;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+    assert(A->type == MATRIX_TYPE_REAL);
+
+    SparseMatrix_decompose_to_supervariables(A, &nsuper, &super, &superp);
+
+    *ncluster = 0;
+    (*clusterp)[0] = 0;
+    nz = 0;
+    a = (real *) A->a;
+
+    for (i = 0; i < nsuper; i++) {
+       if (superp[i + 1] - superp[i] <= 1)
+           continue;
+       nz0 = (*clusterp)[*ncluster];
+       for (j = superp[i]; j < superp[i + 1]; j++) {
+           matched[super[j]] = MATCHED;
+           (*cluster)[nz++] = super[j];
+           if (nz - nz0 >= MAX_CLUSTER_SIZE) {
+               (*clusterp)[++(*ncluster)] = nz;
+               nz0 = nz;
+           }
+       }
+       if (nz > nz0)
+           (*clusterp)[++(*ncluster)] = nz;
     }
 
-    /* dan yi dian, wu ban */
-    for (i = 0; i < m; i++){
-      if (matched[i] == i){
-       (*cluster)[nz++] = i;
-       (*clusterp)[++(*ncluster)] = nz;
-      }
-    }
-    FREE(p);
+    if (!randomize) {
+       for (i = 0; i < m; i++) {
+           first = TRUE;
+           if (matched[i] == MATCHED)
+               continue;
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if (matched[ja[j]] != MATCHED && matched[i] != MATCHED) {
+                   if (first) {
+                       amax = a[j];
+                       jamax = ja[j];
+                       first = FALSE;
+                   } else {
+                       if (a[j] > amax) {
+                           amax = a[j];
+                           jamax = ja[j];
+                       }
+                   }
+               }
+           }
+           if (!first) {
+               matched[jamax] = MATCHED;
+               matched[i] = MATCHED;
+               (*cluster)[nz++] = i;
+               (*cluster)[nz++] = jamax;
+               (*clusterp)[++(*ncluster)] = nz;
+           }
+       }
+
+       /* dan yi dian, wu ban */
+       for (i = 0; i < m; i++) {
+           if (matched[i] == i) {
+               (*cluster)[nz++] = i;
+               (*clusterp)[++(*ncluster)] = nz;
+           }
+       }
+       assert(nz == n);
 
-  }
+    } else {
+       p = random_permutation(m);
+       for (ii = 0; ii < m; ii++) {
+           i = p[ii];
+           first = TRUE;
+           if (matched[i] == MATCHED)
+               continue;
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if (matched[ja[j]] != MATCHED && matched[i] != MATCHED) {
+                   if (first) {
+                       amax = a[j];
+                       jamax = ja[j];
+                       first = FALSE;
+                   } else {
+                       if (a[j] > amax) {
+                           amax = a[j];
+                           jamax = ja[j];
+                       }
+                   }
+               }
+           }
+           if (!first) {
+               matched[jamax] = MATCHED;
+               matched[i] = MATCHED;
+               (*cluster)[nz++] = i;
+               (*cluster)[nz++] = jamax;
+               (*clusterp)[++(*ncluster)] = nz;
+           }
+       }
 
-  FREE(super);
+       /* dan yi dian, wu ban */
+       for (i = 0; i < m; i++) {
+           if (matched[i] == i) {
+               (*cluster)[nz++] = i;
+               (*clusterp)[++(*ncluster)] = nz;
+           }
+       }
+       free(p);
 
-  FREE(superp);
+    }
 
-  FREE(matched);
-}
+    free(super);
+
+    free(superp);
 
-static int scomp(const void *s1, const void *s2){
-  real *ss1, *ss2;
-  ss1 = (real*) s1;
-  ss2 = (real*) s2;
-
-  if ((ss1)[1] > (ss2)[1]){
-    return -1;
-  } else if ((ss1)[1] < (ss2)[1]){
-    return 1;
-  }
-  return 0;
+    free(matched);
 }
 
-static void maximal_independent_edge_set_heavest_cluster_pernode_leaves_first(SparseMatrix A, int csize, 
-                                                                             int randomize, int **cluster, int **clusterp, int *ncluster){
-  int i, ii, j, *ia, *ja, m, n, *p = NULL, q, iv, ncmax;
-  real *a;
-  int *matched, nz,  nz0, nzz,k, nv;
-  enum {UNMATCHED = -2, MATCHED = -1};
-  real *vlist;
-
-  assert(A);
-  assert(SparseMatrix_known_strucural_symmetric(A));
-  ia = A->ia;
-  ja = A->ja;
-  m = A->m;
-  n = A->n;
-  assert(n == m);
-  *cluster = MALLOC(sizeof(int)*m);
-  *clusterp = MALLOC(sizeof(int)*(m+1));
-  matched = MALLOC(sizeof(int)*m);
-  vlist = MALLOC(sizeof(real)*2*m);
-
-  for (i = 0; i < m; i++) matched[i] = i;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
-  assert(A->type == MATRIX_TYPE_REAL);
-
-  *ncluster = 0;
-  (*clusterp)[0] = 0;
-  nz = 0;
-  a = (real*) A->a;
-
-  p = random_permutation(m);
-  for (ii = 0; ii < m; ii++){
-    i = p[ii];
-    if (matched[i] == MATCHED || node_degree(i) != 1) continue;
-    q = ja[ia[i]];
-    assert(matched[q] != MATCHED);
-    matched[q] = MATCHED;
-    (*cluster)[nz++] = q;
-    for (j = ia[q]; j < ia[q+1]; j++){
-      if (q == ja[j]) continue;
-      if (node_degree(ja[j]) == 1){
-       matched[ja[j]] = MATCHED;
-       (*cluster)[nz++] = ja[j];
-      }
-    }
-    ncmax = MAX(ncmax, nz - (*clusterp)[*ncluster]);
-    nz0 = (*clusterp)[*ncluster];
-    if (nz - nz0 <= MAX_CLUSTER_SIZE){
-      (*clusterp)[++(*ncluster)] = nz;
-    } else {
-      (*clusterp)[++(*ncluster)] = ++nz0;      
-      nzz = nz0;
-      for (k = nz0; k < nz && nzz < nz; k++){
-       nzz += MAX_CLUSTER_SIZE - 1;
-       nzz = MIN(nz, nzz);
-       (*clusterp)[++(*ncluster)] = nzz;
-      }
+static int scomp(const void *s1, const void *s2)
+{
+    real *ss1, *ss2;
+    ss1 = (real *) s1;
+    ss2 = (real *) s2;
+
+    if ((ss1)[1] > (ss2)[1]) {
+       return -1;
+    } else if ((ss1)[1] < (ss2)[1]) {
+       return 1;
     }
-  }
-  
-  for (ii = 0; ii < m; ii++){
-    i = p[ii];
-    if (matched[i] == MATCHED) continue;
-    nv = 0;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      if (i == ja[j]) continue;
-      if (matched[ja[j]] != MATCHED && matched[i] != MATCHED){
-       vlist[2*nv] = ja[j];
-       vlist[2*nv+1] = a[j];
-       nv++;
-      }
+    return 0;
+}
+
+static void
+maximal_independent_edge_set_heavest_cluster_pernode_leaves_first
+(SparseMatrix * A, int csize, int randomize, int **cluster, int **clusterp,
+int *ncluster)
+{
+    int i, ii, j, *ia, *ja, m, n, *p = NULL, q, iv, ncmax;
+    real *a;
+    int *matched, nz, nz0, nzz, k, nv;
+    enum { UNMATCHED = -2, MATCHED = -1 };
+    real *vlist;
+
+    assert(A);
+    assert(SparseMatrix_known_strucural_symmetric(A));
+    ia = A->ia;
+    ja = A->ja;
+    m = A->m;
+    n = A->n;
+    assert(n == m);
+    *cluster = N_GNEW(m, int);
+    *clusterp = N_GNEW(m + 1, int);
+    matched = N_GNEW(m, int);
+    vlist = N_GNEW(2 * m, real);
+
+    for (i = 0; i < m; i++)
+       matched[i] = i;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+    assert(A->type == MATRIX_TYPE_REAL);
+
+    *ncluster = 0;
+    (*clusterp)[0] = 0;
+    nz = 0;
+    a = (real *) A->a;
+
+    p = random_permutation(m);
+    for (ii = 0; ii < m; ii++) {
+       i = p[ii];
+       if (matched[i] == MATCHED || node_degree(i) != 1)
+           continue;
+       q = ja[ia[i]];
+       assert(matched[q] != MATCHED);
+       matched[q] = MATCHED;
+       (*cluster)[nz++] = q;
+       for (j = ia[q]; j < ia[q + 1]; j++) {
+           if (q == ja[j])
+               continue;
+           if (node_degree(ja[j]) == 1) {
+               matched[ja[j]] = MATCHED;
+               (*cluster)[nz++] = ja[j];
+           }
+       }
+       ncmax = MAX(ncmax, nz - (*clusterp)[*ncluster]);
+       nz0 = (*clusterp)[*ncluster];
+       if (nz - nz0 <= MAX_CLUSTER_SIZE) {
+           (*clusterp)[++(*ncluster)] = nz;
+       } else {
+           (*clusterp)[++(*ncluster)] = ++nz0;
+           nzz = nz0;
+           for (k = nz0; k < nz && nzz < nz; k++) {
+               nzz += MAX_CLUSTER_SIZE - 1;
+               nzz = MIN(nz, nzz);
+               (*clusterp)[++(*ncluster)] = nzz;
+           }
+       }
     }
-    if (nv > 0){
-      qsort(vlist, nv, sizeof(real)*2, scomp);
-      for (j = 0; j < MIN(csize - 1, nv); j++){
-       iv = (int) vlist[2*j];
-       matched[iv] = MATCHED;
-       (*cluster)[nz++] = iv;
-      }
-      matched[i] = MATCHED;
-      (*cluster)[nz++] = i;
-      (*clusterp)[++(*ncluster)] = nz;
+
+    for (ii = 0; ii < m; ii++) {
+       i = p[ii];
+       if (matched[i] == MATCHED)
+           continue;
+       nv = 0;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           if (i == ja[j])
+               continue;
+           if (matched[ja[j]] != MATCHED && matched[i] != MATCHED) {
+               vlist[2 * nv] = ja[j];
+               vlist[2 * nv + 1] = a[j];
+               nv++;
+           }
+       }
+       if (nv > 0) {
+           qsort(vlist, nv, sizeof(real) * 2, scomp);
+           for (j = 0; j < MIN(csize - 1, nv); j++) {
+               iv = (int) vlist[2 * j];
+               matched[iv] = MATCHED;
+               (*cluster)[nz++] = iv;
+           }
+           matched[i] = MATCHED;
+           (*cluster)[nz++] = i;
+           (*clusterp)[++(*ncluster)] = nz;
+       }
     }
-  }
-  
-  /* dan yi dian, wu ban */
-  for (i = 0; i < m; i++){
-    if (matched[i] == i){
-      (*cluster)[nz++] = i;
-      (*clusterp)[++(*ncluster)] = nz;
+
+    /* dan yi dian, wu ban */
+    for (i = 0; i < m; i++) {
+       if (matched[i] == i) {
+           (*cluster)[nz++] = i;
+           (*clusterp)[++(*ncluster)] = nz;
+       }
     }
-  }
-  FREE(p);
+    free(p);
 
 
-  FREE(matched);
+    free(matched);
 }
-static void maximal_independent_edge_set_heavest_edge_pernode_scaled(SparseMatrix A, int randomize, int **matching, int *nmatch){
-  int i, ii, j, *ia, *ja, m, n, *p = NULL;
-  real *a, amax = 0;
-  int first = TRUE, jamax = 0;
-
-  assert(A);
-  assert(SparseMatrix_known_strucural_symmetric(A));
-  ia = A->ia;
-  ja = A->ja;
-  m = A->m;
-  n = A->n;
-  assert(n == m);
-  *matching = MALLOC(sizeof(int)*m);
-  for (i = 0; i < m; i++) (*matching)[i] = i;
-  *nmatch = n;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
-  assert(A->type == MATRIX_TYPE_REAL);
-
-  a = (real*) A->a;
-  if (!randomize){
-    for (i = 0; i < m; i++){
-      first = TRUE;
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
-         if (first) {
-           amax = a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]);
-           jamax = ja[j];
-           first = FALSE;
-         } else {
-           if (a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]) > amax){
-             amax = a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]);
-             jamax = ja[j];
-           }
-         }
-       }
-      }
-      if (!first){
-         (*matching)[jamax] = i;
-         (*matching)[i] = jamax;
-         (*nmatch)--;
-      }
-    }
-  } else {
-    p = random_permutation(m);
-    for (ii = 0; ii < m; ii++){
-      i = p[ii];
-      if ((*matching)[i] != i) continue;
-      first = TRUE;
-      for (j = ia[i]; j < ia[i+1]; j++){
-       if (i == ja[j]) continue;
-       if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i){
-         if (first) {
-           amax = a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]);
-           jamax = ja[j];
-           first = FALSE;
-         } else {
-           if (a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]) > amax){
-             amax = a[j]/(ia[i+1]-ia[i])/(ia[ja[j]+1]-ia[ja[j]]);
-             jamax = ja[j];
-           }
-         }
-       }
-      }
-      if (!first){
-         (*matching)[jamax] = i;
-         (*matching)[i] = jamax;
-         (*nmatch)--;
-      }
+static void
+maximal_independent_edge_set_heavest_edge_pernode_scaled(SparseMatrix * A,
+                                                        int randomize,
+                                                        int **matching,
+                                                        int *nmatch)
+{
+    int i, ii, j, *ia, *ja, m, n, *p = NULL;
+    real *a, amax = 0;
+    int first = TRUE, jamax = 0;
+
+    assert(A);
+    assert(SparseMatrix_known_strucural_symmetric(A));
+    ia = A->ia;
+    ja = A->ja;
+    m = A->m;
+    n = A->n;
+    assert(n == m);
+    *matching = N_GNEW(m, int);
+    for (i = 0; i < m; i++)
+       (*matching)[i] = i;
+    *nmatch = n;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+    assert(A->type == MATRIX_TYPE_REAL);
+
+    a = (real *) A->a;
+    if (!randomize) {
+       for (i = 0; i < m; i++) {
+           first = TRUE;
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i) {
+                   if (first) {
+                       amax =
+                           a[j] / (ia[i + 1] - ia[i]) / (ia[ja[j] + 1] -
+                                                         ia[ja[j]]);
+                       jamax = ja[j];
+                       first = FALSE;
+                   } else {
+                       if (a[j] / (ia[i + 1] - ia[i]) /
+                           (ia[ja[j] + 1] - ia[ja[j]]) > amax) {
+                           amax =
+                               a[j] / (ia[i + 1] -
+                                       ia[i]) / (ia[ja[j] + 1] -
+                                                 ia[ja[j]]);
+                           jamax = ja[j];
+                       }
+                   }
+               }
+           }
+           if (!first) {
+               (*matching)[jamax] = i;
+               (*matching)[i] = jamax;
+               (*nmatch)--;
+           }
+       }
+    } else {
+       p = random_permutation(m);
+       for (ii = 0; ii < m; ii++) {
+           i = p[ii];
+           if ((*matching)[i] != i)
+               continue;
+           first = TRUE;
+           for (j = ia[i]; j < ia[i + 1]; j++) {
+               if (i == ja[j])
+                   continue;
+               if ((*matching)[ja[j]] == ja[j] && (*matching)[i] == i) {
+                   if (first) {
+                       amax =
+                           a[j] / (ia[i + 1] - ia[i]) / (ia[ja[j] + 1] -
+                                                         ia[ja[j]]);
+                       jamax = ja[j];
+                       first = FALSE;
+                   } else {
+                       if (a[j] / (ia[i + 1] - ia[i]) /
+                           (ia[ja[j] + 1] - ia[ja[j]]) > amax) {
+                           amax =
+                               a[j] / (ia[i + 1] -
+                                       ia[i]) / (ia[ja[j] + 1] -
+                                                 ia[ja[j]]);
+                           jamax = ja[j];
+                       }
+                   }
+               }
+           }
+           if (!first) {
+               (*matching)[jamax] = i;
+               (*matching)[i] = jamax;
+               (*nmatch)--;
+           }
+       }
+       free(p);
     }
-    FREE(p);
-  }
 }
 
-static void Multilevel_coarsen(SparseMatrix A, SparseMatrix *cA, real *node_wgt, real **cnode_wgt,
-                              SparseMatrix *P, SparseMatrix *R, Multilevel_control ctrl, int *coarsen_scheme_used){
-  int *matching = NULL, nmatch, nc, nzc, n, i;
-  int *irn = NULL, *jcn = NULL, *ia = NULL, *ja = NULL;
-  real *val = NULL;
-  SparseMatrix B = NULL;
-  int *vset = NULL, nvset, ncov, j;
-  int *cluster, *clusterp, ncluster;
-
-  assert(A->m == A->n);
-  *cA = NULL;
-  *P = NULL;
-  *R = NULL;
-  n = A->m;
-
-  *coarsen_scheme_used = ctrl->coarsen_scheme;
-
-  switch (ctrl->coarsen_scheme){
-  case COARSEN_HYBRID:
+static void Multilevel_coarsen(SparseMatrix * A, SparseMatrix * *cA,
+                              real * node_wgt, real ** cnode_wgt,
+                              SparseMatrix * *P, SparseMatrix * *R,
+                              Multilevel_control * ctrl,
+                              int *coarsen_scheme_used)
+{
+    int *matching = NULL, nmatch, nc, nzc, n, i;
+    int *irn = NULL, *jcn = NULL, *ia = NULL, *ja = NULL;
+    real *val = NULL;
+    SparseMatrix *B = NULL;
+    int *vset = NULL, nvset, ncov, j;
+    int *cluster, *clusterp, ncluster;
+
+    assert(A->m == A->n);
+    *cA = NULL;
+    *P = NULL;
+    *R = NULL;
+    n = A->m;
+
+    *coarsen_scheme_used = ctrl->coarsen_scheme;
+
+    switch (ctrl->coarsen_scheme) {
+    case COARSEN_HYBRID:
 #ifdef DEBUG_PRINT
-    if (Verbose)
-      fprintf(stderr, "hybrid scheme, try COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST first\n");
+       if (Verbose)
+           fprintf(stderr,
+                   "hybrid scheme, try COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST first\n");
 #endif
-    *coarsen_scheme_used = ctrl->coarsen_scheme =  COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST;
-    Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
+       *coarsen_scheme_used = ctrl->coarsen_scheme =
+           COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST;
+       Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl,
+                          coarsen_scheme_used);
 
-    if (!(*cA)) {
+       if (!(*cA)) {
 #ifdef DEBUG_PRINT
-      if (Verbose)
-        fprintf(stderr, "switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST\n");
+           if (Verbose)
+               fprintf(stderr,
+                       "switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST\n");
 #endif
-      *coarsen_scheme_used = ctrl->coarsen_scheme =  COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST;
-      Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
-    }
+           *coarsen_scheme_used = ctrl->coarsen_scheme =
+               COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST;
+           Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl,
+                              coarsen_scheme_used);
+       }
 
-    if (!(*cA)) {
+       if (!(*cA)) {
 #ifdef DEBUG_PRINT
-      if (Verbose)
-        fprintf(stderr, "switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST\n");
+           if (Verbose)
+               fprintf(stderr,
+                       "switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST\n");
 #endif
-      *coarsen_scheme_used = ctrl->coarsen_scheme =  COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST;
-      Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
-    }
+           *coarsen_scheme_used = ctrl->coarsen_scheme =
+               COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST;
+           Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl,
+                              coarsen_scheme_used);
+       }
 
-    if (!(*cA)) {
+       if (!(*cA)) {
 #ifdef DEBUG_PRINT
-     if (Verbose)
-        fprintf(stderr, "switching to COARSEN_INDEPENDENT_VERTEX_SET\n");
+           if (Verbose)
+               fprintf(stderr,
+                       "switching to COARSEN_INDEPENDENT_VERTEX_SET\n");
 #endif
-      *coarsen_scheme_used = ctrl->coarsen_scheme = COARSEN_INDEPENDENT_VERTEX_SET;
-      Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
-    }
+           *coarsen_scheme_used = ctrl->coarsen_scheme =
+               COARSEN_INDEPENDENT_VERTEX_SET;
+           Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl,
+                              coarsen_scheme_used);
+       }
 
 
-    if (!(*cA)) {
+       if (!(*cA)) {
 #ifdef DEBUG_PRINT
-      if (Verbose)
-        fprintf(stderr, "switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE\n");
+           if (Verbose)
+               fprintf(stderr,
+                       "switching to COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE\n");
 #endif
-      *coarsen_scheme_used = ctrl->coarsen_scheme = COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE;
-      Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl, coarsen_scheme_used);
-    }
-    ctrl->coarsen_scheme = COARSEN_HYBRID;
-    break;
-  case  COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST:
-  case  COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST:
-  case COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST:
-    if (ctrl->coarsen_scheme == COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST) {
-      maximal_independent_edge_set_heavest_edge_pernode_leaves_first(A, ctrl->randomize, &cluster, &clusterp, &ncluster);
-    } else if (ctrl->coarsen_scheme == COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST) {
-      maximal_independent_edge_set_heavest_edge_pernode_supernodes_first(A, ctrl->randomize, &cluster, &clusterp, &ncluster);
-    } else {
-      maximal_independent_edge_set_heavest_cluster_pernode_leaves_first(A, 4, ctrl->randomize, &cluster, &clusterp, &ncluster);
-    }
-    assert(ncluster <= n);
-    nc = ncluster;
-    if (nc > ctrl->min_coarsen_factor*n || nc < ctrl->minsize) {
+           *coarsen_scheme_used = ctrl->coarsen_scheme =
+               COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE;
+           Multilevel_coarsen(A, cA, node_wgt, cnode_wgt, P, R, ctrl,
+                              coarsen_scheme_used);
+       }
+       ctrl->coarsen_scheme = COARSEN_HYBRID;
+       break;
+    case COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST:
+    case COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST:
+    case COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST:
+       if (ctrl->coarsen_scheme ==
+           COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST)
+       {
+           maximal_independent_edge_set_heavest_edge_pernode_leaves_first
+               (A, ctrl->randomize, &cluster, &clusterp, &ncluster);
+       } else if (ctrl->coarsen_scheme ==
+                  COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST)
+       {
+           maximal_independent_edge_set_heavest_edge_pernode_supernodes_first
+               (A, ctrl->randomize, &cluster, &clusterp, &ncluster);
+       } else {
+           maximal_independent_edge_set_heavest_cluster_pernode_leaves_first
+               (A, 4, ctrl->randomize, &cluster, &clusterp, &ncluster);
+       }
+       assert(ncluster <= n);
+       nc = ncluster;
+       if (nc > ctrl->min_coarsen_factor * n || nc < ctrl->minsize) {
 #ifdef DEBUG_PRINT
-      if (Verbose)
-        fprintf(stderr, "nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",nc, n, ctrl->minsize, ctrl->min_coarsen_factor);
+           if (Verbose)
+               fprintf(stderr,
+                       "nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",
+                       nc, n, ctrl->minsize, ctrl->min_coarsen_factor);
 #endif
-      goto RETURN;
-    }
-    irn = MALLOC(sizeof(int)*n);
-    jcn = MALLOC(sizeof(int)*n);
-    val = MALLOC(sizeof(real)*n);
-    nzc = 0; 
-    for (i = 0; i < ncluster; i++){
-      for (j = clusterp[i]; j < clusterp[i+1]; j++){
-       assert(clusterp[i+1] > clusterp[i]);
-       irn[nzc] = cluster[j];
-       jcn[nzc] = i;
-       val[nzc++] = 1.;
-     }
-    }
-    assert(nzc == n);
-    *P = SparseMatrix_from_coordinate_arrays(nzc, n, nc, irn, jcn, (void *) val, MATRIX_TYPE_REAL);
-    *R = SparseMatrix_transpose(*P);
-    B = SparseMatrix_multiply(*R, A);
-    *cA = SparseMatrix_multiply(B, *P); 
-    SparseMatrix_multiply_vector(*R, node_wgt, cnode_wgt, FALSE);
-    *R = SparseMatrix_divide_row_by_degree(*R);
-    SparseMatrix_set_symmetric(*cA);
-    SparseMatrix_set_pattern_symmetric(*cA);
-    *cA = SparseMatrix_remove_diagonal(*cA);
-    break;
-  case COARSEN_INDEPENDENT_EDGE_SET:
-    maximal_independent_edge_set(A, ctrl->randomize, &matching, &nmatch);
-  case COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE:
-    if (ctrl->coarsen_scheme == COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE) 
-      maximal_independent_edge_set_heavest_edge_pernode(A, ctrl->randomize, &matching, &nmatch);
-  case COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_DEGREE_SCALED:
-    if (ctrl->coarsen_scheme == COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_DEGREE_SCALED) 
-      maximal_independent_edge_set_heavest_edge_pernode_scaled(A, ctrl->randomize, &matching, &nmatch);
-    nc = nmatch;
-    if (nc > ctrl->min_coarsen_factor*n || nc < ctrl->minsize) {
+           goto RETURN;
+       }
+       irn = N_GNEW(n, int);
+       jcn = N_GNEW(n, int);
+       val = N_GNEW(n, real);
+       nzc = 0;
+       for (i = 0; i < ncluster; i++) {
+           for (j = clusterp[i]; j < clusterp[i + 1]; j++) {
+               assert(clusterp[i + 1] > clusterp[i]);
+               irn[nzc] = cluster[j];
+               jcn[nzc] = i;
+               val[nzc++] = 1.;
+           }
+       }
+       assert(nzc == n);
+       *P = SparseMatrix_from_coordinate_arrays(nzc, n, nc, irn, jcn,
+                                                (void *) val,
+                                                MATRIX_TYPE_REAL);
+       *R = SparseMatrix_transpose(*P);
+       B = SparseMatrix_multiply(*R, A);
+       *cA = SparseMatrix_multiply(B, *P);
+       SparseMatrix_multiply_vector(*R, node_wgt, cnode_wgt, FALSE);
+       *R = SparseMatrix_divide_row_by_degree(*R);
+       SparseMatrix_set_symmetric(*cA);
+       SparseMatrix_set_pattern_symmetric(*cA);
+       *cA = SparseMatrix_remove_diagonal(*cA);
+       break;
+    case COARSEN_INDEPENDENT_EDGE_SET:
+       maximal_independent_edge_set(A, ctrl->randomize, &matching,
+                                    &nmatch);
+    case COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE:
+       if (ctrl->coarsen_scheme ==
+           COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE)
+           maximal_independent_edge_set_heavest_edge_pernode(A,
+                                                             ctrl->
+                                                             randomize,
+                                                             &matching,
+                                                             &nmatch);
+    case COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_DEGREE_SCALED:
+       if (ctrl->coarsen_scheme ==
+           COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_DEGREE_SCALED)
+           maximal_independent_edge_set_heavest_edge_pernode_scaled(A,
+                                                                    ctrl->
+                                                                    randomize,
+                                                                    &matching,
+                                                                    &nmatch);
+       nc = nmatch;
+       if (nc > ctrl->min_coarsen_factor * n || nc < ctrl->minsize) {
 #ifdef DEBUG_PRINT
-      if (Verbose)
-        fprintf(stderr, "nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",nc, n, ctrl->minsize, ctrl->min_coarsen_factor);
+           if (Verbose)
+               fprintf(stderr,
+                       "nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",
+                       nc, n, ctrl->minsize, ctrl->min_coarsen_factor);
 #endif
-      goto RETURN;
-    }
-    irn = MALLOC(sizeof(int)*n);
-    jcn = MALLOC(sizeof(int)*n);
-    val = MALLOC(sizeof(real)*n);
-    nzc = 0; nc = 0;
-    for (i = 0; i < n; i++){
-      if (matching[i] >= 0){
-       if (matching[i] == i){
-         irn[nzc] = i;
-         jcn[nzc] = nc;
-         val[nzc++] = 1.;
-       } else {
-         irn[nzc] = i;
-         jcn[nzc] = nc;
-         val[nzc++] = 1;
-         irn[nzc] = matching[i];
-         jcn[nzc] = nc;
-         val[nzc++] = 1;
-         matching[matching[i]] = -1;
-       }
-       nc++;
-       matching[i] = -1;
-      }
-    }
-    assert(nc == nmatch);
-    assert(nzc == n);
-    *P = SparseMatrix_from_coordinate_arrays(nzc, n, nc, irn, jcn, (void *) val, MATRIX_TYPE_REAL);
-    *R = SparseMatrix_transpose(*P);
-    B = SparseMatrix_multiply(*R, A);
-    *cA = SparseMatrix_multiply(B, *P); 
-    SparseMatrix_multiply_vector(*R, node_wgt, cnode_wgt, FALSE);
-    *R = SparseMatrix_divide_row_by_degree(*R);
-    SparseMatrix_set_symmetric(*cA);
-    SparseMatrix_set_pattern_symmetric(*cA);
-    *cA = SparseMatrix_remove_diagonal(*cA);
-    break;
-  case COARSEN_INDEPENDENT_VERTEX_SET:
-    maximal_independent_vertex_set(A, ctrl->randomize, &vset, &nvset, &nzc);
-    ia = A->ia;
-    ja = A->ja;
-    nc = nvset;
-    if (nc > ctrl->min_coarsen_factor*n || nc < ctrl->minsize) {
+           goto RETURN;
+       }
+       irn = N_GNEW(n, int);
+       jcn = N_GNEW(n, int);
+       val = N_GNEW(n, real);
+       nzc = 0;
+       nc = 0;
+       for (i = 0; i < n; i++) {
+           if (matching[i] >= 0) {
+               if (matching[i] == i) {
+                   irn[nzc] = i;
+                   jcn[nzc] = nc;
+                   val[nzc++] = 1.;
+               } else {
+                   irn[nzc] = i;
+                   jcn[nzc] = nc;
+                   val[nzc++] = 1;
+                   irn[nzc] = matching[i];
+                   jcn[nzc] = nc;
+                   val[nzc++] = 1;
+                   matching[matching[i]] = -1;
+               }
+               nc++;
+               matching[i] = -1;
+           }
+       }
+       assert(nc == nmatch);
+       assert(nzc == n);
+       *P = SparseMatrix_from_coordinate_arrays(nzc, n, nc, irn, jcn,
+                                                (void *) val,
+                                                MATRIX_TYPE_REAL);
+       *R = SparseMatrix_transpose(*P);
+       B = SparseMatrix_multiply(*R, A);
+       *cA = SparseMatrix_multiply(B, *P);
+       SparseMatrix_multiply_vector(*R, node_wgt, cnode_wgt, FALSE);
+       *R = SparseMatrix_divide_row_by_degree(*R);
+       SparseMatrix_set_symmetric(*cA);
+       SparseMatrix_set_pattern_symmetric(*cA);
+       *cA = SparseMatrix_remove_diagonal(*cA);
+       break;
+    case COARSEN_INDEPENDENT_VERTEX_SET:
+       maximal_independent_vertex_set(A, ctrl->randomize, &vset, &nvset,
+                                      &nzc);
+       ia = A->ia;
+       ja = A->ja;
+       nc = nvset;
+       if (nc > ctrl->min_coarsen_factor * n || nc < ctrl->minsize) {
 #ifdef DEBUG_PRINT
-      if (Verbose)
-        fprintf(stderr, "nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",nc, n, ctrl->minsize, ctrl->min_coarsen_factor);
+           if (Verbose)
+               fprintf(stderr,
+                       "nc = %d, nf = %d, minsz = %d, coarsen_factor = %f coarsening stops\n",
+                       nc, n, ctrl->minsize, ctrl->min_coarsen_factor);
 #endif
-      goto RETURN;
-    }
-    irn = MALLOC(sizeof(int)*nzc);
-    jcn = MALLOC(sizeof(int)*nzc);
-    val = MALLOC(sizeof(real)*nzc);
-    nzc = 0; 
-    for (i = 0; i < n; i++){
-      if (vset[i] == MAX_IND_VTX_SET_U){
-       ncov = 0;
-       for (j = ia[i]; j < ia[i+1]; j++){
-         if (vset[ja[j]] >= MAX_IND_VTX_SET_C){
-           ncov++;
-         }
-       }
-       assert(ncov > 0);
-       for (j = ia[i]; j < ia[i+1]; j++){
-         if (vset[ja[j]] >= MAX_IND_VTX_SET_C){
-           irn[nzc] = i;
-           jcn[nzc] = vset[ja[j]];
-           val[nzc++] = 1./(double) ncov;
-         }
-       }
-      } else {
-       assert(vset[i] >= MAX_IND_VTX_SET_C);
-       irn[nzc] = i;
-       jcn[nzc] = vset[i];
-       val[nzc++] = 1.;
-      }
-    }
+           goto RETURN;
+       }
+       irn = N_GNEW(nzc, int);
+       jcn = N_GNEW(nzc, int);
+       val = N_GNEW(nzc, real);
+       nzc = 0;
+       for (i = 0; i < n; i++) {
+           if (vset[i] == MAX_IND_VTX_SET_U) {
+               ncov = 0;
+               for (j = ia[i]; j < ia[i + 1]; j++) {
+                   if (vset[ja[j]] >= MAX_IND_VTX_SET_C) {
+                       ncov++;
+                   }
+               }
+               assert(ncov > 0);
+               for (j = ia[i]; j < ia[i + 1]; j++) {
+                   if (vset[ja[j]] >= MAX_IND_VTX_SET_C) {
+                       irn[nzc] = i;
+                       jcn[nzc] = vset[ja[j]];
+                       val[nzc++] = 1. / (double) ncov;
+                   }
+               }
+           } else {
+               assert(vset[i] >= MAX_IND_VTX_SET_C);
+               irn[nzc] = i;
+               jcn[nzc] = vset[i];
+               val[nzc++] = 1.;
+           }
+       }
 
-    *P = SparseMatrix_from_coordinate_arrays(nzc, n, nc, irn, jcn, (void *) val, MATRIX_TYPE_REAL);
-    *R = SparseMatrix_transpose(*P);
-    B = SparseMatrix_multiply(*R, A);
-    *cA = SparseMatrix_multiply(B, *P); 
-    SparseMatrix_multiply_vector(*R, node_wgt, cnode_wgt, FALSE);
-    SparseMatrix_set_symmetric(*cA);
-    SparseMatrix_set_pattern_symmetric(*cA);
-    *cA = SparseMatrix_remove_diagonal(*cA);
-    break;
-  default:
-    goto RETURN;
-  }
- RETURN:
-  if (matching) FREE(matching);
-  if (vset) FREE(vset);
-  if (irn) FREE(irn);
-  if (jcn) FREE(jcn);
-  if (val) FREE(val);
-  if (B) SparseMatrix_delete(B);
+       *P = SparseMatrix_from_coordinate_arrays(nzc, n, nc, irn, jcn,
+                                                (void *) val,
+                                                MATRIX_TYPE_REAL);
+       *R = SparseMatrix_transpose(*P);
+       B = SparseMatrix_multiply(*R, A);
+       *cA = SparseMatrix_multiply(B, *P);
+       SparseMatrix_multiply_vector(*R, node_wgt, cnode_wgt, FALSE);
+       SparseMatrix_set_symmetric(*cA);
+       SparseMatrix_set_pattern_symmetric(*cA);
+       *cA = SparseMatrix_remove_diagonal(*cA);
+       break;
+    default:
+       goto RETURN;
+    }
+  RETURN:
+    if (matching)
+       free(matching);
+    if (vset)
+       free(vset);
+    if (irn)
+       free(irn);
+    if (jcn)
+       free(jcn);
+    if (val)
+       free(val);
+    if (B)
+       SparseMatrix_delete(B);
 }
 
-void print_padding(int n){
-  int i;
-  for (i = 0; i < n; i++) fputs (" ", stderr);
+void print_padding(int n)
+{
+    int i;
+    for (i = 0; i < n; i++)
+       fputs(" ", stderr);
 }
-static Multilevel Multilevel_establish(Multilevel grid, Multilevel_control ctrl){
-  Multilevel cgrid;
-  int coarsen_scheme_used;
-  real *cnode_weights = NULL;
-  SparseMatrix P, R, A, cA;
+static Multilevel *Multilevel_establish(Multilevel * grid,
+                                       Multilevel_control * ctrl)
+{
+    Multilevel *cgrid;
+    int coarsen_scheme_used;
+    real *cnode_weights = NULL;
+    SparseMatrix *P, *R, *A, *cA;
 
 #ifdef DEBUG_PRINT
-  if (Verbose) {
-    print_padding(grid->level);
-    fprintf(stderr, "level -- %d, n = %d, nz = %d nz/n = %f\n", grid->level, grid->n, grid->A->nz, grid->A->nz/(double) grid->n);
-  }
+    if (Verbose) {
+       print_padding(grid->level);
+       fprintf(stderr, "level -- %d, n = %d, nz = %d nz/n = %f\n",
+               grid->level, grid->n, grid->A->nz,
+               grid->A->nz / (double) grid->n);
+    }
 #endif
-  A = grid->A;
-  if (grid->level >= ctrl->maxlevel - 1) {
+    A = grid->A;
+    if (grid->level >= ctrl->maxlevel - 1) {
 #ifdef DEBUG_PRINT
-  if (Verbose) {
-    print_padding(grid->level);
-    fprintf(stderr, " maxlevel reached, coarsening stops\n");
-  }
+       if (Verbose) {
+           print_padding(grid->level);
+           fprintf(stderr, " maxlevel reached, coarsening stops\n");
+       }
 #endif
+       return grid;
+    }
+    Multilevel_coarsen(A, &cA, grid->node_weights, &cnode_weights, &P, &R,
+                      ctrl, &coarsen_scheme_used);
+    if (!cA)
+       return grid;
+
+    cgrid = Multilevel_init(cA, cnode_weights);
+    grid->next = cgrid;
+    cgrid->coarsen_scheme_used = coarsen_scheme_used;
+    cgrid->level = grid->level + 1;
+    cgrid->n = cA->m;
+    cgrid->A = cA;
+    cgrid->P = P;
+    grid->R = R;
+    cgrid->prev = grid;
+    cgrid = Multilevel_establish(cgrid, ctrl);
     return grid;
-  }
-  Multilevel_coarsen(A, &cA, grid->node_weights, &cnode_weights, &P, &R, ctrl, &coarsen_scheme_used);
-  if (!cA) return grid;
-
-  cgrid = Multilevel_init(cA, cnode_weights);
-  grid->next = cgrid;
-  cgrid->coarsen_scheme_used = coarsen_scheme_used;
-  cgrid->level = grid->level + 1;
-  cgrid->n = cA->m;
-  cgrid->A = cA;
-  cgrid->P = P;
-  grid->R = R;
-  cgrid->prev = grid;
-  cgrid = Multilevel_establish(cgrid, ctrl);
-  return grid;
-  
-}
 
-Multilevel Multilevel_new(SparseMatrix A0, real *node_weights, Multilevel_control ctrl){
-  Multilevel grid;
-  SparseMatrix A = A0;
-
-  if (!SparseMatrix_is_symmetric(A, FALSE) || A->type != MATRIX_TYPE_REAL){
-    A = SparseMatrix_get_real_adjacency_matrix_symmetrized(A);
-  }
-  grid = Multilevel_init(A, node_weights);
-  grid = Multilevel_establish(grid, ctrl);
-  if (A != A0) grid->delete_top_level_A = TRUE;/* be sure to clean up later */
-  return grid;
 }
 
+Multilevel *Multilevel_new(SparseMatrix * A0, real * node_weights,
+                          Multilevel_control * ctrl)
+{
+    Multilevel *grid;
+    SparseMatrix *A = A0;
 
-Multilevel Multilevel_get_coarsest(Multilevel grid){
-  while (grid->next){
-    grid = grid->next;
-  }
-  return grid;
+    if (!SparseMatrix_is_symmetric(A, FALSE)
+       || A->type != MATRIX_TYPE_REAL) {
+       A = SparseMatrix_get_real_adjacency_matrix_symmetrized(A);
+    }
+    grid = Multilevel_init(A, node_weights);
+    grid = Multilevel_establish(grid, ctrl);
+    if (A != A0)
+       grid->delete_top_level_A = TRUE;        /* be sure to clean up later */
+    return grid;
 }
 
+
+Multilevel *Multilevel_get_coarsest(Multilevel * grid)
+{
+    while (grid->next) {
+       grid = grid->next;
+    }
+    return grid;
+}
index 1fd21125a0130dfe1754dfa6da1c962b64dab631..a1299f2df346ed502d340a2c0458bedbd97ca99b 100644 (file)
@@ -1,49 +1,70 @@
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
 #ifndef MULTILEVEL_H
 #define MULTILEVEL_H
 
 #include "SparseMatrix.h"
 
-typedef struct Multilevel_struct *Multilevel;
-
-struct Multilevel_struct {
-  int level;/* 0, 1, ... */
-  int n;
-  SparseMatrix A;
-  SparseMatrix P; 
-  SparseMatrix R; 
-  real *node_weights;
-  Multilevel next;
-  Multilevel prev;
-  int delete_top_level_A;
-  int coarsen_scheme_used;/* to get from previous level to here */
-};
+typedef struct Multilevel_s {
+    int level;                 /* 0, 1, ... */
+    int n;
+    SparseMatrix *A;
+    SparseMatrix *P;
+    SparseMatrix *R;
+    real *node_weights;
+    struct Multilevel_s *next;
+    struct Multilevel_s *prev;
+    int delete_top_level_A;
+    int coarsen_scheme_used;   /* to get from previous level to here */
+} Multilevel;
 
-enum {MAX_IND_VTX_SET_0 = -100, MAX_IND_VTX_SET_U = -1, MAX_IND_VTX_SET_C = 0};
+enum { MAX_IND_VTX_SET_0 = -100, MAX_IND_VTX_SET_U =
+       -1, MAX_IND_VTX_SET_C = 0 };
 
-enum {MAX_CLUSTER_SIZE = 4};
+enum { MAX_CLUSTER_SIZE = 4 };
 
-enum {EDGE_BASED_STA, COARSEN_INDEPENDENT_EDGE_SET, COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE, COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST, COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST, COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_DEGREE_SCALED, COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST, EDGE_BASED_STO, VERTEX_BASED_STA, COARSEN_INDEPENDENT_VERTEX_SET, VERTEX_BASED_STO, COARSEN_HYBRID};
+enum { EDGE_BASED_STA, COARSEN_INDEPENDENT_EDGE_SET,
+       COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE,
+       COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_LEAVES_FIRST,
+       COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_SUPERNODES_FIRST,
+       COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_EDGE_PERNODE_DEGREE_SCALED,
+       COARSEN_INDEPENDENT_EDGE_SET_HEAVEST_CLUSTER_PERNODE_LEAVES_FIRST,
+       EDGE_BASED_STO, VERTEX_BASED_STA, COARSEN_INDEPENDENT_VERTEX_SET,
+       VERTEX_BASED_STO, COARSEN_HYBRID };
 
 
-struct Multilevel_control_struct {
-  int minsize;
-  real min_coarsen_factor;
-  int maxlevel;
-  int randomize;
-  int coarsen_scheme;
-};
+typedef struct {
+    int minsize;
+    real min_coarsen_factor;
+    int maxlevel;
+    int randomize;
+    int coarsen_scheme;
+} Multilevel_control;
 
-typedef struct Multilevel_control_struct *Multilevel_control;
 
-Multilevel_control Multilevel_control_new();
+Multilevel_control *Multilevel_control_new();
 
-void Multilevel_control_delete(Multilevel_control ctrl);
+void Multilevel_control_delete(Multilevel_control ctrl);
 
-void Multilevel_delete(Multilevel grid);
+void Multilevel_delete(Multilevel grid);
 
-Multilevel Multilevel_new(SparseMatrix A, real *node_weights, Multilevel_control ctrl);
+Multilevel *Multilevel_new(SparseMatrix * A, real * node_weights,
+                          Multilevel_control * ctrl);
 
-Multilevel Multilevel_get_coarsest(Multilevel grid);
+Multilevel *Multilevel_get_coarsest(Multilevel * grid);
 
 void print_padding(int n);
 
index de2eb85105cc4fcb5d3358e147fc88beaaa47921..43cad8dbefc909f09a3eafad4fa79b4ef7748d72 100644 (file)
-#include "general.h"
-#include "LinkedList.h"
-#include "QuadTree.h"
-
-struct node_data_struct {
-  real node_weight;
-  real *coord;
-  real id;
-};
-
-typedef struct node_data_struct *node_data;
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
 
-real point_distance(real *p1, real *p2, int dim){
-  int i;
-  real dist;
-  dist = 0;
-  for (i = 0; i < dim; i++) dist += (p1[i] - p2[i])*(p1[i] - p2[i]);
-  return sqrt(dist);
+#include "QuadTree.h"
+#include "memory.h"
+#include "arith.h"
+#include <math.h>
+#include <assert.h>
+
+typedef struct {
+    real node_weight;
+    real *coord;
+    real id;
+} node_data;
+
+real point_distance(real * p1, real * p2, int dim)
+{
+    int i;
+    real dist;
+    dist = 0;
+    for (i = 0; i < dim; i++)
+       dist += (p1[i] - p2[i]) * (p1[i] - p2[i]);
+    return sqrt(dist);
 }
 
-static node_data node_data_new(int dim, real weight, real *coord, int id){
-  node_data nd;
-  int i;
-  nd = MALLOC(sizeof(struct node_data_struct));
-  nd->node_weight = weight;
-  nd->coord = MALLOC(sizeof(real)*dim);
-  nd->id = id;
-  for (i = 0; i < dim; i++) nd->coord[i] = coord[i];
-  return nd;
+static node_data *node_data_new(int dim, real weight, real * coord, int id)
+{
+    node_data *nd;
+    int i;
+    nd = GNEW(node_data);
+    nd->node_weight = weight;
+    nd->coord = N_GNEW(dim, real);
+    nd->id = id;
+    for (i = 0; i < dim; i++)
+       nd->coord[i] = coord[i];
+    return nd;
 }
 
-void node_data_delete(void *d){
-  node_data nd = (node_data) d;
-  FREE(nd->coord);
-  FREE(nd);
+void node_data_delete(void *d)
+{
+    node_data *nd = (node_data *) d;
+    free(nd->coord);
+    free(nd);
 }
 
-real node_data_get_weight(void *d){
-  node_data nd = (node_data) d;
-  return nd->node_weight;
+real node_data_get_weight(void *d)
+{
+    node_data *nd = (node_data *) d;
+    return nd->node_weight;
 }
 
-real* node_data_get_coord(void *d){
-  node_data nd = (node_data) d;
-  return nd->coord;
+real *node_data_get_coord(void *d)
+{
+    node_data *nd = (node_data *) d;
+    return nd->coord;
 }
 
-int node_data_get_id(void *d){
-  node_data nd = (node_data) d;
-  return nd->id;
+int node_data_get_id(void *d)
+{
+    node_data *nd = (node_data *) d;
+    return nd->id;
 }
 
-void check_or_realloc_arrays(int dim, int *nsuper, int *nsupermax, real **center, real **supernode_wgts, real **distances){
-  
-  if (*nsuper >= *nsupermax) {
-    *nsupermax = *nsuper + MAX(10, (int) 0.2*(*nsuper));
-    *center = REALLOC(*center, sizeof(real)*(*nsupermax)*dim);
-    *supernode_wgts = REALLOC(*supernode_wgts, sizeof(real)*(*nsupermax));
-    *distances = REALLOC(*distances, sizeof(real)*(*nsupermax));
-  }
+int check_or_realloc_arrays(int dim, int nsuper, int nsupermax,
+                           real ** center, real ** supernode_wgts,
+                           real ** distances)
+{
+
+    if (nsuper >= nsupermax) {
+       nsupermax = nsuper + MAX(10, (int) 0.2 * (nsuper));
+       *center = RALLOC(nsupermax * dim, *center, real);
+       *supernode_wgts = RALLOC(nsupermax, *supernode_wgts, real);
+       *distances = RALLOC(nsupermax, *distances, real);
+    }
+    return nsupermax;
 }
 
-void QuadTree_get_supernodes_internal(QuadTree qt, real bh, real *point, int nodeid, int *nsuper, int *nsupermax, real **center, real **supernode_wgts, real **distances, real *counts, int *flag){
-  SingleLinkedList l;
-  real *coord, dist;
-  int dim = qt->dim, i;
-
-  (*counts)++;
-  l = qt->l;
-  if (l){
-    while (l){
-      check_or_realloc_arrays(dim, nsuper, nsupermax, center, supernode_wgts, distances);
-      if (node_data_get_id(SingleLinkedList_get_data(l)) != nodeid){
-       coord = node_data_get_coord(SingleLinkedList_get_data(l));
-       for (i = 0; i < dim; i++){
-         (*center)[dim*(*nsuper)+i] = coord[i];
+void QuadTree_get_supernodes_internal(QuadTree * qt, real bh, real * point,
+                                     int nodeid, int *nsuper,
+                                     int *nsupermax, real ** center,
+                                     real ** supernode_wgts,
+                                     real ** distances, real * counts,
+                                     int *flag)
+{
+    SingleLinkedList *l;
+    real *coord, dist;
+    int dim = qt->dim, i;
+
+    (*counts)++;
+    l = qt->l;
+    if (l) {
+       while (l) {
+           *nsupermax =
+               check_or_realloc_arrays(dim, *nsuper, *nsupermax, center,
+                                       supernode_wgts, distances);
+           if (node_data_get_id(SingleLinkedList_get_data(l)) != nodeid) {
+               coord = node_data_get_coord(SingleLinkedList_get_data(l));
+               for (i = 0; i < dim; i++) {
+                   (*center)[dim * (*nsuper) + i] = coord[i];
+               }
+               (*supernode_wgts)[*nsuper] =
+                   node_data_get_weight(SingleLinkedList_get_data(l));
+               (*distances)[*nsuper] = point_distance(point, coord, dim);
+               (*nsuper)++;
+           }
+           l = SingleLinkedList_get_next(l);
        }
-       (*supernode_wgts)[*nsuper] = node_data_get_weight(SingleLinkedList_get_data(l));
-       (*distances)[*nsuper] = point_distance(point, coord, dim);
-       (*nsuper)++;
-      }
-      l = SingleLinkedList_get_next(l);
     }
-  }
-
-  if (qt->qts){
-    dist = point_distance(qt->center, point, dim); 
-    if (qt->width < bh*dist){
-      check_or_realloc_arrays(dim, nsuper, nsupermax, center, supernode_wgts, distances);
-      for (i = 0; i < dim; i++){
-        (*center)[dim*(*nsuper)+i] = qt->average[i];
-      }
-      (*supernode_wgts)[*nsuper] = qt->total_weight;
-      (*distances)[*nsuper] = point_distance(qt->average, point, dim); 
-      (*nsuper)++;
-    } else {
-      for (i = 0; i < 1<<dim; i++){
-       QuadTree_get_supernodes_internal(qt->qts[i], bh, point, nodeid, nsuper, nsupermax, center, 
-                                        supernode_wgts, distances, counts, flag);
-      }
+
+    if (qt->qts) {
+       dist = point_distance(qt->center, point, dim);
+       if (qt->width < bh * dist) {
+           *nsupermax =
+               check_or_realloc_arrays(dim, *nsuper, *nsupermax, center,
+                                       supernode_wgts, distances);
+           for (i = 0; i < dim; i++) {
+               (*center)[dim * (*nsuper) + i] = qt->average[i];
+           }
+           (*supernode_wgts)[*nsuper] = qt->total_weight;
+           (*distances)[*nsuper] =
+               point_distance(qt->average, point, dim);
+           (*nsuper)++;
+       } else {
+           for (i = 0; i < 1 << dim; i++) {
+               QuadTree_get_supernodes_internal(qt->qts[i], bh, point,
+                                                nodeid, nsuper, nsupermax,
+                                                center, supernode_wgts,
+                                                distances, counts, flag);
+           }
+       }
     }
-  }
 
 }
 
-void QuadTree_get_supernodes(QuadTree qt, real bh, real *point, int nodeid, int *nsuper, 
-                            int *nsupermax, real **center, real **supernode_wgts, real **distances, double *counts, int *flag){
-  int dim = qt->dim;
-
-  (*counts) = 0;
-
-  *nsuper = 0;
-
-  *flag = 0;
-  *nsupermax = 10;
-  if (!*center) *center = MALLOC(sizeof(real)*(*nsupermax)*dim);
-  if (!*supernode_wgts) *supernode_wgts = MALLOC(sizeof(real)*(*nsupermax));
-  if (!*distances) *distances = MALLOC(sizeof(real)*(*nsupermax));
-  QuadTree_get_supernodes_internal(qt, bh, point, nodeid, nsuper, nsupermax, center, supernode_wgts, distances, counts, flag);
+void QuadTree_get_supernodes(QuadTree * qt, real bh, real * point,
+                            int nodeid, int *nsuper, int *nsupermax,
+                            real ** center, real ** supernode_wgts,
+                            real ** distances, double *counts, int *flag)
+{
+    int dim = qt->dim;
+
+    (*counts) = 0;
+
+    *nsuper = 0;
+
+    *flag = 0;
+    *nsupermax = 10;
+    if (!*center)
+       *center = N_GNEW((*nsupermax) * dim, real);
+    if (!*supernode_wgts)
+       *supernode_wgts = N_GNEW(*nsupermax, real);
+    if (!*distances)
+       *distances = N_GNEW(*nsupermax, real);
+    QuadTree_get_supernodes_internal(qt, bh, point, nodeid, nsuper,
+                                    nsupermax, center, supernode_wgts,
+                                    distances, counts, flag);
 
 }
 
 
 
-QuadTree QuadTree_new_from_point_list(int dim, int n, int max_level, real *coord, real *weight){
-  /* form a new QuadTree data structure from a list of coordinates of n points
-     coord: of length n*dim, point i sits at [i*dim, i*dim+dim - 1]
-     weight: node weight of lentgth n. If NULL, unit weight assumed.
-   */
-  real *xmin, *xmax, *center, width;
-  QuadTree qt = NULL;
-  int i, k;
-
-  xmin = MALLOC(sizeof(real)*dim);
-  xmax = MALLOC(sizeof(real)*dim);
-  center = MALLOC(sizeof(real)*dim);
-  if (!xmin || !xmax || !center) return NULL;
-
-  for (i = 0; i < dim; i++) xmin[i] = coord[i];
-  for (i = 0; i < dim; i++) xmax[i] = coord[i];
-
-  for (i = 1; i < n; i++){
-    for (k = 0; k < dim; k++){
-      xmin[k] = MIN(xmin[k], coord[i*dim+k]);
-      xmax[k] = MAX(xmax[k], coord[i*dim+k]);
+QuadTree *QuadTree_new_from_point_list(int dim, int n, int max_level,
+                                      real * coord, real * weight)
+{
+    /* form a new QuadTree data structure from a list of coordinates of n points
+       coord: of length n*dim, point i sits at [i*dim, i*dim+dim - 1]
+       weight: node weight of lentgth n. If NULL, unit weight assumed.
+     */
+    real *xmin, *xmax, *center, width;
+    QuadTree *qt = NULL;
+    int i, k;
+
+    xmin = N_GNEW(dim, real);
+    xmax = N_GNEW(dim, real);
+    center = N_GNEW(dim, real);
+    if (!xmin || !xmax || !center)
+       return NULL;
+
+    for (i = 0; i < dim; i++)
+       xmin[i] = coord[i];
+    for (i = 0; i < dim; i++)
+       xmax[i] = coord[i];
+
+    for (i = 1; i < n; i++) {
+       for (k = 0; k < dim; k++) {
+           xmin[k] = MIN(xmin[k], coord[i * dim + k]);
+           xmax[k] = MAX(xmax[k], coord[i * dim + k]);
+       }
     }
-  }
-
-  width = xmax[0] - xmin[0];
-  for (i = 0; i < dim; i++) {
-    center[i] = (xmin[i] + xmax[i])*0.5;
-    width = MAX(width, xmax[i] - xmin[i]);
-  }
-  width *= 0.52;
-  qt = QuadTree_new(dim, center, width, max_level);
-
-  if (weight){
-    for (i = 0; i < n; i++){
-      qt = QuadTree_add(qt, &(coord[i*dim]), weight[i], i);
+
+    width = xmax[0] - xmin[0];
+    for (i = 0; i < dim; i++) {
+       center[i] = (xmin[i] + xmax[i]) * 0.5;
+       width = MAX(width, xmax[i] - xmin[i]);
     }
-  } else {
-    for (i = 0; i < n; i++){
-      qt = QuadTree_add(qt, &(coord[i*dim]), 1, i);
+    width *= 0.52;
+    qt = QuadTree_new(dim, center, width, max_level);
+
+    if (weight) {
+       for (i = 0; i < n; i++) {
+           qt = QuadTree_add(qt, &(coord[i * dim]), weight[i], i);
+       }
+    } else {
+       for (i = 0; i < n; i++) {
+           qt = QuadTree_add(qt, &(coord[i * dim]), 1, i);
+       }
     }
-  }
 
 
-  FREE(xmin);
-  FREE(xmax);
-  FREE(center);
-  return qt;
+    free(xmin);
+    free(xmax);
+    free(center);
+    return qt;
 }
 
-QuadTree QuadTree_new(int dim, real *center, real width, int max_level){
-  QuadTree q;
-  int i;
-  q = MALLOC(sizeof(struct QuadTree_struct));
-  q->dim = dim;
-  q->n = 0;
-  q->center = MALLOC(sizeof(real)*dim);
-  for (i = 0; i < dim; i++) q->center[i] = center[i];
-  assert(width > 0);
-  q->width = width;
-  q->total_weight = 0;
-  q->average = NULL;
-  q->qts = NULL;
-  q->l = NULL;
-  q->max_level = max_level;
-  return q;
+QuadTree *QuadTree_new(int dim, real * center, real width, int max_level)
+{
+    QuadTree *q;
+    int i;
+    q = GNEW(QuadTree);
+    q->dim = dim;
+    q->n = 0;
+    q->center = N_GNEW(dim, real);
+    for (i = 0; i < dim; i++)
+       q->center[i] = center[i];
+    assert(width > 0);
+    q->width = width;
+    q->total_weight = 0;
+    q->average = NULL;
+    q->qts = NULL;
+    q->l = NULL;
+    q->max_level = max_level;
+    return q;
 }
 
-void QuadTree_delete(QuadTree q){
-  int i, dim = q->dim;
-  if (!q) return;
+void QuadTree_delete(QuadTree * q)
+{
+    int i, dim = q->dim;
+    if (!q)
+       return;
+
+    free(q->center);
+    free(q->average);
+    if (q->qts) {
+       for (i = 0; i < 1 << dim; i++) {
+           QuadTree_delete(q->qts[i]);
+       }
+       free(q->qts);
+    }
+    SingleLinkedList_delete(q->l, node_data_delete);
+    free(q);
+}
 
-  FREE(q->center);
-  FREE(q->average);
-  if (q->qts){
-    for (i = 0; i < 1<<dim; i++){
-      QuadTree_delete(q->qts[i]);
+static int QuadTree_get_quadrant(int dim, real * center, real * coord)
+{
+    /* find the quadrant that a point of coordinates coord is going into with reference to the center.
+       if coord - center == {+,-,+,+} = {1,0,1,1}, then it will sit in the i-quadrant where
+       i's binary representation is 1011 (that is, decimal 11).
+     */
+    int d = 0, i;
+
+    for (i = dim - 1; i >= 0; i--) {
+       if (coord[i] - center[i] < 0) {
+           d = 2 * d;
+       } else {
+           d = 2 * d + 1;
+       }
     }
-    FREE(q->qts);
-  }
-  SingleLinkedList_delete(q->l, node_data_delete);
-  FREE(q);
+    return d;
 }
 
-static int QuadTree_get_quadrant(int dim, real *center, real *coord){
-  /* find the quadrant that a point of coordinates coord is going into with reference to the center.
-     if coord - center == {+,-,+,+} = {1,0,1,1}, then it will sit in the i-quadrant where
-     i's binary representation is 1011 (that is, decimal 11).
-   */
-  int d = 0, i;
+static QuadTree *QuadTree_add_internal(QuadTree * q, real * coord,
+                                      real weight, int id, int level)
+{
+    int i, dim = q->dim, ii, k;
+    node_data *nd = NULL;
+    real *center, width;
+    int max_level = q->max_level;
+
+    /* Make sure that coord is within bounding box */
+    for (i = 0; i < q->dim; i++) {
+       if (coord[i] < q->center[i] - q->width
+           || coord[i] > q->center[i] + q->width)
+           return NULL;
+    }
 
-  for (i = dim - 1; i >= 0; i--){
-    if (coord[i] - center[i] < 0){
-      d = 2*d;
+    if (q->n == 0) {
+       /* if this node is empty right now */
+       q->n = 1;
+       q->total_weight = weight;
+       q->average = N_GNEW(dim, real);
+       for (i = 0; i < q->dim; i++)
+           q->average[i] = coord[i];
+       nd = node_data_new(q->dim, weight, coord, id);
+       assert(!(q->l));
+       q->l = SingleLinkedList_new(nd);
+    } else if (level < max_level) {
+       /* otherwise open up into 2^dim quadtrees unless the level is too high */
+       q->total_weight += weight;
+       for (i = 0; i < q->dim; i++)
+           q->average[i] =
+               ((q->average[i]) * q->n + coord[i]) / (q->n + 1);
+       if (!q->qts) {
+           q->qts = N_GNEW(1 << dim, QuadTree *);
+           for (i = 0; i < 1 << dim; i++) {
+               width = (q->width) / 2;
+               q->qts[i] =
+                   QuadTree_new(q->dim, q->center, width, max_level);
+               center = (q->qts[i])->center;   /* right now this has the center for the parent */
+               ii = i;
+               for (k = 0; k < dim; k++) {     /* decompose child id into binary, if {1,0}, say, then
+                                                  add {width/2, -width/2} to the parents' center
+                                                  to get the child's center. */
+                   if (ii % 2 == 0) {
+                       center[k] -= width;
+                   } else {
+                       center[k] += width;
+                   }
+                   ii = (ii - ii % 2) / 2;
+               }
+           }
+       }
+
+       /* done adding new quadtree, now add points to them */
+       /* insert the old node (if exist) and the current node into the appropriate child quadtree */
+       ii = QuadTree_get_quadrant(dim, q->center, coord);
+       assert(ii < 1 << dim && ii >= 0);
+       q->qts[ii] =
+           QuadTree_add_internal(q->qts[ii], coord, weight, id,
+                                 level + 1);
+       assert(q->qts[ii]);
+
+       if (q->l) {
+           assert(q->n == 1);
+           coord = node_data_get_coord(SingleLinkedList_get_data(q->l));
+           weight = node_data_get_weight(SingleLinkedList_get_data(q->l));
+           ii = QuadTree_get_quadrant(dim, q->center, coord);
+           assert(ii < 1 << dim && ii >= 0);
+           q->qts[ii] =
+               QuadTree_add_internal(q->qts[ii], coord, weight, id,
+                                     level + 1);
+           assert(q->qts[ii]);
+
+           /* delete the old node data on parent */
+           SingleLinkedList_delete(q->l, node_data_delete);
+           q->l = NULL;
+       }
+
+       (q->n)++;
     } else {
-      d = 2*d+1;
+       assert(!(q->qts));
+       /* level is too high, append data in the linked list */
+       (q->n)++;
+       q->total_weight += weight;
+       for (i = 0; i < q->dim; i++)
+           q->average[i] =
+               ((q->average[i]) * q->n + coord[i]) / (q->n + 1);
+       nd = node_data_new(q->dim, weight, coord, id);
+       assert(q->l);
+       q->l = SingleLinkedList_prepend(q->l, nd);
     }
-  }
-  return d;
+    return q;
 }
 
-static QuadTree QuadTree_add_internal(QuadTree q, real *coord, real weight, int id, int level){
-  int i, dim = q->dim, ii, k;
-  node_data nd = NULL;
-  real *center, width;
-  int max_level = q->max_level;
-
-  /* Make sure that coord is within bounding box */
-  for (i = 0; i < q->dim; i++) {
-    if (coord[i] < q->center[i] - q->width || coord[i] > q->center[i] + q->width) return NULL;
-  }
-
-  if (q->n == 0){
-    /* if this node is empty right now */
-    q->n = 1;
-    q->total_weight = weight;
-    q->average = MALLOC(sizeof(real)*dim);
-    for (i = 0; i < q->dim; i++) q->average[i] = coord[i];
-    nd = node_data_new(q->dim, weight, coord, id);
-    assert(!(q->l));
-    q->l = SingleLinkedList_new(nd);
-  } else if (level < max_level){
-    /* otherwise open up into 2^dim quadtrees unless the level is too high */
-    q->total_weight += weight;
-    for (i = 0; i < q->dim; i++) q->average[i] = ((q->average[i])*q->n + coord[i])/(q->n + 1);
-    if (!q->qts){
-      q->qts = MALLOC(sizeof(QuadTree)*(1<<dim));
-      for (i = 0; i < 1<<dim; i++){
-       width = (q->width)/2;
-       q->qts[i] = QuadTree_new(q->dim, q->center, width, max_level);
-       center = (q->qts[i])->center;/* right now this has the center for the parent */
-       ii = i;
-       for (k = 0; k < dim; k++){/* decompose child id into binary, if {1,0}, say, then
-                                    add {width/2, -width/2} to the parents' center
-                                    to get the child's center. */
-         if (ii%2 == 0){
-           center[k]  -= width;
-         } else {
-           center[k] += width;
-         }
-         ii = (ii - ii%2)/2;
-       }
-      }
-    }/* done adding new quadtree, now add points to them */
-    
-    /* insert the old node (if exist) and the current node into the appropriate child quadtree */
-    ii = QuadTree_get_quadrant(dim, q->center, coord);
-    assert(ii < 1<<dim && ii >= 0);
-    q->qts[ii] = QuadTree_add_internal(q->qts[ii], coord, weight, id, level + 1);
-    assert(q->qts[ii]);
-
-    if (q->l){
-      assert(q->n == 1);
-      coord = node_data_get_coord(SingleLinkedList_get_data(q->l));
-      weight = node_data_get_weight(SingleLinkedList_get_data(q->l));
-      ii = QuadTree_get_quadrant(dim, q->center, coord);
-      assert(ii < 1<<dim && ii >= 0);
-      q->qts[ii] = QuadTree_add_internal(q->qts[ii], coord, weight, id, level + 1);
-      assert(q->qts[ii]);
-
-      /* delete the old node data on parent */
-      SingleLinkedList_delete(q->l, node_data_delete);
-      q->l = NULL;
-    }
 
-    (q->n)++;
-  } else {
-    assert(!(q->qts));
-    /* level is too high, append data in the linked list */
-    (q->n)++;
-    q->total_weight += weight;
-    for (i = 0; i < q->dim; i++) q->average[i] = ((q->average[i])*q->n + coord[i])/(q->n + 1);
-    nd = node_data_new(q->dim, weight, coord, id);
-    assert(q->l);
-    q->l = SingleLinkedList_prepend(q->l, nd);
-  }
-  return q;
+QuadTree *QuadTree_add(QuadTree * q, real * coord, real weight, int id)
+{
+    if (!q)
+       return q;
+    return QuadTree_add_internal(q, coord, weight, id, 0);
+
 }
 
+static void draw_polygon(FILE * fp, int dim, real * center, real width)
+{
+    /* pliot the enclosing square */
+    if (dim < 2 || dim > 3)
+       return;
+    fprintf(fp, "(*in c*){Line[{");
+
+    if (dim == 2) {
+       fprintf(fp, "{%f, %f}", center[0] + width, center[1] + width);
+       fprintf(fp, ",{%f, %f}", center[0] - width, center[1] + width);
+       fprintf(fp, ",{%f, %f}", center[0] - width, center[1] - width);
+       fprintf(fp, ",{%f, %f}", center[0] + width, center[1] - width);
+       fprintf(fp, ",{%f, %f}", center[0] + width, center[1] + width);
+    } else if (dim == 3) {
+       /* top */
+       fprintf(fp, "{");
+       fprintf(fp, "{%f, %f, %f}", center[0] + width, center[1] + width,
+               center[2] + width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] + width,
+               center[2] + width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] - width,
+               center[2] + width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] - width,
+               center[2] + width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] + width,
+               center[2] + width);
+       fprintf(fp, "},");
+       /* bot */
+       fprintf(fp, "{");
+       fprintf(fp, "{%f, %f, %f}", center[0] + width, center[1] + width,
+               center[2] - width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] + width,
+               center[2] - width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] - width,
+               center[2] - width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] - width,
+               center[2] - width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] + width,
+               center[2] - width);
+       fprintf(fp, "},");
+       /* for sides */
+       fprintf(fp, "{");
+       fprintf(fp, "{%f, %f, %f}", center[0] + width, center[1] + width,
+               center[2] - width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] + width,
+               center[2] + width);
+       fprintf(fp, "},");
+
+       fprintf(fp, "{");
+       fprintf(fp, "{%f, %f, %f}", center[0] - width, center[1] + width,
+               center[2] - width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] + width,
+               center[2] + width);
+       fprintf(fp, "},");
+
+       fprintf(fp, "{");
+       fprintf(fp, "{%f, %f, %f}", center[0] + width, center[1] - width,
+               center[2] - width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] - width,
+               center[2] + width);
+       fprintf(fp, "},");
+
+       fprintf(fp, "{");
+       fprintf(fp, "{%f, %f, %f}", center[0] - width, center[1] - width,
+               center[2] - width);
+       fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] - width,
+               center[2] + width);
+       fprintf(fp, "}");
+    }
 
-QuadTree QuadTree_add(QuadTree q, real *coord, real weight, int id){
-  if (!q) return q;
-  return QuadTree_add_internal(q, coord, weight, id, 0);
-  
-}
 
-static void draw_polygon(FILE *fp, int dim, real *center, real width){
-  /* pliot the enclosing square */
-  if (dim < 2 || dim > 3) return;
-  fprintf(fp,"(*in c*){Line[{");
-
-  if (dim == 2){
-    fprintf(fp, "{%f, %f}", center[0] + width, center[1] + width);
-    fprintf(fp, ",{%f, %f}", center[0] - width, center[1] + width);
-    fprintf(fp, ",{%f, %f}", center[0] - width, center[1] - width);
-    fprintf(fp, ",{%f, %f}", center[0] + width, center[1] - width);
-    fprintf(fp, ",{%f, %f}", center[0] + width, center[1] + width);
-  } else if (dim == 3){
-    /* top */
-    fprintf(fp,"{");
-    fprintf(fp, "{%f, %f, %f}", center[0] + width, center[1] + width, center[2] + width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] + width, center[2] + width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] - width, center[2] + width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] - width, center[2] + width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] + width, center[2] + width);
-    fprintf(fp,"},");
-    /* bot */
-    fprintf(fp,"{");
-    fprintf(fp, "{%f, %f, %f}", center[0] + width, center[1] + width, center[2] - width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] + width, center[2] - width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] - width, center[2] - width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] - width, center[2] - width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] + width, center[2] - width);
-    fprintf(fp,"},");
-    /* for sides */
-    fprintf(fp,"{");
-    fprintf(fp, "{%f, %f, %f}", center[0] + width, center[1] + width, center[2] - width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] + width, center[2] + width);
-    fprintf(fp,"},");
-    
-    fprintf(fp,"{");
-    fprintf(fp, "{%f, %f, %f}", center[0] - width, center[1] + width, center[2] - width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] + width, center[2] + width);
-    fprintf(fp,"},");
-    
-    fprintf(fp,"{");
-    fprintf(fp, "{%f, %f, %f}", center[0] + width, center[1] - width, center[2] - width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] + width, center[1] - width, center[2] + width);
-    fprintf(fp,"},");
-    
-    fprintf(fp,"{");
-    fprintf(fp, "{%f, %f, %f}", center[0] - width, center[1] - width, center[2] - width);
-    fprintf(fp, ",{%f, %f, %f}", center[0] - width, center[1] - width, center[2] + width);
-    fprintf(fp,"}");
-  }
-
-
-  fprintf(fp, "}]}(*end C*)");
+    fprintf(fp, "}]}(*end C*)");
 
 
 }
-static void QuadTree_print_internal(FILE *fp, QuadTree q, int level){
-  /* dump a quad tree in Mathematica format. */
-  SingleLinkedList l, l0;
-  real *coord;
-  int i, dim = q->dim;
-
-  draw_polygon(fp, q->dim, q->center, q->width);
-  
-  l0 = l = q->l;
-  if (l){
-    printf(",(*a*) {Red,");
-    while (l){
-      if (l != l0) printf(",");
-      coord = node_data_get_coord(SingleLinkedList_get_data(l));
-      fprintf(fp, "Point[{");
-      for (i = 0; i < dim; i++){
-       if (i != 0) printf(",");
-       fprintf(fp, "%f",coord[i]);
-      }
-      fprintf(fp, "}]");
-      l = SingleLinkedList_get_next(l);
+static void QuadTree_print_internal(FILE * fp, QuadTree * q, int level)
+{
+    /* dump a quad tree in Mathematica format. */
+    SingleLinkedList *l;
+    SingleLinkedList *l0;
+    real *coord;
+    int i, dim = q->dim;
+
+    draw_polygon(fp, q->dim, q->center, q->width);
+
+    l0 = l = q->l;
+    if (l) {
+       printf(",(*a*) {Red,");
+       while (l) {
+           if (l != l0)
+               printf(",");
+           coord = node_data_get_coord(SingleLinkedList_get_data(l));
+           fprintf(fp, "Point[{");
+           for (i = 0; i < dim; i++) {
+               if (i != 0)
+                   printf(",");
+               fprintf(fp, "%f", coord[i]);
+           }
+           fprintf(fp, "}]");
+           l = SingleLinkedList_get_next(l);
+       }
+       fprintf(fp, "}");
     }
-    fprintf(fp, "}");
-  }
-
-  if (q->qts){
-    for (i = 0; i < 1<<dim; i++){
-      fprintf(fp, ",(*b*){");
-      QuadTree_print_internal(fp, q->qts[i], level + 1); 
-      fprintf(fp, "}");
+
+    if (q->qts) {
+       for (i = 0; i < 1 << dim; i++) {
+           fprintf(fp, ",(*b*){");
+           QuadTree_print_internal(fp, q->qts[i], level + 1);
+           fprintf(fp, "}");
+       }
     }
-  }
 
 
 }
 
-void QuadTree_print(FILE *fp, QuadTree q){
-  if (!fp) return;
-  if (q->dim == 2){
-    fprintf(fp, "Graphics[{");
-  } else if (q->dim == 3){
-    fprintf(fp, "Graphics3D[{");
-  } else {
-    return;
-  }
-  QuadTree_print_internal(fp, q, 0);
-  if (q->dim == 2){
-    fprintf(fp, "}, PlotRange -> All, Frame -> True, FrameTicks -> True]\n");
-  } else {
-    fprintf(fp, "}, PlotRange -> All]\n");
-  }
+void QuadTree_print(FILE * fp, QuadTree * q)
+{
+    if (!fp)
+       return;
+    if (q->dim == 2) {
+       fprintf(fp, "Graphics[{");
+    } else if (q->dim == 3) {
+       fprintf(fp, "Graphics3D[{");
+    } else {
+       return;
+    }
+    QuadTree_print_internal(fp, q, 0);
+    if (q->dim == 2) {
+       fprintf(fp,
+               "}, PlotRange -> All, Frame -> True, FrameTicks -> True]\n");
+    } else {
+       fprintf(fp, "}, PlotRange -> All]\n");
+    }
 }
index a1417e24d680ad9e06b36c2706f5573e94052a9d..643a8a928bc25829165d8b179cb126dde7640bad 100644 (file)
@@ -1,37 +1,61 @@
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#ifndef QUAD_TREE_H
+#define QUAD_TREE_H
+
 #include "LinkedList.h"
+#include "sfdpinternal.h"
+#include <stdio.h>
 
-typedef struct QuadTree_struct *QuadTree;
+typedef struct QuadTree_struct QuadTree;
 
 struct QuadTree_struct {
-  /* a data structure containing coordinates of n items, their average is in "average".
-     The current level is a square or cube of width "width", which is subdivided into 
-     2^dim QuadTrees qts. At the last level, all coordinates are stored in a single linked list l. 
-     total_weight is the combined weights of the nodes */
-  int n;/* number of items */
-  real total_weight;
-  int dim;
-  real *center;/* center of the bounding box, array of dimension dim. Allocated inside */
-  real width;/* center +/- width gives the lower/upper bound, so really width is the 
-               "radius" */
-  real *average;/* the average coordinates. Array of length dim. Allocated inside  */
-  QuadTree *qts;/* subtree . If dim = 2, there are 4, dim = 3 gives 8 */
-  SingleLinkedList l;
-  int max_level;
+    /* a data structure containing coordinates of n items, their average is in "average".
+       The current level is a square or cube of width "width", which is subdivided into 
+       2^dim QuadTrees qts. At the last level, all coordinates are stored in a single linked list l. 
+       total_weight is the combined weights of the nodes */
+    int n;                     /* number of items */
+    real total_weight;
+    int dim;
+    real *center;              /* center of the bounding box, array of dimension dim. Allocated inside */
+    real width;                        /* center +/- width gives the lower/upper bound, so really width is the 
+                                  "radius" */
+    real *average;             /* the average coordinates. Array of length dim. Allocated inside  */
+    QuadTree **qts;            /* subtree . If dim = 2, there are 4, dim = 3 gives 8 */
+    SingleLinkedList *l;
+    int max_level;
 };
 
 
-QuadTree QuadTree_new(int dim, real *center, real width, int max_level);
+QuadTree *QuadTree_new(int dim, real * center, real width, int max_level);
 
-void QuadTree_delete(QuadTree q);
+void QuadTree_delete(QuadTree q);
 
-QuadTree QuadTree_add(QuadTree q, real *coord, real weight, int id);/* coord is copied in */
+QuadTree *QuadTree_add(QuadTree * q, real * coord, real weight, int id);       /* coord is copied in */
 
-void QuadTree_print(FILE *fp, QuadTree q);
+void QuadTree_print(FILE * fp, QuadTree * q);
 
-QuadTree QuadTree_new_from_point_list(int dim, int n, int max_level, real *coord, real *weight);
+QuadTree *QuadTree_new_from_point_list(int dim, int n, int max_level,
+                                      real * coord, real * weight);
 
-real point_distance(real *p1, real *p2, int dim);
+real point_distance(real * p1, real * p2, int dim);
 
-void QuadTree_get_supernodes(QuadTree qt, real bh, real *point, int nodeid, int *nsuper, 
-                            int *nsupermax, real **center, real **supernode_wgts, real **distances, real *counts, int *flag);
+void QuadTree_get_supernodes(QuadTree * qt, real bh, real * point,
+                            int nodeid, int *nsuper, int *nsupermax,
+                            real ** center, real ** supernode_wgts,
+                            real ** distances, real * counts, int *flag);
 
+#endif
index 34342f57409ae5d84145e76a5efa099f054482ef..f89247c5f140fef3cea0368130ea34a74310da2b 100644 (file)
-#include "general.h"
-#include "SparseMatrix.h"
-#include "spring_electrical.h"
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
 
 #include "post_process.h"
+#include "spring_electrical.h"
 #include "sparse_solve.h"
 #include "call_tri.h"
+#include "types.h"
+#include "memory.h"
+#include "globals.h"
 #include <time.h>
+#include <string.h>
+#include <math.h>
 
 #define node_degree(i) (ia[(i)+1] - ia[(i)])
 
-
-
-SparseMatrix ideal_distance_matrix(SparseMatrix A, int dim, real *x){
-  /* find the ideal distance between edges, either 1, or |N[i] \Union N[j]| - |N[i] \Intersection N[j]|
-   */
-  SparseMatrix D;
-  int *ia, *ja, i, j, k, l, nz;
-  real *d;
-  int *mask = NULL;
-  real len, di, sum, sumd;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
-
-  D = SparseMatrix_copy(A);
-  ia = D->ia;
-  ja = D->ja;
-  if (D->type != MATRIX_TYPE_REAL){
-    FREE(D->a);
-    D->type = MATRIX_TYPE_REAL;
-    D->a = MALLOC(sizeof(real)*D->nz);
-  }
-  d = (real*) D->a;
-
-  mask = MALLOC(sizeof(int)*D->m);
-  for (i = 0; i < D->m; i++) mask[i] = -1;
-
-  for (i = 0; i < D->m; i++){
-    di = node_degree(i);
-    mask[i] = i;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      if (i == ja[j]) continue;
-      mask[ja[j]] = i;
+SparseMatrix *ideal_distance_matrix(SparseMatrix * A, int dim, real * x)
+{
+    /* find the ideal distance between edges, either 1, or |N[i] \Union N[j]| - |N[i] \Intersection N[j]|
+     */
+    SparseMatrix *D;
+    int *ia, *ja, i, j, k, l, nz;
+    real *d;
+    int *mask = NULL;
+    real len, di, sum, sumd;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+
+    D = SparseMatrix_copy(A);
+    ia = D->ia;
+    ja = D->ja;
+    if (D->type != MATRIX_TYPE_REAL) {
+       free(D->a);
+       D->type = MATRIX_TYPE_REAL;
+       D->a = N_GNEW(D->nz, real);
     }
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      if (i == k) continue;
-      len = di + node_degree(k);
-      for (l = ia[k]; l < ia[k+1]; l++){
-       if (mask[ja[l]] == i) len--;
-      }
-      d[j] = len;
-      assert(len > 0);
+    d = (real *) D->a;
+
+    mask = N_GNEW(D->m, int);
+    for (i = 0; i < D->m; i++)
+       mask[i] = -1;
+
+    for (i = 0; i < D->m; i++) {
+       di = node_degree(i);
+       mask[i] = i;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           if (i == ja[j])
+               continue;
+           mask[ja[j]] = i;
+       }
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           if (i == k)
+               continue;
+           len = di + node_degree(k);
+           for (l = ia[k]; l < ia[k + 1]; l++) {
+               if (mask[ja[l]] == i)
+                   len--;
+           }
+           d[j] = len;
+           assert(len > 0);
+       }
+
     }
-    
-  }
-
-  sum = 0; sumd = 0;
-  nz = 0;
-  for (i = 0; i < D->m; i++){
-    for (j = ia[i]; j < ia[i+1]; j++){
-      if (i == ja[j]) continue;
-      nz++;
-      sum += distance(x, dim, i, ja[j]);
-      sumd += d[j];
+
+    sum = 0;
+    sumd = 0;
+    nz = 0;
+    for (i = 0; i < D->m; i++) {
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           if (i == ja[j])
+               continue;
+           nz++;
+           sum += distance(x, dim, i, ja[j]);
+           sumd += d[j];
+       }
     }
-  }
-  sum /= nz; sumd /= nz;
-  sum = sum/sumd;
-
-  for (i = 0; i < D->m; i++){
-    for (j = ia[i]; j < ia[i+1]; j++){
-      if (i == ja[j]) continue;
-      d[j] = sum*d[j];
+    sum /= nz;
+    sumd /= nz;
+    sum = sum / sumd;
+
+    for (i = 0; i < D->m; i++) {
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           if (i == ja[j])
+               continue;
+           d[j] = sum * d[j];
+       }
     }
-  }
 
 
-  return D;
+    return D;
 }
 
-StressMajorizationSmoother StressMajorizationSmoother_new(SparseMatrix A, int dim, real lambda0, real *x, 
-                                                         int ideal_dist_scheme){
-  StressMajorizationSmoother sm;
-  int i, j, k, l, m = A->m, *ia = A->ia, *ja = A->ja, *iw, *jw, *id, *jd;
-  int *mask, nz;
-  real *d, *w, *lambda;
-  real *avg_dist, diag_d, diag_w, *dd, dist, s = 0, stop = 0, sbot = 0;
-  SparseMatrix ID;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
-
-  ID = ideal_distance_matrix(A, dim, x);
-  dd = (real*) ID->a;
+StressMajorizationSmoother *StressMajorizationSmoother_new(SparseMatrix *
+                                                          A, int dim,
+                                                          real lambda0,
+                                                          real * x,
+                                                          int
+                                                          ideal_dist_scheme)
+{
+    StressMajorizationSmoother *sm;
+    int i, j, k, l, m = A->m, *ia = A->ia, *ja = A->ja, *iw, *jw, *id, *jd;
+    int *mask, nz;
+    real *d, *w, *lambda;
+    real *avg_dist, diag_d, diag_w, *dd, dist, s = 0, stop = 0, sbot = 0;
+    SparseMatrix *ID;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+
+    ID = ideal_distance_matrix(A, dim, x);
+    dd = (real *) ID->a;
+
+    sm = GNEW(StressMajorizationSmoother);
+    lambda = sm->lambda = N_GNEW(m, real);
+    for (i = 0; i < m; i++)
+       sm->lambda[i] = lambda0;
+    mask = N_GNEW(m, int);
+
+    avg_dist = N_GNEW(m, real);
+
+    for (i = 0; i < m; i++) {
+       avg_dist[i] = 0;
+       nz = 0;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           if (i == ja[j])
+               continue;
+           avg_dist[i] += distance(x, dim, i, ja[j]);
+           nz++;
+       }
+       assert(nz > 0);
+       avg_dist[i] /= nz;
+    }
 
-  sm = MALLOC(sizeof(struct StressMajorizationSmoother_struct));
-  lambda = sm->lambda = MALLOC(sizeof(real)*m);
-  for (i = 0; i < m; i++) sm->lambda[i] = lambda0;
-  mask = MALLOC(sizeof(int)*m);
 
-  avg_dist = MALLOC(sizeof(real)*m);
+    for (i = 0; i < m; i++)
+       mask[i] = -1;
 
-  for (i = 0; i < m ;i++){
-    avg_dist[i] = 0;
     nz = 0;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      if (i == ja[j]) continue;
-      avg_dist[i] += distance(x, dim, i, ja[j]);
-      nz++;
+    for (i = 0; i < m; i++) {
+       mask[i] = i;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           if (mask[k] != i) {
+               mask[k] = i;
+               nz++;
+           }
+       }
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           for (l = ia[k]; l < ia[k + 1]; l++) {
+               if (mask[ja[l]] != i) {
+                   mask[ja[l]] = i;
+                   nz++;
+               }
+           }
+       }
     }
-    assert(nz > 0);
-    avg_dist[i] /= nz;
-  }
 
+    sm->Lw = SparseMatrix_new(m, m, nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
+    sm->Lwd = SparseMatrix_new(m, m, nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
+    if (!(sm->Lw) || !(sm->Lwd)) {
+       StressMajorizationSmoother_delete(sm);
+       return NULL;
+    }
 
-  for (i = 0; i < m; i++) mask[i] = -1;
+    iw = sm->Lw->ia;
+    jw = sm->Lw->ja;
+    id = sm->Lwd->ia;
+    jd = sm->Lwd->ja;
+    w = (real *) sm->Lw->a;
+    d = (real *) sm->Lwd->a;
+    iw[0] = id[0] = 0;
 
-  nz = 0;
-  for (i = 0; i < m; i++){
-    mask[i] = i;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      if (mask[k] != i){
-       mask[k] = i;
-       nz++;
-      }
-    }
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      for (l = ia[k]; l < ia[k+1]; l++){
-       if (mask[ja[l]] != i){
-         mask[ja[l]] = i;
-         nz++;
+    nz = 0;
+    for (i = 0; i < m; i++) {
+       mask[i] = i + m;
+       diag_d = diag_w = 0;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           if (mask[k] != i + m) {
+               mask[k] = i + m;
+
+               jw[nz] = k;
+               if (ideal_dist_scheme == IDEAL_GRAPH_DIST) {
+                   dist = 1;
+               } else if (ideal_dist_scheme == IDEAL_AVG_DIST) {
+                   dist = (avg_dist[i] + avg_dist[k]) * 0.5;
+               } else if (ideal_dist_scheme == IDEAL_POWER_DIST) {
+                   dist = pow(distance_cropped(x, dim, i, k), .4);
+               } else {
+                   fprintf(stderr, "ideal_dist_scheme value wrong");
+                   assert(0);
+                   exit(1);
+               }
+
+               /*      
+                  w[nz] = -1./(ia[i+1]-ia[i]+ia[ja[j]+1]-ia[ja[j]]);
+                  w[nz] = -2./(avg_dist[i]+avg_dist[k]); */
+               /* w[nz] = -1.; *//* use unit weight for now, later can try 1/(deg(i)+deg(k)) */
+               w[nz] = -1 / (dist * dist);
+
+               diag_w += w[nz];
+
+               jd[nz] = k;
+               /*
+                  d[nz] = w[nz]*distance(x,dim,i,k);
+                  d[nz] = w[nz]*dd[j];
+                  d[nz] = w[nz]*(avg_dist[i] + avg_dist[k])*0.5;
+                */
+               d[nz] = w[nz] * dist;
+               stop += d[nz] * distance(x, dim, i, k);
+               sbot += d[nz] * dist;
+               diag_d += d[nz];
+
+               nz++;
+           }
        }
-      }
-    }
-  }
 
-  sm->Lw = SparseMatrix_new(m, m, nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
-  sm->Lwd = SparseMatrix_new(m, m, nz + m, MATRIX_TYPE_REAL, FORMAT_CSR);
-  if (!(sm->Lw) || !(sm->Lwd)) {
-    StressMajorizationSmoother_delete(sm);
-    return NULL;
-  }
-
-  iw = sm->Lw->ia; jw = sm->Lw->ja;
-  id = sm->Lwd->ia; jd = sm->Lwd->ja;
-  w = (real*) sm->Lw->a; d = (real*) sm->Lwd->a;
-  iw[0] = id[0] = 0;
-
-  nz = 0;
-  for (i = 0; i < m; i++){
-    mask[i] = i+m;
-    diag_d = diag_w = 0;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      if (mask[k] != i+m){
-       mask[k] = i+m;
-
-       jw[nz] = k;
-       if (ideal_dist_scheme == IDEAL_GRAPH_DIST){
-         dist = 1;
-       } else if (ideal_dist_scheme == IDEAL_AVG_DIST){
-         dist = (avg_dist[i] + avg_dist[k])*0.5;
-       } else if (ideal_dist_scheme == IDEAL_POWER_DIST){
-         dist = pow(distance_cropped(x,dim,i,k),.4);
-       } else {
-         fprintf(stderr,"ideal_dist_scheme value wrong");
-         assert(0);
-         exit(1);
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           for (l = ia[k]; l < ia[k + 1]; l++) {
+               if (mask[ja[l]] != i + m) {
+                   mask[ja[l]] = i + m;
+
+                   if (ideal_dist_scheme == IDEAL_GRAPH_DIST) {
+                       dist = 2;
+                   } else if (ideal_dist_scheme == IDEAL_AVG_DIST) {
+                       dist =
+                           (avg_dist[i] + 2 * avg_dist[k] +
+                            avg_dist[ja[l]]) * 0.5;
+                   } else if (ideal_dist_scheme == IDEAL_POWER_DIST) {
+                       dist = pow(distance_cropped(x, dim, i, ja[l]), .4);
+                   } else {
+                       fprintf(stderr, "ideal_dist_scheme value wrong");
+                       assert(0);
+                       exit(1);
+                   }
+
+                   jw[nz] = ja[l];
+                   /*
+                      w[nz] = -1/(ia[i+1]-ia[i]+ia[ja[l]+1]-ia[ja[l]]);
+                      w[nz] = -2/(avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]]); */
+                   /* w[nz] = -1.; *//* use unit weight for now, later can try 1/(deg(i)+deg(k)) */
+
+                   w[nz] = -1 / (dist * dist);
+
+                   diag_w += w[nz];
+
+                   jd[nz] = ja[l];
+                   /*
+                      d[nz] = w[nz]*(distance(x,dim,i,k)+distance(x,dim,k,ja[l]));
+                      d[nz] = w[nz]*(dd[j]+dd[l]);
+                      d[nz] = w[nz]*(avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]])*0.5;
+                    */
+                   d[nz] = w[nz] * dist;
+                   stop += d[nz] * distance(x, dim, ja[l], k);
+                   sbot += d[nz] * dist;
+                   diag_d += d[nz];
+
+                   nz++;
+               }
+           }
        }
+       jw[nz] = i;
+       lambda[i] *= (-diag_w); /* alternatively don't do that then we have a constant penalty term scaled by lambda0 */
 
-       /*      
-         w[nz] = -1./(ia[i+1]-ia[i]+ia[ja[j]+1]-ia[ja[j]]);
-         w[nz] = -2./(avg_dist[i]+avg_dist[k]);*/
-       /* w[nz] = -1.;*//* use unit weight for now, later can try 1/(deg(i)+deg(k)) */
-       w[nz] = -1/(dist*dist);
-
-       diag_w += w[nz];
-
-       jd[nz] = k;
-       /*
-         d[nz] = w[nz]*distance(x,dim,i,k);
-         d[nz] = w[nz]*dd[j];
-         d[nz] = w[nz]*(avg_dist[i] + avg_dist[k])*0.5;
-       */
-       d[nz] = w[nz]*dist;
-       stop += d[nz]*distance(x,dim,i,k);
-       sbot += d[nz]*dist;
-       diag_d += d[nz];
-
+       w[nz] = -diag_w + lambda[i];
+       jd[nz] = i;
+       d[nz] = -diag_d;
        nz++;
-      }
-    }
 
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      for (l = ia[k]; l < ia[k+1]; l++){
-       if (mask[ja[l]] != i+m){
-         mask[ja[l]] = i+m;
-
-         if (ideal_dist_scheme == IDEAL_GRAPH_DIST){
-           dist = 2;
-         } else if (ideal_dist_scheme == IDEAL_AVG_DIST){
-           dist = (avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]])*0.5;
-         } else if (ideal_dist_scheme == IDEAL_POWER_DIST){
-           dist = pow(distance_cropped(x,dim,i,ja[l]),.4);
-         } else {
-           fprintf(stderr,"ideal_dist_scheme value wrong");
-           assert(0);
-           exit(1);
-         }
-
-         jw[nz] = ja[l];
-         /*
-           w[nz] = -1/(ia[i+1]-ia[i]+ia[ja[l]+1]-ia[ja[l]]);
-           w[nz] = -2/(avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]]);*/
-         /* w[nz] = -1.;*//* use unit weight for now, later can try 1/(deg(i)+deg(k)) */
-
-         w[nz] = -1/(dist*dist);
-
-         diag_w += w[nz];
-
-         jd[nz] = ja[l];
-         /*
-           d[nz] = w[nz]*(distance(x,dim,i,k)+distance(x,dim,k,ja[l]));
-           d[nz] = w[nz]*(dd[j]+dd[l]);
-           d[nz] = w[nz]*(avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]])*0.5;
-         */
-         d[nz] = w[nz]*dist;
-         stop += d[nz]*distance(x,dim,ja[l],k);
-         sbot += d[nz]*dist;
-         diag_d += d[nz];
-
-         nz++;
-       }
-      }
+       iw[i + 1] = nz;
+       id[i + 1] = nz;
     }
-    jw[nz] = i;
-    lambda[i] *= (-diag_w);/* alternatively don't do that then we have a constant penalty term scaled by lambda0 */
-
-    w[nz] = -diag_w + lambda[i];
-    jd[nz] = i;
-    d[nz] = -diag_d;
-    nz++;
-
-    iw[i+1] = nz;
-    id[i+1] = nz;
-  }
-  s = stop/sbot;
-  for (i = 0; i < nz; i++) d[i] *= s;
-
-  sm->Lw->nz = nz;
-  sm->Lwd->nz = nz;
-
-  FREE(mask);
-  FREE(avg_dist);
-  SparseMatrix_delete(ID);
-  return sm;
-}
-
-static real total_distance(int m, int dim, real* x, real* y){
-  real total = 0, dist = 0;
-  int i, j;
+    s = stop / sbot;
+    for (i = 0; i < nz; i++)
+       d[i] *= s;
 
-  for (i = 0; i < m; i++){
-    dist = 0.;
-    for (j = 0; j < dim; j++){
-      dist += (y[i*dim+j] - x[i*dim+j])*(y[i*dim+j] - x[i*dim+j]);
-    }
-    total += sqrt(dist);
-  }
-  return total;
+    sm->Lw->nz = nz;
+    sm->Lwd->nz = nz;
 
+    free(mask);
+    free(avg_dist);
+    SparseMatrix_delete(ID);
+    return sm;
 }
 
+static real total_distance(int m, int dim, real * x, real * y)
+{
+    real total = 0, dist = 0;
+    int i, j;
+
+    for (i = 0; i < m; i++) {
+       dist = 0.;
+       for (j = 0; j < dim; j++) {
+           dist +=
+               (y[i * dim + j] - x[i * dim + j]) * (y[i * dim + j] -
+                                                    x[i * dim + j]);
+       }
+       total += sqrt(dist);
+    }
+    return total;
 
+}
 
-void StressMajorizationSmoother_smooth(StressMajorizationSmoother sm, int dim, real *x, int maxit_sm) {
-  SparseMatrix Lw = sm->Lw, Lwd = sm->Lwd, Lwdd = NULL;
-  int i, j, m, *id, *jd, idiag, flag = 0, iter = 0;
-  real *dd, *d, *y = NULL, *x0 = NULL, diag, diff = 1, tol = 0.001, *lambda = sm->lambda, maxit, res;
-
-  Lwdd = SparseMatrix_copy(Lwd);
-  m = Lw->m;
-  x0 = MALLOC(sizeof(real)*dim*m);
-  if (!x0) goto RETURN;
-
-  x0 = MEMCPY(x0, x, sizeof(real)*dim*m);
-  y = MALLOC(sizeof(real)*dim*m);
-  if (!y) goto RETURN;
 
-  id = Lwd->ia; jd = Lwd->ja;
-  d = (real*) Lwd->a;
-  dd = (real*) Lwdd->a;
 
-  while (iter++ < maxit_sm && diff > tol){
-    for (i = 0; i < m; i++){
-      idiag = -1;
-      diag = 0.;
-      for (j = id[i]; j < id[i+1]; j++){
-       if (i == jd[j]) {
-         idiag = j;
-         continue;
+void StressMajorizationSmoother_smooth(StressMajorizationSmoother * sm,
+                                      int dim, real * x, int maxit_sm)
+{
+    SparseMatrix *Lw = sm->Lw;
+    SparseMatrix *Lwd = sm->Lwd;
+    SparseMatrix *Lwdd = NULL;
+    int i, j, m, *id, *jd, idiag, flag = 0, iter = 0;
+    real *dd, *d, *y = NULL, *x0 = NULL, diag, diff = 1, tol =
+       0.001, *lambda = sm->lambda, maxit, res;
+
+    Lwdd = SparseMatrix_copy(Lwd);
+    m = Lw->m;
+    x0 = N_GNEW(dim * m, real);
+    if (!x0)
+       goto RETURN;
+
+    x0 = memcpy(x0, x, sizeof(real) * dim * m);
+    y = N_GNEW(dim * m, real);
+    if (!y)
+       goto RETURN;
+
+    id = Lwd->ia;
+    jd = Lwd->ja;
+    d = (real *) Lwd->a;
+    dd = (real *) Lwdd->a;
+
+    while (iter++ < maxit_sm && diff > tol) {
+       for (i = 0; i < m; i++) {
+           idiag = -1;
+           diag = 0.;
+           for (j = id[i]; j < id[i + 1]; j++) {
+               if (i == jd[j]) {
+                   idiag = j;
+                   continue;
+               }
+               dd[j] = d[j] / distance_cropped(x, dim, i, jd[j]);
+               diag += dd[j];
+           }
+           assert(idiag >= 0);
+           dd[idiag] = -diag;
        }
-       dd[j] = d[j]/distance_cropped(x, dim, i, jd[j]);
-       diag += dd[j];
-      }
-      assert(idiag >= 0);
-      dd[idiag] = -diag;
-    }
-    /* solve (Lw+lambda*I) x = Lwdd y + lambda x0 */
+       /* solve (Lw+lambda*I) x = Lwdd y + lambda x0 */
 
-    SparseMatrix_multiply_dense(Lwdd, FALSE, x, FALSE, &y, FALSE, dim);
-    for (i = 0; i < m; i++){
-      for (j = 0; j < dim; j++){
-       y[i*dim+j] += lambda[i]*x0[i*dim+j];
-      }
-    }
+       SparseMatrix_multiply_dense(Lwdd, FALSE, x, FALSE, &y, FALSE, dim);
+       for (i = 0; i < m; i++) {
+           for (j = 0; j < dim; j++) {
+               y[i * dim + j] += lambda[i] * x0[i * dim + j];
+           }
+       }
 
-    maxit = sqrt((double) m);
-    res = SparseMatrix_solve(Lw, dim, x, y, 0.01, maxit, SOLVE_METHOD_CG, &flag);
+       maxit = sqrt((double) m);
+       res =
+           SparseMatrix_solve(Lw, dim, x, y, 0.01, maxit, SOLVE_METHOD_CG,
+                              &flag);
 
-    if (flag) goto RETURN;
+       if (flag)
+           goto RETURN;
 
-    diff = total_distance(m, dim, x, y)/m;
+       diff = total_distance(m, dim, x, y) / m;
 #ifdef DEBUG_PRINT
-    if (Verbose){
-      fprintf(stderr, "Outer iter = %d, res = %g Stress Majorization diff = %g\n",iter, res, diff);
-    }
+       if (Verbose) {
+           fprintf(stderr,
+                   "Outer iter = %d, res = %g Stress Majorization diff = %g\n",
+                   iter, res, diff);
+       }
 #endif
-    MEMCPY(x, y, sizeof(real)*m*dim);
-  }
+       memcpy(x, y, sizeof(real) * m * dim);
+    }
 
-#ifdef OVERLAP
-  _statistics[1] += iter-1;
+#ifdef DEBUG
+    _statistics[1] += iter - 1;
 #endif
 
- RETURN:
-  SparseMatrix_delete(Lwdd);
-  if (!x0) FREE(x0);
-  if (!y) FREE(y);
+  RETURN:
+    SparseMatrix_delete(Lwdd);
+    if (!x0)
+       free(x0);
+    if (!y)
+       free(y);
 }
 
-void StressMajorizationSmoother_delete(StressMajorizationSmoother sm){
-  if (!sm) return;
-  if (sm->Lw) SparseMatrix_delete(sm->Lw);
-  if (sm->Lwd) SparseMatrix_delete(sm->Lwd);
-  if (sm->lambda) FREE(sm->lambda);
+void StressMajorizationSmoother_delete(StressMajorizationSmoother * sm)
+{
+    if (!sm)
+       return;
+    if (sm->Lw)
+       SparseMatrix_delete(sm->Lw);
+    if (sm->Lwd)
+       SparseMatrix_delete(sm->Lwd);
+    if (sm->lambda)
+       free(sm->lambda);
 }
 
 
-TriangleSmoother TriangleSmoother_new(SparseMatrix A, int dim, real lambda0, real *x, int use_triangularization){
-  TriangleSmoother sm;
-  int i, j, k, m = A->m, *ia = A->ia, *ja = A->ja, *iw, *jw, *id, *jd, jdiag, nz;
-  SparseMatrix B;
-  real *avg_dist, *lambda, *d, *w, diag_d, diag_w, dist;
-  real s = 0, stop = 0, sbot = 0;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
+TriangleSmoother *TriangleSmoother_new(SparseMatrix * A, int dim,
+                                      real lambda0, real * x,
+                                      int use_triangularization)
+{
+    TriangleSmoother *sm;
+    int i, j, k, m = A->m, *ia = A->ia, *ja =
+       A->ja, *iw, *jw, *id, *jd, jdiag, nz;
+    SparseMatrix *B;
+    real *avg_dist, *lambda, *d, *w, diag_d, diag_w, dist;
+    real s = 0, stop = 0, sbot = 0;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+
+    avg_dist = N_GNEW(m, real);
+
+    for (i = 0; i < m; i++) {
+       avg_dist[i] = 0;
+       nz = 0;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           if (i == ja[j])
+               continue;
+           avg_dist[i] += distance(x, dim, i, ja[j]);
+           nz++;
+       }
+       assert(nz > 0);
+       avg_dist[i] /= nz;
+    }
 
-  avg_dist = MALLOC(sizeof(real)*m);
+    sm = GNEW(TriangleSmoother);
+    lambda = sm->lambda = N_GNEW(m, real);
+    for (i = 0; i < m; i++)
+       sm->lambda[i] = lambda0;
 
-  for (i = 0; i < m ;i++){
-    avg_dist[i] = 0;
-    nz = 0;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      if (i == ja[j]) continue;
-      avg_dist[i] += distance(x, dim, i, ja[j]);
-      nz++;
-    }
-    assert(nz > 0);
-    avg_dist[i] /= nz;
-  }
-
-  sm = MALLOC(sizeof(struct TriangleSmoother_struct));
-  lambda = sm->lambda = MALLOC(sizeof(real)*m);
-  for (i = 0; i < m; i++) sm->lambda[i] = lambda0;
-  
-  if (m > 2){
-    if (use_triangularization){
-      B= call_tri(m, dim, x);
+    if (m > 2) {
+       if (use_triangularization) {
+           B = call_tri(m, dim, x);
+       } else {
+           B = call_tri2(m, dim, x);
+       }
     } else {
-      B= call_tri2(m, dim, x);
+       B = SparseMatrix_copy(A);
     }
-  } else {
-    B = SparseMatrix_copy(A);
-  }
-
-  /*
-  {FILE *fp;
-  fp = fopen("/tmp/111","w");
-  export_embedding(fp, dim, B, x, NULL);
-  fclose(fp);}
-  */
-
-
-  sm->Lw = SparseMatrix_add(A, B);
-
-  SparseMatrix_delete(B);
-  sm->Lwd = SparseMatrix_copy(sm->Lw);
-  if (!(sm->Lw) || !(sm->Lwd)) {
-    TriangleSmoother_delete(sm);
-    return NULL;
-  }
-
-  iw = sm->Lw->ia; jw = sm->Lw->ja;
-  id = sm->Lwd->ia; jd = sm->Lwd->ja;
-  w = (real*) sm->Lw->a; d = (real*) sm->Lwd->a;
-
-  for (i = 0; i < m; i++){
-    diag_d = diag_w = 0;
-    jdiag = -1;
-    for (j = iw[i]; j < iw[i+1]; j++){
-      k = jw[j];
-      if (k == i){
-       jdiag = j;
-       continue;
-      }
-      /*      w[j] = -1./(ia[i+1]-ia[i]+ia[ja[j]+1]-ia[ja[j]]);
-             w[j] = -2./(avg_dist[i]+avg_dist[k]);
-             w[j] = -1.*/;/* use unit weight for now, later can try 1/(deg(i)+deg(k)) */
-      dist = pow(distance_cropped(x,dim,i,k),0.6);
-      w[j] = 1/(dist*dist);
-      diag_w += w[j];
-
-      /*      d[j] = w[j]*distance(x,dim,i,k);
-             d[j] = w[j]*(avg_dist[i] + avg_dist[k])*0.5;*/
-      d[j] = w[j]*dist;
-      stop += d[j]*distance(x,dim,i,k);
-      sbot += d[j]*dist;
-      diag_d += d[j];
 
+    /*
+       {FILE *fp;
+       fp = fopen("/tmp/111","w");
+       export_embedding(fp, dim, B, x, NULL);
+       fclose(fp);}
+     */
+
+
+    sm->Lw = SparseMatrix_add(A, B);
+
+    SparseMatrix_delete(B);
+    sm->Lwd = SparseMatrix_copy(sm->Lw);
+    if (!(sm->Lw) || !(sm->Lwd)) {
+       TriangleSmoother_delete(sm);
+       return NULL;
     }
 
-    lambda[i] *= (-diag_w);/* alternatively don't do that then we have a constant penalty term scaled by lambda0 */
+    iw = sm->Lw->ia;
+    jw = sm->Lw->ja;
+    id = sm->Lwd->ia;
+    jd = sm->Lwd->ja;
+    w = (real *) sm->Lw->a;
+    d = (real *) sm->Lwd->a;
+
+    for (i = 0; i < m; i++) {
+       diag_d = diag_w = 0;
+       jdiag = -1;
+       for (j = iw[i]; j < iw[i + 1]; j++) {
+           k = jw[j];
+           if (k == i) {
+               jdiag = j;
+               continue;
+           }
+           /*      w[j] = -1./(ia[i+1]-ia[i]+ia[ja[j]+1]-ia[ja[j]]);
+              w[j] = -2./(avg_dist[i]+avg_dist[k]);
+                                  w[j] = -1. */ ;
+                               /* use unit weight for now, later can try 1/(deg(i)+deg(k)) */
+           dist = pow(distance_cropped(x, dim, i, k), 0.6);
+           w[j] = 1 / (dist * dist);
+           diag_w += w[j];
+
+           /*      d[j] = w[j]*distance(x,dim,i,k);
+              d[j] = w[j]*(avg_dist[i] + avg_dist[k])*0.5; */
+           d[j] = w[j] * dist;
+           stop += d[j] * distance(x, dim, i, k);
+           sbot += d[j] * dist;
+           diag_d += d[j];
+
+       }
+
+       lambda[i] *= (-diag_w); /* alternatively don't do that then we have a constant penalty term scaled by lambda0 */
 
-    assert(jdiag >= 0);
-    w[jdiag] = -diag_w + lambda[i];
-    d[jdiag] = -diag_d;
-  }
+       assert(jdiag >= 0);
+       w[jdiag] = -diag_w + lambda[i];
+       d[jdiag] = -diag_d;
+    }
 
-  s = stop/sbot;
-  for (i = 0; i < iw[m]; i++) d[i] *= s;
+    s = stop / sbot;
+    for (i = 0; i < iw[m]; i++)
+       d[i] *= s;
 
-  FREE(avg_dist);
+    free(avg_dist);
 
-  return sm;
+    return sm;
 }
 
-void TriangleSmoother_delete(TriangleSmoother sm){
+void TriangleSmoother_delete(TriangleSmoother * sm)
+{
 
-  StressMajorizationSmoother_delete(sm);
+    StressMajorizationSmoother_delete(sm);
 
 }
 
-void TriangleSmoother_smooth(TriangleSmoother sm, int dim, real *x){
+void TriangleSmoother_smooth(TriangleSmoother * sm, int dim, real * x)
+{
 
-  StressMajorizationSmoother_smooth(sm, dim, x, 50);
+    StressMajorizationSmoother_smooth(sm, dim, x, 50);
 }
 
 
 
 
 /* ================================ spring and spring-electrical based smoother ================ */
-SpringSmoother SpringSmoother_new(SparseMatrix A, int dim, spring_electrical_control ctrl, real *x){
-  SpringSmoother sm;
-  int i, j, k, l, m = A->m, *ia = A->ia, *ja = A->ja, *id, *jd;
-  int *mask, nz;
-  real *d, *dd;
-  real *avg_dist;
-  SparseMatrix ID = NULL;
-
-  assert(SparseMatrix_is_symmetric(A, FALSE));
-
-  ID = ideal_distance_matrix(A, dim, x);
-  dd = (real*) ID->a;
+SpringSmoother *SpringSmoother_new(SparseMatrix * A, int dim,
+                                  spring_electrical_control * ctrl,
+                                  real * x)
+{
+    SpringSmoother *sm;
+    int i, j, k, l, m = A->m, *ia = A->ia, *ja = A->ja, *id, *jd;
+    int *mask, nz;
+    real *d, *dd;
+    real *avg_dist;
+    SparseMatrix *ID = NULL;
+
+    assert(SparseMatrix_is_symmetric(A, FALSE));
+
+    ID = ideal_distance_matrix(A, dim, x);
+    dd = (real *) ID->a;
+
+    sm = GNEW(SpringSmoother);
+    mask = N_GNEW(m, int);
+
+    avg_dist = N_GNEW(m, real);
+
+    for (i = 0; i < m; i++) {
+       avg_dist[i] = 0;
+       nz = 0;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           if (i == ja[j])
+               continue;
+           avg_dist[i] += distance(x, dim, i, ja[j]);
+           nz++;
+       }
+       assert(nz > 0);
+       avg_dist[i] /= nz;
+    }
 
-  sm = MALLOC(sizeof(struct SpringSmoother_struct));
-  mask = MALLOC(sizeof(int)*m);
 
-  avg_dist = MALLOC(sizeof(real)*m);
+    for (i = 0; i < m; i++)
+       mask[i] = -1;
 
-  for (i = 0; i < m ;i++){
-    avg_dist[i] = 0;
     nz = 0;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      if (i == ja[j]) continue;
-      avg_dist[i] += distance(x, dim, i, ja[j]);
-      nz++;
+    for (i = 0; i < m; i++) {
+       mask[i] = i;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           if (mask[k] != i) {
+               mask[k] = i;
+               nz++;
+           }
+       }
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           for (l = ia[k]; l < ia[k + 1]; l++) {
+               if (mask[ja[l]] != i) {
+                   mask[ja[l]] = i;
+                   nz++;
+               }
+           }
+       }
     }
-    assert(nz > 0);
-    avg_dist[i] /= nz;
-  }
 
+    sm->D = SparseMatrix_new(m, m, nz, MATRIX_TYPE_REAL, FORMAT_CSR);
+    if (!(sm->D)) {
+       SpringSmoother_delete(sm);
+       return NULL;
+    }
 
-  for (i = 0; i < m; i++) mask[i] = -1;
+    id = sm->D->ia;
+    jd = sm->D->ja;
+    d = (real *) sm->D->a;
+    id[0] = 0;
 
-  nz = 0;
-  for (i = 0; i < m; i++){
-    mask[i] = i;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      if (mask[k] != i){
-       mask[k] = i;
-       nz++;
-      }
-    }
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      for (l = ia[k]; l < ia[k+1]; l++){
-       if (mask[ja[l]] != i){
-         mask[ja[l]] = i;
-         nz++;
+    nz = 0;
+    for (i = 0; i < m; i++) {
+       mask[i] = i + m;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           if (mask[k] != i + m) {
+               mask[k] = i + m;
+               jd[nz] = k;
+               d[nz] = (avg_dist[i] + avg_dist[k]) * 0.5;
+               d[nz] = dd[j];
+               nz++;
+           }
        }
-      }
-    }
-  }
-
-  sm->D = SparseMatrix_new(m, m, nz, MATRIX_TYPE_REAL, FORMAT_CSR);
-  if (!(sm->D)){
-    SpringSmoother_delete(sm);
-    return NULL;
-  }
-
-  id = sm->D->ia; jd = sm->D->ja;
-  d = (real*) sm->D->a;
-  id[0] = 0;
-
-  nz = 0;
-  for (i = 0; i < m; i++){
-    mask[i] = i+m;
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      if (mask[k] != i+m){
-       mask[k] = i+m;
-       jd[nz] = k;
-       d[nz] = (avg_dist[i] + avg_dist[k])*0.5;
-       d[nz] = dd[j];
-       nz++;
-      }
-    }
 
-    for (j = ia[i]; j < ia[i+1]; j++){
-      k = ja[j];
-      for (l = ia[k]; l < ia[k+1]; l++){
-       if (mask[ja[l]] != i+m){
-         mask[ja[l]] = i+m;
-         jd[nz] = ja[l];
-         d[nz] = (avg_dist[i] + 2*avg_dist[k] + avg_dist[ja[l]])*0.5;
-         d[nz] = dd[j]+dd[l];
-         nz++;
+       for (j = ia[i]; j < ia[i + 1]; j++) {
+           k = ja[j];
+           for (l = ia[k]; l < ia[k + 1]; l++) {
+               if (mask[ja[l]] != i + m) {
+                   mask[ja[l]] = i + m;
+                   jd[nz] = ja[l];
+                   d[nz] =
+                       (avg_dist[i] + 2 * avg_dist[k] +
+                        avg_dist[ja[l]]) * 0.5;
+                   d[nz] = dd[j] + dd[l];
+                   nz++;
+               }
+           }
        }
-      }
+       id[i + 1] = nz;
     }
-    id[i+1] = nz;
-  }
-  sm->D->nz = nz;
-  sm->ctrl = spring_electrical_control_new();
-  *(sm->ctrl) = *ctrl;
-  sm->ctrl->random_start = FALSE;
-  sm->ctrl->multilevels = 1;
-  sm->ctrl->step /= 2;
-  sm->ctrl->maxiter = 20;
-
-  FREE(mask);
-  FREE(avg_dist);
-  SparseMatrix_delete(ID);
-
-  return sm;
+    sm->D->nz = nz;
+    sm->ctrl = spring_electrical_control_new();
+    *(sm->ctrl) = *ctrl;
+    sm->ctrl->random_start = FALSE;
+    sm->ctrl->multilevels = 1;
+    sm->ctrl->step /= 2;
+    sm->ctrl->maxiter = 20;
+
+    free(mask);
+    free(avg_dist);
+    SparseMatrix_delete(ID);
+
+    return sm;
 }
 
 
-void SpringSmoother_delete(SpringSmoother sm){
-  if (!sm) return;
-  if (sm->D) SparseMatrix_delete(sm->D);
-  if (sm->ctrl) spring_electrical_control_delete(sm->ctrl);
+void SpringSmoother_delete(SpringSmoother * sm)
+{
+    if (!sm)
+       return;
+    if (sm->D)
+       SparseMatrix_delete(sm->D);
+    if (sm->ctrl)
+       spring_electrical_control_delete(sm->ctrl);
 }
 
 
 
 
-void SpringSmoother_smooth(SpringSmoother sm, SparseMatrix A, real *node_weights, int dim, real *x){
-  int flag = 0;
+void SpringSmoother_smooth(SpringSmoother * sm, SparseMatrix * A,
+                          real * node_weights, int dim, real * x)
+{
+    int flag = 0;
 
-  spring_electrical_spring_embedding(dim, A, sm->D, sm->ctrl, node_weights, x, &flag);
-  assert(!flag);
+    spring_electrical_spring_embedding(dim, A, sm->D, sm->ctrl,
+                                      node_weights, x, &flag);
+    assert(!flag);
 
 }
 
 /*=============================== end of spring and spring-electrical based smoother =========== */
 
-void post_process_smoothing(int dim, SparseMatrix A, spring_electrical_control ctrl, real *node_weights, real *x, int *flag){
-#ifdef TIME
-  clock_t  cpu;
+int post_process_smoothing(int dim, SparseMatrix * A,
+                           spring_electrical_control * ctrl,
+                           real * node_weights, real * x)
+{
+#ifdef DEBUG
+    clock_t cpu = clock();
 #endif
 
-#ifdef TIME
-  cpu = clock();
-#endif
-  *flag = 0;
-
-  switch (ctrl->smoothing){
-  case SMOOTHING_RNG:
-  case SMOOTHING_TRIANGLE:{
-    TriangleSmoother sm;
-    
-    if (ctrl->smoothing == SMOOTHING_RNG){
-      sm = TriangleSmoother_new(A, dim, 0, x, FALSE);
-    } else {
-      sm = TriangleSmoother_new(A, dim, 0, x, TRUE);
-    }
-    TriangleSmoother_smooth(sm, dim, x);
-    TriangleSmoother_delete(sm);
-    break;
-  }
-  case SMOOTHING_STRESS_MAJORIZATION_GRAPH_DIST:
-  case SMOOTHING_STRESS_MAJORIZATION_POWER_DIST:
-  case SMOOTHING_STRESS_MAJORIZATION_AVG_DIST:
-    {
-      StressMajorizationSmoother sm;
-      int k, dist_scheme = IDEAL_AVG_DIST;
-
-      if (ctrl->smoothing == SMOOTHING_STRESS_MAJORIZATION_GRAPH_DIST){
-       dist_scheme = IDEAL_GRAPH_DIST;
-      } else if (ctrl->smoothing == SMOOTHING_STRESS_MAJORIZATION_AVG_DIST){
-       dist_scheme = IDEAL_AVG_DIST;
-      } else if (ctrl->smoothing == SMOOTHING_STRESS_MAJORIZATION_POWER_DIST){
-       dist_scheme = IDEAL_POWER_DIST;
-      }
-
-      for (k = 0; k < 1; k++){
-       sm = StressMajorizationSmoother_new(A, dim, 0.05, x, dist_scheme);
-       StressMajorizationSmoother_smooth(sm, dim, x, 50);
-       StressMajorizationSmoother_delete(sm);
-      }
-      break;
-    }
-  case SMOOTHING_SPRING:{
-    SpringSmoother sm;
-    int k;
-
-    for (k = 0; k < 1; k++){
-      sm = SpringSmoother_new(A, dim, ctrl, x);
-      SpringSmoother_smooth(sm, A, node_weights, dim, x);
-      SpringSmoother_delete(sm);
-    }
+    int flag = 0;
+
+    switch (ctrl->smoothing) {
+    case SMOOTHING_RNG:
+    case SMOOTHING_TRIANGLE:{
+           TriangleSmoother *sm;
+
+           if (ctrl->smoothing == SMOOTHING_RNG) {
+               sm = TriangleSmoother_new(A, dim, 0, x, FALSE);
+           } else {
+               sm = TriangleSmoother_new(A, dim, 0, x, TRUE);
+           }
+           TriangleSmoother_smooth(sm, dim, x);
+           TriangleSmoother_delete(sm);
+           break;
+       }
+    case SMOOTHING_STRESS_MAJORIZATION_GRAPH_DIST:
+    case SMOOTHING_STRESS_MAJORIZATION_POWER_DIST:
+    case SMOOTHING_STRESS_MAJORIZATION_AVG_DIST:
+       {
+           StressMajorizationSmoother *sm;
+           int k, dist_scheme = IDEAL_AVG_DIST;
+
+           if (ctrl->smoothing ==
+               SMOOTHING_STRESS_MAJORIZATION_GRAPH_DIST) {
+               dist_scheme = IDEAL_GRAPH_DIST;
+           } else if (ctrl->smoothing ==
+                      SMOOTHING_STRESS_MAJORIZATION_AVG_DIST) {
+               dist_scheme = IDEAL_AVG_DIST;
+           } else if (ctrl->smoothing ==
+                      SMOOTHING_STRESS_MAJORIZATION_POWER_DIST) {
+               dist_scheme = IDEAL_POWER_DIST;
+           }
+
+           for (k = 0; k < 1; k++) {
+               sm = StressMajorizationSmoother_new(A, dim, 0.05, x,
+                                                   dist_scheme);
+               StressMajorizationSmoother_smooth(sm, dim, x, 50);
+               StressMajorizationSmoother_delete(sm);
+           }
+           break;
+       }
+    case SMOOTHING_SPRING:{
+           SpringSmoother *sm;
+           int k;
 
-    break;
-  }
+           for (k = 0; k < 1; k++) {
+               sm = SpringSmoother_new(A, dim, ctrl, x);
+               SpringSmoother_smooth(sm, A, node_weights, dim, x);
+               SpringSmoother_delete(sm);
+           }
+
+           break;
+       }
 
-  }/* end switch between smoothing methods */
+    }                          /* end switch between smoothing methods */
 
-#ifdef TIME
-  if (Verbose) fprintf(stderr, "post processing %f\n",((real) (clock() - cpu)) / CLOCKS_PER_SEC);
+#ifdef DEBUG
+    if (Verbose)
+       fprintf(stderr, "post processing %f\n",
+               ((real) (clock() - cpu)) / CLOCKS_PER_SEC);
 #endif
+    return flag;
 }
index 771ac202201c07bdaac5b96985c859a2a8bcba7c..5c3932ef90a0bbc637e50ef0f094db33aeeb8232 100644 (file)
@@ -1,44 +1,75 @@
-struct StressMajorizationSmoother_struct {
-  SparseMatrix Lw;
-  SparseMatrix Lwd;
-  real* lambda;
-};
-
-typedef struct StressMajorizationSmoother_struct *StressMajorizationSmoother;
-
-void StressMajorizationSmoother_delete(StressMajorizationSmoother sm);
-
-enum {IDEAL_GRAPH_DIST, IDEAL_AVG_DIST, IDEAL_POWER_DIST};
-StressMajorizationSmoother StressMajorizationSmoother_new(SparseMatrix A, int dim, real lambda, real *x, int ideal_dist_scheme);
-
-void StressMajorizationSmoother_smooth(StressMajorizationSmoother sm, int dim, real *x, int maxit);
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#ifndef POST_PROCESS_H
+#define POST_PROCESS_H
+
+#include <spring_electrical.h>
+
+typedef struct {
+    SparseMatrix *Lw;
+    SparseMatrix *Lwd;
+    real *lambda;
+} StressMajorizationSmoother;
+
+void StressMajorizationSmoother_delete(StressMajorizationSmoother * sm);
+
+enum { IDEAL_GRAPH_DIST, IDEAL_AVG_DIST, IDEAL_POWER_DIST };
+StressMajorizationSmoother *StressMajorizationSmoother_new(SparseMatrix *
+                                                          A, int dim,
+                                                          real lambda,
+                                                          real * x,
+                                                          int
+                                                          ideal_dist_scheme);
+
+void StressMajorizationSmoother_smooth(StressMajorizationSmoother * sm,
+                                      int dim, real * x, int maxit);
 /*-------------------- triangle/neirhborhood graph based smoother ------------------- */
-typedef  StressMajorizationSmoother TriangleSmoother;
+typedef StressMajorizationSmoother TriangleSmoother;
 
-#define TriangleSmoother_struct StressMajorizationSmoother_struct
+/* #define TriangleSmoother_struct StressMajorizationSmoother_struct */
 
-void TriangleSmoother_delete(TriangleSmoother sm);
+void TriangleSmoother_delete(TriangleSmoother sm);
 
-TriangleSmoother TriangleSmoother_new(SparseMatrix A, int dim, real lambda, real *x, int use_triangularization);
+TriangleSmoother *TriangleSmoother_new(SparseMatrix * A, int dim,
+                                      real lambda, real * x,
+                                      int use_triangularization);
 
-void TriangleSmoother_smooth(TriangleSmoother sm, int dim, real *x);
+void TriangleSmoother_smooth(TriangleSmoother * sm, int dim, real * x);
 
 
 
 /*------------------ spring and spring-electrical based smoother */
 
-struct SpringSmoother_struct {
-  SparseMatrix D;
-  spring_electrical_control ctrl;
-};
-
-typedef struct SpringSmoother_struct *SpringSmoother;
+typedef struct {
+    SparseMatrix *D;
+    spring_electrical_control *ctrl;
+} SpringSmoother;
 
-SpringSmoother SpringSmoother_new(SparseMatrix A, int dim, spring_electrical_control ctrl, real *x);
+SpringSmoother *SpringSmoother_new(SparseMatrix * A, int dim,
+                                  spring_electrical_control * ctrl,
+                                  real * x);
 
-void SpringSmoother_delete(SpringSmoother sm);
+void SpringSmoother_delete(SpringSmoother sm);
 
-void SpringSmoother_smooth(SpringSmoother sm, SparseMatrix A, real *node_weights, int dim, real *x);
+void SpringSmoother_smooth(SpringSmoother * sm, SparseMatrix * A,
+                          real * node_weights, int dim, real * x);
 /*------------------------------------------------------------------*/
 
-void post_process_smoothing(int dim, SparseMatrix A, spring_electrical_control ctrl, real *node_weights, real *x, int *flag);
+int post_process_smoothing(int dim, SparseMatrix * A,
+                           spring_electrical_control * ctrl,
+                           real * node_weights, real * x);
+
+#endif