【问题标题】:define a diagonal matrix from a matrix, with products of subdiagonals从一个矩阵定义一个对角矩阵,其中包含子对角线的乘积
【发布时间】:2019-10-02 13:47:43
【问题描述】:

如何从矩阵 A 构造对角矩阵 D,其中:

  • 对角矩阵 D 的第一个元素必须是矩阵 A 的下对角线中所有元素的乘积
  • 对角矩阵 D 中的第二个元素必须是矩阵 A 的下对角线中除第一个元素之外的所有元素的乘积
  • 对角矩阵 D 中的第三个元素必须是矩阵 A 的下对角线中除第一个和第二个之外的所有元素的乘积
  • ...对角矩阵D的最后一个元素必须是1

【问题讨论】:

  • 请发布一个最小的输入和输出示例,以及您尝试了什么。你在使用纯 Python、NumPy 还是其他东西?
  • 可以通过 numpy.diag 提取子对角线,并且可以通过 numpy.prod 计算元素的乘积。请发布您的输入/输出示例
  • 嗨@amalloui 不要忘记您可以投票和接受答案,请参阅What should I do when someone answers my question?

标签: python numpy


【解决方案1】:

这是一种方法:

def subdiag_prod_(a):
    sub_diag = np.diagonal(a, offset=-1)
    mask = np.triu(np.ones((sub_diag.shape*2))).astype('bool')
    m = sub_diag[:,None].T * mask
    ma = np.ma.array(sub_diag[:,None].T * mask, mask=~mask)
    diag = np.prod(ma, axis=1).data
    out = np.diag(diag)
    last_row = np.zeros([out.shape[0]+1]*2)
    last_row[:out.shape[0], :out.shape[1]] += out
    return last_row

a = np.random.randint(1,5,(10,10))

array([[2, 2, 1, 4, 3, 1, 3, 1, 4, 4],
       [2, 2, 2, 1, 1, 2, 3, 2, 2, 2],
       [4, 2, 2, 4, 2, 1, 3, 3, 3, 4],
       [2, 3, 3, 1, 1, 1, 4, 2, 3, 4],
       [3, 3, 1, 1, 2, 1, 3, 4, 4, 3],
       [1, 4, 4, 1, 1, 4, 1, 1, 1, 4],
       [4, 2, 3, 2, 1, 4, 4, 1, 3, 2],
       [4, 2, 2, 4, 4, 4, 1, 4, 3, 1],
       [1, 3, 1, 1, 2, 2, 2, 3, 4, 1],
       [1, 3, 2, 2, 3, 4, 1, 3, 2, 1]])

subdiag_prod(a)

array([[288.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
       [  0., 144.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
       [  0.,   0.,  72.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
       [  0.,   0.,   0.,  24.,   0.,   0.,   0.,   0.,   0.,   0.],
       [  0.,   0.,   0.,   0.,  24.,   0.,   0.,   0.,   0.,   0.],
       [  0.,   0.,   0.,   0.,   0.,  24.,   0.,   0.,   0.,   0.],
       [  0.,   0.,   0.,   0.,   0.,   0.,   6.,   0.,   0.,   0.],
       [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   6.,   0.,   0.],
       [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   2.,   0.],
       [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.,   1.]])

详情

第一步是用np.diagonal取ndarray的对角线:

sub_diag = np.diagonal(a, offset=-1)
# array([2, 2, 3, 1, 1, 4, 1, 3, 2])

我们可以通过使用np.tril 创建一个mask,然后我们可以使用它以指定的方式获取对角元素的乘积:

mask = np.triu(np.ones((sub_diag.shape*2))).astype('bool')

现在我们可以使用上面的ndarray 作为掩码,通过掩码和下对角线相乘来创建一个掩码数组:

mask = np.ma.array(sub_diag[:,None].T * mask, mask=~mask)

现在我们可以获取掩码数组的逐行乘积:

d = np.prod(ma, axis=1).data
# array([288, 144,  72,  24,  24,  24,   6,   6,   2])

然后简单地从中构建一个对角矩阵:

out = np.diag(d)
last_row = np.zeros([out.shape[0]+1]*2)
last_row[:out.shape[0], :out.shape[1]] += out

【讨论】:

  • 最后一个元素必须是 1
  • 虽然@MadPhysicist 但它是次对角线而不是对角线
  • 根据OP:“并且对角矩阵D的最后一个元素必须为1”。这就是为什么您不应该用不完整的信息来回答指定不清的问题。
  • 顺便说一句,我并不反对您的回答。这很有意义。这个问题虽然没有
  • 哦,谢谢,我完全错过了@MadPhysicist。问题是这似乎是一个有趣的问题,虽然它完全没有 mcve,但问题陈述似乎足够清晰
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 1970-01-01
  • 1970-01-01
  • 2017-03-22
  • 2017-07-23
相关资源
最近更新 更多