Készítsük el a saját mátrix osztályunkat, aminek az exp() taggfüggvénye a mátrix exponciálisát adja vissza (tehát nem egyszerűen a mátrix elemeinek exponencializáltját). Az osztályunk minden más tekinetben ugyanúgy viselkedjen, mint a numpy mátrixosztálya. Kis segitség: https://docs.scipy.org/doc/numpy/user/basics.subclassing.html
Mivel a mátrix osztály a numpy
modulban található, először ezt hívjuk meg, továbbá a math
modul factorial()
függvényére is szükségünk lehet
import numpy as np
from math import factorial as fact
A feladatot megvalósító sajatmatrix
osztály az np.matrix
osztály leszármazottja kell legyen, hogy annak összes funkcióját tudja. Mivel ez az osztály tudja a mátrixok helyes módon való összeadását, számmal szorzását, egymással való szorzását és hatványozását, csak az exp()
függvény elkészítésére kell koncentrálni.
Az exponenciálist hatványsor segítségével értelmezzük, így az összegzés egy for-ciklus segítségével oldható meg legegyszerűbben. Mivel az exponenciális végtelen tag összege, ezért pontosan nem lehet ezzel a módszerrel kiszámolni, de mivel a számítógép úgyis csak véges tizedes jegyet tárol, nem kell végtelen mátrixot összeadni, csak annyit, hogy a további tagok, kerekítve 0-t adjanak.
Ismert, hogy az exponenciális függvény hatványsora mindig konvergens, úgyhogy előbb utóbb biztos eljutunk egy pontig, amikor már a soron következő tag elég kicsi ahhoz, hogy kezelje a gép. Ez azért jelenik meg, mert a faktoriális sorozat gyorsabban tart a végtelenhez, mint a polinom, és ezzel osztva az eredmény kicsi lesz. Mivel azonban a faktoriális függvény eredménye egész, ezért ha elég nagy számmal akarunk osztani ahhoz, hogy a gép kezelni tudja, OverflowError
-t fog dobni. Ennek a kiszűrésével, megtalálható, hogy hol kell leállni.
class sajatmatrix(np.matrix):
'''Mátrix-osztály, ami tudja kezelni a mátrix exponenciálisát is.'''
def exp(self):
'''Függvény, mely a mátrix exponenciálisát adja vissza'''
eredmeny = self**0 # Az eredményt a sor 0. tagjával indítjuk, ehhez adjuk hozzá a többit
k = 1 # Futóváltozó, a hatványsor tagjának sorszámáról
try: # Kivételkezelés a hiba kiszűrésére
while ((self**k)/fact(k) > self*0).any(): # Addig menjen a ciklus amíg következő tag nem a nullmátrix
eredmeny = eredmeny + (self**k)/fact(k) # A hatványsor k. tagját hozzáadjuk az eredményhez
k += 1
except OverflowError: # Elkapjuk a hibát, amikor túl kicsi lesz a hatványsor tagja
pass
return eredmeny
És most nézzünk néhány példát, amivel ellenőrizhetjük az osztály működését:
a = sajatmatrix('1., 0; 0, 1')
b = sajatmatrix('1, 2; 3, 4')
c = sajatmatrix('0.5, 1.23, 2.56; 3.14, 2.7, 0; 4, 13, 11')
a.exp()
b.exp()
c.exp()