How to create a program that multiplies matrices?

0

I try to make a program that multiplies two matrices given by the user. What I have managed to do is this:

def CrearMatrizA (m, n):
    return [[0.0 for j in range (n)] for i in range (m)]
def CrearMatrizB (m, n):
    return [[0.0 for k in range (n)] for p in range (m)]
def CrearMatrizC (m, n):
    return [[0.0 for x in range (n)] for y in range (m)]



def EntrarDatos (matriz):
    m = len(matriz)
    n = len(matriz[0])
    for i in range(m):
        for j in range (n):
            matriz [i] [j] = float(input( "m["+ str(i) + "][" + str(j) + "]?"))
    return

def EntrarDatosC (matriz):
    m = len(A)
    n = len (B[0])
    for x in range (m):
        for y in range (n):
            matriz [x][y] = MultiplicarMatriz (A, B, C)
    return

def MostrarMatriz(matriz):
    m = len(matriz)
    n = len(matriz[0])
    for i in range (m):
        for j in range (n):
            print (matriz [i][j])
        print
    return


def MultiplicarMatriz(A, B, C):
    m1 = len(A)
    n1 = len(A[0])
    m2 = len(B)
    n1 = len(B[0])
    x = 0
    y = 0
    for p in range (m2):
        for i in range (m1):
            for j in range (n1): 
                for k in range (m2):
                    l = A[i][j] * B[k][p]
                    C[x][y] = C[x][y] + l
                    j = j + 1
                    k = k + 1
        i = i + 1
        x = x + 1
        j = 1
        k = 1
    p = p + 1
    y = y + 1
    x = 1
    i = 1
    return 


def main():
    m1 = int(input("Digite la cantidad de filas de la primera matriz: "))
    n1 = int(input("Digite la cantidad de columnas de la primera matriz: "))
    m2 = int(input("Digite la cantidad de filas de la segunda matriz: "))
    n2 = int(input("Digite la cantidad de columnas de la segunda matriz: "))

    if((m1, m2, n1, n2 > 0) and (m1 == n2)):
        '''hay un problema cuando todos son cero'''
        A = CrearMatrizA(m1, n1)
        EntrarDatos(A)
        B = CrearMatrizB(m2, n2)
        EntrarDatos (B)
        C = CrearMatrizC(m1, n2)
        C = MultiplicarMatriz(A, B, C)

        MostrarMatriz(A)
        MostrarMatriz(B)
        MostrarMatriz (C)   
    else:
       print("Las matrices no son multiplicables")    
    return

I have a million errors since I am new to this, but the main thing is the following:

  • how to make the program MultiplyMatrices recognize each of the subscripts that I want to use?
  • what is the data that will return me MultiplyMatrices?
  • how to create the product matrix?
  • is it necessary to create a function to create each of the matrices that will be used in the program?

I know it's a lot and probably my code does not make much sense, but I would appreciate any help.

    
asked by ABC 10.04.2017 в 02:26
source

1 answer

2

I think you're rolling something in between index ... XD. Let's see if we can clarify some things:

  • When defining the function to create the matrices, it is not necessary (in fact it does not make sense) to use a function for each matrix, with a coarse.

  • You can even create the matrix according to the user enter the data, you do not have to initialize it first with values that you will then modify. That is, the input can perfectly go within the list compression statement that you use to initialize the array.

  • The line if(m1, m2, n1, n2 > 0) does not do what you think. You want to check that none of the numbers is 0, but in reality you are only checking the value of m1 , if m1 is not 0 (False) is evaluated as True regardless of whether the others are 0 or not. The line should be:

    if m1>0 and m2>0 and n1>0 and n2>0 and m1 == n2

    Another option is to use the pre-built all function that returns True if all the conditions are met and False otherwise:

    if all((m1>0,m2>1,n1>1,n2>1, m1 == n2))

  • In Python it is not necessary that the functions return something compulsorily, if you do not need it you do not have to use the return at the end of each of them. On the other hand, class functions and methods are usually named starting with lowercase, reserving names that start with a capital letter to name classes. It's just a convention, not an error in itself.

  • The matrix that is responsible for multiplying does not have to receive the output matrix already built, you can have it created within the function and return the resulting matrix with the most encapsulated code, although your form is also valid.

  • The fattest mess I think you have it in the own function that multiplies the matrices. Think what is done when multiplying a matrix, we need to go through each row of the first matrix as many times as there are columns in the second. That's two for nested. To be able to save the data in the output matrix we need to add the result of multiplying the elements obtained with the previous indexes for which we need another for nested more:

    def multiplicarMatriz(A, B):
        filasA = len(A)
        columnasA = len(A[0])
        columnasB = len(B[0])
    
        C=[[0 for j in range(columnasB)] for i in range(filasA)]
    
        for i in range(filasA):
            for j in range(columnasB):
                for k in range(columnasA):
                    C[i][j] += A[i][k] * B[k][j]
        return C
    

    This can actually be greatly reduced by using list compression and enumerate :

    def multiplicarMatriz(A, B):
        return [[sum(x * B[i][col] for i,x in enumerate(fila)) for col in range(len(B[0]))] for fila in A]
    

    Or you can use zip :

    def multiplicarMatriz(A, B):
        return [[sum(a*b for a,b in zip(filA,colB)) for colB in zip(*B)] for filA in A] 
    

The code might look something like this:

def crearMatriz(filas, columnas):
   return [[float(input("m[{}][{}]?: ".format(i, j))) for j in range(columnas)] for i in range(filas)]

def mostrarMatriz(matriz):
    for fila in matriz:
        for n in fila:
            print("{:10.2f} ".format(n), end='') 
        print()
    print()

def multiplicarMatriz(A, B):
    return [[sum(x * B[i][col] for i,x in enumerate(fila)) for col in range(len(B[0]))] for fila in A]


def main():
    filasA = int(input("Digite la cantidad de filas de la primera matriz: "))
    columnasA= int(input("Digite la cantidad de columnas de la primera matriz: "))
    filasB = int(input("Digite la cantidad de filas de la segunda matriz: "))
    columnasB = int(input("Digite la cantidad de columnas de la segunda matriz: "))

    if all((filasA>0,columnasA>1,filasB>1,columnasB>1, columnasA == filasB)):
        A = crearMatriz(filasA, columnasA)
        B = crearMatriz(filasB, columnasB)
        C = multiplicarMatriz(A, B)

        print('\nMatriz A:')
        mostrarMatriz(A)
        print('Matriz B:')
        mostrarMatriz(B)
        print('Matriz AxB:')
        mostrarMatriz(C)     
    else:
       print("Las matrices no son multiplicables")    

if __name__ == '__main__':
    main()

The function in charge of showing the matrix I have modified it a bit so that instead of printing the numbers one after the other I printed them in a format something more similar to an array and aligned with the possibility of showing 7 whole digits and two decimals for each data. It's a basic output, it can be improved. On the other hand, instead of using m and n to name the variables I have tried to use some more descriptive ones such as columnaB , filaA , etc to make it easier to follow the logic.

The ammunition multiplicarMatriz is the one you use list comprehensions and enumerate , you can exchange it for any of the other two versions without modifying anything else. It's just a code showing a bit of the ideas I've tried to explain, I do not know if something has escaped me ...

Example of output:

    
answered by 10.04.2017 в 05:39