In [72]:
from __future__ import print_function
import sdm as sdmlib
from sdm import utils
import matplotlib.pyplot as plt
import numpy as np
from IPython.display import clear_output
%matplotlib inline
In [104]:
bits = 255
radius = 104 #utils.calculate_radius(bits)
sample = 1000000
scanner_type = sdmlib.SDM_SCANNER_OPENCL
In [105]:
address_space = sdmlib.AddressSpace.init_random(bits, sample)
counter = sdmlib.Counter.init_zero(bits, sample)
In [106]:
sdm = sdmlib.SDM(address_space, counter, radius, scanner_type)
In [107]:
bs_ref = sdmlib.Bitstring.init_random(bits)
sdm.write(bs_ref, bs_ref)
In [108]:
def write(n=1000, prefix=''):
print('{}Writing {} random bitstrings... '.format(prefix, n), end='')
for i in range(n):
if i%20 == 0:
print('!', end='')
b = sdmlib.Bitstring.init_random(bits)
sdm.write(b, b)
print('')
return n
In [109]:
def calculate_distances(bs, k=6, sample=1, step=1, prefix='', z=None):
distances = []
x = range(0, bits+1, step)
print('{}Calculating distances... '.format(prefix), end='')
for i, dist in enumerate(x):
if i%20 == 0:
print('!', end='')
v1 = []
for _ in range(sample):
c = sdmlib.Bitstring.init_from_bitstring(bs)
c.flip_random_bits(dist)
assert c.distance_to(bs) == dist
v2 = []
v2.append(c.distance_to(bs))
d = c
for j in range(k):
d = sdm.read(d, z=z)
v2.append(d.distance_to(bs))
v1.append(v2)
distances.append([dist, v1])
print('')
return distances
In [110]:
def plot_heatmap(data, iter_readings):
# Make plot with vertical (default) colorbar
maxd = int(data.max())
mind = int(data.min())
avgd = int ((maxd+mind)/2);
fig = plt.figure(figsize=(8, 6), dpi=100)
ax = fig.add_subplot(111)
#use aspect=20 when N=1000
#use aspect=5 when N=256
from matplotlib.pylab import cm, contourf, contour
cax = ax.imshow(data, cmap=cm.YlGnBu, aspect='auto', interpolation=None, norm=None, origin='lower')
ax.grid(True, label='Distance')
# Add colorbar, make sure to specify tick locations to match desired ticklabels
cbar = fig.colorbar(cax, ticks=[mind, avgd, maxd]) #had ZERO here before
cbar.ax.set_yticklabels([str(mind), str(avgd), str(maxd)])
cbar.ax.set_ylabel(u'Distance obtained after {} iteractive-readings'.format(iter_readings), fontsize=12)
#########CONTOUR DELINEATES THE CRITICAL DISTANCE
# We are using automatic selection of contour levels;
# this is usually not such a good idea, because they don't
# occur on nice boundaries, but we do it here for purposes
# of illustration.
#CS = ax.contourf(data, 100, levels=[mind,avgd,maxd], alpha=0.1, cmap=cm.YlGnBu, origin='lower')
# Note that in the following, we explicitly pass in a subset of
# the contour levels used for the filled contours. Alternatively,
# We could pass in additional levels to provide extra resolution,
# or leave out the levels kwarg to use all of the original levels.
#CS2 = ax.contour(CS, levels=[88], colors='gray', origin='lower', hold='on', linestyles='dashdot')
#CS2 = ax.contour(data, levels=[1,2,3,4,5,6,7,8,9,10], colors='gray', origin='lower', hold='on', linestyles='dashdot')
plt.title('Critical Distance Behavior', fontsize=20)
plt.xlabel('Original distance', fontsize=12)
plt.ylabel('# items previously stored (000\'s)', fontsize=12)
# Add the contour line levels to the colorbar
#cbar.add_lines(CS2)
plt.show()
In [111]:
def get_data(distances, k):
# k = iterative readings
# [(x, y, z)]
# x = old distance
# y = number of writings
# z = new distance
data = []
for writings, v1 in distances:
v = []
for old, v2 in v1:
new = sum(x[k] for x in v2)/len(v2)
#data.append([old, writings, new])
v.append(new)
data.append(v)
return np.array(data)
In [112]:
def run():
import time
start_time = time.time()
distances = []
qty = 1000
n = 10
step = 1
sample = 1
k = 6 # number of iterative readings
total = 0
z = 0.5 #None
for i in range(n):
prefix = '[{}] '.format(total)
total += write(qty, prefix=prefix)
v = calculate_distances(bs_ref, k=k, sample=sample, step=step, prefix=prefix, z=z)
distances.append((total, v))
clear_output(wait=True)
data = get_data(distances, k)
plot_heatmap(data, k)
end_time = time.time()
print('time={:10.0f} time_per_loop={:5.2f}'.format(end_time - start_time, total/(end_time - start_time)))
end_time = time.time()
In [113]:
%time run()
In [ ]: