2015-04-15 16 views
5

Voglio trovare gli autovettori di una matrice in Sympy e ho scritto il seguente programma, ma non funziona. D'altra parte, la funzione A.eigenvects() in Sympy calcola gli autovalori e gli autovettori della matrice A e I hanno usato una cosa simile qui, ma quando voglio stampare i risultati, viene mostrata una lista vuota. Per favore, guidami?Eigenvector non funziona in Sympy

from sympy import * 

H=Matrix([ [215.0 ,-104.1 ,5.1 ,-4.3 ,4.7 ,-15.1 ,-7.8], 
     [-104.1 , 220.0 ,32.6 , 7.1 ,5.4 , 8.3 ,0.8], 
     [ 5.1 , 32.6 , 0. , -46.8 , 1.0 , -8.1 , 5.1 ], 
     [ -4.3 , 7.1  ,-46.8 ,125.0 ,-70.7 ,-14.7 ,-61.5], 
     [ 4.7 , 5.4  , 1.0 ,-70.7 ,450.0 ,89.7 ,-2.5], 
     [-15.1 , 8.3  ,-8.1 ,-14.7 ,89.7 ,330.0 ,32.7], 
     [-7.8 ,0.8  ,5.1 ,-61.5 ,-2.5 ,32.7 ,280.0]]) 


zz=H.eigenvects() 
pprint(zz) 
+1

Sei sicuro che matrice ha alcun autovettori? – KSFT

+0

@KSFT Lo fa davvero. Calcola il polinomio caratteristico. – miradulo

+1

@DonkeyKong Non ricordo come farlo, ed è troppo lungo per Wolfram Alpha, quindi mi fiderò di te. – KSFT

risposta

2
>>> H 
    Matrix([ 
    [ 215.0, -104.1, 5.1, -4.3, 4.7, -15.1, -7.8], 
    [-104.1, 220.0, 32.6, 7.1, 5.4, 8.3, 0.8], 
    [ 5.1, 32.6,  0, -46.8, 1.0, -8.1, 5.1], 
    [ -4.3, 7.1, -46.8, 125.0, -70.7, -14.7, -61.5], 
    [ 4.7, 5.4, 1.0, -70.7, 450.0, 89.7, -2.5], 
    [ -15.1, 8.3, -8.1, -14.7, 89.7, 330.0, 32.7], 
    [ -7.8, 0.8, 5.1, -61.5, -2.5, 32.7, 280.0]]) 
    >>> x = H.charpoly(symbols('lamda')) 
    >>> factor(x) 
    1.0*(1.0*lamda**7 - 1620.0*lamda**6 + 1029369.57*lamda**5 - 
324725076.332*lamda**4 + 52250209639.9248*lamda**3 - 
3762668861934.64*lamda**2 + 49798018861415.7*lamda + 
4.112530087788e+15) 

l'ultima equazione ha radici reali 7 => (lamda +23.738) *(lamda -101.965) *(lamda -120.956) *(lamda -268.369) *(lamda -307.126) *(lamda -332.005) *(lamda -513.317) = 0

[-23.738, 101.965, 120.956, 268.369, 307.126, 332.005, 513.317]

ed è davvero strano, perché sympy continuano a dire questa matrice non ha autovettori.

+0

@Romano Zumbé per favore dai un'occhiata a questo: http://docs.sympy.org /latest/tutorial/matrices.html?highlight=lamda – marmeladze

+0

Ah, Ok. Capisco perché è usato in questo modo. Scusa –

2

Sembra che potrebbe essere un bug per me, per qualche motivo non gradisce la matrice. Il tentativo di utilizzare eigenvals() anche semplicemente restituisce nulla, ma utilizzando l'algoritmo di Berkowitz produce un risultato atteso (questi sono corretti):

>>> H.berkowitz_eigenvals() 
{−23.7383543150805:1,101.965215714556:1,120.955771704237:1, 
    268.369453977695:1,307.126362241411:1,332.004505895816:1,513.317044781366:1} 

