Producto de matrices en C: ejercicio resuelto

Producto de matrices en C: ejercicio resuelto

Si buscas producto de matrices en C ejercicio resuelto, aquí tienes la multiplicación de dos matrices con el orden de bucles ikj (más eficiente en caché que el orden ijk clásico) y la verificación del resultado elemento a elemento.

La multiplicación de matrices A (m×k) por B (k×n) produce C (m×n) donde C[i][j] = Σ A[i][p] * B[p][j] para p = 0..k-1. La complejidad es O(m·k·n).

Enunciado

Multiplica la matriz A (3×2) por la matriz B (2×4) y muestra el resultado C (3×4).

1
2
3
A = | 1  2 |    B = | 5  6  7  8 |
    | 3  4 |        | 9 10 11 12 |
    | 5  6 |

Solución en C

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>

#define M 3  /* filas de A */
#define K 2  /* cols de A = filas de B */
#define N 4  /* cols de B */

void multiplicar(const int A[M][K], const int B[K][N], int C[M][N]) {
    /* Inicializar C a cero */
    for (int i = 0; i < M; i++)
        for (int j = 0; j < N; j++)
            C[i][j] = 0;

    /* Orden ikj: mejor localidad de caché que ijk */
    for (int i = 0; i < M; i++)
        for (int p = 0; p < K; p++)
            for (int j = 0; j < N; j++)
                C[i][j] += A[i][p] * B[p][j];
}

void imprimir_matriz(const char *nombre, const int mat[], int filas, int cols) {
    printf("%s:\n", nombre);
    for (int i = 0; i < filas; i++) {
        printf("  |");
        for (int j = 0; j < cols; j++)
            printf(" %3d", mat[i * cols + j]);
        printf(" |\n");
    }
}

int main(void) {
    int A[M][K] = {{1, 2}, {3, 4}, {5, 6}};
    int B[K][N] = {{5, 6, 7, 8}, {9, 10, 11, 12}};
    int C[M][N];

    multiplicar(A, B, C);

    imprimir_matriz("A", (int *)A, M, K);
    imprimir_matriz("B", (int *)B, K, N);
    imprimir_matriz("C = A x B", (int *)C, M, N);

    return 0;
}

Resultado esperado

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
A:
  |   1   2 |
  |   3   4 |
  |   5   6 |
B:
  |   5   6   7   8 |
  |   9  10  11  12 |
C = A x B:
  |  23  26  29  32 |
  |  51  58  65  72 |
  |  79  90 101 112 |

Errores frecuentes

  • No inicializar C a cero antes de acumular: los valores residuales de la pila producen resultados incorrectos.
  • Usar el orden de bucles ijk sin pensar en caché: en el orden ijk el acceso a B[p][j] salta por columnas, lo que causa muchos cache misses. El orden ikj mantiene B[p][j] en la misma fila y es más eficiente.
  • Confundir las dimensiones: A[m×k] × B[k×n] = C[m×n]. El número de columnas de A debe ser igual al número de filas de B.
  • Usar int para matrices grandes: el producto de dos matrices 100×100 con valores de 1000 puede producir entradas de hasta 10^8, dentro del rango de int, pero con valores mayores conviene usar long long.

Aplicación práctica

La multiplicación de matrices es el núcleo de álgebra lineal numérica, redes neuronales (propagación hacia adelante), gráficos 3D (transformaciones) y computación científica. Bibliotecas como BLAS implementan versiones altamente optimizadas con SIMD y multihilo.

Siguiente ejercicio recomendado

Práctica guiada y libro completo

Si quieres una ruta completa con progresión real de dificultad:

FAQ

¿Por qué el orden de bucles ikj es más eficiente que ijk?

Por la localidad de caché. En el orden ijk, el bucle interno accede a B[p][j] con p variando, lo que salta filas en la memoria (matrices en C son row-major). En el orden ikj, el bucle interno accede a B[p][j] con j variando, recorriendo una fila de forma secuencial y aprovechando las líneas de caché cargadas.

¿Cómo verificar el resultado de la multiplicación?

Calculando manualmente los primeros elementos: C[0][0] = A[0][0]*B[0][0] + A[0][1]*B[1][0] = 1*5 + 2*9 = 23. Comprueba también C[2][3] = 5*8 + 6*12 = 40 + 72 = 112.

¿Qué es la multiplicación de matrices de Strassen?

Es un algoritmo que multiplica matrices n×n en O(n^2.807) en lugar de O(n³), dividiendo cada matriz en cuatro submatrices y usando 7 multiplicaciones recursivas en lugar de 8. En la práctica se usa solo para matrices muy grandes (n > 1000) porque la constante oculta es mayor que en el algoritmo estándar.