Bir polinomda bir matrisi değiştirirken karşılaşılan sorunlar

Jan 12 2021

Örnek: let

M = Matrix([[1,2],[3,4]]) # and 
p = Poly(x**3 + x + 1)    # then
p.subs(x,M).expand()

şu hatayı verir:

TypeError: <class'sympy.matrices.immutable.ImmutableDenseMatrix '> ve <class' sympy.core.numbers.One '> eklenemiyor

ki ilk iki terim matris haline geldiğinden, ancak son terim (sabit terim) bir matris değil skaler olduğu için bu çok mantıklıdır. Bu durumu düzeltmek için polinomu şu şekilde değiştirdim

p = Poly(x**3 + x + x**0)    # then

aynı hata devam ediyor. İfadeyi x'i M ile değiştirerek elle yazmak zorunda mıyım? Bu örnekte polinomun yalnızca üç terimi vardır, ancak gerçekte düzinelerce terimle (çok değişkenli polinomlarla) karşılaşıyorum.

Yanıtlar

1 wsdookadr Jan 12 2021 at 12:40

Bu yüzden sorunun esas olarak Matrix polinomu kavramı etrafında döndüğünü düşünüyorum :

(burada P bir polinomdur ve A bir matristir)

Sanırım bu, serbest terimin bir sayı olduğunu ve bir matris olan geri kalanıyla eklenemeyeceğini söylüyor, etkili bir şekilde toplama işlemi bu iki tür arasında tanımsız.

TypeError: <class'sympy.matrices.immutable.ImmutableDenseMatrix '> ve <class' sympy.core.numbers.One '> eklenemiyor

Bununla birlikte, belirli bir matris için matris polinomunu değerlendiren bir işlev tanımlanarak bu aşılabilir. Burada fark Kullandığımız olmasıdır matris üs alma doğru olarak matris polinomun serbest terimini hesaplamak, böylece bir kimlik matris gerekli şeklin:a_0 * II=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)

Çıktı:

Bu örnekte polinomun yalnızca üç terimi vardır, ancak gerçekte düzinelerce terimle (çok değişkenli polinomlarla) karşılaşıyorum.

Yukarıdaki işlev , sıfır olmayan katsayılara sahip tek terimlileri çıkarma yöntemi eval_poly_matrixkullanılarak çok değişkenli polinomlar için çalışmak üzere genişletilebilir , örneğin:.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))

Not: Bazı akıl sağlığı kontrolleri, uç vakaların ele alınması ve optimizasyonlar mümkündür:

  1. Polinomda bulunan değişkenlerin sayısı, parametre olarak aktarılan matrislerin sayısı ile ilgilidir (birincisi, ikincisinden asla büyük olmamalıdır ve bunun üstesinden gelmek için bazı mantığın mevcut olması gerekiyorsa, yalnızca durumu ele aldım. ikisi eşit olduğunda)
  2. Matris polinomunun tanımına göre tüm matrisler kare olmalıdır
  3. Bir çok değişkenli sürümü hakkında bir tartışma Horner kuralı özelliklerini bu sorunun yorumlarla . Bu, matris çarpımlarının sayısını en aza indirmek için yararlı olabilir.
  4. Bir Matrix polinomunun matris çarpımının değişmeli olmadığı için olandanx*y farklı olduğu gerçeğini ele alın . Görünüşe sympy içinde poli işlevleri desteklemeyen olmayan değişmeli değişkenleri, ancak birlikte sembolleri tanımlayabilir ve ileriye orada bir yol var gibi görünüyory*x commutative=False

Yukarıdaki 4. nokta hakkında, SymPy'de Matrix ifadeleri için destek var ve bu burada yardımcı olabilir:

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)

Çıktı:

Bu özellikle ilgili daha fazla gelişme için # 18555'i takip edin