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
Branches
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";
module P = Polynome(SimpleCoeff)(SimpleDegree);;
(*base monomiale pour la construction du polynôme*)
let pm = P.NotNull(big_int_of_int 1, 1, P.Null);;
let p1 = P.NotNull(big_int_of_int 3, 2, pm);;
let p1 = P.generate 4;;
print_string "P1 = ";
print_string (P.print p1);
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 (P.print p2);
......@@ -30,5 +29,25 @@ print_string (P.print(P.add p1 p2));;
print_string "\n";
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";
......@@ -16,6 +16,7 @@ module type Coefficient =
val add: coeff -> coeff -> coeff
val mul: coeff -> coeff -> coeff
val minus: coeff -> coeff
val generate: int -> coeff
end
;;
......@@ -25,9 +26,12 @@ module type Degree =
val print: degree -> string
val add: degree -> degree -> degree
val subtract: degree -> degree -> degree
val div: degree -> int -> degree
val equal: degree -> degree -> bool
val is_bigger: degree -> degree -> bool
val is_null: degree -> bool
val increment: degree -> degree
val unit: degree
end
;;
......@@ -37,7 +41,9 @@ module type Polynomes =
val print: polynome -> string
val equal: polynome -> polynome -> bool
val add: polynome -> polynome -> polynome
val cut_2: polynome -> polynome*polynome
val naive_mul: polynome -> polynome -> polynome
val generate: int -> polynome
end
;;
......@@ -94,62 +100,62 @@ module Polynome (C : Coefficient) (D : Degree) =
if C.is_null c then Null
else NotNull ((C.mul c cx), dx, (multiply_coeffs c xx))
(*Naive multiplication de deux polynomes*)
let rec naive_mul x y = match x with
|Null -> Null
|NotNull (cx, dx, xx) ->
(match y with
|Null -> Null
|NotNull (_, _, _)->
let rec naive_mul x y = match x, y with
|Null, _ -> Null
|_, Null -> Null
|NotNull (cx, dx, xx), _ ->
let xxy = naive_mul xx y in
add xxy (increment_degree dx (multiply_coeffs cx y))
)
(*fonction privée de soustraction de deux polynomes pour karatsuba*)
let rec subtract x y =
let rec minus p = match p with
|Null -> Null
|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*)
(*polynome -> degree -> degree *)
let cut x n =
let rec acc_cut acc p i = match p, i with
|Null, _ -> acc, Null
|NotNull (cp, dp, pp), j ->
if D.is_null j then acc, p else
if D.is_bigger dp j then
let rec acc_cut acc p i = match p with
|Null -> acc, Null
|NotNull (cp, dp, pp) ->
if D.is_null i then acc, p else
if D.is_bigger dp i then
let rec insert cc dd pp = (match pp with
|Null -> NotNull (cc, dd, Null)
|NotNull (ccp, ddp, ppp) ->
NotNull (ccp, ddp, (insert cc dd ppp))
) 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
in acc_cut Null x n
(*fonction privée pour connaitre la longeur du polynome *)
let length x =
let rec acc_length p l = match p with
|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
let cut_2 x = match x with
|Null-> Null, Null
|NotNull (cx, dx, xx) -> cut x (D.div dx 2)
(*multiplication de Karatsuba offman *)
let rec karatsuba_mul x y = match x with
|Null -> Null
|NotNull (cx, dx, xx) ->
(match y with
|Null -> Null
|NotNull (_, dy, _) ->
let n = (1 + max x y)/2 in
let rec karatsuba_mul x y = match x, y with
|Null,_ -> Null
|_,Null -> Null
|NotNull (cx, dx, xx), NotNull (_, dy, _) ->
if D.is_null (D.div dx 2) || D.is_null (D.div dy 2) then
naive_mul x y
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 y1, y2 = cut y n in
let xy1 = karatsuba_mul x1 y1 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
;;
(* projet AP 2016 edouard Paris *)
open Big_int;;
open Random;;
Random.self_init ();
module SimpleDegree =
struct
......@@ -8,9 +11,12 @@ module SimpleDegree =
let print d = (string_of_int d)
let add d1 d2 = d1 + d2
let subtract d1 d2 = d1 - d2
let div d i = d/i
let equal d1 d2 = (d1 == d2)
let is_bigger d1 d2 = (d1 > d2)
let is_null d = (d == 0)
let unit = 1
let increment d = d+1
end
;;
......@@ -23,5 +29,6 @@ module SimpleCoeff =
let is_null c = eq_big_int c zero_big_int
let mul c1 c2 = mult_big_int c1 c2
let minus c = minus_big_int c
let generate i = big_int_of_int (Random.int (100+i))
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