Is there a way to implicitly define the elements of a symbolic matrix in SymPy following a rule such as: symbol followed by subindices in the matrix (or pairs of numbers)
For example, I would like to define a 3 x 2 matrix called M
, and I would like SymPy to automatically create it and populate it as:
M =
[ M_11 M_12]
[ M_21 M_22]
[ M_31 M_32]
If there is no way to do this implicitly, what would be the easiest way to do this explicitly (e.g. looping)?
Consider using the MatrixSymbol
rather than Matrix
object. MatrixSymbol
represents matrices without the need for explicit elements.
In [1]: M = MatrixSymbol('M', 3, 2)
In [2]: M # Just an expression
Out[2]: M
In [3]: Matrix(M) # Turn it into an explicit matrix if you desire
Out[3]:
⎡M₀₀ M₀₁⎤
⎢ ⎥
⎢M₁₀ M₁₁⎥
⎢ ⎥
⎣M₂₀ M₂₁⎦
In [4]: M.T * M # Still just an expression
Out[4]:
T
M ⋅M
In [5]: Matrix(M.T * M) # Fully evaluate
Out[5]:
⎡ 2 2 2 ⎤
⎢ M₀₀ + M₁₀ + M₂₀ M₀₀⋅M₀₁ + M₁₀⋅M₁₁ + M₂₀⋅M₂₁⎥
⎢ ⎥
⎢ 2 2 2 ⎥
⎣M₀₁⋅M₀₀ + M₁₁⋅M₁₀ + M₂₁⋅M₂₀ M₀₁ + M₁₁ + M₂₁ ⎦
How about something like this:
import sympy
M = sympy.Matrix(3, 2, lambda i,j:sympy.var('M_%d%d' % (i+1,j+1)))
Edit: I suppose I should add a small explanation. The first two arguments to sympy.Matrix() are defining the matrix as 3x2 (as you specified). The third argument is a lambda function, which is essentially a shorthand way of defining a function in one line, rather than formally defining it with def. This function takes variables i and j as input, which conveniently are the indices of the matrix. For each pair (i,j) which are passed into the lambda (i.e., for each element of the matrix), we are creating a new symbolic variable M_ij. sympy.var() takes a string as input which defines the name of the new symbolic variable. We generate this string on-the-fly using the format string 'M_%d%d' and filling it with (i+1,j+1). We are adding 1 to i and j because you want the matrix to be 1-indexed, rather than 0-indexed as is the standard in Python.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With