My Project
Loading...
Searching...
No Matches
facFqBivar.cc
Go to the documentation of this file.
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file facFqBivar.cc
5 *
6 * This file provides functions for factorizing a bivariate polynomial over
7 * \f$ F_{p} \f$ , \f$ F_{p}(\alpha ) \f$ or GF, based on "Modern Computer
8 * Algebra, Chapter 15" by J. von zur Gathen & J. Gerhard and "Factoring
9 * multivariate polynomials over a finite field" by L. Bernardin.
10 * Factor Recombination is described in "Factoring polynomials over global
11 * fields" by K. Belabas, M. van Hoeij, J. Klueners, A. Steel
12 *
13 *
14 * @author Martin Lee
15 *
16 **/
17/*****************************************************************************/
18
19
20#include "config.h"
21
22
23#include "cf_assert.h"
24#include "cf_util.h"
25#include "debug.h"
26#include "timing.h"
27
28#include "canonicalform.h"
29#include "cf_defs.h"
30#include "cf_map_ext.h"
31#include "cf_random.h"
32#include "facHensel.h"
33#include "facMul.h"
34#include "cf_map.h"
35#include "cf_irred.h"
36#include "facFqBivarUtil.h"
37#include "facFqBivar.h"
38#include "cfNewtonPolygon.h"
39
40#ifdef HAVE_NTL
41#include "NTLconvert.h"
42#endif
43
44#ifdef HAVE_FLINT
45#include "FLINTconvert.h"
46#endif
47
48TIMING_DEFINE_PRINT(fac_fq_uni_factorizer)
49TIMING_DEFINE_PRINT(fac_fq_bi_hensel_lift)
50TIMING_DEFINE_PRINT(fac_fq_bi_factor_recombination)
51TIMING_DEFINE_PRINT(fac_fq_bi_evaluation)
52TIMING_DEFINE_PRINT(fac_fq_bi_shift_to_zero)
53TIMING_DEFINE_PRINT(fac_fq_logarithmic)
54TIMING_DEFINE_PRINT(fac_fq_compute_lattice_lift)
55TIMING_DEFINE_PRINT(fac_fq_till_reduced)
56TIMING_DEFINE_PRINT(fac_fq_reconstruction)
57TIMING_DEFINE_PRINT(fac_fq_lift)
58TIMING_DEFINE_PRINT(fac_fq_uni_total)
59
61{
62 if (L.isEmpty())
63 return 1;
64 else if (L.length() == 1)
65 return mod (L.getFirst()(0, 1) , M);
66 else if (L.length() == 2)
67 return mod (mulNTL (L.getFirst()(0, 1),L.getLast()(0, 1), b), M);
68 else
69 {
70 int l= L.length()/2;
74 for (int j= 1; j <= l; j++, i++)
75 tmp1.append (i.getItem());
76 tmp2= Difference (L, tmp1);
77 buf1= prodMod0 (tmp1, M, b);
78 buf2= prodMod0 (tmp2, M, b);
79 return mod (mulNTL (buf1,buf2, b), M);
80 }
81}
82
83#if defined(HAVE_NTL) || defined(HAVE_FLINT)
85 const Variable& alpha, CFList& list, const bool& GF,
86 bool& fail)
87{
88 fail= false;
91 FFRandom genFF;
92 GFRandom genGF;
93 CanonicalForm random, mipo;
94 double bound;
95 int p= getCharacteristic ();
96 if (alpha.level() != 1)
97 {
99 int d= degree (mipo);
100 bound= pow ((double) p, (double) d);
101 }
102 else if (GF)
103 {
104 int d= getGFDegree();
105 bound= ipower (p, d);
106 }
107 else
108 bound= p;
109
110 random= 0;
111 do
112 {
113 if (list.length() >= bound)
114 {
115 fail= true;
116 break;
117 }
118 if (list.isEmpty())
119 random= 0;
120 else if (GF)
121 {
122 if (list.length() == 1)
123 random= getGFGenerator();
124 else
125 random= genGF.generate();
126 }
127 else if (list.length() < p || alpha.level() == 1)
128 random= genFF.generate();
129 else if (alpha != x && list.length() >= p)
130 {
131 if (list.length() == p)
132 random= alpha;
133 else
134 {
135 AlgExtRandomF genAlgExt (alpha);
136 random= genAlgExt.generate();
137 }
138 }
139 if (find (list, random)) continue;
140 eval= F (random, x);
141 if (degree (eval) != degree (F, y))
142 { //leading coeff vanishes
143 if (!find (list, random))
144 list.append (random);
145 continue;
146 }
147 if (degree (gcd (deriv (eval, eval.mvar()), eval), eval.mvar()) > 0)
148 { //evaluated polynomial is not squarefree
149 if (!find (list, random))
150 list.append (random);
151 continue;
152 }
153 } while (find (list, random));
154
155 return random;
156}
157
158#if defined(HAVE_NTL) || defined(HAVE_FLINT)
159CFList
160uniFactorizer (const CanonicalForm& A, const Variable& alpha, const bool& GF)
161{
162 Variable x= A.mvar();
163 if (A.inCoeffDomain())
164 return CFList();
165 ASSERT (A.isUnivariate(),
166 "univariate polynomial expected or constant expected");
167 CFFList factorsA;
168 if (GF)
169 {
170 int k= getGFDegree();
171 char cGFName= gf_name;
176#ifdef HAVE_NTL
177 if (getCharacteristic() > 2)
178#else
179 if (getCharacteristic() > 0)
180#endif
181 {
182#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
183 nmod_poly_t FLINTmipo, leadingCoeff;
184 fq_nmod_ctx_t fq_con;
185 fq_nmod_poly_t FLINTA;
186 fq_nmod_poly_factor_t FLINTFactorsA;
187
188 nmod_poly_init (FLINTmipo, getCharacteristic());
190
191 fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
192
194 fq_nmod_poly_make_monic (FLINTA, FLINTA, fq_con);
195
196 fq_nmod_poly_factor_init (FLINTFactorsA, fq_con);
197 nmod_poly_init (leadingCoeff, getCharacteristic());
198
199 fq_nmod_poly_factor (FLINTFactorsA, leadingCoeff, FLINTA, fq_con);
200
201 factorsA= convertFLINTFq_nmod_poly_factor2FacCFFList (FLINTFactorsA, x,
202 beta, fq_con);
203
204 fq_nmod_poly_factor_clear (FLINTFactorsA, fq_con);
205 fq_nmod_poly_clear (FLINTA, fq_con);
206 nmod_poly_clear (FLINTmipo);
207 nmod_poly_clear (leadingCoeff);
209#else
211 {
213 zz_p::init (getCharacteristic());
214 }
215 zz_pX NTLMipo= convertFacCF2NTLzzpX (mipo.mapinto());
216 zz_pE::init (NTLMipo);
217 zz_pEX NTLA= convertFacCF2NTLzz_pEX (buf, NTLMipo);
218 MakeMonic (NTLA);
219 vec_pair_zz_pEX_long NTLFactorsA= CanZass (NTLA);
220 zz_pE multi= to_zz_pE (1);
221 factorsA= convertNTLvec_pair_zzpEX_long2FacCFFList (NTLFactorsA, multi,
222 x, beta);
223#endif
224 }
225#ifdef HAVE_NTL
226 else
227 {
228 GF2X NTLMipo= convertFacCF2NTLGF2X (mipo.mapinto());
229 GF2E::init (NTLMipo);
230 GF2EX NTLA= convertFacCF2NTLGF2EX (buf, NTLMipo);
231 MakeMonic (NTLA);
232 vec_pair_GF2EX_long NTLFactorsA= CanZass (NTLA);
233 GF2E multi= to_GF2E (1);
234 factorsA= convertNTLvec_pair_GF2EX_long2FacCFFList (NTLFactorsA, multi,
235 x, beta);
236 }
237#endif
239 for (CFFListIterator i= factorsA; i.hasItem(); i++)
240 {
241 buf= i.getItem().factor();
243 i.getItem()= CFFactor (buf, i.getItem().exp());
244 }
245 prune (beta);
246 }
247 else if (alpha.level() != 1)
248 {
249#ifdef HAVE_NTL
250 if (getCharacteristic() > 2)
251#else
252 if (getCharacteristic() > 0)
253#endif
254 {
255#if (HAVE_FLINT && __FLINT_RELEASE >= 20400)
256 nmod_poly_t FLINTmipo, leadingCoeff;
257 fq_nmod_ctx_t fq_con;
258 fq_nmod_poly_t FLINTA;
259 fq_nmod_poly_factor_t FLINTFactorsA;
260
261 nmod_poly_init (FLINTmipo, getCharacteristic());
263
264 fq_nmod_ctx_init_modulus (fq_con, FLINTmipo, "Z");
265
267 fq_nmod_poly_make_monic (FLINTA, FLINTA, fq_con);
268
269 fq_nmod_poly_factor_init (FLINTFactorsA, fq_con);
270 nmod_poly_init (leadingCoeff, getCharacteristic());
271
272 fq_nmod_poly_factor (FLINTFactorsA, leadingCoeff, FLINTA, fq_con);
273
274 factorsA= convertFLINTFq_nmod_poly_factor2FacCFFList (FLINTFactorsA, x,
275 alpha, fq_con);
276
277 fq_nmod_poly_factor_clear (FLINTFactorsA, fq_con);
278 fq_nmod_poly_clear (FLINTA, fq_con);
279 nmod_poly_clear (FLINTmipo);
280 nmod_poly_clear (leadingCoeff);
282#else
284 {
286 zz_p::init (getCharacteristic());
287 }
288 zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
289 zz_pE::init (NTLMipo);
290 zz_pEX NTLA= convertFacCF2NTLzz_pEX (A, NTLMipo);
291 MakeMonic (NTLA);
292 vec_pair_zz_pEX_long NTLFactorsA= CanZass (NTLA);
293 zz_pE multi= to_zz_pE (1);
294 factorsA= convertNTLvec_pair_zzpEX_long2FacCFFList (NTLFactorsA, multi,
295 x, alpha);
296#endif
297 }
298#ifdef HAVE_NTL
299 else
300 {
301 GF2X NTLMipo= convertFacCF2NTLGF2X (getMipo (alpha));
302 GF2E::init (NTLMipo);
303 GF2EX NTLA= convertFacCF2NTLGF2EX (A, NTLMipo);
304 MakeMonic (NTLA);
305 vec_pair_GF2EX_long NTLFactorsA= CanZass (NTLA);
306 GF2E multi= to_GF2E (1);
307 factorsA= convertNTLvec_pair_GF2EX_long2FacCFFList (NTLFactorsA, multi,
308 x, alpha);
309 }
310#endif
311 }
312 else
313 {
314#ifdef HAVE_FLINT
315#ifdef HAVE_NTL
316 if (degree (A) < 300)
317#endif
318 {
319 nmod_poly_t FLINTA;
320 convertFacCF2nmod_poly_t (FLINTA, A);
321 nmod_poly_factor_t result;
322 nmod_poly_factor_init (result);
323 mp_limb_t leadingCoeff= nmod_poly_factor (result, FLINTA);
324 factorsA= convertFLINTnmod_poly_factor2FacCFFList (result, leadingCoeff, x);
325 if (factorsA.getFirst().factor().inCoeffDomain())
326 factorsA.removeFirst();
327 nmod_poly_factor_clear (result);
328 nmod_poly_clear (FLINTA);
329 }
330#ifdef HAVE_NTL
331 else
332#endif
333#endif /* HAVE_FLINT */
334#ifdef HAVE_NTL
335 if (getCharacteristic() > 2)
336 {
338 {
340 zz_p::init (getCharacteristic());
341 }
342 zz_pX NTLA= convertFacCF2NTLzzpX (A);
343 MakeMonic (NTLA);
344 vec_pair_zz_pX_long NTLFactorsA= CanZass (NTLA);
345 zz_p multi= to_zz_p (1);
346 factorsA= convertNTLvec_pair_zzpX_long2FacCFFList (NTLFactorsA, multi,
347 x);
348 }
349 else
350 {
351 GF2X NTLA= convertFacCF2NTLGF2X (A);
352 vec_pair_GF2X_long NTLFactorsA= CanZass (NTLA);
353 GF2 multi= to_GF2 (1);
354 factorsA= convertNTLvec_pair_GF2X_long2FacCFFList (NTLFactorsA, multi,
355 x);
356 }
357#endif
358 }
359 CFList uniFactors;
360 for (CFFListIterator i= factorsA; i.hasItem(); i++)
361 uniFactors.append (i.getItem().factor());
362 return uniFactors;
363}
364#endif
365
366#if defined(HAVE_NTL) || defined(HAVE_FLINT)
367/// naive factor recombination as decribed in "Factoring
368/// multivariate polynomials over a finite field" by L Bernardin.
369CFList
371 const CanonicalForm& N, const ExtensionInfo& info,
372 DegreePattern& degs, const CanonicalForm& eval, int s,
373 int thres)
374{
375 if (factors.length() == 0)
376 {
377 F= 1;
378 return CFList();
379 }
380 if (F.inCoeffDomain())
381 return CFList();
382
383 Variable alpha= info.getAlpha();
384 Variable beta= info.getBeta();
385 CanonicalForm gamma= info.getGamma();
386 CanonicalForm delta= info.getDelta();
387 int k= info.getGFDegree();
388
390 int l= degree (N);
391 Variable y= F.mvar();
392 Variable x= Variable (1);
393 CFList source, dest;
394 if (degs.getLength() <= 1 || factors.length() == 1)
395 {
396 CFList result= CFList(mapDown (F(y-eval, y), info, source, dest));
397 F= 1;
398 return result;
399 }
400
401 DEBOUTLN (cerr, "LC (F, 1)*prodMod (factors, M) == F " <<
402 (mod (LC (F, 1)*prodMod (factors, M), M)/Lc (mod (LC (F, 1)*prodMod (factors, M), M)) == F/Lc (F)));
403 int degMipoBeta= 1;
404 if (!k && beta.level() != 1)
405 degMipoBeta= degree (getMipo (beta));
406
407 CFList T, S, Diff;
408 T= factors;
409
411 CanonicalForm buf, buf2, quot;
412
413 buf= F;
414
415 CanonicalForm g, LCBuf= LC (buf, x);
416 int * v= new int [T.length()];
417 for (int i= 0; i < T.length(); i++)
418 v[i]= 0;
419
420 CFArray TT;
421 DegreePattern bufDegs1, bufDegs2;
422 bufDegs1= degs;
423 int subsetDeg;
424 TT= copy (factors);
425 bool nosubset= false;
426 bool recombination= false;
427 bool trueFactor= false;
429 CanonicalForm buf0= buf (0, x)*LCBuf;
430 while (T.length() >= 2*s && s <= thres)
431 {
432 while (nosubset == false)
433 {
434 if (T.length() == s)
435 {
436 delete [] v;
437 if (recombination)
438 {
439 T.insert (LCBuf);
440 g= prodMod (T, M);
441 T.removeFirst();
442 g /= content(g);
443 g= g (y - eval, y);
444 g /= Lc (g);
445 appendTestMapDown (result, g, info, source, dest);
446 F= 1;
447 return result;
448 }
449 else
450 {
451 appendMapDown (result, F (y - eval, y), info, source, dest);
452 F= 1;
453 return result;
454 }
455 }
456 S= subset (v, s, TT, nosubset);
457 if (nosubset) break;
458 subsetDeg= subsetDegree (S);
459 // skip those combinations that are not possible
460 if (!degs.find (subsetDeg))
461 continue;
462 else
463 {
464 test= prodMod0 (S, M);
465 test *= LCBuf;
466 test = mod (test, M);
467 if (fdivides (test, buf0))
468 {
469 S.insert (LCBuf);
470 g= prodMod (S, M);
471 S.removeFirst();
472 g /= content (g, x);
473 if (fdivides (g, buf, quot))
474 {
475 buf2= g (y - eval, y);
476 buf2 /= Lc (buf2);
477
478 if (!k && beta.level() == 1)
479 {
480 if (degree (buf2, alpha) < degMipoBeta)
481 {
482 buf= quot;
483 LCBuf= LC (buf, x);
484 recombination= true;
485 appendTestMapDown (result, buf2, info, source, dest);
486 trueFactor= true;
487 }
488 }
489 else
490 {
491 if (!isInExtension (buf2, gamma, k, delta, source, dest))
492 {
493 buf= quot;
494 LCBuf= LC (buf, x);
495 recombination= true;
496 appendTestMapDown (result, buf2, info, source, dest);
497 trueFactor= true;
498 }
499 }
500 if (trueFactor)
501 {
502 T= Difference (T, S);
503 l -= degree (g);
504 M= power (y, l);
505 buf0= buf (0, x)*LCBuf;
506
507 // compute new possible degree pattern
508 bufDegs2= DegreePattern (T);
509 bufDegs1.intersect (bufDegs2);
510 bufDegs1.refine ();
511 if (T.length() < 2*s || T.length() == s ||
512 bufDegs1.getLength() == 1)
513 {
514 delete [] v;
515 if (recombination)
516 {
517 buf= buf (y-eval,y);
518 buf /= Lc (buf);
519 appendTestMapDown (result, buf, info, source,
520 dest);
521 F= 1;
522 return result;
523 }
524 else
525 {
526 appendMapDown (result, F (y - eval, y), info, source, dest);
527 F= 1;
528 return result;
529 }
530 }
531 trueFactor= false;
532 TT= copy (T);
533 indexUpdate (v, s, T.length(), nosubset);
534 if (nosubset) break;
535 }
536 }
537 }
538 }
539 }
540 s++;
541 if (T.length() < 2*s || T.length() == s)
542 {
543 delete [] v;
544 if (recombination)
545 {
546 buf= buf (y-eval,y);
547 buf /= Lc (buf);
548 appendTestMapDown (result, buf, info, source, dest);
549 F= 1;
550 return result;
551 }
552 else
553 {
554 appendMapDown (result, F (y - eval, y), info, source, dest);
555 F= 1;
556 return result;
557 }
558 }
559 for (int i= 0; i < T.length(); i++)
560 v[i]= 0;
561 nosubset= false;
562 }
563 if (T.length() < 2*s)
564 {
565 appendMapDown (result, F (y - eval, y), info, source, dest);
566 F= 1;
567 delete [] v;
568 return result;
569 }
570
571 if (s > thres)
572 {
573 factors= T;
574 F= buf;
575 degs= bufDegs1;
576 }
577
578 delete [] v;
579 return result;
580}
581#endif
582
583/// naive factor recombination as decribed in "Factoring
584/// multivariate polynomials over a finite field" by L Bernardin.
585CFList
587 const CanonicalForm& N, DegreePattern& degs, const
588 CanonicalForm& eval, int s, int thres, const modpk& b,
589 const CanonicalForm& den
590 )
591{
592 if (factors.length() == 0)
593 {
594 F= 1;
595 return CFList ();
596 }
597 if (F.inCoeffDomain())
598 return CFList();
599 Variable y= Variable (2);
600 if (degs.getLength() <= 1 || factors.length() == 1)
601 {
602 CFList result= CFList (F(y-eval,y));
603 F= 1;
604 return result;
605 }
606#ifdef DEBUGOUTPUT
607 if (b.getp() == 0)
608 DEBOUTLN (cerr, "LC (F, 1)*prodMod (factors, N) == F " <<
609 (mod (LC (F, 1)*prodMod (factors, N),N)/Lc (mod (LC (F, 1)*prodMod (factors, N),N)) == F/Lc(F)));
610 else
611 DEBOUTLN (cerr, "LC (F, 1)*prodMod (factors, N) == F " <<
612 (mod (b(LC (F, 1)*prodMod (factors, N)),N)/Lc (mod (b(LC (F, 1)*prodMod (factors, N)),N)) == F/Lc(F)));
613#endif
614
615 CFList T, S;
616
618 int l= degree (N);
619 T= factors;
621 Variable x= Variable (1);
622 CanonicalForm denom= den, denQuot;
623 CanonicalForm LCBuf= LC (F, x)*denom;
624 CanonicalForm g, quot, buf= F;
625 int * v= new int [T.length()];
626 for (int i= 0; i < T.length(); i++)
627 v[i]= 0;
628 bool nosubset= false;
629 CFArray TT;
630 DegreePattern bufDegs1, bufDegs2;
631 bufDegs1= degs;
632 int subsetDeg;
633 TT= copy (factors);
634 bool recombination= false;
636 bool isRat= (isOn (SW_RATIONAL) && getCharacteristic() == 0) ||
637 getCharacteristic() > 0;
638 if (!isRat)
639 On (SW_RATIONAL);
640 CanonicalForm buf0= mulNTL (buf (0, x), LCBuf);
641 if (!isRat)
643 while (T.length() >= 2*s && s <= thres)
644 {
645 while (nosubset == false)
646 {
647 if (T.length() == s)
648 {
649 delete [] v;
650 if (recombination)
651 {
652 T.insert (LCBuf);
653 g= prodMod (T, M);
654 if (b.getp() != 0)
655 g= b(g);
656 T.removeFirst();
657 g /= content (g,x);
658 result.append (g(y-eval,y));
659 F= 1;
660 return result;
661 }
662 else
663 {
664 result= CFList (F(y-eval,y));
665 F= 1;
666 return result;
667 }
668 }
669 S= subset (v, s, TT, nosubset);
670 if (nosubset) break;
671 subsetDeg= subsetDegree (S);
672 // skip those combinations that are not possible
673 if (!degs.find (subsetDeg))
674 continue;
675 else
676 {
677 if (!isRat)
678 On (SW_RATIONAL);
679 test= prodMod0 (S, M);
680 if (!isRat)
681 {
682 test *= bCommonDen (test);
684 }
685 test= mulNTL (test, LCBuf, b);
686 test= mod (test, M);
687 if (uniFdivides (test, buf0))
688 {
689 if (!isRat)
690 On (SW_RATIONAL);
691 S.insert (LCBuf);
692 g= prodMod (S, M);
693 S.removeFirst();
694 if (!isRat)
695 {
696 g *= bCommonDen(g);
698 }
699 if (b.getp() != 0)
700 g= b(g);
701 if (!isRat)
702 On (SW_RATIONAL);
703 g /= content (g, x);
704 if (!isRat)
705 {
706 On (SW_RATIONAL);
707 if (!Lc (g).inBaseDomain())
708 g /= Lc (g);
709 g *= bCommonDen (g);
711 g /= icontent (g);
712 On (SW_RATIONAL);
713 }
714 if (fdivides (g, buf, quot))
715 {
716 denom *= abs (lc (g));
717 recombination= true;
718 result.append (g (y-eval,y));
719 if (b.getp() != 0)
720 {
721 denQuot= bCommonDen (quot);
722 buf= quot*denQuot;
724 denom /= gcd (denom, denQuot);
725 On (SW_RATIONAL);
726 }
727 else
728 buf= quot;
729 LCBuf= LC (buf, x)*denom;
730 T= Difference (T, S);
731 l -= degree (g);
732 M= power (y, l);
733 buf0= mulNTL (buf (0, x), LCBuf);
734 if (!isRat)
736 // compute new possible degree pattern
737 bufDegs2= DegreePattern (T);
738 bufDegs1.intersect (bufDegs2);
739 bufDegs1.refine ();
740 if (T.length() < 2*s || T.length() == s ||
741 bufDegs1.getLength() == 1)
742 {
743 delete [] v;
744 if (recombination)
745 {
746 result.append (buf (y-eval,y));
747 F= 1;
748 return result;
749 }
750 else
751 {
752 result= CFList (F (y-eval,y));
753 F= 1;
754 return result;
755 }
756 }
757 TT= copy (T);
758 indexUpdate (v, s, T.length(), nosubset);
759 if (nosubset) break;
760 }
761 if (!isRat)
763 }
764 }
765 }
766 s++;
767 if (T.length() < 2*s || T.length() == s)
768 {
769 delete [] v;
770 if (recombination)
771 {
772 result.append (buf(y-eval,y));
773 F= 1;
774 return result;
775 }
776 else
777 {
778 result= CFList (F(y-eval,y));
779 F= 1;
780 return result;
781 }
782 }
783 for (int i= 0; i < T.length(); i++)
784 v[i]= 0;
785 nosubset= false;
786 }
787 delete [] v;
788 if (T.length() < 2*s)
789 {
790 result.append (F(y-eval,y));
791 F= 1;
792 return result;
793 }
794
795 if (s > thres)
796 {
797 factors= T;
798 F= buf;
799 degs= bufDegs1;
800 }
801
802 return result;
803}
804
805#if defined(HAVE_NTL) || defined(HAVE_FLINT)
807{
808 int i=1, m= 2;
809 // extension of F_p needed
810 if (alpha.level() == 1 && beta.level() == 1 && k == 1)
811 {
812 i= 1;
813 m= 2;
814 } //extension of F_p(alpha) needed but want to factorize over F_p
815 else if (alpha.level() != 1 && beta.level() == 1 && k == 1)
816 {
817 i= 1;
818 m= degree (getMipo (alpha)) + 1;
819 } //extension of F_p(alpha) needed for first time
820 else if (alpha.level() != 1 && beta.level() == 1 && k != 1)
821 {
822 i= 2;
823 m= degree (getMipo (alpha));
824 }
825 else if (alpha.level() != 1 && beta.level() != 1 && k != 1)
826 {
827 m= degree (getMipo (beta));
828 i= degree (getMipo (alpha))/m + 1;
829 }
830 #if defined(HAVE_FLINT)
831 nmod_poly_t Irredpoly;
833 nmod_poly_randtest_monic_irreducible(Irredpoly,FLINTrandom,i*m+1);
834 CanonicalForm newMipo= convertnmod_poly_t2FacCF(Irredpoly,Variable (1));
835 #elif defined(HAVE_NTL)
837 {
839 zz_p::init (getCharacteristic());
840 }
841 zz_pX NTLIrredpoly;
842 BuildIrred (NTLIrredpoly, i*m);
843 CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));
844 #else
845 factoryError("NTL/FLINT missing: chooseExtension");
846 #endif
847 return rootOf (newMipo);
848}
849#endif
850
851void
853 factors, int& adaptedLiftBound, int*& factorsFoundIndex,
854 DegreePattern& degs, bool& success, int deg, const
856{
857 DegreePattern bufDegs1= degs;
858 DegreePattern bufDegs2;
859 CFList T= factors;
861 Variable x= Variable (1);
862 Variable y= Variable (2);
863 CanonicalForm g, quot;
864 CanonicalForm M= power (F.mvar(), deg);
865 adaptedLiftBound= 0;
866 int d= degree (F), l= 0;
867 bool isRat= (isOn (SW_RATIONAL) && getCharacteristic() == 0) ||
868 getCharacteristic() > 0;
869 if (!isRat)
870 On (SW_RATIONAL);
871 if (b.getp() != 0)
872 buf *= bCommonDen (buf);
873 CanonicalForm LCBuf= LC (buf, x)*den;
874 CanonicalForm buf0= mulNTL (buf (0,x), LCBuf);
875 CanonicalForm buf1= mulNTL (buf (1,x), LCBuf);
876 if (!isRat)
878 CanonicalForm test0, test1;
879 CanonicalForm denQuot;
880
881 for (CFListIterator i= factors; i.hasItem(); i++, l++)
882 {
883 if (!bufDegs1.find (degree (i.getItem(), 1)) || factorsFoundIndex[l] == 1)
884 continue;
885 else
886 {
887 test1= mod (mulNTL (i.getItem() (1,x), LCBuf, b), M);
888 if (uniFdivides (test1, buf1))
889 {
890 test0= mod (mulNTL (i.getItem() (0,x), LCBuf, b), M);
891 if (uniFdivides (test0, buf0))
892 {
893 if (!isRat)
894 On (SW_RATIONAL);
895 g= mulMod2 (i.getItem(), LCBuf, M);
896 if (!isRat)
897 {
898 g *= bCommonDen(g);
900 }
901 if (b.getp() != 0)
902 g= b(g);
903 if (!isRat)
904 On (SW_RATIONAL);
905 g /= content (g, x);
906 if (!isRat)
907 {
908 On (SW_RATIONAL);
909 if (!Lc (g).inBaseDomain())
910 g /= Lc (g);
911 g *= bCommonDen (g);
913 g /= icontent (g);
914 On (SW_RATIONAL);
915 }
916 if (fdivides (g, buf, quot))
917 {
918 den *= abs (lc (g));
919 reconstructedFactors.append (g (y-eval,y));
920 factorsFoundIndex[l]= 1;
921 if (b.getp() != 0)
922 {
923 denQuot= bCommonDen (quot);
924 buf= quot*denQuot;
926 den /= gcd (den, denQuot);
927 On (SW_RATIONAL);
928 }
929 else
930 buf= quot;
931 d -= degree (g);
932 LCBuf= LC (buf, x)*den;
933 buf0= mulNTL (buf (0,x), LCBuf);
934 buf1= mulNTL (buf (1,x), LCBuf);
935 if (!isRat)
937 T= Difference (T, CFList (i.getItem()));
938 F= buf;
939
940 // compute new possible degree pattern
941 bufDegs2= DegreePattern (T);
942 bufDegs1.intersect (bufDegs2);
943 bufDegs1.refine ();
944 if (bufDegs1.getLength() <= 1)
945 {
946 if (!buf.inCoeffDomain())
947 {
948 reconstructedFactors.append (buf (y-eval,y));
949 F= 1;
950 }
951 break;
952 }
953 }
954 if (!isRat)
956 }
957 }
958 }
959 }
960 adaptedLiftBound= d + 1;
961 if (adaptedLiftBound < deg)
962 {
963 degs= bufDegs1;
964 success= true;
965 }
966 if (bufDegs1.getLength() <= 1)
967 degs= bufDegs1;
968}
969
970void
972 factors, int& adaptedLiftBound, int*& factorsFoundIndex,
973 DegreePattern& degs, bool& success, int deg, const
974 CanonicalForm& eval, const modpk& b)
975{
977 earlyFactorDetection (reconstructedFactors, F, factors, adaptedLiftBound,
978 factorsFoundIndex, degs, success, deg, eval, b, den);
979}
980
981void
983 factors,int& adaptedLiftBound, int*& factorsFoundIndex,
984 DegreePattern& degs, bool& success, const
985 ExtensionInfo& info, const CanonicalForm& eval, int deg
986 )
987{
988 Variable alpha= info.getAlpha();
989 Variable beta= info.getBeta();
990 CanonicalForm gamma= info.getGamma();
991 CanonicalForm delta= info.getDelta();
992 int k= info.getGFDegree();
993 DegreePattern bufDegs1= degs, bufDegs2;
995 CFList T= factors;
996 Variable y= F.mvar();
997 Variable x= Variable (1);
998 CanonicalForm buf= F, LCBuf= LC (buf, x), g, buf2;
999 CanonicalForm M= power (y, deg);
1000 adaptedLiftBound= 0;
1001 bool trueFactor= false;
1002 int d= degree (F), l= 0;
1003 CFList source, dest;
1004 int degMipoBeta= 1;
1005 if (!k && beta.level() != 1)
1006 degMipoBeta= degree (getMipo (beta));
1007 CanonicalForm quot;
1008 for (CFListIterator i= factors; i.hasItem(); i++, l++)
1009 {
1010 if (!bufDegs1.find (degree (i.getItem(), 1)) || factorsFoundIndex[l] == 1)
1011 continue;
1012 else
1013 {
1014 g= mulMod2 (i.getItem(), LCBuf, M);
1015 g /= content (g, x);
1016 if (fdivides (g, buf, quot))
1017 {
1018 buf2= g (y - eval, y);
1019 buf2 /= Lc (buf2);
1020
1021 if (!k && beta == x)
1022 {
1023 if (degree (buf2, alpha) < degMipoBeta)
1024 {
1025 appendTestMapDown (reconstructedFactors, buf2, info, source, dest);
1026 factorsFoundIndex[l]= 1;
1027 buf= quot;
1028 d -= degree (g);
1029 LCBuf= LC (buf, x);
1030 trueFactor= true;
1031 }
1032 }
1033 else
1034 {
1035 if (!isInExtension (buf2, gamma, k, delta, source, dest))
1036 {
1037 appendTestMapDown (reconstructedFactors, buf2, info, source, dest);
1038 factorsFoundIndex[l]= 1;
1039 buf= quot;
1040 d -= degree (g);
1041 LCBuf= LC (buf, x);
1042 trueFactor= true;
1043 }
1044 }
1045 if (trueFactor)
1046 {
1047 T= Difference (T, CFList (i.getItem()));
1048 F= buf;
1049
1050 // compute new possible degree pattern
1051 bufDegs2= DegreePattern (T);
1052 bufDegs1.intersect (bufDegs2);
1053 bufDegs1.refine ();
1054 trueFactor= false;
1055 if (bufDegs1.getLength() <= 1)
1056 {
1057 if (!buf.inCoeffDomain())
1058 {
1059 buf= buf (y - eval, y);
1060 buf /= Lc (buf);
1061 appendMapDown (reconstructedFactors, buf, info, source, dest);
1062 F= 1;
1063 }
1064 break;
1065 }
1066 }
1067 }
1068 }
1069 }
1070 adaptedLiftBound= d + 1;
1071 if (adaptedLiftBound < deg)
1072 {
1073 degs= bufDegs1;
1074 success= true;
1075 }
1076 if (bufDegs1.getLength() <= 1)
1077 degs= bufDegs1;
1078}
1079
1080int*
1081getCombinations (int * rightSide, int sizeOfRightSide, int& sizeOfOutput,
1082 int degreeLC)
1083{
1084 Variable x= Variable (1);
1085 int p= getCharacteristic();
1086 int d= getGFDegree();
1087 char cGFName= gf_name;
1089 CanonicalForm buf= 1;
1090 for (int i= 0; i < sizeOfRightSide; i++)
1091 buf *= (power (x, rightSide [i]) + 1);
1092
1093 int j= 0;
1094 for (CFIterator i= buf; i.hasTerms(); i++, j++)
1095 {
1096 if (i.exp() < degreeLC)
1097 {
1098 j++;
1099 break;
1100 }
1101 }
1102
1103 ASSERT ( j > 1, "j > 1 expected" );
1104
1105 int* result = new int [j - 1];
1106 sizeOfOutput= j - 1;
1107
1108 int i= 0;
1109 for (CFIterator m = buf; i < j - 1; i++, m++)
1110 result [i]= m.exp();
1111
1112 if (d > 1)
1113 setCharacteristic (p, d, cGFName);
1114 else
1116 return result;
1117}
1118
1119int *
1120getLiftPrecisions (const CanonicalForm& F, int& sizeOfOutput, int degreeLC)
1121{
1122 int sizeOfNewtonPoly;
1123 int ** newtonPolyg= newtonPolygon (F, sizeOfNewtonPoly);
1124 int sizeOfRightSide;
1125 int * rightSide= getRightSide(newtonPolyg, sizeOfNewtonPoly, sizeOfRightSide);
1126 int * result= getCombinations(rightSide, sizeOfRightSide, sizeOfOutput,
1127 degreeLC);
1128 delete [] rightSide;
1129 for (int i= 0; i < sizeOfNewtonPoly; i++)
1130 delete [] newtonPolyg[i];
1131 delete [] newtonPolyg;
1132 return result;
1133}
1134
1135void
1136deleteFactors (CFList& factors, int* factorsFoundIndex)
1137{
1138 CFList result;
1139 int i= 0;
1140 for (CFListIterator iter= factors; iter.hasItem(); iter++, i++)
1141 {
1142 if (factorsFoundIndex[i] == 1)
1143 continue;
1144 else
1145 result.append (iter.getItem());
1146 }
1147 factors= result;
1148}
1149
1150#if defined(HAVE_NTL) || defined(HAVE_FLINT) // henselLift12
1151CFList
1153 earlyFactors, DegreePattern& degs, int& liftBound,
1154 const CFList& uniFactors, const ExtensionInfo& info,
1156{
1157 Variable alpha= info.getAlpha();
1158 Variable beta= info.getBeta();
1159 CanonicalForm gamma= info.getGamma();
1160 CanonicalForm delta= info.getDelta();
1161 bool extension= info.isInExtension();
1162
1163 int sizeOfLiftPre;
1164 int * liftPre= getLiftPrecisions (A, sizeOfLiftPre, degree (LC (A, 1), 2));
1165
1166 Variable x= Variable (1);
1167 Variable y= Variable (2);
1168 CFArray Pi;
1169 CFList diophant;
1170 CFList bufUniFactors= uniFactors;
1171 On (SW_RATIONAL);
1172 CanonicalForm bufA= A;
1173 if (!Lc (A).inBaseDomain())
1174 {
1175 bufA /= Lc (A);
1176 CanonicalForm denBufA= bCommonDen (bufA);
1177 bufA *= denBufA;
1178 Off (SW_RATIONAL);
1179 den /= gcd (den, denBufA);
1180 }
1181 else
1182 {
1183 bufA= A;
1184 Off (SW_RATIONAL);
1185 den /= gcd (den, Lc (A));
1186 }
1187 CanonicalForm lcA0= 0;
1188 bool mipoHasDen= false;
1189 if (getCharacteristic() == 0 && b.getp() != 0)
1190 {
1191 if (alpha.level() == 1)
1192 {
1193 lcA0= lc (A (0, 2));
1194 A *= b.inverse (lcA0);
1195 A= b (A);
1196 for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
1197 i.getItem()= b (i.getItem()*b.inverse (lc (i.getItem())));
1198 }
1199 else
1200 {
1201 lcA0= Lc (A (0,2));
1202 On (SW_RATIONAL);
1203 mipoHasDen= !bCommonDen(getMipo(alpha)).isOne();
1204 Off (SW_RATIONAL);
1205 CanonicalForm lcA0inverse= b.inverse (lcA0);
1206 A *= lcA0inverse;
1207 A= b (A);
1208 // Lc of bufUniFactors is in Z
1209 for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
1210 i.getItem()= b (i.getItem()*b.inverse (lc (i.getItem())));
1211 }
1212 }
1213 bufUniFactors.insert (LC (A, x));
1214 CFMatrix M= CFMatrix (liftBound, bufUniFactors.length() - 1);
1215 earlySuccess= false;
1216 int newLiftBound= 0;
1217
1218 int smallFactorDeg= tmin (11, liftPre [sizeOfLiftPre- 1] + 1);//this is a tunable parameter
1219 int dummy;
1220 int * factorsFoundIndex= new int [uniFactors.length()];
1221 for (int i= 0; i < uniFactors.length(); i++)
1222 factorsFoundIndex [i]= 0;
1223
1224 CFList bufBufUniFactors;
1225 Variable v= alpha;
1226 if (smallFactorDeg >= liftBound || degree (A,y) <= 4)
1227 henselLift12 (A, bufUniFactors, liftBound, Pi, diophant, M, b, true);
1228 else if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
1229 {
1230 henselLift12 (A, bufUniFactors, smallFactorDeg, Pi, diophant, M, b, true);
1231 if (mipoHasDen)
1232 {
1233 for (CFListIterator iter= bufUniFactors; iter.hasItem(); iter++)
1234 if (hasFirstAlgVar (iter.getItem(), v))
1235 break;
1236 if (v != alpha)
1237 {
1238 bufBufUniFactors= bufUniFactors;
1239 for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
1241 A= replacevar (A, alpha, v);
1242 }
1243 }
1244
1245 if (!extension)
1246 {
1247 if (v==alpha)
1248 earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
1249 factorsFoundIndex, degs, earlySuccess,
1250 smallFactorDeg, eval, b, den);
1251 else
1252 earlyFactorDetection(earlyFactors, bufA, bufBufUniFactors, newLiftBound,
1253 factorsFoundIndex, degs, earlySuccess,
1254 smallFactorDeg, eval, b, den);
1255 }
1256 else
1257 extEarlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
1258 factorsFoundIndex, degs, earlySuccess, info,
1259 eval, smallFactorDeg);
1260 if (degs.getLength() > 1 && !earlySuccess &&
1261 smallFactorDeg != liftPre [sizeOfLiftPre-1] + 1)
1262 {
1263 if (newLiftBound >= liftPre[sizeOfLiftPre-1]+1)
1264 {
1265 bufUniFactors.insert (LC (A, x));
1266 henselLiftResume12 (A, bufUniFactors, smallFactorDeg,
1267 liftPre[sizeOfLiftPre-1] + 1, Pi, diophant, M, b);
1268 if (v!=alpha)
1269 {
1270 bufBufUniFactors= bufUniFactors;
1271 for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
1273 }
1274 if (!extension)
1275 {
1276 if (v==alpha)
1277 earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
1278 factorsFoundIndex, degs, earlySuccess,
1279 liftPre[sizeOfLiftPre-1] + 1, eval, b, den);
1280 else
1281 earlyFactorDetection (earlyFactors,bufA,bufBufUniFactors,newLiftBound,
1282 factorsFoundIndex, degs, earlySuccess,
1283 liftPre[sizeOfLiftPre-1] + 1, eval, b, den);
1284 }
1285 else
1286 extEarlyFactorDetection (earlyFactors,bufA,bufUniFactors,newLiftBound,
1287 factorsFoundIndex, degs, earlySuccess, info,
1288 eval, liftPre[sizeOfLiftPre-1] + 1);
1289 }
1290 }
1291 else if (earlySuccess)
1292 liftBound= newLiftBound;
1293
1294 int i= sizeOfLiftPre - 1;
1295 while (degs.getLength() > 1 && !earlySuccess && i - 1 >= 0)
1296 {
1297 if (newLiftBound >= liftPre[i] + 1)
1298 {
1299 bufUniFactors.insert (LC (A, x));
1300 henselLiftResume12 (A, bufUniFactors, liftPre[i] + 1,
1301 liftPre[i-1] + 1, Pi, diophant, M, b);
1302 if (v!=alpha)
1303 {
1304 bufBufUniFactors= bufUniFactors;
1305 for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
1307 }
1308 if (!extension)
1309 {
1310 if (v==alpha)
1311 earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
1312 factorsFoundIndex, degs, earlySuccess,
1313 liftPre[i-1] + 1, eval, b, den);
1314 else
1315 earlyFactorDetection (earlyFactors,bufA,bufBufUniFactors,newLiftBound,
1316 factorsFoundIndex, degs, earlySuccess,
1317 liftPre[i-1] + 1, eval, b, den);
1318 }
1319 else
1320 extEarlyFactorDetection (earlyFactors,bufA,bufUniFactors,newLiftBound,
1321 factorsFoundIndex, degs, earlySuccess, info,
1322 eval, liftPre[i-1] + 1);
1323 }
1324 else
1325 {
1326 liftBound= newLiftBound;
1327 break;
1328 }
1329 i--;
1330 }
1331 if (earlySuccess)
1332 liftBound= newLiftBound;
1333 //after here all factors are lifted to liftPre[sizeOfLiftPre-1]
1334 }
1335 else
1336 {
1337 henselLift12 (A, bufUniFactors, smallFactorDeg, Pi, diophant, M, b, true);
1338 if (mipoHasDen)
1339 {
1340 for (CFListIterator iter= bufUniFactors; iter.hasItem(); iter++)
1341 if (hasFirstAlgVar (iter.getItem(), v))
1342 break;
1343 if (v != alpha)
1344 {
1345 bufBufUniFactors= bufUniFactors;
1346 for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
1348 A= replacevar (A, alpha, v);
1349 }
1350 }
1351 if (!extension)
1352 {
1353 if (v==alpha)
1354 earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
1355 factorsFoundIndex, degs, earlySuccess,
1356 smallFactorDeg, eval, b, den);
1357 else
1358 earlyFactorDetection (earlyFactors, bufA, bufBufUniFactors, newLiftBound,
1359 factorsFoundIndex, degs, earlySuccess,
1360 smallFactorDeg, eval, b, den);
1361 }
1362 else
1363 extEarlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
1364 factorsFoundIndex, degs, earlySuccess, info,
1365 eval, smallFactorDeg);
1366 int i= 1;
1367 while ((degree (A,y)/4)*i + 4 <= smallFactorDeg)
1368 i++;
1369 dummy= tmin (degree (A,y)+1, (degree (A,y)/4)*i+4);
1370 if (degs.getLength() > 1 && !earlySuccess && dummy > smallFactorDeg)
1371 {
1372 bufUniFactors.insert (LC (A, x));
1373 henselLiftResume12 (A, bufUniFactors, smallFactorDeg,
1374 dummy, Pi, diophant, M, b);
1375 if (v!=alpha)
1376 {
1377 bufBufUniFactors= bufUniFactors;
1378 for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
1380 }
1381 if (!extension)
1382 {
1383 if (v==alpha)
1384 earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
1385 factorsFoundIndex, degs, earlySuccess, dummy,eval,
1386 b, den);
1387 else
1388 earlyFactorDetection (earlyFactors, bufA,bufBufUniFactors, newLiftBound,
1389 factorsFoundIndex, degs, earlySuccess, dummy,eval,
1390 b, den);
1391 }
1392 else
1393 extEarlyFactorDetection (earlyFactors, bufA,bufUniFactors, newLiftBound,
1394 factorsFoundIndex, degs, earlySuccess, info,
1395 eval, dummy);
1396 }
1397 while (degs.getLength() > 1 && !earlySuccess && i < 4)
1398 {
1399 if (newLiftBound >= dummy)
1400 {
1401 bufUniFactors.insert (LC (A, x));
1402 dummy= tmin (degree (A,y)+1, (degree (A,y)/4)*(i+1)+4);
1403 henselLiftResume12 (A, bufUniFactors, (degree (A,y)/4)*i + 4,
1404 dummy, Pi, diophant, M, b);
1405 if (v!=alpha)
1406 {
1407 bufBufUniFactors= bufUniFactors;
1408 for (CFListIterator iter= bufBufUniFactors; iter.hasItem(); iter++)
1410 }
1411 if (!extension)
1412 {
1413 if (v==alpha)
1414 earlyFactorDetection (earlyFactors, bufA, bufUniFactors, newLiftBound,
1415 factorsFoundIndex, degs, earlySuccess, dummy,
1416 eval, b, den);
1417 else
1418 earlyFactorDetection (earlyFactors,bufA,bufBufUniFactors,newLiftBound,
1419 factorsFoundIndex, degs, earlySuccess, dummy,
1420 eval, b, den);
1421 }
1422 else
1423 extEarlyFactorDetection (earlyFactors,bufA,bufUniFactors,newLiftBound,
1424 factorsFoundIndex, degs, earlySuccess, info,
1425 eval, dummy);
1426 }
1427 else
1428 {
1429 liftBound= newLiftBound;
1430 break;
1431 }
1432 i++;
1433 }
1434 if (earlySuccess)
1435 liftBound= newLiftBound;
1436 }
1437
1438 A= bufA;
1439 if (earlyFactors.length() > 0 && degs.getLength() > 1)
1440 {
1441 liftBound= degree (A,y) + 1;
1442 earlySuccess= true;
1443 deleteFactors (bufUniFactors, factorsFoundIndex);
1444 }
1445
1446 delete [] factorsFoundIndex;
1447 delete [] liftPre;
1448
1449 return bufUniFactors;
1450}
1451#endif
1452
1453#ifdef HAVE_NTL // henselLiftAndEarly
1454CFList
1456 earlyFactors, DegreePattern& degs, int& liftBound,
1457 const CFList& uniFactors, const ExtensionInfo& info,
1458 const CanonicalForm& eval)
1459{
1460 modpk dummy= modpk();
1461 CanonicalForm den= 1;
1462 return henselLiftAndEarly (A, earlySuccess, earlyFactors, degs, liftBound,
1463 uniFactors, info, eval, dummy, den);
1464}
1465#endif
1466
1467#ifdef HAVE_NTL
1468long isReduced (const mat_zz_p& M)
1469{
1470 long i, j, nonZero;
1471 for (i = 1; i <= M.NumRows(); i++)
1472 {
1473 nonZero= 0;
1474 for (j = 1; j <= M.NumCols(); j++)
1475 {
1476 if (!IsZero (M (i,j)))
1477 nonZero++;
1478 }
1479 if (nonZero != 1)
1480 return 0;
1481 }
1482 return 1;
1483}
1484#endif
1485
1486#ifdef HAVE_FLINT
1487long isReduced (const nmod_mat_t M)
1488{
1489 long i, j, nonZero;
1490 for (i = 1; i <= nmod_mat_nrows(M); i++)
1491 {
1492 nonZero= 0;
1493 for (j = 1; j <= nmod_mat_ncols (M); j++)
1494 {
1495 if (!(nmod_mat_entry (M, i-1, j-1)==0))
1496 nonZero++;
1497 }
1498 if (nonZero != 1)
1499 return 0;
1500 }
1501 return 1;
1502}
1503#endif
1504
1505#ifdef HAVE_NTL
1506long isReduced (const mat_zz_pE& M)
1507{
1508 long i, j, nonZero;
1509 for (i = 1; i <= M.NumRows(); i++)
1510 {
1511 nonZero= 0;
1512 for (j = 1; j <= M.NumCols(); j++)
1513 {
1514 if (!IsZero (M (i,j)))
1515 nonZero++;
1516 }
1517 if (nonZero != 1)
1518 return 0;
1519 }
1520 return 1;
1521}
1522#endif
1523
1524#ifdef HAVE_NTL
1525int * extractZeroOneVecs (const mat_zz_p& M)
1526{
1527 long i, j;
1528 bool nonZeroOne= false;
1529 int * result= new int [M.NumCols()];
1530 for (i = 1; i <= M.NumCols(); i++)
1531 {
1532 for (j = 1; j <= M.NumRows(); j++)
1533 {
1534 if (!(IsOne (M (j,i)) || IsZero (M (j,i))))
1535 {
1536 nonZeroOne= true;
1537 break;
1538 }
1539 }
1540 if (!nonZeroOne)
1541 result [i - 1]= 1;
1542 else
1543 result [i - 1]= 0;
1544 nonZeroOne= false;
1545 }
1546 return result;
1547}
1548#endif
1549
1550#ifdef HAVE_FLINT
1551int * extractZeroOneVecs (const nmod_mat_t M)
1552{
1553 long i, j;
1554 bool nonZeroOne= false;
1555 int * result= new int [nmod_mat_ncols (M)];
1556 for (i = 0; i < nmod_mat_ncols (M); i++)
1557 {
1558 for (j = 0; j < nmod_mat_nrows (M); j++)
1559 {
1560 if (!((nmod_mat_entry (M, j, i) == 1) || (nmod_mat_entry (M, j,i) == 0)))
1561 {
1562 nonZeroOne= true;
1563 break;
1564 }
1565 }
1566 if (!nonZeroOne)
1567 result [i]= 1;
1568 else
1569 result [i]= 0;
1570 nonZeroOne= false;
1571 }
1572 return result;
1573}
1574#endif
1575
1576#ifdef HAVE_NTL
1577int * extractZeroOneVecs (const mat_zz_pE& M)
1578{
1579 long i, j;
1580 bool nonZeroOne= false;
1581 int * result= new int [M.NumCols()];
1582 for (i = 1; i <= M.NumCols(); i++)
1583 {
1584 for (j = 1; j <= M.NumRows(); j++)
1585 {
1586 if (!(IsOne (M (j,i)) || IsZero (M (j,i))))
1587 {
1588 nonZeroOne= true;
1589 break;
1590 }
1591 }
1592 if (!nonZeroOne)
1593 result [i - 1]= 1;
1594 else
1595 result [i - 1]= 0;
1596 nonZeroOne= false;
1597 }
1598 return result;
1599}
1600#endif
1601
1602#ifdef HAVE_NTL
1603void
1604reconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const CFList&
1605 factors, const int liftBound, int& factorsFound, int*&
1606 factorsFoundIndex, mat_zz_pE& N, const CanonicalForm& eval,
1607 bool beenInThres
1608 )
1609{
1610 Variable y= Variable (2);
1611 Variable x= Variable (1);
1612 CanonicalForm yToL= power (y, liftBound);
1613 CanonicalForm bufF= F (y-eval, y);
1614 if (factors.length() == 2)
1615 {
1616 CanonicalForm tmp1, tmp2, tmp3;
1617 tmp1= factors.getFirst();
1618 tmp2= factors.getLast();
1619 tmp1= mulMod2 (tmp1, LC (F,x), yToL);
1620 tmp1 /= content (tmp1, x);
1621 tmp1= tmp1 (y-eval, y);
1622 tmp2= mulMod2 (tmp2, LC (F,x), yToL);
1623 tmp2 /= content (tmp2, x);
1624 tmp2= tmp2 (y-eval, y);
1625 tmp3 = tmp1*tmp2;
1626 if (tmp3/Lc (tmp3) == bufF/Lc (bufF))
1627 {
1628 factorsFound++;
1629 F= 1;
1630 reconstructedFactors.append (tmp1);
1631 reconstructedFactors.append (tmp2);
1632 return;
1633 }
1634 }
1635 CanonicalForm quot, buf;
1637 for (long i= 1; i <= N.NumCols(); i++)
1638 {
1639 if (factorsFoundIndex [i - 1] == 1)
1640 continue;
1641 iter= factors;
1642 if (beenInThres)
1643 {
1644 int count= 1;
1645 while (count < i)
1646 {
1647 count++;
1648 iter++;
1649 }
1650 buf= iter.getItem();
1651 }
1652 else
1653 {
1654 buf= 1;
1655 for (long j= 1; j <= N.NumRows(); j++, iter++)
1656 {
1657 if (!IsZero (N (j,i)))
1658 buf= mulMod2 (buf, iter.getItem(), yToL);
1659 }
1660 }
1661 buf= mulMod2 (buf, LC (F,x), yToL);
1662 buf /= content (buf, x);
1663 buf= buf (y-eval,y);
1664 if (fdivides (buf, bufF, quot))
1665 {
1666 factorsFoundIndex[i - 1]= 1;
1667 factorsFound++;
1668 bufF= quot;
1669 bufF /= Lc (bufF);
1670 reconstructedFactors.append (buf);
1671 }
1672 if (degree (bufF) <= 0)
1673 return;
1674 if (factorsFound + 1 == N.NumCols())
1675 {
1676 reconstructedFactors.append (bufF);
1677 F= 1;
1678 return;
1679 }
1680 }
1681 if (reconstructedFactors.length() != 0)
1682 F= bufF (y+eval,y);
1683}
1684#endif
1685
1686#ifdef HAVE_NTL
1687void
1688reconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const CFList&
1689 factors, const int liftBound, int& factorsFound, int*&
1690 factorsFoundIndex, mat_zz_p& N, const CanonicalForm& eval,
1691 bool beenInThres
1692 )
1693{
1694 Variable y= Variable (2);
1695 Variable x= Variable (1);
1696 CanonicalForm yToL= power (y, liftBound);
1697 CanonicalForm bufF= F (y-eval, y);
1698 if (factors.length() == 2)
1699 {
1700 CanonicalForm tmp1, tmp2, tmp3;
1701 tmp1= factors.getFirst();
1702 tmp2= factors.getLast();
1703 tmp1= mulMod2 (tmp1, LC (F,x), yToL);
1704 tmp1 /= content (tmp1, x);
1705 tmp1= tmp1 (y-eval, y);
1706 tmp2= mulMod2 (tmp2, LC (F,x), yToL);
1707 tmp2 /= content (tmp2, x);
1708 tmp2= tmp2 (y-eval,y);
1709 tmp3 = tmp1*tmp2;
1710 if (tmp3/Lc (tmp3) == bufF/Lc (bufF))
1711 {
1712 factorsFound++;
1713 F= 1;
1714 reconstructedFactors.append (tmp1);
1715 reconstructedFactors.append (tmp2);
1716 return;
1717 }
1718 }
1719 CanonicalForm quot, buf;
1721 for (long i= 1; i <= N.NumCols(); i++)
1722 {
1723 if (factorsFoundIndex [i - 1] == 1)
1724 continue;
1725 iter= factors;
1726 if (beenInThres)
1727 {
1728 int count= 1;
1729 while (count < i)
1730 {
1731 count++;
1732 iter++;
1733 }
1734 buf= iter.getItem();
1735 }
1736 else
1737 {
1738 buf= 1;
1739 for (long j= 1; j <= N.NumRows(); j++, iter++)
1740 {
1741 if (!IsZero (N (j,i)))
1742 buf= mulMod2 (buf, iter.getItem(), yToL);
1743 }
1744 }
1745 buf= mulMod2 (buf, LC (F,x), yToL);
1746 buf /= content (buf, x);
1747 buf= buf (y-eval,y);
1748 if (fdivides (buf, bufF, quot))
1749 {
1750 factorsFoundIndex[i - 1]= 1;
1751 factorsFound++;
1752 bufF= quot;
1753 bufF /= Lc (bufF);
1754 reconstructedFactors.append (buf);
1755 }
1756 if (degree (bufF) <= 0)
1757 return;
1758 if (factorsFound + 1 == N.NumCols())
1759 {
1760 reconstructedFactors.append (bufF);
1761 F=1;
1762 return;
1763 }
1764 }
1765 if (reconstructedFactors.length() != 0)
1766 F= bufF (y+eval,y);
1767}
1768#endif
1769
1770#ifdef HAVE_FLINT
1771void
1772reconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const CFList&
1773 factors, const int liftBound, int& factorsFound, int*&
1774 factorsFoundIndex, nmod_mat_t N, const CanonicalForm& eval,
1775 bool beenInThres
1776 )
1777{
1778 Variable y= Variable (2);
1779 Variable x= Variable (1);
1780 CanonicalForm yToL= power (y, liftBound);
1781 CanonicalForm bufF= F (y-eval, y);
1782 if (factors.length() == 2)
1783 {
1784 CanonicalForm tmp1, tmp2, tmp3;
1785 tmp1= factors.getFirst();
1786 tmp2= factors.getLast();
1787 tmp1= mulMod2 (tmp1, LC (F,x), yToL);
1788 tmp1 /= content (tmp1, x);
1789 tmp1= tmp1 (y-eval, y);
1790 tmp2= mulMod2 (tmp2, LC (F,x), yToL);
1791 tmp2 /= content (tmp2, x);
1792 tmp2= tmp2 (y-eval, y);
1793 tmp3 = tmp1*tmp2;
1794 if (tmp3/Lc (tmp3) == bufF/Lc (bufF))
1795 {
1796 factorsFound++;
1797 F= 1;
1798 reconstructedFactors.append (tmp1);
1799 reconstructedFactors.append (tmp2);
1800 return;
1801 }
1802 }
1803 CanonicalForm quot, buf;
1805 for (long i= 0; i < nmod_mat_ncols (N); i++)
1806 {
1807 if (factorsFoundIndex [i] == 1)
1808 continue;
1809 iter= factors;
1810 if (beenInThres)
1811 {
1812 int count= 0;
1813 while (count < i)
1814 {
1815 count++;
1816 iter++;
1817 }
1818 buf= iter.getItem();
1819 }
1820 else
1821 {
1822 buf= 1;
1823 for (long j= 0; j < nmod_mat_nrows (N); j++, iter++)
1824 {
1825 if (!(nmod_mat_entry (N, j, i) == 0))
1826 buf= mulMod2 (buf, iter.getItem(), yToL);
1827 }
1828 }
1829 buf= mulMod2 (buf, LC (F,x), yToL);
1830 buf /= content (buf, x);
1831 buf= buf (y-eval,y);
1832 if (fdivides (buf, bufF, quot))
1833 {
1834 factorsFoundIndex[i]= 1;
1835 factorsFound++;
1836 bufF= quot;
1837 bufF /= Lc (bufF);
1838 reconstructedFactors.append (buf);
1839 }
1840 if (degree (F) <= 0)
1841 return;
1842 if (factorsFound + 1 == nmod_mat_ncols (N))
1843 {
1844 F= 1;
1845 reconstructedFactors.append (bufF);
1846 return;
1847 }
1848 }
1849 if (reconstructedFactors.length() != 0)
1850 F= bufF (y+eval,y);
1851}
1852#endif
1853
1854#ifdef HAVE_NTL
1855CFList
1856reconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs, int
1857 precision, const mat_zz_pE& N, const CanonicalForm& eval
1858 )
1859{
1860 Variable y= Variable (2);
1861 Variable x= Variable (1);
1862 CanonicalForm F= G;
1863 CanonicalForm yToL= power (y, precision);
1864 CanonicalForm quot, buf;
1865 CFList result, factorsConsidered;
1866 CFList bufFactors= factors;
1868 for (long i= 1; i <= N.NumCols(); i++)
1869 {
1870 if (zeroOneVecs [i - 1] == 0)
1871 continue;
1872 iter= factors;
1873 buf= 1;
1874 factorsConsidered= CFList();
1875 for (long j= 1; j <= N.NumRows(); j++, iter++)
1876 {
1877 if (!IsZero (N (j,i)))
1878 {
1879 factorsConsidered.append (iter.getItem());
1880 buf= mulMod2 (buf, iter.getItem(), yToL);
1881 }
1882 }
1883 buf= mulMod2 (buf, LC (F,x), yToL);
1884 buf /= content (buf, x);
1885 if (fdivides (buf, F, quot))
1886 {
1887 F= quot;
1888 F /= Lc (F);
1889 result.append (buf (y-eval,y));
1890 bufFactors= Difference (bufFactors, factorsConsidered);
1891 }
1892 if (degree (F) <= 0)
1893 {
1894 G= F;
1895 factors= bufFactors;
1896 return result;
1897 }
1898 }
1899 G= F;
1900 factors= bufFactors;
1901 return result;
1902}
1903#endif
1904
1905#ifdef HAVE_NTL
1906CFList
1907monicReconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs,
1908 int precision, const mat_zz_pE& N
1909 )
1910{
1911 Variable y= Variable (2);
1912 Variable x= Variable (1);
1913 CanonicalForm F= G;
1914 CanonicalForm yToL= power (y, precision);
1915 CanonicalForm quot, buf, buf2;
1916 CFList result;
1917 CFList bufFactors= factors;
1918 CFList factorsConsidered;
1920 for (long i= 1; i <= N.NumCols(); i++)
1921 {
1922 if (zeroOneVecs [i - 1] == 0)
1923 continue;
1924 iter= factors;
1925 buf= 1;
1926 factorsConsidered= CFList();
1927 for (long j= 1; j <= N.NumRows(); j++, iter++)
1928 {
1929 if (!IsZero (N (j,i)))
1930 {
1931 factorsConsidered.append (iter.getItem());
1932 buf= mulMod2 (buf, iter.getItem(), yToL);
1933 }
1934 }
1935 buf2= buf;
1936 buf= mulMod2 (buf, LC (F,x), yToL);
1937 buf /= content (buf, x);
1938 if (fdivides (buf, F, quot))
1939 {
1940 F= quot;
1941 F /= Lc (F);
1942 result.append (buf2);
1943 bufFactors= Difference (bufFactors, factorsConsidered);
1944 }
1945 if (degree (F) <= 0)
1946 {
1947 G= F;
1948 factors= bufFactors;
1949 return result;
1950 }
1951 }
1952 G= F;
1953 factors= bufFactors;
1954 return result;
1955}
1956#endif
1957
1958#ifdef HAVE_NTL
1959CFList
1960extReconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs, int
1961 precision, const mat_zz_p& N, const ExtensionInfo& info,
1963 )
1964{
1965 Variable y= Variable (2);
1966 Variable x= Variable (1);
1967 Variable alpha= info.getAlpha();
1968 Variable beta= info.getBeta();
1969 int k= info.getGFDegree();
1970 CanonicalForm gamma= info.getGamma();
1971 CanonicalForm delta= info.getDelta();
1972 CanonicalForm F= G;
1973 CanonicalForm yToL= power (y, precision);
1974 CFList result;
1975 CFList bufFactors= factors;
1976 CFList factorsConsidered;
1977 CanonicalForm buf2, quot, buf;
1979 for (long i= 1; i <= N.NumCols(); i++)
1980 {
1981 if (zeroOneVecs [i - 1] == 0)
1982 continue;
1983 iter= factors;
1984 buf= 1;
1985 factorsConsidered= CFList();
1986 for (long j= 1; j <= N.NumRows(); j++, iter++)
1987 {
1988 if (!IsZero (N (j,i)))
1989 {
1990 factorsConsidered.append (iter.getItem());
1991 buf= mulMod2 (buf, iter.getItem(), yToL);
1992 }
1993 }
1994 buf= mulMod2 (buf, LC (F,x), yToL);
1995 buf /= content (buf, x);
1996 buf2= buf (y-evaluation, y);
1997 buf2 /= Lc (buf2);
1998 if (!k && beta == x)
1999 {
2000 if (degree (buf2, alpha) < 1)
2001 {
2002 if (fdivides (buf, F, quot))
2003 {
2004 F= quot;
2005 F /= Lc (F);
2006 result.append (buf2);
2007 bufFactors= Difference (bufFactors, factorsConsidered);
2008 }
2009 }
2010 }
2011 else
2012 {
2013 CFList source, dest;
2014
2015 if (!isInExtension (buf2, gamma, k, delta, source, dest))
2016 {
2017 if (fdivides (buf, F, quot))
2018 {
2019 F= quot;
2020 F /= Lc (F);
2021 result.append (buf2);
2022 bufFactors= Difference (bufFactors, factorsConsidered);
2023 }
2024 }
2025 }
2026 if (degree (F) <= 0)
2027 {
2028 G= F;
2029 factors= bufFactors;
2030 return result;
2031 }
2032 }
2033 G= F;
2034 factors= bufFactors;
2035 return result;
2036}
2037#endif
2038
2039#ifdef HAVE_FLINT
2040CFList
2041extReconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs, int
2042 precision, const nmod_mat_t N, const ExtensionInfo& info,
2044 )
2045{
2046 Variable y= Variable (2);
2047 Variable x= Variable (1);
2048 Variable alpha= info.getAlpha();
2049 Variable beta= info.getBeta();
2050 int k= info.getGFDegree();
2051 CanonicalForm gamma= info.getGamma();
2052 CanonicalForm delta= info.getDelta();
2053 CanonicalForm F= G;
2054 CanonicalForm yToL= power (y, precision);
2055 CFList result;
2056 CFList bufFactors= factors;
2057 CFList factorsConsidered;
2058 CanonicalForm buf2, quot, buf;
2060 for (long i= 0; i < nmod_mat_ncols(N); i++)
2061 {
2062 if (zeroOneVecs [i] == 0)
2063 continue;
2064 iter= factors;
2065 buf= 1;
2066 factorsConsidered= CFList();
2067 for (long j= 0; j < nmod_mat_nrows(N); j++, iter++)
2068 {
2069 if (!(nmod_mat_entry (N, j, i) == 0))
2070 {
2071 factorsConsidered.append (iter.getItem());
2072 buf= mulMod2 (buf, iter.getItem(), yToL);
2073 }
2074 }
2075 buf= mulMod2 (buf, LC (F,x), yToL);
2076 buf /= content (buf, x);
2077 buf2= buf (y-evaluation, y);
2078 buf2 /= Lc (buf2);
2079 if (!k && beta == x)
2080 {
2081 if (degree (buf2, alpha) < 1)
2082 {
2083 if (fdivides (buf, F, quot))
2084 {
2085 F= quot;
2086 F /= Lc (F);
2087 result.append (buf2);
2088 bufFactors= Difference (bufFactors, factorsConsidered);
2089 }
2090 }
2091 }
2092 else
2093 {
2094 CFList source, dest;
2095
2096 if (!isInExtension (buf2, gamma, k, delta, source, dest))
2097 {
2098 if (fdivides (buf, F, quot))
2099 {
2100 F= quot;
2101 F /= Lc (F);
2102 result.append (buf2);
2103 bufFactors= Difference (bufFactors, factorsConsidered);
2104 }
2105 }
2106 }
2107 if (degree (F) <= 0)
2108 {
2109 G= F;
2110 factors= bufFactors;
2111 return result;
2112 }
2113 }
2114 G= F;
2115 factors= bufFactors;
2116 return result;
2117}
2118#endif
2119
2120#ifdef HAVE_NTL
2121CFList
2122reconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs,
2123 int precision, const mat_zz_p& N, const CanonicalForm& eval)
2124{
2125 Variable y= Variable (2);
2126 Variable x= Variable (1);
2127 CanonicalForm F= G;
2128 CanonicalForm yToL= power (y, precision);
2129 CanonicalForm quot, buf;
2130 CFList result;
2131 CFList bufFactors= factors;
2132 CFList factorsConsidered;
2134 for (long i= 1; i <= N.NumCols(); i++)
2135 {
2136 if (zeroOneVecs [i - 1] == 0)
2137 continue;
2138 iter= factors;
2139 buf= 1;
2140 factorsConsidered= CFList();
2141 for (long j= 1; j <= N.NumRows(); j++, iter++)
2142 {
2143 if (!IsZero (N (j,i)))
2144 {
2145 factorsConsidered.append (iter.getItem());
2146 buf= mulMod2 (buf, iter.getItem(), yToL);
2147 }
2148 }
2149 buf= mulMod2 (buf, LC (F,x), yToL);
2150 buf /= content (buf, x);
2151 if (fdivides (buf, F, quot))
2152 {
2153 F= quot;
2154 F /= Lc (F);
2155 result.append (buf (y-eval,y));
2156 bufFactors= Difference (bufFactors, factorsConsidered);
2157 }
2158 if (degree (F) <= 0)
2159 {
2160 G= F;
2161 factors= bufFactors;
2162 return result;
2163 }
2164 }
2165 G= F;
2166 factors= bufFactors;
2167 return result;
2168}
2169#endif
2170
2171#ifdef HAVE_FLINT
2172CFList
2173reconstruction (CanonicalForm& G, CFList& factors, int* zeroOneVecs,
2174 int precision, const nmod_mat_t N, const CanonicalForm& eval)
2175{
2176 Variable y= Variable (2);
2177 Variable x= Variable (1);
2178 CanonicalForm F= G;
2179 CanonicalForm yToL= power (y, precision);
2180 CanonicalForm quot, buf;
2181 CFList result;
2182 CFList bufFactors= factors;
2183 CFList factorsConsidered;
2185 for (long i= 0; i < nmod_mat_ncols (N); i++)
2186 {
2187 if (zeroOneVecs [i] == 0)
2188 continue;
2189 iter= factors;
2190 buf= 1;
2191 factorsConsidered= CFList();
2192 for (long j= 0; j < nmod_mat_nrows (N); j++, iter++)
2193 {
2194 if (!(nmod_mat_entry (N, j, i) == 0))
2195 {
2196 factorsConsidered.append (iter.getItem());
2197 buf= mulMod2 (buf, iter.getItem(), yToL);
2198 }
2199 }
2200 buf= mulMod2 (buf, LC (F,x), yToL);
2201 buf /= content (buf, x);
2202 if (fdivides (buf, F, quot))
2203 {
2204 F= quot;
2205 F /= Lc (F);
2206 result.append (buf (y-eval,y));
2207 bufFactors= Difference (bufFactors, factorsConsidered);
2208 }
2209 if (degree (F) <= 0)
2210 {
2211 G= F;
2212 factors= bufFactors;
2213 return result;
2214 }
2215 }
2216 G= F;
2217 factors= bufFactors;
2218 return result;
2219}
2220#endif
2221
2222#ifdef HAVE_NTL
2223void
2224extReconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const
2225 CFList& factors, const int liftBound, int& factorsFound,
2226 int*& factorsFoundIndex, mat_zz_p& N, bool beenInThres,
2228 )
2229{
2230 Variable y= Variable (2);
2231 Variable x= Variable (1);
2232 Variable alpha= info.getAlpha();
2233 Variable beta= info.getBeta();
2234 int k= info.getGFDegree();
2235 CanonicalForm gamma= info.getGamma();
2236 CanonicalForm delta= info.getDelta();
2237 CanonicalForm yToL= power (y, liftBound);
2238 CFList source, dest;
2239 if (factors.length() == 2)
2240 {
2241 CanonicalForm tmp1, tmp2, tmp3;
2242 tmp1= factors.getFirst();
2243 tmp2= factors.getLast();
2244 tmp1= mulMod2 (tmp1, LC (F,x), yToL);
2245 tmp1 /= content (tmp1, x);
2246 tmp2= mulMod2 (tmp2, LC (F,x), yToL);
2247 tmp2 /= content (tmp2, x);
2248 tmp3 = tmp1*tmp2;
2249 if (tmp3/Lc (tmp3) == F/Lc (F))
2250 {
2251 tmp1= tmp1 (y - evaluation, y);
2252 tmp2= tmp2 (y - evaluation, y);
2253 tmp1 /= Lc (tmp1);
2254 tmp2 /= Lc (tmp2);
2255 if (!k && beta == x && degree (tmp2, alpha) < 1 &&
2256 degree (tmp1, alpha) < 1)
2257 {
2258 factorsFound++;
2259 F= 1;
2260 tmp1= mapDown (tmp1, info, source, dest);
2261 tmp2= mapDown (tmp2, info, source, dest);
2262 reconstructedFactors.append (tmp1);
2263 reconstructedFactors.append (tmp2);
2264 return;
2265 }
2266 else if (!isInExtension (tmp2, gamma, k, delta, source, dest) &&
2267 !isInExtension (tmp1, gamma, k, delta, source, dest))
2268 {
2269 factorsFound++;
2270 F= 1;
2271 tmp1= mapDown (tmp1, info, source, dest);
2272 tmp2= mapDown (tmp2, info, source, dest);
2273 reconstructedFactors.append (tmp1);
2274 reconstructedFactors.append (tmp2);
2275 return;
2276 }
2277 }
2278 }
2279 CanonicalForm quot, buf, buf2;
2281 for (long i= 1; i <= N.NumCols(); i++)
2282 {
2283 if (factorsFoundIndex [i - 1] == 1)
2284 continue;
2285 iter= factors;
2286 if (beenInThres)
2287 {
2288 int count= 1;
2289 while (count < i)
2290 {
2291 count++;
2292 iter++;
2293 }
2294 buf= iter.getItem();
2295 }
2296 else
2297 {
2298 buf= 1;
2299 for (long j= 1; j <= N.NumRows(); j++, iter++)
2300 {
2301 if (!IsZero (N (j,i)))
2302 buf= mulMod2 (buf, iter.getItem(), yToL);
2303 }
2304 }
2305 buf= mulMod2 (buf, LC (F,x), yToL);
2306 buf /= content (buf, x);
2307 buf2= buf (y - evaluation, y);
2308 buf2 /= Lc (buf2);
2309 if (!k && beta == x)
2310 {
2311 if (degree (buf2, alpha) < 1)
2312 {
2313 if (fdivides (buf, F, quot))
2314 {
2315 factorsFoundIndex[i - 1]= 1;
2316 factorsFound++;
2317 F= quot;
2318 F /= Lc (F);
2319 buf2= mapDown (buf2, info, source, dest);
2320 reconstructedFactors.append (buf2);
2321 }
2322 }
2323 }
2324 else
2325 {
2326 if (!isInExtension (buf2, gamma, k, delta, source, dest))
2327 {
2328 if (fdivides (buf, F, quot))
2329 {
2330 factorsFoundIndex[i - 1]= 1;
2331 factorsFound++;
2332 F= quot;
2333 F /= Lc (F);
2334 buf2= mapDown (buf2, info, source, dest);
2335 reconstructedFactors.append (buf2);
2336 }
2337 }
2338 }
2339 if (degree (F) <= 0)
2340 return;
2341 if (factorsFound + 1 == N.NumCols())
2342 {
2343 CanonicalForm tmp= F (y - evaluation, y);
2344 tmp= mapDown (tmp, info, source, dest);
2345 reconstructedFactors.append (tmp);
2346 return;
2347 }
2348 }
2349}
2350#endif
2351
2352#ifdef HAVE_FLINT
2353void
2354extReconstructionTry (CFList& reconstructedFactors, CanonicalForm& F, const
2355 CFList& factors, const int liftBound, int& factorsFound,
2356 int*& factorsFoundIndex, nmod_mat_t N, bool beenInThres,
2358 )
2359{
2360 Variable y= Variable (2);
2361 Variable x= Variable (1);
2362 Variable alpha= info.getAlpha();
2363 Variable beta= info.getBeta();
2364 int k= info.getGFDegree();
2365 CanonicalForm gamma= info.getGamma();
2366 CanonicalForm delta= info.getDelta();
2367 CanonicalForm yToL= power (y, liftBound);
2368 CFList source, dest;
2369 if (factors.length() == 2)
2370 {
2371 CanonicalForm tmp1, tmp2, tmp3;
2372 tmp1= factors.getFirst();
2373 tmp2= factors.getLast();
2374 tmp1= mulMod2 (tmp1, LC (F,x), yToL);
2375 tmp1 /= content (tmp1, x);
2376 tmp2= mulMod2 (tmp2, LC (F,x), yToL);
2377 tmp2 /= content (tmp2, x);
2378 tmp3 = tmp1*tmp2;
2379 if (tmp3/Lc (tmp3) == F/Lc (F))
2380 {
2381 tmp1= tmp1 (y - evaluation, y);
2382 tmp2= tmp2 (y - evaluation, y);
2383 tmp1 /= Lc (tmp1);
2384 tmp2 /= Lc (tmp2);
2385 if (!k && beta == x && degree (tmp2, alpha) < 1 &&
2386 degree (tmp1, alpha) < 1)
2387 {
2388 factorsFound++;
2389 F= 1;
2390 tmp1= mapDown (tmp1, info, source, dest);
2391 tmp2= mapDown (tmp2, info, source, dest);
2392 reconstructedFactors.append (tmp1);
2393 reconstructedFactors.append (tmp2);
2394 return;
2395 }
2396 else if (!isInExtension (tmp2, gamma, k, delta, source, dest) &&
2397 !isInExtension (tmp1, gamma, k, delta, source, dest))
2398 {
2399 factorsFound++;
2400 F= 1;
2401 tmp1= mapDown (tmp1, info, source, dest);
2402 tmp2= mapDown (tmp2, info, source, dest);
2403 reconstructedFactors.append (tmp1);
2404 reconstructedFactors.append (tmp2);
2405 return;
2406 }
2407 }
2408 }
2409 CanonicalForm quot, buf, buf2;
2411 for (long i= 0; i < nmod_mat_ncols (N); i++)
2412 {
2413 if (factorsFoundIndex [i] == 1)
2414 continue;
2415 iter= factors;
2416 if (beenInThres)
2417 {
2418 int count= 0;
2419 while (count < i)
2420 {
2421 count++;
2422 iter++;
2423 }
2424 buf= iter.getItem();
2425 }
2426 else
2427 {
2428 buf= 1;
2429 for (long j= 0; j < nmod_mat_nrows (N); j++, iter++)
2430 {
2431 if (!(nmod_mat_entry (N, j, i) == 0))
2432 buf= mulMod2 (buf, iter.getItem(), yToL);
2433 }
2434 }
2435 buf= mulMod2 (buf, LC (F,x), yToL);
2436 buf /= content (buf, x);
2437 buf2= buf (y - evaluation, y);
2438 buf2 /= Lc (buf2);
2439 if (!k && beta == x)
2440 {
2441 if (degree (buf2, alpha) < 1)
2442 {
2443 if (fdivides (buf, F, quot))
2444 {
2445 factorsFoundIndex[i]= 1;
2446 factorsFound++;
2447 F= quot;
2448 F /= Lc (F);
2449 buf2= mapDown (buf2, info, source, dest);
2450 reconstructedFactors.append (buf2);
2451 }
2452 }
2453 }
2454 else
2455 {
2456 if (!isInExtension (buf2, gamma, k, delta, source, dest))
2457 {
2458 if (fdivides (buf, F, quot))
2459 {
2460 factorsFoundIndex[i]= 1;
2461 factorsFound++;
2462 F= quot;
2463 F /= Lc (F);
2464 buf2= mapDown (buf2, info, source, dest);
2465 reconstructedFactors.append (buf2);
2466 }
2467 }
2468 }
2469 if (degree (F) <= 0)
2470 return;
2471 if (factorsFound + 1 == nmod_mat_nrows (N))
2472 {
2473 CanonicalForm tmp= F (y - evaluation, y);
2474 tmp= mapDown (tmp, info, source, dest);
2475 reconstructedFactors.append (tmp);
2476 return;
2477 }
2478 }
2479}
2480#endif
2481
2482#ifdef HAVE_NTL
2483//over Fp
2484int
2485liftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds, int
2486 start, int liftBound, int minBound, CFList& factors,
2487 mat_zz_p& NTLN, CFList& diophant, CFMatrix& M, CFArray&
2488 Pi, CFArray& bufQ, bool& irreducible
2489 )
2490{
2491 CanonicalForm LCF= LC (F, 1);
2492 CFArray *A= new CFArray [factors.length() - 1];
2493 bool wasInBounds= false;
2494 bool hitBound= false;
2495 int l= (minBound+1)*2;
2496 int stepSize= 2;
2497 int oldL= l/2;
2498 bool reduced= false;
2499 mat_zz_p NTLK, *NTLC;
2500 CFMatrix C;
2501 CFArray buf;
2503 CanonicalForm truncF;
2504 Variable y= F.mvar();
2505 while (l <= liftBound)
2506 {
2507 TIMING_START (fac_fq_compute_lattice_lift);
2508 if (start)
2509 {
2510 henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
2511 start= 0;
2512 }
2513 else
2514 {
2515 if (wasInBounds)
2516 henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
2517 else
2518 henselLift12 (F, factors, l, Pi, diophant, M);
2519 }
2520 TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
2521 "time to lift in compute lattice: ");
2522
2523 factors.insert (LCF);
2524 j= factors;
2525 j++;
2526
2527 truncF= mod (F, power (y, l));
2528 TIMING_START (fac_fq_logarithmic);
2529 for (int i= 0; i < factors.length() - 1; i++, j++)
2530 {
2531 if (!wasInBounds)
2532 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
2533 else
2534 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
2535 bufQ[i]);
2536 }
2537 TIMING_END_AND_PRINT (fac_fq_logarithmic,
2538 "time to compute logarithmic derivative: ");
2539
2540 for (int i= 0; i < sizeBounds; i++)
2541 {
2542 if (bounds [i] + 1 <= l/2)
2543 {
2544 wasInBounds= true;
2545 int k= tmin (bounds [i] + 1, l/2);
2546 C= CFMatrix (l - k, factors.length() - 1);
2547 for (int ii= 0; ii < factors.length() - 1; ii++)
2548 {
2549 if (A[ii].size() - 1 >= i)
2550 {
2551 buf= getCoeffs (A[ii] [i], k);
2552 writeInMatrix (C, buf, ii + 1, 0);
2553 }
2554 }
2556 NTLK= (*NTLC)*NTLN;
2557 transpose (NTLK, NTLK);
2558 kernel (NTLK, NTLK);
2559 transpose (NTLK, NTLK);
2560 NTLN *= NTLK;
2561 delete NTLC;
2562
2563 if (NTLN.NumCols() == 1)
2564 {
2565 irreducible= true;
2566 break;
2567 }
2568 if (isReduced (NTLN) && l > (minBound+1)*2)
2569 {
2570 reduced= true;
2571 break;
2572 }
2573 }
2574 }
2575
2576 if (irreducible)
2577 break;
2578 if (reduced)
2579 break;
2580 oldL= l;
2581 l += stepSize;
2582 stepSize *= 2;
2583 if (l > liftBound)
2584 {
2585 if (!hitBound)
2586 {
2587 l= liftBound;
2588 hitBound= true;
2589 }
2590 else
2591 break;
2592 }
2593 }
2594 delete [] A;
2595 if (!wasInBounds)
2596 {
2597 if (start)
2598 henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
2599 else
2600 henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
2601 factors.insert (LCF);
2602 }
2603 return l;
2604}
2605#endif
2606
2607#ifdef HAVE_FLINT
2608#ifdef HAVE_NTL // henselLift12
2609int
2610liftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds, int
2611 start, int liftBound, int minBound, CFList& factors,
2612 nmod_mat_t FLINTN, CFList& diophant, CFMatrix& M,CFArray&
2613 Pi, CFArray& bufQ, bool& irreducible
2614 )
2615{
2616 CanonicalForm LCF= LC (F, 1);
2617 CFArray *A= new CFArray [factors.length() - 1];
2618 bool wasInBounds= false;
2619 bool hitBound= false;
2620 int l= (minBound+1)*2;
2621 int stepSize= 2;
2622 int oldL= l/2;
2623 bool reduced= false;
2624 long rank;
2625 nmod_mat_t FLINTK, FLINTC, null;
2626 CFMatrix C;
2627 CFArray buf;
2629 CanonicalForm truncF;
2630 Variable y= F.mvar();
2631 while (l <= liftBound)
2632 {
2633 TIMING_START (fac_fq_compute_lattice_lift);
2634 if (start)
2635 {
2636 henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
2637 start= 0;
2638 }
2639 else
2640 {
2641 if (wasInBounds)
2642 henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
2643 else
2644 henselLift12 (F, factors, l, Pi, diophant, M);
2645 }
2646 TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
2647 "time to lift in compute lattice: ");
2648
2649 factors.insert (LCF);
2650 j= factors;
2651 j++;
2652
2653 truncF= mod (F, power (y, l));
2654 TIMING_START (fac_fq_logarithmic);
2655 for (int i= 0; i < factors.length() - 1; i++, j++)
2656 {
2657 if (!wasInBounds)
2658 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
2659 else
2660 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
2661 bufQ[i]);
2662 }
2663 TIMING_END_AND_PRINT (fac_fq_logarithmic,
2664 "time to compute logarithmic derivative: ");
2665
2666 for (int i= 0; i < sizeBounds; i++)
2667 {
2668 if (bounds [i] + 1 <= l/2)
2669 {
2670 wasInBounds= true;
2671 int k= tmin (bounds [i] + 1, l/2);
2672 C= CFMatrix (l - k, factors.length() - 1);
2673 for (int ii= 0; ii < factors.length() - 1; ii++)
2674 {
2675 if (A[ii].size() - 1 >= i)
2676 {
2677 buf= getCoeffs (A[ii] [i], k);
2678 writeInMatrix (C, buf, ii + 1, 0);
2679 }
2680 }
2681
2683 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
2685 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
2686 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
2688 rank= nmod_mat_nullspace (null, FLINTK);
2689 nmod_mat_clear (FLINTK);
2690 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
2691 nmod_mat_clear (FLINTC);
2692 nmod_mat_init_set (FLINTC, FLINTN);
2693 nmod_mat_clear (FLINTN);
2694 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
2696 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
2697
2698 nmod_mat_clear (FLINTC);
2699 nmod_mat_window_clear (FLINTK);
2700 nmod_mat_clear (null);
2701 if (nmod_mat_ncols (FLINTN) == 1)
2702 {
2703 irreducible= true;
2704 break;
2705 }
2706 if (isReduced (FLINTN) && l > (minBound+1)*2)
2707 {
2708 reduced= true;
2709 break;
2710 }
2711 }
2712 }
2713
2714 if (irreducible)
2715 break;
2716 if (reduced)
2717 break;
2718 oldL= l;
2719 l += stepSize;
2720 stepSize *= 2;
2721 if (l > liftBound)
2722 {
2723 if (!hitBound)
2724 {
2725 l= liftBound;
2726 hitBound= true;
2727 }
2728 else
2729 break;
2730 }
2731 }
2732 delete [] A;
2733 if (!wasInBounds)
2734 {
2735 if (start)
2736 henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
2737 else
2738 henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
2739 factors.insert (LCF);
2740 }
2741 return l;
2742}
2743#endif
2744#endif
2745
2746#ifdef HAVE_NTL
2747//over field extension
2748int
2749extLiftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds,
2750 int liftBound, int minBound, int start, CFList&
2751 factors, mat_zz_p& NTLN, CFList& diophant,
2752 CFMatrix& M, CFArray& Pi, CFArray& bufQ, bool&
2753 irreducible, const CanonicalForm& evaluation, const
2754 ExtensionInfo& info, CFList& source, CFList& dest
2755 )
2756{
2758 CanonicalForm LCF= LC (F, 1);
2759 CFArray *A= new CFArray [factors.length() - 1];
2760 bool wasInBounds= false;
2761 bool hitBound= false;
2762 int degMipo;
2764 alpha= info.getAlpha();
2765 degMipo= degree (getMipo (alpha));
2766
2767 Variable gamma= info.getBeta();
2768 CanonicalForm primElemAlpha= info.getGamma();
2769 CanonicalForm imPrimElemAlpha= info.getDelta();
2770
2771 int stepSize= 2;
2772 int l= ((minBound+1)/degMipo+1)*2;
2773 l= tmax (l, 2);
2774 if (start > l)
2775 l= start;
2776 int oldL= l/2;
2777 bool reduced= false;
2778 Variable y= F.mvar();
2779 Variable x= Variable (1);
2780 CanonicalForm powX, imBasis, truncF;
2781 CFMatrix Mat, C;
2782 CFArray buf;
2784 mat_zz_p* NTLMat, *NTLC, NTLK;
2786 while (l <= liftBound)
2787 {
2788 TIMING_START (fac_fq_compute_lattice_lift);
2789 if (start)
2790 {
2791 henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
2792 start= 0;
2793 }
2794 else
2795 {
2796 if (wasInBounds)
2797 henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
2798 else
2799 henselLift12 (F, factors, l, Pi, diophant, M);
2800 }
2801 TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
2802 "time to lift in compute lattice: ");
2803
2804 factors.insert (LCF);
2805
2806 if (GF)
2808
2809 powX= power (y-gamma, l);
2810 Mat= CFMatrix (l*degMipo, l*degMipo);
2811 for (int i= 0; i < l*degMipo; i++)
2812 {
2813 imBasis= mod (power (y, i), powX);
2814 imBasis= imBasis (power (y, degMipo), y);
2815 imBasis= imBasis (y, gamma);
2816 iter= imBasis;
2817 for (; iter.hasTerms(); iter++)
2818 Mat (iter.exp()+ 1, i+1)= iter.coeff();
2819 }
2820
2821 NTLMat= convertFacCFMatrix2NTLmat_zz_p (Mat);
2822 *NTLMat= inv (*NTLMat);
2823
2824 if (GF)
2825 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
2826
2827 j= factors;
2828 j++;
2829
2830 truncF= mod (F, power (y, l));
2831 TIMING_START (fac_fq_logarithmic);
2832 for (int i= 0; i < factors.length() - 1; i++, j++)
2833 {
2834 if (!wasInBounds)
2835 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
2836 else
2837 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
2838 bufQ[i]);
2839 }
2840 TIMING_END_AND_PRINT (fac_fq_logarithmic,
2841 "time to compute logarithmic derivative: ");
2842
2843 for (int i= 0; i < sizeBounds; i++)
2844 {
2845 if (bounds [i] + 1 <= (l/2)*degMipo)
2846 {
2847 wasInBounds= true;
2848 int k= tmin (bounds [i] + 1, (l/2)*degMipo);
2849 C= CFMatrix (l*degMipo - k, factors.length() - 1);
2850
2851 for (int ii= 0; ii < factors.length() - 1; ii++)
2852 {
2853 if (A[ii].size() - 1 >= i)
2854 {
2855 if (GF)
2856 {
2857 A [ii] [i]= A [ii] [i] (y-evaluation, y);
2859 A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
2860 if (alpha != gamma)
2861 A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
2862 gamma, source, dest
2863 );
2864 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
2865 }
2866 else
2867 {
2868 A [ii] [i]= A [ii] [i] (y-evaluation, y);
2869 if (alpha != gamma)
2870 A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
2871 gamma, source, dest
2872 );
2873 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
2874 }
2875 writeInMatrix (C, buf, ii + 1, 0);
2876 }
2877 if (GF)
2878 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
2879 }
2880
2881 if (GF)
2883
2885 NTLK= (*NTLC)*NTLN;
2886 transpose (NTLK, NTLK);
2887 kernel (NTLK, NTLK);
2888 transpose (NTLK, NTLK);
2889 NTLN *= NTLK;
2890 delete NTLC;
2891
2892 if (GF)
2893 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
2894
2895 if (NTLN.NumCols() == 1)
2896 {
2897 irreducible= true;
2898 break;
2899 }
2900 if (isReduced (NTLN))
2901 {
2902 reduced= true;
2903 break;
2904 }
2905 }
2906 }
2907
2908 delete NTLMat;
2909
2910 if (NTLN.NumCols() == 1)
2911 {
2912 irreducible= true;
2913 break;
2914 }
2915 if (reduced)
2916 break;
2917 oldL= l;
2918 l += stepSize;
2919 stepSize *= 2;
2920 if (l > liftBound)
2921 {
2922 if (!hitBound)
2923 {
2924 l= liftBound;
2925 hitBound= true;
2926 }
2927 else
2928 break;
2929 }
2930 }
2931 delete [] A;
2932 if (!wasInBounds)
2933 {
2934 if (start)
2935 henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
2936 else
2937 henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
2938 factors.insert (LCF);
2939 }
2940 return l;
2941}
2942#endif
2943
2944#ifdef HAVE_FLINT
2945#ifdef HAVE_NTL // henselLift12
2946//over field extension
2947int
2948extLiftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds,
2949 int liftBound, int minBound, int start, CFList&
2950 factors, nmod_mat_t FLINTN, CFList& diophant,
2951 CFMatrix& M, CFArray& Pi, CFArray& bufQ, bool&
2952 irreducible, const CanonicalForm& evaluation, const
2953 ExtensionInfo& info, CFList& source, CFList& dest
2954 )
2955{
2957 CanonicalForm LCF= LC (F, 1);
2958 CFArray *A= new CFArray [factors.length() - 1];
2959 bool wasInBounds= false;
2960 bool hitBound= false;
2961 int degMipo;
2963 alpha= info.getAlpha();
2964 degMipo= degree (getMipo (alpha));
2965
2966 Variable gamma= info.getBeta();
2967 CanonicalForm primElemAlpha= info.getGamma();
2968 CanonicalForm imPrimElemAlpha= info.getDelta();
2969
2970 int stepSize= 2;
2971 int l= ((minBound+1)/degMipo+1)*2;
2972 l= tmax (l, 2);
2973 if (start > l)
2974 l= start;
2975 int oldL= l/2;
2976 bool reduced= false;
2977 Variable y= F.mvar();
2978 Variable x= Variable (1);
2979 CanonicalForm powX, imBasis, truncF;
2980 CFMatrix Mat, C;
2981 CFArray buf;
2983 long rank;
2984 nmod_mat_t FLINTMat, FLINTMatInv, FLINTC, FLINTK, null;
2986 while (l <= liftBound)
2987 {
2988 if (start)
2989 {
2990 henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
2991 start= 0;
2992 }
2993 else
2994 {
2995 if (wasInBounds)
2996 henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
2997 else
2998 henselLift12 (F, factors, l, Pi, diophant, M);
2999 }
3000
3001 factors.insert (LCF);
3002
3003 if (GF)
3005
3006 powX= power (y-gamma, l);
3007 Mat= CFMatrix (l*degMipo, l*degMipo);
3008 for (int i= 0; i < l*degMipo; i++)
3009 {
3010 imBasis= mod (power (y, i), powX);
3011 imBasis= imBasis (power (y, degMipo), y);
3012 imBasis= imBasis (y, gamma);
3013 iter= imBasis;
3014 for (; iter.hasTerms(); iter++)
3015 Mat (iter.exp()+ 1, i+1)= iter.coeff();
3016 }
3017
3018 convertFacCFMatrix2nmod_mat_t (FLINTMat, Mat);
3019 nmod_mat_init (FLINTMatInv, nmod_mat_nrows (FLINTMat),
3020 nmod_mat_nrows (FLINTMat), getCharacteristic());
3021 nmod_mat_inv (FLINTMatInv, FLINTMat);
3022
3023 if (GF)
3024 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
3025
3026 j= factors;
3027 j++;
3028
3029 truncF= mod (F, power (y, l));
3030 for (int i= 0; i < factors.length() - 1; i++, j++)
3031 {
3032 if (!wasInBounds)
3033 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
3034 else
3035 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
3036 bufQ[i]);
3037 }
3038
3039 for (int i= 0; i < sizeBounds; i++)
3040 {
3041 if (bounds [i] + 1 <= (l/2)*degMipo)
3042 {
3043 wasInBounds= true;
3044 int k= tmin (bounds [i] + 1, (l/2)*degMipo);
3045 C= CFMatrix (l*degMipo - k, factors.length() - 1);
3046
3047 for (int ii= 0; ii < factors.length() - 1; ii++)
3048 {
3049 if (A[ii].size() - 1 >= i)
3050 {
3051 if (GF)
3052 {
3053 A [ii] [i]= A [ii] [i] (y-evaluation, y);
3055 A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
3056 if (alpha != gamma)
3057 A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
3058 gamma, source, dest
3059 );
3060 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
3061 }
3062 else
3063 {
3064 A [ii] [i]= A [ii] [i] (y-evaluation, y);
3065 if (alpha != gamma)
3066 A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
3067 gamma, source, dest
3068 );
3069 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
3070 }
3071 writeInMatrix (C, buf, ii + 1, 0);
3072 }
3073 if (GF)
3074 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
3075 }
3076
3077 if (GF)
3079
3081 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
3083 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
3084 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
3086 rank= nmod_mat_nullspace (null, FLINTK);
3087 nmod_mat_clear (FLINTK);
3088 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
3089 nmod_mat_clear (FLINTC);
3090 nmod_mat_init_set (FLINTC, FLINTN);
3091 nmod_mat_clear (FLINTN);
3092 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
3094 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
3095
3096 nmod_mat_clear (FLINTC);
3097 nmod_mat_window_clear (FLINTK);
3098 nmod_mat_clear (null);
3099
3100 if (GF)
3101 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
3102
3103 if (nmod_mat_ncols (FLINTN) == 1)
3104 {
3105 irreducible= true;
3106 break;
3107 }
3108 if (isReduced (FLINTN))
3109 {
3110 reduced= true;
3111 break;
3112 }
3113 }
3114 }
3115
3116 nmod_mat_clear (FLINTMat);
3117 nmod_mat_clear (FLINTMatInv);
3118
3119 if (nmod_mat_ncols (FLINTN) == 1)
3120 {
3121 irreducible= true;
3122 break;
3123 }
3124 if (reduced)
3125 break;
3126 oldL= l;
3127 l += stepSize;
3128 stepSize *= 2;
3129 if (l > liftBound)
3130 {
3131 if (!hitBound)
3132 {
3133 l= liftBound;
3134 hitBound= true;
3135 }
3136 else
3137 break;
3138 }
3139 }
3140 delete [] A;
3141 if (!wasInBounds)
3142 {
3143 if (start)
3144 henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
3145 else
3146 henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
3147 factors.insert (LCF);
3148 }
3149 return l;
3150}
3151#endif
3152#endif
3153
3154// over Fq
3155#ifdef HAVE_NTL
3156int
3157liftAndComputeLattice (const CanonicalForm& F, int* bounds, int sizeBounds,
3158 int start, int liftBound, int minBound, CFList& factors,
3159 mat_zz_pE& NTLN, CFList& diophant, CFMatrix& M, CFArray&
3160 Pi, CFArray& bufQ, bool& irreducible
3161 )
3162{
3163 CanonicalForm LCF= LC (F, 1);
3164 CFArray *A= new CFArray [factors.length() - 1];
3165 bool wasInBounds= false;
3166 bool hitBound= false;
3167 int l= (minBound+1)*2;
3168 int stepSize= 2;
3169 int oldL= l/2;
3170 bool reduced= false;
3172 mat_zz_pE* NTLC, NTLK;
3173 CFArray buf;
3174 CFMatrix C;
3175 Variable y= F.mvar();
3176 CanonicalForm truncF;
3177 while (l <= liftBound)
3178 {
3179 TIMING_START (fac_fq_compute_lattice_lift);
3180 if (start)
3181 {
3182 henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
3183 start= 0;
3184 }
3185 else
3186 {
3187 if (wasInBounds)
3188 henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
3189 else
3190 henselLift12 (F, factors, l, Pi, diophant, M);
3191 }
3192 TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
3193 "time to lift in compute lattice: ");
3194
3195 factors.insert (LCF);
3196 j= factors;
3197 j++;
3198
3199 truncF= mod (F, power (y,l));
3200 TIMING_START (fac_fq_logarithmic);
3201 for (int i= 0; i < factors.length() - 1; i++, j++)
3202 {
3203 if (l == (minBound+1)*2)
3204 {
3205 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
3206 }
3207 else
3208 {
3209 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
3210 bufQ[i]
3211 );
3212 }
3213 }
3214 TIMING_END_AND_PRINT (fac_fq_logarithmic,
3215 "time to compute logarithmic derivative: ");
3216
3217 for (int i= 0; i < sizeBounds; i++)
3218 {
3219 if (bounds [i] + 1 <= l/2)
3220 {
3221 wasInBounds= true;
3222 int k= tmin (bounds [i] + 1, l/2);
3223 C= CFMatrix (l - k, factors.length() - 1);
3224 for (int ii= 0; ii < factors.length() - 1; ii++)
3225 {
3226
3227 if (A[ii].size() - 1 >= i)
3228 {
3229 buf= getCoeffs (A[ii] [i], k);
3230 writeInMatrix (C, buf, ii + 1, 0);
3231 }
3232 }
3233
3235 NTLK= (*NTLC)*NTLN;
3236 transpose (NTLK, NTLK);
3237 kernel (NTLK, NTLK);
3238 transpose (NTLK, NTLK);
3239 NTLN *= NTLK;
3240 delete NTLC;
3241
3242 if (NTLN.NumCols() == 1)
3243 {
3244 irreducible= true;
3245 break;
3246 }
3247 if (isReduced (NTLN) && l > (minBound+1)*2)
3248 {
3249 reduced= true;
3250 break;
3251 }
3252 }
3253 }
3254
3255 if (NTLN.NumCols() == 1)
3256 {
3257 irreducible= true;
3258 break;
3259 }
3260 if (reduced)
3261 break;
3262 oldL= l;
3263 l += stepSize;
3264 stepSize *= 2;
3265 if (l > liftBound)
3266 {
3267 if (!hitBound)
3268 {
3269 l= liftBound;
3270 hitBound= true;
3271 }
3272 else
3273 break;
3274 }
3275 }
3276 delete [] A;
3277 if (!wasInBounds)
3278 {
3279 if (start)
3280 henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
3281 else
3282 henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
3283 factors.insert (LCF);
3284 }
3285 return l;
3286}
3287#endif
3288
3289#ifdef HAVE_NTL // henselLift12
3290#ifdef HAVE_FLINT
3291int
3292liftAndComputeLatticeFq2Fp (const CanonicalForm& F, int* bounds, int sizeBounds,
3293 int start, int liftBound, int minBound, CFList&
3294 factors, nmod_mat_t FLINTN, CFList& diophant,
3295 CFMatrix& M, CFArray& Pi, CFArray& bufQ, bool&
3296 irreducible, const Variable& alpha
3297 )
3298#else
3299int
3300liftAndComputeLatticeFq2Fp (const CanonicalForm& F, int* bounds, int sizeBounds,
3301 int start, int liftBound, int minBound, CFList&
3302 factors, mat_zz_p& NTLN, CFList& diophant, CFMatrix&
3303 M, CFArray& Pi, CFArray& bufQ, bool& irreducible,
3304 const Variable& alpha
3305 )
3306#endif
3307{
3308 CanonicalForm LCF= LC (F, 1);
3309 CFArray *A= new CFArray [factors.length() - 1];
3310 bool wasInBounds= false;
3311 int l= (minBound+1)*2;
3312 int oldL= l/2;
3313 int stepSize= 2;
3314 bool hitBound= false;
3315 int extensionDeg= degree (getMipo (alpha));
3316 bool reduced= false;
3318 CFMatrix C;
3319 CFArray buf;
3320#ifdef HAVE_FLINT
3321 long rank;
3322 nmod_mat_t FLINTC, FLINTK, null;
3323#else
3324 mat_zz_p* NTLC, NTLK;
3325#endif
3326 Variable y= F.mvar();
3327 CanonicalForm truncF;
3328 while (l <= liftBound)
3329 {
3330 TIMING_START (fac_fq_compute_lattice_lift);
3331 if (start)
3332 {
3333 henselLiftResume12 (F, factors, start, l, Pi, diophant, M);
3334 start= 0;
3335 }
3336 else
3337 {
3338 if (wasInBounds)
3339 henselLiftResume12 (F, factors, oldL, l, Pi, diophant, M);
3340 else
3341 henselLift12 (F, factors, l, Pi, diophant, M);
3342 }
3343 TIMING_END_AND_PRINT (fac_fq_compute_lattice_lift,
3344 "time to lift in compute lattice: ");
3345
3346 factors.insert (LCF);
3347 j= factors;
3348 j++;
3349
3350 truncF= mod (F, power (y,l));
3351 TIMING_START (fac_fq_logarithmic);
3352 for (int i= 0; i < factors.length() - 1; i++, j++)
3353 {
3354 if (l == (minBound+1)*2)
3355 {
3356 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ[i]);
3357 }
3358 else
3359 {
3360 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
3361 bufQ[i]
3362 );
3363 }
3364 }
3365 TIMING_END_AND_PRINT (fac_fq_logarithmic,
3366 "time to compute logarithmic derivative: ");
3367
3368 for (int i= 0; i < sizeBounds; i++)
3369 {
3370 if (bounds [i] + 1 <= l/2)
3371 {
3372 wasInBounds= true;
3373 int k= tmin (bounds [i] + 1, l/2);
3374 C= CFMatrix ((l - k)*extensionDeg, factors.length() - 1);
3375 for (int ii= 0; ii < factors.length() - 1; ii++)
3376 {
3377 if (A[ii].size() - 1 >= i)
3378 {
3379 buf= getCoeffs (A[ii] [i], k, alpha);
3380 writeInMatrix (C, buf, ii + 1, 0);
3381 }
3382 }
3383
3384#ifdef HAVE_FLINT
3386 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
3388 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
3389 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
3391 rank= nmod_mat_nullspace (null, FLINTK);
3392 nmod_mat_clear (FLINTK);
3393 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
3394 nmod_mat_clear (FLINTC);
3395 nmod_mat_init_set (FLINTC, FLINTN);
3396 nmod_mat_clear (FLINTN);
3397 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
3399 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
3400
3401 nmod_mat_clear (FLINTC);
3402 nmod_mat_window_clear (FLINTK);
3403 nmod_mat_clear (null);
3404#else
3406 NTLK= (*NTLC)*NTLN;
3407 transpose (NTLK, NTLK);
3408 kernel (NTLK, NTLK);
3409 transpose (NTLK, NTLK);
3410 NTLN *= NTLK;
3411 delete NTLC;
3412#endif
3413
3414#ifdef HAVE_FLINT
3415 if (nmod_mat_nrows (FLINTN) == 1)
3416#else
3417 if (NTLN.NumCols() == 1)
3418#endif
3419 {
3420 irreducible= true;
3421 break;
3422 }
3423#ifdef HAVE_FLINT
3424 if (isReduced (FLINTN) && l > (minBound+1)*2)
3425#else
3426 if (isReduced (NTLN) && l > (minBound+1)*2)
3427#endif
3428 {
3429 reduced= true;
3430 break;
3431 }
3432 }
3433 }
3434
3435#ifdef HAVE_FLINT
3436 if (nmod_mat_ncols (FLINTN) == 1)
3437#else
3438 if (NTLN.NumCols() == 1)
3439#endif
3440 {
3441 irreducible= true;
3442 break;
3443 }
3444 if (reduced)
3445 break;
3446 oldL= l;
3447 l += stepSize;
3448 stepSize *= 2;
3449 if (l > liftBound)
3450 {
3451 if (!hitBound)
3452 {
3453 l= liftBound;
3454 hitBound= true;
3455 }
3456 else
3457 break;
3458 }
3459 }
3460 delete [] A;
3461 if (!wasInBounds)
3462 {
3463 if (start)
3464 henselLiftResume12 (F, factors, start, degree (F) + 1, Pi, diophant, M);
3465 else
3466 henselLift12 (F, factors, degree (F) + 1, Pi, diophant, M);
3467 factors.insert (LCF);
3468 }
3469 return l;
3470}
3471#endif
3472
3473#ifdef HAVE_NTL // logarithmicDerivative
3474CFList
3475increasePrecision (CanonicalForm& F, CFList& factors, int factorsFound,
3476 int oldNumCols, int oldL, int precision,
3477 const CanonicalForm& eval
3478 )
3479{
3480 int d;
3481 bool isIrreducible= false;
3482 int* bounds= computeBounds (F, d, isIrreducible);
3483 Variable y= F.mvar();
3484 if (isIrreducible)
3485 {
3486 delete [] bounds;
3487 CanonicalForm G= F;
3488 F= 1;
3489 return CFList (G (y-eval, y));
3490 }
3491 CFArray * A= new CFArray [factors.length()];
3492 CFArray bufQ= CFArray (factors.length());
3493#ifdef HAVE_FLINT
3494 nmod_mat_t FLINTN;
3495 nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
3496 for (long i=factors.length()-1; i >= 0; i--)
3497 nmod_mat_entry (FLINTN, i, i)= 1;
3498#else
3499 mat_zz_p NTLN;
3500 ident (NTLN, factors.length());
3501#endif
3502 int minBound= bounds[0];
3503 for (int i= 1; i < d; i++)
3504 {
3505 if (bounds[i] != 0)
3506 minBound= tmin (minBound, bounds[i]);
3507 }
3508 int l= tmax (2*(minBound + 1), oldL);
3509 int oldL2= l/2;
3510 int stepSize= 2;
3511 bool useOldQs= false;
3512 bool hitBound= false;
3514 CFMatrix C;
3515 CFArray buf;
3516#ifdef HAVE_FLINT
3517 long rank;
3518 nmod_mat_t FLINTC, FLINTK, null;
3519#else
3520 mat_zz_p* NTLC, NTLK;
3521#endif
3522 CanonicalForm truncF;
3523 while (l <= precision)
3524 {
3525 j= factors;
3526 truncF= mod (F, power (y,l));
3527 if (useOldQs)
3528 {
3529 for (int i= 0; i < factors.length(); i++, j++)
3530 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL2, bufQ[i],
3531 bufQ[i]
3532 );
3533 }
3534 else
3535 {
3536 for (int i= 0; i < factors.length(); i++, j++)
3537 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
3538 }
3539 useOldQs= true;
3540 for (int i= 0; i < d; i++)
3541 {
3542 if (bounds [i] + 1 <= l/2)
3543 {
3544 int k= tmin (bounds [i] + 1, l/2);
3545 C= CFMatrix (l - k, factors.length());
3546 for (int ii= 0; ii < factors.length(); ii++)
3547 {
3548 if (A[ii].size() - 1 >= i)
3549 {
3550 buf= getCoeffs (A[ii] [i], k);
3551 writeInMatrix (C, buf, ii + 1, 0);
3552 }
3553 }
3554#ifdef HAVE_FLINT
3556 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
3558 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
3559 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
3561 rank= nmod_mat_nullspace (null, FLINTK);
3562 nmod_mat_clear (FLINTK);
3563 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
3564 nmod_mat_clear (FLINTC);
3565 nmod_mat_init_set (FLINTC, FLINTN);
3566 nmod_mat_clear (FLINTN);
3567 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
3569 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
3570
3571 nmod_mat_clear (FLINTC);
3572 nmod_mat_window_clear (FLINTK);
3573 nmod_mat_clear (null);
3574#else
3576 NTLK= (*NTLC)*NTLN;
3577 transpose (NTLK, NTLK);
3578 kernel (NTLK, NTLK);
3579 transpose (NTLK, NTLK);
3580 NTLN *= NTLK;
3581 delete NTLC;
3582#endif
3583#ifdef HAVE_FLINT
3584 if (nmod_mat_ncols (FLINTN) == 1)
3585 {
3586 nmod_mat_clear (FLINTN);
3587#else
3588 if (NTLN.NumCols() == 1)
3589 {
3590#endif
3591 delete [] A;
3592 delete [] bounds;
3593 CanonicalForm G= F;
3594 F= 1;
3595 return CFList (G (y-eval,y));
3596 }
3597 }
3598 }
3599
3600#ifdef HAVE_FLINT
3601 if (nmod_mat_ncols (FLINTN) < oldNumCols - factorsFound)
3602 {
3603 if (isReduced (FLINTN))
3604 {
3605 int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
3606 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
3607#else
3608 if (NTLN.NumCols() < oldNumCols - factorsFound)
3609 {
3610 if (isReduced (NTLN))
3611 {
3612 int * factorsFoundIndex= new int [NTLN.NumCols()];
3613 for (long i= 0; i < NTLN.NumCols(); i++)
3614#endif
3615 factorsFoundIndex[i]= 0;
3616 int factorsFound2= 0;
3617 CFList result;
3618 CanonicalForm bufF= F;
3619#ifdef HAVE_FLINT
3620 reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
3621 factorsFoundIndex, FLINTN, eval, false
3622 );
3623 if (result.length() == nmod_mat_ncols (FLINTN))
3624 {
3625 nmod_mat_clear (FLINTN);
3626#else
3627 reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
3628 factorsFoundIndex, NTLN, eval, false
3629 );
3630 if (result.length() == NTLN.NumCols())
3631 {
3632#endif
3633 delete [] factorsFoundIndex;
3634 delete [] A;
3635 delete [] bounds;
3636 F= 1;
3637 return result;
3638 }
3639 delete [] factorsFoundIndex;
3640 }
3641 else if (l == precision)
3642 {
3643 CanonicalForm bufF= F;
3644#ifdef HAVE_FLINT
3645 int * zeroOne= extractZeroOneVecs (FLINTN);
3646 CFList result= reconstruction (bufF,factors,zeroOne,precision,FLINTN, eval);
3647 nmod_mat_clear (FLINTN);
3648#else
3649 int * zeroOne= extractZeroOneVecs (NTLN);
3650 CFList result= reconstruction (bufF, factors, zeroOne, precision, NTLN, eval);
3651#endif
3652 F= bufF;
3653 delete [] zeroOne;
3654 delete [] A;
3655 delete [] bounds;
3656 return result;
3657 }
3658 }
3659 oldL2= l;
3660 l += stepSize;
3661 stepSize *= 2;
3662 if (l > precision)
3663 {
3664 if (!hitBound)
3665 {
3666 l= precision;
3667 hitBound= true;
3668 }
3669 else
3670 break;
3671 }
3672 }
3673#ifdef HAVE_FLINT
3674 nmod_mat_clear (FLINTN);
3675#endif
3676 delete [] bounds;
3677 delete [] A;
3678 return CFList();
3679}
3680#endif
3681
3682#ifdef HAVE_NTL // mat_zz_pE
3683CFList
3684increasePrecision (CanonicalForm& F, CFList& factors, int factorsFound,
3685 int oldNumCols, int oldL, const Variable&,
3686 int precision, const CanonicalForm& eval
3687 )
3688{
3689 int d;
3690 bool isIrreducible= false;
3691 Variable y= F.mvar();
3692 int* bounds= computeBounds (F, d, isIrreducible);
3693 if (isIrreducible)
3694 {
3695 delete [] bounds;
3696 CanonicalForm G= F;
3697 F= 1;
3698 return CFList (G (y-eval,y));
3699 }
3700 CFArray * A= new CFArray [factors.length()];
3701 CFArray bufQ= CFArray (factors.length());
3702 mat_zz_pE NTLN;
3703 ident (NTLN, factors.length());
3704 int minBound= bounds[0];
3705 for (int i= 1; i < d; i++)
3706 {
3707 if (bounds[i] != 0)
3708 minBound= tmin (minBound, bounds[i]);
3709 }
3710 int l= tmax (2*(minBound + 1), oldL);
3711 int oldL2= l/2;
3712 int stepSize= 2;
3713 bool useOldQs= false;
3714 bool hitBound= false;
3716 CFMatrix C;
3717 mat_zz_pE* NTLC, NTLK;
3718 CFArray buf;
3719 CanonicalForm truncF;
3720 while (l <= precision)
3721 {
3722 j= factors;
3723 truncF= mod (F, power (y,l));
3724 if (useOldQs)
3725 {
3726 for (int i= 0; i < factors.length(); i++, j++)
3727 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL2, bufQ[i],
3728 bufQ[i]
3729 );
3730 }
3731 else
3732 {
3733 for (int i= 0; i < factors.length(); i++, j++)
3734 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
3735 }
3736 useOldQs= true;
3737 for (int i= 0; i < d; i++)
3738 {
3739 if (bounds [i] + 1 <= l/2)
3740 {
3741 int k= tmin (bounds [i] + 1, l/2);
3742 C= CFMatrix (l - k, factors.length());
3743 for (int ii= 0; ii < factors.length(); ii++)
3744 {
3745 if (A[ii].size() - 1 >= i)
3746 {
3747 buf= getCoeffs (A[ii] [i], k);
3748 writeInMatrix (C, buf, ii + 1, 0);
3749 }
3750 }
3752 NTLK= (*NTLC)*NTLN;
3753 transpose (NTLK, NTLK);
3754 kernel (NTLK, NTLK);
3755 transpose (NTLK, NTLK);
3756 NTLN *= NTLK;
3757 delete NTLC;
3758 if (NTLN.NumCols() == 1)
3759 {
3760 delete [] A;
3761 delete [] bounds;
3762 CanonicalForm G= F;
3763 F= 1;
3764 return CFList (G (y-eval,y));
3765 }
3766 }
3767 }
3768
3769 if (NTLN.NumCols() < oldNumCols - factorsFound)
3770 {
3771 if (isReduced (NTLN))
3772 {
3773 int * factorsFoundIndex= new int [NTLN.NumCols()];
3774 for (long i= 0; i < NTLN.NumCols(); i++)
3775 factorsFoundIndex[i]= 0;
3776 int factorsFound2= 0;
3777 CFList result;
3778 CanonicalForm bufF= F;
3779 reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
3780 factorsFoundIndex, NTLN, eval, false);
3781 if (result.length() == NTLN.NumCols())
3782 {
3783 delete [] factorsFoundIndex;
3784 delete [] A;
3785 delete [] bounds;
3786 F= 1;
3787 return result;
3788 }
3789 delete [] factorsFoundIndex;
3790 }
3791 else if (l == precision)
3792 {
3793 CanonicalForm bufF= F;
3794 int * zeroOne= extractZeroOneVecs (NTLN);
3795 CFList result= reconstruction (bufF, factors, zeroOne, precision, NTLN, eval);
3796 F= bufF;
3797 delete [] zeroOne;
3798 delete [] A;
3799 delete [] bounds;
3800 return result;
3801 }
3802 }
3803 oldL2= l;
3804 l += stepSize;
3805 stepSize *= 2;
3806 if (l > precision)
3807 {
3808 if (!hitBound)
3809 {
3810 l= precision;
3811 hitBound= true;
3812 }
3813 else
3814 break;
3815 }
3816 }
3817 delete [] bounds;
3818 delete [] A;
3819 return CFList();
3820}
3821#endif
3822
3823#ifdef HAVE_NTL // logarithmicDerivative
3824//over field extension
3825CFList
3826extIncreasePrecision (CanonicalForm& F, CFList& factors, int factorsFound,
3827 int oldNumCols, int oldL, const CanonicalForm& evaluation,
3828 const ExtensionInfo& info, CFList& source, CFList& dest,
3829 int precision
3830 )
3831{
3833 int degMipo= degree (getMipo (info.getAlpha()));
3834 Variable alpha= info.getAlpha();
3835 int d;
3836 bool isIrreducible= false;
3837 int* bounds= computeBounds (F, d, isIrreducible);
3838 if (isIrreducible)
3839 {
3840 delete [] bounds;
3841 Variable y= Variable (2);
3842 CanonicalForm tmp= F (y - evaluation, y);
3843 CFList source, dest;
3844 tmp= mapDown (tmp, info, source, dest);
3845 F= 1;
3846 return CFList (tmp);
3847 }
3848
3849 CFArray * A= new CFArray [factors.length()];
3850 CFArray bufQ= CFArray (factors.length());
3851#ifdef HAVE_FLINT
3852 nmod_mat_t FLINTN;
3853 nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
3854 for (long i=factors.length()-1; i >= 0; i--)
3855 nmod_mat_entry (FLINTN, i, i)= 1;
3856#else
3858 {
3860 zz_p::init (getCharacteristic());
3861 }
3862 mat_zz_p NTLN;
3863 ident (NTLN, factors.length());
3864#endif
3865 int minBound= bounds[0];
3866 for (int i= 1; i < d; i++)
3867 {
3868 if (bounds[i] != 0)
3869 minBound= tmin (minBound, bounds[i]);
3870 }
3871 int l= tmax (oldL, 2*((minBound+1)/degMipo+1));
3872 int oldL2= l/2;
3873 int stepSize= 2;
3874 bool useOldQs= false;
3875 bool hitBound= false;
3876 Variable gamma= info.getBeta();
3877 CanonicalForm primElemAlpha= info.getGamma();
3878 CanonicalForm imPrimElemAlpha= info.getDelta();
3880 Variable y= F.mvar();
3881 CanonicalForm powX, imBasis, truncF;
3882 CFMatrix Mat, C;
3884#ifdef HAVE_FLINT
3885 long rank;
3886 nmod_mat_t FLINTMat, FLINTMatInv, FLINTC, FLINTK, null;
3887#else
3888 mat_zz_p* NTLMat,*NTLC, NTLK;
3889#endif
3890 CFArray buf;
3891 while (l <= precision)
3892 {
3893 j= factors;
3894 if (GF)
3896 powX= power (y-gamma, l);
3897 Mat= CFMatrix (l*degMipo, l*degMipo);
3898 for (int i= 0; i < l*degMipo; i++)
3899 {
3900 imBasis= mod (power (y, i), powX);
3901 imBasis= imBasis (power (y, degMipo), y);
3902 imBasis= imBasis (y, gamma);
3903 iter= imBasis;
3904 for (; iter.hasTerms(); iter++)
3905 Mat (iter.exp()+ 1, i+1)= iter.coeff();
3906 }
3907
3908#ifdef HAVE_FLINT
3909 convertFacCFMatrix2nmod_mat_t (FLINTMat, Mat);
3910 nmod_mat_init (FLINTMatInv, nmod_mat_nrows (FLINTMat),
3911 nmod_mat_nrows (FLINTMat), getCharacteristic());
3912 nmod_mat_inv (FLINTMatInv, FLINTMat);
3913#else
3914 NTLMat= convertFacCFMatrix2NTLmat_zz_p (Mat);
3915 *NTLMat= inv (*NTLMat);
3916#endif
3917
3918 if (GF)
3919 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
3920
3921 truncF= mod (F, power (y, l));
3922 if (useOldQs)
3923 {
3924 for (int i= 0; i < factors.length(); i++, j++)
3925 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL2, bufQ[i],
3926 bufQ[i]
3927 );
3928 }
3929 else
3930 {
3931 for (int i= 0; i < factors.length(); i++, j++)
3932 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
3933 }
3934 useOldQs= true;
3935 for (int i= 0; i < d; i++)
3936 {
3937 if (bounds [i] + 1 <= (l/2)*degMipo)
3938 {
3939 int k= tmin (bounds [i] + 1, (l/2)*degMipo);
3940 C= CFMatrix (l*degMipo - k, factors.length());
3941 for (int ii= 0; ii < factors.length(); ii++)
3942 {
3943 if (A[ii].size() - 1 >= i)
3944 {
3945 if (GF)
3946 {
3947 A[ii] [i]= A [ii] [i] (y-evaluation, y);
3949 A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
3950 if (alpha != gamma)
3951 A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
3952 gamma, source, dest
3953 );
3954#ifdef HAVE_FLINT
3955 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
3956#else
3957 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
3958#endif
3959 }
3960 else
3961 {
3962 A [ii] [i]= A [ii] [i] (y-evaluation, y);
3963 if (alpha != gamma)
3964 A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
3965 gamma, source, dest
3966 );
3967#ifdef HAVE_FLINT
3968 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
3969#else
3970 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
3971#endif
3972 }
3973 writeInMatrix (C, buf, ii + 1, 0);
3974 }
3975 if (GF)
3976 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
3977 }
3978
3979 if (GF)
3981
3982#ifdef HAVE_FLINT
3984 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
3986 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
3987 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
3989 rank= nmod_mat_nullspace (null, FLINTK);
3990 nmod_mat_clear (FLINTK);
3991 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
3992 nmod_mat_clear (FLINTC);
3993 nmod_mat_init_set (FLINTC, FLINTN);
3994 nmod_mat_clear (FLINTN);
3995 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
3997 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
3998
3999 nmod_mat_clear (FLINTC);
4000 nmod_mat_window_clear (FLINTK);
4001 nmod_mat_clear (null);
4002#else
4004 NTLK= (*NTLC)*NTLN;
4005 transpose (NTLK, NTLK);
4006 kernel (NTLK, NTLK);
4007 transpose (NTLK, NTLK);
4008 NTLN *= NTLK;
4009 delete NTLC;
4010#endif
4011
4012 if (GF)
4013 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
4014
4015#ifdef HAVE_FLINT
4016 if (nmod_mat_ncols (FLINTN) == 1)
4017 {
4018 nmod_mat_clear (FLINTMat);
4019 nmod_mat_clear (FLINTMatInv);
4020 nmod_mat_clear (FLINTN);
4021#else
4022 if (NTLN.NumCols() == 1)
4023 {
4024 delete NTLMat;
4025#endif
4026 Variable y= Variable (2);
4027 CanonicalForm tmp= F (y - evaluation, y);
4028 CFList source, dest;
4029 tmp= mapDown (tmp, info, source, dest);
4030 delete [] A;
4031 delete [] bounds;
4032 F= 1;
4033 return CFList (tmp);
4034 }
4035 }
4036 }
4037
4038#ifdef HAVE_FLINT
4039 nmod_mat_clear (FLINTMat);
4040 nmod_mat_clear (FLINTMatInv);
4041#else
4042 delete NTLMat;
4043#endif
4044
4045#ifdef HAVE_FLINT
4046 if (nmod_mat_ncols (FLINTN) < oldNumCols - factorsFound)
4047 {
4048 if (isReduced (FLINTN))
4049 {
4050 int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
4051 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
4052#else
4053 if (NTLN.NumCols() < oldNumCols - factorsFound)
4054 {
4055 if (isReduced (NTLN))
4056 {
4057 int * factorsFoundIndex= new int [NTLN.NumCols()];
4058 for (long i= 0; i < NTLN.NumCols(); i++)
4059#endif
4060 factorsFoundIndex[i]= 0;
4061 int factorsFound2= 0;
4062 CFList result;
4063 CanonicalForm bufF= F;
4064#ifdef HAVE_FLINT
4065 extReconstructionTry (result, bufF, factors,degree (F)+1, factorsFound2,
4066 factorsFoundIndex, FLINTN, false, info, evaluation
4067 );
4068 if (result.length() == nmod_mat_ncols (FLINTN))
4069 {
4070 nmod_mat_clear (FLINTN);
4071#else
4072 extReconstructionTry (result, bufF, factors,degree (F)+1, factorsFound2,
4073 factorsFoundIndex, NTLN, false, info, evaluation
4074 );
4075 if (result.length() == NTLN.NumCols())
4076 {
4077#endif
4078 delete [] factorsFoundIndex;
4079 delete [] A;
4080 delete [] bounds;
4081 F= 1;
4082 return result;
4083 }
4084 delete [] factorsFoundIndex;
4085 }
4086 else if (l == precision)
4087 {
4088 CanonicalForm bufF= F;
4089#ifdef HAVE_FLINT
4090 int * zeroOne= extractZeroOneVecs (FLINTN);
4091 CFList result= extReconstruction (bufF, factors, zeroOne, precision,
4092 FLINTN, info, evaluation
4093 );
4094 nmod_mat_clear (FLINTN);
4095#else
4096 int * zeroOne= extractZeroOneVecs (NTLN);
4097 CFList result= extReconstruction (bufF, factors, zeroOne, precision,
4098 NTLN, info, evaluation
4099 );
4100#endif
4101 F= bufF;
4102 delete [] zeroOne;
4103 delete [] A;
4104 delete [] bounds;
4105 return result;
4106 }
4107 }
4108 oldL2= l;
4109 l += stepSize;
4110 stepSize *= 2;
4111 if (l > precision)
4112 {
4113 if (!hitBound)
4114 {
4115 hitBound= true;
4116 l= precision;
4117 }
4118 else
4119 break;
4120 }
4121 }
4122
4123#ifdef HAVE_FLINT
4124 nmod_mat_clear (FLINTN);
4125#endif
4126 delete [] bounds;
4127 delete [] A;
4128 return CFList();
4129}
4130#endif
4131
4132#ifdef HAVE_NTL // mat_zz_pE
4133CFList
4135 const Variable& alpha, int precision)
4136{
4137 int d;
4138 bool isIrreducible= false;
4139 int* bounds= computeBounds (F, d, isIrreducible);
4140 if (isIrreducible)
4141 {
4142 delete [] bounds;
4143 return CFList (F);
4144 }
4145 CFArray * A= new CFArray [factors.length()];
4146 CFArray bufQ= CFArray (factors.length());
4148 {
4150 zz_p::init (getCharacteristic());
4151 }
4152 zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
4153 zz_pE::init (NTLMipo);
4154 mat_zz_pE NTLN;
4155 ident (NTLN, factors.length());
4156 int minBound= bounds[0];
4157 for (int i= 1; i < d; i++)
4158 {
4159 if (bounds[i] != 0)
4160 minBound= tmin (minBound, bounds[i]);
4161 }
4162 int l= tmin (2*(minBound + 1), precision);
4163 int oldL= l/2;
4164 int stepSize= 2;
4165 bool useOldQs= false;
4166 bool hitBound= false;
4168 CFMatrix C;
4169 CFArray buf;
4170 mat_zz_pE* NTLC, NTLK;
4171 Variable y= F.mvar();
4172 CanonicalForm truncF;
4173 while (l <= precision)
4174 {
4175 j= factors;
4176 truncF= mod (F, power (y, l));
4177 if (useOldQs)
4178 {
4179 for (int i= 0; i < factors.length(); i++, j++)
4180 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i], bufQ[i]);
4181 }
4182 else
4183 {
4184 for (int i= 0; i < factors.length(); i++, j++)
4185 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
4186 }
4187 useOldQs= true;
4188 for (int i= 0; i < d; i++)
4189 {
4190 if (bounds [i] + 1 <= l/2)
4191 {
4192 int k= tmin (bounds [i] + 1, l/2);
4193 C= CFMatrix (l - k, factors.length());
4194 for (int ii= 0; ii < factors.length(); ii++)
4195 {
4196 if (A[ii].size() - 1 >= i)
4197 {
4198 buf= getCoeffs (A[ii] [i], k);
4199 writeInMatrix (C, buf, ii + 1, 0);
4200 }
4201 }
4203 NTLK= (*NTLC)*NTLN;
4204 transpose (NTLK, NTLK);
4205 kernel (NTLK, NTLK);
4206 transpose (NTLK, NTLK);
4207 NTLN *= NTLK;
4208 delete NTLC;
4209
4210 if (NTLN.NumCols() == 1)
4211 {
4212 delete [] A;
4213 delete [] bounds;
4214 return CFList (F);
4215 }
4216 }
4217 }
4218
4219 if (isReduced (NTLN) || l == precision)
4220 {
4221 CanonicalForm bufF= F;
4222 int * zeroOne= extractZeroOneVecs (NTLN);
4223 CFList bufFactors= factors;
4224 CFList result= monicReconstruction (bufF, factors, zeroOne, precision,
4225 NTLN
4226 );
4227 if (result.length() != NTLN.NumCols() && l != precision)
4228 factors= bufFactors;
4229 if (result.length() == NTLN.NumCols())
4230 {
4231 delete [] zeroOne;
4232 delete [] A;
4233 delete [] bounds;
4234 return result;
4235 }
4236 if (l == precision)
4237 {
4238 delete [] zeroOne;
4239 delete [] A;
4240 delete [] bounds;
4241 return Union (result, factors);
4242 }
4243 delete [] zeroOne;
4244 }
4245 oldL= l;
4246 l += stepSize;
4247 stepSize *= 2;
4248 if (l > precision)
4249 {
4250 if (!hitBound)
4251 {
4252 l= precision;
4253 hitBound= true;
4254 }
4255 else
4256 break;
4257 }
4258 }
4259 delete [] bounds;
4260 delete [] A;
4261 return CFList();
4262}
4263#endif
4264
4265#ifdef HAVE_NTL // logarithmicDerivative
4266CFList
4267increasePrecisionFq2Fp (CanonicalForm& F, CFList& factors, int factorsFound,
4268 int oldNumCols, int oldL, const Variable& alpha,
4269 int precision, const CanonicalForm& eval
4270 )
4271{
4272 int d;
4273 bool isIrreducible= false;
4274 Variable y= F.mvar();
4275 int* bounds= computeBounds (F, d, isIrreducible);
4276 if (isIrreducible)
4277 {
4278 delete [] bounds;
4279 CanonicalForm G= F;
4280 F= 1;
4281 return CFList (G (y-eval,y));
4282 }
4283 int extensionDeg= degree (getMipo (alpha));
4284 CFArray * A= new CFArray [factors.length()];
4285 CFArray bufQ= CFArray (factors.length());
4286#ifdef HAVE_FLINT
4287 nmod_mat_t FLINTN;
4288 nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
4289 for (long i=factors.length()-1; i >= 0; i--)
4290 nmod_mat_entry (FLINTN, i, i)= 1;
4291#else
4292 mat_zz_p NTLN;
4293 ident (NTLN, factors.length());
4294#endif
4295 int minBound= bounds[0];
4296 for (int i= 1; i < d; i++)
4297 {
4298 if (bounds[i] != 0)
4299 minBound= tmin (minBound, bounds[i]);
4300 }
4301 int l= tmax (2*(minBound + 1), oldL);
4302 int oldL2= l/2;
4303 int stepSize= 2;
4304 bool useOldQs= false;
4305 bool hitBound= false;
4307 CFMatrix C;
4308#ifdef HAVE_FLINT
4309 long rank;
4310 nmod_mat_t FLINTC, FLINTK, null;
4311#else
4312 mat_zz_p* NTLC, NTLK;
4313#endif
4314 CFArray buf;
4315 CanonicalForm truncF;
4316 while (l <= precision)
4317 {
4318 j= factors;
4319 truncF= mod (F, power (y, l));
4320 if (useOldQs)
4321 {
4322 for (int i= 0; i < factors.length(); i++, j++)
4323 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL2, bufQ[i],
4324 bufQ[i]
4325 );
4326 }
4327 else
4328 {
4329 for (int i= 0; i < factors.length(); i++, j++)
4330 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
4331 }
4332 useOldQs= true;
4333 for (int i= 0; i < d; i++)
4334 {
4335 if (bounds [i] + 1 <= l/2)
4336 {
4337 int k= tmin (bounds [i] + 1, l/2);
4338 C= CFMatrix ((l - k)*extensionDeg, factors.length());
4339 for (int ii= 0; ii < factors.length(); ii++)
4340 {
4341 if (A[ii].size() - 1 >= i)
4342 {
4343 buf= getCoeffs (A[ii] [i], k, alpha);
4344 writeInMatrix (C, buf, ii + 1, 0);
4345 }
4346 }
4347#ifdef HAVE_FLINT
4349 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
4351 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
4352 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
4354 rank= nmod_mat_nullspace (null, FLINTK);
4355 nmod_mat_clear (FLINTK);
4356 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
4357 nmod_mat_clear (FLINTC);
4358 nmod_mat_init_set (FLINTC, FLINTN);
4359 nmod_mat_clear (FLINTN);
4360 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
4362 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
4363
4364 nmod_mat_clear (FLINTC);
4365 nmod_mat_window_clear (FLINTK);
4366 nmod_mat_clear (null);
4367#else
4369 NTLK= (*NTLC)*NTLN;
4370 transpose (NTLK, NTLK);
4371 kernel (NTLK, NTLK);
4372 transpose (NTLK, NTLK);
4373 NTLN *= NTLK;
4374 delete NTLC;
4375#endif
4376#ifdef HAVE_FLINT
4377 if (nmod_mat_ncols (FLINTN) == 1)
4378 {
4379 nmod_mat_clear (FLINTN);
4380#else
4381 if (NTLN.NumCols() == 1)
4382 {
4383#endif
4384 delete [] A;
4385 delete [] bounds;
4386 CanonicalForm G= F;
4387 F= 1;
4388 return CFList (G (y-eval,y));
4389 }
4390 }
4391 }
4392
4393#ifdef HAVE_FLINT
4394 if (nmod_mat_ncols (FLINTN) < oldNumCols - factorsFound)
4395 {
4396 if (isReduced (FLINTN))
4397 {
4398 int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
4399 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
4400#else
4401 if (NTLN.NumCols() < oldNumCols - factorsFound)
4402 {
4403 if (isReduced (NTLN))
4404 {
4405 int * factorsFoundIndex= new int [NTLN.NumCols()];
4406 for (long i= 0; i < NTLN.NumCols(); i++)
4407#endif
4408 factorsFoundIndex[i]= 0;
4409 int factorsFound2= 0;
4410 CFList result;
4411 CanonicalForm bufF= F;
4412#ifdef HAVE_FLINT
4413 reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
4414 factorsFoundIndex, FLINTN, eval, false
4415 );
4416 if (result.length() == nmod_mat_ncols (FLINTN))
4417 {
4418 nmod_mat_clear (FLINTN);
4419#else
4420 reconstructionTry (result, bufF, factors, degree (F) + 1, factorsFound2,
4421 factorsFoundIndex, NTLN, eval, false
4422 );
4423 if (result.length() == NTLN.NumCols())
4424 {
4425#endif
4426 delete [] factorsFoundIndex;
4427 delete [] A;
4428 delete [] bounds;
4429 F= 1;
4430 return result;
4431 }
4432 delete [] factorsFoundIndex;
4433 }
4434 else if (l == precision)
4435 {
4436 CanonicalForm bufF= F;
4437#ifdef HAVE_FLINT
4438 int * zeroOne= extractZeroOneVecs (FLINTN);
4439 CFList result= reconstruction (bufF,factors,zeroOne,precision,FLINTN, eval);
4440 nmod_mat_clear (FLINTN);
4441#else
4442 int * zeroOne= extractZeroOneVecs (NTLN);
4443 CFList result= reconstruction (bufF, factors, zeroOne, precision, NTLN, eval);
4444#endif
4445 F= bufF;
4446 delete [] zeroOne;
4447 delete [] A;
4448 delete [] bounds;
4449 return result;
4450 }
4451 }
4452 oldL2= l;
4453 l += stepSize;
4454 stepSize *= 2;
4455 if (l > precision)
4456 {
4457 if (!hitBound)
4458 {
4459 hitBound= true;
4460 l= precision;
4461 }
4462 else
4463 break;
4464 }
4465 }
4466#ifdef HAVE_FLINT
4467 nmod_mat_clear (FLINTN);
4468#endif
4469 delete [] bounds;
4470 delete [] A;
4471 return CFList();
4472}
4473#endif
4474
4475#ifdef HAVE_NTL // logarithmicDerivative
4476#ifdef HAVE_FLINT
4477CFList
4478increasePrecision (CanonicalForm& F, CFList& factors, int oldL, int
4479 l, int d, int* bounds, CFArray& bufQ, nmod_mat_t FLINTN,
4480 const CanonicalForm& eval
4481 )
4482#else
4483CFList
4484increasePrecision (CanonicalForm& F, CFList& factors, int oldL, int
4485 l, int d, int* bounds, CFArray& bufQ, mat_zz_p& NTLN,
4486 const CanonicalForm& eval
4487 )
4488#endif
4489{
4490 CFList result= CFList();
4491 CFArray * A= new CFArray [factors.length()];
4492 int oldL2= oldL/2;
4493 bool hitBound= false;
4494#ifdef HAVE_FLINT
4495 if (nmod_mat_nrows (FLINTN) != factors.length()) //refined factors
4496 {
4497 nmod_mat_clear (FLINTN);
4498 nmod_mat_init(FLINTN,factors.length(),factors.length(),getCharacteristic());
4499 for (long i=factors.length()-1; i >= 0; i--)
4500 nmod_mat_entry (FLINTN, i, i)= 1;
4501 bufQ= CFArray (factors.length());
4502 }
4503#else
4504 if (NTLN.NumRows() != factors.length()) //refined factors
4505 {
4506 ident (NTLN, factors.length());
4507 bufQ= CFArray (factors.length());
4508 }
4509#endif
4510 bool useOldQs= false;
4512 CFMatrix C;
4513 CFArray buf;
4514#ifdef HAVE_FLINT
4515 long rank;
4516 nmod_mat_t FLINTC, FLINTK, null;
4517#else
4518 mat_zz_p* NTLC, NTLK;
4519#endif
4520 CanonicalForm bufF, truncF;
4521 CFList bufUniFactors;
4522 Variable y= F.mvar();
4523 while (oldL <= l)
4524 {
4525 j= factors;
4526 truncF= mod (F, power (y, oldL));
4527 if (useOldQs)
4528 {
4529 for (int i= 0; i < factors.length(); i++, j++)
4530 A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, oldL2, bufQ[i],
4531 bufQ[i]
4532 );
4533 }
4534 else
4535 {
4536 for (int i= 0; i < factors.length(); i++, j++)
4537 A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, bufQ [i]);
4538 }
4539 useOldQs= true;
4540
4541 for (int i= 0; i < d; i++)
4542 {
4543 if (bounds [i] + 1 <= oldL/2)
4544 {
4545 int k= tmin (bounds [i] + 1, oldL/2);
4546 C= CFMatrix (oldL - k, factors.length());
4547 for (int ii= 0; ii < factors.length(); ii++)
4548 {
4549 if (A[ii].size() - 1 >= i)
4550 {
4551 buf= getCoeffs (A[ii] [i], k);
4552 writeInMatrix (C, buf, ii + 1, 0);
4553 }
4554 }
4555#ifdef HAVE_FLINT
4557 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
4559 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
4560 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
4562 rank= nmod_mat_nullspace (null, FLINTK);
4563 nmod_mat_clear (FLINTK);
4564 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
4565 nmod_mat_clear (FLINTC);
4566 nmod_mat_init_set (FLINTC, FLINTN);
4567 nmod_mat_clear (FLINTN);
4568 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
4570 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
4571
4572 nmod_mat_clear (FLINTC);
4573 nmod_mat_window_clear (FLINTK);
4574 nmod_mat_clear (null);
4575#else
4577 NTLK= (*NTLC)*NTLN;
4578 transpose (NTLK, NTLK);
4579 kernel (NTLK, NTLK);
4580 transpose (NTLK, NTLK);
4581 NTLN *= NTLK;
4582 delete NTLC;
4583#endif
4584#ifdef HAVE_FLINT
4585 if (nmod_mat_ncols (FLINTN) == 1)
4586#else
4587 if (NTLN.NumCols() == 1)
4588#endif
4589 {
4590 delete [] A;
4591 return CFList (F (y-eval,y));
4592 }
4593 }
4594 }
4595#ifdef HAVE_FLINT
4596 if (nmod_mat_ncols (FLINTN) == 1)
4597#else
4598 if (NTLN.NumCols() == 1)
4599#endif
4600 {
4601 delete [] A;
4602 return CFList (F (y-eval,y));
4603 }
4604 int * zeroOneVecs;
4605#ifdef HAVE_FLINT
4606 zeroOneVecs= extractZeroOneVecs (FLINTN);
4607#else
4608 zeroOneVecs= extractZeroOneVecs (NTLN);
4609#endif
4610 bufF= F;
4611 bufUniFactors= factors;
4612#ifdef HAVE_FLINT
4613 result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, FLINTN, eval);
4614#else
4615 result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, NTLN, eval);
4616#endif
4617 delete [] zeroOneVecs;
4618 if (degree (bufF) + 1 + degree (LC (bufF, 1)) < oldL && result.length() > 0)
4619 {
4620 F= bufF;
4621 factors= bufUniFactors;
4622 delete [] A;
4623 return result;
4624 }
4625
4626 result= CFList();
4627 oldL2= oldL;
4628 oldL *= 2;
4629 if (oldL > l)
4630 {
4631 if (!hitBound)
4632 {
4633 oldL= l;
4634 hitBound= true;
4635 }
4636 else
4637 break;
4638 }
4639 }
4640 delete [] A;
4641 return result;
4642}
4643#endif
4644
4645#ifdef HAVE_NTL // mat_zz_pE
4646CFList
4647increasePrecision (CanonicalForm& F, CFList& factors, int oldL, int
4648 l, int d, int* bounds, CFArray& bufQ, mat_zz_pE& NTLN,
4649 const CanonicalForm& eval
4650 )
4651{
4652 CFList result= CFList();
4653 CFArray * A= new CFArray [factors.length()];
4654 int oldL2= oldL/2;
4655 bool hitBound= false;
4656 bool useOldQs= false;
4657 if (NTLN.NumRows() != factors.length()) //refined factors
4658 ident (NTLN, factors.length());
4660 CFMatrix C;
4661 CFArray buf;
4662 mat_zz_pE* NTLC, NTLK;
4663 CanonicalForm bufF, truncF;
4664 CFList bufUniFactors;
4665 Variable y= F.mvar();
4666 while (oldL <= l)
4667 {
4668 j= factors;
4669 truncF= mod (F, power (y, oldL));
4670 if (useOldQs)
4671 {
4672 for (int i= 0; i < factors.length(); i++, j++)
4673 A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, oldL2, bufQ[i],
4674 bufQ[i]
4675 );
4676 }
4677 else
4678 {
4679 for (int i= 0; i < factors.length(); i++, j++)
4680 A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, bufQ [i]);
4681 }
4682 useOldQs= true;
4683
4684 for (int i= 0; i < d; i++)
4685 {
4686 if (bounds [i] + 1 <= oldL/2)
4687 {
4688 int k= tmin (bounds [i] + 1, oldL/2);
4689 C= CFMatrix (oldL - k, factors.length());
4690 for (int ii= 0; ii < factors.length(); ii++)
4691 {
4692 if (A[ii].size() - 1 >= i)
4693 {
4694 buf= getCoeffs (A[ii] [i], k);
4695 writeInMatrix (C, buf, ii + 1, 0);
4696 }
4697 }
4699 NTLK= (*NTLC)*NTLN;
4700 transpose (NTLK, NTLK);
4701 kernel (NTLK, NTLK);
4702 transpose (NTLK, NTLK);
4703 NTLN *= NTLK;
4704 delete NTLC;
4705
4706 if (NTLN.NumCols() == 1)
4707 {
4708 delete [] A;
4709 return CFList (F (y-eval,y));
4710 }
4711 }
4712 }
4713 if (NTLN.NumCols() == 1)
4714 {
4715 delete [] A;
4716 return CFList (F (y-eval,y));
4717 }
4718
4719 int * zeroOneVecs;
4720 zeroOneVecs= extractZeroOneVecs (NTLN);
4721 bufF= F;
4722 bufUniFactors= factors;
4723 result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, NTLN, eval);
4724 delete [] zeroOneVecs;
4725 if (degree (bufF) + 1 + degree (LC (bufF, 1)) < l && result.length() > 0)
4726 {
4727 F= bufF;
4728 factors= bufUniFactors;
4729 delete [] A;
4730 return result;
4731 }
4732
4733 result= CFList();
4734 oldL2= oldL;
4735 oldL *= 2;
4736 if (oldL > l)
4737 {
4738 if (!hitBound)
4739 {
4740 oldL= l;
4741 hitBound= true;
4742 }
4743 else
4744 break;
4745 }
4746 }
4747 delete [] A;
4748 return result;
4749}
4750#endif
4751
4752//over field extension
4753#ifdef HAVE_NTL // logarithmicDerivative
4754#ifdef HAVE_FLINT
4755CFList
4756extIncreasePrecision (CanonicalForm& F, CFList& factors, int oldL, int l, int d,
4757 int* bounds, CFArray& bufQ, nmod_mat_t FLINTN, const
4759 CFList& source, CFList& dest
4760 )
4761#else
4762CFList
4763extIncreasePrecision (CanonicalForm& F, CFList& factors, int oldL, int l, int d,
4764 int* bounds, CFArray& bufQ, mat_zz_p& NTLN, const
4766 CFList& source, CFList& dest
4767 )
4768#endif
4769{
4770 CFList result= CFList();
4771 CFArray * A= new CFArray [factors.length()];
4772 int oldL2= oldL/2; //be careful
4773 bool hitBound= false;
4774 bool useOldQs= false;
4776 int degMipo= degree (getMipo (info.getAlpha()));
4777 Variable alpha= info.getAlpha();
4778
4779 Variable gamma= info.getBeta();
4780 CanonicalForm primElemAlpha= info.getGamma();
4781 CanonicalForm imPrimElemAlpha= info.getDelta();
4782#ifdef HAVE_FLINT
4783 nmod_mat_clear (FLINTN);
4784 nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
4785 for (long i=factors.length()-1; i >= 0; i--)
4786 nmod_mat_entry (FLINTN, i, i)= 1;
4787#else
4788 if (NTLN.NumRows() != factors.length()) //refined factors
4789 ident (NTLN, factors.length());
4790#endif
4791 Variable y= F.mvar();
4793 CanonicalForm powX, imBasis, bufF, truncF;
4794 CFMatrix Mat, C;
4796 CFArray buf;
4797#ifdef HAVE_FLINT
4798 long rank;
4799 nmod_mat_t FLINTMat, FLINTMatInv, FLINTC, FLINTK, null;
4800#else
4801 mat_zz_p* NTLC, NTLK, *NTLMat;
4802#endif
4803 CFList bufUniFactors;
4804 while (oldL <= l)
4805 {
4806 j= factors;
4807 if (GF)
4809
4810 powX= power (y-gamma, oldL);
4811 Mat= CFMatrix (oldL*degMipo, oldL*degMipo);
4812 for (int i= 0; i < oldL*degMipo; i++)
4813 {
4814 imBasis= mod (power (y, i), powX);
4815 imBasis= imBasis (power (y, degMipo), y);
4816 imBasis= imBasis (y, gamma);
4817 iter= imBasis;
4818 for (; iter.hasTerms(); iter++)
4819 Mat (iter.exp()+ 1, i+1)= iter.coeff();
4820 }
4821
4822#ifdef HAVE_FLINT
4823 convertFacCFMatrix2nmod_mat_t (FLINTMat, Mat);
4824 nmod_mat_init (FLINTMatInv, nmod_mat_nrows (FLINTMat),
4825 nmod_mat_nrows (FLINTMat), getCharacteristic());
4826 nmod_mat_inv (FLINTMatInv, FLINTMat);
4827#else
4828 NTLMat= convertFacCFMatrix2NTLmat_zz_p (Mat);
4829 *NTLMat= inv (*NTLMat);
4830#endif
4831
4832 if (GF)
4833 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
4834
4835 truncF= mod (F, power (y, oldL));
4836 if (useOldQs)
4837 {
4838 for (int i= 0; i < factors.length(); i++, j++)
4839 A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, oldL2, bufQ[i],
4840 bufQ[i]);
4841 }
4842 else
4843 {
4844 for (int i= 0; i < factors.length(); i++, j++)
4845 A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, bufQ [i]);
4846 }
4847 useOldQs= true;
4848
4849 for (int i= 0; i < d; i++)
4850 {
4851 if (bounds [i] + 1 <= oldL/2)
4852 {
4853 int k= tmin (bounds [i] + 1, oldL/2);
4854 C= CFMatrix (oldL*degMipo - k, factors.length());
4855 for (int ii= 0; ii < factors.length(); ii++)
4856 {
4857 if (A[ii].size() - 1 >= i)
4858 {
4859 if (GF)
4860 {
4861 A [ii] [i]= A [ii] [i] (y-evaluation, y);
4863 A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
4864 if (alpha != gamma)
4865 A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
4866 gamma, source, dest
4867 );
4868#ifdef HAVE_FLINT
4869 buf= getCoeffs (A[ii] [i], k, oldL, degMipo, gamma, 0, FLINTMatInv);
4870#else
4871 buf= getCoeffs (A[ii] [i], k, oldL, degMipo, gamma, 0, *NTLMat);
4872#endif
4873 }
4874 else
4875 {
4876 A [ii] [i]= A [ii] [i] (y-evaluation, y);
4877 if (alpha != gamma)
4878 A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
4879 gamma, source, dest
4880 );
4881#ifdef HAVE_FLINT
4882 buf= getCoeffs (A[ii] [i], k, oldL, degMipo, gamma, 0, FLINTMatInv);
4883#else
4884 buf= getCoeffs (A[ii] [i], k, oldL, degMipo, gamma, 0, *NTLMat);
4885#endif
4886 }
4887 writeInMatrix (C, buf, ii + 1, 0);
4888 }
4889 if (GF)
4890 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
4891 }
4892
4893 if (GF)
4895
4896#ifdef HAVE_FLINT
4898 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
4900 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
4901 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
4903 rank= nmod_mat_nullspace (null, FLINTK);
4904 nmod_mat_clear (FLINTK);
4905 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
4906 nmod_mat_clear (FLINTC);
4907 nmod_mat_init_set (FLINTC, FLINTN);
4908 nmod_mat_clear (FLINTN);
4909 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
4911 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
4912
4913 nmod_mat_clear (FLINTC);
4914 nmod_mat_window_clear (FLINTK);
4915 nmod_mat_clear (null);
4916#else
4918 NTLK= (*NTLC)*NTLN;
4919 transpose (NTLK, NTLK);
4920 kernel (NTLK, NTLK);
4921 transpose (NTLK, NTLK);
4922 NTLN *= NTLK;
4923 delete NTLC;
4924#endif
4925
4926 if (GF)
4927 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
4928
4929#ifdef HAVE_FLINT
4930 if (nmod_mat_ncols (FLINTN) == 1)
4931 {
4932 nmod_mat_clear (FLINTMat);
4933 nmod_mat_clear (FLINTMatInv);
4934#else
4935 if (NTLN.NumCols() == 1)
4936 {
4937 delete NTLMat;
4938#endif
4939 Variable y= Variable (2);
4940 CanonicalForm tmp= F (y - evaluation, y);
4941 CFList source, dest;
4942 tmp= mapDown (tmp, info, source, dest);
4943 delete [] A;
4944 return CFList (tmp);
4945 }
4946 }
4947 }
4948
4949#ifdef HAVE_FLINT
4950 nmod_mat_clear (FLINTMat);
4951 nmod_mat_clear (FLINTMatInv);
4952#else
4953 delete NTLMat;
4954#endif
4955
4956#ifdef HAVE_FLINT
4957 if (nmod_mat_ncols (FLINTN) == 1)
4958#else
4959 if (NTLN.NumCols() == 1)
4960#endif
4961 {
4962 Variable y= Variable (2);
4963 CanonicalForm tmp= F (y - evaluation, y);
4964 CFList source, dest;
4965 tmp= mapDown (tmp, info, source, dest);
4966 delete [] A;
4967 return CFList (tmp);
4968 }
4969
4970 int * zeroOneVecs;
4971 bufF= F;
4972 bufUniFactors= factors;
4973#ifdef HAVE_FLINT
4974 zeroOneVecs= extractZeroOneVecs (FLINTN);
4975 result= extReconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, FLINTN,
4977 );
4978#else
4979 zeroOneVecs= extractZeroOneVecs (NTLN);
4980 result= extReconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, NTLN,
4982 );
4983#endif
4984 delete [] zeroOneVecs;
4985 if (degree (bufF) + 1 + degree (LC (bufF, 1)) < l && result.length() > 0)
4986 {
4987 F= bufF;
4988 factors= bufUniFactors;
4989 return result;
4990 }
4991
4992 result= CFList();
4993 oldL2= oldL;
4994 oldL *= 2;
4995 if (oldL > l)
4996 {
4997 if (!hitBound)
4998 {
4999 oldL= l;
5000 hitBound= true;
5001 }
5002 else
5003 break;
5004 }
5005 }
5006 delete [] A;
5007 return result;
5008}
5009#endif
5010
5011#ifdef HAVE_NTL // logarithmicDerivative
5012#ifdef HAVE_FLINT
5013CFList
5014increasePrecisionFq2Fp (CanonicalForm& F, CFList& factors, int oldL, int l,
5015 int d, int* bounds, CFArray& bufQ, nmod_mat_t FLINTN,
5016 const Variable& alpha, const CanonicalForm& eval
5017 )
5018#else
5019CFList
5020increasePrecisionFq2Fp (CanonicalForm& F, CFList& factors, int oldL, int l,
5021 int d, int* bounds, CFArray& bufQ, mat_zz_p& NTLN,
5022 const Variable& alpha, const CanonicalForm& eval
5023 )
5024#endif
5025{
5026 CFList result= CFList();
5027 CFArray * A= new CFArray [factors.length()];
5028 int extensionDeg= degree (getMipo (alpha));
5029 int oldL2= oldL/2;
5030 bool hitBound= false;
5031 bool useOldQs= false;
5032#ifdef HAVE_FLINT
5033 if (nmod_mat_nrows (FLINTN) != factors.length()) //refined factors
5034 {
5035 nmod_mat_clear (FLINTN);
5036 nmod_mat_init(FLINTN,factors.length(),factors.length(),getCharacteristic());
5037 for (long i=factors.length()-1; i >= 0; i--)
5038 nmod_mat_entry (FLINTN, i, i)= 1;
5039 }
5040#else
5041 if (NTLN.NumRows() != factors.length()) //refined factors
5042 ident (NTLN, factors.length());
5043#endif
5045 CFMatrix C;
5046 CFArray buf;
5047#ifdef HAVE_FLINT
5048 long rank;
5049 nmod_mat_t FLINTC, FLINTK, null;
5050#else
5051 mat_zz_p* NTLC, NTLK;
5052#endif
5053 CanonicalForm bufF, truncF;
5054 CFList bufUniFactors;
5055 Variable y= F.mvar();
5056 while (oldL <= l)
5057 {
5058 j= factors;
5059 truncF= mod (F, power (y, oldL));
5060 if (useOldQs)
5061 {
5062 for (int i= 0; i < factors.length(); i++, j++)
5063 A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, oldL2, bufQ[i],
5064 bufQ[i]
5065 );
5066 }
5067 else
5068 {
5069 for (int i= 0; i < factors.length(); i++, j++)
5070 A[i]= logarithmicDerivative (truncF, j.getItem(), oldL, bufQ [i]);
5071 }
5072 useOldQs= true;
5073
5074 for (int i= 0; i < d; i++)
5075 {
5076 if (bounds [i] + 1 <= oldL/2)
5077 {
5078 int k= tmin (bounds [i] + 1, oldL/2);
5079 C= CFMatrix ((oldL - k)*extensionDeg, factors.length());
5080 for (int ii= 0; ii < factors.length(); ii++)
5081 {
5082 if (A[ii].size() - 1 >= i)
5083 {
5084 buf= getCoeffs (A[ii] [i], k, alpha);
5085 writeInMatrix (C, buf, ii + 1, 0);
5086 }
5087 }
5088#ifdef HAVE_FLINT
5090 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
5092 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
5093 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
5095 rank= nmod_mat_nullspace (null, FLINTK);
5096 nmod_mat_clear (FLINTK);
5097 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
5098 nmod_mat_clear (FLINTC);
5099 nmod_mat_init_set (FLINTC, FLINTN);
5100 nmod_mat_clear (FLINTN);
5101 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
5103 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
5104
5105 nmod_mat_clear (FLINTC);
5106 nmod_mat_window_clear (FLINTK);
5107 nmod_mat_clear (null);
5108#else
5110 NTLK= (*NTLC)*NTLN;
5111 transpose (NTLK, NTLK);
5112 kernel (NTLK, NTLK);
5113 transpose (NTLK, NTLK);
5114 NTLN *= NTLK;
5115 delete NTLC;
5116#endif
5117#ifdef HAVE_FLINT
5118 if (nmod_mat_ncols (FLINTN) == 1)
5119#else
5120 if (NTLN.NumCols() == 1)
5121#endif
5122 {
5123 delete [] A;
5124 return CFList (F(y-eval,y));
5125 }
5126 }
5127 }
5128
5129 int * zeroOneVecs;
5130#ifdef HAVE_FLINT
5131 zeroOneVecs= extractZeroOneVecs (FLINTN);
5132#else
5133 zeroOneVecs= extractZeroOneVecs (NTLN);
5134#endif
5135
5136 bufF= F;
5137 bufUniFactors= factors;
5138#ifdef HAVE_FLINT
5139 result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, FLINTN, eval);
5140#else
5141 result= reconstruction (bufF, bufUniFactors, zeroOneVecs, oldL, NTLN, eval);
5142#endif
5143 delete [] zeroOneVecs;
5144 if (degree (bufF) + 1 + degree (LC (bufF, 1)) < l && result.length() > 0)
5145 {
5146 F= bufF;
5147 factors= bufUniFactors;
5148 delete [] A;
5149 return result;
5150 }
5151
5152 result= CFList();
5153 oldL2= oldL;
5154 oldL *= 2;
5155 if (oldL > l)
5156 {
5157 if (!hitBound)
5158 {
5159 oldL= l;
5160 hitBound= true;
5161 }
5162 else
5163 break;
5164 }
5165 }
5166 delete [] A;
5167 return result;
5168}
5169#endif
5170
5171#ifdef HAVE_NTL // logarithmicDerivative
5172#ifdef HAVE_FLINT
5173CFList
5175 factors, int l, int liftBound, int d, int*
5176 bounds, nmod_mat_t FLINTN, CFList& diophant,
5177 CFMatrix& M, CFArray& Pi, CFArray& bufQ,
5178 const CanonicalForm& eval
5179 )
5180#else
5181CFList
5183 factors, int l, int liftBound, int d, int*
5184 bounds, mat_zz_p& NTLN, CFList& diophant,
5185 CFMatrix& M, CFArray& Pi, CFArray& bufQ,
5186 const CanonicalForm& eval
5187 )
5188#endif
5189{
5190 CanonicalForm LCF= LC (F, 1);
5191 CFList result;
5192 bool irreducible= false;
5193 CFList bufFactors= factors;
5194 CFList bufBufFactors;
5195 CFArray *A = new CFArray [bufFactors.length()];
5196 bool useOldQs= false;
5197 bool hitBound= false;
5198 int oldL= l;
5199 int stepSize= 8; //TODO choose better step size?
5200 l += tmax (tmin (8, degree (F) + 1 + degree (LC (F, 1))-l), 2);
5201#ifdef HAVE_FLINT
5202 if (nmod_mat_nrows (FLINTN) != factors.length()) //refined factors
5203 {
5204 nmod_mat_clear (FLINTN);
5205 nmod_mat_init(FLINTN,factors.length(),factors.length(),getCharacteristic());
5206 for (long i=factors.length()-1; i >= 0; i--)
5207 nmod_mat_entry (FLINTN, i, i)= 1;
5208 }
5209#else
5210 if (NTLN.NumRows() != factors.length()) //refined factors
5211 ident (NTLN, factors.length());
5212#endif
5214 CFMatrix C;
5215 CFArray buf;
5216#ifdef HAVE_FLINT
5217 long rank;
5218 nmod_mat_t FLINTC, FLINTK, null;
5219#else
5220 mat_zz_p* NTLC, NTLK;
5221#endif
5222 CanonicalForm bufF, truncF;
5223 Variable y= F.mvar();
5224 while (l <= liftBound)
5225 {
5226 bufFactors.insert (LCF);
5227 henselLiftResume12 (F, bufFactors, oldL, l, Pi, diophant, M);
5228 j= bufFactors;
5229 truncF= mod (F, power (y, l));
5230 if (useOldQs)
5231 {
5232 for (int i= 0; i < bufFactors.length(); i++, j++)
5233 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
5234 bufQ[i]);
5235 }
5236 else
5237 {
5238 for (int i= 0; i < bufFactors.length(); i++, j++)
5239 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
5240 }
5241 for (int i= 0; i < d; i++)
5242 {
5243 if (bounds [i] + 1 <= l/2)
5244 {
5245 int k= tmin (bounds [i] + 1, l/2);
5246 C= CFMatrix (l - k, bufFactors.length());
5247 for (int ii= 0; ii < bufFactors.length(); ii++)
5248 {
5249 if (A[ii].size() - 1 >= i)
5250 {
5251 buf= getCoeffs (A[ii] [i], k);
5252 writeInMatrix (C, buf, ii + 1, 0);
5253 }
5254 }
5255#ifdef HAVE_FLINT
5257 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
5259 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
5260 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
5262 rank= nmod_mat_nullspace (null, FLINTK);
5263 nmod_mat_clear (FLINTK);
5264 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
5265 nmod_mat_clear (FLINTC);
5266 nmod_mat_init_set (FLINTC, FLINTN);
5267 nmod_mat_clear (FLINTN);
5268 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
5270 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
5271
5272 nmod_mat_clear (FLINTC);
5273 nmod_mat_window_clear (FLINTK);
5274 nmod_mat_clear (null);
5275#else
5277 NTLK= (*NTLC)*NTLN;
5278 transpose (NTLK, NTLK);
5279 kernel (NTLK, NTLK);
5280 transpose (NTLK, NTLK);
5281 NTLN *= NTLK;
5282 delete NTLC;
5283#endif
5284#ifdef HAVE_FLINT
5285 if (nmod_mat_ncols (FLINTN) == 1)
5286#else
5287 if (NTLN.NumCols() == 1)
5288#endif
5289 {
5290 irreducible= true;
5291 break;
5292 }
5293 }
5294 }
5295
5296#ifdef HAVE_FLINT
5297 if (nmod_mat_ncols (FLINTN) == 1)
5298#else
5299 if (NTLN.NumCols() == 1)
5300#endif
5301 {
5302 irreducible= true;
5303 break;
5304 }
5305
5306#ifdef HAVE_FLINT
5307 int * zeroOneVecs= extractZeroOneVecs (FLINTN);
5308#else
5309 int * zeroOneVecs= extractZeroOneVecs (NTLN);
5310#endif
5311 bufF= F;
5312 bufBufFactors= bufFactors;
5313#ifdef HAVE_FLINT
5314 result= reconstruction (bufF, bufFactors, zeroOneVecs, l, FLINTN, eval);
5315#else
5316 result= reconstruction (bufF, bufFactors, zeroOneVecs, l, NTLN, eval);
5317#endif
5318 delete [] zeroOneVecs;
5319 if (result.length() > 0 && degree (bufF) + 1 + degree (LC (bufF, 1)) <= l)
5320 {
5321 F= bufF;
5322 factors= bufFactors;
5323 delete [] A;
5324 return result;
5325 }
5326 else
5327 {
5328 bufF= F;
5329 bufFactors= bufBufFactors;
5330 }
5331
5332#ifdef HAVE_FLINT
5333 if (isReduced (FLINTN))
5334#else
5335 if (isReduced (NTLN))
5336#endif
5337 {
5338 int factorsFound= 0;
5339 bufF= F;
5340#ifdef HAVE_FLINT
5341 int* factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
5342 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
5343#else
5344 int* factorsFoundIndex= new int [NTLN.NumCols()];
5345 for (long i= 0; i < NTLN.NumCols(); i++)
5346#endif
5347 factorsFoundIndex[i]= 0;
5348#ifdef HAVE_FLINT
5349 if (l < liftBound)
5350 reconstructionTry (result, bufF, bufFactors, l, factorsFound,
5351 factorsFoundIndex, FLINTN, eval, false
5352 );
5353 else
5354 reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
5355 degree (LCF), factorsFound, factorsFoundIndex,
5356 FLINTN, eval, false
5357 );
5358
5359 if (nmod_mat_ncols (FLINTN) == result.length())
5360#else
5361 if (l < liftBound)
5362 reconstructionTry (result, bufF, bufFactors, l, factorsFound,
5363 factorsFoundIndex, NTLN, eval, false
5364 );
5365 else
5366 reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
5367 degree (LCF), factorsFound, factorsFoundIndex,
5368 NTLN, eval, false
5369 );
5370
5371 if (NTLN.NumCols() == result.length())
5372#endif
5373 {
5374 delete [] A;
5375 delete [] factorsFoundIndex;
5376 return result;
5377 }
5378 delete [] factorsFoundIndex;
5379 }
5380 result= CFList();
5381 oldL= l;
5382 stepSize *= 2;
5383 l += stepSize;
5384 if (l > liftBound)
5385 {
5386 if (!hitBound)
5387 {
5388 l= liftBound;
5389 hitBound= true;
5390 }
5391 else
5392 break;
5393 }
5394 }
5395 if (irreducible)
5396 {
5397 delete [] A;
5398 return CFList (F (y-eval,y));
5399 }
5400 delete [] A;
5401 factors= bufFactors;
5402 return CFList();
5403}
5404#endif
5405
5406//Fq
5407#ifdef HAVE_NTL
5408CFList
5410 factors, int l, int liftBound, int d, int*
5411 bounds, mat_zz_pE& NTLN, CFList& diophant,
5412 CFMatrix& M, CFArray& Pi, CFArray& bufQ,
5413 const CanonicalForm& eval
5414 )
5415{
5416 CanonicalForm LCF= LC (F, 1);
5417 CFList result;
5418 bool irreducible= false;
5419 CFList bufFactors= factors;
5420 CFList bufBufFactors;
5421 CFArray *A = new CFArray [bufFactors.length()];
5422 bool useOldQs= false;
5423 bool hitBound= false;
5424 int oldL= l;
5425 int stepSize= 8; //TODO choose better step size?
5426 l += tmax (tmin (8, degree (F) + 1 + degree (LC (F, 1))-l), 2);
5427 if (NTLN.NumRows() != factors.length()) //refined factors
5428 ident (NTLN, factors.length());
5430 CFArray buf;
5431 mat_zz_pE* NTLC, NTLK;
5432 CanonicalForm bufF, truncF;
5433 Variable y= F.mvar();
5434 while (l <= liftBound)
5435 {
5436 bufFactors.insert (LCF);
5437 henselLiftResume12 (F, bufFactors, oldL, l, Pi, diophant, M);
5438 j= bufFactors;
5439 truncF= mod (F, power (y, l));
5440 if (useOldQs)
5441 {
5442 for (int i= 0; i < bufFactors.length(); i++, j++)
5443 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
5444 bufQ[i]);
5445 }
5446 else
5447 {
5448 for (int i= 0; i < bufFactors.length(); i++, j++)
5449 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
5450 }
5451 for (int i= 0; i < d; i++)
5452 {
5453 if (bounds [i] + 1 <= l/2)
5454 {
5455 int k= tmin (bounds [i] + 1, l/2);
5456 CFMatrix C= CFMatrix (l - k, bufFactors.length());
5457 for (int ii= 0; ii < bufFactors.length(); ii++)
5458 {
5459 if (A[ii].size() - 1 >= i)
5460 {
5461 buf= getCoeffs (A[ii] [i], k);
5462 writeInMatrix (C, buf, ii + 1, 0);
5463 }
5464 }
5466 NTLK= (*NTLC)*NTLN;
5467 transpose (NTLK, NTLK);
5468 kernel (NTLK, NTLK);
5469 transpose (NTLK, NTLK);
5470 NTLN *= NTLK;
5471 delete NTLC;
5472 if (NTLN.NumCols() == 1)
5473 {
5474 irreducible= true;
5475 break;
5476 }
5477 }
5478 }
5479 if (NTLN.NumCols() == 1)
5480 {
5481 irreducible= true;
5482 break;
5483 }
5484
5485 int * zeroOneVecs= extractZeroOneVecs (NTLN);
5486 bufF= F;
5487 bufBufFactors= bufFactors;
5488 result= reconstruction (bufF, bufFactors, zeroOneVecs, l, NTLN, eval);
5489 delete [] zeroOneVecs;
5490 if (result.length() > 0 && degree (bufF) + 1 + degree (LC (bufF, 1)) <= l)
5491 {
5492 F= bufF;
5493 factors= bufFactors;
5494 delete [] A;
5495 return result;
5496 }
5497 else
5498 {
5499 bufF= F;
5500 bufFactors= bufBufFactors;
5501 }
5502
5503 if (isReduced (NTLN))
5504 {
5505 int factorsFound= 0;
5506 bufF= F;
5507 int* factorsFoundIndex= new int [NTLN.NumCols()];
5508 for (long i= 0; i < NTLN.NumCols(); i++)
5509 factorsFoundIndex[i]= 0;
5510 if (l < liftBound)
5511 reconstructionTry (result, bufF, bufFactors, l, factorsFound,
5512 factorsFoundIndex, NTLN, eval, false
5513 );
5514 else
5515 reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
5516 degree (LCF), factorsFound, factorsFoundIndex,
5517 NTLN, eval, false
5518 );
5519 if (NTLN.NumCols() == result.length())
5520 {
5521 delete [] A;
5522 delete [] factorsFoundIndex;
5523 return result;
5524 }
5525 delete [] factorsFoundIndex;
5526 }
5527 result= CFList();
5528 oldL= l;
5529 stepSize *= 2;
5530 l += stepSize;
5531 if (l > liftBound)
5532 {
5533 if (!hitBound)
5534 {
5535 l= liftBound;
5536 hitBound= true;
5537 }
5538 else
5539 break;
5540 }
5541 }
5542 if (irreducible)
5543 {
5544 delete [] A;
5545 return CFList (F (y-eval,y));
5546 }
5547 delete [] A;
5548 factors= bufFactors;
5549 return CFList();
5550}
5551#endif
5552
5553//over field extension
5554#ifdef HAVE_NTL // logarithmicDerivative
5555#ifdef HAVE_FLINT
5556CFList
5558 int liftBound, int d, int* bounds,
5559 nmod_mat_t FLINTN, CFList& diophant,
5560 CFMatrix& M, CFArray& Pi, CFArray& bufQ,
5561 const CanonicalForm& evaluation, const
5562 ExtensionInfo& info, CFList& source,
5563 CFList& dest
5564 )
5565#else
5566CFList
5568 int liftBound, int d, int* bounds,
5569 mat_zz_p& NTLN, CFList& diophant,
5570 CFMatrix& M, CFArray& Pi, CFArray& bufQ,
5571 const CanonicalForm& evaluation, const
5572 ExtensionInfo& info, CFList& source,
5573 CFList& dest
5574 )
5575#endif
5576{
5577 CanonicalForm LCF= LC (F, 1);
5578 CFList result;
5579 bool irreducible= false;
5580 CFList bufFactors= factors;
5581 CFList bufBufFactors;
5582 CFArray *A = new CFArray [bufFactors.length()];
5583 bool useOldQs= false;
5584 bool hitBound= false;
5586 int degMipo= degree (getMipo (info.getAlpha()));
5587 Variable alpha= info.getAlpha();
5588 int oldL= l; //be careful
5589 int stepSize= 8;
5590 l += tmax (tmin (8, degree (F) + 1 + degree (LC (F, 1))-l),2);
5591 Variable gamma= info.getBeta();
5592 CanonicalForm primElemAlpha= info.getGamma();
5593 CanonicalForm imPrimElemAlpha= info.getDelta();
5594#ifdef HAVE_FLINT
5595 nmod_mat_clear (FLINTN);
5596 nmod_mat_init (FLINTN,factors.length(),factors.length(), getCharacteristic());
5597 for (long i=factors.length()-1; i >= 0; i--)
5598 nmod_mat_entry (FLINTN, i, i)= 1;
5599#else
5600 if (NTLN.NumRows() != factors.length()) //refined factors
5601 ident (NTLN, factors.length());
5602#endif
5603 Variable y= F.mvar();
5604 CanonicalForm powX, imBasis, bufF, truncF;
5605 CFMatrix Mat, C;
5607#ifdef HAVE_FLINT
5608 long rank;
5609 nmod_mat_t FLINTMat, FLINTMatInv, FLINTC, FLINTK, null;
5610#else
5611 mat_zz_p* NTLMat,*NTLC, NTLK;
5612#endif
5614 CFArray buf;
5615 while (l <= liftBound)
5616 {
5617 bufFactors.insert (LCF);
5618 henselLiftResume12 (F, bufFactors, oldL, l, Pi, diophant, M);
5619
5620 if (GF)
5622
5623 powX= power (y-gamma, l);
5624 Mat= CFMatrix (l*degMipo, l*degMipo);
5625 for (int i= 0; i < l*degMipo; i++)
5626 {
5627
5628 imBasis= mod (power (y, i), powX);
5629 imBasis= imBasis (power (y, degMipo), y);
5630 imBasis= imBasis (y, gamma);
5631 iter= imBasis;
5632 for (; iter.hasTerms(); iter++)
5633 Mat (iter.exp()+ 1, i+1)= iter.coeff();
5634 }
5635
5636#ifdef HAVE_FLINT
5637 convertFacCFMatrix2nmod_mat_t (FLINTMat, Mat);
5638 nmod_mat_init (FLINTMatInv, nmod_mat_nrows (FLINTMat),
5639 nmod_mat_nrows (FLINTMat), getCharacteristic());
5640 nmod_mat_inv (FLINTMatInv, FLINTMat);
5641#else
5642 NTLMat= convertFacCFMatrix2NTLmat_zz_p (Mat);
5643 *NTLMat= inv (*NTLMat);
5644#endif
5645
5646 if (GF)
5647 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
5648
5649 j= bufFactors;
5650 truncF= mod (F, power (y, l));
5651 if (useOldQs)
5652 {
5653 for (int i= 0; i < bufFactors.length(); i++, j++)
5654 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
5655 bufQ[i]);
5656 }
5657 else
5658 {
5659 for (int i= 0; i < bufFactors.length(); i++, j++)
5660 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
5661 }
5662 for (int i= 0; i < d; i++)
5663 {
5664 if (bounds [i] + 1 <= l/2)
5665 {
5666 int k= tmin (bounds [i] + 1, l/2);
5667 C= CFMatrix (l*degMipo - k, bufFactors.length());
5668 for (int ii= 0; ii < bufFactors.length(); ii++)
5669 {
5670 if (A[ii].size() - 1 >= i)
5671 {
5672 if (GF)
5673 {
5674 A [ii] [i]= A [ii] [i] (y-evaluation, y);
5676 A[ii] [i]= GF2FalphaRep (A[ii] [i], alpha);
5677 if (alpha != gamma)
5678 A [ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
5679 gamma, source, dest
5680 );
5681#ifdef HAVE_FLINT
5682 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
5683#else
5684 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
5685#endif
5686 }
5687 else
5688 {
5689 A [ii] [i]= A [ii] [i] (y-evaluation, y);
5690 if (alpha != gamma)
5691 A[ii] [i]= mapDown (A[ii] [i], imPrimElemAlpha, primElemAlpha,
5692 gamma, source, dest
5693 );
5694#ifdef HAVE_FLINT
5695 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, FLINTMatInv);
5696#else
5697 buf= getCoeffs (A[ii] [i], k, l, degMipo, gamma, 0, *NTLMat);
5698#endif
5699 }
5700 writeInMatrix (C, buf, ii + 1, 0);
5701 }
5702 if (GF)
5703 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
5704 }
5705
5706 if (GF)
5708
5709#ifdef HAVE_FLINT
5711 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
5713 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
5714 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
5716 rank= nmod_mat_nullspace (null, FLINTK);
5717 nmod_mat_clear (FLINTK);
5718 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
5719 nmod_mat_clear (FLINTC);
5720 nmod_mat_init_set (FLINTC, FLINTN);
5721 nmod_mat_clear (FLINTN);
5722 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
5724 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
5725
5726 nmod_mat_clear (FLINTC);
5727 nmod_mat_window_clear (FLINTK);
5728 nmod_mat_clear (null);
5729#else
5731 NTLK= (*NTLC)*NTLN;
5732 transpose (NTLK, NTLK);
5733 kernel (NTLK, NTLK);
5734 transpose (NTLK, NTLK);
5735 NTLN *= NTLK;
5736 delete NTLC;
5737#endif
5738
5739 if (GF)
5740 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
5741
5742#ifdef HAVE_FLINT
5743 if (nmod_mat_ncols (FLINTN) == 1)
5744#else
5745 if (NTLN.NumCols() == 1)
5746#endif
5747 {
5748 irreducible= true;
5749 break;
5750 }
5751 }
5752 }
5753
5754#ifdef HAVE_FLINT
5755 nmod_mat_clear (FLINTMat);
5756 nmod_mat_clear (FLINTMatInv);
5757 if (nmod_mat_ncols (FLINTN) == 1)
5758#else
5759 delete NTLMat;
5760 if (NTLN.NumCols() == 1)
5761#endif
5762 {
5763 irreducible= true;
5764 break;
5765 }
5766
5767 bufF= F;
5768 bufBufFactors= bufFactors;
5769#ifdef HAVE_FLINT
5770 int * zeroOneVecs= extractZeroOneVecs (FLINTN);
5771 result= extReconstruction (bufF, bufFactors, zeroOneVecs, l, FLINTN, info,
5773 );
5774#else
5775 int * zeroOneVecs= extractZeroOneVecs (NTLN);
5776 result= extReconstruction (bufF, bufFactors, zeroOneVecs, l, NTLN, info,
5778 );
5779#endif
5780 delete [] zeroOneVecs;
5781 if (result.length() > 0 && degree (bufF) + 1 + degree (LC (bufF, 1)) <= l)
5782 {
5783 F= bufF;
5784 factors= bufFactors;
5785 delete [] A;
5786 return result;
5787 }
5788 else
5789 {
5790 bufF= F;
5791 bufFactors= bufBufFactors;
5792 }
5793
5794#ifdef HAVE_FLINT
5795 if (isReduced (FLINTN))
5796#else
5797 if (isReduced (NTLN))
5798#endif
5799 {
5800 int factorsFound= 0;
5801 bufF= F;
5802#ifdef HAVE_FLINT
5803 int* factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
5804 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
5805#else
5806 int* factorsFoundIndex= new int [NTLN.NumCols()];
5807 for (long i= 0; i < NTLN.NumCols(); i++)
5808#endif
5809 factorsFoundIndex[i]= 0;
5810#ifdef HAVE_FLINT
5811 if (l < degree (bufF) + 1 + degree (LCF))
5812 extReconstructionTry (result, bufF, bufFactors, l, factorsFound,
5813 factorsFoundIndex, FLINTN, false, info, evaluation
5814 );
5815 else
5816 extReconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
5817 degree (LCF), factorsFound, factorsFoundIndex,
5818 FLINTN, false, info, evaluation
5819 );
5820 if (nmod_mat_ncols (FLINTN) == result.length())
5821#else
5822 if (l < degree (bufF) + 1 + degree (LCF))
5823 extReconstructionTry (result, bufF, bufFactors, l, factorsFound,
5824 factorsFoundIndex, NTLN, false, info, evaluation
5825 );
5826 else
5827 extReconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
5828 degree (LCF), factorsFound, factorsFoundIndex,
5829 NTLN, false, info, evaluation
5830 );
5831 if (NTLN.NumCols() == result.length())
5832#endif
5833 {
5834 delete [] A;
5835 delete [] factorsFoundIndex;
5836 return result;
5837 }
5838 delete [] factorsFoundIndex;
5839 }
5840 result= CFList();
5841 oldL= l;
5842 stepSize *= 2;
5843 l += stepSize;
5844 if (l > liftBound)
5845 {
5846 if (!hitBound)
5847 {
5848 l= liftBound;
5849 hitBound= true;
5850 }
5851 else
5852 break;
5853 }
5854 }
5855 if (irreducible)
5856 {
5857 delete [] A;
5858 Variable y= Variable (2);
5859 CanonicalForm tmp= F (y - evaluation, y);
5860 CFList source, dest;
5861 tmp= mapDown (tmp, info, source, dest);
5862 return CFList (tmp);
5863 }
5864 delete [] A;
5865 factors= bufFactors;
5866 return CFList();
5867}
5868#endif
5869
5870#ifdef HAVE_NTL // logarithmicDerivative
5871#ifdef HAVE_FLINT
5872CFList
5874 l, int liftBound, int d, int* bounds,
5875 nmod_mat_t FLINTN, CFList& diophant,
5876 CFMatrix& M, CFArray& Pi, CFArray& bufQ,
5877 const Variable& alpha,
5878 const CanonicalForm& eval
5879 )
5880#else
5881CFList
5883 l, int liftBound, int d, int* bounds,
5884 mat_zz_p& NTLN, CFList& diophant,
5885 CFMatrix& M, CFArray& Pi, CFArray& bufQ,
5886 const Variable& alpha,
5887 const CanonicalForm& eval
5888 )
5889#endif
5890{
5891 CanonicalForm LCF= LC (F, 1);
5892 CFList result;
5893 bool irreducible= false;
5894 CFList bufFactors= factors;
5895 CFList bufBufFactors;
5896 CFArray *A = new CFArray [bufFactors.length()];
5897 bool useOldQs= false;
5898 int extensionDeg= degree (getMipo (alpha));
5899 bool hitBound= false;
5900 int oldL= l;
5901 int stepSize= 8; //TODO choose better step size?
5902 l += tmax (tmin (8, degree (F) + 1 + degree (LC (F, 1))-l), 2);
5903#ifdef HAVE_FLINT
5904 if (nmod_mat_nrows (FLINTN) != factors.length()) //refined factors
5905 {
5906 nmod_mat_clear (FLINTN);
5907 nmod_mat_init(FLINTN,factors.length(),factors.length(),getCharacteristic());
5908 for (long i=factors.length()-1; i >= 0; i--)
5909 nmod_mat_entry (FLINTN, i, i)= 1;
5910 }
5911#else
5912 if (NTLN.NumRows() != factors.length()) //refined factors
5913 ident (NTLN, factors.length());
5914#endif
5916 CFMatrix C;
5917#ifdef HAVE_FLINT
5918 long rank;
5919 nmod_mat_t FLINTC, FLINTK, null;
5920#else
5921 mat_zz_p* NTLC, NTLK;
5922#endif
5923 CanonicalForm bufF, truncF;
5924 Variable y= F.mvar();
5925 while (l <= liftBound)
5926 {
5927 bufFactors.insert (LCF);
5928 henselLiftResume12 (F, bufFactors, oldL, l, Pi, diophant, M);
5929 j= bufFactors;
5930 truncF= mod (F, power (y, l));
5931 if (useOldQs)
5932 {
5933 for (int i= 0; i < bufFactors.length(); i++, j++)
5934 A[i]= logarithmicDerivative (truncF, j.getItem(), l, oldL, bufQ[i],
5935 bufQ[i]);
5936 }
5937 else
5938 {
5939 for (int i= 0; i < bufFactors.length(); i++, j++)
5940 A[i]= logarithmicDerivative (truncF, j.getItem(), l, bufQ [i]);
5941 }
5942 for (int i= 0; i < d; i++)
5943 {
5944 if (bounds [i] + 1 <= l/2)
5945 {
5946 int k= tmin (bounds [i] + 1, l/2);
5947 C= CFMatrix ((l - k)*extensionDeg, bufFactors.length());
5948 for (int ii= 0; ii < bufFactors.length(); ii++)
5949 {
5950 CFArray buf;
5951 if (A[ii].size() - 1 >= i)
5952 {
5953 buf= getCoeffs (A[ii] [i], k, alpha);
5954 writeInMatrix (C, buf, ii + 1, 0);
5955 }
5956 }
5957#ifdef HAVE_FLINT
5959 nmod_mat_init (FLINTK, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTN),
5961 nmod_mat_mul (FLINTK, FLINTC, FLINTN);
5962 nmod_mat_init (null, nmod_mat_ncols (FLINTK), nmod_mat_ncols (FLINTK),
5964 rank= nmod_mat_nullspace (null, FLINTK);
5965 nmod_mat_clear (FLINTK);
5966 nmod_mat_window_init (FLINTK, null, 0, 0, nmod_mat_nrows(null), rank);
5967 nmod_mat_clear (FLINTC);
5968 nmod_mat_init_set (FLINTC, FLINTN);
5969 nmod_mat_clear (FLINTN);
5970 nmod_mat_init (FLINTN, nmod_mat_nrows (FLINTC), nmod_mat_ncols (FLINTK),
5972 nmod_mat_mul (FLINTN, FLINTC, FLINTK); //no aliasing allowed!!
5973
5974 nmod_mat_clear (FLINTC);
5975 nmod_mat_window_clear (FLINTK);
5976 nmod_mat_clear (null);
5977#else
5979 NTLK= (*NTLC)*NTLN;
5980 transpose (NTLK, NTLK);
5981 kernel (NTLK, NTLK);
5982 transpose (NTLK, NTLK);
5983 NTLN *= NTLK;
5984 delete NTLC;
5985#endif
5986#ifdef HAVE_FLINT
5987 if (nmod_mat_ncols (FLINTN) == 1)
5988#else
5989 if (NTLN.NumCols() == 1)
5990#endif
5991 {
5992 irreducible= true;
5993 break;
5994 }
5995 }
5996 }
5997#ifdef HAVE_FLINT
5998 if (nmod_mat_ncols (FLINTN) == 1)
5999#else
6000 if (NTLN.NumCols() == 1)
6001#endif
6002 {
6003 irreducible= true;
6004 break;
6005 }
6006
6007#ifdef HAVE_FLINT
6008 int * zeroOneVecs= extractZeroOneVecs (FLINTN);
6009#else
6010 int * zeroOneVecs= extractZeroOneVecs (NTLN);
6011#endif
6012 CanonicalForm bufF= F;
6013 bufBufFactors= bufFactors;
6014#ifdef HAVE_FLINT
6015 result= reconstruction (bufF, bufFactors, zeroOneVecs, l, FLINTN, eval);
6016#else
6017 result= reconstruction (bufF, bufFactors, zeroOneVecs, l, NTLN, eval);
6018#endif
6019 delete [] zeroOneVecs;
6020 if (result.length() > 0 && degree (bufF) + 1 + degree (LC (bufF, 1)) <= l)
6021 {
6022 F= bufF;
6023 factors= bufFactors;
6024 delete [] A;
6025 return result;
6026 }
6027 else
6028 {
6029 bufF= F;
6030 bufFactors= bufBufFactors;
6031 }
6032
6033#ifdef HAVE_FLINT
6034 if (isReduced (FLINTN))
6035#else
6036 if (isReduced (NTLN))
6037#endif
6038 {
6039 int factorsFound= 0;
6040 bufF= F;
6041#ifdef HAVE_FLINT
6042 int* factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
6043 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
6044#else
6045 int* factorsFoundIndex= new int [NTLN.NumCols()];
6046 for (long i= 0; i < NTLN.NumCols(); i++)
6047#endif
6048 factorsFoundIndex[i]= 0;
6049#ifdef HAVE_FLINT
6050 if (l < degree (bufF) + 1 + degree (LCF))
6051 reconstructionTry (result, bufF, bufFactors, l, factorsFound,
6052 factorsFoundIndex, FLINTN, eval, false
6053 );
6054 else
6055 reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
6056 degree (LCF), factorsFound, factorsFoundIndex,
6057 FLINTN, eval, false
6058 );
6059 if (nmod_mat_ncols (FLINTN) == result.length())
6060#else
6061 if (l < degree (bufF) + 1 + degree (LCF))
6062 reconstructionTry (result, bufF, bufFactors, l, factorsFound,
6063 factorsFoundIndex, NTLN, eval, false
6064 );
6065 else
6066 reconstructionTry (result, bufF, bufFactors, degree (bufF) + 1 +
6067 degree (LCF), factorsFound, factorsFoundIndex,
6068 NTLN, eval, false
6069 );
6070 if (NTLN.NumCols() == result.length())
6071#endif
6072 {
6073 delete [] A;
6074 delete [] factorsFoundIndex;
6075 return result;
6076 }
6077 delete [] factorsFoundIndex;
6078 }
6079 result= CFList();
6080 oldL= l;
6081 stepSize *= 2;
6082 l += stepSize;
6083 if (l > liftBound)
6084 {
6085 if (!hitBound)
6086 {
6087 l= liftBound;
6088 hitBound= true;
6089 }
6090 else
6091 break;
6092 }
6093 }
6094 if (irreducible)
6095 {
6096 delete [] A;
6097 return CFList (F (y-eval,y));
6098 }
6099 delete [] A;
6100 factors= bufFactors;
6101 return CFList();
6102}
6103#endif
6104
6105#ifndef HAVE_FLINT
6106void
6107refineAndRestartLift (const CanonicalForm& F, const mat_zz_p& NTLN, int
6108 liftBound, int l, CFList& factors, CFMatrix& M, CFArray&
6109 Pi, CFList& diophant
6110 )
6111{
6112 CFList bufFactors;
6113 Variable y= Variable (2);
6114 CanonicalForm LCF= LC (F, 1);
6117 for (long i= 1; i <= NTLN.NumCols(); i++)
6118 {
6119 iter= factors;
6120 buf= 1;
6121 for (long j= 1; j <= NTLN.NumRows(); j++, iter++)
6122 {
6123 if (!IsZero (NTLN (j,i)))
6124 buf= mulNTL (buf, mod (iter.getItem(), y));
6125 }
6126 bufFactors.append (buf);
6127 }
6128 factors= bufFactors;
6129 M= CFMatrix (liftBound, factors.length());
6130 Pi= CFArray();
6131 diophant= CFList();
6132 factors.insert (LCF);
6133 henselLift12 (F, factors, l, Pi, diophant, M);
6134}
6135#endif
6136
6137#ifdef HAVE_FLINT
6138#ifdef HAVE_NTL // henselLift12
6139void
6140refineAndRestartLift (const CanonicalForm& F, const nmod_mat_t FLINTN, int
6141 liftBound, int l, CFList& factors, CFMatrix& M, CFArray&
6142 Pi, CFList& diophant
6143 )
6144{
6145 CFList bufFactors;
6146 Variable y= Variable (2);
6147 CanonicalForm LCF= LC (F, 1);
6150 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
6151 {
6152 iter= factors;
6153 buf= 1;
6154 for (long j= 0; j < nmod_mat_nrows (FLINTN); j++, iter++)
6155 {
6156 if (!(nmod_mat_entry (FLINTN,j,i) == 0))
6157 buf= mulNTL (buf, mod (iter.getItem(), y));
6158 }
6159 bufFactors.append (buf);
6160 }
6161 factors= bufFactors;
6162 M= CFMatrix (liftBound, factors.length());
6163 Pi= CFArray();
6164 diophant= CFList();
6165 factors.insert (LCF);
6166 henselLift12 (F, factors, l, Pi, diophant, M);
6167}
6168#endif
6169#endif
6170
6171#ifdef HAVE_NTL // mat_zz_pE
6172void
6173refineAndRestartLift (const CanonicalForm& F, const mat_zz_pE& NTLN, int
6174 liftBound, int l, CFList& factors, CFMatrix& M, CFArray&
6175 Pi, CFList& diophant
6176 )
6177{
6178 CFList bufFactors;
6179 Variable y= Variable (2);
6180 CanonicalForm LCF= LC (F, 1);
6183 for (long i= 1; i <= NTLN.NumCols(); i++)
6184 {
6185 iter= factors;
6186 buf= 1;
6187 for (long j= 1; j <= NTLN.NumRows(); j++, iter++)
6188 {
6189 if (!IsZero (NTLN (j,i)))
6190 buf= mulNTL (buf, mod (iter.getItem(), y));
6191 }
6192 bufFactors.append (buf);
6193 }
6194 factors= bufFactors;
6195 M= CFMatrix (liftBound, factors.length());
6196 Pi= CFArray();
6197 diophant= CFList();
6198 factors.insert (LCF);
6199 henselLift12 (F, factors, l, Pi, diophant, M);
6200}
6201#endif
6202
6203#ifdef HAVE_FLINT
6204CFList
6206 CanonicalForm& bufF, CFList& factors, int& l,
6207 int& factorsFound, bool beenInThres, CFMatrix& M,
6208 CFArray& Pi, CFList& diophant, bool symmetric,
6210 )
6211#else
6212CFList
6213earlyReconstructionAndLifting (const CanonicalForm& F, const mat_zz_p& N,
6214 CanonicalForm& bufF, CFList& factors, int& l,
6215 int& factorsFound, bool beenInThres, CFMatrix& M,
6216 CFArray& Pi, CFList& diophant, bool symmetric,
6218 )
6219#endif
6220{
6221 int sizeOfLiftPre;
6222 int * liftPre= getLiftPrecisions (F, sizeOfLiftPre, degree (LC (F, 1), 2));
6223
6224 Variable y= F.mvar();
6225 factorsFound= 0;
6226 CanonicalForm LCF= LC (F, 1);
6227 CFList result;
6228 int smallFactorDeg= tmin (11, liftPre [sizeOfLiftPre- 1] + 1);
6229#ifdef HAVE_FLINT
6230 nmod_mat_t FLINTN;
6231 nmod_mat_init_set (FLINTN, N);
6232 int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
6233 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
6234#else
6235 mat_zz_p NTLN= N;
6236 int * factorsFoundIndex= new int [NTLN.NumCols()];
6237 for (long i= 0; i < NTLN.NumCols(); i++)
6238#endif
6239 factorsFoundIndex [i]= 0;
6240
6241 if (degree (F) + 1 > smallFactorDeg)
6242 {
6243 if (l < smallFactorDeg)
6244 {
6245 TIMING_START (fac_fq_lift);
6246 factors.insert (LCF);
6247 henselLiftResume12 (F, factors, l, smallFactorDeg, Pi, diophant, M);
6248 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction0: ");
6249 l= smallFactorDeg;
6250 }
6251#ifdef HAVE_FLINT
6252 TIMING_START (fac_fq_reconstruction);
6253 reconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
6254 factorsFoundIndex, FLINTN, evaluation, beenInThres
6255 );
6256 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct0: ");
6257 if (result.length() == nmod_mat_ncols (FLINTN))
6258 {
6259 nmod_mat_clear (FLINTN);
6260#else
6261 TIMING_START (fac_fq_reconstruction);
6262 reconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
6263 factorsFoundIndex, NTLN, evaluation, beenInThres
6264 );
6265 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct0: ");
6266 if (result.length() == NTLN.NumCols())
6267 {
6268#endif
6269 delete [] liftPre;
6270 delete [] factorsFoundIndex;
6271 return result;
6272 }
6273 }
6274
6275 int i= sizeOfLiftPre - 1;
6276 int dummy= 1;
6277 if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
6278 {
6279 while (i > 0)
6280 {
6281 if (l < liftPre[i-1] + 1)
6282 {
6283 factors.insert (LCF);
6284 TIMING_START (fac_fq_lift);
6285 henselLiftResume12 (F, factors, l, liftPre[i-1] + 1, Pi, diophant, M);
6286 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction1: ");
6287 l= liftPre[i-1] + 1;
6288 }
6289 else
6290 {
6291 i--;
6292 if (i != 0)
6293 continue;
6294 }
6295#ifdef HAVE_FLINT
6296 TIMING_START (fac_fq_reconstruction);
6297 reconstructionTry (result, bufF, factors, l, factorsFound,
6298 factorsFoundIndex, FLINTN, evaluation, beenInThres
6299 );
6300 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct1: ");
6301 if (result.length() == nmod_mat_ncols (FLINTN))
6302 {
6303 nmod_mat_clear (FLINTN);
6304#else
6305 TIMING_START (fac_fq_reconstruction);
6306 reconstructionTry (result, bufF, factors, l, factorsFound,
6307 factorsFoundIndex, NTLN, evaluation, beenInThres
6308 );
6309 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct1: ");
6310 if (result.length() == NTLN.NumCols())
6311 {
6312#endif
6313 delete [] liftPre;
6314 delete [] factorsFoundIndex;
6315 return result;
6316 }
6317 i--;
6318 }
6319 }
6320 else
6321 {
6322 i= 1;
6323 while (((degree (F,y)/4)*i+1) + 4 <= smallFactorDeg)
6324 i++;
6325 while (i < 5)
6326 {
6327 dummy= tmin (degree (F,y)+1, ((degree (F,y)/4)+1)*i+4);
6328 if (l < dummy)
6329 {
6330 factors.insert (LCF);
6331 TIMING_START (fac_fq_lift);
6332 henselLiftResume12 (F, factors, l, dummy, Pi, diophant, M);
6333 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction2: ");
6334 l= dummy;
6335 if (i == 1 && degree (F)%4==0 && symmetric && factors.length() == 2 &&
6336 LC (F,1).inCoeffDomain() &&
6337 (degree (factors.getFirst(), 1) == degree (factors.getLast(),1)))
6338 {
6339 Variable x= Variable (1);
6340 CanonicalForm g, h, gg, hh, multiplier1, multiplier2, check1, check2;
6341 int m= degree (F)/4+1;
6342 g= factors.getFirst();
6343 h= factors.getLast();
6344 g= mod (g, power (y,m));
6345 h= mod (h, power (y,m));
6346 g= g (y-evaluation, y);
6347 h= h (y-evaluation, y);
6348 gg= mod (swapvar (g,x,y),power (x,m));
6349 gg= gg (y + evaluation, y);
6350 multiplier1= factors.getLast()[m-1][0]/gg[m-1][0];
6351 gg= div (gg, power (y,m));
6352 gg= gg*power (y,m);
6353 hh= mod (swapvar (h,x,y),power (x,m));
6354 hh= hh (y + evaluation, y);
6355 multiplier2= factors.getFirst()[m-1][0]/hh[m-1][0];
6356 hh= div (hh, power (y,m));
6357 hh= hh*power (y,m);
6358 gg= multiplier1*gg+mod (factors.getLast(), power (y,m));
6359 hh= multiplier2*hh+mod (factors.getFirst(), power (y,m));
6360 check1= gg (y-evaluation,y);
6361 check2= hh (y-evaluation,y);
6362 CanonicalForm oldcheck1= check1;
6363 check1= swapvar (check1, x, y);
6364 if (check1/Lc (check1) == check2/Lc (check2))
6365 {
6366#ifdef HAVE_FLINT
6367 nmod_mat_clear (FLINTN);
6368#endif
6369 result.append (oldcheck1);
6370 result.append (check2);
6371 delete [] liftPre;
6372 delete [] factorsFoundIndex;
6373 return result;
6374 }
6375 }
6376 }
6377 else
6378 {
6379 i++;
6380 if (i < 5)
6381 continue;
6382 }
6383#ifdef HAVE_FLINT
6384 TIMING_START (fac_fq_reconstruction);
6385 reconstructionTry (result, bufF, factors, l, factorsFound,
6386 factorsFoundIndex, FLINTN, evaluation, beenInThres
6387 );
6388 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct2: ");
6389 if (result.length() == nmod_mat_ncols (FLINTN))
6390 {
6391 nmod_mat_clear (FLINTN);
6392#else
6393 TIMING_START (fac_fq_reconstruction);
6394 reconstructionTry (result, bufF, factors, l, factorsFound,
6395 factorsFoundIndex, NTLN, evaluation, beenInThres
6396 );
6397 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct2: ");
6398 if (result.length() == NTLN.NumCols())
6399 {
6400#endif
6401 delete [] liftPre;
6402 delete [] factorsFoundIndex;
6403 return result;
6404 }
6405 i++;
6406 }
6407 }
6408
6409#ifdef HAVE_FLINT
6410 nmod_mat_clear (FLINTN);
6411#endif
6412 delete [] liftPre;
6413 delete [] factorsFoundIndex;
6414 return result;
6415}
6416
6417#ifdef HAVE_NTL // mat_zz_pE
6418CFList
6420 CanonicalForm& bufF, CFList& factors, int& l,
6421 int& factorsFound, bool beenInThres, CFMatrix& M,
6422 CFArray& Pi, CFList& diophant, bool symmetric,
6424 )
6425{
6426 int sizeOfLiftPre;
6427 int * liftPre= getLiftPrecisions (F, sizeOfLiftPre, degree (LC (F, 1), 2));
6428 Variable y= F.mvar();
6429 factorsFound= 0;
6430 CanonicalForm LCF= LC (F, 1);
6431 CFList result;
6432 int smallFactorDeg= 11;
6433 mat_zz_pE NTLN= N;
6434 int * factorsFoundIndex= new int [NTLN.NumCols()];
6435 for (long i= 0; i < NTLN.NumCols(); i++)
6436 factorsFoundIndex [i]= 0;
6437
6438 if (degree (F) + 1 > smallFactorDeg)
6439 {
6440 if (l < smallFactorDeg)
6441 {
6442 TIMING_START (fac_fq_lift);
6443 factors.insert (LCF);
6444 henselLiftResume12 (F, factors, l, smallFactorDeg, Pi, diophant, M);
6445 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction0: ");
6446 l= smallFactorDeg;
6447 }
6448 TIMING_START (fac_fq_reconstruction);
6449 reconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
6450 factorsFoundIndex, NTLN, evaluation, beenInThres
6451 );
6452 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct0: ");
6453 if (result.length() == NTLN.NumCols())
6454 {
6455 delete [] liftPre;
6456 delete [] factorsFoundIndex;
6457 return result;
6458 }
6459 }
6460
6461 int i= sizeOfLiftPre - 1;
6462 int dummy= 1;
6463 if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
6464 {
6465 while (i > 0)
6466 {
6467 if (l < liftPre[i-1] + 1)
6468 {
6469 factors.insert (LCF);
6470 TIMING_START (fac_fq_lift);
6471 henselLiftResume12 (F, factors, l, liftPre[i-1] + 1, Pi, diophant, M);
6472 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction1: ");
6473 l= liftPre[i-1] + 1;
6474 }
6475 else
6476 {
6477 i--;
6478 if (i != 0)
6479 continue;
6480 }
6481 TIMING_START (fac_fq_reconstruction);
6482 reconstructionTry (result, bufF, factors, l, factorsFound,
6483 factorsFoundIndex, NTLN, evaluation, beenInThres
6484 );
6485 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct1: ");
6486 if (result.length() == NTLN.NumCols())
6487 {
6488 delete [] liftPre;
6489 delete [] factorsFoundIndex;
6490 return result;
6491 }
6492 i--;
6493 }
6494 }
6495 else
6496 {
6497 i= 1;
6498 while ((degree (F,y)/4+1)*i + 4 <= smallFactorDeg)
6499 i++;
6500 while (i < 5)
6501 {
6502 dummy= tmin (degree (F,y)+1, (degree (F,y)/4+1)*i+4);
6503 if (l < dummy)
6504 {
6505 factors.insert (LCF);
6506 TIMING_START (fac_fq_lift);
6507 henselLiftResume12 (F, factors, l, dummy, Pi, diophant, M);
6508 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction2: ");
6509 l= dummy;
6510 if (i == 1 && degree (F)%4==0 && symmetric && factors.length() == 2 &&
6511 LC (F,1).inCoeffDomain() &&
6512 (degree (factors.getFirst(), 1) == degree (factors.getLast(),1)))
6513 {
6514 Variable x= Variable (1);
6515 CanonicalForm g, h, gg, hh, multiplier1, multiplier2, check1, check2;
6516 int m= degree (F)/4+1;
6517 g= factors.getFirst();
6518 h= factors.getLast();
6519 g= mod (g, power (y,m));
6520 h= mod (h, power (y,m));
6521 g= g (y-evaluation, y);
6522 h= h (y-evaluation, y);
6523 gg= mod (swapvar (g,x,y),power (x,m));
6524 gg= gg (y + evaluation, y);
6525 multiplier1= factors.getLast()[m-1][0]/gg[m-1][0];
6526 gg= div (gg, power (y,m));
6527 gg= gg*power (y,m);
6528 hh= mod (swapvar (h,x,y),power (x,m));
6529 hh= hh (y + evaluation, y);
6530 multiplier2= factors.getFirst()[m-1][0]/hh[m-1][0];
6531 hh= div (hh, power (y,m));
6532 hh= hh*power (y,m);
6533 gg= multiplier1*gg+mod (factors.getLast(), power (y,m));
6534 hh= multiplier2*hh+mod (factors.getFirst(), power (y,m));
6535 check1= gg (y-evaluation,y);
6536 check2= hh (y-evaluation,y);
6537 CanonicalForm oldcheck1= check1;
6538 check1= swapvar (check1, x, y);
6539 if (check1/Lc (check1) == check2/Lc (check2))
6540 {
6541 result.append (oldcheck1);
6542 result.append (check2);
6543 delete [] liftPre;
6544 delete [] factorsFoundIndex;
6545 return result;
6546 }
6547 }
6548 }
6549 else
6550 {
6551 i++;
6552 if (i < 5)
6553 continue;
6554 }
6555 TIMING_START (fac_fq_reconstruction);
6556 reconstructionTry (result, bufF, factors, l, factorsFound,
6557 factorsFoundIndex, NTLN, evaluation, beenInThres
6558 );
6559 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct2: ");
6560 if (result.length() == NTLN.NumCols())
6561 {
6562 delete [] liftPre;
6563 delete [] factorsFoundIndex;
6564 return result;
6565 }
6566 i++;
6567 }
6568 }
6569
6570 delete [] liftPre;
6571 delete [] factorsFoundIndex;
6572 return result;
6573}
6574#endif
6575
6576//over field extension
6577#ifdef HAVE_FLINT
6578CFList
6580 CanonicalForm& bufF, CFList& factors, int& l,
6581 int& factorsFound, bool beenInThres, CFMatrix&
6582 M, CFArray& Pi, CFList& diophant, const
6585 )
6586#else
6587CFList
6588extEarlyReconstructionAndLifting (const CanonicalForm& F, const mat_zz_p& N,
6589 CanonicalForm& bufF, CFList& factors, int& l,
6590 int& factorsFound, bool beenInThres, CFMatrix&
6591 M, CFArray& Pi, CFList& diophant, const
6594 )
6595#endif
6596{
6597 int sizeOfLiftPre;
6598 int * liftPre= getLiftPrecisions (F, sizeOfLiftPre, degree (LC (F, 1), 2));
6599 Variable y= F.mvar();
6600 factorsFound= 0;
6601 CanonicalForm LCF= LC (F, 1);
6602 CFList result;
6603 int smallFactorDeg= 11;
6604#ifdef HAVE_FLINT
6605 nmod_mat_t FLINTN;
6606 nmod_mat_init_set (FLINTN, N);
6607 int * factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
6608 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
6609#else
6610 mat_zz_p NTLN= N;
6611 int * factorsFoundIndex= new int [NTLN.NumCols()];
6612 for (long i= 0; i < NTLN.NumCols(); i++)
6613#endif
6614 factorsFoundIndex [i]= 0;
6615
6616 if (degree (F) + 1 > smallFactorDeg)
6617 {
6618 if (l < smallFactorDeg)
6619 {
6620 TIMING_START (fac_fq_lift);
6621 factors.insert (LCF);
6622 henselLiftResume12 (F, factors, l, smallFactorDeg, Pi, diophant, M);
6623 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction0: ");
6624 l= smallFactorDeg;
6625 }
6626 TIMING_START (fac_fq_reconstruction);
6627#ifdef HAVE_FLINT
6628 extReconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
6629 factorsFoundIndex, FLINTN, beenInThres, info,
6631 );
6632#else
6633 extReconstructionTry (result, bufF, factors, smallFactorDeg, factorsFound,
6634 factorsFoundIndex, NTLN, beenInThres, info,
6636 );
6637#endif
6638 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct0: ");
6639#ifdef HAVE_FLINT
6640 if (result.length() == nmod_mat_ncols (FLINTN))
6641 {
6642 nmod_mat_clear (FLINTN);
6643#else
6644 if (result.length() == NTLN.NumCols())
6645 {
6646#endif
6647 delete [] liftPre;
6648 delete [] factorsFoundIndex;
6649 return result;
6650 }
6651 }
6652
6653 int i= sizeOfLiftPre - 1;
6654 int dummy= 1;
6655 if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
6656 {
6657 while (i > 0)
6658 {
6659 if (l < liftPre[i-1] + 1)
6660 {
6661 factors.insert (LCF);
6662 TIMING_START (fac_fq_lift);
6663 henselLiftResume12 (F, factors, l, liftPre[i-1] + 1, Pi, diophant, M);
6664 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction1: ");
6665 l= liftPre[i-1] + 1;
6666 }
6667 else
6668 {
6669 i--;
6670 if (i != 0)
6671 continue;
6672 }
6673 TIMING_START (fac_fq_reconstruction);
6674#ifdef HAVE_FLINT
6675 extReconstructionTry (result, bufF, factors, l, factorsFound,
6676 factorsFoundIndex, FLINTN, beenInThres, info,
6678 );
6679#else
6680 extReconstructionTry (result, bufF, factors, l, factorsFound,
6681 factorsFoundIndex, NTLN, beenInThres, info,
6683 );
6684#endif
6685 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct1: ");
6686#ifdef HAVE_FLINT
6687 if (result.length() == nmod_mat_ncols (FLINTN))
6688 {
6689 nmod_mat_clear (FLINTN);
6690#else
6691 if (result.length() == NTLN.NumCols())
6692 {
6693#endif
6694 delete [] liftPre;
6695 delete [] factorsFoundIndex;
6696 return result;
6697 }
6698 i--;
6699 }
6700 }
6701 else
6702 {
6703 i= 1;
6704 while ((degree (F,y)/4+1)*i + 4 <= smallFactorDeg)
6705 i++;
6706 while (i < 5)
6707 {
6708 dummy= tmin (degree (F,y)+1, (degree (F,y)/4+1)*i+4);
6709 if (l < dummy)
6710 {
6711 factors.insert (LCF);
6712 TIMING_START (fac_fq_lift);
6713 henselLiftResume12 (F, factors, l, dummy, Pi, diophant, M);
6714 TIMING_END_AND_PRINT (fac_fq_lift, "time to lift in reconstruction2: ");
6715 l= dummy;
6716 }
6717 else
6718 {
6719 i++;
6720 if (i < 5)
6721 continue;
6722 }
6723 TIMING_START (fac_fq_reconstruction);
6724#ifdef HAVE_FLINT
6725 extReconstructionTry (result, bufF, factors, l, factorsFound,
6726 factorsFoundIndex, FLINTN, beenInThres, info,
6728 );
6729#else
6730 extReconstructionTry (result, bufF, factors, l, factorsFound,
6731 factorsFoundIndex, NTLN, beenInThres, info,
6733 );
6734#endif
6735 TIMING_END_AND_PRINT (fac_fq_reconstruction, "time to reconstruct2: ");
6736#ifdef HAVE_FLINT
6737 if (result.length() == nmod_mat_ncols (FLINTN))
6738 {
6739 nmod_mat_clear (FLINTN);
6740#else
6741 if (result.length() == NTLN.NumCols())
6742 {
6743#endif
6744 delete [] liftPre;
6745 delete [] factorsFoundIndex;
6746 return result;
6747 }
6748 i++;
6749 }
6750 }
6751
6752#ifdef HAVE_FLINT
6753 nmod_mat_clear (FLINTN);
6754#endif
6755 delete [] liftPre;
6756 delete [] factorsFoundIndex;
6757 return result;
6758}
6759
6760#ifdef HAVE_NTL // henselLift12
6761CFList
6763 degPat, CanonicalForm& H, CFList& diophant, CFArray& Pi,
6764 CFMatrix& M, bool& success, int d, const CanonicalForm& eval
6765 )
6766{
6767 CanonicalForm F= G;
6768 CFList bufUniFactors= uniFactors;
6769 bufUniFactors.insert (LC (F, 1));
6770 int smallFactorDeg= d;
6771 DegreePattern degs= degPat;
6772 henselLift12 (F, bufUniFactors, smallFactorDeg, Pi, diophant, M);
6773 int adaptedLiftBound;
6774 success= false;
6775 int * factorsFoundIndex= new int [uniFactors.length()];
6776 for (int i= 0; i < uniFactors.length(); i++)
6777 factorsFoundIndex [i]= 0;
6778 CFList earlyFactors;
6779 earlyFactorDetection (earlyFactors, F, bufUniFactors, adaptedLiftBound,
6780 factorsFoundIndex, degs, success, smallFactorDeg, eval);
6781 delete [] factorsFoundIndex;
6782 if (degs.getLength() == 1)
6783 {
6784 degPat= degs;
6785 return earlyFactors;
6786 }
6787 if (success)
6788 {
6789 H= F;
6790 return earlyFactors;
6791 }
6792 int sizeOldF= size (G);
6793 if (size (F) < sizeOldF)
6794 {
6795 H= F;
6796 success= true;
6797 return earlyFactors;
6798 }
6799 else
6800 {
6801 uniFactors= bufUniFactors;
6802 return CFList();
6803 }
6804}
6805#endif
6806
6807#ifdef HAVE_NTL // henselLift12
6808CFList
6810 degPat, CanonicalForm& H, CFList& diophant, CFArray& Pi,
6811 CFMatrix& M, bool& success, int d, const CanonicalForm&
6813 )
6814{
6815 CanonicalForm F= G;
6816 CFList bufUniFactors= uniFactors;
6817 bufUniFactors.insert (LC (F, 1));
6818 int smallFactorDeg= d;
6819 DegreePattern degs= degPat;
6820 henselLift12 (F, bufUniFactors, smallFactorDeg, Pi, diophant, M);
6821 int adaptedLiftBound;
6822 success= false;
6823 int * factorsFoundIndex= new int [uniFactors.length()];
6824 for (int i= 0; i < uniFactors.length(); i++)
6825 factorsFoundIndex [i]= 0;
6826 CFList earlyFactors;
6827 extEarlyFactorDetection (earlyFactors, F, bufUniFactors, adaptedLiftBound,
6828 factorsFoundIndex, degs, success, info, evaluation,
6829 smallFactorDeg);
6830 delete [] factorsFoundIndex;
6831 if (degs.getLength() == 1)
6832 {
6833 degPat= degs;
6834 return earlyFactors;
6835 }
6836 if (success)
6837 {
6838 H= F;
6839 return earlyFactors;
6840 }
6841 Variable y= F.mvar();
6842 int sizeOldF= size (G);
6843 if (size (F) < sizeOldF)
6844 {
6845 H= F;
6846 success= true;
6847 return earlyFactors;
6848 }
6849 else
6850 {
6851 uniFactors= bufUniFactors;
6852 return CFList();
6853 }
6854}
6855#endif
6856
6857#ifdef HAVE_NTL // matrix Fq
6858CFList
6860 const Variable& alpha, const DegreePattern& degPat,
6861 bool symmetric, const CanonicalForm& eval
6862 )
6863{
6864 DegreePattern degs= degPat;
6865 CanonicalForm F= G;
6866 CanonicalForm LCF= LC (F, 1);
6867 Variable y= F.mvar();
6868 Variable x= Variable (1);
6869 int d;
6870 bool isIrreducible= false;
6871 int* bounds= computeBounds (F, d, isIrreducible);
6872 if (isIrreducible)
6873 {
6874 delete [] bounds;
6875 return CFList (G);
6876 }
6877 int minBound= bounds[0];
6878 for (int i= 1; i < d; i++)
6879 {
6880 if (bounds[i] != 0)
6881 minBound= tmin (minBound, bounds[i]);
6882 }
6883
6884 CFList bufUniFactors= uniFactors;
6885 CFArray Pi;
6886 CFList diophant;
6887 int liftBound= 2*totaldegree (F) - 1;
6888 CFMatrix M= CFMatrix (liftBound, bufUniFactors.length());
6889
6890 CFList smallFactors;
6892 bool success= false;
6893 smallFactors= sieveSmallFactors (F, bufUniFactors, degs, H, diophant, Pi, M,
6894 success, minBound + 1, eval
6895 );
6896
6897 if (smallFactors.length() > 0)
6898 {
6899 if (smallFactors.length() == 1)
6900 {
6901 if (smallFactors.getFirst() == F)
6902 {
6903 delete [] bounds;
6904 return CFList (G (y-eval,y));
6905 }
6906 }
6907 if (degs.getLength() <= 1)
6908 {
6909 delete [] bounds;
6910 return smallFactors;
6911 }
6912 }
6913
6914 int index;
6916 for (CFListIterator i= smallFactors; i.hasItem(); i++)
6917 {
6918 index= 1;
6919 tmp1= mod (i.getItem(),y-eval);
6920 tmp1 /= Lc (tmp1);
6921 for (CFListIterator j= bufUniFactors; j.hasItem(); j++, index++)
6922 {
6923 tmp2= mod (j.getItem(), y);
6924 tmp2 /= Lc (tmp2);
6925 if (tmp1 == tmp2)
6926 {
6927 index++;
6928 j.remove(index);
6929 break;
6930 }
6931 }
6932 }
6933
6934 if (bufUniFactors.isEmpty())
6935 {
6936 delete [] bounds;
6937 return smallFactors;
6938 }
6939
6940 if (success)
6941 {
6942 F= H;
6943 delete [] bounds;
6944 bounds= computeBounds (F, d, isIrreducible);
6945 if (isIrreducible)
6946 {
6947 smallFactors.append (F (y-eval,y));
6948 delete [] bounds;
6949 return smallFactors;
6950 }
6951 LCF= LC (F, 1);
6952
6953 minBound= bounds[0];
6954 for (int i= 1; i < d; i++)
6955 {
6956 if (bounds[i] != 0)
6957 minBound= tmin (minBound, bounds[i]);
6958 }
6959 Pi= CFArray();
6960 diophant= CFList();
6961 liftBound= 2*totaldegree (F) - 1;
6962 M= CFMatrix (liftBound, bufUniFactors.length());
6963 DegreePattern bufDegs= DegreePattern (bufUniFactors);
6964 degs.intersect (bufDegs);
6965 degs.refine();
6966 if (degs.getLength() <= 1)
6967 {
6968 smallFactors.append (F (y-eval,y));
6969 delete [] bounds;
6970 return smallFactors;
6971 }
6972 }
6973
6974 bool reduceFq2Fp= (degree (F) > getCharacteristic());
6975 bufUniFactors.insert (LCF);
6976 int l= 1;
6977
6978#ifdef HAVE_FLINT
6979 nmod_mat_t FLINTN;
6980#endif
6981
6983 {
6985 zz_p::init (getCharacteristic());
6986 }
6987 mat_zz_p NTLN;
6988
6989 if (alpha.level() != 1)
6990 {
6991 zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha));
6992 zz_pE::init (NTLMipo);
6993 }
6994 mat_zz_pE NTLNe;
6995
6996 if (alpha.level() == 1)
6997 {
6998#ifdef HAVE_FLINT
6999 nmod_mat_init (FLINTN, bufUniFactors.length()-1, bufUniFactors.length()-1, getCharacteristic());
7000 for (long i= bufUniFactors.length()-2; i >= 0; i--)
7001 nmod_mat_entry (FLINTN, i, i)= 1;
7002#else
7003 ident (NTLN, bufUniFactors.length() - 1);
7004#endif
7005 }
7006 else
7007 {
7008 if (reduceFq2Fp)
7009#ifdef HAVE_FLINT
7010 {
7011 nmod_mat_init (FLINTN, bufUniFactors.length()-1, bufUniFactors.length()-1, getCharacteristic());
7012 for (long i= bufUniFactors.length()-2; i >= 0; i--)
7013 nmod_mat_entry (FLINTN, i, i)= 1;
7014 }
7015#else
7016 ident (NTLN, bufUniFactors.length() - 1);
7017#endif
7018 else
7019 ident (NTLNe, bufUniFactors.length() - 1);
7020 }
7021 bool irreducible= false;
7022 CFArray bufQ= CFArray (bufUniFactors.length() - 1);
7023
7024 int oldL;
7025 TIMING_START (fac_fq_till_reduced);
7026 if (success)
7027 {
7028 int start= 0;
7029 if (alpha.level() == 1)
7030 oldL= liftAndComputeLattice (F, bounds, d, start, liftBound, minBound,
7031#ifdef HAVE_FLINT
7032 bufUniFactors, FLINTN, diophant, M, Pi, bufQ,
7033#else
7034 bufUniFactors, NTLN, diophant, M, Pi, bufQ,
7035#endif
7037 );
7038 else
7039 {
7040 if (reduceFq2Fp)
7041 oldL= liftAndComputeLatticeFq2Fp (F, bounds, d, start, liftBound,
7042#ifdef HAVE_FLINT
7043 minBound, bufUniFactors, FLINTN,
7044#else
7045 minBound, bufUniFactors, NTLN,
7046#endif
7047 diophant, M, Pi, bufQ, irreducible,
7048 alpha
7049 );
7050 else
7051 oldL= liftAndComputeLattice (F, bounds, d, start, liftBound, minBound,
7052 bufUniFactors, NTLNe, diophant, M, Pi, bufQ,
7054 );
7055 }
7056 }
7057 else
7058 {
7059 if (alpha.level() == 1)
7060 {
7061 oldL= liftAndComputeLattice (F, bounds, d, minBound + 1, liftBound,
7062#ifdef HAVE_FLINT
7063 minBound, bufUniFactors, FLINTN, diophant, M,
7064#else
7065 minBound, bufUniFactors, NTLN, diophant, M,
7066#endif
7067 Pi, bufQ, irreducible
7068 );
7069 }
7070 else
7071 {
7072 if (reduceFq2Fp)
7073 oldL= liftAndComputeLatticeFq2Fp (F, bounds, d, minBound + 1,
7074 liftBound, minBound, bufUniFactors,
7075#ifdef HAVE_FLINT
7076 FLINTN, diophant, M, Pi, bufQ,
7077#else
7078 NTLN, diophant, M, Pi, bufQ,
7079#endif
7081 );
7082 else
7083 oldL= liftAndComputeLattice (F, bounds, d, minBound + 1, liftBound,
7084 minBound, bufUniFactors, NTLNe, diophant,
7085 M, Pi, bufQ, irreducible
7086 );
7087 }
7088 }
7089
7090 TIMING_END_AND_PRINT (fac_fq_till_reduced,
7091 "time to compute a reduced lattice: ");
7092 bufUniFactors.removeFirst();
7093 if (oldL > liftBound)
7094 {
7095#ifdef HAVE_FLINT
7096 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7097 nmod_mat_clear (FLINTN);
7098#endif
7099 delete [] bounds;
7100 return Union (smallFactors,
7101 factorRecombination (bufUniFactors, F,
7102 power (y, degree (F) + 1),
7103 degs, eval, 1, bufUniFactors.length()/2
7104 )
7105 );
7106 }
7107
7108 l= oldL;
7109 if (irreducible)
7110 {
7111#ifdef HAVE_FLINT
7112 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7113 nmod_mat_clear (FLINTN);
7114#endif
7115 delete [] bounds;
7116 return Union (CFList (F(y-eval,y)), smallFactors);
7117 }
7118
7119 CanonicalForm yToL= power (y,l);
7120
7121 CFList result;
7122 if (l >= degree (F) + 1)
7123 {
7124 int * factorsFoundIndex;
7125 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7126 {
7127#ifdef HAVE_FLINT
7128 factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
7129 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
7130#else
7131 factorsFoundIndex= new int [NTLN.NumCols()];
7132 for (long i= 0; i < NTLN.NumCols(); i++)
7133#endif
7134 factorsFoundIndex[i]= 0;
7135 }
7136 else
7137 {
7138 factorsFoundIndex= new int [NTLNe.NumCols()];
7139 for (long i= 0; i < NTLNe.NumCols(); i++)
7140 factorsFoundIndex[i]= 0;
7141 }
7142 int factorsFound= 0;
7143 CanonicalForm bufF= F;
7144 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7145 reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
7146#ifdef HAVE_FLINT
7147 factorsFound, factorsFoundIndex, FLINTN, eval, false
7148#else
7149 factorsFound, factorsFoundIndex, NTLN, eval, false
7150#endif
7151 );
7152 else
7153 reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
7154 factorsFound, factorsFoundIndex, NTLNe, eval, false
7155 );
7156 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7157 {
7158#ifdef HAVE_FLINT
7159 if (result.length() == nmod_mat_ncols (FLINTN))
7160 {
7161 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7162 nmod_mat_clear (FLINTN);
7163#else
7164 if (result.length() == NTLN.NumCols())
7165 {
7166#endif
7167 delete [] factorsFoundIndex;
7168 delete [] bounds;
7169 return Union (result, smallFactors);
7170 }
7171 }
7172 else
7173 {
7174 if (result.length() == NTLNe.NumCols())
7175 {
7176 delete [] factorsFoundIndex;
7177 delete [] bounds;
7178 return Union (result, smallFactors);
7179 }
7180 }
7181 delete [] factorsFoundIndex;
7182 }
7183 if (l >= liftBound)
7184 {
7185 int * factorsFoundIndex;
7186 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7187 {
7188#ifdef HAVE_FLINT
7189 factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
7190 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
7191#else
7192 factorsFoundIndex= new int [NTLN.NumCols()];
7193 for (long i= 0; i < NTLN.NumCols(); i++)
7194#endif
7195 factorsFoundIndex[i]= 0;
7196 }
7197 else
7198 {
7199 factorsFoundIndex= new int [NTLNe.NumCols()];
7200 for (long i= 0; i < NTLNe.NumCols(); i++)
7201 factorsFoundIndex[i]= 0;
7202 }
7203 CanonicalForm bufF= F;
7204 int factorsFound= 0;
7205 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7206 reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
7207#ifdef HAVE_FLINT
7208 factorsFound, factorsFoundIndex, FLINTN, eval, false
7209#else
7210 factorsFound, factorsFoundIndex, NTLN, eval, false
7211#endif
7212 );
7213 else
7214 reconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
7215 factorsFound, factorsFoundIndex, NTLNe, eval, false
7216 );
7217 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7218 {
7219#ifdef HAVE_FLINT
7220 if (result.length() == nmod_mat_ncols(FLINTN))
7221 {
7222 nmod_mat_clear (FLINTN);
7223#else
7224 if (result.length() == NTLN.NumCols())
7225 {
7226#endif
7227 delete [] factorsFoundIndex;
7228 delete [] bounds;
7229 return Union (result, smallFactors);
7230 }
7231 }
7232 else
7233 {
7234 if (result.length() == NTLNe.NumCols())
7235 {
7236 delete [] factorsFoundIndex;
7237 delete [] bounds;
7238 return Union (result, smallFactors);
7239 }
7240 }
7241 delete [] factorsFoundIndex;
7242 }
7243
7244 result= CFList();
7245 bool beenInThres= false;
7246 int thres= 100;
7247 if (l <= thres)
7248 {
7249 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7250 {
7251#ifdef HAVE_FLINT
7252 if (nmod_mat_ncols (FLINTN) < bufUniFactors.length())
7253 {
7254 refineAndRestartLift (F, FLINTN, liftBound, l, bufUniFactors, M, Pi,
7255#else
7256 if (NTLN.NumCols() < bufUniFactors.length())
7257 {
7258 refineAndRestartLift (F, NTLN, liftBound, l, bufUniFactors, M, Pi,
7259#endif
7260 diophant
7261 );
7262 beenInThres= true;
7263 }
7264 }
7265 else
7266 {
7267 if (NTLNe.NumCols() < bufUniFactors.length())
7268 {
7269 refineAndRestartLift (F, NTLNe, liftBound, l, bufUniFactors, M, Pi,
7270 diophant
7271 );
7272 beenInThres= true;
7273 }
7274 }
7275 }
7276
7277 CanonicalForm bufF= F;
7278 int factorsFound= 0;
7279 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7280 {
7281#ifdef HAVE_FLINT
7282 result= earlyReconstructionAndLifting (F, FLINTN, bufF, bufUniFactors, l,
7283#else
7284 result= earlyReconstructionAndLifting (F, NTLN, bufF, bufUniFactors, l,
7285#endif
7286 factorsFound, beenInThres, M, Pi,
7287 diophant, symmetric, eval
7288 );
7289
7290#ifdef HAVE_FLINT
7291 if (result.length() == nmod_mat_ncols (FLINTN))
7292 {
7293 nmod_mat_clear (FLINTN);
7294#else
7295 if (result.length() == NTLN.NumCols())
7296 {
7297#endif
7298 delete [] bounds;
7299 return Union (result, smallFactors);
7300 }
7301 }
7302 else
7303 {
7304 result= earlyReconstructionAndLifting (F, NTLNe, bufF, bufUniFactors, l,
7305 factorsFound, beenInThres, M, Pi,
7306 diophant, symmetric, eval
7307 );
7308
7309 if (result.length() == NTLNe.NumCols())
7310 {
7311 delete [] bounds;
7312 return Union (result, smallFactors);
7313 }
7314 }
7315
7316 if (result.length() > 0)
7317 {
7318 if (beenInThres)
7319 {
7320 int index;
7321 for (CFListIterator i= result; i.hasItem(); i++)
7322 {
7323 index= 1;
7324 tmp1= mod (i.getItem(), y-eval);
7325 tmp1 /= Lc (tmp1);
7326 for (CFListIterator j= bufUniFactors; j.hasItem(); j++, index++)
7327 {
7328 tmp2= mod (j.getItem(), y);
7329 tmp2 /= Lc (tmp2);
7330 if (tmp1 == tmp2)
7331 {
7332 index++;
7333 j.remove(index);
7334 break;
7335 }
7336 }
7337 }
7338 }
7339 else
7340 {
7341 int * zeroOne;
7342 long numCols, numRows;
7343 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7344 {
7345#ifdef HAVE_FLINT
7346 numCols= nmod_mat_ncols (FLINTN);
7347 numRows= nmod_mat_nrows (FLINTN);
7348 zeroOne= extractZeroOneVecs (FLINTN);
7349#else
7350 numCols= NTLN.NumCols();
7351 numRows= NTLN.NumRows();
7352 zeroOne= extractZeroOneVecs (NTLN);
7353#endif
7354 }
7355 else
7356 {
7357 numCols= NTLNe.NumCols();
7358 numRows= NTLNe.NumRows();
7359 zeroOne= extractZeroOneVecs (NTLNe);
7360 }
7361 CFList bufBufUniFactors= bufUniFactors;
7362 CFListIterator iter, iter2;
7364 CFList factorsConsidered;
7365 CanonicalForm tmp;
7366 for (int i= 0; i < numCols; i++)
7367 {
7368 if (zeroOne [i] == 0)
7369 continue;
7370 iter= bufUniFactors;
7371 buf= 1;
7372 factorsConsidered= CFList();
7373 for (int j= 0; j < numRows; j++, iter++)
7374 {
7375 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7376 {
7377#ifdef HAVE_FLINT
7378 if (!(nmod_mat_entry (FLINTN, j,i) == 0))
7379#else
7380 if (!IsZero (NTLN (j + 1,i + 1)))
7381#endif
7382 {
7383 factorsConsidered.append (iter.getItem());
7384 buf *= mod (iter.getItem(), y);
7385 }
7386 }
7387 else
7388 {
7389 if (!IsZero (NTLNe (j + 1,i + 1)))
7390 {
7391 factorsConsidered.append (iter.getItem());
7392 buf *= mod (iter.getItem(), y);
7393 }
7394 }
7395 }
7396 buf /= Lc (buf);
7397 for (iter2= result; iter2.hasItem(); iter2++)
7398 {
7399 tmp= mod (iter2.getItem(), y-eval);
7400 tmp /= Lc (tmp);
7401 if (tmp == buf)
7402 {
7403 bufBufUniFactors= Difference (bufBufUniFactors, factorsConsidered);
7404 break;
7405 }
7406 }
7407 }
7408 bufUniFactors= bufBufUniFactors;
7409 delete [] zeroOne;
7410 }
7411
7412 int oldNumCols;
7413 CFList resultBufF;
7414 irreducible= false;
7415
7416 if (alpha.level() == 1)
7417 {
7418#ifdef HAVE_FLINT
7419 oldNumCols= nmod_mat_ncols (FLINTN);
7420#else
7421 oldNumCols= NTLN.NumCols();
7422#endif
7423 resultBufF= increasePrecision (bufF, bufUniFactors, factorsFound,
7424 oldNumCols, oldL, l, eval
7425 );
7426 }
7427 else
7428 {
7429 if (reduceFq2Fp)
7430 {
7431#ifdef HAVE_FLINT
7432 oldNumCols= nmod_mat_ncols (FLINTN);
7433#else
7434 oldNumCols= NTLN.NumCols();
7435#endif
7436
7437 resultBufF= increasePrecisionFq2Fp (bufF, bufUniFactors, factorsFound,
7438 oldNumCols, oldL, alpha, l, eval
7439 );
7440 }
7441 else
7442 {
7443 oldNumCols= NTLNe.NumCols();
7444
7445 resultBufF= increasePrecision (bufF, bufUniFactors, factorsFound,
7446 oldNumCols, oldL, alpha, l, eval
7447 );
7448 }
7449 }
7450
7451 if (bufUniFactors.isEmpty() || degree (bufF) <= 0)
7452 {
7453#ifdef HAVE_FLINT
7454 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7455 nmod_mat_clear (FLINTN);
7456#endif
7457 delete [] bounds;
7458 result= Union (resultBufF, result);
7459 return Union (result, smallFactors);
7460 }
7461
7462 for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
7463 i.getItem()= mod (i.getItem(), y);
7464
7465 result= Union (result, resultBufF);
7466 result= Union (result, smallFactors);
7467 delete [] bounds;
7468 DegreePattern bufDegs= DegreePattern (bufUniFactors);
7469 degs.intersect (bufDegs);
7470 degs.refine();
7471 if (degs.getLength() == 1 || bufUniFactors.length() == 1)
7472 {
7473#ifdef HAVE_FLINT
7474 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7475 nmod_mat_clear (FLINTN);
7476#endif
7477 result.append (bufF (y-eval,y));
7478 return result;
7479 }
7480#ifdef HAVE_FLINT
7481 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7482 nmod_mat_clear (FLINTN);
7483#endif
7484 return Union (result, henselLiftAndLatticeRecombi (bufF, bufUniFactors,
7485 alpha, degs, symmetric,
7486 eval
7487 )
7488 );
7489 }
7490
7491 if (l < liftBound)
7492 {
7493 if (alpha.level() == 1)
7494 {
7495 result=increasePrecision (F, bufUniFactors, oldL, l, d, bounds, bufQ,
7496#ifdef HAVE_FLINT
7497 FLINTN, eval
7498#else
7499 NTLN, eval
7500#endif
7501 );
7502 }
7503 else
7504 {
7505 if (reduceFq2Fp)
7506 {
7507 result=increasePrecisionFq2Fp (F, bufUniFactors, oldL, l, d, bounds,
7508#ifdef HAVE_FLINT
7509 bufQ, FLINTN, alpha, eval
7510#else
7511 bufQ, NTLN, alpha, eval
7512#endif
7513 );
7514 }
7515 else
7516 {
7517 result=increasePrecision (F, bufUniFactors, oldL, l, d, bounds, bufQ,
7518 NTLNe, eval
7519 );
7520 }
7521 }
7522 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7523 {
7524#ifdef HAVE_FLINT
7525 if (result.length()== nmod_mat_ncols (FLINTN))
7526 {
7527 nmod_mat_clear (FLINTN);
7528#else
7529 if (result.length()== NTLN.NumCols())
7530 {
7531#endif
7532 delete [] bounds;
7533 result= Union (result, smallFactors);
7534 return result;
7535 }
7536 }
7537 else
7538 {
7539 if (result.length()== NTLNe.NumCols())
7540 {
7541 delete [] bounds;
7542 result= Union (result, smallFactors);
7543 return result;
7544 }
7545 }
7546
7547 if (result.isEmpty())
7548 {
7549 if (alpha.level() == 1)
7550 result= furtherLiftingAndIncreasePrecision (F,bufUniFactors, l,
7551#ifdef HAVE_FLINT
7552 liftBound,d,bounds,FLINTN,
7553#else
7554 liftBound, d, bounds, NTLN,
7555#endif
7556 diophant, M, Pi, bufQ, eval
7557 );
7558 else
7559 {
7560 if (reduceFq2Fp)
7562 liftBound, d, bounds,
7563#ifdef HAVE_FLINT
7564 FLINTN, diophant, M,
7565#else
7566 NTLN, diophant, M,
7567#endif
7568 Pi, bufQ, alpha, eval
7569 );
7570 else
7571 result= furtherLiftingAndIncreasePrecision (F,bufUniFactors, l,
7572 liftBound, d, bounds,
7573 NTLNe, diophant, M,
7574 Pi, bufQ, eval
7575 );
7576 }
7577
7578 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7579 {
7580#ifdef HAVE_FLINT
7581 if (result.length() == nmod_mat_ncols (FLINTN))
7582 {
7583 nmod_mat_clear (FLINTN);
7584#else
7585 if (result.length() == NTLN.NumCols())
7586 {
7587#endif
7588 delete [] bounds;
7589 result= Union (result, smallFactors);
7590 return result;
7591 }
7592 }
7593 else
7594 {
7595 if (result.length() == NTLNe.NumCols())
7596 {
7597 delete [] bounds;
7598 result= Union (result, smallFactors);
7599 return result;
7600 }
7601 }
7602 }
7603 }
7604
7605 DEBOUTLN (cerr, "lattice recombination failed");
7606
7607 DegreePattern bufDegs= DegreePattern (bufUniFactors);
7608 degs.intersect (bufDegs);
7609 degs.refine();
7610
7611 delete [] bounds;
7612 bounds= computeBounds (F, d, isIrreducible);
7613#ifdef HAVE_FLINT
7614 if (alpha.level() == 1 || (alpha.level() != 1 && reduceFq2Fp))
7615 nmod_mat_clear (FLINTN);
7616#endif
7617 if (isIrreducible)
7618 {
7619 delete [] bounds;
7620 result= Union (result, smallFactors);
7621 result.append (F (y-eval,y));
7622 return result;
7623 }
7624 minBound= bounds[0];
7625 for (int i= 1; i < d; i++)
7626 {
7627 if (bounds[i] != 0)
7628 minBound= tmin (minBound, bounds[i]);
7629 }
7630
7631 if (minBound > 16 || result.length() == 0)
7632 {
7633 result= Union (result, smallFactors);
7634 CanonicalForm MODl= power (y, degree (F) + 1);
7635 delete [] bounds;
7636 return Union (result, factorRecombination (bufUniFactors, F, MODl, degs,
7637 eval, 1, bufUniFactors.length()/2
7638 )
7639 );
7640 }
7641 else
7642 {
7643 result= Union (result, smallFactors);
7644 for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
7645 i.getItem()= mod (i.getItem(), y);
7646 delete [] bounds;
7647 return Union (result, henselLiftAndLatticeRecombi (F, bufUniFactors, alpha,
7648 degs,symmetric, eval
7649 )
7650 );
7651 }
7652}
7653#endif
7654
7655#ifdef HAVE_NTL // findMinPoly
7658 int& degMipo
7659 )
7660{
7661 bool GF= (CFFactory::gettype() == GaloisFieldDomain);
7662 Variable alpha= info.getAlpha();
7663 if (GF)
7664 {
7665 degMipo= getGFDegree();
7666 CanonicalForm GFMipo= gf_mipo;
7668 GFMipo.mapinto();
7669 alpha= rootOf (GFMipo);
7670 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
7671 }
7672 else
7673 {
7674 alpha= info.getAlpha();
7675 degMipo= degree (getMipo (alpha));
7676 }
7677
7678 Variable gamma;
7679 CanonicalForm primElemAlpha, imPrimElemAlpha;
7680 if ((!GF && evaluation != alpha) || (GF && evaluation != getGFGenerator()))
7681 {
7682 CanonicalForm bufEvaluation;
7683 if (GF)
7684 {
7686 bufEvaluation= GF2FalphaRep (evaluation, alpha);
7687 }
7688 else
7689 bufEvaluation= evaluation;
7690 CanonicalForm mipo= findMinPoly (bufEvaluation, alpha);
7691 gamma= rootOf (mipo);
7692 Variable V_buf;
7693 bool fail= false;
7694 primElemAlpha= primitiveElement (alpha, V_buf, fail);
7695 imPrimElemAlpha= map (primElemAlpha, alpha, bufEvaluation, gamma);
7696
7697 if (GF)
7698 setCharacteristic (getCharacteristic(), degMipo, info.getGFName());
7699 }
7700 else
7701 gamma= alpha;
7702 ExtensionInfo info2= ExtensionInfo (alpha, gamma, primElemAlpha,
7703 imPrimElemAlpha, 1, info.getGFName(), true
7704 );
7705
7706 return info2;
7707}
7708#endif
7709
7710#ifdef HAVE_NTL // extSieveSmallFactors,...
7711CFList
7713 const ExtensionInfo& extInfo, const
7714 DegreePattern& degPat, const CanonicalForm& eval
7715 )
7716{
7718 ExtensionInfo info= extInfo;
7720 DegreePattern degs= degPat;
7721 CanonicalForm F= G;
7722 Variable x= Variable (1);
7723 Variable y= F.mvar();
7724 CFList bufUniFactors= uniFactors;
7725
7726
7727 int degMipo;
7728 ExtensionInfo info2= init4ext (info, evaluation, degMipo);
7729
7730 CFList source, dest;
7731 CanonicalForm LCF= LC (F, 1);
7732
7733 int d;
7734 bool isIrreducible= false;
7735 int* bounds= computeBounds (F, d, isIrreducible);
7736 if (isIrreducible)
7737 {
7738 delete [] bounds;
7739 CFList source, dest;
7740 CanonicalForm tmp= G (y - evaluation, y);
7741 tmp= mapDown (tmp, info, source, dest);
7742 return CFList (tmp);
7743 }
7744 int minBound= bounds[0];
7745 for (int i= 1; i < d; i++)
7746 {
7747 if (bounds[i] != 0)
7748 minBound= tmin (minBound, bounds[i]);
7749 }
7750
7751
7752 CFArray Pi;
7753 CFList diophant;
7754 int liftBound= tmax ((2*totaldegree (F) - 1)/degMipo + 1, degree (F) + 1 +
7755 degree (LC (F, 1)));
7756 CFMatrix M= CFMatrix (liftBound, bufUniFactors.length());
7757
7758 CFList smallFactors;
7760 bool success= false;
7761 smallFactors= extSieveSmallFactors (F, bufUniFactors, degs, H, diophant, Pi,
7762 M, success, minBound + 1, evaluation, info
7763 );
7764
7765 if (smallFactors.length() > 0)
7766 {
7767 if (smallFactors.length() == 1)
7768 {
7769 if (smallFactors.getFirst() == F)
7770 {
7771 delete [] bounds;
7772 CFList source, dest;
7773 CanonicalForm tmp= G (y - evaluation, y);
7774 tmp= mapDown (tmp, info, source, dest);
7775 return CFList (tmp);
7776 }
7777 }
7778 if (degs.getLength() <= 1)
7779 {
7780 delete [] bounds;
7781 return smallFactors;
7782 }
7783 }
7784
7785 int index;
7787 for (CFListIterator i= smallFactors; i.hasItem(); i++)
7788 {
7789 index= 1;
7790 tmp1= mod (i.getItem(), y - evaluation);
7791 tmp1 /= Lc (tmp1);
7792 for (CFListIterator j= bufUniFactors; j.hasItem(); j++, index++)
7793 {
7794 tmp2= mod (j.getItem(), y);
7795 tmp2 /= Lc (tmp2);
7796 if (tmp1 == tmp2)
7797 {
7798 index++;
7799 j.remove(index);
7800 break;
7801 }
7802 }
7803 }
7804
7805 if (bufUniFactors.isEmpty())
7806 {
7807 delete [] bounds;
7808 return smallFactors;
7809 }
7810
7811 if (success)
7812 {
7813 F= H/Lc(H);
7814 delete [] bounds;
7815 bounds= computeBounds (F, d, isIrreducible);
7816 if (isIrreducible)
7817 {
7818 delete [] bounds;
7819 CFList source, dest;
7820 CanonicalForm tmp= F (y - evaluation, y);
7821 tmp= mapDown (tmp, info, source, dest);
7822 smallFactors.append (tmp);
7823 return smallFactors;
7824 }
7825 LCF= LC (F, 1);
7826
7827 minBound= bounds[0];
7828 for (int i= 1; i < d; i++)
7829 {
7830 if (bounds[i] != 0)
7831 minBound= tmin (minBound, bounds[i]);
7832 }
7833 Pi= CFArray();
7834 diophant= CFList();
7835 liftBound=tmax ((2*totaldegree (F) - 1)/degMipo + 1, degree (F) + 1 +
7836 degree (LC (F, 1)));
7837 M= CFMatrix (liftBound, bufUniFactors.length());
7838 DegreePattern bufDegs= DegreePattern (bufUniFactors);
7839 degs.intersect (bufDegs);
7840 degs.refine();
7841 if (degs.getLength() <= 1)
7842 {
7843 delete [] bounds;
7844 CFList source, dest;
7845 CanonicalForm tmp= F (y - evaluation, y);
7846 tmp= mapDown (tmp, info, source, dest);
7847 smallFactors.append (tmp);
7848 return smallFactors;
7849 }
7850 }
7851
7852 bufUniFactors.insert (LCF);
7853 int l= 1;
7854
7855#ifdef HAVE_FLINT
7856 nmod_mat_t FLINTN;
7857 nmod_mat_init (FLINTN, bufUniFactors.length()-1, bufUniFactors.length()-1,
7859 for (long i= bufUniFactors.length()-2; i >= 0; i--)
7860 nmod_mat_entry (FLINTN, i, i)= 1;
7861#else
7863 {
7865 zz_p::init (getCharacteristic());
7866 }
7867 zz_pX NTLMipo;
7868 mat_zz_p NTLN;
7869
7870 ident (NTLN, bufUniFactors.length() - 1);
7871#endif
7872 bool irreducible= false;
7873 CFArray bufQ= CFArray (bufUniFactors.length() - 1);
7874
7875 int oldL;
7876 TIMING_START (fac_fq_till_reduced);
7877 if (success)
7878 {
7879 int start= 0;
7880#ifdef HAVE_FLINT
7881 oldL= extLiftAndComputeLattice (F, bounds, d, liftBound, minBound, start,
7882 bufUniFactors, FLINTN, diophant,M, Pi, bufQ,
7883 irreducible, evaluation, info2, source, dest
7884 );
7885#else
7886 oldL= extLiftAndComputeLattice (F, bounds, d, liftBound, minBound, start,
7887 bufUniFactors, NTLN, diophant, M, Pi, bufQ,
7888 irreducible, evaluation, info2, source, dest
7889 );
7890#endif
7891 }
7892 else
7893 {
7894#ifdef HAVE_FLINT
7895 oldL= extLiftAndComputeLattice (F, bounds, d, liftBound, minBound,
7896 minBound+1, bufUniFactors, FLINTN, diophant,
7897 M, Pi, bufQ, irreducible, evaluation, info2,
7898 source, dest
7899 );
7900#else
7901 oldL= extLiftAndComputeLattice (F, bounds, d, liftBound, minBound,
7902 minBound + 1, bufUniFactors, NTLN, diophant,
7903 M, Pi, bufQ, irreducible, evaluation, info2,
7904 source, dest
7905 );
7906#endif
7907 }
7908 TIMING_END_AND_PRINT (fac_fq_till_reduced,
7909 "time to compute a reduced lattice: ");
7910
7911 bufUniFactors.removeFirst();
7912 if (oldL > liftBound)
7913 {
7914#ifdef HAVE_FLINT
7915 nmod_mat_clear (FLINTN);
7916#endif
7917 delete [] bounds;
7918 return Union (smallFactors, extFactorRecombination
7919 (bufUniFactors, F,
7920 power (y, degree (F) + 1),info,
7921 degs, evaluation, 1, bufUniFactors.length()/2
7922 )
7923 );
7924 }
7925
7926 l= oldL;
7927 if (irreducible)
7928 {
7929#ifdef HAVE_FLINT
7930 nmod_mat_clear (FLINTN);
7931#endif
7932 delete [] bounds;
7933 CFList source, dest;
7934 CanonicalForm tmp= F (y - evaluation, y);
7935 tmp= mapDown (tmp, info, source, dest);
7936 return Union (CFList (tmp), smallFactors);
7937 }
7938
7939 CanonicalForm yToL= power (y,l);
7940
7941 CFList result;
7942 if (l >= degree (F) + 1)
7943 {
7944 int * factorsFoundIndex;
7945
7946#ifdef HAVE_FLINT
7947 factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
7948 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
7949#else
7950 factorsFoundIndex= new int [NTLN.NumCols()];
7951 for (long i= 0; i < NTLN.NumCols(); i++)
7952#endif
7953 factorsFoundIndex[i]= 0;
7954
7955 int factorsFound= 0;
7956 CanonicalForm bufF= F;
7957
7958#ifdef HAVE_FLINT
7959 extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
7960 factorsFound, factorsFoundIndex, FLINTN, false, info,
7962 );
7963
7964 if (result.length() == nmod_mat_ncols (FLINTN))
7965 {
7966 nmod_mat_clear (FLINTN);
7967#else
7968 extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
7969 factorsFound, factorsFoundIndex, NTLN, false, info,
7971 );
7972
7973 if (result.length() == NTLN.NumCols())
7974 {
7975#endif
7976 delete [] factorsFoundIndex;
7977 delete [] bounds;
7978 return Union (result, smallFactors);
7979 }
7980
7981 delete [] factorsFoundIndex;
7982 }
7983 if (l >= liftBound)
7984 {
7985 int * factorsFoundIndex;
7986#ifdef HAVE_FLINT
7987 factorsFoundIndex= new int [nmod_mat_ncols (FLINTN)];
7988 for (long i= 0; i < nmod_mat_ncols (FLINTN); i++)
7989#else
7990 factorsFoundIndex= new int [NTLN.NumCols()];
7991 for (long i= 0; i < NTLN.NumCols(); i++)
7992#endif
7993 factorsFoundIndex[i]= 0;
7994 CanonicalForm bufF= F;
7995 int factorsFound= 0;
7996
7997#ifdef HAVE_FLINT
7998 extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
7999 factorsFound, factorsFoundIndex, FLINTN, false,
8001 );
8002
8003 if (result.length() == nmod_mat_ncols (FLINTN))
8004 {
8005 nmod_mat_clear (FLINTN);
8006#else
8007 extReconstructionTry (result, bufF, bufUniFactors, degree (F) + 1,
8008 factorsFound, factorsFoundIndex, NTLN, false,
8010 );
8011
8012 if (result.length() == NTLN.NumCols())
8013 {
8014#endif
8015 delete [] factorsFoundIndex;
8016 delete [] bounds;
8017 return Union (result, smallFactors);
8018 }
8019 delete [] factorsFoundIndex;
8020 }
8021
8022 result= CFList();
8023 bool beenInThres= false;
8024 int thres= 100;
8025#ifdef HAVE_FLINT
8026 if (l <= thres && bufUniFactors.length() > nmod_mat_ncols (FLINTN))
8027 {
8028 refineAndRestartLift (F, FLINTN, 2*totaldegree (F)-1, l, bufUniFactors, M, Pi,
8029 diophant
8030 );
8031#else
8032 if (l <= thres && bufUniFactors.length() > NTLN.NumCols())
8033 {
8034 refineAndRestartLift (F, NTLN, 2*totaldegree (F)-1, l, bufUniFactors, M, Pi,
8035 diophant
8036 );
8037#endif
8038 beenInThres= true;
8039 }
8040
8041
8042 CanonicalForm bufF= F;
8043 int factorsFound= 0;
8044
8045#ifdef HAVE_FLINT
8046 result= extEarlyReconstructionAndLifting (F, FLINTN, bufF, bufUniFactors, l,
8047 factorsFound, beenInThres, M, Pi,
8048 diophant, info, evaluation
8049 );
8050
8051 if (result.length() == nmod_mat_ncols (FLINTN))
8052 {
8053 nmod_mat_clear (FLINTN);
8054#else
8055 result= extEarlyReconstructionAndLifting (F, NTLN, bufF, bufUniFactors, l,
8056 factorsFound, beenInThres, M, Pi,
8057 diophant, info, evaluation
8058 );
8059
8060 if (result.length() == NTLN.NumCols())
8061 {
8062#endif
8063 delete [] bounds;
8064 return Union (result, smallFactors);
8065 }
8066
8067 if (result.length() > 0)
8068 {
8069 if (beenInThres)
8070 {
8071 int index;
8072 for (CFListIterator i= result; i.hasItem(); i++)
8073 {
8074 index= 1;
8075 tmp1= mod (i.getItem(), y-evaluation);
8076 tmp1 /= Lc (tmp1);
8077 for (CFListIterator j= bufUniFactors; j.hasItem(); j++, index++)
8078 {
8079 tmp2= mod (j.getItem(), y);
8080 tmp2 /= Lc (tmp2);
8081 if (tmp1 == tmp2)
8082 {
8083 index++;
8084 j.remove(index);
8085 break;
8086 }
8087 }
8088 }
8089 }
8090 else
8091 {
8092#ifdef HAVE_FLINT
8093 int * zeroOne= extractZeroOneVecs (FLINTN);
8094#else
8095 int * zeroOne= extractZeroOneVecs (NTLN);
8096#endif
8097 CFList bufBufUniFactors= bufUniFactors;
8098 CFListIterator iter, iter2;
8100 CFList factorsConsidered;
8101#ifdef HAVE_FLINT
8102 for (int i= 0; i < nmod_mat_ncols (FLINTN); i++)
8103#else
8104 for (int i= 0; i < NTLN.NumCols(); i++)
8105#endif
8106 {
8107 if (zeroOne [i] == 0)
8108 continue;
8109 iter= bufUniFactors;
8110 buf= 1;
8111 factorsConsidered= CFList();
8112#ifdef HAVE_FLINT
8113 for (int j= 0; j < nmod_mat_nrows (FLINTN); j++, iter++)
8114 {
8115 if (!(nmod_mat_entry (FLINTN, j, i) == 0))
8116#else
8117 for (int j= 0; j < NTLN.NumRows(); j++, iter++)
8118 {
8119 if (!IsZero (NTLN (j + 1,i + 1)))
8120#endif
8121 {
8122 factorsConsidered.append (iter.getItem());
8123 buf *= mod (iter.getItem(), y);
8124 }
8125 }
8126 buf /= Lc (buf);
8127 for (iter2= result; iter2.hasItem(); iter2++)
8128 {
8129 CanonicalForm tmp= mod (iter2.getItem(), y - evaluation);
8130 tmp /= Lc (tmp);
8131 if (tmp == buf)
8132 {
8133 bufBufUniFactors= Difference (bufBufUniFactors, factorsConsidered);
8134 break;
8135 }
8136 }
8137 }
8138 bufUniFactors= bufBufUniFactors;
8139 delete [] zeroOne;
8140 }
8141
8142 int oldNumCols;
8143 CFList resultBufF;
8144 irreducible= false;
8145
8146#ifdef HAVE_FLINT //TODO
8147 oldNumCols= nmod_mat_ncols (FLINTN);
8148 resultBufF= extIncreasePrecision (bufF, bufUniFactors, factorsFound,
8149 oldNumCols, oldL, evaluation, info2,
8150 source, dest, l
8151 );
8152 nmod_mat_clear (FLINTN);
8153#else
8154 oldNumCols= NTLN.NumCols();
8155 resultBufF= extIncreasePrecision (bufF, bufUniFactors, factorsFound,
8156 oldNumCols, oldL, evaluation, info2,
8157 source, dest, l
8158 );
8159#endif
8160 if (bufUniFactors.isEmpty() || degree (bufF) <= 0)
8161 {
8162 delete [] bounds;
8163 result= Union (resultBufF, result);
8164 return Union (result, smallFactors);
8165 }
8166
8167 for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
8168 i.getItem()= mod (i.getItem(), y);
8169
8170 delete [] bounds;
8171 CFList bufResult;
8172 DegreePattern bufDegs= DegreePattern (bufUniFactors);
8173 degs.intersect (bufDegs);
8174 degs.refine();
8175 result= Union (result, smallFactors);
8176 if (degs.getLength() == 1 || bufUniFactors.length() == 1)
8177 {
8178 CFList source, dest;
8179 CanonicalForm tmp= bufF (y - evaluation, y);
8180 tmp= mapDown (tmp, info, source, dest);
8181 result.append (tmp);
8182 return result;
8183 }
8184 return Union (result, extHenselLiftAndLatticeRecombi (bufF, bufUniFactors,
8185 info, degs, evaluation
8186 )
8187 );
8188 }
8189
8190 if (l/degMipo < liftBound)
8191 {
8192#ifdef HAVE_FLINT
8193 result=extIncreasePrecision (F, bufUniFactors, oldL, l, d, bounds, bufQ,
8194 FLINTN, evaluation, info2, source, dest
8195 );
8196
8197 if (result.length()== nmod_mat_ncols (FLINTN))
8198 {
8199 nmod_mat_clear (FLINTN);
8200#else
8201 result=extIncreasePrecision (F, bufUniFactors, oldL, l, d, bounds, bufQ,
8202 NTLN, evaluation, info2, source, dest
8203 );
8204
8205 if (result.length()== NTLN.NumCols())
8206 {
8207#endif
8208 delete [] bounds;
8209 result= Union (result, smallFactors);
8210 return result;
8211 }
8212
8213 if (result.isEmpty())
8214 {
8215#ifdef HAVE_FLINT
8217 liftBound, d,bounds,FLINTN,
8218 diophant, M, Pi, bufQ,
8219 evaluation, info2, source,
8220 dest
8221 );
8222 if (result.length()== nmod_mat_ncols (FLINTN))
8223 {
8224 nmod_mat_clear (FLINTN);
8225#else
8227 liftBound, d, bounds, NTLN,
8228 diophant, M, Pi, bufQ,
8229 evaluation, info2, source,
8230 dest
8231 );
8232 if (result.length()== NTLN.NumCols())
8233 {
8234#endif
8235 delete [] bounds;
8236 result= Union (result, smallFactors);
8237 return result;
8238 }
8239 }
8240 }
8241
8242#ifdef HAVE_FLINT
8243 nmod_mat_clear (FLINTN);
8244#endif
8245
8246 DEBOUTLN (cerr, "lattice recombination failed");
8247
8248 DegreePattern bufDegs= DegreePattern (bufUniFactors);
8249 degs.intersect (bufDegs);
8250 degs.refine();
8251
8252 delete [] bounds;
8253 bounds= computeBounds (F, d, isIrreducible);
8254 if (isIrreducible)
8255 {
8256 delete [] bounds;
8257 CFList source, dest;
8258 CanonicalForm tmp= F (y - evaluation, y);
8259 tmp= mapDown (tmp, info, source, dest);
8260 smallFactors.append (tmp);
8261 result= Union (result, smallFactors);
8262 return result;
8263 }
8264 minBound= bounds[0];
8265 for (int i= 1; i < d; i++)
8266 {
8267 if (bounds[i] != 0)
8268 minBound= tmin (minBound, bounds[i]);
8269 }
8270
8271 if (minBound > 16 || result.length() == 0)
8272 {
8273 result= Union (result, smallFactors);
8274 CanonicalForm MODl= power (y, degree (F) + 1);
8275 delete [] bounds;
8276 return Union (result, extFactorRecombination (bufUniFactors, F, MODl, info,
8277 degs, evaluation, 1,
8278 bufUniFactors.length()/2
8279 )
8280 );
8281 }
8282 else
8283 {
8284 result= Union (result, smallFactors);
8285 for (CFListIterator i= bufUniFactors; i.hasItem(); i++)
8286 i.getItem()= mod (i.getItem(), y);
8287 delete [] bounds;
8288 return Union (result, extHenselLiftAndLatticeRecombi (F, bufUniFactors,
8289 info, degs, evaluation
8290 )
8291 );
8292 }
8293}
8294#endif
8295
8296#ifdef HAVE_NTL // henselLiftAndLatticeRecombi
8297CFList
8299
8300/// bivariate factorization over finite fields as decribed in "Factoring
8301/// multivariate polynomials over a finite field" by L Bernardin.
8302CFList
8304{
8305 if (F.inCoeffDomain())
8306 return CFList(F);
8307
8308 CanonicalForm A= F;
8309 bool GF= (CFFactory::gettype() == GaloisFieldDomain);
8310
8311 Variable alpha= info.getAlpha();
8312 Variable beta= info.getBeta();
8313 CanonicalForm gamma= info.getGamma();
8314 CanonicalForm delta= info.getDelta();
8315 int k= info.getGFDegree();
8316 bool extension= info.isInExtension();
8317 if (A.isUnivariate())
8318 {
8319 if (extension == false)
8320 return uniFactorizer (F, alpha, GF);
8321 else
8322 {
8323 CFList source, dest;
8324 A= mapDown (A, info, source, dest);
8325 return uniFactorizer (A, beta, GF);
8326 }
8327 }
8328
8329 CFMap N;
8330 A= compress (A, N);
8331 Variable y= A.mvar();
8332
8333 if (y.level() > 2) return CFList (F);
8334 Variable x= Variable (1);
8335
8336 //remove and factorize content
8337 CanonicalForm contentAx= content (A, x);
8338 CanonicalForm contentAy= content (A);
8339
8340 A= A/(contentAx*contentAy);
8341 CFList contentAxFactors, contentAyFactors;
8342
8343 if (!extension)
8344 {
8345 contentAxFactors= uniFactorizer (contentAx, alpha, GF);
8346 contentAyFactors= uniFactorizer (contentAy, alpha, GF);
8347 }
8348
8349 //trivial case
8350 CFList factors;
8351 if (A.inCoeffDomain())
8352 {
8353 append (factors, contentAxFactors);
8354 append (factors, contentAyFactors);
8355 decompress (factors, N);
8356 return factors;
8357 }
8358 else if (A.isUnivariate())
8359 {
8360 factors= uniFactorizer (A, alpha, GF);
8361 append (factors, contentAxFactors);
8362 append (factors, contentAyFactors);
8363 decompress (factors, N);
8364 return factors;
8365 }
8366
8367
8368 //check trivial case
8369 if (degree (A) == 1 || degree (A, 1) == 1 ||
8370 (size (A) == 2 && igcd (degree (A), degree (A,1))==1))
8371 {
8372 factors.append (A);
8373
8374 appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
8375 false, false, N);
8376
8377 if (!extension)
8378 normalize (factors);
8379 return factors;
8380 }
8381
8382 // check derivatives
8383 bool derivXZero= false;
8384 CanonicalForm derivX= deriv (A, x);
8385 CanonicalForm gcdDerivX;
8386 if (derivX.isZero())
8387 derivXZero= true;
8388 else
8389 {
8390 gcdDerivX= gcd (A, derivX);
8391 if (degree (gcdDerivX) > 0)
8392 {
8393 CanonicalForm g= A/gcdDerivX;
8394 CFList factorsG=
8395 Union (biFactorize (g, info), biFactorize (gcdDerivX, info));
8396 append (factorsG, contentAxFactors);
8397 append (factorsG, contentAyFactors);
8398 decompress (factorsG, N);
8399 if (!extension)
8400 normalize (factorsG);
8401 return factorsG;
8402 }
8403 }
8404 bool derivYZero= false;
8405 CanonicalForm derivY= deriv (A, y);
8406 CanonicalForm gcdDerivY;
8407 if (derivY.isZero())
8408 derivYZero= true;
8409 else
8410 {
8411 gcdDerivY= gcd (A, derivY);
8412 if (degree (gcdDerivY) > 0)
8413 {
8414 CanonicalForm g= A/gcdDerivY;
8415 CFList factorsG=
8416 Union (biFactorize (g, info), biFactorize (gcdDerivY, info));
8417 append (factorsG, contentAxFactors);
8418 append (factorsG, contentAyFactors);
8419 decompress (factorsG, N);
8420 if (!extension)
8421 normalize (factorsG);
8422 return factorsG;
8423 }
8424 }
8425 //main variable is chosen s.t. the degree in x is minimal
8426 bool swap= false;
8427 if ((degree (A) > degree (A, x)) || derivXZero)
8428 {
8429 if (!derivYZero)
8430 {
8431 A= swapvar (A, y, x);
8432 swap= derivXZero;
8433 derivXZero= derivYZero;
8434 derivYZero= swap;
8435 swap= true;
8436 }
8437 }
8438
8439 int boundsLength;
8440 bool isIrreducible= false;
8441 int * bounds= computeBounds (A, boundsLength, isIrreducible);
8442 if (isIrreducible)
8443 {
8444 delete [] bounds;
8445 factors.append (A);
8446
8447 appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
8448 swap, false, N);
8449
8450 if (!extension)
8451 normalize (factors);
8452 return factors;
8453 }
8454
8455 int minBound= bounds[0];
8456 for (int i= 1; i < boundsLength; i++)
8457 {
8458 if (bounds[i] != 0)
8459 minBound= tmin (minBound, bounds[i]);
8460 }
8461
8462 int boundsLength2;
8463 int * bounds2= computeBoundsWrtDiffMainvar (A, boundsLength2, isIrreducible);
8464 int minBound2= bounds2[0];
8465 for (int i= 1; i < boundsLength2; i++)
8466 {
8467 if (bounds2[i] != 0)
8468 minBound2= tmin (minBound2, bounds2[i]);
8469 }
8470
8471
8472 bool fail= false;
8473 CanonicalForm Aeval, evaluation, bufAeval, bufEvaluation, buf, tmp;
8474 CFList uniFactors, list, bufUniFactors;
8475 DegreePattern degs;
8476 DegreePattern bufDegs;
8477
8478 bool fail2= false;
8479 CanonicalForm Aeval2, evaluation2, bufAeval2, bufEvaluation2;
8480 CFList bufUniFactors2, list2, uniFactors2;
8481 DegreePattern degs2;
8482 DegreePattern bufDegs2;
8483 bool swap2= false;
8484
8485 // several univariate factorizations to obtain more information about the
8486 // degree pattern therefore usually less combinations have to be tried during
8487 // the recombination process
8488 int factorNums= 3;
8489 int subCheck1= substituteCheck (A, x);
8490 int subCheck2= substituteCheck (A, y);
8491 bool symmetric= false;
8492
8493 TIMING_START (fac_fq_uni_total);
8494 for (int i= 0; i < factorNums; i++)
8495 {
8496 bufAeval= A;
8497 TIMING_START (fac_fq_bi_evaluation);
8498 bufEvaluation= evalPoint (A, bufAeval, alpha, list, GF, fail);
8499 TIMING_END_AND_PRINT (fac_fq_bi_evaluation, "time to find eval point: ");
8500 if (!derivXZero && !fail2 && !symmetric)
8501 {
8502 if (i == 0)
8503 {
8504 buf= swapvar (A, x, y);
8505 symmetric= (A/Lc (A) == buf/Lc (buf));
8506 }
8507 bufAeval2= buf;
8508 TIMING_START (fac_fq_bi_evaluation);
8509 bufEvaluation2= evalPoint (buf, bufAeval2, alpha, list2, GF, fail2);
8510 TIMING_END_AND_PRINT (fac_fq_bi_evaluation,
8511 "time to find eval point wrt y: ");
8512 }
8513 // first try to change main variable if there is no valid evaluation point
8514 if (fail && (i == 0))
8515 {
8516 if (!derivXZero && !fail2 && !symmetric)
8517 {
8518 bufEvaluation= bufEvaluation2;
8519 int dummy= subCheck2;
8520 subCheck2= subCheck1;
8521 subCheck1= dummy;
8522 tmp= A;
8523 A= buf;
8524 buf= tmp;
8525 bufAeval= bufAeval2;
8526 swap2= true;
8527 fail= false;
8528 }
8529 else
8530 fail= true;
8531 }
8532
8533 // if there is no valid evaluation point pass to a field extension
8534 if (fail && (i == 0))
8535 {
8536 factors= extBiFactorize (A, info);
8537 appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
8538 swap, swap2, N);
8539 normalize (factors);
8540 delete [] bounds;
8541 delete [] bounds2;
8542 return factors;
8543 }
8544
8545 // there is at least one valid evaluation point
8546 // but we do not compute more univariate factorization over an extension
8547 if (fail && (i != 0))
8548 break;
8549
8550 // univariate factorization
8551 TIMING_START (fac_fq_uni_factorizer);
8552 bufUniFactors= uniFactorizer (bufAeval, alpha, GF);
8553 TIMING_END_AND_PRINT (fac_fq_uni_factorizer,
8554 "time for univariate factorization over Fq: ");
8555 DEBOUTLN (cerr, "Lc (bufAeval)*prod (bufUniFactors)== bufAeval " <<
8556 (prod (bufUniFactors)*Lc (bufAeval) == bufAeval));
8557
8558 if (!derivXZero && !fail2 && !symmetric)
8559 {
8560 TIMING_START (fac_fq_uni_factorizer);
8561 bufUniFactors2= uniFactorizer (bufAeval2, alpha, GF);
8562 TIMING_END_AND_PRINT (fac_fq_uni_factorizer,
8563 "time for univariate factorization in y over Fq: ");
8564 DEBOUTLN (cerr, "Lc (bufAeval2)*prod (bufUniFactors2)== bufAeval2 " <<
8565 (prod (bufUniFactors2)*Lc (bufAeval2) == bufAeval2));
8566 }
8567
8568 if (bufUniFactors.length() == 1 ||
8569 (!fail2 && !derivXZero && !symmetric && (bufUniFactors2.length() == 1)))
8570 {
8571 if (extension)
8572 {
8573 CFList source, dest;
8574 appendMapDown (factors, A, info, source, dest);
8575 }
8576 else
8577 factors.append (A);
8578
8579 appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
8580 swap, swap2, N);
8581
8582 if (!extension)
8583 normalize (factors);
8584 delete [] bounds;
8585 delete [] bounds2;
8586 return factors;
8587 }
8588
8589 if (i == 0 && !extension)
8590 {
8591 if (subCheck1 > 0)
8592 {
8593 int subCheck= substituteCheck (bufUniFactors);
8594
8595 if (subCheck > 1 && (subCheck1%subCheck == 0))
8596 {
8597 CanonicalForm bufA= A;
8598 subst (bufA, bufA, subCheck, x);
8599 factors= biFactorize (bufA, info);
8600 reverseSubst (factors, subCheck, x);
8601 appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
8602 swap, swap2, N);
8603 if (!extension)
8604 normalize (factors);
8605 delete [] bounds;
8606 delete [] bounds2;
8607 return factors;
8608 }
8609 }
8610
8611 if (!derivXZero && !fail2 && !symmetric && subCheck2 > 0)
8612 {
8613 int subCheck= substituteCheck (bufUniFactors2);
8614
8615 if (subCheck > 1 && (subCheck2%subCheck == 0))
8616 {
8617 CanonicalForm bufA= A;
8618 subst (bufA, bufA, subCheck, y);
8619 factors= biFactorize (bufA, info);
8620 reverseSubst (factors, subCheck, y);
8621 appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
8622 swap, swap2, N);
8623 if (!extension)
8624 normalize (factors);
8625 delete [] bounds;
8626 delete [] bounds2;
8627 return factors;
8628 }
8629 }
8630 }
8631
8632 // degree analysis
8633 bufDegs = DegreePattern (bufUniFactors);
8634 if (!derivXZero && !fail2 && !symmetric)
8635 bufDegs2= DegreePattern (bufUniFactors2);
8636
8637 if (i == 0)
8638 {
8639 Aeval= bufAeval;
8640 evaluation= bufEvaluation;
8641 uniFactors= bufUniFactors;
8642 degs= bufDegs;
8643 if (!derivXZero && !fail2 && !symmetric)
8644 {
8645 Aeval2= bufAeval2;
8646 evaluation2= bufEvaluation2;
8647 uniFactors2= bufUniFactors2;
8648 degs2= bufDegs2;
8649 }
8650 }
8651 else
8652 {
8653 degs.intersect (bufDegs);
8654 if (!derivXZero && !fail2 && !symmetric)
8655 {
8656 degs2.intersect (bufDegs2);
8657 if (bufUniFactors2.length() < uniFactors2.length())
8658 {
8659 uniFactors2= bufUniFactors2;
8660 Aeval2= bufAeval2;
8661 evaluation2= bufEvaluation2;
8662 }
8663 }
8664 if (bufUniFactors.length() < uniFactors.length())
8665 {
8666 uniFactors= bufUniFactors;
8667 Aeval= bufAeval;
8668 evaluation= bufEvaluation;
8669 }
8670 }
8671 list.append (bufEvaluation);
8672 if (!derivXZero && !fail2 && !symmetric)
8673 list2.append (bufEvaluation2);
8674 }
8675 TIMING_END_AND_PRINT (fac_fq_uni_total,
8676 "total time for univariate factorizations: ");
8677
8678 if (!derivXZero && !fail2 && !symmetric)
8679 {
8680 if ((uniFactors.length() > uniFactors2.length() && minBound2 <= minBound)||
8681 (uniFactors.length() == uniFactors2.length()
8682 && degs.getLength() > degs2.getLength() && minBound2 <= minBound))
8683 {
8684 degs= degs2;
8685 uniFactors= uniFactors2;
8686 evaluation= evaluation2;
8687 Aeval= Aeval2;
8688 A= buf;
8689 swap2= true;
8690 }
8691 }
8692
8693 if (degs.getLength() == 1) // A is irreducible
8694 {
8695 if (extension)
8696 {
8697 CFList source, dest;
8698 appendMapDown (factors, A, info, source, dest);
8699 }
8700 else
8701 factors.append (A);
8702 appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
8703 swap, swap2, N);
8704 if (!extension)
8705 normalize (factors);
8706 delete [] bounds;
8707 delete [] bounds2;
8708 return factors;
8709 }
8710
8711 int liftBound= degree (A, y) + 1;
8712
8713 if (swap2)
8714 {
8715 delete [] bounds;
8716 bounds= bounds2;
8717 minBound= minBound2;
8718 }
8719
8720 TIMING_START (fac_fq_bi_shift_to_zero);
8721 A= A (y + evaluation, y);
8722 TIMING_END_AND_PRINT (fac_fq_bi_shift_to_zero,
8723 "time to shift eval to zero: ");
8724
8725 int degMipo= 1;
8726 if (extension && alpha.level() != 1 && k==1)
8727 degMipo= degree (getMipo (alpha));
8728
8729 DEBOUTLN (cerr, "uniFactors= " << uniFactors);
8730
8731 if ((GF && !extension) || (GF && extension && k != 1))
8732 {
8733 bool earlySuccess= false;
8734 CFList earlyFactors;
8735 TIMING_START (fac_fq_bi_hensel_lift);
8736 uniFactors= henselLiftAndEarly
8737 (A, earlySuccess, earlyFactors, degs, liftBound,
8738 uniFactors, info, evaluation);
8739 TIMING_END_AND_PRINT (fac_fq_bi_hensel_lift,
8740 "time for bivariate hensel lifting over Fq: ");
8741 DEBOUTLN (cerr, "lifted factors= " << uniFactors);
8742
8743 CanonicalForm MODl= power (y, liftBound);
8744
8745 TIMING_START (fac_fq_bi_factor_recombination);
8746 if (extension)
8747 factors= extFactorRecombination (uniFactors, A, MODl, info, degs,
8748 evaluation, 1, uniFactors.length()/2);
8749 else
8750 factors= factorRecombination (uniFactors, A, MODl, degs, evaluation, 1,
8751 uniFactors.length()/2);
8752 TIMING_END_AND_PRINT (fac_fq_bi_factor_recombination,
8753 "time for naive bivariate factor recombi over Fq: ");
8754
8755 if (earlySuccess)
8756 factors= Union (earlyFactors, factors);
8757 else if (!earlySuccess && degs.getLength() == 1)
8758 factors= earlyFactors;
8759 }
8760 else if (degree (A) > 4 && beta.level() == 1 && (2*minBound)/degMipo < 32)
8761 {
8762 TIMING_START (fac_fq_bi_hensel_lift);
8763 if (extension)
8764 {
8765 CFList lll= extHenselLiftAndLatticeRecombi (A, uniFactors, info, degs,
8767 );
8768 factors= Union (lll, factors);
8769 }
8770 else if (alpha.level() == 1 && !GF)
8771 {
8772 CFList lll= henselLiftAndLatticeRecombi (A, uniFactors, alpha, degs,
8773 symmetric, evaluation);
8774 factors= Union (lll, factors);
8775 }
8776 else if (!extension && (alpha != x || GF))
8777 {
8778 CFList lll= henselLiftAndLatticeRecombi (A, uniFactors, alpha, degs,
8779 symmetric, evaluation);
8780 factors= Union (lll, factors);
8781 }
8782 TIMING_END_AND_PRINT (fac_fq_bi_hensel_lift,
8783 "time to bivar lift and LLL recombi over Fq: ");
8784 DEBOUTLN (cerr, "lifted factors= " << uniFactors);
8785 }
8786 else
8787 {
8788 bool earlySuccess= false;
8789 CFList earlyFactors;
8790 TIMING_START (fac_fq_bi_hensel_lift);
8791 uniFactors= henselLiftAndEarly
8792 (A, earlySuccess, earlyFactors, degs, liftBound,
8793 uniFactors, info, evaluation);
8794 TIMING_END_AND_PRINT (fac_fq_bi_hensel_lift,
8795 "time for bivar hensel lifting over Fq: ");
8796 DEBOUTLN (cerr, "lifted factors= " << uniFactors);
8797
8798 CanonicalForm MODl= power (y, liftBound);
8799 if (!extension)
8800 {
8801 TIMING_START (fac_fq_bi_factor_recombination);
8802 factors= factorRecombination (uniFactors, A, MODl, degs, evaluation, 1, 3);
8803 TIMING_END_AND_PRINT (fac_fq_bi_factor_recombination,
8804 "time for small subset naive recombi over Fq: ");
8805
8806 int oldUniFactorsLength= uniFactors.length();
8807 if (degree (A) > 0)
8808 {
8809 CFList tmp;
8810 TIMING_START (fac_fq_bi_hensel_lift);
8811 if (alpha.level() == 1)
8812 tmp= increasePrecision (A, uniFactors, 0, uniFactors.length(), 1,
8813 liftBound, evaluation
8814 );
8815 else
8816 {
8817 if (degree (A) > getCharacteristic())
8818 tmp= increasePrecisionFq2Fp (A, uniFactors, 0, uniFactors.length(),
8819 1, alpha, liftBound, evaluation
8820 );
8821 else
8822 tmp= increasePrecision (A, uniFactors, 0, uniFactors.length(), 1,
8823 alpha, liftBound, evaluation
8824 );
8825 }
8826 TIMING_END_AND_PRINT (fac_fq_bi_hensel_lift,
8827 "time to increase precision: ");
8828 factors= Union (factors, tmp);
8829 if (tmp.length() == 0 || (tmp.length() > 0 && uniFactors.length() != 0
8830 && uniFactors.length() != oldUniFactorsLength)
8831 )
8832 {
8833 DegreePattern bufDegs= DegreePattern (uniFactors);
8834 degs.intersect (bufDegs);
8835 degs.refine ();
8836 factors= Union (factors, factorRecombination (uniFactors, A, MODl,
8837 degs, evaluation, 4,
8838 uniFactors.length()/2
8839 )
8840 );
8841 }
8842 }
8843 }
8844 else
8845 {
8846 if (beta.level() != 1 || k > 1)
8847 {
8848 if (k > 1)
8849 {
8850 factors= extFactorRecombination (uniFactors, A, MODl, info, degs,
8851 evaluation, 1, uniFactors.length()/2
8852 );
8853 }
8854 else
8855 {
8856 factors= extFactorRecombination (uniFactors, A, MODl, info, degs,
8857 evaluation, 1, 3
8858 );
8859 if (degree (A) > 0)
8860 {
8861 CFList tmp= increasePrecision2 (A, uniFactors, alpha, liftBound);
8862 DegreePattern bufDegs= DegreePattern (tmp);
8863 degs.intersect (bufDegs);
8864 degs.refine ();
8865 factors= Union (factors, extFactorRecombination (tmp, A, MODl, info,
8866 degs, evaluation,
8867 1, tmp.length()/2
8868 )
8869 );
8870 }
8871 }
8872 }
8873 else
8874 {
8875 factors= extFactorRecombination (uniFactors, A, MODl, info, degs,
8876 evaluation, 1, 3
8877 );
8878 int oldUniFactorsLength= uniFactors.length();
8879 if (degree (A) > 0)
8880 {
8881 int degMipo;
8882 ExtensionInfo info2= init4ext (info, evaluation, degMipo);
8883
8884 CFList source, dest;
8885 CFList tmp= extIncreasePrecision (A, uniFactors, 0,
8886 uniFactors.length(), 1, evaluation,
8887 info2, source, dest, liftBound
8888 );
8889 factors= Union (factors, tmp);
8890 if (tmp.length() == 0 || (tmp.length() > 0 && uniFactors.length() != 0
8891 && uniFactors.length() != oldUniFactorsLength)
8892 )
8893 {
8894 DegreePattern bufDegs= DegreePattern (uniFactors);
8895 degs.intersect (bufDegs);
8896 degs.refine ();
8897 factors= Union (factors,extFactorRecombination (uniFactors, A, MODl,
8898 info, degs, evaluation,
8899 4, uniFactors.length()/2
8900 )
8901 );
8902 }
8903 }
8904 }
8905 }
8906
8907 if (earlySuccess)
8908 factors= Union (earlyFactors, factors);
8909 else if (!earlySuccess && degs.getLength() == 1)
8910 factors= earlyFactors;
8911 }
8912
8913 if (!swap2)
8914 delete [] bounds2;
8915 delete [] bounds;
8916
8917 appendSwapDecompress (factors, contentAxFactors, contentAyFactors,
8918 swap, swap2, N);
8919 if (!extension)
8920 normalize (factors);
8921
8922 return factors;
8923}
8924#endif
8925
8926#ifdef HAVE_NTL // biFactorize
8927CFList
8929{
8930
8931 CanonicalForm A= F;
8932 Variable alpha= info.getAlpha();
8933 Variable beta= info.getBeta();
8934 int k= info.getGFDegree();
8935 char cGFName= info.getGFName();
8936 CanonicalForm delta= info.getDelta();
8937
8938 bool GF= (CFFactory::gettype() == GaloisFieldDomain);
8939 Variable x= Variable (1);
8940 CFList factors;
8941 if (!GF && alpha == x) // we are in F_p
8942 {
8943 bool extension= true;
8944 int p= getCharacteristic();
8945 if (p*p < (1<<16)) // pass to GF if possible
8946 {
8948 A= A.mapinto();
8949 ExtensionInfo info2= ExtensionInfo (extension);
8950 factors= biFactorize (A, info2);
8951
8954 Variable vBuf= rootOf (mipo.mapinto());
8955 for (CFListIterator j= factors; j.hasItem(); j++)
8956 j.getItem()= GF2FalphaRep (j.getItem(), vBuf);
8957 prune (vBuf);
8958 }
8959 else // not able to pass to GF, pass to F_p(\alpha)
8960 {
8962 Variable v= rootOf (mipo);
8963 ExtensionInfo info2= ExtensionInfo (v);
8964 factors= biFactorize (A, info2);
8965 prune (v);
8966 }
8967 return factors;
8968 }
8969 else if (!GF && (alpha != x)) // we are in F_p(\alpha)
8970 {
8971 if (k == 1) // need factorization over F_p
8972 {
8973 int extDeg= degree (getMipo (alpha));
8974 extDeg++;
8976 Variable v= rootOf (mipo);
8977 ExtensionInfo info2= ExtensionInfo (v);
8978 factors= biFactorize (A, info2);
8979 prune (v);
8980 }
8981 else
8982 {
8983 if (beta == x)
8984 {
8986 CanonicalForm primElem, imPrimElem;
8987 bool primFail= false;
8988 Variable vBuf;
8989 primElem= primitiveElement (alpha, vBuf, primFail);
8990 ASSERT (!primFail, "failure in integer factorizer");
8991 if (primFail)
8992 ; //ERROR
8993 else
8994 imPrimElem= mapPrimElem (primElem, alpha, v);
8995
8996 CFList source, dest;
8997 CanonicalForm bufA= mapUp (A, alpha, v, primElem, imPrimElem,
8998 source, dest);
8999 ExtensionInfo info2= ExtensionInfo (v, alpha, imPrimElem, primElem);
9000 factors= biFactorize (bufA, info2);
9001 prune (v);
9002 }
9003 else
9004 {
9006 CanonicalForm primElem, imPrimElem;
9007 bool primFail= false;
9008 Variable vBuf;
9009 ASSERT (!primFail, "failure in integer factorizer");
9010 if (primFail)
9011 ; //ERROR
9012 else
9013 imPrimElem= mapPrimElem (delta, beta, v);
9014
9015 CFList source, dest;
9016 CanonicalForm bufA= mapDown (A, info, source, dest);
9017 source= CFList();
9018 dest= CFList();
9019 bufA= mapUp (bufA, beta, v, delta, imPrimElem, source, dest);
9020 ExtensionInfo info2= ExtensionInfo (v, beta, imPrimElem, delta);
9021 factors= biFactorize (bufA, info2);
9022 prune (v);
9023 }
9024 }
9025 return factors;
9026 }
9027 else // we are in GF (p^k)
9028 {
9029 int p= getCharacteristic();
9030 int extensionDeg= getGFDegree();
9031 bool extension= true;
9032 if (k == 1) // need factorization over F_p
9033 {
9034 extensionDeg++;
9035 if (ipower (p, extensionDeg) < (1<<16))
9036 // pass to GF(p^k+1)
9037 {
9040 Variable vBuf= rootOf (mipo.mapinto());
9041 A= GF2FalphaRep (A, vBuf);
9042 setCharacteristic (p, extensionDeg, 'Z');
9043 ExtensionInfo info2= ExtensionInfo (extension);
9044 factors= biFactorize (A.mapinto(), info2);
9045 prune (vBuf);
9046 }
9047 else // not able to pass to another GF, pass to F_p(\alpha)
9048 {
9051 Variable vBuf= rootOf (mipo.mapinto());
9052 A= GF2FalphaRep (A, vBuf);
9053 Variable v= chooseExtension (vBuf, beta, k);
9054 ExtensionInfo info2= ExtensionInfo (v, extension);
9055 factors= biFactorize (A, info2);
9056 prune (vBuf);
9057 }
9058 }
9059 else // need factorization over GF (p^k)
9060 {
9061 if (ipower (p, 2*extensionDeg) < (1<<16))
9062 // pass to GF (p^2k)
9063 {
9064 setCharacteristic (p, 2*extensionDeg, 'Z');
9065 ExtensionInfo info2= ExtensionInfo (k, cGFName, extension);
9066 factors= biFactorize (GFMapUp (A, extensionDeg), info2);
9067 setCharacteristic (p, extensionDeg, cGFName);
9068 }
9069 else // not able to pass to GF (p^2k), pass to F_p (\alpha)
9070 {
9073 Variable v1= rootOf (mipo.mapinto());
9074 A= GF2FalphaRep (A, v1);
9075 Variable v2= chooseExtension (v1, v1, k);
9076 CanonicalForm primElem, imPrimElem;
9077 bool primFail= false;
9078 Variable vBuf;
9079 primElem= primitiveElement (v1, vBuf, primFail);
9080 ASSERT (!primFail, "failure in integer factorizer");
9081 if (primFail)
9082 ; //ERROR
9083 else
9084 imPrimElem= mapPrimElem (primElem, v1, v2);
9085
9086 CFList source, dest;
9087 CanonicalForm bufA= mapUp (A, v1, v2, primElem, imPrimElem,
9088 source, dest);
9089 ExtensionInfo info2= ExtensionInfo (v2, v1, imPrimElem, primElem);
9090 factors= biFactorize (bufA, info2);
9091 setCharacteristic (p, k, cGFName);
9092 for (CFListIterator i= factors; i.hasItem(); i++)
9094 prune (v1);
9095 }
9096 }
9097 return factors;
9098 }
9099}
9100#endif
9101#endif
void convertFacCFMatrix2nmod_mat_t(nmod_mat_t M, const CFMatrix &m)
conversion of a factory matrix over Z/p to a nmod_mat_t
CFFList convertFLINTFq_nmod_poly_factor2FacCFFList(const fq_nmod_poly_factor_t fac, const Variable &x, const Variable &alpha, const fq_nmod_ctx_t fq_con)
conversion of a FLINT factorization over Fq (for word size p) to a CFFList
CanonicalForm convertnmod_poly_t2FacCF(const nmod_poly_t poly, const Variable &x)
conversion of a FLINT poly over Z/p to CanonicalForm
void convertFacCF2Fq_nmod_poly_t(fq_nmod_poly_t result, const CanonicalForm &f, const fq_nmod_ctx_t ctx)
conversion of a factory univariate poly over F_q to a FLINT fq_nmod_poly_t
CFFList convertFLINTnmod_poly_factor2FacCFFList(const nmod_poly_factor_t fac, const mp_limb_t leadingCoeff, const Variable &x)
conversion of a FLINT factorization over Z/p (for word size p) to a CFFList
This file defines functions for conversion to FLINT (www.flintlib.org) and back.
Rational pow(const Rational &a, int e)
Definition: GMPrat.cc:411
Rational abs(const Rational &a)
Definition: GMPrat.cc:436
CFFList convertNTLvec_pair_GF2X_long2FacCFFList(const vec_pair_GF2X_long &e, GF2, const Variable &x)
NAME: convertNTLvec_pair_GF2X_long2FacCFFList.
Definition: NTLconvert.cc:446
zz_pEX convertFacCF2NTLzz_pEX(const CanonicalForm &f, const zz_pX &mipo)
Definition: NTLconvert.cc:1064
CFFList convertNTLvec_pair_zzpEX_long2FacCFFList(const vec_pair_zz_pEX_long &e, const zz_pE &cont, const Variable &x, const Variable &alpha)
Definition: NTLconvert.cc:870
CFFList convertNTLvec_pair_GF2EX_long2FacCFFList(const vec_pair_GF2EX_long &e, const GF2E &cont, const Variable &x, const Variable &alpha)
NAME: convertNTLvec_pair_GF2EX_long2FacCFFList.
Definition: NTLconvert.cc:959
CanonicalForm convertNTLzzpX2CF(const zz_pX &poly, const Variable &x)
Definition: NTLconvert.cc:255
CFFList convertNTLvec_pair_zzpX_long2FacCFFList(const vec_pair_zz_pX_long &e, const zz_p cont, const Variable &x)
Definition: NTLconvert.cc:399
mat_zz_pE * convertFacCFMatrix2NTLmat_zz_pE(const CFMatrix &m)
Definition: NTLconvert.cc:1196
GF2EX convertFacCF2NTLGF2EX(const CanonicalForm &f, const GF2X &mipo)
CanonicalForm in Z_2(a)[X] to NTL GF2EX.
Definition: NTLconvert.cc:1007
zz_pX convertFacCF2NTLzzpX(const CanonicalForm &f)
Definition: NTLconvert.cc:105
mat_zz_p * convertFacCFMatrix2NTLmat_zz_p(const CFMatrix &m)
Definition: NTLconvert.cc:1167
VAR long fac_NTL_char
Definition: NTLconvert.cc:46
GF2X convertFacCF2NTLGF2X(const CanonicalForm &f)
NAME: convertFacCF2NTLGF2X.
Definition: NTLconvert.cc:184
Conversion to and from NTL.
#define swap(_i, _j)
bool isOn(int sw)
switches
void On(int sw)
switches
void Off(int sw)
switches
CanonicalForm power(const CanonicalForm &f, int n)
exponentiation
Header for factory's main class CanonicalForm.
CanonicalForm FACTORY_PUBLIC content(const CanonicalForm &)
CanonicalForm content ( const CanonicalForm & f )
Definition: cf_gcd.cc:603
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
CF_NO_INLINE FACTORY_PUBLIC CanonicalForm div(const CanonicalForm &, const CanonicalForm &)
CanonicalForm lc(const CanonicalForm &f)
CanonicalForm FACTORY_PUBLIC icontent(const CanonicalForm &f)
CanonicalForm icontent ( const CanonicalForm & f )
Definition: cf_gcd.cc:74
CanonicalForm FACTORY_PUBLIC replacevar(const CanonicalForm &, const Variable &, const Variable &)
CanonicalForm replacevar ( const CanonicalForm & f, const Variable & x1, const Variable & x2 )
Definition: cf_ops.cc:271
int degree(const CanonicalForm &f)
CanonicalForm deriv(const CanonicalForm &f, const Variable &x)
int getGFDegree()
Definition: cf_char.cc:75
Array< CanonicalForm > CFArray
void FACTORY_PUBLIC setCharacteristic(int c)
Definition: cf_char.cc:28
bool hasFirstAlgVar(const CanonicalForm &f, Variable &a)
check if poly f contains an algebraic variable a
Definition: cf_ops.cc:679
Matrix< CanonicalForm > CFMatrix
CanonicalForm FACTORY_PUBLIC swapvar(const CanonicalForm &, const Variable &, const Variable &)
swapvar() - swap variables x1 and x2 in f.
Definition: cf_ops.cc:168
CanonicalForm den(const CanonicalForm &f)
int totaldegree(const CanonicalForm &f)
int totaldegree ( const CanonicalForm & f )
Definition: cf_ops.cc:523
CanonicalForm Lc(const CanonicalForm &f)
CanonicalForm getGFGenerator()
Definition: cf_char.cc:81
Factor< CanonicalForm > CFFactor
List< CanonicalForm > CFList
CanonicalForm LC(const CanonicalForm &f)
int FACTORY_PUBLIC getCharacteristic()
Definition: cf_char.cc:70
static bool irreducible(const CFList &AS)
Definition: cfCharSets.cc:487
const CanonicalForm CFMap CFMap & N
Definition: cfEzgcd.cc:56
int l
Definition: cfEzgcd.cc:100
int m
Definition: cfEzgcd.cc:128
int k
Definition: cfEzgcd.cc:99
Variable x
Definition: cfModGcd.cc:4082
int p
Definition: cfModGcd.cc:4078
g
Definition: cfModGcd.cc:4090
CanonicalForm test
Definition: cfModGcd.cc:4096
int * getRightSide(int **polygon, int sizeOfPolygon, int &sizeOfOutput)
get the y-direction slopes of all edges with positive slope in y-direction of a convex polygon with a...
CanonicalForm decompress(const CanonicalForm &F, const mpz_t *inverseM, const mpz_t *A)
decompress a bivariate poly
This file provides functions to compute the Newton polygon of a bivariate polynomial.
CanonicalForm bCommonDen(const CanonicalForm &f)
CanonicalForm bCommonDen ( const CanonicalForm & f )
bool fdivides(const CanonicalForm &f, const CanonicalForm &g)
bool fdivides ( const CanonicalForm & f, const CanonicalForm & g )
assertions for Factory
#define ASSERT(expression, message)
Definition: cf_assert.h:99
factory switches.
static const int SW_RATIONAL
set to 1 for computations over Q
Definition: cf_defs.h:31
#define GaloisFieldDomain
Definition: cf_defs.h:18
CanonicalForm randomIrredpoly(int i, const Variable &x)
computes a random monic irreducible univariate polynomial in x over Fp of degree i via NTL/FLINT
Definition: cf_irred.cc:26
generate random irreducible univariate polynomials
static CanonicalForm bound(const CFMatrix &M)
Definition: cf_linsys.cc:460
CanonicalForm compress(const CanonicalForm &f, CFMap &m)
CanonicalForm compress ( const CanonicalForm & f, CFMap & m )
Definition: cf_map.cc:210
map polynomials
CanonicalForm mapPrimElem(const CanonicalForm &primElem, const Variable &alpha, const Variable &beta)
compute the image of a primitive element of in . We assume .
Definition: cf_map_ext.cc:450
CanonicalForm primitiveElement(const Variable &alpha, Variable &beta, bool &fail)
determine a primitive element of , is a primitive element of a field which is isomorphic to
Definition: cf_map_ext.cc:342
CanonicalForm findMinPoly(const CanonicalForm &F, const Variable &alpha)
compute minimal polynomial of via NTL
Definition: cf_map_ext.cc:640
static CanonicalForm mapDown(const CanonicalForm &F, const Variable &alpha, const CanonicalForm &G, CFList &source, CFList &dest)
the CanonicalForm G is the output of map_up, returns F considered as an element over ,...
Definition: cf_map_ext.cc:123
static CanonicalForm mapUp(const Variable &alpha, const Variable &beta)
and is a primitive element, returns the image of
Definition: cf_map_ext.cc:70
CanonicalForm Falpha2GFRep(const CanonicalForm &F)
change representation by residue classes modulo a Conway polynomial to representation by primitive el...
Definition: cf_map_ext.cc:203
CanonicalForm GFMapUp(const CanonicalForm &F, int k)
maps a polynomial over to a polynomial over , d needs to be a multiple of k
Definition: cf_map_ext.cc:240
CanonicalForm GF2FalphaRep(const CanonicalForm &F, const Variable &alpha)
changes representation by primitive element to representation by residue classes modulo a Conway poly...
Definition: cf_map_ext.cc:195
CanonicalForm map(const CanonicalForm &primElem, const Variable &alpha, const CanonicalForm &F, const Variable &beta)
map from to such that is mapped onto
Definition: cf_map_ext.cc:504
This file implements functions to map between extensions of finite fields.
GLOBAL_VAR flint_rand_t FLINTrandom
Definition: cf_random.cc:25
generate random integers, random elements of finite fields
VAR void(* factoryError)(const char *s)
Definition: cf_util.cc:80
int igcd(int a, int b)
Definition: cf_util.cc:56
int ipower(int b, int m)
int ipower ( int b, int m )
Definition: cf_util.cc:27
generate random elements in F_p(alpha)
Definition: cf_random.h:70
CanonicalForm generate() const
Definition: cf_random.cc:157
static int gettype()
Definition: cf_factory.h:28
class to iterate through CanonicalForm's
Definition: cf_iter.h:44
class CFMap
Definition: cf_map.h:85
factory's main class
Definition: canonicalform.h:86
CF_NO_INLINE bool isZero() const
Variable mvar() const
mvar() returns the main variable of CO or Variable() if CO is in a base domain.
CF_NO_INLINE bool isOne() const
bool inCoeffDomain() const
int level() const
level() returns the level of CO.
CanonicalForm mapinto() const
DegreePattern provides a functionality to create, intersect and refine degree patterns.
Definition: DegreePattern.h:32
int find(const int x) const
find an element x
void intersect(const DegreePattern &degPat)
intersect two degree patterns
int getLength() const
getter
Definition: DegreePattern.h:86
void refine()
Refine a degree pattern. Assumes that (*this)[0]:= d is the degree of the poly to be factored....
ExtensionInfo contains information about extension.
Definition: ExtensionInfo.h:51
generate random elements in F_p
Definition: cf_random.h:44
CanonicalForm generate() const
Definition: cf_random.cc:68
generate random elements in GF
Definition: cf_random.h:32
CanonicalForm generate() const
Definition: cf_random.cc:78
T & getItem() const
Definition: ftmpl_list.cc:431
T getFirst() const
Definition: ftmpl_list.cc:279
void removeFirst()
Definition: ftmpl_list.cc:287
int length() const
Definition: ftmpl_list.cc:273
void append(const T &)
Definition: ftmpl_list.cc:256
T getLast() const
Definition: ftmpl_list.cc:309
void insert(const T &)
Definition: ftmpl_list.cc:193
int isEmpty() const
Definition: ftmpl_list.cc:267
factory's class for variables
Definition: variable.h:33
int level() const
Definition: variable.h:49
class to do operations mod p^k for int's p and k
Definition: fac_util.h:23
functions to print debug output
#define DEBOUTLN(stream, objects)
Definition: debug.h:49
CFFListIterator iter
Definition: facAbsBiFact.cc:53
Variable alpha
Definition: facAbsBiFact.cc:51
return result
Definition: facAbsBiFact.cc:75
const CanonicalForm int const CFList & evaluation
Definition: facAbsFact.cc:52
const CanonicalForm int s
Definition: facAbsFact.cc:51
const CanonicalForm int const CFList const Variable & y
Definition: facAbsFact.cc:53
Variable beta
Definition: facAbsFact.cc:95
CanonicalForm H
Definition: facAbsFact.cc:60
CanonicalForm mipo
Definition: facAlgExt.cc:57
CFFList append(const CFFList &Inputlist, const CFFactor &TheFactor)
CanonicalForm subst(const CanonicalForm &f, const CFList &a, const CFList &b, const CanonicalForm &Rstar, bool isFunctionField)
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39
CanonicalForm LCF
Definition: facFactorize.cc:52
CFList & eval
Definition: facFactorize.cc:47
CFList *& Aeval
<[in] poly
Definition: facFactorize.h:31
int subsetDegree(const CFList &S)
compute the sum of degrees in Variable(1) of elements in S
CFArray logarithmicDerivative(const CanonicalForm &F, const CanonicalForm &G, int l, CanonicalForm &Q)
compute the coefficients of the logarithmic derivative of G mod Variable (2)^l over Fq
int * computeBounds(const CanonicalForm &F, int &n, bool &isIrreducible)
compute bounds for logarithmic derivative as described in K. Belabas, M. van Hoeij,...
void appendTestMapDown(CFList &factors, const CanonicalForm &f, const ExtensionInfo &info, CFList &source, CFList &dest)
test if g is in a subfield of the current field, if so map it down and append it to factors
void appendSwapDecompress(CFList &factors1, const CFList &factors2, const CFList &factors3, const bool swap1, const bool swap2, const CFMap &N)
first swap Variables in factors1 if necessary, then append factors2 and factors3 on factors1 and fina...
void indexUpdate(int index[], const int &subsetSize, const int &setSize, bool &noSubset)
update index
void appendMapDown(CFList &factors, const CanonicalForm &g, const ExtensionInfo &info, CFList &source, CFList &dest)
map g down into a subfield of the current field and append it to factors
CanonicalForm reverseSubst(const CanonicalForm &F, const int d, const Variable &x)
reverse a substitution x^d->x
CFArray getCoeffs(const CanonicalForm &F, const int k)
extract coefficients of for where is a variable of level 1
CFArray copy(const CFList &list)
write elements of list into an array
CFList subset(int index[], const int &s, const CFArray &elements, bool &noSubset)
extract a subset given by index of size s from elements, if there is no subset we have not yet consid...
bool isInExtension(const CanonicalForm &F, const CanonicalForm &gamma, const int k, const CanonicalForm &delta, CFList &source, CFList &dest)
tests if F is not contained in a subfield defined by gamma (Fq case) or k (GF case)
void writeInMatrix(CFMatrix &M, const CFArray &A, const int column, const int startIndex)
write A into M starting at row startIndex
int substituteCheck(const CanonicalForm &F, const Variable &x)
check if a substitution x^n->x is possible
int * computeBoundsWrtDiffMainvar(const CanonicalForm &F, int &n, bool &isIrreducible)
as above just wrt to the other variable
This file provides utility functions for bivariate factorization.
CFList biFactorize(const CanonicalForm &F, const ExtensionInfo &info)
bivariate factorization over finite fields as decribed in "Factoring multivariate polynomials over a ...
Definition: facFqBivar.cc:8303
void extEarlyFactorDetection(CFList &reconstructedFactors, CanonicalForm &F, CFList &factors, int &adaptedLiftBound, int *&factorsFoundIndex, DegreePattern &degs, bool &success, const ExtensionInfo &info, const CanonicalForm &eval, int deg)
detects factors of F at stage deg of Hensel lifting. No combinations of more than one factor are test...
Definition: facFqBivar.cc:982
CFList increasePrecision(CanonicalForm &F, CFList &factors, int factorsFound, int oldNumCols, int oldL, int precision, const CanonicalForm &eval)
Definition: facFqBivar.cc:3475
CFList extFurtherLiftingAndIncreasePrecision(CanonicalForm &F, CFList &factors, int l, int liftBound, int d, int *bounds, nmod_mat_t FLINTN, CFList &diophant, CFMatrix &M, CFArray &Pi, CFArray &bufQ, const CanonicalForm &evaluation, const ExtensionInfo &info, CFList &source, CFList &dest)
Definition: facFqBivar.cc:5557
return mod(mulNTL(buf1, buf2, b), M)
CFList extHenselLiftAndLatticeRecombi(const CanonicalForm &G, const CFList &uniFactors, const ExtensionInfo &extInfo, const DegreePattern &degPat, const CanonicalForm &eval)
Definition: facFqBivar.cc:7712
CFList tmp1
Definition: facFqBivar.cc:72
int * getCombinations(int *rightSide, int sizeOfRightSide, int &sizeOfOutput, int degreeLC)
Definition: facFqBivar.cc:1081
CFList furtherLiftingAndIncreasePrecision(CanonicalForm &F, CFList &factors, int l, int liftBound, int d, int *bounds, nmod_mat_t FLINTN, CFList &diophant, CFMatrix &M, CFArray &Pi, CFArray &bufQ, const CanonicalForm &eval)
Definition: facFqBivar.cc:5174
void deleteFactors(CFList &factors, int *factorsFoundIndex)
Definition: facFqBivar.cc:1136
void extReconstructionTry(CFList &reconstructedFactors, CanonicalForm &F, const CFList &factors, const int liftBound, int &factorsFound, int *&factorsFoundIndex, mat_zz_p &N, bool beenInThres, const ExtensionInfo &info, const CanonicalForm &evaluation)
Definition: facFqBivar.cc:2224
CanonicalForm buf2
Definition: facFqBivar.cc:73
CFList extBiFactorize(const CanonicalForm &F, const ExtensionInfo &info)
Factorization over an extension of initial field.
Definition: facFqBivar.cc:8928
int * getLiftPrecisions(const CanonicalForm &F, int &sizeOfOutput, int degreeLC)
compute lifting precisions from the shape of the Newton polygon of F
Definition: facFqBivar.cc:1120
int liftAndComputeLatticeFq2Fp(const CanonicalForm &F, int *bounds, int sizeBounds, int start, int liftBound, int minBound, CFList &factors, nmod_mat_t FLINTN, CFList &diophant, CFMatrix &M, CFArray &Pi, CFArray &bufQ, bool &irreducible, const Variable &alpha)
Definition: facFqBivar.cc:3292
CFList extReconstruction(CanonicalForm &G, CFList &factors, int *zeroOneVecs, int precision, const mat_zz_p &N, const ExtensionInfo &info, const CanonicalForm &evaluation)
Definition: facFqBivar.cc:1960
int liftAndComputeLattice(const CanonicalForm &F, int *bounds, int sizeBounds, int start, int liftBound, int minBound, CFList &factors, mat_zz_p &NTLN, CFList &diophant, CFMatrix &M, CFArray &Pi, CFArray &bufQ, bool &irreducible)
Definition: facFqBivar.cc:2485
CFList extEarlyReconstructionAndLifting(const CanonicalForm &F, const nmod_mat_t N, CanonicalForm &bufF, CFList &factors, int &l, int &factorsFound, bool beenInThres, CFMatrix &M, CFArray &Pi, CFList &diophant, const ExtensionInfo &info, const CanonicalForm &evaluation)
Definition: facFqBivar.cc:6579
int * extractZeroOneVecs(const mat_zz_p &M)
Definition: facFqBivar.cc:1525
CFList increasePrecisionFq2Fp(CanonicalForm &F, CFList &factors, int factorsFound, int oldNumCols, int oldL, const Variable &alpha, int precision, const CanonicalForm &eval)
Definition: facFqBivar.cc:4267
CFList tmp2
Definition: facFqBivar.cc:72
CFList extIncreasePrecision(CanonicalForm &F, CFList &factors, int factorsFound, int oldNumCols, int oldL, const CanonicalForm &evaluation, const ExtensionInfo &info, CFList &source, CFList &dest, int precision)
Definition: facFqBivar.cc:3826
CFList monicReconstruction(CanonicalForm &G, CFList &factors, int *zeroOneVecs, int precision, const mat_zz_pE &N)
Definition: facFqBivar.cc:1907
CFList henselLiftAndLatticeRecombi(const CanonicalForm &G, const CFList &uniFactors, const Variable &alpha, const DegreePattern &degPat, bool symmetric, const CanonicalForm &eval)
Definition: facFqBivar.cc:6859
CFList reconstruction(CanonicalForm &G, CFList &factors, int *zeroOneVecs, int precision, const mat_zz_pE &N, const CanonicalForm &eval)
Definition: facFqBivar.cc:1856
CFListIterator i
Definition: facFqBivar.cc:71
CFList extSieveSmallFactors(const CanonicalForm &G, CFList &uniFactors, DegreePattern &degPat, CanonicalForm &H, CFList &diophant, CFArray &Pi, CFMatrix &M, bool &success, int d, const CanonicalForm &evaluation, const ExtensionInfo &info)
Definition: facFqBivar.cc:6809
CFList extFactorRecombination(CFList &factors, CanonicalForm &F, const CanonicalForm &N, const ExtensionInfo &info, DegreePattern &degs, const CanonicalForm &eval, int s, int thres)
naive factor recombination as decribed in "Factoring multivariate polynomials over a finite field" by...
Definition: facFqBivar.cc:370
CanonicalForm evalPoint(const CanonicalForm &F, CanonicalForm &eval, const Variable &alpha, CFList &list, const bool &GF, bool &fail)
find an evaluation point p, s.t. F(p,y) is squarefree and .
Definition: facFqBivar.cc:84
CFList henselLiftAndEarly(CanonicalForm &A, bool &earlySuccess, CFList &earlyFactors, DegreePattern &degs, int &liftBound, const CFList &uniFactors, const ExtensionInfo &info, const CanonicalForm &eval, modpk &b, CanonicalForm &den)
hensel Lifting and early factor detection
Definition: facFqBivar.cc:1152
CFList sieveSmallFactors(const CanonicalForm &G, CFList &uniFactors, DegreePattern &degPat, CanonicalForm &H, CFList &diophant, CFArray &Pi, CFMatrix &M, bool &success, int d, const CanonicalForm &eval)
Definition: facFqBivar.cc:6762
const CanonicalForm & M
Definition: facFqBivar.cc:60
void refineAndRestartLift(const CanonicalForm &F, const nmod_mat_t FLINTN, int liftBound, int l, CFList &factors, CFMatrix &M, CFArray &Pi, CFList &diophant)
Definition: facFqBivar.cc:6140
void reconstructionTry(CFList &reconstructedFactors, CanonicalForm &F, const CFList &factors, const int liftBound, int &factorsFound, int *&factorsFoundIndex, mat_zz_pE &N, const CanonicalForm &eval, bool beenInThres)
Definition: facFqBivar.cc:1604
void earlyFactorDetection(CFList &reconstructedFactors, CanonicalForm &F, CFList &factors, int &adaptedLiftBound, int *&factorsFoundIndex, DegreePattern &degs, bool &success, int deg, const CanonicalForm &eval, const modpk &b, CanonicalForm &den)
Definition: facFqBivar.cc:852
CFList uniFactorizer(const CanonicalForm &A, const Variable &alpha, const bool &GF)
Univariate factorization of squarefree monic polys over finite fields via NTL. If the characteristic ...
Definition: facFqBivar.cc:160
long isReduced(const mat_zz_p &M)
Definition: facFqBivar.cc:1468
Variable chooseExtension(const Variable &alpha, const Variable &beta, int k)
chooses a field extension.
Definition: facFqBivar.cc:806
CFList factorRecombination(CFList &factors, CanonicalForm &F, const CanonicalForm &N, DegreePattern &degs, const CanonicalForm &eval, int s, int thres, const modpk &b, const CanonicalForm &den)
naive factor recombination as decribed in "Factoring multivariate polynomials over a finite field" by...
Definition: facFqBivar.cc:586
CFList earlyReconstructionAndLifting(const CanonicalForm &F, const nmod_mat_t N, CanonicalForm &bufF, CFList &factors, int &l, int &factorsFound, bool beenInThres, CFMatrix &M, CFArray &Pi, CFList &diophant, bool symmetric, const CanonicalForm &evaluation)
Definition: facFqBivar.cc:6205
int extLiftAndComputeLattice(const CanonicalForm &F, int *bounds, int sizeBounds, int liftBound, int minBound, int start, CFList &factors, mat_zz_p &NTLN, CFList &diophant, CFMatrix &M, CFArray &Pi, CFArray &bufQ, bool &irreducible, const CanonicalForm &evaluation, const ExtensionInfo &info, CFList &source, CFList &dest)
Definition: facFqBivar.cc:2749
CanonicalForm buf1
Definition: facFqBivar.cc:73
ExtensionInfo init4ext(const ExtensionInfo &info, const CanonicalForm &evaluation, int &degMipo)
Definition: facFqBivar.cc:7657
const CanonicalForm const modpk & b
Definition: facFqBivar.cc:61
CFList increasePrecision2(const CanonicalForm &F, CFList &factors, const Variable &alpha, int precision)
Definition: facFqBivar.cc:4134
CFList furtherLiftingAndIncreasePrecisionFq2Fp(CanonicalForm &F, CFList &factors, int l, int liftBound, int d, int *bounds, nmod_mat_t FLINTN, CFList &diophant, CFMatrix &M, CFArray &Pi, CFArray &bufQ, const Variable &alpha, const CanonicalForm &eval)
Definition: facFqBivar.cc:5873
This file provides functions for factorizing a bivariate polynomial over , or GF.
CanonicalForm prodMod0(const CFList &L, const CanonicalForm &M, const modpk &b=modpk())
via divide-and-conquer
CFList recombination(const CFList &factors1, const CFList &factors2, int s, int thres, const CanonicalForm &evalPoint, const Variable &x)
recombination of bivariate factors factors1 s. t. the result evaluated at evalPoint coincides with fa...
for(j=0;j< factors.length();j++)
Definition: facHensel.cc:129
fq_nmod_ctx_t fq_con
Definition: facHensel.cc:99
int j
Definition: facHensel.cc:110
fq_nmod_ctx_clear(fq_con)
nmod_poly_init(FLINTmipo, getCharacteristic())
fq_nmod_ctx_init_modulus(fq_con, FLINTmipo, "Z")
fq_nmod_poly_t prod
Definition: facHensel.cc:100
void henselLift12(const CanonicalForm &F, CFList &factors, int l, CFArray &Pi, CFList &diophant, CFMatrix &M, modpk &b, bool sort)
Hensel lift from univariate to bivariate.
Definition: facHensel.cc:1274
convertFacCF2nmod_poly_t(FLINTmipo, M)
void henselLiftResume12(const CanonicalForm &F, CFList &factors, int start, int end, CFArray &Pi, const CFList &diophant, CFMatrix &M, const modpk &b)
resume Hensel lift from univariate to bivariate. Assumes factors are lifted to precision Variable (2)...
Definition: facHensel.cc:1343
nmod_poly_clear(FLINTmipo)
fq_nmod_poly_clear(prod, fq_con)
This file defines functions for Hensel lifting.
CanonicalForm mulNTL(const CanonicalForm &F, const CanonicalForm &G, const modpk &b)
multiplication of univariate polys using FLINT/NTL over F_p, F_q, Z/p^k, Z/p^k[t]/(f),...
Definition: facMul.cc:411
bool uniFdivides(const CanonicalForm &A, const CanonicalForm &B)
divisibility test for univariate polys
Definition: facMul.cc:3759
CanonicalForm mulMod2(const CanonicalForm &A, const CanonicalForm &B, const CanonicalForm &M)
Karatsuba style modular multiplication for bivariate polynomials.
Definition: facMul.cc:2986
CanonicalForm prodMod(const CFList &L, const CanonicalForm &M)
product of all elements in L modulo M via divide-and-conquer.
Definition: facMul.cc:3180
This file defines functions for fast multiplication and division with remainder.
#define const
Definition: fegetopt.c:39
static BOOLEAN IsOne(number a, const coeffs)
Definition: flintcf_Q.cc:332
static BOOLEAN IsZero(number a, const coeffs)
Definition: flintcf_Q.cc:328
template CanonicalForm tmax(const CanonicalForm &, const CanonicalForm &)
template CanonicalForm tmin(const CanonicalForm &, const CanonicalForm &)
template List< Variable > Union(const List< Variable > &, const List< Variable > &)
template List< Variable > Difference(const List< Variable > &, const List< Variable > &)
template bool find(const List< CanonicalForm > &, const CanonicalForm &)
bool isIrreducible(const CanonicalForm &f)
bool isIrreducible ( const CanonicalForm & f )
VAR char gf_name
Definition: gfops.cc:52
INST_VAR CanonicalForm gf_mipo
Definition: gfops.cc:56
STATIC_VAR jList * T
Definition: janet.cc:30
STATIC_VAR TreeM * G
Definition: janet.cc:31
STATIC_VAR Poly * h
Definition: janet.cc:971
#define info
Definition: libparse.cc:1256
static int index(p_Length length, p_Ord ord)
Definition: p_Procs_Impl.h:592
int status int void size_t count
Definition: si_signals.h:59
int status int void * buf
Definition: si_signals.h:59
#define A
Definition: sirandom.c:24
static poly normalize(poly next_p, ideal add_generators, syStrategy syzstr, int *g_l, int *p_l, int crit_comp)
Definition: syz3.cc:1027
#define TIMING_DEFINE_PRINT(t)
Definition: timing.h:95
#define TIMING_START(t)
Definition: timing.h:92
#define TIMING_END_AND_PRINT(t, msg)
Definition: timing.h:94
void prune(Variable &alpha)
Definition: variable.cc:261
CanonicalForm getMipo(const Variable &alpha, const Variable &x)
Definition: variable.cc:207
Variable rootOf(const CanonicalForm &mipo, char name)
returns a symbolic root of polynomial with name name Use it to define algebraic variables
Definition: variable.cc:162
int gcd(int a, int b)
Definition: walkSupport.cc:836