In [127]:
tau = 20.0
sigma = lambda u: 1.0/(1.0 + exp(-u + log(tau)))
#sigma = lambda x: 1.0/(1.0 + exp(x))
inv_sigma = lambda s: -log(1./s - 1.0) + log(tau)
#inv_sigma = lambda s: log(1./s - 1.0)
log(tau)


Out[127]:
2.9957322735539909

In [136]:
def approximate(points=8, threshold=0.01):
    a = inv_sigma(threshold)
    b = inv_sigma(1. - threshold)
    #print a, sigma(a), b, sigma(b)
    x = linspace(a, b, points)
    y = sigma(x)
    return x, y


def generate_lookup_table(index_bits=4, index_fraction=1):
    x = array([ float(-2**(index_bits-1) + i)/2**index_fraction for i in xrange(2**index_bits) ])
    #y = sigma(x + 2**-(index_fraction+1))
    y = sigma(x)

    def lookup(u):
        index = int(u * 2**index_fraction + 2**(index_bits-1)) % 2**index_bits
        if u > x[-1]:
            return sigma(10)
        elif u < x[0]:
            return sigma(-10)
        else:
            return y[index]
    
    return x, y, lookup
    

def vhdl_lookup_table(aprx, apry, index_bits=4, index_fraction=1):
    rv = "(\n"
    for x,y in zip(aprx, apry):
        if x >= 0:
            index = int(x * 2**index_fraction) % 2**(index_bits-1)
        else:
            index = int(2**index_bits - abs(x * 2**index_fraction))
        rv += "\t%2d => make_ufixed(%f, lfsr_use_width-lfsr_fraction, lfsr_fraction),\n" % (
            index,
            y
        )
    rv += ");\n"
    return rv

In [120]:
2**4 - 1


Out[120]:
15

In [142]:
aprx, apry, lut = generate_lookup_table(index_bits=5, index_fraction=2)
print vhdl_lookup_table(aprx, apry, index_bits=5, index_fraction=2)
print lut(-1.0)
print sigma(-1.0)
print aprx[0], " to ", aprx[-1]
print aprx
print apry


(
	16 => make_ufixed(0.000915, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	17 => make_ufixed(0.001175, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	18 => make_ufixed(0.001508, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	19 => make_ufixed(0.001935, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	20 => make_ufixed(0.002483, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	21 => make_ufixed(0.003186, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	22 => make_ufixed(0.004087, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	23 => make_ufixed(0.005242, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	24 => make_ufixed(0.006721, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	25 => make_ufixed(0.008614, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	26 => make_ufixed(0.011033, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	27 => make_ufixed(0.014123, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	28 => make_ufixed(0.018062, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	29 => make_ufixed(0.023073, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	30 => make_ufixed(0.029434, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	31 => make_ufixed(0.037481, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 0 => make_ufixed(0.047619, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 1 => make_ufixed(0.060328, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 2 => make_ufixed(0.076158, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 3 => make_ufixed(0.095718, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 4 => make_ufixed(0.119652, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 5 => make_ufixed(0.148586, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 6 => make_ufixed(0.183063, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 7 => make_ufixed(0.223440, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 8 => make_ufixed(0.269781, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	 9 => make_ufixed(0.321752, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	10 => make_ufixed(0.378544, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	11 => make_ufixed(0.438874, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	12 => make_ufixed(0.501067, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	13 => make_ufixed(0.563227, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	14 => make_ufixed(0.623462, lfsr_use_width-lfsr_fraction, lfsr_fraction),
	15 => make_ufixed(0.680108, lfsr_use_width-lfsr_fraction, lfsr_fraction),
);

0.0180617448289
0.0180617448289
-4.0  to  3.75
[-4.   -3.75 -3.5  -3.25 -3.   -2.75 -2.5  -2.25 -2.   -1.75 -1.5  -1.25
 -1.   -0.75 -0.5  -0.25  0.    0.25  0.5   0.75  1.    1.25  1.5   1.75
  2.    2.25  2.5   2.75  3.    3.25  3.5   3.75]
[ 0.00091494  0.00117451  0.00150759  0.00193496  0.00248317  0.00318621
  0.00408747  0.00524233  0.00672128  0.00861385  0.01103341  0.01412293
  0.01806174  0.02307337  0.0294339   0.03748055  0.04761905  0.06032813
  0.07615791  0.09571823  0.11965173  0.14858629  0.1830629   0.22343978
  0.26978133  0.32175193  0.37854412  0.43887421  0.50106693  0.56322665
  0.62346174  0.6801079 ]

In [50]:
aprx, apry = approximate(points=8, threshold=0.01)

In [143]:
fig = figure(figsize=(15,10))
x = linspace(-10, 10, 100)
y = sigma(x)

plot(x, y)
#plot(aprx, apry)
plot(x, [lut(i) for i in x], '+')


Out[143]:
[<matplotlib.lines.Line2D at 0x7fda6466e210>]

In [54]:
fig = figure(figsize=(15,10))
err = []
points = range(2,17)
for t in [ 0.0001, 0.001, 0.01, 0.1 ]:
    err.append([])
    for p in points:
        aprx, apry = approximate(points=p, threshold=t)
        
        x = linspace(-10, 10, 10000)
        y = sigma(x)
        cmp_y = interp(x, aprx, apry, 0.0, 1.0)
        fig = figure(figsize=(15,10))
err = []
points = range(2,17)
for t in [ 0.0001, 0.001, 0.01, 0.1 ]:
    err.append([])
    for p in points:
        aprx, apry = approximate(points=p, threshold=t)def approximate(points=8, threshold=0.01):
    a = inv_sigma(threshold)
    b = inv_sigma(1. - threshold)
    #print a, sigma(a), b, sigma(b)
    x = linspace(a, b, points)
    y = sigma(x)
    return x, y

def approximate2(index_bits=4, membrane_repr=(16,8)):
    pass
        
        x = linspace(-10, 10, 10000)
        y = sigma(x)
        cmp_y = interp(x, aprx, apry, 0.0, 1.0)
        
        err[-1].append(sqrt(sum((cmp_y - y) ** 2)))
     
    plot(points, err[-1], label='t=%1.4f' % (t))

legend(loc='best')
#print err
        err[-1].append(sqrt(sum((cmp_y - y) ** 2)))
     
    plot(points, err[-1], label='t=%1.4f' % (t))

legend(loc='best')
#print err


Out[54]:
<matplotlib.legend.Legend at 0x7fda751cfe50>

In [ ]: