Proposition de correction pour l'exercice 1, partie 3

In [63]:
# Question 2 and 3
%pylab inline

def getA(alpha, c, n):
    assert alpha>0.
    A = c/alpha*np.eye(n)
    i, j = np.indices(A.shape)
    A[i==j+1] = -c
    A[i==j-1] = -c
    return A

def resolutionIterative(A, b, x0, omega, eps, nIterMax):
    D = diag(diag(A))
    if abs(det(D))<1.e-14:
        print("Erreur: Matrice D non inversible.")
        exit(-1)
    else:
        # Préparation des matrices
        Dinv = diag(1./diag(A))
        # Remarque: L'inversion de D est très facile dans le cas présent
        # car D diagonale. Il suffit de prendre l'inverse de coefs
        # diagonaux comme ci-dessus. Si D n'avait pas été diagonale,
        # il aurait fallu résoudre un système linéaire à chaque itération
        # avec la commande solve. Il n'aurait surtout pas fallu calculer 
        # l'inverse avec la commande inv(D) car elle est plus coûteuse
        # et beaucoup moins robuste face aux erreurs d'arrondi
        J = dot(Dinv, D - A)
        J_omega = (1.-omega)*eye(A.shape[0]) + omega*J
        b_omega = omega*dot(Dinv,b)
        # Itérations
        res = norm(dot(A,x0)-b)
        x = x0
        nIter = 0
        while res>eps and nIter<nIterMax:
            nIter+=1
            x = dot(J_omega, x) + b_omega
            res = norm(dot(A,x)-b)
            print(res)
        return [x, nIter, res]    
        
alpha = 0.1
c = 1.
n = 10
A = getA(alpha, c, n)

omega = 0.5
eps = 1.e-6
x0 = np.zeros(n)
b = np.ones(n)
nIterMax = 100
[x, nIter, res] = resolutionIterative(A, b, x0, omega, eps, nIterMax)
print('residu = ', res)
print('nIter = ', nIter)
print('x = ', x)
Populating the interactive namespace from numpy and matplotlib
1.86681547026
1.10420220069
0.654042286477
0.387807572793
0.230129929794
0.136647420455
0.081179696939
0.0482471081872
0.028684211208
0.0170584270683
0.0101470799246
0.00603718360675
0.00359258268483
0.00213819935879
0.0012727708268
0.00075771460977
0.000451136955702
0.00026862915288
0.000159968792249
9.52688105429e-05
5.67408750603e-05
3.37962096517e-05
2.01309314356e-05
1.19917119576e-05
7.14361033038e-06
4.25570598749e-06
2.53536806687e-06
1.51051272296e-06
8.99954028929e-07
('residu = ', 8.9995402892920251e-07)
('nIter = ', 29)
('x = ', array([ 0.11237242,  0.12372433,  0.1248711 ,  0.12498693,  0.12499851,
        0.12499851,  0.12498693,  0.1248711 ,  0.12372433,  0.11237242]))
In [ ]: