source: git/factory/facFactorize.cc @ 09723d

fieker-DuValspielwiese
Last change on this file since 09723d was 327efa2, checked in by Martin Lee <martinlee84@…>, 13 years ago
different lifting in precomputeLeadingCoeff extend henselLift122 to lift more than two factors git-svn-id: file:///usr/local/Singular/svn/trunk@14382 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 21.7 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file facFqFactorize.cc
5 *
6 * multivariate factorization over Q(a)
7 *
8 * @author Martin Lee
9 *
10 * @internal @version \$Id$
11 *
12 **/
13/*****************************************************************************/
14
15#include <config.h>
16
17#include "assert.h"
18#include "debug.h"
19#include "timing.h"
20
21#include "facFqFactorizeUtil.h"
22#include "facFactorize.h"
23#include "facFqFactorize.h"
24#include "cf_random.h"
25#include "facHensel.h"
26#include "cf_gcd_smallp.h"
27#include "cf_map_ext.h"
28#include "algext.h"
29#include "cf_reval.h"
30
31CFList evalPoints (const CanonicalForm& F, CFList& eval, Evaluation& E)
32{
33  CFList result;
34  Variable x= Variable (1);
35
36  bool found= false;
37  CanonicalForm deriv_x, gcd_deriv;
38  CFListIterator iter;
39  do
40  {
41    eval.insert (F);
42    bool bad= false;
43    for (int i= E.max(); i >= E.min(); i--)
44    {
45      eval.insert (eval.getFirst()( E [i], i));
46      result.append (E[i]);
47      if (degree (eval.getFirst(), i - 1) != degree (F, i - 1))
48      {
49        result= CFList();
50        eval= CFList();
51        bad= true;
52        break;
53      }
54    }
55
56    if (bad)
57    {
58      E.nextpoint();
59      continue;
60    }
61
62    if (degree (eval.getFirst()) != degree (F, 1))
63    {
64      result= CFList();
65      eval= CFList();
66      E.nextpoint();
67      continue;
68    }
69
70    deriv_x= deriv (eval.getFirst(), x);
71    gcd_deriv= gcd (eval.getFirst(), deriv_x);
72    if (degree (gcd_deriv) > 0)
73    {
74      result= CFList();
75      eval= CFList();
76      E.nextpoint();
77      continue;
78    }
79    iter= eval;
80    iter++;
81    CanonicalForm contentx= content (iter.getItem(), x);
82    if (degree (contentx) > 0)
83    {
84      result= CFList();
85      eval= CFList();
86      E.nextpoint();
87      continue;
88    }
89    found= true;
90  }
91  while (!found);
92
93  if (!eval.isEmpty())
94    eval.removeFirst();
95  return result;
96}
97
98void
99factorizationWRTDifferentSecondVars (const CanonicalForm& A, CFList*& Aeval,
100                                     int& minFactorsLength, bool& irred,
101                                     const Variable& w)
102{
103  Variable x= Variable (1);
104  minFactorsLength= 0;
105  irred= false;
106  Variable v;
107  CFList factors;
108  for (int j= 0; j < A.level() - 2; j++)
109  {
110    if (!Aeval[j].isEmpty())
111    {
112      v= Variable (Aeval[j].getFirst().level());
113
114      factors= ratBiSqrfFactorize (Aeval[j].getFirst(), w);
115
116      if (factors.getFirst().inCoeffDomain())
117        factors.removeFirst();
118
119      if (minFactorsLength == 0)
120        minFactorsLength= factors.length();
121      else
122        minFactorsLength= tmin (minFactorsLength, factors.length());
123
124      if (factors.length() == 1)
125      {
126        irred= true;
127        return;
128      }
129      sortList (factors, x);
130      Aeval [j]= factors;
131    }
132  }
133}
134
135int
136testFactors (const CanonicalForm& G, const CFList& uniFactors,
137             CanonicalForm& sqrfPartF, CFList& factors,
138             CFFList*& bufSqrfFactors, CFList& evalSqrfPartF)
139{
140  CanonicalForm tmp;
141  CFListIterator j;
142  for (CFListIterator i= uniFactors; i.hasItem(); i++)
143  {
144    tmp= i.getItem();
145    if (i.hasItem())
146      i++;
147    else
148      break;
149    for (j= i; j.hasItem(); j++)
150    {
151      if (tmp == j.getItem())
152        return 0;
153    }
154  }
155
156  CanonicalForm F= G;
157  CFFList sqrfFactorization= sqrFree (F);
158
159  sqrfPartF= 1;
160  for (CFFListIterator i= sqrfFactorization; i.hasItem(); i++)
161    sqrfPartF *= i.getItem().factor();
162
163  evalSqrfPartF= evaluateAtZero (sqrfPartF);
164
165  CanonicalForm test= evalSqrfPartF.getFirst() (0, 2);
166
167  if (degree (test) != degree (sqrfPartF, 1))
168    return 0;
169
170  CFFList sqrfFactors;
171  CFList tmp2;
172  int k= 0;
173  factors= uniFactors;
174  CFFListIterator iter;
175  for (CFListIterator i= factors; i.hasItem(); i++, k++)
176  {
177    tmp= 1;
178    sqrfFactors= sqrFree (i.getItem());
179
180    for (iter= sqrfFactors; iter.hasItem(); iter++)
181    {
182      tmp2.append (iter.getItem().factor());
183      tmp *= iter.getItem().factor();
184    }
185    i.getItem()= tmp/Lc(tmp);
186    bufSqrfFactors [k]= sqrfFactors;
187  }
188
189  for (int i= 0; i < factors.length() - 1; i++)
190  {
191    for (int k= i + 1; k < factors.length(); k++)
192    {
193      gcdFreeBasis (bufSqrfFactors [i], bufSqrfFactors[k]);
194    }
195  }
196
197  factors= CFList();
198  for (int i= 0; i < uniFactors.length(); i++)
199  {
200    if (i == 0)
201    {
202      for (iter= bufSqrfFactors [i]; iter.hasItem(); iter++)
203      {
204        if (iter.getItem().factor().inCoeffDomain())
205          continue;
206        iter.getItem()= CFFactor (iter.getItem().factor()/
207                                  Lc (iter.getItem().factor()),
208                                  iter.getItem().exp());
209        factors.append (iter.getItem().factor());
210      }
211    }
212    else
213    {
214      for (iter= bufSqrfFactors [i]; iter.hasItem(); iter++)
215      {
216        if (iter.getItem().factor().inCoeffDomain())
217          continue;
218        iter.getItem()= CFFactor (iter.getItem().factor()/
219                               Lc (iter.getItem().factor()),
220                               iter.getItem().exp());
221        if (!find (factors, iter.getItem().factor()))
222          factors.append (iter.getItem().factor());
223      }
224    }
225  }
226
227  test= prod (factors);
228  tmp= evalSqrfPartF.getFirst() (0,2);
229  if (test/Lc (test) != tmp/Lc (tmp))
230    return 0;
231  else
232    return 1;
233}
234
235CFList
236precomputeLeadingCoeff (const CanonicalForm& LCF, const CFList& LCFFactors,
237                        const CFList& evaluation,CFList*& differentSecondVarLCs,
238                        int length, Variable& y
239                       )
240{
241  y= Variable (1);
242  if (LCF.inCoeffDomain())
243  {
244    CFList result;
245    for (int i= 1; i <= LCFFactors.length() + 1; i++)
246      result.append (1);
247    return result;
248  }
249
250  CFMap N;
251  CanonicalForm F= compress (LCF, N);
252  if (LCF.isUnivariate())
253  {
254    CFList result;
255    int LCFLevel= LCF.level();
256    bool found= false;
257    if (LCFLevel == 2)
258    {
259    //bivariate leading coefficients are already the true leading coefficients
260      result= LCFFactors;
261      Variable v= Variable (LCF.mvar());
262      CanonicalForm bla= 1;
263      for (CFListIterator i= result; i.hasItem(); i++)
264      {
265        i.getItem()= i.getItem() (v+evaluation.getLast(), v);
266        bla *= Lc (i.getItem());
267      }
268      found= true;
269    }
270    else
271    {
272      CFListIterator j;
273      for (int i= 0; i < length; i++)
274      {
275        for (j= differentSecondVarLCs[i]; j.hasItem(); j++)
276        {
277          if (j.getItem().level() == LCFLevel)
278          {
279            found= true;
280            break;
281          }
282        }
283        if (found)
284        {
285          result= differentSecondVarLCs [i];
286          break;
287        }
288      }
289      if (!found)
290        result= LCFFactors;
291    }
292    if (found)
293      result.insert (Lc (LCF));
294    else
295      result.append (LCF);
296    return result;
297  }
298
299  CFList factors= LCFFactors;
300
301  CFMap dummy;
302  for (CFListIterator i= factors; i.hasItem(); i++)
303  {
304    i.getItem()= compress (i.getItem(), dummy);
305    i.getItem()= i.getItem() (Variable (1)+evaluation.getLast(), Variable (1));
306  }
307
308  CanonicalForm sqrfPartF;
309  CFFList * bufSqrfFactors= new CFFList [factors.length()];
310  CFList evalSqrfPartF;
311  CFList bufFactors;
312  //TODO sqrfPartF einmal berechnen nicht stÀndig
313  int pass= testFactors (F, factors, sqrfPartF,
314                         bufFactors, bufSqrfFactors, evalSqrfPartF);
315
316  bool foundDifferent= false;
317  Variable z;
318  Variable x= y;
319  int j= 0;
320  if (!pass)
321  {
322    int lev;
323    for (int i= 1; i <= LCF.level(); i++)
324    {
325      if(degree (LCF, i) > 0)
326      {
327        lev= i - 1;
328        break;
329      }
330    }
331    for (int i= 0; i < length; i++)
332    {
333      CanonicalForm bufF;
334      CFListIterator iter;
335      CFList bufBufFactors;
336      if (!differentSecondVarLCs [i].isEmpty())
337      {
338        bool allConstant= true;
339        for (iter= differentSecondVarLCs[i]; iter.hasItem(); iter++)
340        {
341          if (!iter.getItem().inCoeffDomain())
342          {
343            allConstant= false;
344            y= Variable (iter.getItem().level());
345          }
346        }
347        if (allConstant)
348          continue;
349
350        bufFactors= differentSecondVarLCs [i];
351        for (iter= bufFactors; iter.hasItem(); iter++)
352          iter.getItem()= swapvar (iter.getItem(), x, y);
353        bufF= F;
354        z= Variable (y.level() - lev);
355        bufF= swapvar (bufF, x, z);
356        bufBufFactors= bufFactors;
357        pass= testFactors (bufF, bufBufFactors, sqrfPartF, bufFactors,
358                           bufSqrfFactors, evalSqrfPartF);
359        if (pass)
360        {
361          foundDifferent= true;
362          F= bufF;
363          CFList l= factors;
364          for (iter= l; iter.hasItem(); iter++)
365            iter.getItem()= swapvar (iter.getItem(), x, y);
366          differentSecondVarLCs [i]= l;
367          j= i;
368          break;
369        }
370        if (!pass && i == length - 1)
371        {
372          CFList result;
373          result.append (LCF);
374          for (int j= 1; j <= factors.length(); j++)
375            result.append (LCF);
376          y= Variable (1);
377          return result;
378        }
379      }
380    }
381  }
382  if (!pass)
383  {
384    CFList result;
385    result.append (LCF);
386    for (int j= 1; j <= factors.length(); j++)
387      result.append (LCF);
388    y= Variable (1);
389    return result;
390  }
391  else
392    factors= bufFactors;
393
394
395  bufFactors= factors;
396
397  if (factors.length() > 1)
398  {
399    CanonicalForm LC1= LC (evalSqrfPartF.getFirst(), 1);
400
401    CFArray leadingCoeffs= CFArray (factors.length());
402    for (int i= 0; i < factors.length(); i++)
403      leadingCoeffs[i]= LC1;
404    for (CFListIterator i= factors; i.hasItem(); i++)
405      i.getItem() *= LC1 (0,2)/Lc (i.getItem());
406    factors.insert (1);
407
408    CanonicalForm
409    newSqrfPartF= evalSqrfPartF.getFirst()*power (LC1, factors.length() - 2);
410
411    int liftBound= degree (newSqrfPartF,2) + 1;
412
413    CFMatrix M= CFMatrix (liftBound, factors.length() - 1);
414    CFArray Pi;
415    CFList diophant;
416    henselLift122 (newSqrfPartF, factors, liftBound, Pi, diophant, M,
417                   leadingCoeffs, false);
418
419    if (sqrfPartF.level() > 2)
420    {
421      int* liftBounds= new int [sqrfPartF.level() - 1];
422      liftBounds [0]= liftBound;
423      bool noOneToOne= false;
424      CFList *leadingCoeffs2= new CFList [sqrfPartF.level()-2];
425      LC1= LC (evalSqrfPartF.getLast(), 1);
426      CFList LCs;
427      for (int i= 0; i < factors.length(); i++)
428        LCs.append (LC1);
429      leadingCoeffs2 [sqrfPartF.level() - 3]= LCs;
430      for (int i= sqrfPartF.level() - 1; i > 2; i--)
431      {
432        for (CFListIterator j= LCs; j.hasItem(); j++)
433          j.getItem()= j.getItem() (0, i + 1);
434        leadingCoeffs2 [i - 3]= LCs;
435      }
436      sqrfPartF= sqrfPartF*power (LC1, factors.length()-1);
437
438      int liftBoundsLength= sqrfPartF.level() - 1;
439      for (int i= 1; i < liftBoundsLength; i++)
440        liftBounds [i]= degree (sqrfPartF, i + 2) + 1;
441      evalSqrfPartF= evaluateAtZero (sqrfPartF);
442      evalSqrfPartF.removeFirst();
443      factors= nonMonicHenselLift (evalSqrfPartF, factors, leadingCoeffs2,
444               diophant, Pi, liftBounds, sqrfPartF.level() - 1, noOneToOne);
445      delete [] leadingCoeffs2;
446      delete [] liftBounds;
447    }
448  }
449  else
450    factors= evalSqrfPartF.getLast();
451
452  CFList interMedResult= recoverFactors (evalSqrfPartF.getLast(), factors);
453
454  CFList result;
455  CFFListIterator k;
456  CanonicalForm tmp;
457  for (int i= 0; i < LCFFactors.length(); i++)
458  {
459    tmp= 1;
460    for (k= bufSqrfFactors[i]; k.hasItem(); k++)
461    {
462      int pos= findItem (bufFactors, k.getItem().factor());
463      if (pos)
464        tmp *= power (getItem (interMedResult, pos), k.getItem().exp());
465    }
466    result.append (tmp);
467  }
468
469  for (CFListIterator i= result; i.hasItem(); i++)
470  {
471    F /= i.getItem();
472    if (foundDifferent)
473      i.getItem()= swapvar (i.getItem(), x, z);
474    i.getItem()= N (i.getItem());
475  }
476
477  if (foundDifferent)
478  {
479    CFList l= differentSecondVarLCs [j];
480    for (CFListIterator i= l; i.hasItem(); i++)
481      i.getItem()= swapvar (i.getItem(), y, z);
482    differentSecondVarLCs [j]= l;
483    F= swapvar (F, x, z);
484  }
485
486  result.insert (N (F));
487
488  result= distributeContent (result, differentSecondVarLCs, length);
489
490  if (!result.getFirst().inCoeffDomain())
491  {
492    CFListIterator i= result;
493    CanonicalForm tmp;
494    if (foundDifferent)
495      i.getItem()= swapvar (i.getItem(), Variable (2), y);
496
497    tmp= i.getItem();
498
499    i++;
500    for (; i.hasItem(); i++)
501    {
502      if (foundDifferent)
503        i.getItem()= swapvar (i.getItem(), Variable (2), y)*tmp;
504      else
505        i.getItem() *= tmp;
506    }
507  }
508  else
509    y= Variable (1);
510
511  return result;
512}
513
514
515CFList
516multiFactorize (const CanonicalForm& F, const Variable& v)
517{
518  if (F.inCoeffDomain())
519    return CFList (F);
520
521  // compress and find main Variable
522  CFMap N;
523  CanonicalForm A= myCompress (F, N);
524
525  //univariate case
526  if (F.isUnivariate())
527  {
528    CFList result= conv (factorize (F, v));
529    if (result.getFirst().inCoeffDomain())
530      result.removeFirst();
531    return result;
532  }
533
534  //bivariate case
535  if (A.level() == 2)
536  {
537    CFList buf= biFactorize (F, v);
538    return buf;
539  }
540
541  Variable x= Variable (1);
542  Variable y= Variable (2);
543
544  // remove content
545  CFList contentAi;
546  CanonicalForm lcmCont= lcmContent (A, contentAi);
547  A /= lcmCont;
548
549  // trivial after content removal
550  CFList contentAFactors;
551  if (A.inCoeffDomain())
552  {
553    for (CFListIterator i= contentAi; i.hasItem(); i++)
554    {
555      if (i.getItem().inCoeffDomain())
556        continue;
557      else
558      {
559        lcmCont /= i.getItem();
560        contentAFactors=
561        Union (multiFactorize (lcmCont, v),
562               multiFactorize (i.getItem(), v));
563        break;
564      }
565    }
566    decompress (contentAFactors, N);
567    if (isOn (SW_RATIONAL))
568      normalize (contentAFactors);
569    return contentAFactors;
570  }
571
572  // factorize content
573  contentAFactors= multiFactorize (lcmCont, v);
574
575  // univariate after content removal
576  CFList factors;
577  if (A.isUnivariate ())
578  {
579    factors= conv (factorize (A, v));
580    append (factors, contentAFactors);
581    decompress (factors, N);
582    return factors;
583  }
584
585  // check main variable
586  CFList Aeval, list, evaluation, bufEvaluation, bufAeval;
587  int factorNums= 3;
588  CanonicalForm bivarEval;
589  CFList biFactors, bufBiFactors;
590  CanonicalForm evalPoly;
591  int lift, bufLift;
592  CFList* bufAeval2= new CFList [A.level() - 2];
593  CFList* Aeval2= new CFList [A.level() - 2];
594  int counter;
595  int differentSecondVar= 0;
596  CanonicalForm bufA;
597  // several bivariate factorizations
598  REvaluation E (2, A.level(), IntRandom (25));
599  for (int i= 0; i < factorNums; i++)
600  {
601    counter= 0;
602    bufA= A;
603    bufAeval= CFList();
604    bufEvaluation= evalPoints (bufA, bufAeval, E);
605    E.nextpoint();
606    evalPoly= 0;
607
608    bivarEval= bufEvaluation.getLast();
609
610    evaluationWRTDifferentSecondVars (bufAeval2, bufEvaluation, A);
611
612    for (int j= 0; j < A.level() - 1; j++)
613    {
614      if (!bufAeval2[j].isEmpty())
615        counter++;
616    }
617
618    bufLift= degree (A, y) + 1 + degree (LC(A, x), y);
619
620    TIMING_START (fac_bi_factorizer);
621    bufBiFactors= ratBiSqrfFactorize (bufAeval.getFirst(), v);
622    TIMING_END_AND_PRINT (fac_bi_factorizer,
623                          "time for bivariate factorization: ");
624    bufBiFactors.removeFirst();
625
626    if (bufBiFactors.length() == 1)
627    {
628      factors.append (A);
629      appendSwapDecompress (factors, contentAFactors, N, 0, 0, x);
630      if (isOn (SW_RATIONAL))
631        normalize (factors);
632      delete [] bufAeval2;
633      delete [] Aeval2;
634      return factors;
635    }
636
637    if (i == 0)
638    {
639      Aeval= bufAeval;
640      evaluation= bufEvaluation;
641      biFactors= bufBiFactors;
642      lift= bufLift;
643      for (int j= 0; j < A.level() - 2; j++)
644        Aeval2 [j]= bufAeval2 [j];
645      differentSecondVar= counter;
646    }
647    else
648    {
649      if (bufBiFactors.length() < biFactors.length() ||
650          ((bufLift < lift) && (bufBiFactors.length() == biFactors.length())) ||
651          counter > differentSecondVar)
652      {
653        Aeval= bufAeval;
654        evaluation= bufEvaluation;
655        biFactors= bufBiFactors;
656        lift= bufLift;
657        for (int j= 0; j < A.level() - 2; j++)
658          Aeval2 [j]= bufAeval2 [j];
659        differentSecondVar= counter;
660      }
661    }
662    int k= 0;
663    for (CFListIterator j= bufEvaluation; j.hasItem(); j++, k++)
664      evalPoly += j.getItem()*power (x, k);
665    list.append (evalPoly);
666  }
667
668  delete [] bufAeval2;
669
670  sortList (biFactors, x);
671
672  int minFactorsLength;
673  bool irred= false;
674  factorizationWRTDifferentSecondVars (A, Aeval2, minFactorsLength, irred, v);
675
676  if (irred)
677  {
678    factors.append (A);
679    appendSwapDecompress (factors, contentAFactors, N, 0, 0, x);
680    if (isOn (SW_RATIONAL))
681      normalize (factors);
682    delete [] Aeval2;
683    return factors;
684  }
685
686  if (minFactorsLength == 0)
687    minFactorsLength= biFactors.length();
688  else if (biFactors.length() > minFactorsLength)
689    refineBiFactors (A, biFactors, Aeval2, evaluation, minFactorsLength);
690
691  CFList uniFactors= buildUniFactors (biFactors, evaluation.getLast(), y);
692
693  CFList * oldAeval= new CFList [A.level() - 2];
694  for (int i= 0; i < A.level() - 2; i++)
695    oldAeval[i]= Aeval2[i];
696
697  getLeadingCoeffs (A, Aeval2, uniFactors, evaluation);
698
699  CFList biFactorsLCs;
700  for (CFListIterator i= biFactors; i.hasItem(); i++)
701    biFactorsLCs.append (LC (i.getItem(), 1));
702
703
704  //shifting to zero
705  A= shift2Zero (A, Aeval, evaluation);
706
707  CanonicalForm hh= Lc (Aeval.getFirst());
708
709  for (CFListIterator i= Aeval; i.hasItem(); i++)
710    i.getItem() /= hh;
711
712  A /= hh;
713
714  Variable w;
715  CFList leadingCoeffs= precomputeLeadingCoeff (LC (A, 1), biFactorsLCs,
716                                          evaluation, Aeval2, A.level() - 2, w);
717
718  if (w.level() != 1)
719  {
720    A= swapvar (A, y, w);
721    for (int i= 0; i < A.level() - 2; i++)
722    {
723      if (oldAeval[i].isEmpty())
724        continue;
725      if (oldAeval[i].getFirst().level() == w.level())
726      {
727        biFactors= CFList();
728        for (CFListIterator iter= oldAeval [i]; iter.hasItem(); iter++)
729          biFactors.append (swapvar (iter.getItem(), w, y));
730      }
731    }
732    int i= A.level();
733    CanonicalForm evalPoint;
734    for (CFListIterator iter= evaluation; iter.hasItem(); iter++, i--)
735    {
736      if (i == w.level())
737      {
738        evalPoint= iter.getItem();
739        iter.getItem()= evaluation.getLast();
740        evaluation.removeLast();
741        evaluation.append (evalPoint);
742        break;
743      }
744    }
745    Aeval= evaluateAtZero (A);
746  }
747
748  CFListIterator iter= biFactors;
749  for (; iter.hasItem(); iter++)
750    iter.getItem()= iter.getItem () (y + evaluation.getLast(), y);
751
752  CanonicalForm oldA= A;
753  CFList oldBiFactors= biFactors;
754  if (!leadingCoeffs.getFirst().inCoeffDomain())
755  {
756    CanonicalForm tmp= power (leadingCoeffs.getFirst(), biFactors.length() - 1);
757    A *= tmp;
758    Aeval= evaluateAtZero (A);
759    tmp= leadingCoeffs.getFirst();
760    for (int i= A.level(); i > 2; i--)
761      tmp= tmp (0, i);
762    if (!tmp.inCoeffDomain())
763    {
764      for (CFListIterator i= biFactors; i.hasItem(); i++)
765      {
766        i.getItem() *= tmp/LC (i.getItem(), 1);
767        i.getItem() /= Lc (i.getItem());
768      }
769    }
770    hh= Lc (Aeval.getFirst());
771    for (CFListIterator i= Aeval; i.hasItem(); i++)
772      i.getItem() /= hh;
773
774    A /= hh;
775  }
776
777  leadingCoeffs.removeFirst();
778
779  //prepare leading coefficients
780  CFList* leadingCoeffs2= new CFList [A.level() - 2];
781  prepareLeadingCoeffs (leadingCoeffs2, A.level(), leadingCoeffs, biFactors);
782
783  CFArray Pi;
784  CFList diophant;
785  int* liftBounds= new int [A.level() - 1];
786  int liftBoundsLength= A.level() - 1;
787  for (int i= 0; i < liftBoundsLength; i++)
788    liftBounds [i]= degree (A, i + 2) + 1;
789
790  Aeval.removeFirst();
791  bool noOneToOne= false;
792
793  factors= nonMonicHenselLift (Aeval, biFactors, leadingCoeffs2, diophant,
794                               Pi, liftBounds, liftBoundsLength, noOneToOne);
795
796  if (!noOneToOne)
797  {
798    int check= factors.length();
799    factors= recoverFactors (A, factors);
800    if (check != factors.length())
801      noOneToOne= true;
802  }
803  if (noOneToOne)
804  {
805    A= oldA;
806    Aeval= evaluateAtZero (A);
807    biFactors= oldBiFactors;
808    CanonicalForm LCA= LC (Aeval.getFirst(), 1);
809    CanonicalForm yToLift= power (y, lift);
810    CFListIterator i= biFactors;
811    lift= degree (i.getItem(), 2) + degree (LC (i.getItem(), 1)) + 1;
812    i++;
813
814    for (; i.hasItem(); i++)
815      lift= tmax (lift, degree (i.getItem(), 2)+degree (LC (i.getItem(), 1))+1);
816
817    lift= tmax (degree (Aeval.getFirst() , 2) + 1, lift);
818
819    i= biFactors;
820    yToLift= power (y, lift);
821    CanonicalForm dummy;
822    for (; i.hasItem(); i++)
823    {
824      LCA= LC (i.getItem(), 1);
825      extgcd (LCA, yToLift, LCA, dummy);
826      i.getItem()= mod (i.getItem()*LCA, yToLift);
827    }
828
829    liftBoundsLength= F.level() - 1;
830    liftBounds= liftingBounds (A, lift);
831
832    CFList MOD;
833    bool earlySuccess;
834    CFList earlyFactors;
835    ExtensionInfo info= ExtensionInfo (false);
836    TIMING_START (fac_hensel_lift);
837    CFList liftedFactors= henselLiftAndEarly
838                          (A, MOD, liftBounds, earlySuccess, earlyFactors,
839                           Aeval, biFactors, evaluation, info);
840    TIMING_END_AND_PRINT (fac_hensel_lift, "time for hensel lifting: ");
841
842    TIMING_START (fac_factor_recombination);
843    factors= factorRecombination (A, liftedFactors, MOD);
844    TIMING_END_AND_PRINT (fac_factor_recombination,
845                          "time for factor recombination: ");
846
847    if (earlySuccess)
848      factors= Union (factors, earlyFactors);
849  }
850
851  for (CFListIterator i= factors; i.hasItem(); i++)
852  {
853    int kk= Aeval.getLast().level();
854    for (CFListIterator j= evaluation; j.hasItem(); j++, kk--)
855    {
856      if (i.getItem().level() < kk)
857        continue;
858      i.getItem()= i.getItem() (Variable (kk) - j.getItem(), kk);
859    }
860  }
861
862  if (w.level() != 1)
863  {
864    for (CFListIterator iter= factors; iter.hasItem(); iter++)
865      iter.getItem()= swapvar (iter.getItem(), w, y);
866  }
867
868  swap (factors, 0, 0, x);
869  append (factors, contentAFactors);
870  decompress (factors, N);
871  if (isOn (SW_RATIONAL))
872    normalize (factors);
873
874  delete[] liftBounds;
875
876  return factors;
877}
Note: See TracBrowser for help on using the repository browser.