#!/usr/bin/env pythonimport stringclass Macierz: #konstruktor def __init__(self, daneMac=None, wymiar=None): #sprawdzamy co i czy dobrze zostalo przekazane do budowy macierzy if daneMac != None: if isinstance(daneMac, str): # jesli przekazalismy strinka z nazwa pliku f = open(daneMac, 'r') listaA = f.readlines() listaB = [] for x in range(len(listaA)): lista = map(lambda zz: float(zz), string.rsplit(listaA[x])) #rozbijamy co mamy rozbic i konwertujemy stringi z pliku na float listaB.append(lista) f.close() daneMac = listaB self.daneMac = daneMac r = len(daneMac) c = len(daneMac[0]) wymiarWiersz = sum([len(daneMac[i]) != c for i in range(r)]) #sprawdzanie dlugosci wierszy if wymiarWiersz > 0: raise ValueError #jesli podalismy zly wymiar, niezgodny z danymi to plujemy wyjatkiem else: self.wymiar = (r,c) if wymiar != None: if (wymiar[0] == r) and (wymiar[1] == c): self.wymiar = (r,c) else: # tutaj jednym slowem ustawiamy prawidlowe wymiary. taka budowa umozliwi w przyszlosci modyfikowanie wymiarow macierzy podczas pracy self.wymiar = (r,c) else: if wymiar != None: if len(wymiar) == 2: # mamy tylko dwa wymiary macierzy wiec tylko dwa wymiary mozemy przekazac, jesli bedzie cos nie tak to, wiadomo, wyjatek! self.wymiar = tuple(wymiar) r = wymiar[0] c = wymiar[1] else: arg = ("len(wymiar) != 2: ", wymiar) raise ValueError, arg # alokowanie macierzy w pamieci... uzywane przy operacjach matematycznych na macierzach (a to potrzebne nam jest do tworzenia macierzy wynikowych dla mnozenia, dodawania itp) self.daneMac = [[x * 0.0 for x in range(c)]] for i in range(1,r): self.daneMac.append([x * 0.0 for x in range(c)]) else: self.daneMac = [] self.wymiar = (0,0) def __getitem__(self, i): #zwracamy wybrany element, obslugujemy jak tablice r = i[0] c = i[1] return self.daneMac[r][c] def transponuj(self): # no wiadomo, obracamy se macierzatko m = Macierz(wymiar=(self.wymiar[1],self.wymiar[0])) for r in range(self.wymiar[0]): for c in range(self.wymiar[1]): m.daneMac[c][r] = self.daneMac[r][c] return m def __add__(self, q): #overloading operatora +. mozemy dodawac macierze i liczby skalarne (int i flaot) if isinstance(q, Macierz): #jesli dodajemy macierz do macierzy... if self.wymiar != q.wymiar: arg = ("p.wymiar != q.wymiar", self.wymiar, q.wymiar) raise IndexError, arg else: # dodajemy macierze m = Macierz(wymiar=self.wymiar) for r in range(self.wymiar[0]): m.daneMac[r] = map(lambda x, y: x + y, self.daneMac[r], q.daneMac[r]) return m elif isinstance(q, float) or isinstance(q, int): # dodajemy liczby calkowite i zmiennoprzecinkowe m = Macierz(wymiar=self.wymiar) for r in range(self.wymiar[0]): m.daneMac[r] = map(lambda x: x + q, self.daneMac[r]) return m else: arg = ("symbol nie jest macierza, typem calkowitym badz liczba zmiennoprzecinkowa--->", q) raise TypeError, arg def __sub__(self, q): #odejmwoanie dziala tak samo jak dodawanie, tylko odwrotnie ;) if isinstance(q, Macierz): if self.wymiar != q.wymiar: arg = ("p.wymiar != q.wymiar", self.wymiar, q.wymiar) raise IndexError, arg else: # odejmujemy macierze m = Macierz(wymiar=self.wymiar) for r in range(self.wymiar[0]): m.daneMac[r] = map(lambda x, y: x - y, self.daneMac[r], q.daneMac[r]) return m elif isinstance(q, float) or isinstance(q, int): # odejmujemy wartosci zmiennoprzecinkowe i calkowite m = Macierz(wymiar=self.wymiar) for r in range(self.wymiar[0]): m.daneMac[r] = map(lambda x: x - q, self.daneMac[r]) return m else: arg = ("symbol nie jest macierza, typem calkowitym badz liczba zmiennoprzecinkowa--->", q) raise TypeError, arg def __str__(self): # o starczy ze potem napiszemy print naszamacierz i juz # print the matrix daneMac s = "" for r in range(self.wymiar[0]): for c in range(self.wymiar[1]): s += "%f " % (self.daneMac[r][c]) s += "\n" return s def __mul__(self, q): #mnozenie, najtrudniejsza czesc programu, zdokumentowana dosc dokladnie if isinstance(q, Macierz): #jezeli mnozymi macierz przez maciez.. if self.wymiar[1] != q.wymiar[0]: #sprawdzamy czy wymiary macierzy sa odpowiednie arg = ("p.wymiar[1] != q.wymiar[0]", self.wymiar[1], q.wymiar[0]) #wyrzucamy wyjatek ze jest bee raise IndexError, arg else: #jesli wszystko jest ok to mnozymy m = Macierz(wymiar=(self.wymiar[0], q.wymiar[1])) #tworzymy maciez wynikowa for r in range(self.wymiar[0]): # wiersze pierwszej macierzy for c in range(q.wymiar[1]): # kolumny drugiej macierzy # wymnazamy teraz poszczegolne "sumy" wierszy i kolumn wierszWek = self.daneMac[r] kolWek = [q.daneMac[a][c] for a in xrange(q.wymiar[0])] m.daneMac[r][c] = sum(map(lambda x, y: x * y, wierszWek, kolWek)) return m #wynik elif isinstance(q, float) or isinstance(q, int): # jesli mnozymy przez liczbe int czy float # tworzymy macierz wynikowa m = Macierz(wymiar=self.wymiar) for r in range(self.wymiar[0]): # wiersze m.daneMac[r] = map(lambda x: x * q, self.daneMac[r]) #mnozenie return m #zwracamy wynikowa macierz else: arg = ("Wartosc jest niestosownego formatu: ", q) #jesli bedziemy chcieli mnozyc przez jakies smieci to wyrzucamy wyjatek raise TypeError, arg #PRZYKLADY#1.# jak tworzymy dane potrzebne do zainicjowania macierzy: # sprawa jest prosta. po prostu lista z listami odpowiadajaca budowie macierzy np:dane1 = [[1,2],[3,4],[5,6],[7,8],[9,10]]dane2 = [[11,12],[13,14],[15,6.12],[7.12,8.21],[9.12,10.21]]dane3 = [[1,2,3,4,5],[1,2,3,4,5]]#dane mozemy pociagnac rowniez z pliku, ale o tym pozniej#Tworzymy macierz!#Mozemy to zrobic z danych wczesniej stworzonych, np tak:mac1 = Macierz(dane1)mac2 = Macierz(dane2)mac3 = Macierz(dane3)#albo wykorzystac plik tekstowy (zalaczony test.mtx). i tu UWAGA: pola macierzy w pliku oddzielone sa od siebie bialymi znakami (np tabulatorem). Wiersze koncza sie znakiem nowej linii (ENTER) ale ostatni wiersz NIE MOZE sie nim konczyc (tzn nie stawiamy enter'a w ostatnim wierszu)m3 = Macierz("test.mtx")#mozemy wykonywac roznorakie operacje na macierzach w banalny sposob (dziekujemy tworcon pythona za overloading operatorow atymetycznych:m11 = mac1 + 10.05 #odejmowac tak tez mozemym12 = mac1 * 15.12 #mnozymy przez liczbem31 = mac1 * mac3 # albo przez inna macierz#albo tez mozemy przetransponowac macierz i uzyc jej w dalszych obliczeniach:m32 = mac3.transponuj()#mozemy wypisac dane pole macierzy:print "pole m3[1,3]: " , m3[1,3]# albo mozemy wypisac cala macierz:print mac3