372 val P = P * p |
372 val P = P * p |
373 val g = centr_up ((chinese_remainder_up (P, p) (g, g_p)) mod_up P) P |
373 val g = centr_up ((chinese_remainder_up (P, p) (g, g_p)) mod_up P) P |
374 in try_new_prime_up a b d M P g p end |
374 in try_new_prime_up a b d M P g p end |
375 end |
375 end |
376 |
376 |
377 (* HENSEL_lifting_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> unipoly |
377 (* iterate_CHINESE_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int \<Rightarrow> unipoly |
378 HENSEL_lifting_up p1 p2 d M p = gcd |
378 iterate_CHINESE_up p1 p2 d M p = gcd |
379 assumes d = gcd (lcoeff_up p1, lcoeff_up p2) \<and> |
379 assumes d = gcd (lcoeff_up p1, lcoeff_up p2) \<and> |
380 M = LANDAU_MIGNOTTE_bound \<and> p = prime \<and> p ~| d \<and> |
380 M = LANDAU_MIGNOTTE_bound \<and> p = prime \<and> p ~| d \<and> |
381 p1 is primitive \<and> p2 is primitive |
381 p1 is primitive \<and> p2 is primitive |
382 yields gcd | p1 \<and> gcd | p2 \<and> gcd is primitive |
382 yields gcd | p1 \<and> gcd | p2 \<and> gcd is primitive |
383 |
383 |
384 argumentns "a b d M p" named according to [1] p.93 *) |
384 argumentns "a b d M p" named according to [1] p.93 *) |
385 fun HENSEL_lifting_up a b d M p = |
385 fun iterate_CHINESE_up a b d M p = |
386 let |
386 let |
387 val p = p next_prime_not_dvd d |
387 val p = p next_prime_not_dvd d |
388 val g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (d mod p)) mod_up p) p |
388 val g_p = centr_up (((normalise (mod_up_gcd a b p) p) %* (d mod p)) mod_up p) p |
389 (*.. nesting of functions see above*) |
389 (*.. nesting of functions see above*) |
390 in |
390 in |
391 if deg_up g_p = 0 then [1] else |
391 if deg_up g_p = 0 then [1] else |
392 let |
392 let |
393 val g = primitive_up (try_new_prime_up a b d M p g_p p) |
393 val g = primitive_up (try_new_prime_up a b d M p g_p p) |
394 in |
394 in |
395 if (g %|% a) andalso (g %|% b) then g:unipoly else HENSEL_lifting_up a b d M p |
395 if (g %|% a) andalso (g %|% b) then g:unipoly else iterate_CHINESE_up a b d M p |
396 end |
396 end |
397 end |
397 end |
398 |
398 |
399 (* gcd_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly |
399 (* gcd_up :: unipoly \<Rightarrow> unipoly \<Rightarrow> unipoly |
400 gcd_up a b = c |
400 gcd_up a b = c |
677 (* a b are made primitive and this is compensated by multiplying with gcd of divisors *) |
677 (* a b are made primitive and this is compensated by multiplying with gcd of divisors *) |
678 uni_to_multi ((gcd_up (primitive_up a') (primitive_up b')) %* |
678 uni_to_multi ((gcd_up (primitive_up a') (primitive_up b')) %* |
679 (abs (Integer.gcd (gcd_coeff a') (gcd_coeff b')))) |
679 (abs (Integer.gcd (gcd_coeff a') (gcd_coeff b')))) |
680 end |
680 end |
681 |
681 |
682 (* fn: poly -> poly -> int -> |
682 (* try_new_r :: poly -> poly -> int -> int -> int -> int list -> poly list -> poly |
683 int -> int -> int list -> poly list -> poly |
683 try_new_r a b n M r r_list steps = |
684 assumes length a > 1 \<and> length b > 1 |
684 assumes length a > 1 \<and> length b > 1 |
685 yields TODO |
685 yields TODO |
686 *) |
686 *) |
687 and try_new_r a b n M r r_list steps = |
687 and try_new_r a b n M r r_list steps = |
688 let |
688 let |
689 val r = find_new_r a b r; |
689 val r = find_new_r a b r; |
690 val r_list = r_list @ [r]; |
690 val r_list = r_list @ [r]; |
691 val g_r = gcd_poly' (order (eval a (n - 2) r)) |
691 val g_r = gcd_poly' (order (eval a (n - 2) r)) |
692 (order (eval b (n - 2) r)) (n - 1) 0 |
692 (order (eval b (n - 2) r)) (n - 1) 0 |
693 val steps = steps @ [g_r]; |
693 val steps = steps @ [g_r]; |
694 in HENSEL_lifting a b n M 1 r r_list steps g_r ( zero_poly n ) [1] end |
694 in iterate_CHINESE a b n M 1 r r_list steps g_r (zero_poly n) [1] end |
695 (* fn: poly -> poly -> int -> |
695 |
696 int -> int -> int -> int list -> poly list -> |
696 (* iterate_CHINESE :: poly -> poly -> int -> int -> int -> int -> int list -> |
697 | poly -> poly -> int list -> poly |
697 | poly list -> poly -> poly -> int list -> poly |
|
698 iterate_CHINESE a | b n M m r r_list |
|
699 steps g g_n mult = |
698 assumes length a > 1 \<and> length b > 1 |
700 assumes length a > 1 \<and> length b > 1 |
699 yields TODO |
701 yields TODO |
700 *) |
702 *) |
701 and HENSEL_lifting a b n M m r r_list steps g g_n mult = |
703 and iterate_CHINESE a b n M m r r_list steps g g_n mult = |
702 if m > M then if g_n %%|%% a andalso g_n %%|%% b then g_n else |
704 if m > M then if g_n %%|%% a andalso g_n %%|%% b then g_n else |
703 try_new_r a b n M r r_list steps |
705 try_new_r a b n M r r_list steps |
704 else |
706 else |
705 let |
707 let |
706 val r = find_new_r a b r; |
708 val r = find_new_r a b r; |
707 val r_list = r_list @ [r]; |
709 val r_list = r_list @ [r]; |
708 val g_r = gcd_poly' (order (eval a (n - 2) r)) |
710 val g_r = gcd_poly' (order (eval a (n - 2) r)) |
709 (order (eval b (n - 2) r)) (n - 1) 0 |
711 (order (eval b (n - 2) r)) (n - 1) 0 |
710 in |
712 in |
711 if lex_ord (lmonom g) (lmonom g_r) |
713 if lex_ord (lmonom g) (lmonom g_r) |
712 then HENSEL_lifting a b n M 1 r r_list steps g g_n mult |
714 then iterate_CHINESE a b n M 1 r r_list steps g g_n mult |
713 else if (lexp g) = (lexp g_r) |
715 else if lexp g = lexp g_r |
714 then |
716 then |
715 let val (g_n, new, steps) = NEWTON r_list [g, g_r] steps mult g_n (n - 2) |
717 let val (g_n, new, steps) = NEWTON r_list [g, g_r] steps mult g_n (n - 2) |
716 in |
718 in |
717 if (nth steps (length steps - 1)) = (zero_poly (n - 1)) |
719 if nth steps (length steps - 1) = zero_poly (n - 1) |
718 then HENSEL_lifting a b n M (M + 1) r r_list steps g_r g_n new |
720 then iterate_CHINESE a b n M (M + 1) r r_list steps g_r g_n new |
719 else HENSEL_lifting a b n M (m + 1) r r_list steps g_r g_n new |
721 else iterate_CHINESE a b n M (m + 1) r r_list steps g_r g_n new |
720 end |
722 end |
721 else (* \<not> lex_ord (lmonom g) (lmonom g_r) *) |
723 else (* \<not> lex_ord (lmonom g) (lmonom g_r) *) |
722 HENSEL_lifting a b n M (m + 1) r r_list steps g g_n mult |
724 iterate_CHINESE a b n M (m + 1) r r_list steps g g_n mult |
723 end |
725 end |
724 |
726 |
725 fun majority_of_coefficients_is_negative a b c = |
727 fun majority_of_coefficients_is_negative_in a b c = |
726 let val cs = (coeffs a) @ (coeffs b) @ (coeffs c) |
728 let val cs = (coeffs a) @ (coeffs b) @ (coeffs c) |
727 in length (filter (curry op < 0) cs) < length cs div 2 end |
729 in length (filter (curry op < 0) cs) < length cs div 2 end |
728 |
730 |
729 (* gcd_poly :: poly \<Rightarrow> poly \<Rightarrow> poly |
731 (* gcd_poly :: poly \<Rightarrow> poly \<Rightarrow> poly |
730 gcd_poly a b = ((a', b'), c) |
732 gcd_poly a b = ((a', b'), c) |