._site

(Arne Babenhauserheide)
2012-07-25: logarithmic binning for the deviation-from-small-world costfunction.

logarithmic binning for the deviation-from-small-world costfunction.

diff --git a/sim.py b/sim.py
--- a/sim.py
+++ b/sim.py
@@ -7,6 +7,7 @@ import numpy as np
 import pylab as pl
 import bisect
 from copy import deepcopy
+import math
 
 def dist(loc0, loc1):
     """return the wraparound distance of 2 nodes in the [0,1) space."""
@@ -19,7 +20,7 @@ def distances(target, nodelist):
         lengths.append(dist(n,target))
     return lengths
 
-def randomnodes(num=1000):
+def randomnodes(num=20000):
     """Generate num nodes with locations between 0 and 1."""
     nodes = set()
     for n in range(num):
@@ -29,7 +30,7 @@ def randomnodes(num=1000):
        nodes.add(n)
     return sorted(list(nodes))
 
-def generateflat(nodes, connectionspernode=10):
+def generateflat(nodes, connectionspernode=20):
     """generate a randomly connected network with the given connectionspernode."""
     net = {}
     for node in nodes:
@@ -76,7 +77,7 @@ def smallworldtargetlocations(node, conn
     shuffle(locs)
     return locs[:connectionspernode]
 
-def generatesmallworldunclean(nodes, connectionspernode=10):
+def generatesmallworldunclean(nodes, connectionspernode=20):
     """generate an ideal small world network with the given connectionspernode."""
 
     net = {}
@@ -159,16 +160,22 @@ def dofold(target, prev, net):
     for conn in connections:
         net[conn] = sorted([c for c in net[conn] if not c == prev] + [realtarget])
 
-def deviationfromsmallworld(distribution, numbins=100):
+def deviationfromsmallworld(distribution, numbins=5):
     """Calculate the deviation of the given local link length
-    distribution from a small world distribution."""
+    distribution from a small world distribution.
+
+    Use logarithmic binning to represent the relevant feature correctly.
+
+    numbins should be clearly less than the number of connections
+    """
     # first define the bin step: upper boundary.
-    bindefupper = [0.5/numbins*(i+1) for i in range(numbins)]
+    #: [0.0005, 0.005, 0.05, 0.5]
+    bindefupper = [0.5/10**((numbins-(i+1))) for i in range(numbins)]
     # then get the total number of links
     numlinks = len(distribution)
     # and define how an ideal bin distribution would look
-    idealbins = [1/((i+1)/numbins) for i in range(numbins)]
-    idealbins = [i/sum(idealbins) for i in idealbins]
+    idealbins = [1/numbins for i in range(numbins)]
+    #idealbins = [i/sum(idealbins) for i in idealbins]
     # now create the real bins
     realbins = [0 for i in range(numbins)]
     for link in distribution:
@@ -178,7 +185,12 @@ def deviationfromsmallworld(distribution
                 break
     #print ("ideal", idealbins)
     #print ("real", realbins)
-    diff = sum(abs(realbins[i] - idealbins[i]) for i in range(numbins))
+    #print ("def", bindefupper)
+    # the difference is the cost
+    diff = sum(abs(realbins[i] - idealbins[i]) for i in range(numbins)) 
+    # add additional cost for highest bin mismatch (they lose that too easily)
+    diff += abs(realbins[-1] - idealbins[-1])
+    #print ([abs(realbins[i] - idealbins[i]) for i in range(numbins)])
     #print("diff", diff)
     #print()
     return diff