Ismerkedés a sympy modullal

Számos kereskedelmi (Mathematica, Maple) számítógépes algebrai csomag létezik már, melyek bonyolult analitikusformula-manipulációs készséggel rendelkeznek. A sympy csomag egy ingyenes nyílt forráskódú python modul, ami használható alternatívát kínál kereskedelmi vetélytársaival szemben. Ebben a notebookban néhány sympy függvénnyel fogunk megismerkedni. Mielőtt fejest ugranánk a modul ismertetésébe, álljon itt az alábbi két kép figyelmeztetésül:

vs.

Általában ugyanis igaz az, hogy a hétköznapi felhasználók (alapvetően diákok) hajlamosak túlságosan megbízni ezekben a formulamanipulációs programcsomagokban. Sokszor hallani oktatási intézmények folyosóin, hogy: 'Még a Mathematica se tudta kiszámolni!' Ezek a programcsomagok nem mindentudó orákulumok! Alapvetően inkább mankóként tekintsünk rájuk, amit a saját készségeinkhez próbálunk igazítani, s nem mint egy mindent tudó feketedobozra amely minden kérdésre tévedhetetlenül a pontos választ adja.

Fontos megjegyezni, hogy mivel van pár, a sympy függvényeihez hasonló nevű függvény a pylab parancs által importált modulokban, ezért a kellemetlenségek elkerülése végett célszerű - legalábbis a házi feladatok megoldása során - mindig külön notebookot indítani a sympy-os problémák megoldásánál! Ezen felül a már megszokott %pylab inline helyett %matplotlib inline -al kezdjük a notebookokat, hogy az esetlegesen megjeleníteni kívánt ábrák jól működjenek!

In [1]:
# Figyelem az alábbi parancs csak az ábrázolásra készíti fel a környezetet
%matplotlib inline
# Ez a két parancs pedig a szimbolikus számításra
from sympy import * # a sympy csomag rutinjainak betöltése
init_printing()     # szép kimenet  

Változók, egyenletek és egyenletrendszerek megoldása

Ahhoz, hogy változókat szimbolikusan is manipulálni tudjunk, meg kell mondanunk a Pythonnak, hogy ezentúl tekintsen a változónkra mint valamilyen matematikai formulában előforduló szimbólumra. Ezt a legegyszerűbben így tehetjük meg:

In [2]:
x=symbols('x')

Ezek után az $x$ változót használhatjuk szimbolikus számításokra. Oldjuk meg például a következő egyszerű egyenletet: $$3x=5$$ Ezt a solve függvény segítségével tehetjük meg. A solve függvény első bemenete a megoldandó egyenlet 0-ra rendezve, a második pedig a keresett változó:

In [3]:
solve(3*x-5,x)
Out[3]:
$$\left [ \frac{5}{3}\right ]$$

Definiáljunk néhány további változót is!

In [4]:
y,z,a,b,c=symbols('y,z,a,b,c') # Így definiálunk egyszerre több változót
In [5]:
k,l=symbols('k,l',integer=True) # Így specifikáljuk hogy a defiiált változók egész számok
p,q=symbols('p,q',real=True) # Így pedig hogy valósak

Oldjuk meg most az $$a x+b=y$$ egyenletet $x$ -re!

In [6]:
solve(a*x+b-y,x)
Out[6]:
$$\left [ \frac{1}{a} \left(- b + y\right)\right ]$$

Ha több megoldása is van az egyenletnek, akkor a sympy solve függvénye lehetőség szerint mind a kettőt megtalálja. Jól mutatja ezt a másodfokú egyenlet megoldásának "megtalálása":

In [7]:
solve(a*x**2+b*x+c,x)
Out[7]:
$$\left [ \frac{1}{2 a} \left(- b + \sqrt{- 4 a c + b^{2}}\right), \quad - \frac{1}{2 a} \left(b + \sqrt{- 4 a c + b^{2}}\right)\right ]$$

Természetesen a megoldás nem feltétlenül valós szám! A komplex egységgyököt a sympy I-vel jelöli:

In [8]:
I**2
Out[8]:
$$-1$$

A solve függvényt egyenletrendszerek megoldására is lehet használni. Ilyenkor a nullára rendezett egyenleteket listába foglaljuk. A keresett változókat szintúgy. Oldjuk meg a következő egyenletrendszert az $x$ és $y$ változókra: $$y=x^2+ax-4b$$ $$y=x-b$$ Mivel $x$-ben másodrendű az első egyenlet, ezért két megoldáspárt várunk (A parabola legfeljebb két helyen metszi az egyenest...)

In [9]:
solve([x**2 + a*x -4*b - y, x - y - b],[x,y]) # Így kell egyenletrendszert megoldani
Out[9]:
$$\left [ \left ( - \frac{a}{2} - \frac{1}{2} \sqrt{a^{2} - 2 a + 12 b + 1} + \frac{1}{2}, \quad - \frac{a}{2} - b - \frac{1}{2} \sqrt{a^{2} - 2 a + 12 b + 1} + \frac{1}{2}\right ), \quad \left ( - \frac{a}{2} + \frac{1}{2} \sqrt{a^{2} - 2 a + 12 b + 1} + \frac{1}{2}, \quad - \frac{a}{2} - b + \frac{1}{2} \sqrt{a^{2} - 2 a + 12 b + 1} + \frac{1}{2}\right )\right ]$$

A solve függvény kimenete most egy lista, amelynek az elemei a megfelelő $(x,y)$ párok.

Behelyettesítés és kiértékelés

Sokszor előfordul, hogy analitikus számítások során a képletek egyszerűsítése végett egy-egy gyakran ismétlődő kifejezésre az ember bevezet egy rövidítést. A számolás befejeztével ezeket a rövidítéseket vissza kell helyettesíteni az eredeti megfelelőikkel a végeredménybe. Ilyen és ehhez hasonló helyettesítésekre alkalmazható a subs() metódus, mely a sympy minden kifejezés objektumának metódusa. Lássunk erre egy példát! Legyen egy számolás eredménye $x^2+ax-y$, és legyen ez az eredmény a valami változóban eltárolva:

In [10]:
valami=x**2 + a*x - y
valami
Out[10]:
$$a x + x^{2} - y$$

Tegyük most fel, hogy korábban az $y$-t az $x^3$ kifejezés helyettesítésére vezettük be, és most vissza akarjuk vezetni. Ekkor a subs metódus az alábbiak szerint alkalmazható:

In [11]:
valami.subs(y,x**3)
Out[11]:
$$a x - x^{3} + x^{2}$$

A számítások végrehajtásának utolsó lépése, hogy numerikusan kiértékeljük az eredményeket. Ezt a sympy-ban az evalf() metódus segítségével tehetjük meg. Például:

In [12]:
ize=sqrt(8)
In [13]:
ize.evalf()
Out[13]:
$$2.82842712474619$$

Az evalf metódust egyetlen egész számú argumentummal meghívva tudjuk az eredmény elvárt numerikus precizióját befolyásolni:

In [14]:
ize.evalf(40)
Out[14]:
$$2.828427124746190097603377448419396157139$$

Ha a kifejezésünk több ismeretlent tartalmaz, akkor az evalf-nak a subs kulcsszavas argumentumába szótárszerűen felsorolhatjuk a kívánt numerikus behelyettesítési értékeket:

In [15]:
ize2=sin(2*x)+cos(y)
In [16]:
ize2.evalf(12,subs={x:0.5,y:0.3})
Out[16]:
$$1.79680747393$$

Függvényanalízis

A sympy egyik legnagyobb előnye, hogy a Python nyelven belül lehetővé teszi egyszerűbb analízisbeli feladatok elvégzését. Alább a teljesség igénye nélkül összefoglalunk néhány egyszerű függvényt. Vizsgáljuk meg a következő két határértéket: $$\lim_{x\rightarrow 0}\frac{\sin x}{x}=? $$ illetve $$\lim_{x\rightarrow \infty}\frac{1}{1+\mathrm{e}^{-x}}=? $$ A határértéket a limit függvény segítségével tudjuk meghatározni:

In [17]:
limit(sin(x)/x,x,0)# sin(x)/x határértéke az x=0 pontban.
Out[17]:
$$1$$

Ha a végtelenben vagyunk kíváncsiak a határértékre, akkor azt az oo-szimbólummal tudjuk elérni!

In [18]:
limit(1/(1+exp(-x)),x,oo)
Out[18]:
$$1$$

Egy kifejezés deriváltjait a diff függvény segítségével tudjuk meghatározni. Például a $\sin$ függvény első $x$-szerinti deriváltja:

In [19]:
diff(sin(x),x)
Out[19]:
$$\cos{\left (x \right )}$$

A második deriváltat vagy így

In [20]:
diff(sin(x),x,x)
Out[20]:
$$- \sin{\left (x \right )}$$

vagy így, (talán egy kicsit átláthatóbban) írjuk.

In [21]:
diff(sin(x),x,2)
Out[21]:
$$- \sin{\left (x \right )}$$

Természetesen parciális deriváltak elvégzésére is van mód:

In [22]:
diff(sin(x)*cos(y),x,y)
Out[22]:
$$- \sin{\left (y \right )} \cos{\left (x \right )}$$

A magasabb rendű parciális deriváltak legyártása az egyszerű deriváltak általánosításán alapszik:

In [23]:
diff(sin(x)*cos(y),x,2,y,3)
Out[23]:
$$- \sin{\left (x \right )} \sin{\left (y \right )}$$

Az integrate függvény segítségével határozott és határozattlan integrálokat tudunk elvégezni.

Határozzuk meg először az $x^2$ primitív függvényét:

In [24]:
integrate(x**2,x)
Out[24]:
$$\frac{x^{3}}{3}$$

Az $$\int_0^3 x^2\mathrm{d}x$$ határozott integrált pedig az alábbi módon értékelhetjük ki.

In [25]:
integrate(x**2,(x,0,3))
Out[25]:
$$9$$

Természetesen az integrálás során szerepelhetnek a kifejezésben más paraméterek is:

In [26]:
integrate(x**2+y**3,(x,0,3))
Out[26]:
$$3 y^{3} + 9$$

Többváltozós integrált egyszerűen a változók (és ha határozott integrálról van szó, akkor az integrálási határok) egymás után írásával értékelhetünk ki:

A $$\int x^2+y^3 \mathrm{d}x\mathrm{d}y $$ határozatlan integrál:

In [27]:
integrate(x**2+y**3,x,y)
Out[27]:
$$\frac{x^{3} y}{3} + \frac{x y^{4}}{4}$$

A $$\int_0^3\int_{-3}^{5} x^2+y^3 \mathrm{d}x\mathrm{d}y $$ határozott integrál:

In [28]:
integrate(x**2+y**3,(x,0,3),(y,-3,5))
Out[28]:
$$480$$

Analitikus függvények ábrázolása

A sympy modul segítségével a meghatározott analitikus függvényeket ábrázolni is tudjuk. Erre a sympy a már korábban megismert matplotlib csomag függvényeit használja, DE egy kicsit MÁS SZINTAKTIKÁT követve! Az alapvető különbség a két csomag között, hogy míg a matplotlib szigorúan csak numerikus adatokat tud kezelni, a mintavételezésről és a függvény kiértékeléséről a felhasználó gondoskodik, addig a sympy-nak elég magát az analitikus kifelyezést megadni, és maga gondoskodik az ábrázolás létrehozásához szükséges numerikus értékeket tartalmazó struktúrák létrehozásáról. Az alábbiakban a sympy modul plotting almodulja segítségével síkbeli és térbeli analitikus görbék és alakzatok megjelenítésére látunk néhány példát:

In [29]:
from sympy.plotting import * # A modul betöltése

Az plot függvény egyváltozós skalár kifejezések megjelenítését teszi lehetővé.

In [30]:
plot(1/(exp(x)+1),(x,-10,10))
Out[30]:
<sympy.plotting.plot.Plot at 0x7f5178f044a8>

A plot_parametric síkbeli általános parametrikus görbék ábrázolására szolgál

In [31]:
plot_parametric(sin(x),cos(x),(x,0,2*pi))
Out[31]:
<sympy.plotting.plot.Plot at 0x7f5178f11cc0>

Térbeli görbék a plot3d_parametric_line függvénnyel jeleníthetők meg.

In [32]:
plot3d_parametric_line(cos(3*x),sin(3*x),x,(x,0,2*pi))
Out[32]:
<sympy.plotting.plot.Plot at 0x7f517909fef0>

Térbeli felületek a ábrázolására a plot3d és plot3d_parametric_surface függvények szolgálnak:

In [33]:
plot3d(sin(x)*cos(y),(x,-pi,pi),(y,-pi,pi))
Out[33]:
<sympy.plotting.plot.Plot at 0x7f51790acb00>
In [34]:
 u, v = symbols('u v')
