我有矩阵,其中对角线是该行中所有其他元素之和的负数。这是一个例子
import numpy as np
Q = np.array([[-6, 2, 2, 1, 1],
[1, -4, 0, 1, 2],
[1, 0, -4, 2, 1],
[2, 1, 0, -3, 0],
[1, 1, 1, 1, -4]])
我想编写一个Theano函数,它接收这些矩阵并返回一个行数相同的矩阵,少一列,并删除对角线。所以对于Q来说,这将是
Q_raw = np.array([[2, 2, 1, 1],
[1, 0, 1, 2],
[1, 0, 2, 1],
[2, 1, 0, 0],
[1, 1, 1, 1]])
我也喜欢反过来,即给定Q_raw,我想写一个吐出Q的Theano函数。我怎样才能在Theano中编写这些函数?到目前为止,我还没有想出一个只将矩阵本身作为输入的解决方案。
答案 0 :(得分:1)
这里有几种方法可以做我认为你要求的方法。可能有更有效的方法。
import numpy
import theano
import theano.tensor as tt
def symbolic_remove_diagonal(x):
flat_x = x.flatten()
indexes = tt.arange(flat_x.shape[0], dtype='int64')
diagonal_modulo = indexes % (x.shape[0] + 1)
off_diagonal_flat_x = flat_x[tt.neq(diagonal_modulo, 0).nonzero()]
return off_diagonal_flat_x.reshape((x.shape[0], x.shape[1] - 1))
def symbolic_add_diagonal(x):
diagonal_values = -x.sum(axis=1)
flat_x = x.flatten()
result_length = flat_x.shape[0] + x.shape[0]
indexes = tt.arange(result_length, dtype='int64')
diagonal_modulo = indexes % (x.shape[0] + 1)
result = tt.zeros((result_length,), dtype=x.dtype)
result = tt.set_subtensor(result[tt.eq(diagonal_modulo, 0).nonzero()], diagonal_values)
result = tt.set_subtensor(result[tt.neq(diagonal_modulo, 0).nonzero()], flat_x)
return result.reshape((x.shape[0], x.shape[1] + 1))
def main():
theano.config.compute_test_value = 'raise'
x1 = tt.matrix()
x1.tag.test_value = numpy.array(
[[-6, 2, 2, 1, 1],
[1, -4, 0, 1, 2],
[1, 0, -4, 2, 1],
[2, 1, 0, -3, 0],
[1, 1, 1, 1, -4]])
x2 = tt.matrix()
x2.tag.test_value = numpy.array(
[[2, 2, 1, 1],
[1, 0, 1, 2],
[1, 0, 2, 1],
[2, 1, 0, 0],
[1, 1, 1, 1]])
remove_diagonal = theano.function(inputs=[x1], outputs=symbolic_remove_diagonal(x1))
add_diagonal = theano.function(inputs=[x2], outputs=symbolic_add_diagonal(x2))
x2_prime = remove_diagonal(x1.tag.test_value)
x1_prime = add_diagonal(x2.tag.test_value)
print 'Diagonal removed:\n', x2_prime
print 'Diagonal added:\n', x1_prime
assert numpy.all(x2_prime == x2.tag.test_value)
assert numpy.all(x1_prime == x1.tag.test_value)
main()