380 p1 is primitive \<and> p2 is primitive |
380 p1 is primitive \<and> p2 is primitive |
381 yields gcd | p1 \<and> gcd | p2 \<and> gcd is primitive |
381 yields gcd | p1 \<and> gcd | p2 \<and> gcd is primitive |
382 |
382 |
383 argumentns "a b d M p" named according to [1] p.93 *) |
383 argumentns "a b d M p" named according to [1] p.93 *) |
384 fun HENSEL_lifting_up a b d M p = |
384 fun HENSEL_lifting_up a b d M p = |
385 let |
385 let |
|
386 val _ = writeln ("HENSEL-univ d = " ^ PolyML.makestring d ^ |
|
387 ", M = " ^ PolyML.makestring (2 * d * LANDAU_MIGNOTTE_bound a b) ^ |
|
388 ", p = " ^ PolyML.makestring p) |
386 val p = p next_prime_not_dvd d |
389 val p = p next_prime_not_dvd d |
387 val g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (d mod p)) mod_up p) p (*see above*) |
390 val g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (d mod p)) mod_up p) p (*see above*) |
388 in |
391 in |
389 if deg_up g_p = 0 then [1] else |
392 if deg_up g_p = 0 then [1] else |
390 let |
393 let |
391 val g = primitive_up (try_new_prime_up a b d M p g_p p) |
394 val g = primitive_up (try_new_prime_up a b d M p g_p p) |
392 in |
395 in |
393 if (g %|% a) andalso (g %|% b) then |
396 if (g %|% a) andalso (g %|% b) then |
394 (writeln ("HENSEL-univ M = " ^ PolyML.makestring M ^ ", p = " ^ PolyML.makestring p ^ |
397 (writeln ("HENSEL-univ -------------------> " ^ PolyML.makestring g); |
395 ": " ^ PolyML.makestring g ^ " %|% " ^ PolyML.makestring a ^ |
|
396 " /\\ " ^ PolyML.makestring g ^ " %|% " ^ PolyML.makestring b); |
|
397 g:unipoly |
398 g:unipoly |
398 ) |
399 ) |
399 else HENSEL_lifting_up a b d M p |
400 else HENSEL_lifting_up a b d M p |
400 end |
401 end |
401 end |
402 end |
491 fun max_deg_var (p: poly) var = (maxs o (map ((nth_swapped var) o snd))) p; |
492 fun max_deg_var (p: poly) var = (maxs o (map ((nth_swapped var) o snd))) p; |
492 *} |
493 *} |
493 |
494 |
494 subsection {* evaluation, translation uni--multivariate, etc *} |
495 subsection {* evaluation, translation uni--multivariate, etc *} |
495 ML {* |
496 ML {* |
496 (* evaluate a polynomial in a certain variable and remove this from the exp-list *) |
497 (* evaluate a polynomial in a certain variable and remove this var from the exp-list *) |
497 fun eval (p: poly) var value = |
498 fun eval (p: poly) var value = (* TODO use "map" instead*) |
498 let |
499 let |
499 fun eval [] _ _ new = order new |
500 fun eval [] _ _ new = order new |
500 | eval ((c, es)::ps) var value new = |
501 | eval ((c, es)::ps) var value new = |
501 eval ps var value (new @ [((Integer.pow (nth es var) value) * c, nth_drop var es)]); |
502 eval ps var value (new @ [((Integer.pow (nth es var) value) * c, nth_drop var es)]); |
502 in eval p var value [] end |
503 in eval p var value [] end |
677 in (order p', new_vals, steps) end |
678 in (order p', new_vals, steps) end |
678 *} |
679 *} |
679 |
680 |
680 subsection {* gcd_poly algorithm, code for [1] p.95 *} |
681 subsection {* gcd_poly algorithm, code for [1] p.95 *} |
681 ML {* |
682 ML {* |
682 (* naming of n, M, m, r, ... follows Winkler p. 95 *) |
683 (* naming of n, M, m, r, ... follows Winkler p. 95 |
|
684 n: amount of variables |
|
685 r: *) |
683 fun gcd_poly' (a as (_, es1)::_ : poly) (b as (_, es2)::_ : poly) n r = |
686 fun gcd_poly' (a as (_, es1)::_ : poly) (b as (_, es2)::_ : poly) n r = |
684 if lex_ord (lmonom b) (lmonom a) then gcd_poly' b a n r else |
687 if lex_ord (lmonom b) (lmonom a) then gcd_poly' b a n r else |
685 if n - 1 = 0 |
688 if n > 1 |
686 then |
689 then |
|
690 let val M = 1 + Int.min (max_deg_var a (length es1 - 2), max_deg_var b (length es2 - 2)); |
|
691 in try_new_r a b n M r [] [] end |
|
692 else |
687 let val (a', b') = (multi_to_uni a, multi_to_uni b) |
693 let val (a', b') = (multi_to_uni a, multi_to_uni b) |
688 in |
694 in |
689 (* a b are made primitive and this is compensated by multiplying with gcd of divisors *) |
695 (* a b are made primitive and this is compensated by multiplying with gcd of divisors *) |
690 uni_to_multi ((gcd_up (primitive_up a') (primitive_up b')) %* |
696 uni_to_multi ((gcd_up (primitive_up a') (primitive_up b')) %* |
691 (abs (Integer.gcd (gcd_coeff a') (gcd_coeff b')))) |
697 (abs (Integer.gcd (gcd_coeff a') (gcd_coeff b')))) |
692 end |
698 end |
693 else |
|
694 let val M = 1 + Int.min (max_deg_var a (length es1 - 2), max_deg_var b (length es2 - 2)); |
|
695 in try_new_r a b n M r [] [] end |
|
696 |
699 |
697 (* fn: poly -> poly -> int -> |
700 (* fn: poly -> poly -> int -> |
698 int -> int -> int list -> poly list -> poly*) |
701 int -> int -> int list -> poly list -> poly*) |
699 and try_new_r a b n M r r_list steps = |
702 and try_new_r a b n M r r_list steps = |
700 let |
703 let |
710 end |
713 end |
711 (* fn: poly -> poly -> int -> |
714 (* fn: poly -> poly -> int -> |
712 int -> int -> int -> int list -> poly list -> |
715 int -> int -> int -> int list -> poly list -> |
713 | poly -> poly -> int list -> poly*) |
716 | poly -> poly -> int list -> poly*) |
714 and HENSEL_lifting a b n M m r r_list steps g g_n mult = |
717 and HENSEL_lifting a b n M m r r_list steps g g_n mult = |
|
718 ((*begin function body*) |
|
719 writeln ("HENSEL-poly n = " ^ PolyML.makestring n ^ |
|
720 ", M = " ^ PolyML.makestring M ^ ", m = " ^ PolyML.makestring m ^ |
|
721 ", r = " ^ PolyML.makestring r ^ ", r_list = " ^ PolyML.makestring r_list^ |
|
722 ", steps = " ^ PolyML.makestring steps ^ ", g = " ^ PolyML.makestring g ^ |
|
723 ", g_n = " ^ PolyML.makestring g_n ^ ", mult = " ^ PolyML.makestring mult); |
715 if m > M then if g_n %%|%% a andalso g_n %%|%% b then |
724 if m > M then if g_n %%|%% a andalso g_n %%|%% b then |
716 (writeln ("HENSEL-poly M = " ^ PolyML.makestring M ^ "HENSEL-poly M = " ^ PolyML.makestring M ^ |
725 (writeln ("HENSEL-poly ------------------------------> " ^ PolyML.makestring g_n); |
717 ": " ^ PolyML.makestring g_n ^ " %%|%% " ^ PolyML.makestring a ^ |
|
718 " /\\ " ^ PolyML.makestring g_n ^ " %%|%% " ^ PolyML.makestring b); |
|
719 g_n |
726 g_n |
720 ) |
727 ) |
721 else |
728 else |
722 try_new_r a b n M r r_list steps |
729 try_new_r a b n M r r_list steps |
723 else |
730 else |
748 end |
755 end |
749 else (* \<not> lex_ord (lmonom g) (lmonom g_r) *) |
756 else (* \<not> lex_ord (lmonom g) (lmonom g_r) *) |
750 (writeln ("recurs.call 4 HENSEL-poly"); |
757 (writeln ("recurs.call 4 HENSEL-poly"); |
751 HENSEL_lifting a b n M (m + 1) r r_list steps g g_n mult |
758 HENSEL_lifting a b n M (m + 1) r r_list steps g g_n mult |
752 ) |
759 ) |
753 end |
760 end |
|
761 )(*end function body*) |
754 |
762 |
755 (* gcd_poly :: poly \<Rightarrow> poly \<Rightarrow> poly |
763 (* gcd_poly :: poly \<Rightarrow> poly \<Rightarrow> poly |
756 gcd_poly a b = ((a', b'), c) |
764 gcd_poly a b = ((a', b'), c) |
757 assumes a \<noteq> [] \<and> b \<noteq> [] \<and> |
765 assumes a \<noteq> [] \<and> b \<noteq> [] \<and> |
758 yields a = a' *\<^isub>p c \<and> b = b' *\<^isub>p c \<and> |
766 yields a = a' *\<^isub>p c \<and> b = b' *\<^isub>p c \<and> |