TP 2 : éléments de correction
In [1]:
import numpy as np
In [2]:
S = np.matrix([[1, 3, 2, 5], [7, 4, -1, 0], [3, 8, -1, 3], [1, -5, 4, 6]])
print(S)
[[ 1  3  2  5]
 [ 7  4 -1  0]
 [ 3  8 -1  3]
 [ 1 -5  4  6]]
In [3]:
S[2,1]
Out[3]:
8
In [4]:
S[2,1] = -2
print(S)
[[ 1  3  2  5]
 [ 7  4 -1  0]
 [ 3 -2 -1  3]
 [ 1 -5  4  6]]
In [5]:
S[:,2]
Out[5]:
matrix([[ 2],
        [-1],
        [-1],
        [ 4]])
In [6]:
S[1,:]
Out[6]:
matrix([[ 7,  4, -1,  0]])
In [7]:
S[1,:] = S[1,:] - 7 * S[0,]
print(S)
[[  1   3   2   5]
 [  0 -17 -15 -35]
 [  3  -2  -1   3]
 [  1  -5   4   6]]
In [8]:
S.shape
Out[8]:
(4, 4)
In [9]:
S.shape[0]
Out[9]:
4
In [10]:
S.shape[1]
Out[10]:
4
In [11]:
I = np.eye(4)
print(I)
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
In [12]:
A = np.matrix([[1, 3, 2, 5], [-1, -1, 1, 2], [2, 4, -1, 3], [3, 5, 4, 6]])
print(A)
[[ 1  3  2  5]
 [-1 -1  1  2]
 [ 2  4 -1  3]
 [ 3  5  4  6]]
In [13]:
def zeroColSousDiag(j, M, N) :
    "zerocolSousDiag(j : int, M : np.matrix, N : np.matrix) -> [G : np.matrix, D : np.matrix]"
    G = np.copy(M) # sinon Python modifie aussi la matrice initiale
    D = np.copy(N)
    n = M.shape[0]
    for i in range(j+1, n) :
        D[i,:] = G[j,j] * D[i,:] - G[i,j] * D[j,:]
        G[i,:] = G[j,j] * G[i,:] - G[i,j] * G[j,:]
    return [G, D]
In [14]:
[G, D] = zeroColSousDiag(0, A, I)
print([G, D])
[array([[ 1,  3,  2,  5],
       [ 0,  2,  3,  7],
       [ 0, -2, -5, -7],
       [ 0, -4, -2, -9]]), array([[ 1.,  0.,  0.,  0.],
       [ 1.,  1.,  0.,  0.],
       [-2.,  0.,  1.,  0.],
       [-3.,  0.,  0.,  1.]])]
In [15]:
zeroColSousDiag(1, G, D)
Out[15]:
[array([[ 1,  3,  2,  5],
        [ 0,  2,  3,  7],
        [ 0,  0, -4,  0],
        [ 0,  0,  8, 10]]),
 array([[ 1.,  0.,  0.,  0.],
        [ 1.,  1.,  0.,  0.],
        [-2.,  2.,  2.,  0.],
        [-2.,  4.,  0.,  2.]])]
In [16]:
def transfTriangSup(M, N) :
    "transfTriangSup(M : np.matrix, N : np.matrix) -> [G : np.matrix, D : np.matrix]"
    G = np.copy(M)
    D = np.copy(N)
    n = M.shape[0]
    for j in range(n) :
        [G, D] = zeroColSousDiag(j, G, D)
    return [G, D]
In [17]:
transfTriangSup(A, I)
Out[17]:
[array([[  1,   3,   2,   5],
        [  0,   2,   3,   7],
        [  0,   0,  -4,   0],
        [  0,   0,   0, -40]]),
 array([[  1.,   0.,   0.,   0.],
        [  1.,   1.,   0.,   0.],
        [ -2.,   2.,   2.,   0.],
        [ 24., -32., -16.,  -8.]])]
In [18]:
def zeroColSurDiag(j, T, P) :
    "zeroColSurDiag(j : int, T : np.matrix, P : np.matrix) -> [G : np.matrix, D : np.matrix]"
    G = np.copy(T)
    D = np.copy(P)
    for i in range(j) :
        D[i,:] = G[j,j] * D[i,:] - G[i,j] * D[j,:]
        G[i,:] = G[j,j] * G[i,:] - G[i,j] * G[j,:]
    return [G, D]
