Skip to content
Extraits de code Groupes Projets
Valider 909f31e6 rédigé par EdouardParis's avatar EdouardParis
Parcourir les fichiers

generate random polynome

parent d8f46721
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -12,14 +12,13 @@ print_string "\n 1. big num avec simple variable\n\n"; ...@@ -12,14 +12,13 @@ print_string "\n 1. big num avec simple variable\n\n";
module P = Polynome(SimpleCoeff)(SimpleDegree);; module P = Polynome(SimpleCoeff)(SimpleDegree);;
(*base monomiale pour la construction du polynôme*) (*base monomiale pour la construction du polynôme*)
let pm = P.NotNull(big_int_of_int 1, 1, P.Null);; let p1 = P.generate 4;;
let p1 = P.NotNull(big_int_of_int 3, 2, pm);;
print_string "P1 = "; print_string "P1 = ";
print_string (P.print p1); print_string (P.print p1);
print_string "\n";; print_string "\n";;
let p2 = P.NotNull(big_int_of_int 5, 2, P.NotNull(big_int_of_int 1, 1, P.Null));; let p2 = P.generate 5;;
print_string "P2 = "; print_string "P2 = ";
print_string (P.print p2); print_string (P.print p2);
...@@ -30,5 +29,25 @@ print_string (P.print(P.add p1 p2));; ...@@ -30,5 +29,25 @@ print_string (P.print(P.add p1 p2));;
print_string "\n"; print_string "\n";
print_string "naive multiplication:\np1 x p2 = "; print_string "naive multiplication:\np1 x p2 = ";
print_string (P.print(P.naive_mul p1 p2));; print_string (P.print(P.naive_mul p2 p1));;
print_string "\n";
print_string "decoupe p1 en 2 = \n";
let first (pp1, pp2) = pp1 in
print_string (P.print(first (P.cut_2 p1)));;
print_string "\n";
let second (pp1, pp2) = pp2 in
print_string (P.print(second (P.cut_2 p1)));;
print_string "\n";
print_string "decoupe p2 en 2 = \n";
let first (pp1, pp2) = pp1 in
print_string (P.print(first (P.cut_2 p2)));;
print_string "\n";
let second (pp1, pp2) = pp2 in
print_string (P.print(second (P.cut_2 p2)));;
print_string "\n";
print_string "karatsuba multiplication:\np1 x p2 = ";
print_string (P.print(P.karatsuba_mul p1 p2));;
print_string "\n"; print_string "\n";
...@@ -16,6 +16,7 @@ module type Coefficient = ...@@ -16,6 +16,7 @@ module type Coefficient =
val add: coeff -> coeff -> coeff val add: coeff -> coeff -> coeff
val mul: coeff -> coeff -> coeff val mul: coeff -> coeff -> coeff
val minus: coeff -> coeff val minus: coeff -> coeff
val generate: int -> coeff
end end
;; ;;
...@@ -25,9 +26,12 @@ module type Degree = ...@@ -25,9 +26,12 @@ module type Degree =
val print: degree -> string val print: degree -> string
val add: degree -> degree -> degree val add: degree -> degree -> degree
val subtract: degree -> degree -> degree val subtract: degree -> degree -> degree
val div: degree -> int -> degree
val equal: degree -> degree -> bool val equal: degree -> degree -> bool
val is_bigger: degree -> degree -> bool val is_bigger: degree -> degree -> bool
val is_null: degree -> bool val is_null: degree -> bool
val increment: degree -> degree
val unit: degree
end end
;; ;;
...@@ -37,7 +41,9 @@ module type Polynomes = ...@@ -37,7 +41,9 @@ module type Polynomes =
val print: polynome -> string val print: polynome -> string
val equal: polynome -> polynome -> bool val equal: polynome -> polynome -> bool
val add: polynome -> polynome -> polynome val add: polynome -> polynome -> polynome
val cut_2: polynome -> polynome*polynome
val naive_mul: polynome -> polynome -> polynome val naive_mul: polynome -> polynome -> polynome
val generate: int -> polynome
end end
;; ;;
...@@ -94,62 +100,62 @@ module Polynome (C : Coefficient) (D : Degree) = ...@@ -94,62 +100,62 @@ module Polynome (C : Coefficient) (D : Degree) =
if C.is_null c then Null if C.is_null c then Null
else NotNull ((C.mul c cx), dx, (multiply_coeffs c xx)) else NotNull ((C.mul c cx), dx, (multiply_coeffs c xx))
(*Naive multiplication de deux polynomes*) (*Naive multiplication de deux polynomes*)
let rec naive_mul x y = match x with let rec naive_mul x y = match x, y with
|Null -> Null |Null, _ -> Null
|NotNull (cx, dx, xx) -> |_, Null -> Null
(match y with |NotNull (cx, dx, xx), _ ->
|Null -> Null
|NotNull (_, _, _)->
let xxy = naive_mul xx y in let xxy = naive_mul xx y in
add xxy (increment_degree dx (multiply_coeffs cx y)) add xxy (increment_degree dx (multiply_coeffs cx y))
)
(*fonction privée de soustraction de deux polynomes pour karatsuba*) (*fonction privée de soustraction de deux polynomes pour karatsuba*)
let rec subtract x y = let rec subtract x y =
let rec minus p = match p with let rec minus p = match p with
|Null -> Null |Null -> Null
|NotNull (cp, dp, pp) -> NotNull (C.minus cp, dp, minus pp) |NotNull (cp, dp, pp) -> NotNull (C.minus cp, dp, minus pp)
in x add (minus y) in add x (minus y)
(*fonction privée pour couper un polynome selon un degree*) (*fonction privée pour couper un polynome selon un degree*)
(*polynome -> degree -> degree *) (*polynome -> degree -> degree *)
let cut x n = let cut x n =
let rec acc_cut acc p i = match p, i with let rec acc_cut acc p i = match p with
|Null, _ -> acc, Null |Null -> acc, Null
|NotNull (cp, dp, pp), j -> |NotNull (cp, dp, pp) ->
if D.is_null j then acc, p else if D.is_null i then acc, p else
if D.is_bigger dp j then if D.is_bigger dp i then
let rec insert cc dd pp = (match pp with let rec insert cc dd pp = (match pp with
|Null -> NotNull (cc, dd, Null) |Null -> NotNull (cc, dd, Null)
|NotNull (ccp, ddp, ppp) -> |NotNull (ccp, ddp, ppp) ->
NotNull (ccp, ddp, (insert cc dd ppp)) NotNull (ccp, ddp, (insert cc dd ppp))
) in ) in
acc_cut (insert cp (D.subtract dp j) acc) pp j let new_acc = insert cp (D.subtract dp i) acc in
acc_cut new_acc pp i
else acc, p else acc, p
in acc_cut Null x n in acc_cut Null x n
(*fonction privée pour connaitre la longeur du polynome *) let cut_2 x = match x with
let length x = |Null-> Null, Null
let rec acc_length p l = match p with |NotNull (cx, dx, xx) -> cut x (D.div dx 2)
|Null -> l
|NotNull (_, _, pp) -> acc_length pp (l+1)
in acc_length x 0
(*fonction privée renvoyant la longeur la plus grande de deux polynomes*)
let max x y =
let ly = length y in
let lx = length x in
if lx > ly then lx else ly
(*multiplication de Karatsuba offman *) (*multiplication de Karatsuba offman *)
let rec karatsuba_mul x y = match x with let rec karatsuba_mul x y = match x, y with
|Null -> Null |Null,_ -> Null
|NotNull (cx, dx, xx) -> |_,Null -> Null
(match y with |NotNull (cx, dx, xx), NotNull (_, dy, _) ->
|Null -> Null if D.is_null (D.div dx 2) || D.is_null (D.div dy 2) then
|NotNull (_, dy, _) -> naive_mul x y
let n = (1 + max x y)/2 in else
let degree_max = if D.is_bigger dx dy then dx else dy in
let n = D.div degree_max 2 in
let x1, x2 = cut x n in let x1, x2 = cut x n in
let y1, y2 = cut y n in let y1, y2 = cut y n in
let xy1 = karatsuba_mul x1 y1 in let xy1 = karatsuba_mul x1 y1 in
let xy2 = karatsuba_mul x2 y2 in let xy2 = karatsuba_mul x2 y2 in
let xy3 = subtract (karatsuba_mul(add )) let xy3 = subtract (karatsuba_mul (add x1 y1) (add x2 y2)) (add xy1 xy2) in
) add (add (increment_degree degree_max xy1) (increment_degree n xy3)) xy2
(*generate polynome from another polynome*)
let generate n =
let rec gen acc count =
if count == 0 then acc else
let add_monome x c = match x with
|Null -> NotNull(C.generate c, D.unit, x)
|NotNull(_,dx,_) -> NotNull(C.generate c, D.increment dx, x) in
gen (add_monome acc (count - 1)) (count-1) in
gen Null n
end end
;; ;;
(* projet AP 2016 edouard Paris *) (* projet AP 2016 edouard Paris *)
open Big_int;; open Big_int;;
open Random;;
Random.self_init ();
module SimpleDegree = module SimpleDegree =
struct struct
...@@ -8,9 +11,12 @@ module SimpleDegree = ...@@ -8,9 +11,12 @@ module SimpleDegree =
let print d = (string_of_int d) let print d = (string_of_int d)
let add d1 d2 = d1 + d2 let add d1 d2 = d1 + d2
let subtract d1 d2 = d1 - d2 let subtract d1 d2 = d1 - d2
let div d i = d/i
let equal d1 d2 = (d1 == d2) let equal d1 d2 = (d1 == d2)
let is_bigger d1 d2 = (d1 > d2) let is_bigger d1 d2 = (d1 > d2)
let is_null d = (d == 0) let is_null d = (d == 0)
let unit = 1
let increment d = d+1
end end
;; ;;
...@@ -23,5 +29,6 @@ module SimpleCoeff = ...@@ -23,5 +29,6 @@ module SimpleCoeff =
let is_null c = eq_big_int c zero_big_int let is_null c = eq_big_int c zero_big_int
let mul c1 c2 = mult_big_int c1 c2 let mul c1 c2 = mult_big_int c1 c2
let minus c = minus_big_int c let minus c = minus_big_int c
let generate i = big_int_of_int (Random.int (100+i))
end end
;; ;;
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter