我有一个这样的张量:
out = [[ 3, 6, 5, 4],
[ 6, 5, 10, 13],
[ 5, 10, 6, 22],
[ 4, 13, 22, 9]]
这是一个对称矩阵。我想要做的是将每个元素除以对角线相同索引中的值。因此,此矩阵中对角线的值为:
index0 = 3
index1 = 5
index2 = 6
index3 = 9
结果将如下所示:
[[3 , 6/(3*5) , 5/(3*6) , 4/(3*9) ]
[6/(3*5), 5 , 10/(5*6), 13/(5*9)]
[5/(3*6), 10/(5*6), 6 , 22/(6*9)]
[4/(3*9), 13/(5*9), 22/(6*9), 9 ]]
让我浏览第一行:
3
是对角线中的值,因此我们将跳过它
6/3*5
,6
是index 0 and 1
的值,因此我将6
除以index0 and 1
中的对角线值。
5/3*6
,5
是索引0 and 2
的值,因此我将其除以索引0 and 2
处的对角线值
4/3*9
,4
是索引0 and 3
的值,因此我将其除以索引0 and 3
处的对角线值
答案 0 :(得分:3)
可以在tensorflow(或numpy)中执行以下操作。
import tensorflow as tf
out = [[ 3, 6, 5, 4],
[ 6, 5, 10, 13],
[ 5, 10, 6, 22],
[ 4, 13, 22, 9]]
tensor = tf.constant(out, dtype=tf.float32)
diag_indices = tf.tile(tf.range(tf.shape(tensor)[0])[..., None], [1, 2])
diag = tf.gather_nd(tensor, diag_indices) # [3. 5. 6. 9.]
diag_matrix = tf.linalg.tensor_diag(diag)
zero_diag_matrix = tensor - diag_matrix
res = tf.transpose(zero_diag_matrix / diag) / diag + diag_matrix
with tf.Session() as sess:
print(res.eval())
# [[3. 0.4 0.27777776 0.14814815]
# [0.4 5. 0.33333334 0.28888887]
# [0.27777776 0.3333333 6. 0.4074074 ]
# [0.14814815 0.28888887 0.4074074 9. ]]
答案 1 :(得分:2)
使用numpy,您可以执行以下操作:
import numpy as np
out = out.astype(float)
# diagonal elements in out
d = np.copy(np.diagonal(out))
# Indices of lower triangular matriX
tril_ix = np.tril_indices_from(out, k=-1)
# cumulative sum of the diagonal values
# over the first axis on a square matrix
dx = np.cumsum(np.diag(d), 1)
# replicate ove lower triangular
dx[tril_ix] += np.rot90(dx, k=1)[::-1][tril_ix]
# same but accumulating the diagonal elements
# upwards on the y axis
dy = np.cumsum(np.diag(d)[::-1],0)[::-1]
# replicate ove rlower triangular
dy[tril_ix] += np.rot90(dy, k=1)[::-1][tril_ix]
# mask where to apply the product
m = dy!=0
# perform div and mult
out[m] = out[m]/(dx[m]*dy[m])
np.fill_diagonal(out, d)
print(out)
array([[3. , 0.4 , 0.27777778, 0.14814815],
[0.4 , 5. , 0.33333333, 0.28888889],
[0.27777778, 0.33333333, 6. , 0.40740741],
[0.14814815, 0.28888889, 0.40740741, 9. ]])
答案 2 :(得分:1)
这是张量流版本。
import tensorflow as tf
import numpy as np
out = tf.Variable([[ 3, 6, 5, 4],
[ 6, 5, 10, 13],
[ 5, 10, 6, 22],
[ 4, 13, 22, 9]], dtype=tf.float32)
# this solution only works for square matrices
assert out.shape[-2] == out.shape[-1]
out_diag = tf.linalg.diag_part(out)
res = tf.Variable(tf.zeros(out.shape, dtype=tf.float32))
for i in tf.range(out.shape[0]):
_ = res[..., (i+1):, i].assign(out[..., (i+1):, i] / out_diag[..., (i+1):] / out_diag[..., i])
_ = res[..., i, (i+1):].assign(out[..., i, (i+1):] / out_diag[..., (i+1):] / out_diag[..., i])
print(res)