In alternativa, trovare il carattere radici polinomio dà lo stesso risultato:

>>> roots(H.charpoly(x),x) 
{−23.7383543150805:1,101.965215714556:1,120.955771704237:1, 
    268.369453977695:1,307.126362241411:1,332.004505895816:1,513.317044781366:1} 

Per quanto riguarda una soluzione alternativa, al momento non ho idee oltre all'utilizzo di un'altra libreria, forse NumPy/SciPy:

>>> from numpy import linalg as LA 
>>> w,v = LA.eig(np.array([ [215.0 ,-104.1 ,5.1 ,-4.3 ,4.7 ,-15.1 ,-7.8], 
     [-104.1 , 220.0 ,32.6 , 7.1 ,5.4 , 8.3 ,0.8], 
     [ 5.1 , 32.6 , 0. , -46.8 , 1.0 , -8.1 , 5.1 ], 
     [ -4.3 , 7.1  ,-46.8 ,125.0 ,-70.7 ,-14.7 ,-61.5], 
     [ 4.7 , 5.4  , 1.0 ,-70.7 ,450.0 ,89.7 ,-2.5], 
     [-15.1 , 8.3  ,-8.1 ,-14.7 ,89.7 ,330.0 ,32.7], 
     [-7.8 ,0.8  ,5.1 ,-61.5 ,-2.5 ,32.7 ,280.0]]) 
>>> w;v 
array([[ 0.0211232 , -0.0863685 , 0.31060486, 0.64800412, 0.58825511, 
     0.34578278, -0.1004976 ], 
     [-0.03360278, -0.17141713, 0.28577077, 0.60531169, -0.57444552, 
     -0.41080118, 0.15058085], 
     [-0.01492258, 0.91780802, -0.23783515, 0.29790711, -0.04561479, 
     -0.00789624, 0.09974215], 
     [ 0.19183148, 0.33999268, 0.79845203, -0.30609739, 0.01552874, 
     -0.18077 , -0.2889039 ], 
     [-0.86037599, 0.04835763, 0.171535 , -0.10783263, 0.27161704, 
     -0.27390267, 0.25993089], 
     [-0.45801107, 0.01859027, -0.05846719, 0.07732967, -0.35064091, 
     0.32022588, -0.74497537], 
     [-0.1066849 , 0.05006013, 0.30810033, -0.11677503, -0.35344244, 
     0.70807431, 0.50125772]]) 
7

Il problema deriva dall'uso di Floats e Rationals. eigenvects riporta i float su Rationals. La routine eigenvals non riesce quando root non riesce a calcolare il polinomio. Quando chiami direttamente eigenvals, i Float sono anche rifusi ma puoi selezionare non per rifarli; quando lo fai, roots è in grado di restituire valori e vengono restituiti i valori di eigen.

>>> H.eigenvals() 
{} 
>>> H.eigenvals(rational=False) 
{513.317044781366: 1, 101.965215714556: 1, 332.004505895816: 1, 268.369453977695: 1, 120.955771704237: 1, -23.7383543150805: 1, 307.126362241411: 1} 

Sembra roots dovrebbe essere tornando casi RootOf per questo 7 ° ordine polinomiale, piuttosto che tornare senza radici. Sarebbe bello per segnalare questa come un problema per SymPy:

radici (p) -> {} invece di istanze RootOf quando p = 5000000*x**7 - 8100000000*x**6 + 5146847850000*x**5 - 1623625381660000*x**4 + 261251048199624000*x**3 - 18813344309673222800*x**2 + 248990094307079384205*x + 20562650438939697400552

+0

Questo particolare polinomio ha le 7 radici reali per la matrice; un semplice esempio di un polinomio fallito che ha solo 1 radice reale è 'x ** 7-x + 1' – smichr

+0

Molto interessante, questo mi ha lasciato perplesso per un po ', +1 – miradulo

+0

Ci sono problemi correlati già segnalati, ad es. https://github.com/sympy/sympy/issues/6331 – smichr