In [35]:
plot3d_parametric_surface(sin(v)*cos(u),sin(v)*sin(u),cos(v), (u, 0, 2*pi), (v, 0, pi))
Out[35]:
<sympy.plotting.plot.Plot at 0x7f51769f7550>

Egyszerűsítés

A sympy csomag számos szimbolikus kifejezések egyszerűbb alakra hozását elősegítő metódussal rendelkezik. Az alábbiakban tekintsük át ezek közül a legegyszerűbbeket!

Általános eset, a simplify fügvény

A legáltalánosabb egyszerűsítő függvény a simplify, mely különösebb specifikációk nélkül arra törekszik, hogy a hasában szereplő kifejezést a lehető legtömörebb alakra hozza. Lássunk erre néhány példát:

In [36]:
simplify(sin(x)**2 + cos(x)**2)
Out[36]:
$$1$$
In [37]:
simplify((x**3 + x**2 - x - 1)/(x**2 + 2*x + 1))
Out[37]:
$$x - 1$$

Láttuk, hogy a fenti két példában valóban tömörebbre sikerült hozni egy-egy bonyolultabb kifejezést, lássunk egy ellenpéldát is! A simplify az alábbi, talán sokak számára könnyen egyszerűsíthető kifejezést nem egyszerűsíti tovább:

In [38]:
simplify(x**2 + 2*x +1)
Out[38]:
$$x^{2} + 2 x + 1$$

A fenti jelenség oka az, hogy algoritmikusan nehéz jól definiálni az 'egyszerűsítés' fogalmát. Ha kicsit jobban kifejtjük, hogy milyen egyszerűsítésre gondolunk, akkor már könnyebb dolga van a sympy-nak is. Az alábbiakban megismerkedünk néhány olyan függvénnyel, ami kifejezések specifikus egyszerűsítésére vagy éppen kibontására ad lehetőséget.

Polinomiális és racionális kifejezések

Az expand() függvény segítségével legegyszerűbb esetben polinomiális kifejezéseket bonthatunk ki:

In [39]:
expand((x+y)**3)
Out[39]:
$$x^{3} + 3 x^{2} y + 3 x y^{2} + y^{3}$$

A factor() függvény talán egy kicsit az expand() függvény ellenkezője. A factor függvény a kapott kifejezést a lehető legtömörebb szorzatalakba próbálja hozni. Így például a simplify által nem egyszerűsített kifejezés a factor() segítségével:

In [40]:
factor(x**2 + 2*x +1)
Out[40]:
$$\left(x + 1\right)^{2}$$

a várt egyszerűbb alakra alakul.

Általánosabb többváltozós polinomiális kifejezések manipulálása során előfordul, hogy egy bizonyos változó szerint szeretnénk a polinomot rendezni. Erre való a collect() függvény. Lássunk erre is egy példát:

In [41]:
kifejezes=x*y + x - 3 + 2*x**2 - z*x**2 + x**3
In [42]:
collect(kifejezes,x)
Out[42]:
$$x^{3} + x^{2} \left(- z + 2\right) + x \left(y + 1\right) - 3$$
In [43]:
xek=collect(kifejezes,x)

A coeff() metódussal pedig megkaphatjuk a polinom megfelelő hatványkitevőihez tartozó együtthatókat:

In [44]:
xek.coeff(x,2)
Out[44]:
$$- z + 2$$

A cancel() függvény racionális (polinom/polinom) kifejezések egyszerűsítésére szolgál:

In [45]:
cancel((x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2)/(x**2 - 1))
Out[45]:
$$\frac{1}{x - 1} \left(y^{2} - 2 y z + z^{2}\right)$$

Az apart() a parciális törtekre bontást végző függvény:

In [46]:
expr = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x)
expr
Out[46]:
$$\frac{4 x^{3} + 21 x^{2} + 10 x + 12}{x^{4} + 5 x^{3} + 5 x^{2} + 4 x}$$
In [47]:
apart(expr)
Out[47]:
$$\frac{2 x - 1}{x^{2} + x + 1} - \frac{1}{x + 4} + \frac{3}{x}$$

Trigonometrikus függvényeket tartalmazó kifejezések

Trigonometrikus függvényeket tartalmazó kifejezések kezelésére két metódus szolgál:

