TIPE2021/Maths.ml

144 lines
3.5 KiB
OCaml

type vecteur = int;;
type matrice = int list;;
type polynome = int;;
(***************** AFFICHAGE *****************)
(* Zolie fonction d'affichage (h=nombre de lignes) *)
(* L'algorithme est moche, mais y a pas trop d'autre solution que de arrayiser la liste, c'est stoqué dans le mauvais sens *)
let nthOfBinarint i n = if ((0b1 lsl n) land i)=0 then "0" else "1";;
let print_matrice h (matl:matrice) :unit =
let mat = Array.of_list matl in
let l = Array.length mat in
print_string "";
for i=0 to (l-1) do
print_string (nthOfBinarint mat.(i) 0)
done;
print_endline "";
for j=1 to (h-2) do
print_string "";
for i=0 to (l-1) do
print_string (nthOfBinarint mat.(i) j)
done;
print_endline "";
done;
print_string "";
for i=0 to (l-1) do
print_string (nthOfBinarint mat.(i) (h-1))
done;
print_endline "";;
let print_vecteur h x = print_matrice h [x];;
let print_polynome pol =
let rec aux pol i preums = match pol with
| 0 -> print_endline ""
| pol when pol mod 2 = 0 -> aux (pol lsr 1) (i+1) preums
| _ -> begin
begin
match (preums,i) with
| true,0 -> print_string "1"
| true,_ -> (print_string "X^";print_int i)
| false,_ -> (print_string " + X^";print_int i)
end;aux (pol lsr 1) (i+1) false
end
in aux pol 0 true;;
(***************** MATRICES *****************)
(* Effectue le produit matriciel 'matrice' . 'vecteur' *)
let produit (matrice:matrice) (vecteur:vecteur) :vecteur =
let rec auxiliaire resultat_partiel masque = function
| [] -> resultat_partiel
| colonne :: reste ->
let resultat =
if masque mod 2 = 1
then (lxor) colonne resultat_partiel
else resultat_partiel
in auxiliaire resultat (masque lsr 1) reste
in auxiliaire 0 vecteur matrice
;;
(* Ne calcul papy *)
let deux_puissance = (lsl) 1;;
let orderize p q =
if (p<q)
then (p,q)
else (q,p);;
(* Construit la matrice identité de taille d.d *)
let identite d =
let rec sub acc = function
| p when p >= 0 -> sub ((deux_puissance p) :: acc) (p-1)
| _ -> acc
in sub [] (d-1)
;;
(* Change l'état du 'i'-eme bit *)
let changer_bit i = (lxor) (deux_puissance i);;
(* Décalage gauche avec entier relatif *)
let rec decagauche x = function
| n when n < 0 -> x lsr (-n)
| n when n > 0 -> x lsl n
| n -> x
;;
(* Vérifie que 'y' respecte toutes les contraintes de 'cs' *)
(* Est-ce que pour tout P dans cs, P(y) ? *)
let respecter y cs =
let ny = (lnot) y in
List.fold_right (fun c b -> b && (land) c ny > 0) cs true
;;
(* Sort une matrice binaire au hazard *)
let matriceAuPif l h =
let filtre = (deux_puissance (h+1))-1 in
let rec aux l h tmp = match l with
| 0 -> tmp
| l -> aux (l-1) h (((Random.bits ()) land filtre)::tmp)
in aux l h [];;
(***************** POLYNOMES *****************)
let polmul (p_in:polynome) (q_in:polynome) : polynome =
let (p,q) = orderize p_in q_in in
let rec sub pa qa somme =
if pa=0 then somme else
sub (pa lsr 1) (qa lsl 1) (if (pa mod 2=0) then somme else (somme lxor qa))
in sub p q 0 ;;
let degre (p:polynome) :int =
let rec aux p d =
match p with
| 0 -> -1
| 1 -> d
| _ -> aux (p lsr 1) (d+1)
in aux p 0;;
let poldiveuc (p:polynome) (q:polynome) : (polynome * polynome) =
let dq = degre q in
let rec sub quotient reste =
let dr = degre reste in
let d = dr - dq in
if d >= 0
then sub (quotient lxor (deux_puissance d)) (reste lxor (q lsl d))
else (quotient, reste)
in sub 0 p;;
let poldiv (p:polynome) (q:polynome) : polynome = fst (poldiveuc p q);;
let polrst (p:polynome) (q:polynome) : polynome = snd (poldiveuc p q);;