ปัญหาเมื่อแทนที่เมทริกซ์ในพหุนาม
ตัวอย่าง: let
M = Matrix([[1,2],[3,4]]) # and
p = Poly(x**3 + x + 1) # then
p.subs(x,M).expand()
ให้ข้อผิดพลาด:
TypeError: ไม่สามารถเพิ่ม <class'sympy.matrices.immutable.ImmutableDenseMatrix '> และ <class' sympy.core.numbers.One '>
ซึ่งเป็นไปได้มากเนื่องจากสองเทอมแรกกลายเป็นเมทริกซ์ แต่เทอมสุดท้าย (เทอมคงที่) ไม่ใช่เมทริกซ์ แต่เป็นสเกลาร์ เพื่อแก้ไขสถานการณ์นี้ฉันเปลี่ยนพหุนามเป็น
p = Poly(x**3 + x + x**0) # then
ข้อผิดพลาดเดิมยังคงมีอยู่ ฉันจำเป็นต้องพิมพ์นิพจน์ด้วยมือโดยแทนที่ x ด้วย M หรือไม่ ในตัวอย่างนี้พหุนามมีเพียงสามคำ แต่ในความเป็นจริงฉันพบ (พหุนามหลายตัวแปรที่มี) หลายสิบคำ
คำตอบ
ดังนั้นฉันคิดว่าคำถามส่วนใหญ่จะวนเวียนอยู่กับแนวคิดของพหุนามเมทริกซ์ :
(โดยที่ P เป็นพหุนามและ A คือเมทริกซ์)
ฉันคิดว่านี่เป็นการบอกว่าระยะอิสระเป็นตัวเลขและไม่สามารถบวกกับส่วนที่เหลือซึ่งเป็นเมทริกซ์ได้อย่างมีประสิทธิภาพการดำเนินการบวกไม่ได้กำหนดไว้ระหว่างสองประเภทนี้
TypeError: ไม่สามารถเพิ่ม <class'sympy.matrices.immutable.ImmutableDenseMatrix '> และ <class' sympy.core.numbers.One '>
อย่างไรก็ตามสิ่งนี้สามารถหลีกเลี่ยงได้โดยการกำหนดฟังก์ชันที่ประเมินพหุนามเมทริกซ์สำหรับเมทริกซ์เฉพาะ ความแตกต่างที่นี่คือที่ที่เรากำลังใช้เมทริกซ์ยกกำลังเพื่อให้เราได้อย่างถูกต้องคำนวณระยะฟรีของพหุนามเมทริกซ์a_0 * I
ที่I=A^0
เป็นเมทริกซ์เอกลักษณ์ของรูปร่างที่ต้องการ:
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)
เอาท์พุต:
ในตัวอย่างนี้พหุนามมีเพียงสามคำ แต่ในความเป็นจริงฉันพบ (พหุนามหลายตัวแปรที่มี) หลายสิบคำ
ฟังก์ชันeval_poly_matrix
ข้างต้นสามารถขยายเพื่อใช้กับพหุนามหลายตัวแปรโดยใช้.monoms()วิธีการแยกโมโนเมียลที่มีสัมประสิทธิ์ที่ไม่ใช่ศูนย์ดังนี้:
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))
หมายเหตุ: การตรวจสอบความมีสติการจัดการกรณีขอบและการเพิ่มประสิทธิภาพสามารถทำได้:
- จำนวนตัวแปรที่มีอยู่ในพหุนามเกี่ยวข้องกับจำนวนเมทริกซ์ที่ส่งผ่านเป็นพารามิเตอร์ (อดีตไม่ควรมากกว่าตัวหลังและหากต่ำกว่าตรรกะบางอย่างที่จำเป็นต้องมีเพื่อจัดการกับสิ่งนั้นฉันจะจัดการเฉพาะกรณีนี้เท่านั้น เมื่อทั้งสองเท่ากัน)
- เมทริกซ์ทั้งหมดต้องเป็นกำลังสองตามนิยามของพหุนามเมทริกซ์
- การอภิปรายเกี่ยวกับคุณลักษณะกฎของ Hornerเวอร์ชันหลายตัวแปรในความคิดเห็นของคำถามนี้ สิ่งนี้อาจมีประโยชน์ในการลดจำนวนการคูณเมทริกซ์
- จัดการกับความจริงที่ว่าในพหุนามเมทริกซ์
x*y
จะแตกต่างจากy*x
เพราะคูณเมทริกซ์ไม่สามารถสับเปลี่ยน เห็นได้ชัดว่าฟังก์ชัน poly ใน sympy ไม่รองรับ ตัวแปรที่ไม่สับเปลี่ยนแต่คุณสามารถกำหนดสัญลักษณ์ด้วยcommutative=False
และดูเหมือนว่าจะมีทางไปข้างหน้า
เกี่ยวกับจุดที่ 4 ข้างต้นมีการรองรับนิพจน์ Matrixใน SymPy และสามารถช่วยได้ที่นี่:
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)
เอาท์พุต:
สำหรับการพัฒนาเพิ่มเติมเกี่ยวกับคุณลักษณะนี้โปรดติดตาม# 18555