[英]How to replace the the diagonal elements of a matrix by a vector in SymPy?
我有一个矢量X
,我这样创建:
from sympy import *
x1 = Symbol('x1')
x2 = Symbol('x2')
x3 = Symbol('x3')
X = Matrix([x1, x2, x3])
然后我还有一个矩阵myMat
, 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]])
我当然可以在for-loop
这样做:
for ind, el in enumerate(X):
myMat[ind, ind] = el
但我想知道是否通过直接访问该矩阵的对角线有更聪明的方法。 虽然我可以计算矩阵的trace
,但我找不到使用myMat.diag = X
类的方法来替换对角线元素的方法。 有没有办法做到这一点?
编辑
@Emilien让我走上正轨,因此我接受了这个答案。 在这个答案的基础上,我还发布了自己的解决方案,利用了sympy
和numpy
并在一行中解决了问题: 我的回答
我建议的转换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]])
您可以使用对角线和标识矩阵构建它,我不确定它在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])
建立@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]])
这分别在sympy
和numpy
使用了diag
的不同功能; 而在sympy
diag
使用矢量作为输入创建矩阵,使用该矢量的元素作为矩阵的对角线
sp.diag(*X)
Matrix([
[x1, 0, 0],
[ 0, x2, 0],
[ 0, 0, x3]])
在numpy
diag
返回矩阵的对角线:
np.diag(myM)
array([4, 4, 4], dtype=object)
如果您使用一些库函数来查找对角线,我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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.