Écrire produit matrices(a, b)
Exercice de TD · niveau 3 (difficile) · NSI (première), chapitre 4 — Les types construits · Matrices, et le piège de la référence partagée
Énoncé
Écrire produit_matrices(a, b). Quelle précondition relie les dimensions de a et de b ? Combien de multiplications le calcul effectue-t-il ?
Corrigé
def produit_matrices(a, b):
"""Produit matriciel a x b.
Precondition : a et b sont non vides, a lignes de meme longueur, et
len(a[0]) == len(b) : autant de colonnes a a que de
lignes a b.
Postcondition : le resultat a len(a) lignes et len(b[0]) colonnes.
"""
assert len(a) > 0 and len(b) > 0
assert all(len(l) == len(a[0]) for l in a)
assert all(len(l) == len(b[0]) for l in b)
assert len(a[0]) == len(b), "dimensions incompatibles"
n, p, q = len(a), len(a[0]), len(b[0])
c = [[0] * q for _ in range(n)] # jamais [[0]*q]*n !
for i in range(n):
for j in range(q):
s = 0
for k in range(p):
s = s + a[i][k] * b[k][j]
c[i][j] = s
assert len(c) == n and len(c[0]) == q
return c
La précondition qui relie les dimensions. Si est de taille et de taille , le produit n'a de sens que si : le coefficient est la somme des , et il faut que parcoure le même ensemble d'indices des deux côtés. La ligne assert len(a[0]) == len(b) l'exprime exactement. Sans elle, Python lèverait un IndexError au milieu de trois boucles imbriquées — message inutilisable ; avec elle, l'erreur est signalée à l'entrée, avec sa cause.
Le nombre de multiplications. La boucle la plus interne s'exécute une fois par triplet , soit fois, et fait exactement une multiplication. Pour deux matrices carrées de taille , cela fait multiplications : passer de à multiplie le travail par mille, pas par dix.
Vérification.
A = [[1, 2, 3], [4, 5, 6]]
B = [[7, 8], [9, 10], [11, 12]]
assert produit_matrices(A, B) == [[58, 64], [139, 154]]
I3 = [[1 if i == j else 0 for j in range(3)] for i in range(3)]
assert produit_matrices(A, I3) == A # neutre a droite
for _ in range(200): # 200 produits aleatoires
n, p, q = random.randint(1, 4), random.randint(1, 4), random.randint(1, 4)
a = [[random.randint(-5, 5) for _ in range(p)] for _ in range(n)]
b = [[random.randint(-5, 5) for _ in range(q)] for _ in range(p)]
c = produit_matrices(a, b)
for i in range(n):
for j in range(q):
assert c[i][j] == sum(a[i][k] * b[k][j] for k in range(p))
Contrôle à la main du premier coefficient : . Et produit_matrices(B, B) est bien refusé par la précondition : est , on ne peut pas la multiplier par elle-même.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.