source: git/factory/facBivar.cc @ 978ce3

jengelh-datetimespielwiese
Last change on this file since 978ce3 was 978ce3, checked in by Martin Lee <martinlee84@…>, 11 years ago
fix: multiple definitions with --enable-timing
  • Property mode set to 100644
File size: 19.5 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file facBivar.cc
5 *
6 * bivariate 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 "cf_algorithm.h"
22#include "facFqBivar.h"
23#include "facBivar.h"
24#include "facHensel.h"
25#include "facMul.h"
26#include "cf_primes.h"
27
28#ifdef HAVE_NTL
29TIMING_DEFINE_PRINT(fac_uni_factorizer)
30TIMING_DEFINE_PRINT(fac_bi_hensel_lift)
31TIMING_DEFINE_PRINT(fac_bi_factor_recombination)
32
33// bound on coeffs of f (cf. Musser: Multivariate Polynomial Factorization,
34//                          Gelfond: Transcendental and Algebraic Numbers)
35modpk
36coeffBound ( const CanonicalForm & f, int p )
37{
38    int * degs = degrees( f );
39    int M = 0, i, k = f.level();
40    CanonicalForm b= 1;
41    for ( i = 1; i <= k; i++ )
42    {
43      M += degs[i];
44      b *= degs[i] + 1;
45    }
46    b /= power (CanonicalForm (2), k);
47    b= b.sqrt() + 1;
48    b *= 2 * maxNorm( f ) * power( CanonicalForm( 2 ), M );
49    CanonicalForm B = p;
50    k = 1;
51    while ( B < b ) {
52        B *= p;
53        k++;
54    }
55    return modpk( p, k );
56}
57
58void findGoodPrime(const CanonicalForm &f, int &start)
59{
60  if (! f.inBaseDomain() )
61  {
62    CFIterator i = f;
63    for(;;)
64    {
65      if  ( i.hasTerms() )
66      {
67        findGoodPrime(i.coeff(),start);
68        if (0==cf_getBigPrime(start)) return;
69        if((i.exp()!=0) && ((i.exp() % cf_getBigPrime(start))==0))
70        {
71          start++;
72          i=f;
73        }
74        else  i++;
75      }
76      else break;
77    }
78  }
79  else
80  {
81    if (f.inZ())
82    {
83      if (0==cf_getBigPrime(start)) return;
84      while((!f.isZero()) && (mod(f,cf_getBigPrime(start))==0))
85      {
86        start++;
87        if (0==cf_getBigPrime(start)) return;
88      }
89    }
90  }
91}
92
93modpk
94coeffBound ( const CanonicalForm & f, int p, const CanonicalForm& mipo )
95{
96    int * degs = degrees( f );
97    int M = 0, i, k = f.level();
98    CanonicalForm K= 1;
99    for ( i = 1; i <= k; i++ )
100    {
101        M += degs[i];
102        K *= degs[i] + 1;
103    }
104    K /= power (CanonicalForm (2), k);
105    K= K.sqrt()+1;
106    K *= power (CanonicalForm (2), M);
107    int N= degree (mipo);
108    CanonicalForm b;
109    b= 2*power (maxNorm (f), N)*power (maxNorm (mipo), 4*N)*K*
110       power (CanonicalForm (2), N)*(CanonicalForm (M+1).sqrt()+1)*
111       power (CanonicalForm (N+1).sqrt()+1, 7*N);
112    b /= power (abs (lc (mipo)), N);
113
114    ZZX NTLmipo= convertFacCF2NTLZZX (mipo);
115    ZZX NTLLcf= convertFacCF2NTLZZX (Lc (f));
116    ZZ NTLf= resultant (NTLmipo, NTLLcf);
117    ZZ NTLD= discriminant (NTLmipo);
118    b /= abs (convertZZ2CF (NTLf))*abs (convertZZ2CF (NTLD));
119
120    CanonicalForm B = p;
121    k = 1;
122    while ( B < b ) {
123        B *= p;
124        k++;
125    }
126    return modpk( p, k );
127}
128
129CFList conv (const CFFList& L)
130{
131  CFList result;
132  for (CFFListIterator i= L; i.hasItem(); i++)
133    result.append (i.getItem().factor());
134  return result;
135}
136
137bool testPoint (const CanonicalForm& F, CanonicalForm& G, int i)
138{
139  G= F (i, 2);
140  if (G.inCoeffDomain() || degree (F, 1) > degree (G, 1))
141    return false;
142
143  if (degree (gcd (deriv (G, G.mvar()), G)) > 0)
144    return false;
145  return true;
146}
147
148CanonicalForm evalPoint (const CanonicalForm& F, int& i)
149{
150  Variable x= Variable (1);
151  Variable y= Variable (2);
152  CanonicalForm result;
153
154  int k;
155
156  if (i == 0)
157  {
158    if (testPoint (F, result, i))
159      return result;
160  }
161  do
162  {
163    if (i > 0)
164      k= 1;
165    else
166      k= 2;
167    while (k < 3)
168    {
169      if (k == 1)
170      {
171        if (testPoint (F, result, i))
172          return result;
173      }
174      else
175      {
176        if (testPoint (F, result, -i))
177        {
178          i= -i;
179          return result;
180        }
181        else if (i < 0)
182          i= -i;
183      }
184      k++;
185    }
186    i++;
187  } while (1);
188}
189
190CFList
191earlyFactorDetection0 (CanonicalForm& F, CFList& factors,int& adaptedLiftBound,
192                      DegreePattern& degs, bool& success, int deg)
193{
194  DegreePattern bufDegs1= degs;
195  DegreePattern bufDegs2;
196  CFList result;
197  CFList T= factors;
198  CanonicalForm buf= F;
199  CanonicalForm LCBuf= LC (buf, Variable (1));
200  CanonicalForm g, quot;
201  CanonicalForm M= power (F.mvar(), deg);
202  adaptedLiftBound= 0;
203  int d= degree (F) + degree (LCBuf, F.mvar());
204  for (CFListIterator i= factors; i.hasItem(); i++)
205  {
206    if (!bufDegs1.find (degree (i.getItem(), 1)))
207      continue;
208    else
209    {
210      g= i.getItem() (0, 1);
211      g *= LCBuf;
212      g= mod (g, M);
213      if (fdivides (LC (g), LCBuf))
214      {
215        g= mulMod2 (i.getItem(), LCBuf, M);
216        g /= content (g, Variable (1));
217        if (fdivides (g, buf, quot))
218        {
219          result.append (g);
220          buf= quot;
221          d -= degree (g) + degree (LC (g, Variable (1)), F.mvar());
222          LCBuf= LC (buf, Variable (1));
223          T= Difference (T, CFList (i.getItem()));
224
225          // compute new possible degree pattern
226          bufDegs2= DegreePattern (T);
227          bufDegs1.intersect (bufDegs2);
228          bufDegs1.refine ();
229          if (bufDegs1.getLength() <= 1)
230          {
231            result.append (buf);
232            break;
233          }
234        }
235      }
236    }
237  }
238  adaptedLiftBound= d + 1;
239  if (d < deg)
240  {
241    factors= T;
242    degs= bufDegs1;
243    F= buf;
244    success= true;
245  }
246  if (bufDegs1.getLength() <= 1)
247    degs= bufDegs1;
248  return result;
249}
250
251
252CFList
253henselLiftAndEarly0 (CanonicalForm& A, bool& earlySuccess, CFList&
254                    earlyFactors, DegreePattern& degs, int& liftBound,
255                    const CFList& uniFactors, const CanonicalForm& eval)
256{
257  int sizeOfLiftPre;
258  int * liftPre= getLiftPrecisions (A, sizeOfLiftPre, degree (LC (A, 1), 2));
259
260  Variable x= Variable (1);
261  Variable y= Variable (2);
262  CFArray Pi;
263  CFList diophant;
264  CFList bufUniFactors= uniFactors;
265  bufUniFactors.insert (LC (A, x));
266  CFMatrix M= CFMatrix (liftBound, bufUniFactors.length() - 1);
267  earlySuccess= false;
268  int newLiftBound= 0;
269  int smallFactorDeg= tmin (11, liftPre [sizeOfLiftPre- 1] + 1);//this is a tunable parameter
270  if (smallFactorDeg >= liftBound || degree (A,y) <= 4)
271    henselLift12 (A, bufUniFactors, liftBound, Pi, diophant, M);
272  else if (sizeOfLiftPre > 1 && sizeOfLiftPre < 30)
273  {
274    henselLift12 (A, bufUniFactors, smallFactorDeg, Pi, diophant, M);
275    earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
276                                        degs, earlySuccess,
277                                        smallFactorDeg);
278    if (degs.getLength() > 1 && !earlySuccess &&
279        smallFactorDeg != liftPre [sizeOfLiftPre-1] + 1)
280    {
281      if (newLiftBound > liftPre[sizeOfLiftPre-1]+1)
282      {
283        bufUniFactors.insert (LC (A, x));
284        henselLiftResume12 (A, bufUniFactors, smallFactorDeg,
285                            liftPre[sizeOfLiftPre-1] + 1, Pi, diophant, M);
286        earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
287                      degs, earlySuccess, liftPre[sizeOfLiftPre-1] + 1);
288      }
289    }
290    else if (earlySuccess)
291      liftBound= newLiftBound;
292    int i= sizeOfLiftPre - 1;
293    while (degs.getLength() > 1 && !earlySuccess && i - 1 >= 0)
294    {
295      if (newLiftBound > liftPre[i] + 1)
296      {
297        bufUniFactors.insert (LC (A, x));
298        henselLiftResume12 (A, bufUniFactors, liftPre[i] + 1,
299                            liftPre[i-1] + 1, Pi, diophant, M);
300        earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
301                      degs, earlySuccess, liftPre[i-1] + 1);
302      }
303      else
304      {
305        liftBound= newLiftBound;
306        break;
307      }
308      i--;
309    }
310    if (earlySuccess)
311      liftBound= newLiftBound;
312    //after here all factors are lifted to liftPre[sizeOfLiftPre-1]
313  }
314  else
315  {
316    henselLift12 (A, bufUniFactors, smallFactorDeg, Pi, diophant, M);
317    earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
318                                        degs, earlySuccess,
319                                        smallFactorDeg);
320    int i= 1;
321    while ((degree (A,y)/4)*i + 4 <= smallFactorDeg)
322      i++;
323    if (degs.getLength() > 1 && !earlySuccess)
324    {
325      bufUniFactors.insert (LC (A, x));
326      henselLiftResume12 (A, bufUniFactors, smallFactorDeg,
327                          (degree (A, y)/4)*i + 4, Pi, diophant, M);
328      earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
329                    degs, earlySuccess, (degree (A, y)/4)*i + 4);
330    }
331    while (degs.getLength() > 1 && !earlySuccess && i < 4)
332    {
333      if (newLiftBound > (degree (A, y)/4)*i + 4)
334      {
335        bufUniFactors.insert (LC (A, x));
336        henselLiftResume12 (A, bufUniFactors, (degree (A,y)/4)*i + 4,
337                            (degree (A, y)/4)*(i+1) + 4, Pi, diophant, M);
338        earlyFactors= earlyFactorDetection0 (A, bufUniFactors, newLiftBound,
339                      degs, earlySuccess, (degree (A, y)/4)*(i+1) + 4);
340      }
341      else
342      {
343        liftBound= newLiftBound;
344        break;
345      }
346      i++;
347    }
348    if (earlySuccess)
349      liftBound= newLiftBound;
350  }
351
352  return bufUniFactors;
353}
354
355CFList biFactorize (const CanonicalForm& F, const Variable& v)
356{
357  if (F.inCoeffDomain())
358    return CFList(F);
359
360  bool extension= (v.level() != 1);
361  CanonicalForm A;
362  if (isOn (SW_RATIONAL))
363    A= F*bCommonDen (F);
364  else
365    A= F;
366
367  CanonicalForm mipo;
368  if (extension)
369    mipo= getMipo (v);
370
371  if (A.isUnivariate())
372  {
373    CFFList buf;
374    if (extension)
375      buf= factorize (A, v);
376    else
377      buf= factorize (A, true);
378    CFList result= conv (buf);
379    if (result.getFirst().inCoeffDomain())
380      result.removeFirst();
381    return result;
382  }
383
384  CFMap N;
385  A= compress (A, N);
386  Variable y= A.mvar();
387
388  if (y.level() > 2) return CFList (F);
389  Variable x= Variable (1);
390
391  CanonicalForm contentAx= content (A, x);
392  CanonicalForm contentAy= content (A);
393
394  A= A/(contentAx*contentAy);
395  CFFList contentAxFactors, contentAyFactors;
396
397  if (extension)
398  {
399    if (!contentAx.inCoeffDomain())
400    {
401      contentAxFactors= factorize (contentAx, v);
402      if (contentAxFactors.getFirst().factor().inCoeffDomain())
403        contentAxFactors.removeFirst();
404    }
405    if (!contentAy.inCoeffDomain())
406    {
407      contentAyFactors= factorize (contentAy, v);
408      if (contentAyFactors.getFirst().factor().inCoeffDomain())
409        contentAyFactors.removeFirst();
410    }
411  }
412  else
413  {
414    if (!contentAx.inCoeffDomain())
415    {
416      contentAxFactors= factorize (contentAx, true);
417      if (contentAxFactors.getFirst().factor().inCoeffDomain())
418        contentAxFactors.removeFirst();
419    }
420    if (!contentAy.inCoeffDomain())
421    {
422      contentAyFactors= factorize (contentAy, true);
423      if (contentAyFactors.getFirst().factor().inCoeffDomain())
424        contentAyFactors.removeFirst();
425    }
426  }
427
428  //check trivial case
429  if (degree (A) == 1 || degree (A, 1) == 1 ||
430      (size (A) == 2 && gcd (degree (A), degree (A,1)).isOne()))
431  {
432    CFList factors;
433    factors.append (A);
434
435    appendSwapDecompress (factors, conv (contentAxFactors),
436                          conv (contentAyFactors), false, false, N);
437
438    normalize (factors);
439    return factors;
440  }
441
442  //trivial case
443  CFList factors;
444  if (A.inCoeffDomain())
445  {
446    append (factors, conv (contentAxFactors));
447    append (factors, conv (contentAyFactors));
448    decompress (factors, N);
449    return factors;
450  }
451  else if (A.isUnivariate())
452  {
453    if (extension)
454      factors= conv (factorize (A, v));
455    else
456      factors= conv (factorize (A, true));
457    append (factors, conv (contentAxFactors));
458    append (factors, conv (contentAyFactors));
459    decompress (factors, N);
460    return factors;
461  }
462
463  if (irreducibilityTest (A))
464  {
465    CFList factors;
466    factors.append (A);
467
468    appendSwapDecompress (factors, conv (contentAxFactors),
469                          conv (contentAyFactors), false, false, N);
470
471    normalize (factors);
472    return factors;
473  }
474  bool swap= false;
475  if (degree (A) > degree (A, x))
476  {
477    A= swapvar (A, y, x);
478    swap= true;
479  }
480
481  CanonicalForm Aeval, bufAeval, buf;
482  CFList uniFactors, list, bufUniFactors;
483  DegreePattern degs;
484  DegreePattern bufDegs;
485
486  CanonicalForm Aeval2, bufAeval2;
487  CFList bufUniFactors2, list2, uniFactors2;
488  DegreePattern degs2;
489  DegreePattern bufDegs2;
490  bool swap2= false;
491
492  // several univariate factorizations to obtain more information about the
493  // degree pattern therefore usually less combinations have to be tried during
494  // the recombination process
495  int factorNums= 2;
496  int subCheck1= substituteCheck (A, x);
497  int subCheck2= substituteCheck (A, y);
498  buf= swapvar (A,x,y);
499  int evaluation, evaluation2, bufEvaluation= 0, bufEvaluation2= 0;
500  for (int i= 0; i < factorNums; i++)
501  {
502    bufAeval= A;
503    bufAeval= evalPoint (A, bufEvaluation);
504
505    bufAeval2= buf;
506    bufAeval2= evalPoint (buf, bufEvaluation2);
507
508    // univariate factorization
509    TIMING_START (uni_factorize);
510
511    if (extension)
512      bufUniFactors= conv (factorize (bufAeval, v));
513    else
514      bufUniFactors= conv (factorize (bufAeval, true));
515    TIMING_END_AND_PRINT (uni_factorize,
516                          "time for univariate factorization: ");
517    DEBOUTLN (cerr, "prod (bufUniFactors)== bufAeval " <<
518              (prod (bufUniFactors) == bufAeval));
519
520    TIMING_START (uni_factorize);
521    if (extension)
522      bufUniFactors2= conv (factorize (bufAeval2, v));
523    else
524      bufUniFactors2= conv (factorize (bufAeval2, true));
525    TIMING_END_AND_PRINT (uni_factorize,
526                          "time for univariate factorization in y: ");
527    DEBOUTLN (cerr, "prod (bufuniFactors2)== bufAeval2 " <<
528              (prod (bufUniFactors2) == bufAeval2));
529
530    if (bufUniFactors.getFirst().inCoeffDomain())
531      bufUniFactors.removeFirst();
532    if (bufUniFactors2.getFirst().inCoeffDomain())
533      bufUniFactors2.removeFirst();
534    if (bufUniFactors.length() == 1 || bufUniFactors2.length() == 1)
535    {
536      factors.append (A);
537
538      appendSwapDecompress (factors, conv (contentAxFactors),
539                            conv (contentAyFactors), swap, swap2, N);
540
541      if (isOn (SW_RATIONAL))
542        normalize (factors);
543      return factors;
544    }
545
546    if (i == 0)
547    {
548      if (subCheck1 > 0)
549      {
550        int subCheck= substituteCheck (bufUniFactors);
551
552        if (subCheck > 1 && (subCheck1%subCheck == 0))
553        {
554          CanonicalForm bufA= A;
555          subst (bufA, bufA, subCheck, x);
556          factors= biFactorize (bufA, v);
557          reverseSubst (factors, subCheck, x);
558          appendSwapDecompress (factors, conv (contentAxFactors),
559                                conv (contentAyFactors), swap, swap2, N);
560          if (isOn (SW_RATIONAL))
561            normalize (factors);
562          return factors;
563        }
564      }
565
566      if (subCheck2 > 0)
567      {
568        int subCheck= substituteCheck (bufUniFactors2);
569
570        if (subCheck > 1 && (subCheck2%subCheck == 0))
571        {
572          CanonicalForm bufA= A;
573          subst (bufA, bufA, subCheck, y);
574          factors= biFactorize (bufA, v);
575          reverseSubst (factors, subCheck, y);
576          appendSwapDecompress (factors, conv (contentAxFactors),
577                                conv (contentAyFactors), swap, swap2, N);
578          if (isOn (SW_RATIONAL))
579            normalize (factors);
580          return factors;
581        }
582      }
583    }
584
585    // degree analysis
586    bufDegs = DegreePattern (bufUniFactors);
587    bufDegs2= DegreePattern (bufUniFactors2);
588
589    if (i == 0)
590    {
591      Aeval= bufAeval;
592      evaluation= bufEvaluation;
593      uniFactors= bufUniFactors;
594      degs= bufDegs;
595      Aeval2= bufAeval2;
596      evaluation2= bufEvaluation2;
597      uniFactors2= bufUniFactors2;
598      degs2= bufDegs2;
599    }
600    else
601    {
602      degs.intersect (bufDegs);
603      degs2.intersect (bufDegs2);
604      if (bufUniFactors2.length() < uniFactors2.length())
605      {
606        uniFactors2= bufUniFactors2;
607        Aeval2= bufAeval2;
608        evaluation2= bufEvaluation2;
609      }
610      if (bufUniFactors.length() < uniFactors.length())
611      {
612        uniFactors= bufUniFactors;
613        Aeval= bufAeval;
614        evaluation= bufEvaluation;
615      }
616    }
617    if (bufEvaluation > 0)
618      bufEvaluation++;
619    else
620      bufEvaluation= -bufEvaluation + 1;
621    if (bufEvaluation > 0)
622      bufEvaluation2++;
623    else
624      bufEvaluation2= -bufEvaluation2 + 1;
625  }
626
627  if (uniFactors.length() > uniFactors2.length() ||
628      (uniFactors.length() == uniFactors2.length()
629       && degs.getLength() > degs2.getLength()))
630  {
631    degs= degs2;
632    uniFactors= uniFactors2;
633    evaluation= evaluation2;
634    Aeval= Aeval2;
635    A= buf;
636    swap2= true;
637  }
638
639  if (degs.getLength() == 1) // A is irreducible
640  {
641    factors.append (A);
642    appendSwapDecompress (factors, conv (contentAxFactors),
643                          conv (contentAyFactors), swap, swap2, N);
644    if (isOn (SW_RATIONAL))
645      normalize (factors);
646    return factors;
647  }
648
649  A= A (y + evaluation, y);
650
651  int liftBound= degree (A, y) + 1;
652
653  modpk b= modpk();
654  bool mipoHasDen= false;
655  if (!extension)
656  {
657    Off (SW_RATIONAL);
658    int i= 0;
659    findGoodPrime(F,i);
660    findGoodPrime(Aeval,i);
661    findGoodPrime(A,i);
662    if (i >= cf_getNumBigPrimes())
663      printf ("out of primes\n"); //TODO exit
664
665    int p=cf_getBigPrime(i);
666    b = coeffBound( A, p );
667    modpk bb= coeffBound (Aeval, p);
668    if (bb.getk() > b.getk() ) b=bb;
669      bb= coeffBound (F, p);
670    if (bb.getk() > b.getk() ) b=bb;
671  }
672  else
673  {
674    A /= Lc (Aeval);
675    // make factors elements of Z(a)[x] disable for modularDiophant
676    CanonicalForm multiplier= 1;
677    for (CFListIterator i= uniFactors; i.hasItem(); i++)
678    {
679      multiplier *= bCommonDen (i.getItem());
680      i.getItem()= i.getItem()*bCommonDen(i.getItem());
681    }
682    A *= multiplier;
683    A *= bCommonDen (A);
684
685    mipoHasDen= !bCommonDen(mipo).isOne();
686    mipo *= bCommonDen (mipo);
687    Off (SW_RATIONAL);
688    int i= 0;
689    ZZX NTLmipo= convertFacCF2NTLZZX (mipo);
690    CanonicalForm discMipo= convertZZ2CF (discriminant (NTLmipo));
691    findGoodPrime (F*discMipo,i);
692    findGoodPrime (Aeval*discMipo,i);
693    findGoodPrime (A*discMipo,i);
694
695    int p=cf_getBigPrime(i);
696    b = coeffBound( A, p, mipo );
697    modpk bb= coeffBound (Aeval, p, mipo);
698    if (bb.getk() > b.getk() ) b=bb;
699      bb= coeffBound (F, p, mipo);
700    if (bb.getk() > b.getk() ) b=bb;
701  }
702
703  ExtensionInfo dummy= ExtensionInfo (false);
704  if (extension)
705    dummy= ExtensionInfo (v, false);
706  bool earlySuccess= false;
707  CFList earlyFactors;
708  TIMING_START (fac_bi_hensel_lift);
709  uniFactors= henselLiftAndEarly
710              (A, earlySuccess, earlyFactors, degs, liftBound,
711               uniFactors, dummy, evaluation, b);
712  TIMING_END_AND_PRINT (fac_bi_hensel_lift, "time for hensel lifting: ");
713  DEBOUTLN (cerr, "lifted factors= " << uniFactors);
714
715  CanonicalForm MODl= power (y, liftBound);
716
717  if (mipoHasDen)
718  {
719    Variable vv;
720    for (CFListIterator iter= uniFactors; iter.hasItem(); iter++)
721      if (hasFirstAlgVar (iter.getItem(), vv))
722        break;
723    for (CFListIterator iter= uniFactors; iter.hasItem(); iter++)
724      iter.getItem()= replacevar (iter.getItem(), vv, v);
725  }
726
727  factors= factorRecombination (uniFactors, A, MODl, degs, 1,
728                                uniFactors.length()/2, b);
729
730  On (SW_RATIONAL);
731
732  if (earlySuccess)
733    factors= Union (earlyFactors, factors);
734  else if (!earlySuccess && degs.getLength() == 1)
735    factors= earlyFactors;
736
737  for (CFListIterator i= factors; i.hasItem(); i++)
738    i.getItem()= i.getItem() (y - evaluation, y);
739
740  appendSwapDecompress (factors, conv (contentAxFactors),
741                        conv (contentAyFactors), swap, swap2, N);
742  if (isOn (SW_RATIONAL))
743    normalize (factors);
744
745  return factors;
746}
747
748#endif
Note: See TracBrowser for help on using the repository browser.