In [1]:
from __future__ import print_function
from collections import defaultdict
from math import factorial
import sdm as sdmlib

In [2]:
bits = 1000
sample = 1000000
radius = 451

In [3]:
_comb_cache = {}
def comb(a, b):
    if a < 0:
        return 0
    if b == 0:
        return 1
    ret = _comb_cache.get((a, b), None)
    if ret is None:
        ret = comb(a-1, b) + comb(a-1, b-1)
        _comb_cache[(a, b)] = ret
    return ret

def comb(a, b):
    return factorial(a) // factorial(b) // factorial(a-b)

In [38]:
def genM(n, h):
    M = defaultdict(int)
    for i in range(n):
        x = h+i
        y = i
        if 0 <= x < n and 0 <= y < n:
            M[(x, y)] = comb(n-h, i)

        x = h-i
        y = i
        if 0 <= x < n and 0 <= y < n:
            M[(x, y)] = comb(h, i)

    for j in range(1, h+1):
        mult = M[(h-j, j)]
        for i in range(1, n):
            x = h+i
            y = i
            nx = x - j
            ny = y + j

            if 0 <= x < n and 0 <= y < n and 0 <= nx < n and 0 <= ny < n:
                #print('i={} j={} ({}, {}) ({}, {})'.format(i, j, x, y, nx, ny))
                M[(nx, ny)] = mult * M[(x, y)]

    return M

In [35]:
def printM(M):
    for i in range(n):
        for j in range(n):
            y = n-1-i
            x = j
            if (M[(x, y)]):
                print('{:3d}'.format(M[(x, y)]), end=' ')
            else:
                print('   ', end=' ')
        print('')

In [39]:
def phi2_fn(bits, sample, radius, d):
    total = 0
    M = genM(bits, d)
    for i in range(radius+1):
        for j in range(radius+1):
            total += M[(i, j)]
    return 1.0 * sample * total / (2**bits)

In [7]:
_phi_fn_cache = {}

In [8]:
def phi_fn(n, H, r, d, steps=500):
    key = (n, H, r, d, steps)
    if key in _phi_fn_cache:
        return _phi_fn_cache[key]
    v = []
    for _ in range(steps):
        bs1 = sdmlib.Bitstring.init_random(n)
        bs2 = bs1.copy()
        bs2.flip_random_bits(d)
        selected1 = address_space.scan_thread2(bs1, r)
        selected2 = address_space.scan_thread2(bs2, r)
        x = len(set(selected1) & set(selected2))
        v.append(x)
    mu = 1.0*sum(v)/len(v)
    _phi_fn_cache[key] = mu
    return mu

In [10]:
address_space = sdmlib.AddressSpace.init_random(bits, sample)

In [40]:
h = 102
a = phi_fn(bits, sample, radius, h, steps=200)
b = phi2_fn(bits, sample, radius, h)
(a, b, a-b)


Out[40]:
(280.22, 280.2046153835306, 0.015384616469418688)

In [15]:



Out[15]:
72.90908288196275

In [17]:
for h in range(0, 1001):
    a = phi_fn(bits, sample, radius, h, steps=20)
    b = phi2_fn(bits, sample, radius, h)
    print('{} {} {}'.format(a, b, abs(a-b)))


1072.25 1071.85004892 0.399951076334
964.8 958.436527391 6.36347260943
953.9 958.436527391 4.53652739057
912.9 902.208104539 10.6918954609
901.0 902.208104539 1.20810453914
862.8 860.394028924 2.40597107589
868.25 860.394028924 7.85597107589
826.2 825.8454042 0.354595800216
818.25 825.8454042 7.59540419978
804.6 795.873633311 8.72636668879
788.15 795.873633311 7.72363331121
768.2 769.130488339 0.930488339434
783.2 769.130488339 14.0695116606
742.0 744.827181999 2.82718199914
742.35 744.827181999 2.47718199914
710.15 722.455125934 12.3051259336
722.15 722.455125934 0.305125933626
703.95 701.663613943 2.28638605706
702.6 701.663613943 0.936386057057
678.85 682.198589157 3.34858915679
686.85 682.198589157 4.65141084321
665.55 663.86892494 1.68107506028
671.4 663.86892494 7.53107506028
646.8 646.526475663 0.273524336524
646.5 646.526475663 0.0264756634762
627.65 630.053593212 2.4035932119
635.2 630.053593212 5.1464067881
614.25 614.354954716 0.104954715998
603.55 614.354954716 10.804954716
594.35 599.352010301 5.00201030114
610.85 599.352010301 11.4979896989
589.5 584.979091748 4.52090825168
589.5 584.979091748 4.52090825168
578.0 571.180612164 6.81938783576
571.35 571.180612164 0.169387835762
561.5 557.909004388 3.59099561246
564.45 557.909004388 6.54099561246
548.65 545.123172894 3.52682710641
545.9 545.123172894 0.776827106406
536.7 532.7873109 3.91268909952
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-17-1ef1ac5f9df5> in <module>()
      1 for h in range(0, 1001):
----> 2     a = phi_fn(bits, sample, radius, h, steps=20)
      3     b = phi2_fn(bits, sample, radius, h)
      4     print('{} {} {}'.format(a, b, abs(a-b)))

<ipython-input-8-ef2a5a8798bb> in phi_fn(n, H, r, d, steps)
      9         bs2.flip_random_bits(d)
     10         selected1 = address_space.scan_thread2(bs1, r)
---> 11         selected2 = address_space.scan_thread2(bs2, r)
     12         x = len(set(selected1) & set(selected2))
     13         v.append(x)

/Users/msbrogli/Dropbox/FGV - Doutorado/working-papers/sdm-framework/docs/notebooks/sdm/__init__.pyc in scan_thread2(self, bs, radius, thread_count)
    224     def scan_thread2(self, bs, radius, thread_count=4):
    225         # See https://docs.python.org/3/library/ctypes.html#type-conversions
--> 226         selected = (c_uint * (self.sample))()
    227         cnt = libsdm.as_scan_thread2(pointer(self), bs.bs_data, c_uint(radius), selected, thread_count)
    228         return selected[:cnt]

KeyboardInterrupt: 

In [ ]: