source: git/factory/facBivar.cc @ 72bfc8

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