2016-10-31 14 views
1

Предположим, у меня есть тензор 2d A. Я хотел бы символический вычислить Apow, то степенной ряд A, который является 3d тензор определяется следующим образом:Символическая матричная степенная серия в Theano

Apow = [I, A, A^2, A^3, ..., A^k] 

A^2 где означает A.dot(A) (т.е. степенного ряда определяется относительно скалярного произведения, а не поэлементно). k - это символический скаляр, определяющий длину ряда.

Как я могу реализовать это в Theano? Похоже, что решение будет основано на scan, но я не смог заставить его работать.

Любые мысли?

ответ

1

Позвольте мне разделить мой ответ на Numpy реализации в и Theano реализация:

Использование NumPy:

def kpow(A, k): 
    if k == 0: 
     return np.identity(A.shape[0]) 
    if k == 1: 
     return A 
    else: 
     return np.dot(A, kpow(A, k-1)) 

Вы могли бы получить ваши Apow так:

k = 5 
A = np.array([[1, 1, 1],[2, 2, 2],[3, 3, 3]]) 
Apow = [kpow(A,i) for i in range(k)] 

Конечно, вы могли бы сделать этот способ более эффективным, фактически накапливая список по мере продвижения. Важно отметить повторение, как мы используем предыдущий результат для вычисления следующего.

Использование Theano:

Во-первых, давайте определим две символические переменные для нашего k и матрицы M:

k = T.iscalar('k') 
M = T.dmatrix('M') 

Далее, давайте определим функцию рекуррентное:

def recurrence(M, prev_result): 
    return prev_result * M 

Наконец , пришло время для функции сканирования:

result, updates = theano.scan(fn=recurrence, 
           outputs_info=T.identity_like(M), 
           non_sequences=M, 
           n_steps=k) 

Теперь давайте получить некоторые результаты:

A = np.array([[1, 1, 1],[2, 2, 2],[3, 3, 3]], dtype='int32') 
kpow_theano = theano.function(inputs=[M,k], outputs=result) 
Apow = [kpow_theano(A,10)[i] for i in range(10)] 

Я не уверен, как вы бы получить единичную матрицу на фронте с использованием Theano. Думаю, вы могли бы добавить его в список.