from pylab import *
import time
import scipy.special
%matplotlib inline
plt.rcParams.update({'font.size': 20})
plt.rcParams.update({'text.usetex': True})
matplotlib.rcParams['text.latex.preamble'] = [
r'\usepackage{amsmath}',
r'\usepackage{amssymb}']
plt.rcParams.update({'font.family': 'serif',
'font.serif':['Computer Modern']})
def crvec(N, D=1):
rphase = 2*np.pi * np.random.rand(int(D), int(N))
return np.cos(rphase) + 1.0j * np.sin(rphase)
def scvec(N, D, K):
letter_vectors_c = crvec(N, D)
for d in range(D):
ip = np.random.choice(int(N), size=int(N-K), replace=False)
letter_vectors_c[d, ip] = 0
return letter_vectors_c
def lccvec(N, D, K):
# N needs to be multiple of K
R = N/K
assert(R==N//K)
letter_vectors_c = 0*crvec(N, D)
for d in range(D):
ip = np.random.choice(int(R), size=int(K), replace=True)
ip += int(R) * np.arange(int(K))
letter_vectors_c[d, ip] = crvec(K, 1)
return letter_vectors_c
def cconv(a, b):
return ifft(fft(a) * fft(b))
def ccinv(a):
return ifft(np.conj(fft(a)))
def lccbind(vec1, vec2, Kv):
Nv = vec1.shape[0]
Rv = Nv/Kv
vec1r = np.reshape(vec1, [int(Kv), int(Rv)])
vec2r = np.reshape(vec2, [int(Kv), int(Rv)])
vec_br = cconv(vec1r, vec2r)
vec_b = vec_br.flatten()
return vec_b
def lccinv(vec1, Kv):
Nv = vec1.shape[0]
Rv = Nv/Kv
vec1r = np.reshape(vec1, [int(Kv), int(Rv)])
vec1_ir = ccinv(vec1r)
vec1_i = vec1_ir.flatten()
return vec1_i
Sparse binding demo – What’s the dollar of mexico?#
To demonstrate the binding operation with sparse block code, we replicate the example from Kanerva’s What we mean when we say ‘What’s the dollar of mexico?’
https://pdfs.semanticscholar.org/f477/232c0a0835dcbc4fc6b6283db484695482f9.pdf
N = 2000
K = 100
# Make a vector for each concept
codebook = lccvec(N, 9, K)
labels = 9*['']
NAM = codebook[0]; labels[0] = 'Name'
CAP = codebook[1]; labels[1] = 'Capitol'
MON = codebook[2]; labels[2] = 'Money'
USA = codebook[3]; labels[3] = 'USA'
WDC = codebook[4]; labels[4] = 'Wash. D.C.'
DOL = codebook[5]; labels[5] = 'Dollar'
MEX = codebook[6]; labels[6] = 'Mexico'
MXC = codebook[7]; labels[7] = 'Mex. City'
PES = codebook[8]; labels[8] = 'Peso'
Now we make a vector that represents the united states and mexico
USTATES = lccbind(NAM, USA, K) + lccbind(CAP, WDC, K) + lccbind(MON, DOL, K)
MEXICO = lccbind(NAM, MEX, K) + lccbind(CAP, MXC, K) + lccbind(MON, PES, K)
# block code vectors are not self-inverses, so we need to do inverse when unbinding
F_UM = lccbind(MEXICO, lccinv(USTATES, K), K)
mex_dol = lccbind(DOL, F_UM, K)
plot(mex_dol)
plot(PES)
/home/epaxon/anaconda3/lib/python3.7/site-packages/numpy/core/numeric.py:538: ComplexWarning: Casting complex values to real discards the imaginary part
return array(a, dtype, copy=False, order=order)
[<matplotlib.lines.Line2D at 0x7f1db1476e10>]

readout = np.real(np.dot(codebook, np.conj(mex_dol)))
plot(readout)
title('Dollar of Mexico: '+ labels[np.argmax(readout)])
ax = gca()
ax.set_xticks(np.arange(len(labels)))
ax.set_xticklabels(labels)
plt.xticks(rotation=45, ha='right')
(array([0, 1, 2, 3, 4, 5, 6, 7, 8]), <a list of 9 Text xticklabel objects>)
