In [1]:
%matplotlib inline

In [2]:
import numpy as np
import theano
import theano.tensor as T
import os

from theano.tensor.shared_randomstreams import RandomStreams

First Something Easy


In [3]:
x = T.iscalar('x')
result = T.arange(x)
do_something = theano.function(inputs=[x], outputs=result)
do_something(5)


Out[3]:
array([0, 1, 2, 3, 4])

A Simple Loop


In [4]:
X = T.matrix("X")
results, _ = theano.scan(lambda v: v*2, sequences=X)
my_iterator = theano.function(inputs=[X], outputs=[results])
my_iterator([[1, 2, 3],[4, 5, 6],[7, 8, 9]])


Out[4]:
[array([[  2.,   4.,   6.],
        [  8.,  10.,  12.],
        [ 14.,  16.,  18.]])]

Accumulator with shared variable

Scan returns the updates, which are used by the function to update the shared variable.


In [5]:
k = theano.shared(0)
n = T.iscalar("n")

_, updates = theano.scan(lambda : ({k : (k + 1)}), n_steps=n)
acc = theano.function([n],[], updates=updates, allow_input_downcast=True)

In [6]:
k.get_value()


Out[6]:
0

In [7]:
acc(5)
k.get_value()


Out[7]:
5

Geometric Series with Shared Variable and Recursion


In [8]:
k = theano.shared(1)
n = T.iscalar("n")
    
#def geo_func(prior_result):
#    current_result = prior_result + (1.0 / k)
#    updates = {k: k*2}
#    return current_result, updates

output = T.as_tensor_variable(np.asarray(0, np.float64))
results, updates = theano.scan(lambda prior : (prior + 1.0/k, {k : k*2}), outputs_info=output, n_steps=n)
#results, updates = theano.scan(geo_func, outputs_info=output, n_steps=n)
#result = results[-1]
geo = theano.function(inputs=[n], outputs=[results], updates=updates)
geo(2)


Out[8]:
[array([ 1. ,  1.5])]

In [ ]: