Soit la matrice symétrique
A = np.array([[10, 7, 8, 7], [7, 5, 6, 5], [8, 6, 10, 9], [7, 5, 9, 10]])
array([[10, 7, 8, 7],
[ 7, 5, 6, 5],
[ 8, 6, 10, 9],
[ 7, 5, 9, 10]])
lin.det(A) # calcul son determinant
0.9999999999999869 # on peut arrondir a 1
Construisons
b = A.sum(axis=1)
[32 23 33 31]
x = lin.solve(A, b)
array([1., 1., 1., 1.])
Perturbons
bp = [32.1, 22.9, 33.1, 30.9]
eb = lin.norm(b - bp) / lin.norm(b)
# une erreur se mesure par rapport à la valeur de la donnée
0.0033319453118976702
On a une erreur de l'ordre de
On note l'erreur :
Regardons la solution
xp = lin.solve(A, bp)
array([ 9.2, -12.6, 4.5, -1.1])
La solution n'a rien n'a voir avec
ex = lin.norm(x - xp) / lin.norm(x) #mesure de l'erreur
8.19847546803699
L'erreur est de l'ordre de 8.
ex / eb
2460.567236431514
C'est
Comme
donc :
lin.norm(lin.inv(A)) * lin.norm(A)
3009.5787080586942
On appelle cela le conditionnement de
Une matrice mal conditionnée va générer des erreurs de calcul lors de la résolution du système matriciel.
np.linalg.cond(A) # scipy n'a pas le conditionnement mais numpy l'a.
2984.0927016757555 # different de 3009
np.random.seed(0)
dA = 2 * np.random.random(size = A.shape) - 1
array([[ 0.098, 0.43 , 0.206, 0.09 ],
[-0.153, 0.292, -0.125, 0.784],
[ 0.927, -0.233, 0.583, 0.058],
[ 0.136, 0.851, -0.858, -0.826]])
ea = lin.norm(dA) / lin.norm(A) # erreur relative sur A
0.06868857112100454
Ap = A + dA
array([[10.098, 7.43 , 8.206, 7.09 ],
[ 6.847, 5.292, 5.875, 5.784],
[ 8.927, 5.767, 10.583, 9.058],
[ 7.136, 5.851, 8.142, 9.174]])
xp = lin.solve(Ap, b)
array([-12.365, 15.574, 10.146, -5.94 ])
ex = lin.norm(xp - x) / lin.norm(x)
11.432687335993894
ex / ea # valeur de l'erreur
166.44235204505293
L'erreur est moins grande.
Une erreur peut fortement perturber
Pour retrouver le conditionnement de
Donc
et
vp = lin.eigvals(A)
vp.max() / vp.min()
Le conditionnement peut etre tranformé :
On résoud