How to replace the the diagonal elements of a matrix by a vector in SymPy?

落花浮王杯 提交于 2019-12-05 20:25:52

You can build it with diagonal and identity matrices, I'm not sure it's much better on a performance point of vue thought, but maybe it's easier to understand when reading the code if that's what you're looking for.

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

or

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

As you wish.

Another tricky solution, maybe less readable:

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

Finally, if you do not wish to modify the original

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])

I would suggest to convert the sympy.matrices.dense.MutableDenseMatrix to a numpy.ndarray and reconvert after all is done. Something like:

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]])

Building up on @Emilien answer, one could do the following:

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)

So myM looks like this:

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

Now the command

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

gives the desired outcome:

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

That makes use of the different functionalities of diag in sympy and numpy, respectively; while in sympy diag creates a matrix using a vector as an input using the elements of this vector as the diagonal of the matrix

sp.diag(*X)

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

in numpy diag returns the diagonal of a matrix:

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

If you us some library function for finding the diagonal, I am 100% sure that the Library Function will use "For" loops. Just run a nested for loop with i varying from 1 to Row.Count and j varying from 1 to Columns.count. Diagonal is where i=j. Do what Ever you want there.Example below, you get the idea

for (i=1; i<= Rows.Count; i++)
     for (j=1; j<= Columns.Count; j++)
          if (i==j)
          {
            // Do your Thing
          }
     end
 end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!