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

init Karatsuba multiplication

parent 5b787e14
Branches
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -12,5 +12,23 @@ print_string "\n 1. big num avec simple variable\n\n"; ...@@ -12,5 +12,23 @@ 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, 0, P.Null);; let pm = P.NotNull(big_int_of_int 1, 1, P.Null);;
print_string (P.print pm); let p1 = P.NotNull(big_int_of_int 3, 2, pm);;
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));;
print_string "P2 = ";
print_string (P.print p2);
print_string "\n";
print_string "addition polynome:\np1 + p2 = ";
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 "\n";
(*Projet AP Edouard Paris 2016*) (*Projet AP Edouard Paris 2016*)
(*Invariant sur les polynomes
* on ne stock que les monômes dont le coefficient
* est non nul et un seul coefficient par degré
* *)
open Big_int;; open Big_int;;
module type Coefficient = module type Coefficient =
...@@ -10,6 +15,7 @@ module type Coefficient = ...@@ -10,6 +15,7 @@ module type Coefficient =
val equal: coeff -> coeff -> bool val equal: coeff -> coeff -> bool
val add: coeff -> coeff -> coeff val add: coeff -> coeff -> coeff
val mul: coeff -> coeff -> coeff val mul: coeff -> coeff -> coeff
val minus: coeff -> coeff
end end
;; ;;
...@@ -57,6 +63,7 @@ module Polynome (C : Coefficient) (D : Degree) = ...@@ -57,6 +63,7 @@ module Polynome (C : Coefficient) (D : Degree) =
else false else false
else false else false
) )
(*addition de deux polynomes*)
let rec add x y = match x with let rec add x y = match x with
|Null -> y |Null -> y
|NotNull (cx, dx, xx)-> |NotNull (cx, dx, xx)->
...@@ -74,24 +81,70 @@ module Polynome (C : Coefficient) (D : Degree) = ...@@ -74,24 +81,70 @@ module Polynome (C : Coefficient) (D : Degree) =
then add xx yy then add xx yy
else NotNull (m, dx, add xx yy) else NotNull (m, dx, add xx yy)
) )
(*private function for incrementing the degree of a polynome*) (*fonction privée pour incrémenter les degrees des monomes d'un polynome*)
let rec increment_degree d x = match x with let rec increment_degree d x = match x with
|Null -> Null |Null -> Null
|NotNull (cx, dx, xx)-> NotNull (cx, (D.add d dx), (increment_degree d xx)) |NotNull (cx, dx, xx)-> NotNull (cx, (D.add d dx), (increment_degree d xx))
(*private function in order to multiply all the coeffs of a pol*) (*fonction privée pour multiplier les coefficients d'un polynome*)
let rec multiply_coeffs c x = match x with let rec multiply_coeffs c x = match x with
|Null -> Null |Null -> Null
|NotNull (cx, dx, xx) -> |NotNull (cx, dx, xx) ->
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 of two polynomes*) (*Naive multiplication de deux polynomes*)
let rec naive_mul x y = match x with let rec naive_mul x y = match x with
|Null -> Null |Null -> Null
|NotNull (cx, dx, xx) -> |NotNull (cx, dx, xx) ->
(match y with (match y with
|Null -> Null |Null -> Null
|NotNull (_, _, _)-> |NotNull (_, _, _)->
add (increment_degree dx (multiply_coeffs cx y))(naive_mul xx y) 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)
(*fonction privée pour couper un polynome*)
let cut x n =
let rec acc_cut acc p i = match p, i with
|Null, _ -> acc, Null
|_, 0 -> acc, p
|NotNull (cp, dp, pp), j ->
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 dp acc) pp (j - 1)
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
(*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 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 ))
) )
end end
;; ;;
...@@ -20,5 +20,6 @@ module SimpleCoeff = ...@@ -20,5 +20,6 @@ module SimpleCoeff =
let equal c1 c2 = eq_big_int c1 c2 let equal c1 c2 = eq_big_int c1 c2
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
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