diff --git a/main.ml b/main.ml index 3e590d69ce2252850e38c759ab2fb99ce85e0959..70474a14e2f0dcb93e43bbbeb3b4ef718a2e2724 100644 --- a/main.ml +++ b/main.ml @@ -12,5 +12,23 @@ 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, 0, P.Null);; -print_string (P.print pm); +let pm = P.NotNull(big_int_of_int 1, 1, P.Null);; +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"; diff --git a/polynome.ml b/polynome.ml index b44e23c83bdffbdce368bb991fac4ed3395b48af..adf65ea4704dee048fff9664bb4267657030852f 100644 --- a/polynome.ml +++ b/polynome.ml @@ -1,5 +1,10 @@ (*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;; module type Coefficient = @@ -10,6 +15,7 @@ module type Coefficient = val equal: coeff -> coeff -> bool val add: coeff -> coeff -> coeff val mul: coeff -> coeff -> coeff + val minus: coeff -> coeff end ;; @@ -57,6 +63,7 @@ module Polynome (C : Coefficient) (D : Degree) = else false else false ) + (*addition de deux polynomes*) let rec add x y = match x with |Null -> y |NotNull (cx, dx, xx)-> @@ -74,24 +81,70 @@ module Polynome (C : Coefficient) (D : Degree) = then 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 |Null -> Null |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 |Null -> Null |NotNull (cx, dx, xx) -> if C.is_null c then Null 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 |Null -> Null |NotNull (cx, dx, xx) -> (match y with |Null -> Null |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 ;; diff --git a/simplepolynome.ml b/simplepolynome.ml index db1ccf634320a29e5ea194739f1dc0e809c020cb..b7f2de39bc1ecccaeebb3bb0332ec8ba0e55c787 100644 --- a/simplepolynome.ml +++ b/simplepolynome.ml @@ -20,5 +20,6 @@ module SimpleCoeff = 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 + let minus c = minus_big_int c end ;;