diff --git a/main.ml b/main.ml index d90c16df634e07a627ce27e7c7f20022da829553..ed97747e2ea8bae4faa6362541b8e75b30577731 100644 --- a/main.ml +++ b/main.ml @@ -28,26 +28,16 @@ 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 p2 p1));; +print_string "naive multiplication:\np1 x p2 = ";; +let naive = P.naive_mul p2 p1;; +print_string (P.print(naive));; 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 "karatsuba multiplication:\np1 x p2 = ";; +let karatsuba = (P.karatsuba_mul p1 p2);; +print_string (P.print(karatsuba));; print_string "\n"; -print_string "karatsuba multiplication:\np1 x p2 = "; -print_string (P.print(P.karatsuba_mul p1 p2));; +print_string "diff\n naive_mul - karatsuba = ";; +print_string (P.print(P.sub naive karatsuba));; print_string "\n"; diff --git a/polynome.ml b/polynome.ml index 7360ba4a65988785bf93d87b6b0c56dd0e6c16b0..fea7a65916279ed44c6844bc53fe939634075db9 100644 --- a/polynome.ml +++ b/polynome.ml @@ -14,6 +14,7 @@ module type Coefficient = val is_null: coeff -> bool val equal: coeff -> coeff -> bool val add: coeff -> coeff -> coeff + val sub: coeff -> coeff -> coeff val mul: coeff -> coeff -> coeff val minus: coeff -> coeff val generate: int -> coeff @@ -25,7 +26,7 @@ module type Degree = type degree val print: degree -> string val add: degree -> degree -> degree - val subtract: degree -> degree -> degree + val sub: degree -> degree -> degree val div: degree -> int -> degree val equal: degree -> degree -> bool val is_bigger: degree -> degree -> bool @@ -42,8 +43,8 @@ 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 sub: polynome -> polynome -> polynome val generate: int -> polynome end ;; @@ -83,13 +84,28 @@ module Polynome (C : Coefficient) (D : Degree) = then NotNull (cy, dy, add x yy) else if D.is_bigger dx dy - then NotNull (cx, dx, add xx yy) + then NotNull (cx, dx, add xx y) else let m = C.add cx cy in if C.is_null m then add xx yy else NotNull (m, dx, add xx yy) + let rec sub x y = match x, y with + |Null,_ -> y + |_, Null -> x + |NotNull (cx, dx, xx), NotNull (cy, dy, yy)-> + if D.is_bigger dy dx + then NotNull ((C.minus cy), dy, sub x yy) + else + if D.is_bigger dx dy + then NotNull (cx, dx, sub xx y) + else + let m = C.sub cx cy in + if C.is_null m + then sub xx yy + else NotNull (m, dx, sub xx yy) + (*fonction privée pour incrémenter les degrees des monomes d'un polynome*) let rec increment_degree d x = match x with |Null -> Null @@ -109,12 +125,6 @@ module Polynome (C : Coefficient) (D : Degree) = |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 add x (minus y) (*fonction privée pour couper un polynome selon un degree*) (*polynome -> degree -> degree *) @@ -129,30 +139,28 @@ module Polynome (C : Coefficient) (D : Degree) = |NotNull (ccp, ddp, ppp) -> NotNull (ccp, ddp, (insert cc dd ppp)) ) in - let new_acc = insert cp (D.subtract dp i) acc in + let new_acc = insert cp (D.sub dp i) acc in acc_cut new_acc pp i else acc, p in acc_cut Null x n - 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, 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 + if D.equal dx D.unit || D.equal dy D.unit + 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 x1 y1) (add x2 y2)) (add xy1 xy2) in - add (add (increment_degree (D.double n) xy1) (increment_degree n xy3)) xy2 + let xy1 = naive_mul x1 y1 in + let xy2 = naive_mul x2 y2 in + let xy3 = sub (naive_mul (add x1 y1) (add x2 y2)) (add xy1 xy2) in + add xy2 (add (increment_degree (D.double n) xy1) (increment_degree n xy3)) (*generate polynome from another polynome*) let generate n = @@ -160,7 +168,10 @@ module Polynome (C : Coefficient) (D : Degree) = 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 + |NotNull(_,dx,_) -> + let cx = C.generate c in + if C.is_null cx then x + else NotNull(cx, D.increment dx, x) in gen (add_monome acc (count - 1)) (count-1) in gen Null n end diff --git a/simplepolynome.ml b/simplepolynome.ml index 8fa34a4ec8fb8377419963a2030b101aa32bef35..0fec9e25075c4c70ad4bbe3cfbf3a9566260bfd7 100644 --- a/simplepolynome.ml +++ b/simplepolynome.ml @@ -10,7 +10,7 @@ module SimpleDegree = type degree = int let print d = (string_of_int d) let add d1 d2 = d1 + d2 - let subtract d1 d2 = d1 - d2 + let sub d1 d2 = d1 - d2 let div d i = d/i let equal d1 d2 = (d1 == d2) let is_bigger d1 d2 = (d1 > d2) @@ -26,6 +26,7 @@ module SimpleCoeff = type coeff = big_int let print c = (string_of_big_int c) let add c1 c2 = add_big_int c1 c2 + let sub c1 c2 = sub_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 mul c1 c2 = mult_big_int c1 c2