A trigsimp() trigonometrikus azonosságokat figyelembe véve a lehető legtömörebb kifejezés előállítására törekszik:

In [48]:
expr=sin(x)**4 - 2*cos(x)**2*sin(x)**2 + cos(x)**4
expr
Out[48]:
$$\sin^{4}{\left (x \right )} - 2 \sin^{2}{\left (x \right )} \cos^{2}{\left (x \right )} + \cos^{4}{\left (x \right )}$$
In [49]:
trigsimp(expr)
Out[49]:
$$\frac{1}{2} \cos{\left (4 x \right )} + \frac{1}{2}$$

A expand_trig() függvény pedig olyan formulákká alakítja a trigonometrikus függvényeket tartalmazó kifejezéseket melyek argumentumai a lehető legegyszerűbbek... cserébe természetesen a végeredmény hosszabb lesz.

In [50]:
expand_trig(cos(4*x))
Out[50]:
$$8 \cos^{4}{\left (x \right )} - 8 \cos^{2}{\left (x \right )} + 1$$

Rewrite

A rewrite metódus a sympy kifejezések általánosabb átírását teszi lehetővé. Alkalmazható például trigonometrikus kifejezések boncolgatására:

In [51]:
tan(x).rewrite(sin)
Out[51]:
$$\frac{2 \sin^{2}{\left (x \right )}}{\sin{\left (2 x \right )}}$$

vagy trigonometrikus és exponenciális függvényeket tartalmazó kifejezések egymásba alakítására:

In [52]:
sin(x).rewrite(exp)
Out[52]:
$$- \frac{i}{2} \left(e^{i x} - e^{- i x}\right)$$

de más a sympy -ban implementált függvény azonosságokat kihasználó formulamanipulációra is:

In [53]:
factorial(x).rewrite(gamma) # a faktoriális és a gamma függvény kapcsolata
Out[53]:
$$\Gamma{\left(x + 1 \right)}$$
In [54]:
binomial(x,y).rewrite(factorial) # a binomiális eggyütthatók és a faktoriális kapcsolata
Out[54]:
$$\frac{x!}{y! \left(x - y\right)!}$$

A fentiekben a sympy formula manipulációs képességeit csak nagyon felületesen vizsgáltuk meg. Bővebb információért érdemes a megfelelő függvények dokumentációit, illetve magát a sympy documentációt böngészni!

Analitikus Lineáris algebra

A sympy segítségével paraméteres lineáris algebrai problémákat is megoldhatunk. Ilyen problémák kezelésére a sympy modul a Matrix osztályt vezeti be. Figyelem, nem összekeverendő ez a modul a numpy numerikus matrix, illetve array osztályaival! Az alábbiakban egy pár példán keresztül illusztráljuk a szimbolikus mátrixok létrehozását és a rajtuk végrehajtható műveletek viselkedését. Hozzunk létre két egyszerű 2x2-es mátrixot!

In [55]:
M=Matrix([[0, -x*exp(I*y)],
          [-x*exp(-I*y), 0]])
M
Out[55]:
$$\left[\begin{matrix}0 & - x e^{i y}\\- x e^{- i y} & 0\end{matrix}\right]$$
In [56]:
B=Matrix([[1,2],
          [4,5]])
B
Out[56]:
$$\left[\begin{matrix}1 & 2\\4 & 5\end{matrix}\right]$$

Figyeljük meg, hogy az M mátrix elemei maguk is tartalmaznak sympy változókat, míg a B mátrix csak numerikus értékeket tartalmaz. A két mátrix a várható módon viselkedik, például össze tudjuk őket adni:

In [57]:
M+B
Out[57]:
$$\left[\begin{matrix}1 & - x e^{i y} + 2\\- x e^{- i y} + 4 & 5\end{matrix}\right]$$

vagy össze tudjuk őket szorozni:

In [58]:
M*B
Out[58]:
$$\left[\begin{matrix}- 4 x e^{i y} & - 5 x e^{i y}\\- x e^{- i y} & - 2 x e^{- i y}\end{matrix}\right]$$

Természetesen a szorzás eredménye függ a sorrendtől!

In [59]:
B*M
Out[59]:
$$\left[\begin{matrix}- 2 x e^{- i y} & - x e^{i y}\\- 5 x e^{- i y} & - 4 x e^{i y}\end{matrix}\right]$$

