Search code examples
pythoniterationtheano

How to map one matrix value to another in theano function


I want to implement the following function in theano function,

a=numpy.array([ [b_row[dictx[idx]] if idx in dictx else 0 for idx in range(len(b_row))]
               for b_row in b])
where a, b are narray, and dictx is a dictionary

I got the error TensorType does not support iteration Do I have to use scan? or is there any simpler way? Thanks!


Solution

  • Since b is of type ndarray, I'll assume every b_row has the same length.

    If I understood correctly the code swaps the order of columns in b according to dictx, and pads the non-specified columns with zeros.

    The main problem is Theano doesn't have a dictionary-like data structure (please let me know if there's one).

    Because in your example the dictionary keys and values are integers within range(len(b_row)), one way to work around this is to construct a vector that uses indices as keys (if some index should not be contained in the dictionary, make its value -1).

    The same idea should apply for mapping elements of a matrix in general, and there're certainly other (better) ways of doing this.

    Here is the code.
    Numpy:

    dictx = {0:1,1:2}
    b = numpy.asarray([[1,2,3],
                    [4,5,6],
                    [7,8,9]])
    a = numpy.array([[b_row[dictx[idx]] if idx in dictx else 0 for idx in range(len(b_row))] for b_row in b])
    print a
    

    Theano:

    dictx = theano.shared(numpy.asarray([1,2,-1]))
    b = tensor.matrix()
    a = tensor.switch(tensor.eq(dictx, -1), tensor.zeros_like(b), b[:,dictx])
    fn = theano.function([b],a)
    print fn(numpy.asarray([[1,2,3],
                            [4,5,6],
                            [7,8,9]]))
    

    They both print:

    [[2 3 0]  
     [5 6 0]  
     [8 9 0]]