en Curso Python, Programación, Python

Producto de matrices con Python

Producto de matrices con Python

Hola, y bienvenido a esta 4ta entrada en la serie de operaciones en matrices con Python. En esta ocasión, como podrán leer en el título, se trata sobre como podemos calcular el producto de matrices con python.

Una vez más aprovecho para invitarte a que me sigas en mis redes Twitter o en la Fanpage de Facebook, donde podrás estar informado de nuevas entradas del blog, o si tienes alguna duda o comentario puedes decirmelo sin problema.

Operaciones en matrices con python

Hasta el momento las entradas de esta serie han sido las siguientes:

Creando la clase Base

Suma de matrices

Producto por un escalar

Producto de matrices

Transpuesta (Pendiente)

Como en las entradas anteriores, para realizar el ejemplo utilizaremos la clase base que creamos en la primera entrada de esta serie, así que si aún no la tienes, lee la primera entrada y vuelves 😀

Un poco de teoría

El producto de matrices encuentra su origen en el papel que desempeñan las matrices como funciones lineales. Según la forma en que se define este producto, se puede decir que proviene de la composición de funciones lineales.

Si f y g son aplicaciones lineales tal que f: A -> B y g: B -> C (A, B son los dominios respectivos de f, g y B, C son los imágenes que corresponden a estos dominios) entonces la composición de f y g denotada por el operador o, cumple que f o g: A -> C. Los dominios pueden verse como los posibles valores de entrada de la función y pudiera hallarse representado por un conjunto de con las posibles salidas ofrecidas por esta función y también pudiera ser el conjunto de números reales. Por esta razón el producto de la matriz A(m,n) con la matriz B(n,p) sería una matriz C(m,p) lo cual representa una restricción. Dicho de otra forma, solo es posible multiplicar matrices cuando la cantidad de columnas de la primera es igual a la cantidad de filas de la segunda. En la siguiente imagen podemos observar un ejemplo:

Producto de matrices con pythonLa imagen anterior muestra el resultado de realizar el producto de las matrices A y B, operación que se lleva a cabo entre filas de A y columnas de B, lo que justifica que se requiera que esas cantidades sean iguales. Para calcular una celda de C, sea C(i,j), se toman los valores de la fila i de A y se multiplica cada uno con su correspondiente valor en la columna j de B, luego se suman los valores obtenidos y el resultado es C(i,j). De manera general C(i,j) = A(i, 1) * B(1,j) + A(i,2) * B(2,j) + + A(i,m) * B(m,j).

Código: producto de matrices con python

La implementación de la función con la que llevaremos a cabo esta operación, será una función generadora como las que hemos realizado en anteriores entradas de esta serie:

def product(self, m):
    """ Recibe una matriz como argumento """
    if self.rows is not m.cols:
        raise Exception('Number of rows'
                        'and number of columns'
                        "don't match")
    for i in range(self.rows):
        row = []
        for j in range(m.cols):
            add = 0
            for c in range(self.cols):
                add += self.get_value_of_position(i, c) * \
                       m.get_value_of_position(c, j)
            row.append(add)
        yield row

El código es sencillo, primero se hace una comparación para verificar si el número de filas de la matriz A es diferente al número de columnas de la matriz pasada como argumento B, en caso de que esto se cumpla lanzamos una excepción, caso contrario utilizando bucles recorremos las matrices, multiplicando y sumando los valores tal y como se explico anteriormente y añadiendolos a la nueva matriz C.

Si deseamos verificar el comportamiento de nuestra nueva función podemos realizarlo con el siguiente código:

ma = Matrix(2,3)
# First row
ma.define_elem(0,0,1)
ma.define_elem(0,1,2)
ma.define_elem(0,2,3)
# Second row
ma.define_elem(1,0,7)
ma.define_elem(1,1,8)
ma.define_elem(1,2,9)

mb = Matrix(3,2)
# First col
mb.define_elem(0,0,1)
mb.define_elem(1,0,7)
mb.define_elem(2,0,13)
# Second col
mb.define_elem(0,1,2)
mb.define_elem(1,1,8)
mb.define_elem(2,1,14)

for e in ma.product(mb):
    print(e)

Teniendo la siguiente salida:


[54, 60]
[180, 204]

Que como verás corresponden a los valores de las matrices representadas en la imagen anterior. Hasta este punto nuestra clase debe encontrarse de la siguiente forma (Recuerda que también se encuentra todo el código en el repositorio de Github):

#!/usr/bin/python
# -*- coding: utf-8 -*-
# author: Gabriel Cueto <TheMushr00m - @Mushr00m_Dev>


class Matrix:
    _n = 0
    _m = 0
    _elems = None

    def __init__(self, n, m):
        """Inicializa la matriz con valor 0 en cada posición"""
        self._n = n
        self._m = m
        self._elems = []
        for i in range(self._n):
            self._elems.append([])
            for j in range(self._m):
                self._elems[i].append(0)

    def define_elem(self, i, j, v):
        """ Sobreescribe el valor de una celda """
        self._elems[i][j] = v

    def show_matrix(self):
        """ Imprime los valores almacenados en la matriz """
        for i in range(self._n):
            for j in range(self._m):
                # Imprime de una forma elegante la matriz
                print("| {0} ".format(self.get_value_of_position(i, j)), sep=',', end='')
            print('|\n')

    def get_cols(self):
        """ Devuelve el número de columnas en la matriz """
        return self._m

    def get_rows(self):
        """ Devuelve el número de filas en la matriz """
        return self._n

    def get_value_of_position(self, i, j):
        """ Devuelve el valor en la fila(i), columna(j) de la matriz """
        return self._elems[i][j]

    def add(self, *matrix):
        """ Puede recibir varias matrices como argumentos """
        for i in range(self.rows):
            row = []
            for j in range(self.cols):
                tmp = self.get_value_of_position(i, j)
                for m in matrix:
                    tmp += m.get_value_of_position(i, j)
                row.append(tmp)
            yield row

    def scalar_product(self, x):
        """ x: Número real """
        for i in range(self.rows):
            row = []
            for j in range(self.cols):
                row.append(self.get_value_of_position(i, j)*x)
            yield row

    def product(self, m):
        """ Recibe una matriz como argumento """
        if self.rows is not m.cols:
            raise Exception('Number of rows'
                            'and number of columns'
                            "don't match")
        for i in range(self.rows):
            row = []
            for j in range(m.cols):
                add = 0
                for c in range(self.cols):
                    add += self.get_value_of_position(i, c) * \
                           m.get_value_of_position(c, j)
                row.append(add)
            yield row

    cols = property(fget=get_cols)
    rows = property(fget=get_rows)

Y bien, es todo por esta ocasión, espero la explicación haya sido clara y cualquier comentario no dudes en dejarlo aquí abajo, o con confianza mencionalo por Twitter o en la Fanpage de Facebook, y aprovecho a invitarte para que me sigas en las redes y compartas el contenido del blog, con lo cual me harías un gran favor.

Saludos.

Deja un comentario