Masalah saat mengganti matriks dalam polinomial
Contoh: biarkan
M = Matrix([[1,2],[3,4]]) # and
p = Poly(x**3 + x + 1) # then
p.subs(x,M).expand()
memberikan kesalahan:
TypeError: tidak dapat menambahkan <class'sympy.matrices.immutable.ImmutableDenseMatrix '> dan <class' sympy.core.numbers.One '>
yang sangat masuk akal karena dua suku pertama menjadi matriks tetapi suku terakhir (suku konstanta) bukanlah matriks melainkan skalar. Untuk memperbaiki situasi ini, saya mengubah polinomial menjadi
p = Poly(x**3 + x + x**0) # then
kesalahan yang sama terus berlanjut. Apakah saya wajib mengetik ekspresi dengan tangan, mengganti x dengan M? Dalam contoh ini polinomial hanya memiliki tiga suku tetapi pada kenyataannya saya menjumpai (polinomial multivariat dengan) lusinan suku.
Jawaban
Jadi saya pikir pertanyaannya terutama berkisar pada konsep polinomial Matriks :
(di mana P adalah polinomial, dan A adalah matriks)
Saya pikir ini mengatakan bahwa suku bebas adalah angka, dan tidak dapat ditambahkan dengan sisanya yang merupakan matriks, secara efektif operasi penjumlahan tidak ditentukan antara kedua jenis tersebut.
TypeError: tidak dapat menambahkan <class'sympy.matrices.immutable.ImmutableDenseMatrix '> dan <class' sympy.core.numbers.One '>
Namun, hal ini dapat dielakkan dengan mendefinisikan fungsi yang mengevaluasi polinomial matriks untuk matriks tertentu. Perbedaannya di sini adalah bahwa kita sedang menggunakan matriks eksponensial , jadi kami benar menghitung jangka bebas dari polinomial matriks a_0 * I
di mana I=A^0
adalah matriks identitas dari bentuk yang diperlukan:
from sympy import *
x = symbols('x')
M = Matrix([[1,2],[3,4]])
p = Poly(x**3 + x + 1)
def eval_poly_matrix(P,A):
res = zeros(*A.shape)
for t in enumerate(P.all_coeffs()[::-1]):
i, a_i = t
res += a_i * (A**i)
return res
eval_poly_matrix(p,M)
Keluaran:
Dalam contoh ini polinomial hanya memiliki tiga suku tetapi pada kenyataannya saya menjumpai (polinomial multivariat dengan) lusinan suku.
Fungsi di eval_poly_matrix
atas dapat diperluas untuk bekerja untuk polinomial multivariat dengan menggunakan .monoms()metode untuk mengekstrak monomial dengan koefisien bukan nol , seperti:
from sympy import *
x,y = symbols('x y')
M = Matrix([[1,2],[3,4]])
p = poly( x**3 * y + x * y**2 + y )
def eval_poly_matrix(P,*M):
res = zeros(*M[0].shape)
for m in P.monoms():
term = eye(*M[0].shape)
for j in enumerate(m):
i,e = j
term *= M[i]**e
res += term
return res
eval_poly_matrix(p,M,eye(M.rows))
Catatan: Beberapa pemeriksaan kewarasan, penanganan kasus edge, dan pengoptimalan dapat dilakukan:
- Jumlah variabel yang ada dalam polinomial berkaitan dengan jumlah matriks yang diteruskan sebagai parameter (yang pertama tidak boleh lebih besar dari yang terakhir, dan jika lebih rendah dari beberapa logika perlu ada untuk mengatasinya, saya hanya menangani kasusnya ketika keduanya sama)
- Semua matriks harus berbentuk bujursangkar sesuai definisi polinomial matriks
- Sebuah diskusi tentang versi multivarian dari fitur aturan Horner di komentar pertanyaan ini . Ini mungkin berguna untuk meminimalkan jumlah perkalian matriks.
- Tangani fakta bahwa dalam polinomial Matriks
x*y
berbeda dariy*x
karena perkalian matriks bersifat non-komutatif . Rupanya fungsi poli dalam sympy tidak mendukung variabel non-komutatif , tetapi Anda dapat mendefinisikan simbol dengancommutative=False
dan sepertinya ada cara untuk maju ke sana
Tentang poin ke-4 di atas, ada dukungan untuk ekspresi Matrix di SymPy, dan itu dapat membantu di sini:
from sympy import *
from sympy.matrices import MatrixSymbol
A = Matrix([[1,2],[3,4]])
B = Matrix([[2,3],[3,4]])
X = MatrixSymbol('X',2,2)
Y = MatrixSymbol('Y',2,2)
I = eye(X.rows)
p = X**2 * Y + Y * X ** 2 + X ** 3 - I
display(p)
p = p.subs({X: A, Y: B}).doit()
display(p)
Keluaran:
Untuk perkembangan lebih lanjut tentang fitur ini ikuti # 18555