linealge.py

Created by mino-1289

Created on March 12, 2022

10 KB


"""
Un module d'algèbre linéaire en cours de création.
"""
from math import atan
from random import randint
from mathsup import factor


class Matrice:
    """
    Représente une Matrice dans Python, avec une représentation en rectangle.
    """

    def __init__(self, M: list[list[float]]) -> None:
        self.value = M
        if not self.is_squared():
            self.is_identity = False
        else:
            self.is_identity = True
            for i in range(len(self)):
                for j in range(len(self[0])):
                    if i == j and self[i][j] != 1:
                        self.is_identity = False
                    if i != j and self[i][j] != 0:
                        self.is_identity = False
        return None

    def __repr__(self):
        return str(self)

    def __len__(self) -> int:
        return len(self.value)

    def __getitem__(self, i) -> list[float]:
        return self.value[i]

    def __iter__(self):
        return iter(self.value)

    def __eq__(self, M) -> bool:
        if len(self.value) == len(M) and len(self.value[0]) == len(M[0]):
            for i in range(len(M)):
                for j in range(len(M[i])):
                    if self.value[i][j] != M[i][j]:
                        return False
            return True
        return False

    def __ne__(self, M) -> bool:
        if len(self.value) == len(M) and len(self.value[0]) == len(M[0]):
            for i in range(len(M)):
                for j in range(len(M[i])):
                    if self.value[i][j] != M[i][j]:
                        return True
            return False
        return True

    def __str__(self) -> str:
        if self.value == []:
            return ""
        num_of_rows = len(self)
        num_of_cols = len(self[0])
        tp = ""
        for i in range(num_of_rows):
            row_to_print = ""
            for j in range(num_of_cols):
                row_to_print += str(self.value[i][j]) + " "
            tp += row_to_print + "\n"
        return tp

    def __add__(self, M: Matrice) -> Matrice:
        if M == []:
            return self.value
        if len(self.value) != len(M) or len(self.value[0]) != len(M[0]):
            return self.value
        num_rows = len(self.value)
        num_cols = len(self.value[0])
        for i in range(num_rows):
            for j in range(num_cols):
                self.value[i][j] += M[i][j]
        return self

    def __sub__(self, M: Matrice) -> Matrice:
        if M == []:
            return self.value
        if len(self.value) != len(M) or len(self.value[0]) != len(M[0]):
            return self.value
        num_rows = len(self.value)
        num_cols = len(self.value[0])
        for i in range(num_rows):
            for j in range(num_cols):
                self.value[i][j] -= M[i][j]
        return self

    def __mul__(self, M) -> Matrice:
        if isinstance(M, Matrice):
            if M.is_identity:
                return self
            m = []
            if len(self.value[0]) != len(M):
                return m
            for i in range(len(self.value)):
                ligne = []
                for j in range(len(M[0])):
                    element = 0
                    for k in range(len(self.value[0])):
                        element += self.value[i][k] * M[k][j]
                    ligne.append(element)
                m.append(ligne)
            return Matrice(m)
        if isinstance(M, float) or isinstance(M, int):
            n, m = len(self), len(self[0])
            A = zeros(n, m)
            for i in range(n):
                for j in range(m):
                    A[i][j] = self.value[i][j] * M
            return Matrice(A)
        return self

    def __pow__(self, n: int) -> Matrice:
        if not self.is_squared():
            return Matrice([[0]])
        if self.is_identity:
            return self
        if self.is_diagonal():
            for i in range(len(self)):
                self[i][i] = self[i][i]**n
            return self
        if n == 0:
            return self.identity(len(self))
        if n == 1:
            return self
        if n < 0:
            MI = self.inverse()
            L = factor(abs(n))
            for i in range(len(L)):
                ME = MI
                for _ in range(L[i]-1):
                    MI *= ME
            return MI
        M = self
        L = factor(n)
        for i in range(len(L)):
            ME = M
            for _ in range(L[i]-1):
                M *= ME
        return M

    def __neg__(self) -> Matrice:
        return self*(-1)

    def __pos__(self) -> Matrice:
        return self

    def __abs__(self) -> Matrice:
        x, y = len(self.value), len(self.value[0])
        for i in range(x):
            for j in range(y):
                self.value[i][j] = abs(self.value[i][j])
        return self

    def __round__(self, n: int = 0) -> Matrice:
        x, y = len(self.value), len(self.value[0])
        for i in range(x):
            for j in range(y):
                self.value[i][j] = round(self.value[i][j], n)
        return self

    def identity(self, n: int) -> Matrice:
        """
        Renvoie la matrice identité d'ordre n.
        """
        M = []
        for i in range(n):
            L = []
            for j in range(n):
                L.append(1) if i == j else L.append(0)
            M.append(L)
        return Matrice(M)

    def is_squared(self) -> bool:
        """
        Renvoie un booléen, si la matrice est carrée.
        """
        if len(self) != 0:
            return len(self.value) == len(self.value[0])
        return False

    def is_triangular_down(self) -> bool:
        """
        Renvoie un booléen, si la matrice est triangulaire superieur.
        """
        if not self.is_squared():
            return False
        if self.is_identity:
            return True

        for i in range(len(self)):
            for j in range(len(self[0])):
                if i < j and self[i][j] != 0:
                    return False
        return True

    def is_triangular_up(self) -> bool:
        """
        Renvoie un booléen, si la matrice est triangulaire inférieure.
        """
        if not self.is_squared():
            return False
        if self.is_identity:
            return True

        for i in range(len(self)):
            for j in range(len(self[0])):
                if i > j and self[i][j] != 0:
                    return False
        return True

    def is_triangular(self) -> bool:
        """
        Renvoie un booléen, si la matrice est triangulaire.
        """
        return self.is_triangular_up() or self.is_triangular_down()

    def is_diagonal(self) -> bool:
        """
        Renvoie un booléen, si la matrice est diagonale.
        """
        if not self.is_squared():
            return False
        if self.is_identity:
            return True

        for i in range(len(self)):
            for j in range(len(self[0])):
                if i != j and self[i][j] != 0:
                    return False
        return True

    def diag(self, cdiag: list) -> Matrice:
        """
        Renvoie la matrice diagonale.
        """
        n = len(cdiag)
        M = zeros(n, n)
        for i in range(n):
            M[i][i] = cdiag[i]
        return M

    def determinant(self) -> float:
        """
        Renvoie le déterminant de la matrice.
        """
        n = len(self)
        if n == 0:
            return 1
        s = 0
        for j in range(n):
            s += self[0][j] * self.cofacteur(0, j)
        return s

    def cofacteur(self, i: int, j: int) -> int:
        """
        Renvoie le cofacteur de la matrice en i, j.
        """
        m = self.mineur(i, j)
        if (i + j) % 2 == 0:
            return m
        return -m

    def supprimer_ligne_colone(self, i: int, j: int) -> Matrice:
        """
        Renvoie la matrice de taille n-1 ou la ligne i et la colonne j ont été supprimé.
        """
        n = len(self)
        rg = range(n-1)
        B = [[None for _ in rg] for _ in rg]
        for p in rg:
            for q in rg:
                B[p][q] = self[phi(p, i)][phi(q, j)]
        return Matrice(B)

    def mineur(self, i: int, j: int) -> int:
        """
        Renvoie le mineur de la matrice en i j.
        """
        A1 = self.supprimer_ligne_colone(i, j)
        return A1.determinant()

    def comatrice(self) -> Matrice:
        """
        Renvoie la comatrice de la matrice 
        """
        if not self.is_squared():
            return None
        n = len(self.value)
        B = [[None for _ in range(n)] for _ in range(n)]
        for i in range(n):
            for j in range(n):
                B[i][j] = self.cofacteur(i, j)
        return Matrice(B)

    def transposee(self) -> Matrice:
        """
        Renvoie la transposée de la matrice.
        """
        m, n = len(self.value), len(self.value[0])
        B = [[None for _ in range(m)] for _ in range(n)]
        for i in range(n):
            for j in range(m):
                B[i][j] = self.value[j][i]
        return Matrice(B)

    def inverse(self) -> Matrice:
        """
        Renvoie l'inverse de la matrice.
        """
        if not self.is_squared():
            return None
        if self.determinant() == 0:
            return None
        M = self.comatrice().transposee()*(1/self.determinant())
        return Matrice(M)

    def trace(self) -> float:
        """
        Renvoie la trace de la matrice.
        """
        if not self.is_squared():
            return None
        return sum([self.value[i][j] for i in range(len(self.value)) for j in range(len(self.value[i])) if i == j])


def phi(p: int, i: int) -> int:
    if p < i:
        return p
    return p+1


def random_matrix(n: int, m: int, borne=9) -> Matrice:
    return Matrice([[randint(-borne, borne) for _ in range(n)] for _ in range(m)])


def newmatrice(M: list[list]) -> Matrice:
    return Matrice(M)


def eye(n: int) -> Matrice:
    return Matrice([[]]).identity(n)


def diag(coefs: list) -> Matrice:
    return Matrice([[]]).diag(coefs)


def zeros(n: int, m: int) -> Matrice:
    return Matrice([[0 for _ in range(n)] for _ in range(m)])

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.