I'm looking for a way to access sympy matrix elements to perform row operations, but can't seem to come up with a way to do so or find any existing documentation that describes the process.
For example, let's say I have the following code:
import sympy as sp
from sympy import *
matrix = sp.Matrix([[3,2,2],[1,2,3]])
I want to divide the element in the first row and second column, which is 2 in this case. A really hacky way to do so that I can think of would be to do the following:
a = int(matrix.row(0).col(2)[0])
matrix.row(0)/a
But now the first row of my matrix is
[3/2,1,1]
and I want to divide the row again by 3/2 this time, for which my previous method does not work. How can I perform these row operations, and how can I have them update the original matrix? (ie, when i divide a row by 3, it updates the row in the original matrix and doesn't just return a separate matrix reflecting just the updated row)
And, is there any simple way to do row swaps/interchanges (ie r1 <--> r2) with a sympy matrix?
EDIT:
I figured out that I can do the division portion of my question by simply using matrix[row#,:]/matrix[row#,column#]
, but I still am unsure of how to have this row operation be directly reflected in the original matrix, or how to do row swaps.
When I have a question like this I try to search the directory for assistance:
>>> [w for w in dir(Matrix) if 'op' in w and not w.startswith('_')]
[col_op, copy, copyin_list, copyin_matrix, elementary_col_op, elementary_row_op,
row_op, zip_row_op]
>>> help(Matrix.row_op)
Help on method row_op in module sympy.matrices.dense:
row_op(self, i, f) unbound sympy.matrices.dense.MutableDenseMatrix method
In-place operation on row ``i`` using two-arg functor whose args are
interpreted as ``(self[i, j], j)``.
...
>>> help(Matrix.elementary_row_op)
Help on method elementary_row_op in module sympy.matrices.matrices:
elementary_row_op(self, op='n->kn', row=None, k=None, row1=None, row2=None) unbound
sympy.matrices.dense.MutableDenseMatrix method
Performs the elementary row operation `op`.
`op` may be one of
* "n->kn" (row n goes to k*n)
* "n<->m" (swap row n and row m)
* "n->n+km" (row n goes to row n + k*row m)
Parameters
==========
op : string; the elementary row operation
row : the row to apply the row operation
k : the multiple to apply in the row operation
row1 : one row of a row swap
row2 : second row of a row swap or row "m" in the row operation
"n->n+km"
So it looks like either could be used.
>>> m = Matrix([[3,2,2],[1,2,3]])
>>> m.row_op(0, lambda x, j: x/2)
>>> m
Matrix([
[3/2, 1, 1],
[ 1, 2, 3]])
>>> m.row_op(0, lambda x, j: x/(3/2))
>>> m
Matrix([
[1, 2/3, 2/3],
[1, 2, 3]])
or
>>> m = Matrix([[3,2,2],[1,2,3]])
>>> m.elementary_row_op('n->kn',row1=0,k=1/3)
Matrix([
[1, 2/3, 2/3],
[1, 2, 3]])
I'm still a bit of a sympy
novice, but knowledgeable in numpy
. So let's see if sympy
behaves in much the same way.
In an isympy
session:
In [67]: M = Matrix([[3,2,2],[1,2,3]])
In [68]: M
Out[68]:
⎡3 2 2⎤
⎢ ⎥
⎣1 2 3⎦
In [69]: M[0,:] # a row, using a numpy style indexing
Out[69]: [3 2 2]
In [70]: M[0,1] # an element
Out[70]: 2
In [71]: M[0,:]/M[0,1] # division, producing a new matrix
Out[71]: [3/2 1 1]
In [72]: M # no change to M
Out[72]:
⎡3 2 2⎤
⎢ ⎥
⎣1 2 3⎦
In [73]: M[0,:]/=M[0,1] # but with a /= (Python syntax)
In [74]: M
Out[74]:
⎡3/2 1 1⎤
⎢ ⎥
⎣ 1 2 3⎦
In [75]: M[0,:]/=3/2 # again
In [76]: M
Out[76]:
⎡1.0 0.666666666666667 0.666666666666667⎤
⎢ ⎥
⎣ 1 2 3 ⎦
That did a floating point division; I suspect with a different divisor I could have done a proper fractional division.
In [83]: M = Matrix([[3,2,2],[1,2,3]])
In [84]: M[0,:]/=M[0,1]
In [85]: M[0,:]/=Rational(3,2)
In [86]: M
Out[86]:
⎡1 2/3 2/3⎤
⎢ ⎥
⎣1 2 3 ⎦
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.