Classe Mat et Lena
Il s'agit de compléter le CODE ci-dessous à partir de la lecture du chapitre 2 de ce POLY.
On utilisera cette IMAGE.
Python
#!/usr/bin/python3 #-*- coding: utf-8 -*- #from functools import reduce from operator import mul, floordiv, truediv,add from random import randint, random from math import log,ceil #from fractions import Fraction import numpy as np from scipy import misc, linalg from matplotlib import cm from pylab import imshow #from sympy import randMatrix from math import floor, sqrt import matplotlib.pyplot as plt from urllib.request import urlretrieve #from subprocess import call class Mat: """ une matrice sous la forme Mat([nb lignes, nb cols], fonction(i,j))""" def __init__(self, dim, f): self.F = f # fonction (i,j) -> coeff en position i,j self.D = dim # liste [nb de lignes, nb de cols] def ligne(self,i): return None # à compléter def col(self,j): return None # à compléter def indices(self): [r,c] = self.D for i in range(r): for j in range(c): yield (i,j) def __getitem__(self,cle): """ permet d'obtenir Mij avec M[i,j]""" return self.F(*cle) def __iter__(self): """ pour itérer sur la liste des coefficients """ [r,c] = self.D for j in range(c): for i in range(r): yield self.F(i,j) def __str__(self): """ joli affichage d'une matrice""" [r,c],f = self.D, self.F lmax = len(str(max(iter(self)))) + 1 s = '\n'.join( (' '.join('{0:{l}G}'.format(f(i,j),l=lmax) if isinstance(f(i,j), int) or isinstance(f(i,j), float) else str(f(i,j)) for j in range(c))) for i in range(r)) return s def __repr__(self): """ représentation dans le REPL""" return str(self) def __neg__(self): """ opposé d'une matrice : utilisation du symbole -""" return None # à compléter def __add__(self,other): """ somme de deux matrices : utilisation du symbole +""" assert self.D == other.D, "tailles incompatibles" return Mat(self.D, lambda i,j : self.F(i,j) + other.F(i,j)) def __sub__(self,other): """ différence de deux matrices : utilisation dyu symbole -""" return None # à compléter def transpose(self): """ transposée d'une matrice """ return None # à compléter def prod_par_scal(self,k): """ renvoie le produit d'une matrice par un scalaire""" return None # à compléter def prod_mat(self,other): """ renvoie le produit de deux matrices""" return None # à compléter def map(self,f): return Mat(self.D, lambda i,j: f(self.F(i,j))) def __mul__(self,other): """ produit d'une matrice par un scalaire ou une matrice : utilisation du symbole *""" if Mat == type(other): return self.prod_mat(other) else: return self.prod_par_scal(other) def powr(self,n): """ expo rapide : version récursive""" r = self.D[0] if n == 0: return unite(r) def pui(m,k,acc): if k == 0: return acc return pui((m*m),k//2,acc if k % 2 == 0 else (m*acc)) return pui(self,n,unite(r)) def __pow__(self,n): """expo rapide version impérative""" return None # à compléter def __eq__(self,other): """test d'égalité de deux matrices""" if (self.D != other.D): return False f,g = self.F, other.F for (i,j) in self.indices(): if f(i,j) != g(i,j): return False return True def trace(self): return None # à compléter def comb_lignes(self,ki,kj,i,j): """Li <- ki*Li + kj * Lj""" f = self.F g = lambda r,c : ki*f(i,c) + kj*f(j,c) if r == i else f(r,c) return Mat(self.D,g) def mult_ligne(self,k,i): """Li <- k*Li""" return None # à compléter def cat_carre_droite(self): """ Colle l'identité à droite pour la méthode de GJ """ return None # à compléter def extrait_carre_droite(self): """ Extrait le carré de droite d'un tableau de GJ """ return None # à compléter def swap(self,i,j): """ Li <-> Lj """ return None # à compléter def decoupe(self): """ Fonction interne à triangle qui retire la 1ère ligne et la 1ère colonne """ [lig, col], f = self.D, self.F return Mat([lig-1,col-1],lambda r,c : f(r+1,c+1)) def decoupe_bas(self): """ Fonction interne à diago_triangle qui retire la dernière ligne et la colonne de même numéro de S """ [lig, col], f = self.D, self.F #g = lambda r,c: f(lig-1,c) if r == lig else f(i,c) if r == lig-1 else f(r,c) g = lambda r,c: f(r,c) if c < lig - 1 else f(r,c+1) return Mat([lig-1,col-1],lambda r,c : g(r,c)) def remplace_ligned(self,i,g): """ Fonction interne à triangle qui remplace dans la ligne i les coefficients à partir de la colonne i par ceux du tableau S """ [lig, col], f = self.D, self.F h = lambda r,c: g(r-i,c-i) if r == i and c >= i else f(r,c) return Mat([lig,col],h) def remplace_ligneg(self,i,g): """ Fonction interne à diago_triangle qui remplace dans la ligne i les coefficients à partir de la colonne i par ceux du tableau S """ [lig, col], f = self.D, self.F h = lambda r,c: g(r,c - (lig - 1) + i) if r == i and c >= i else f(r,c) return Mat([lig,col],h) def triangle(self): """ renvoie la triangulation d'une matrice de haut en bas """ [r,c] = self.D m = min(r,c) S = self T = zeros(r,c) while m > 0: NoLigne = 0 while S[NoLigne, 0] == 0 and (NoLigne < m - 1): NoLigne += 1 S = S.swap(NoLigne,0) if S[0, 0] != 0: pivot = S[0,0] for k in range(1,m): if S[k,0] != 0: S = S.comb_lignes(pivot, -S[k,0],k,0) #print("pivot = "+str(pivot)) #print("S dans for :") #print(S) T = T.remplace_ligned(r - m,S.F) #print("Évolution de T :") #print(T) S = S.decoupe() m -= 1 return T def diago_triangle(self,inv): """ renvoie la triangulation d'un tableau de GJ d'une matrice inversible de bas en haut """ return None # à compléter def rang(self): return None # à compléter def det(self,div): """ renvoie le déterminant de self par Gauss-Jordan """ return None # à compléter def inverse(self,inv): return self.cat_carre_droite().triangle().diago_triangle(inv).extrait_carre_droite() # In [340]: A = list2mat([[0,1,0,0],[2,-1,9,1],[2,7,4,-12],[2,0,-1,-1]]) def next_pow_2(x): return 2**(ceil(log(x)/log(2))) def all(it): for i in it: if not i: return False return True def randmat(r,c,min = 0,max = 9): return Mat([r,c],lambda i,j : randint(min,max)) def list2mat(mat): r,c = len(mat),len(mat[0]) return Mat([r,c], lambda i,j : mat[i][j]) def prod_scal(it1,it2): return None # à compléter def unite(n): return Mat([n,n], lambda i,j: 1 if i == j else 0) def zeros(r,c): return None # à compléter ############### # # Lena # #################" def rvb_to_gray(m): r = len(m) c = len(m[0]) return(np.array([[m[i,j][0] for j in range(c)] for i in range(r)])) def array2mat(tab): """ convertit un array de numpy en objet de type Mat""" dim = list(tab.shape) return Mat(dim, lambda i,j : tab[i,j]) def mat2array(mat): """ convertir un objet de type Mat en array de numpy """ return np.fromfunction(np.vectorize(mat.F),tuple(mat.D),dtype = int) urlretrieve('http://download.tuxfamily.org/tehessinmath/les_images/lenaFace.jpeg','lenaFace.jpeg') lena_face_couleur = plt.imread('./lenaFace.jpeg') lena_face_array = rvb_to_gray(lena_face_couleur) lena_face = array2mat(lena_face_array) matlena = array2mat(misc.lena()) def montre(mat): """ permet de visualiser les images dans un terminal """ return imshow(mat2array(mat), cmap = cm.gray) def retourne(m): [r,c], f = m.D, m.F return None # à compléter def miroir(m): [r,c], f = m.D, m.F return None # à compléter def resolution(k,mat): [r,c],f = mat.D,mat.F return None # à compléter def ber(p): return 1 if random() < p else 0 def rand_image(dim,p): return Mat(dim, lambda i,j : randint(0,255)*ber(p)) def bruit(mat,p): return (mat + rand_image(mat.D,p)).map(lambda x : x % 256) def moyenne(mat,k): return None # à compléter def mediane(mat,k): return None # à compléter def contour(m): return None # à compléter def comp_svd(mat,k): return None # à compléter def c_svd(mat,k): return None # à compléter # U,s,tV = linalg.svd(mat) # x = np.arange(len(s)) # plot(x,s) def anim(im,n): for k in range(n): plt.imsave("lena_face_svd" + str(1000 + k), c_svd(lena_face_array,k), cmap = cm.gray) # call("apngasm anim_lena_face.png lena_face_svd*.png 1 1 && firefox anim lenaface_svd.png")
Chiffrement de Hill
Python
####################################### # # Chiffrement de Hill # ####################################### def ascii(chaine): return [ord(c)-ord((' ')) for c in chaine] def deascii(chaine): return ''.join(chr(x + ord((' '))) for x in chaine) def to_Hill(m,p): """transforme une chaîne de caractères en une matrice de code ascii de p colonnes""" return None # à compléter cle = list2mat([[1,23,29],[0,31,1],[47,3,1]]) def bezout(a,b): """ retourne des coeffs de Bézout et le pgcd de a et b """ return None # à compléter def inv_mod(p,n): """ retourne l'inverse de p modulo n""" inv_cle = cle.inverse(lambda x: inv_mod(x, 95)).map(lambda n : n % 95) clair = to_Hill("Arghh !! Ce 1000 pattes aurait 314 pattes ??",3) crypte = deascii(iter((cle * clair).map(lambda n : n % 95))) decrypte = deascii(???)
Code correcteur d'erreur
À partir de la classe Mat, créez les fonctions nécessaires pour automatiser la méthode de correction de code présentée dans ce DOCUMENT