In [19]:
[T, P] = transfTriangSup(A, I)
[G, D] = zeroColSurDiag(3, T, P)
print([G, D])
[array([[ -40, -120,  -80,    0],
       [   0,  -80, -120,    0],
       [   0,    0,  160,    0],
       [   0,    0,    0,  -40]]), array([[-160.,  160.,   80.,   40.],
       [-208.,  184.,  112.,   56.],
       [  80.,  -80.,  -80.,    0.],
       [  24.,  -32.,  -16.,   -8.]])]
In [20]:
[G, D] = zeroColSurDiag(2, G, D)
print([G, D])
[array([[ -6400, -19200,      0,      0],
       [     0, -12800,      0,      0],
       [     0,      0,    160,      0],
       [     0,      0,      0,    -40]]), array([[-1.920e+04,  1.920e+04,  6.400e+03,  6.400e+03],
       [-2.368e+04,  1.984e+04,  8.320e+03,  8.960e+03],
       [ 8.000e+01, -8.000e+01, -8.000e+01,  0.000e+00],
       [ 2.400e+01, -3.200e+01, -1.600e+01, -8.000e+00]])]
In [21]:
def transfDiag(T, P) :
    "transfDiag(T : np.matrix, P : np.matrix) -> [G : np.matrix, D : np.matrix]"
    G = np.copy(T)
    D = np.copy(P)
    n = T.shape[0]
    for j in range(n) :
        [G, D] = zeroColSurDiag(j, G, D)
    return [G, D]
In [22]:
[Delta, R] = transfDiag(T, P)
print([Delta, R])
[array([[320,   0,   0,   0],
       [  0, 320,   0,   0],
       [  0,   0, 160,   0],
       [  0,   0,   0, -40]]), array([[-816.,  528.,  304.,  352.],
       [ 592., -496., -208., -224.],
       [  80.,  -80.,  -80.,    0.],
       [  24.,  -32.,  -16.,   -8.]])]
In [23]:
# Delta[0,:] = (1/2) * Delta[0,:]
# print(Delta)
In [24]:
def transfId(Delta, R) :
    "transfId(Delta : np.matrix, R : np.matrix) -> [G : np.matrix, D : np.matrix]"
    G = np.copy(Delta)
    D = np.copy(R)
    n = Delta.shape[0]
    for i in range(n) :
        D[i,:] = (1 / G[i,i]) * D[i,:]
        G[i,:] = (1 / G[i,i]) * G[i,:]
    return [G, D]
In [25]:
[L, U] = transfId(Delta, R)
print([L, U])
[array([[1, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 1, 0],
       [0, 0, 0, 1]]), array([[-2.55,  1.65,  0.95,  1.1 ],
       [ 1.85, -1.55, -0.65, -0.7 ],
       [ 0.5 , -0.5 , -0.5 ,  0.  ],
       [-0.6 ,  0.8 ,  0.4 ,  0.2 ]])]
In [26]:
np.dot(A, U)
Out[26]:
matrix([[ 1.00000000e+00,  0.00000000e+00,  0.00000000e+00,
          0.00000000e+00],
        [ 0.00000000e+00,  1.00000000e+00,  0.00000000e+00,
          0.00000000e+00],
        [-8.88178420e-16,  4.44089210e-16,  1.00000000e+00,
          0.00000000e+00],
        [-8.88178420e-16,  4.44089210e-16,  2.22044605e-16,
          1.00000000e+00]])
In [27]:
def calcInv(M) :
    "calcInv(M : np.matrix) -> Inv : np.matrix"
    G = np.copy(M)
    n = M.shape[0]
    D = np.eye(n)
    [G, D] = transfTriangSup(G, D)
    [G, D] = transfDiag(G, D)
    [G, D] = transfId(G, D)
    Inv = D
    return Inv
In [28]:
V = calcInv(A)
print(V)
[[-2.55  1.65  0.95  1.1 ]
 [ 1.85 -1.55 -0.65 -0.7 ]
 [ 0.5  -0.5  -0.5   0.  ]
 [-0.6   0.8   0.4   0.2 ]]
In [29]:
np.dot(A, V)
Out[29]:
matrix([[ 1.00000000e+00,  0.00000000e+00,  0.00000000e+00,
          0.00000000e+00],
        [ 0.00000000e+00,  1.00000000e+00,  0.00000000e+00,
          0.00000000e+00],
        [-8.88178420e-16,  4.44089210e-16,  1.00000000e+00,
          0.00000000e+00],
        [-8.88178420e-16,  4.44089210e-16,  2.22044605e-16,
          1.00000000e+00]])
In [30]:
J = np.ones([4,4])
print(J)
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]
In [31]:
calcInv(J)
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:7: RuntimeWarning: divide by zero encountered in scalar divide
  D[i,:] = (1 / G[i,i]) * D[i,:]
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:7: RuntimeWarning: invalid value encountered in multiply
  D[i,:] = (1 / G[i,i]) * D[i,:]
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:8: RuntimeWarning: divide by zero encountered in scalar divide
  G[i,:] = (1 / G[i,i]) * G[i,:]
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:8: RuntimeWarning: invalid value encountered in multiply
  G[i,:] = (1 / G[i,i]) * G[i,:]
Out[31]:
array([[nan, nan, nan, nan],
       [nan, nan, nan, nan],
       [nan, nan, nan, nan],
       [nan, nan, nan, nan]])
In [32]:
P = np.matrix([[0, 1], [1, 0]])
print(P)
[[0 1]
 [1 0]]
In [33]:
calcInv(P)
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:7: RuntimeWarning: divide by zero encountered in scalar divide
  D[i,:] = (1 / G[i,i]) * D[i,:]
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:7: RuntimeWarning: invalid value encountered in multiply
  D[i,:] = (1 / G[i,i]) * D[i,:]
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:8: RuntimeWarning: divide by zero encountered in scalar divide
  G[i,:] = (1 / G[i,i]) * G[i,:]
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:8: RuntimeWarning: invalid value encountered in multiply
  G[i,:] = (1 / G[i,i]) * G[i,:]
C:\Users\roxan\AppData\Local\Temp\ipykernel_22272\1601645827.py:8: RuntimeWarning: invalid value encountered in cast
  G[i,:] = (1 / G[i,i]) * G[i,:]
Out[33]:
array([[nan, nan],
       [ 1., -0.]])
In [34]:
def trouvePivot(j, M) :
    "trouvePivot(j : int, M : np.matrix) -> p : int"
    n = M.shape[0]
    for p in range(j, n) :
        if M[p, j] != 0 :
            return p
    return n

## Autre version
# def trouvePivot(j, M) :
#     n = M.shape[0]
#     p = j
#     while M[p,j] == 0 and p < (n-1) :
#         p = p + 1
#     if M[p, j] == 0 and p == (n-1) :
#         p = n
#     return p
In [35]:
trouvePivot(0, P)
Out[35]:
1
In [36]:
def echangeLignes(M, N, i1, i2) :
    G = np.copy(M)
    D = np.copy(N)
    auxG = np.copy(M)
    auxD = np.copy(N)
    G[i1,:] = auxG[i2,:]
    G[i2,:] = auxG[i1,:]
    D[i1,:] = auxD[i2,:]
    D[i2,:] = auxD[i1,:]
    return [G, D]
In [37]:
[B, C] = echangeLignes(U, J, 1, 3)
print([B, C])
[array([[-2.55,  1.65,  0.95,  1.1 ],
       [-0.6 ,  0.8 ,  0.4 ,  0.2 ],
       [ 0.5 , -0.5 , -0.5 ,  0.  ],
       [ 1.85, -1.55, -0.65, -0.7 ]]), array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])]
In [38]:
def transfTriangSup(M, N) :
    "transfTriangSup(M : np.matrix, N : np.matrix) -> [G : np.matrix, D : np.matrix, boolInv : bool]"
    G = np.copy(M)
    D = np.copy(N)
    n = M.shape[0]
    boolInv = True
    j = 0
    p = trouvePivot(j, G)
    while j < (n-1) and p < n :
        [G, D] = echangeLignes(G, D, j, p)
        [G, D] = zeroColSousDiag(j, G, D)
        j = j + 1
        p = trouvePivot(j, G)
    if p == n :
        boolInv = False
    return [G, D, boolInv]
In [39]:
def calcInv(M) :
    "calcInv(M : np.matrix) -> Inv : np.matrix ou str"
    G = np.copy(M)
    n = M.shape[0]
    D = np.eye(n)
    [G, D, boolInv] = transfTriangSup(G, D)
    if boolInv == True :
        [G, D] = transfDiag(G, D)
        [G, D] = transfId(G, D)
        Inv = D
    else :
        Inv = 'La matrice n est pas inversible'
    return Inv
In [ ]: