.. py:module:: matrius Matrius disperses ================= L'objectiu d'aquest exercici és definir la classe :py:class:`MatriuDispersa` que permeti representar una matriu de dimensions grans en la qual la majoria dels valors són nuls (zeros) sense utilitzar gaire memòria, emmagatzemant només els valors no nuls. Especificació de la classe :py:class:`~matrius.MatriuDispersa` -------------------------------------------------------------- .. py:class:: MatriuDispersa(nfiles, ncolumnes) Matriu dispersa de *nfiles* x *ncolumnes* elements. Atributs: .. py:attribute:: nfils Nombre de files de la matriu (enter). .. py:attribute:: ncols Nombre de columnes de la matriu (enter). Aquesta classe ha de suportar les operacions següents: +--------------------------+---------------------------------+ | Operació | Resultat | +==========================+=================================+ | ``m[f, c]`` | retorna el valor de la matriu | | | *m* a la fila *f* i columna *c* | +--------------------------+---------------------------------+ | ``m[f, c] = valor`` | assigna *valor* a l'element | | | de la fila *f* i columna *c* | | | de la matriu *m* | +--------------------------+---------------------------------+ | ``m2 = k * m1`` | la matriu resultant del producte| | | de l'escalar *k* per *m1* | | | (vegeu `[1]`_). | +--------------------------+---------------------------------+ | ``m3 = m1 + m2`` | la matriu resultant de la suma | | | de *m1* i *m2* | | | (vegeu `[2]`_). | +--------------------------+---------------------------------+ | ``m3 = m1 * m2`` | la matriu resultant del | | | producte de *m1* per *m2* | | | (vegeu `[3]`_). | +--------------------------+---------------------------------+ La classe suporta, a més, les funcions: :py:func:`len` i :py:class:`str`. Implementació de la classe :py:class:`~matrius.MatriuDispersa` -------------------------------------------------------------- Deseu la implementació de la classe :py:class:`~matrius.MatriuDispersa` al fitxer :file:`matrius.py` (mòdul :py:mod:`matrius`). Per implementar aquesta classe, haureu de dissenyar els mètodes que donen suport a les operacions i funcions esmentades a l'apartat anterior. Cal que tingueu en compte les següents observacions: #. Per representar els valors diferents de zero de la matriu caldrà un atribut addicional, per exemple: .. py:attribute:: matrius.MatriuDispersa.vals Diccionari que conté **únicament** les posicions amb els valors no nuls de la matriu. En aquest diccionari, la clau serà una tupla amb els índexs enters `(i,j)` de cada posició no nul·la i el valor associat serà el real no nul :math:`m_{i,j}` que hi ha a la posició :math:`(i,j)` de la matriu. Per exemple, el diccionari {(2, 2): 9.4, (2, 9): -0.4, (3, 1): -0.04, (4,5): 1.2} representa una matriu amb només quatre termes no nuls. Si es tracta d'una matriu de 5 files i 10 columnes, la matriu corresponent és aquesta: .. math:: \begin{pmatrix} 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 9.4 & 0 & 0 & 0 & 0 & 0 & 0 & -0.4 & 0 \\ -0.04 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1.2 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \end{pmatrix} #. Quan es crea una instància a la classe :py:class:`~matrius.MatriuDispersa`, aquesta representa una matriu amb tots els valors iguals a zero. Per exemple: .. code:: python >>> from matrius import MatriuDispersa >>> m = MatriuDispersa(3, 4) >>> m[1, 1] 0.0 #. El mètode *__init__* haurà d'inicialitzar els atributs :py:attr:`~matrius.MatriuDispersa.nfils` i :py:attr:`~matrius.MatriuDispersa.ncols` a partir dels paràmetres *nfiles* i *ncolumnes*. També haurà d'inicialitzar el diccionari *vals* tenint en compte el que s'ha explicat en el punts anteriors. #. La consulta i l'assignació a una posició de la matriu `m[f, c]` provoquen un error de tipus: :py:exc:`IndexError` si no es compleix que :math:`1 \le f \le` :py:attr:`~matrius.MatriuDispersa.nfils` i :math:`1 \le c \le` :py:attr:`~matrius.MatriuDispersa.ncols`. Per exemple: .. code-block:: pycon >>> m[0, 0] Traceback (most recent call last): File "", line 1, in File "/home/my_user/matrius.py", line 13, in __getitem__ raise IndexError IndexError #. Quan s'assigna un valor a una posició de la matriu `m[f, c] = c`, cal tenir en compte que en el diccionari :py:attr:`~matrius.MatriuDispersa.vals` hi ha **només** els valors **no nuls** de la matriu. #. La función :py:func:`len` aplicada a una matriu dispersa retorna el nombre de valors diferents de zero de la matriu, és a dir el nombre d'elements emmagatzemats en el diccionari :py:attr:`~matrius.MatriuDispersa.vals`. Per exemple: .. code:: python >>> m = MatriuDispersa(3, 4) >>> m[2, 3] = 23 >>> len(m) 1 #. La funció :py:class:`str` aplicada a una matriu dispersa retorna un string amb tots els valors de la matriu. Cada fila es representa en una línia de text i cada valor està separat per un únic espai en blanc. Els valors es mostren sempre amb un únic decimal. Per exemple: .. code:: python >>> m = MatriuDispersa(3, 4) >>> m[1, 1] = 23 >>> m[3, 4] = 67 >>> str(m) '23.0 0.0 0.0 0.0\n0.0 0.0 0.0 0.0\n0.0 0.0 0.0 67.0' La funció :py:func:`~matrius.identitat` --------------------------------------- Al fitxer :file:`matrius.py`, però fora de la classe :py:class:`~matrius.MatriuDispersa`, definiu-hi la funció següent: .. py:function:: identitat(n) Retorna la :py:class:`~matrius.MatriuDispersa` identitat de dimensió *n*. .. note:: Disposeu dels fitxers :download:`matrius-1.txt ` i :download:`matrius-2.txt ` amb jocs de prova. .. rubric:: Solució Disposeu d'una solució al fitxer :download:`matrius.py `. .. _[1]: https://ca.wikipedia.org/wiki/Multiplicaci%C3%B3_de_matrius#Multiplicaci.C3.B3_d.27una_matriu_per_un_escalar .. _[2]: https://ca.wikipedia.org/wiki/Suma_de_matrius .. _[3]: https://ca.wikipedia.org/wiki/Multiplicaci%C3%B3_de_matrius#Multiplicaci.C3.B3_d.27una_matriu_per_una_matriu