首页 文章

如何用SymPy中的向量替换矩阵的对角元素?

提问于
浏览
3

我有一个矢量 X ,我这样创建:

from sympy import *

x1 = Symbol('x1')
x2 = Symbol('x2')
x3 = Symbol('x3')

X = Matrix([x1, x2, x3])

然后我还有一个矩阵 myMat ,它只包含一个:

myMat = ones(3, 3)

Matrix([
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])

现在我想用我的向量 X 替换矩阵的对角线;我期望的结果如下:

Matrix([
[x1, 1, 1],
[1, x2, 1],
[1, 1, x3]])

我当然可以在_139686中这样做:

for ind, el in enumerate(X):
    myMat[ind, ind] = el

但我想知道是否有更聪明的方法通过直接访问该矩阵的对角线 . 虽然我可以计算矩阵的 trace ,但我找不到用 myMat.diag = X 之类的东西替换对角线元素的方法 . 有没有办法做到这一点?

EDIT

@Emilien让我走上正轨,因此我接受了这个答案 . 在这个答案的基础上,我还发布了自己的解决方案,它使用 sympynumpy 并在一行中解决问题:my answer

4 回答

  • 0

    你可以使用对角线和身份矩阵构建它,我不确定它在vue思想的性能点上要好得多,但是如果你正在寻找它,那么在阅读代码时可能会更容易理解 .

    x1, x2, x3 = symbols('x1 x2 x3')
    mat = diag(x1,x2,x3)-eye(3)+ones(3)
    

    要么

    l = symbols('x1 x2 x3')
    mat = diag(*l)-eye(3)+ones(3)
    

    如你所愿 .

    另一个棘手的解决方案,可能不太可读:

    l = symbols('x1 x2 x3')
    Matrix(3, 3, lambda i,j: l[i] if i==j else 1)
    

    最后,如果您不想修改原件

    l = symbols('x1 x2 x3')
    M = Matrix(([1,2,3],[4,5,6],[7,8,9]))
    M = Matrix(3, 3, lambda i,j: l[i] if i==j else M[i,j])
    
  • 3

    Build @Emilien答案,可以做到以下几点:

    import sympy as sp
    import numpy as np
    
    x1 = sp.Symbol('x1')
    x2 = sp.Symbol('x2')
    x3 = sp.Symbol('x3')
    X = sp.Matrix([x1, x2, x3])
    
    myM = 4 * sp.ones(3, 3)
    

    所以 myM 看起来像这样:

    Matrix([
    [4, 4, 4],
    [4, 4, 4],
    [4, 4, 4]])
    

    现在命令

    sp.diag(*X) + myM - sp.diag(*np.diag(myM))
    

    给出了预期的结果:

    Matrix([
    [x1,  4,  4],
    [ 4, x2,  4],
    [ 4,  4, x3]])
    

    这分别利用 sympynumpydiag 的不同功能;而在 sympy diag 使用向量作为输入创建矩阵,使用此向量的元素作为矩阵的对角线

    sp.diag(*X)
    
    Matrix([
    [x1,  0,  0],
    [ 0, x2,  0],
    [ 0,  0, x3]])
    

    in numpy diag 返回矩阵的对角线:

    np.diag(myM)
    array([4, 4, 4], dtype=object)
    
  • -2

    如果您使用一些库函数来查找对角线,我100%确定库函数将使用“For”循环 . 只需运行一个嵌套的for循环,i从1变为Row.Count,j从1变为Columns.count . 对角线是i = j的地方 . 做你想做的事 . 举例如下,你明白了

    for (i=1; i<= Rows.Count; i++)
         for (j=1; j<= Columns.Count; j++)
              if (i==j)
              {
                // Do your Thing
              }
         end
     end
    
  • 3

    我建议将 sympy.matrices.dense.MutableDenseMatrix 转换为 numpy.ndarray 并在完成后重新转换 . 就像是:

    import numpy as np 
    from sympy import *
    
    x1 = Symbol('x1')
    x2 = Symbol('x2')
    x3 = Symbol('x3')
    
    X = Matrix([x1,x2,x3])
    myMat = ones(3,3)
    
    
    myMat1 = np.array(myMat)
    myMat1[range(3),range(3)] = np.array(X).reshape(myMat1.shape[0])
    
    myMat = Matrix(myMat1)
    
    >> Matrix([
    [x1,  1,  1],
    [ 1, x2,  1],
    [ 1,  1, x3]])
    

相关问题