Mátrixokra a hatványozás művelet nem elemenként, hanem mátrixhatványozásként hat!

In [60]:
M**2
Out[60]:
$$\left[\begin{matrix}x^{2} & 0\\0 & x^{2}\end{matrix}\right]$$

Mátrix inverzét is meg tudjuk határozni a **-operátorral:

In [61]:
B**(-1)
Out[61]:
$$\left[\begin{matrix}- \frac{5}{3} & \frac{2}{3}\\\frac{4}{3} & - \frac{1}{3}\end{matrix}\right]$$

Létezik néhány függvény, ami a mátrixok létrehozását szolgálja. Az eye() tetszőleges méretű egységmátrixot hoz létre:

In [62]:
eye(3)
Out[62]:
$$\left[\begin{matrix}1 & 0 & 0\\0 & 1 & 0\\0 & 0 & 1\end{matrix}\right]$$

A diag() függvény diagonális struktúrájú mátrixok gyártására való:

In [63]:
diag(sin(x),y,z)
Out[63]:
$$\left[\begin{matrix}\sin{\left (x \right )} & 0 & 0\\0 & y & 0\\0 & 0 & z\end{matrix}\right]$$

Ahhoz, hogy néhány alapvető lineáris algebrai feladatot meg tudjunk oldani, szükség lesz oszlop- illetve sorvektorokra is. Ezeket is le tudjuk gyártani a Matrix osztály segítségével:

In [64]:
v=Matrix([[1,2]])
v
Out[64]:
$$\left[\begin{matrix}1 & 2\end{matrix}\right]$$
In [65]:
w=Matrix([[1],[2]])
w
Out[65]:
$$\left[\begin{matrix}1\\2\end{matrix}\right]$$

A mátrix-vektor szorzás a már megszokott módon történik:

In [66]:
B*w
Out[66]:
$$\left[\begin{matrix}5\\14\end{matrix}\right]$$
In [67]:
v*B
Out[67]:
$$\left[\begin{matrix}9 & 12\end{matrix}\right]$$

Mátrixokkal és vektorokkal megadott lineáris egyenletrendszerek megoldására kínál lehetőséget a Matrix osztály solve() metódusa. Például a fent definiált B és w változók által meghatározott $$Bx=w$$ lineáris problémát az alábbi módon oldhatjuk meg:

In [68]:
B.solve(w)
Out[68]:
$$\left[\begin{matrix}- \frac{1}{3}\\\frac{2}{3}\end{matrix}\right]$$

Egy mátrix determinánsa a det, a nyoma a trace metódussal számítható:

In [69]:
M.det()
Out[69]:
$$- x^{2}$$
In [70]:
B.trace()
Out[70]:
$$6$$

A mátrix transzponáltja, illetve adjungáltja a .T, illetve .H konstrukcióval érhető el:

In [71]:
M.T
Out[71]:
$$\left[\begin{matrix}0 & - x e^{- i y}\\- x e^{i y} & 0\end{matrix}\right]$$
In [72]:
M.H
Out[72]:
$$\left[\begin{matrix}0 & - e^{i \overline{y}} \overline{x}\\- e^{- i \overline{y}} \overline{x} & 0\end{matrix}\right]$$

A fenti eredményben a változók fölé húzott vonal a komplex konjugáltat jelöli.

Egy mátrix sajátérték problémájának vizsgálatára az eigenvals() és eigenvects() metódusok szolgálnak. Az eigenvals() egy dict-tel tér vissza, mely a sajátértékeket kulcsszóként tartalmazza, a kulcsokhoz tartozó érték pedig a sajátérték degenerációjának fokát jelzi:

In [73]:
M.eigenvals()
Out[73]:
$$\left \{ - x : 1, \quad x : 1\right \}$$

Az eigenvects() a sajátértékeket, a multiplicitásukat és a sajátértékhez tartozó sajátvektorokat adja vissza:

In [74]:
M.eigenvects()
Out[74]:
$$\left [ \left ( - x, \quad 1, \quad \left [ \left[\begin{matrix}e^{i y}\\1\end{matrix}\right]\right ]\right ), \quad \left ( x, \quad 1, \quad \left [ \left[\begin{matrix}- e^{i y}\\1\end{matrix}\right]\right ]\right )\right ]$$