From 40a5126078b2764232e165e55aaa92f4446b3f79 Mon Sep 17 00:00:00 2001
From: Samuh <quentin@liane.net>
Date: Wed, 24 Mar 2021 15:14:14 +0100
Subject: [PATCH] =?UTF-8?q?Compatibilit=C3=A9=20windows-autre?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 louvain-master/louvain.c   |   4 +-
 louvain-master/partition.c | 334 +++++++++++++++++++++----------------
 2 files changed, 196 insertions(+), 142 deletions(-)

diff --git a/louvain-master/louvain.c b/louvain-master/louvain.c
index 669385f..dbff451 100644
--- a/louvain-master/louvain.c
+++ b/louvain-master/louvain.c
@@ -16,7 +16,9 @@
 
 
 // Version Windows
-#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) 
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
+  #define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
+#endif
 
 
 //compute the maximum of three unsigned long
diff --git a/louvain-master/partition.c b/louvain-master/partition.c
index de9f9c5..19b6c64 100644
--- a/louvain-master/partition.c
+++ b/louvain-master/partition.c
@@ -2,84 +2,100 @@
 
 #define NLINKS2 8
 
-int myCompare (const void * a, const void * b, void * array2) {
+int myCompare(const void *a, const void *b, void *array2)
+{
   long diff = ((unsigned long *)array2)[*(unsigned long *)a] - ((unsigned long *)array2)[*(unsigned *)b];
   int res = (0 < diff) - (diff < 0);
-  return  res;
+  return res;
 }
 
-int myCompare_W (void * array2, const void * a, const void * b) {
+int myCompare_W(void *array2, const void *a, const void *b)
+{
   long diff = ((unsigned long *)array2)[*(unsigned long *)a] - ((unsigned long *)array2)[*(unsigned *)b];
   int res = (0 < diff) - (diff < 0);
-  return  res;
+  return res;
 }
 
-unsigned long * mySort(unsigned long *part, unsigned long size) {
+unsigned long *mySort(unsigned long *part, unsigned long size)
+{
   unsigned long i;
   unsigned long *nodes = (unsigned long *)malloc(size * sizeof(unsigned long));
-  for (i = 0; i < size; i++) {
-    nodes[i]=i;
+  for (i = 0; i < size; i++)
+  {
+    nodes[i] = i;
   }
-  // qsort_r(nodes, size, sizeof(unsigned long), myCompare, (void *)part);
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
   qsort_s(nodes, size, sizeof(unsigned long), myCompare_W, (void *)part);
+#else
+  qsort_r(nodes, size, sizeof(unsigned long), myCompare, (void *)part);
+#endif
   return nodes;
 }
 
-
-
-inline long double degreeWeighted(adjlist *g, unsigned long node) {
+inline long double degreeWeighted(adjlist *g, unsigned long node)
+{
   unsigned long long i;
-  if (g->weights == NULL) {
-    return 1.*(g->cd[node + 1] - g->cd[node]);
+  if (g->weights == NULL)
+  {
+    return 1. * (g->cd[node + 1] - g->cd[node]);
   }
 
   long double res = 0.0L;
-  for (i = g->cd[node]; i < g->cd[node + 1]; i++) {
+  for (i = g->cd[node]; i < g->cd[node + 1]; i++)
+  {
     res += g->weights[i];
   }
   return res;
 }
 
-inline long double selfloopWeighted(adjlist *g, unsigned long node) {
+inline long double selfloopWeighted(adjlist *g, unsigned long node)
+{
   unsigned long long i;
 
-  for (i = g->cd[node]; i < g->cd[node + 1]; i++) {
-    if (g->adj[i] == node) {
-      return (g->weights == NULL)?1.0:g->weights[i];
+  for (i = g->cd[node]; i < g->cd[node + 1]; i++)
+  {
+    if (g->adj[i] == node)
+    {
+      return (g->weights == NULL) ? 1.0 : g->weights[i];
     }
   }
 
   return 0.0;
 }
 
-inline void removeNode(louvainPartition *p, adjlist *g, unsigned long node, unsigned long comm, long double dnodecomm) {
-  p->in[comm]  -= 2.0L * dnodecomm + selfloopWeighted(g, node);
+inline void removeNode(louvainPartition *p, adjlist *g, unsigned long node, unsigned long comm, long double dnodecomm)
+{
+  p->in[comm] -= 2.0L * dnodecomm + selfloopWeighted(g, node);
   p->tot[comm] -= degreeWeighted(g, node);
 }
 
-inline void insertNode(louvainPartition *p, adjlist *g, unsigned long node, unsigned long comm, long double dnodecomm) {
-  p->in[comm]  += 2.0L * dnodecomm + selfloopWeighted(g, node);
+inline void insertNode(louvainPartition *p, adjlist *g, unsigned long node, unsigned long comm, long double dnodecomm)
+{
+  p->in[comm] += 2.0L * dnodecomm + selfloopWeighted(g, node);
   p->tot[comm] += degreeWeighted(g, node);
-  
+
   p->node2Community[node] = comm;
 }
 
-inline long double gain(louvainPartition *p, adjlist *g, unsigned long comm, long double dnc, long double degc) {
+inline long double gain(louvainPartition *p, adjlist *g, unsigned long comm, long double dnc, long double degc)
+{
   long double totc = p->tot[comm];
-  long double m2   = g->totalWeight;
-  
-  return (dnc - totc*degc/m2);
+  long double m2 = g->totalWeight;
+
+  return (dnc - totc * degc / m2);
 }
 
 //freeing memory
-void free_adjlist2(adjlist *g){
+void free_adjlist2(adjlist *g)
+{
   free(g->cd);
   free(g->adj);
   free(g->weights);
   free(g);
 }
 
-void freeLouvainPartition(louvainPartition *p) {
+void freeLouvainPartition(louvainPartition *p)
+{
   free(p->in);
   free(p->tot);
   free(p->neighCommWeights);
@@ -88,8 +104,8 @@ void freeLouvainPartition(louvainPartition *p) {
   free(p);
 }
 
-
-louvainPartition *createLouvainPartition(adjlist *g) {
+louvainPartition *createLouvainPartition(adjlist *g)
+{
   unsigned long i;
 
   louvainPartition *p = malloc(sizeof(louvainPartition));
@@ -104,9 +120,10 @@ louvainPartition *createLouvainPartition(adjlist *g) {
   p->neighCommPos = malloc(p->size * sizeof(unsigned long));
   p->neighCommNb = 0;
 
-  for (i = 0; i < p->size; i++) {
+  for (i = 0; i < p->size; i++)
+  {
     p->node2Community[i] = i;
-    p->in[i]  = selfloopWeighted(g, i);
+    p->in[i] = selfloopWeighted(g, i);
     p->tot[i] = degreeWeighted(g, i);
     p->neighCommWeights[i] = -1;
     p->neighCommPos[i] = 0;
@@ -115,12 +132,14 @@ louvainPartition *createLouvainPartition(adjlist *g) {
   return p;
 }
 
-long double modularity(louvainPartition *p, adjlist *g) {
-  long double q  = 0.0L;
+long double modularity(louvainPartition *p, adjlist *g)
+{
+  long double q = 0.0L;
   long double m2 = g->totalWeight;
   unsigned long i;
 
-  for (i = 0; i < p->size; i++) {
+  for (i = 0; i < p->size; i++)
+  {
     if (p->tot[i] > 0.0L)
       q += p->in[i] - (p->tot[i] * p->tot[i]) / m2;
   }
@@ -128,9 +147,11 @@ long double modularity(louvainPartition *p, adjlist *g) {
   return q / m2;
 }
 
-void neighCommunitiesInit(louvainPartition *p) {
+void neighCommunitiesInit(louvainPartition *p)
+{
   unsigned long i;
-  for (i = 0; i < p->neighCommNb; i++) {
+  for (i = 0; i < p->neighCommNb; i++)
+  {
     p->neighCommWeights[p->neighCommPos[i]] = -1;
   }
   p->neighCommNb = 0;
@@ -139,7 +160,8 @@ void neighCommunitiesInit(louvainPartition *p) {
 /*
 Computes the set of neighbor communities of a given node (excluding self-loops)
 */
-void neighCommunities(louvainPartition *p, adjlist *g, unsigned long node) {
+void neighCommunities(louvainPartition *p, adjlist *g, unsigned long node)
+{
   unsigned long long i;
   unsigned long neigh, neighComm;
   long double neighW;
@@ -148,18 +170,21 @@ void neighCommunities(louvainPartition *p, adjlist *g, unsigned long node) {
   p->neighCommNb = 1;
 
   // for all neighbors of node, add weight to the corresponding community
-  for (i = g->cd[node]; i < g->cd[node + 1]; i++) {
-    neigh  = g->adj[i];
+  for (i = g->cd[node]; i < g->cd[node + 1]; i++)
+  {
+    neigh = g->adj[i];
     neighComm = p->node2Community[neigh];
-    neighW = (g->weights == NULL)?1.0:g->weights[i];
+    neighW = (g->weights == NULL) ? 1.0 : g->weights[i];
 
     // if not a self-loop
-    if (neigh != node) {
+    if (neigh != node)
+    {
       // if community is new (weight == -1)
-      if (p->neighCommWeights[neighComm] == -1) {
-	p->neighCommPos[p->neighCommNb] = neighComm;
-	p->neighCommWeights[neighComm] = 0.;
-	p->neighCommNb++;
+      if (p->neighCommWeights[neighComm] == -1)
+      {
+        p->neighCommPos[p->neighCommNb] = neighComm;
+        p->neighCommWeights[neighComm] = 0.;
+        p->neighCommNb++;
       }
       p->neighCommWeights[neighComm] += neighW;
     }
@@ -171,67 +196,76 @@ Same behavior as neighCommunities except:
 - self loop are counted
 - data structure if not reinitialised
 */
-void neighCommunitiesAll(louvainPartition *p, adjlist *g, unsigned long node) {
+void neighCommunitiesAll(louvainPartition *p, adjlist *g, unsigned long node)
+{
   unsigned long long i;
   unsigned long neigh, neighComm;
   long double neighW;
 
-  for (i = g->cd[node]; i < g->cd[node + 1]; i++) {
-    neigh  = g->adj[i];
+  for (i = g->cd[node]; i < g->cd[node + 1]; i++)
+  {
+    neigh = g->adj[i];
     neighComm = p->node2Community[neigh];
-    neighW = (g->weights == NULL)?1.0:g->weights[i];
-    
+    neighW = (g->weights == NULL) ? 1.0 : g->weights[i];
+
     // if community is new
-    if (p->neighCommWeights[neighComm] == -1) {
+    if (p->neighCommWeights[neighComm] == -1)
+    {
       p->neighCommPos[p->neighCommNb] = neighComm;
-      p->neighCommWeights[neighComm] = 0.;      
+      p->neighCommWeights[neighComm] = 0.;
       p->neighCommNb++;
     }
     p->neighCommWeights[neighComm] += neighW;
   }
 }
 
-
-unsigned long updatePartition(louvainPartition *p, unsigned long *part, unsigned long size) {
+unsigned long updatePartition(louvainPartition *p, unsigned long *part, unsigned long size)
+{
   // Renumber the communities in p
   unsigned long *renumber = calloc(p->size, sizeof(unsigned long));
   unsigned long i, last = 1;
-  for (i = 0; i < p->size; i++) {
-    if (renumber[p->node2Community[i]] == 0) {
+  for (i = 0; i < p->size; i++)
+  {
+    if (renumber[p->node2Community[i]] == 0)
+    {
       renumber[p->node2Community[i]] = last++;
     }
   }
 
   // Update part with the renumbered communities in p
-  for (i = 0; i < size; i++) {
+  for (i = 0; i < size; i++)
+  {
     part[i] = renumber[p->node2Community[part[i]]] - 1;
   }
 
   free(renumber);
-  return last-1;
+  return last - 1;
 }
 
-
 // Return the meta graph induced by a partition of a graph
 // See Louvain article for more details
-adjlist* louvainPartition2Graph(louvainPartition *p, adjlist *g) {
+adjlist *louvainPartition2Graph(louvainPartition *p, adjlist *g)
+{
   unsigned long node, i, j;
   // Renumber communities
   unsigned long *renumber = (unsigned long *)malloc(g->n * sizeof(unsigned long));
   for (node = 0; node < g->n; node++)
     renumber[node] = 0;
   unsigned long last = 1;
-  for (node = 0; node < g->n; node++) {
-    if (renumber[p->node2Community[node]] == 0) {
+  for (node = 0; node < g->n; node++)
+  {
+    if (renumber[p->node2Community[node]] == 0)
+    {
       renumber[p->node2Community[node]] = last++;
     }
   }
-  for (node = 0; node < g->n; node++) {
-    p->node2Community[node] = renumber[p->node2Community[node]] - 1 ;
+  for (node = 0; node < g->n; node++)
+  {
+    p->node2Community[node] = renumber[p->node2Community[node]] - 1;
   }
 
   // sort nodes according to their community
-  unsigned long * order = mySort(p->node2Community, g->n);
+  unsigned long *order = mySort(p->node2Community, g->n);
   //  displayPartU(p->node2Community, g->n);
 
   // Initialize meta graph
@@ -247,53 +281,58 @@ adjlist* louvainPartition2Graph(louvainPartition *p, adjlist *g) {
 
   // for each node (in community order), extract all edges to other communities and build the graph
   neighCommunitiesInit(p);
-  unsigned long oldComm = p->node2Community[order[0]];//renumber[p->node2Community[order[0]]];
+  unsigned long oldComm = p->node2Community[order[0]]; //renumber[p->node2Community[order[0]]];
 
   unsigned long currentComm;
-  for (i = 0; i <= p->size; i++) {
+  for (i = 0; i <= p->size; i++)
+  {
     // current node and current community with dummy values if out of bounds
-    node = (i == p->size)?0:order[i];
-    currentComm = (i == p->size)?currentComm + 1:p->node2Community[order[i]];
-  
+    node = (i == p->size) ? 0 : order[i];
+    currentComm = (i == p->size) ? currentComm + 1 : p->node2Community[order[i]];
+
     // new community, write previous one
-    if (oldComm != currentComm) {
+    if (oldComm != currentComm)
+    {
       res->cd[oldComm + 1] = res->cd[oldComm] + p->neighCommNb;
       //      displayPartU(res->degrees, res->n + 1);
 
       // for all neighboring communities of current community
-      for (j = 0; j < p->neighCommNb; j++) {
-	unsigned long neighComm = p->neighCommPos[j];
-	long double neighCommWeight = p->neighCommWeights[p->neighCommPos[j]];
-
-	// add edge in res
-	res->adj[res->e] = neighComm;
-	res->weights[res->e] = neighCommWeight;
-	res->totalWeight += neighCommWeight;
-	(res->e)++;
-
-	// reallocate edges and weights if necessary
-	if (res->e == e1) {
-	  e1 *= 2;
-	  res->adj = (unsigned long *)realloc(res->adj, e1 * sizeof(unsigned long));
-	  res->weights = (long double *)realloc(res->weights, e1 * sizeof(long double));
-	  if (res->adj == NULL || res->weights == NULL) {
-	    printf("error during memory allocation\n");
-	    exit(0);
-	  }
-	}
-
+      for (j = 0; j < p->neighCommNb; j++)
+      {
+        unsigned long neighComm = p->neighCommPos[j];
+        long double neighCommWeight = p->neighCommWeights[p->neighCommPos[j]];
+
+        // add edge in res
+        res->adj[res->e] = neighComm;
+        res->weights[res->e] = neighCommWeight;
+        res->totalWeight += neighCommWeight;
+        (res->e)++;
+
+        // reallocate edges and weights if necessary
+        if (res->e == e1)
+        {
+          e1 *= 2;
+          res->adj = (unsigned long *)realloc(res->adj, e1 * sizeof(unsigned long));
+          res->weights = (long double *)realloc(res->weights, e1 * sizeof(long double));
+          if (res->adj == NULL || res->weights == NULL)
+          {
+            printf("error during memory allocation\n");
+            exit(0);
+          }
+        }
       }
 
       //      display(res);
 
-      if (i == p->size) {
-	res->adj = (unsigned long *)realloc(res->adj, res->e * sizeof(unsigned long));
-	res->weights = (long double *)realloc(res->weights, res->e * sizeof(long double));
+      if (i == p->size)
+      {
+        res->adj = (unsigned long *)realloc(res->adj, res->e * sizeof(unsigned long));
+        res->weights = (long double *)realloc(res->weights, res->e * sizeof(long double));
 
-	free(order);
-	free(renumber);
+        free(order);
+        free(renumber);
 
-	return res;
+        return res;
       }
 
       oldComm = currentComm;
@@ -310,31 +349,33 @@ adjlist* louvainPartition2Graph(louvainPartition *p, adjlist *g) {
 }
 
 // Compute one pass of Louvain and returns the improvement
-long double louvainOneLevel(louvainPartition *p, adjlist *g) {
+long double louvainOneLevel(louvainPartition *p, adjlist *g)
+{
   unsigned long nbMoves;
   long double startModularity = modularity(p, g);
   long double newModularity = startModularity;
   long double curModularity;
-  unsigned long i,j,node;
-  unsigned long oldComm,newComm,bestComm;
+  unsigned long i, j, node;
+  unsigned long oldComm, newComm, bestComm;
   long double degreeW, bestCommW, bestGain, newGain;
 
-
   // generate a random order for nodes' movements
   unsigned long *randomOrder = (unsigned long *)malloc(p->size * sizeof(unsigned long));
   for (unsigned long i = 0; i < p->size; i++)
     randomOrder[i] = i;
-  for (unsigned long i = 0; i < p->size - 1; i++) {
-    unsigned long randPos = rand()%(p->size - i) + i;
-    unsigned long  tmp = randomOrder[i];
+  for (unsigned long i = 0; i < p->size - 1; i++)
+  {
+    unsigned long randPos = rand() % (p->size - i) + i;
+    unsigned long tmp = randomOrder[i];
     randomOrder[i] = randomOrder[randPos];
     randomOrder[randPos] = tmp;
   }
-  
-  // repeat while 
+
+  // repeat while
   //   there are some nodes moving
-  //   or there is an improvement of quality greater than a given epsilon 
-  do {
+  //   or there is an improvement of quality greater than a given epsilon
+  do
+  {
     curModularity = newModularity;
     nbMoves = 0;
 
@@ -342,8 +383,9 @@ long double louvainOneLevel(louvainPartition *p, adjlist *g) {
     //   remove the node from its community
     //   compute the gain for its insertion in all neighboring communities
     //   insert it in the best community with the highest gain
-    for (i = 0; i < g->n; i++) {
-      node = i;//randomOrder[nodeTmp];
+    for (i = 0; i < g->n; i++)
+    {
+      node = i; //randomOrder[nodeTmp];
       oldComm = p->node2Community[node];
       degreeW = degreeWeighted(g, node);
 
@@ -357,24 +399,27 @@ long double louvainOneLevel(louvainPartition *p, adjlist *g) {
       // compute the gain for all neighboring communities
       // default choice is the former community
       bestComm = oldComm;
-      bestCommW  = 0.0L;
+      bestCommW = 0.0L;
       bestGain = 0.0L;
-      for (j = 0; j < p->neighCommNb; j++) {
-	newComm = p->neighCommPos[j];
-	newGain = gain(p, g, newComm, p->neighCommWeights[newComm], degreeW);
-
-	if (newGain > bestGain) {
-	  bestComm = newComm;
-	  bestCommW = p->neighCommWeights[newComm];
-	  bestGain = newGain;
-	}
+      for (j = 0; j < p->neighCommNb; j++)
+      {
+        newComm = p->neighCommPos[j];
+        newGain = gain(p, g, newComm, p->neighCommWeights[newComm], degreeW);
+
+        if (newGain > bestGain)
+        {
+          bestComm = newComm;
+          bestCommW = p->neighCommWeights[newComm];
+          bestGain = newGain;
+        }
       }
 
       // insert node in the nearest community
       insertNode(p, g, node, bestComm, bestCommW);
 
-      if (bestComm != oldComm) {
-	nbMoves++;
+      if (bestComm != oldComm)
+      {
+        nbMoves++;
       }
     }
 
@@ -382,19 +427,21 @@ long double louvainOneLevel(louvainPartition *p, adjlist *g) {
 
     //    printf("%Lf\n", newModularity);
 
-  } while (nbMoves>0 && 
-    	   newModularity - curModularity > MIN_IMPROVEMENT);
-  
+  } while (nbMoves > 0 &&
+           newModularity - curModularity > MIN_IMPROVEMENT);
+
   free(randomOrder);
 
   return newModularity - startModularity;
 }
 
-unsigned long louvain(adjlist *g, unsigned long *lab) {
-  unsigned long i,n;
+unsigned long louvain(adjlist *g, unsigned long *lab)
+{
+  unsigned long i, n;
   long double improvement;
   // Initialize partition with trivial communities
-  for (i = 0; i < g->n; i++) {
+  for (i = 0; i < g->n; i++)
+  {
     lab[i] = i;
   }
 
@@ -406,44 +453,49 @@ unsigned long louvain(adjlist *g, unsigned long *lab) {
   return n;
 }
 
-unsigned long louvainComplete(adjlist *g, unsigned long *lab) {
+unsigned long louvainComplete(adjlist *g, unsigned long *lab)
+{
   adjlist *init = g, *g2;
   unsigned long n, i;
   unsigned long long j;
   unsigned long originalSize = g->n;
   long double improvement;
   // Initialize partition with trivial communities
-  for (i = 0; i < g->n; i++) {
+  for (i = 0; i < g->n; i++)
+  {
     lab[i] = i;
   }
 
   // Execution of Louvain method
-  while(1) {
+  while (1)
+  {
     louvainPartition *gp = createLouvainPartition(g);
-    
+
     improvement = louvainOneLevel(gp, g);
-    
+
     n = updatePartition(gp, lab, originalSize);
 
-    if (improvement < MIN_IMPROVEMENT) {
+    if (improvement < MIN_IMPROVEMENT)
+    {
       freeLouvainPartition(gp);
       break;
     }
-    
+
     g2 = louvainPartition2Graph(gp, g);
 
     // free all graphs except the original one
-    if (g->n < originalSize) {
+    if (g->n < originalSize)
+    {
       free_adjlist2(g);
     }
     freeLouvainPartition(gp);
     g = g2;
   }
 
-  if (g->n < originalSize) {
+  if (g->n < originalSize)
+  {
     free_adjlist2(g);
   }
 
   return n;
 }
-
-- 
GitLab