In [10]:
# ----------------------------------------------------------------------
# Numenta Platform for Intelligent Computing (NuPIC)
# Copyright (C) 2016, Numenta, Inc.  Unless you have an agreement
# with Numenta, Inc., for a separate license for this software code, the
# following terms and conditions apply:
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero Public License for more details.
#
# You should have received a copy of the GNU Affero Public License
# along with this program.  If not, see http://www.gnu.org/licenses.
#
# http://numenta.org/licenses/
# ----------------------------------------------------------------------


from sympy import *
init_printing()
from IPython.display import display

%matplotlib inline

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams['pdf.fonttype'] = 42

In [4]:
# number of columns
n = Symbol("n", positive=True)

# number of cells per column
m = Symbol("m", positive=True)

# number of active bits
w = Symbol("w", positive=True)

# match thresh
b = Symbol("b", positive=True)

In [8]:
nColL4Val = 2048
wVal = 40
bVal = 20
mVal = 32

nCw = factorial(n) / (factorial(w) * factorial(n - w))
overlapSet = binomial(w, b) * binomial(n - w, w - b)

numPts = nCw.subs(n, nColL4Val).subs(w, wVal)
print "raw feature capacity", numPts.evalf()

sizeOverlapSet = 0
for bVal in range(20, 40):
    sizeOverlapSet += overlapSet.subs(w, wVal).subs(n, nColL4Val).subs(b, bVal)

print "inexact matches for each template: ", sizeOverlapSet.evalf()

numFeatures = numPts / sizeOverlapSet

#numFeature = numFeatures.subs(n, nColL4Val).subs(w, wVal).subs(b, bVal)
print " feature capacity after adjusting inexact matches: ", numFeatures.evalf()


raw feature capacity 2.37177851164536e+84
inexact matches for each template:  5.90869466339081e+58
 feature capacity after adjusting inexact matches:  4.01404818959501e+25

In [9]:
mtow = pow(m, w)
numPts = mtow.subs(m, mVal).subs(w, wVal)
sizeInexactMatch = 0
for bVal in range(20, 40):
    sizeInexactMatch += nCw.subs(n, wVal).subs(w, bVal) * pow(mVal, wVal-bVal)

numLocations = numPts / sizeInexactMatch
print "raw location capacity: ", numPts.evalf()
print "location capacity after adjusting inexact matches: ", numLocations.evalf()


raw location capacity:  1.60693804425899e+60
location capacity after adjusting inexact matches:  8.92318340962837e+18

Verify capacity calculation with simulation


In [14]:
def generateL4SDR(n=2048, m=32, w=40):
  colOrder = np.random.permutation(np.arange(n))
  activeCols = colOrder[:w]
  activeCells = np.random.randint(low=0, high=m, size=(w, ))

  activeBits = activeCols * m + activeCells
  return set(activeBits), set(activeCols)

numRpts = 100000
overlap = []
for rpt in range(numRpts):
    sdr1, sdr1cols = generateL4SDR()
    sdr2, sdr2cols = generateL4SDR()
    overlap.append(len(sdr1.intersection(sdr2)))
overlap = np.array(overlap)
print "mean overlap", np.mean(overlap)
print "max overlap", np.max(overlap)


mean overlap 0.02551
max overlap 2

In [ ]: