source: git/libfac/factor/Factor.cc @ 5299b6

spielwiese
Last change on this file since 5299b6 was 5299b6, checked in by Hans Schönemann <hannes@…>, 18 years ago
*hannes: use sorting option in Factorize git-svn-id: file:///usr/local/Singular/svn/trunk@8847 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 41.1 KB
Line 
1/* Copyright 1996 Michael Messollen. All rights reserved. */
2///////////////////////////////////////////////////////////////////////////////
3static char * rcsid = "$Id: Factor.cc,v 1.21 2005-12-12 18:02:03 Singular Exp $ ";
4static char * errmsg = "\nYou found a bug!\nPlease inform (Michael Messollen) michael@math.uni-sb.de \nPlease include above information and your input (the ideal/polynomial and characteristic) in your bug-report.\nThank you.";
5///////////////////////////////////////////////////////////////////////////////
6// FACTORY - Includes
7#include <factory.h>
8#ifndef NOSTREAMIO
9#include <iostream.h>
10#endif
11// Factor - Includes
12#include "tmpl_inst.h"
13#include "SqrFree.h"
14#include "helpstuff.h"
15#include "MVMultiHensel.h"
16#include "Truefactor.h"
17#include "homogfactor.h"
18#include "interrupt.h"
19// some CC's need this:
20#include "Factor.h"
21
22#include "alg_factor.h"
23
24#ifdef SINGULAR
25#define HAVE_SINGULAR_ERROR
26#endif
27
28#ifdef HAVE_SINGULAR_ERROR
29   extern "C" { void WerrorS(char *); }
30   extern "C" { void WarnS(const char *); }
31#endif
32
33#ifdef FACTORDEBUG
34#  define DEBUGOUTPUT
35#else
36#  undef DEBUGOUTPUT
37#endif
38
39#include "debug.h"
40#include "timing.h"
41TIMING_DEFINE_PRINT(factorize_time);
42TIMING_DEFINE_PRINT(sqrfree_time);
43TIMING_DEFINE_PRINT(discr_time);
44TIMING_DEFINE_PRINT(evaluate_time);
45TIMING_DEFINE_PRINT(hensel_time);
46TIMING_DEFINE_PRINT(truefactor_time);
47
48void out_cf(char *s1,const CanonicalForm &f,char *s2);
49
50/*
51* a wrapper for factorize over algebraic extensions:
52* does a sanity check and, if nec., a conversion
53* before calling factorize(f,alpha)
54* ( in factorize, alpha.level() must be < 0 )
55*/
56CFFList factorize2 ( const CanonicalForm & f,
57                     const Variable & alpha, const CanonicalForm & mipo )
58{
59  if (alpha.level() <0)
60  {
61    if (f.isUnivariate())
62      return factorize(f,alpha);
63    else
64    {
65      return Factorize(f,mipo);
66    }
67  }
68  else
69  {
70    bool repl=(f.mvar() != alpha);
71    //out_cf("f2 - factor:",f,"\n");
72    //out_cf("f2 - ext:",alpha,"\n");
73    //out_cf("f2 - mipo:",mipo,"\n");
74    Variable X=rootOf(mipo);
75    CanonicalForm F=f;
76    if (repl) F=replacevar(f,alpha,X);
77    //out_cf("call - factor:",F,"\n");
78    //out_cf("call - ext:",X,"\n");
79    //out_cf("call - mipo:",getMipo(X,'A'),"\n");
80    CFFList L=factorize(F,X);
81    CFFListIterator i=L;
82    if (repl)
83    {
84      CFFList Outputlist;
85      for(;i.hasItem(); i++ )
86      {
87        Outputlist.append(CFFactor(
88        replacevar(i.getItem().factor(),X,alpha),
89        i.getItem().exp()));
90      }
91      return Outputlist;
92    }
93    else return L;
94  }
95}
96///////////////////////////////////////////////////////////////
97// Choose a main variable if the user didn`t wish a          //
98// special one. Returns level of main variable.              //
99///////////////////////////////////////////////////////////////
100static int
101choose_main_variable( const CanonicalForm & f, int Mainvar=0){
102  CanonicalForm remlc, newlc;
103  int n= level(f), mainvar= Mainvar;
104
105  if (mainvar != 0) return mainvar ; // We force use of the wished mainvar
106  remlc= LC(f,n); mainvar = n;
107  if ( totaldegree(remlc)==0 ){ remlc=f.genOne() ; }
108  DEBOUTLN(cout, "remlc= " , remlc);
109  for ( int i=n-1; i>=1; i-- ){
110    newlc= LC(f,i);
111    if ( totaldegree(newlc)==0 ){ newlc=f.genOne() ; }
112    DEBOUTLN(cout, "newlc= " , newlc);
113    if ( (remlc.isOne()) && (newlc.isOne()) ){ // take care of the degrees
114      if ( degree(f,i) < degree(f,mainvar) ){
115        remlc= newlc;
116        mainvar= i;
117      }
118    }
119    else  if ( (! remlc.isOne() ) && ( newlc.isOne() ) ){
120      remlc= newlc;
121      mainvar= i;
122    }
123  }
124  return mainvar;
125}
126
127///////////////////////////////////////////////////////////////
128// Check if the derivative is nonzero for oldmainvar.        //
129// Returns the level of the choosen main variable.           //
130///////////////////////////////////////////////////////////////
131static int
132necessary_condition( const CanonicalForm & F, int oldmainvar){
133  CanonicalForm g;
134  int n=level(F);
135
136  g= swapvar(F,oldmainvar,n);
137  g= g.deriv();
138  if ( g.isZero() )
139    for ( int i=n; i>=1; i-- ){
140      g= swapvar(F,i,n);
141      g= g.deriv();
142      if ( ! g.isZero() ) return i;
143    }
144  return oldmainvar;
145}
146
147///////////////////////////////////////////////////////////////
148// Make F monic. Return monic polynomial.                    //
149///////////////////////////////////////////////////////////////
150static CanonicalForm
151make_monic( const CanonicalForm & F, const CanonicalForm & lt){
152  CanonicalForm intermediatpoly,f;
153  Variable x(level(F));
154
155  if ( degree(lt) == 0 ) f= 1/lt * F ;
156  else {
157    intermediatpoly= power(lt,degree(F)-1);
158    for ( int i=0; i<=degree(F); i++ )
159      if ( ! F[i].isZero())
160        f+= (F[i] * intermediatpoly*power(x,i))/power(lt,i);
161  }
162  return f;
163}
164
165///////////////////////////////////////////////////////////////
166// Decide whether num/denum (num,denum both from the         //
167// FiniteFielddomain)  lies in the RationalDomain.           //
168// If false, return num/denum else return the zero poly from //
169// the FiniteFielddomain.                                    //
170///////////////////////////////////////////////////////////////
171static CanonicalForm
172is_rational( const CanonicalForm & num, const CanonicalForm & denum ){
173  CanonicalForm a, b;
174  int retvalue;
175
176  retvalue= mydivremt(num,denum,a,b);
177  if ( retvalue && b == num.genZero() ) // num/denum from FFdomain
178    return a;
179  else // num/denum is rational
180    return num.genZero();
181}
182
183///////////////////////////////////////////////////////////////
184// lt_is_product returns 1 iff lt is a product, 0 iff lt is  //
185// a sum.                                                    //
186///////////////////////////////////////////////////////////////
187static int
188lt_is_product( const CanonicalForm & lt ){
189  CFList result;
190
191  result= get_Terms(lt);
192  if ( result.length() > 1 ) return 0;
193  else return 1;
194}
195
196///////////////////////////////////////////////////////////////
197// Reverse the make_monic transformation.                    //
198// Return the list of factors.                               //
199///////////////////////////////////////////////////////////////
200static CFFList
201not_monic( const CFFList & TheList, const CanonicalForm & ltt, const CanonicalForm & F, int levelF){
202  CFFList Returnlist,IntermediateList;
203  CFFListIterator i;
204  CanonicalForm intermediate,lt= ltt,savelc;
205  CanonicalForm numerator,denumerator,test,a,b;
206  Variable x(level(F));
207  int test1;
208
209  if ( lt == lt.genOne() ) return TheList; // the poly was already monic
210  if ( TheList.length() <= 1 ){ // only one factor to substitute back
211    if ( totaldegree(lt) == 0 ) // lt is type numeric
212      Returnlist.append( CFFactor(lt*TheList.getFirst().factor(),
213                                  TheList.getFirst().exp()) );
214    else {
215      intermediate = F(x*lt, levelF)/power(lt,degree(F,levelF)-1);
216      Returnlist.append(CFFactor(intermediate,TheList.getFirst().exp()));
217    }
218  }
219  else { // more then one factor
220    IntermediateList= TheList;
221    if ( totaldegree(lt) == 0 ){ // lt is type numeric;(SqrFree-use, see above)
222      Returnlist.append( CFFactor(lt*IntermediateList.getFirst().factor()
223                                  , IntermediateList.getFirst().exp()) );
224      IntermediateList.removeFirst();
225      Returnlist= Union(Returnlist,IntermediateList);
226    }
227    else{ // lt is a) a product or b) a sum of terms
228      if ( lt_is_product(lt) ){ // case a)
229        DEBOUTLN(cout, "lt_is_product: ", lt);
230        savelc= content(lt) ; // can we simplify to savelc= lc(lt); ?
231        while ( getNumVars(savelc) != 0 )
232          savelc= content(savelc);
233        for ( i=TheList; i.hasItem();i++ ){
234          numerator= i.getItem().factor();
235          numerator= numerator(x*lt,levelF); // x <- x*lt
236          denumerator= power(lt,degree(F,levelF)-1); // == lt^(1-degree(F,x)
237          while (numerator.genZero() == is_rational(numerator, denumerator))
238            numerator*= lt;
239          intermediate= is_rational(numerator,denumerator);
240
241          Returnlist.append( CFFactor(lc(content(intermediate))*intermediate/content(intermediate), i.getItem().exp() ) );
242        }
243        // Now we add a test. If product(factors)/F is a multiple of
244        // savelc, we have to add 1/multiplicity to the factors
245        IntermediateList= Returnlist;
246        intermediate= 1;
247        for ( CFFListIterator j=IntermediateList; j.hasItem(); j++)
248          intermediate*= j.getItem().factor();
249        test1= mydivremt( intermediate,F,a,b);
250        if ( test1 && b == intermediate.genZero() ) { // Yupp!
251          IntermediateList.append(CFFactor(1/a,1));
252          Returnlist= IntermediateList;
253        }
254        else { Returnlist= IntermediateList; }
255      }
256      else{ // case b)
257        DEBOUTLN(cout, "lt_is_sum: ", lt);
258        CanonicalForm save_denumerator= 1;
259        for ( i=TheList; i.hasItem(); i++ ){
260          numerator= i.getItem().factor();
261          numerator= numerator(x*lt,levelF); // x <- x*lt
262          denumerator= power(lt,degree(numerator,levelF)); // == lt^(-degree(numerator,x)
263          test= content(numerator,x);
264          test1= mydivremt(denumerator,test,a,b);
265          if ( test1 && b == numerator.genZero() ){ // Yupp!
266            save_denumerator*= a;
267            Returnlist.append(CFFactor(numerator/test ,1));
268          }
269          else {
270#ifdef HAVE_SINGULAR_ERROR
271            WerrorS("libfac: ERROR: not_monic1: case lt is a sum.");
272#else
273#ifndef NOSTREAMIO
274            cerr << "libfac: ERROR: not_monic1: case lt is a sum.\n"
275                 << rcsid << errmsg << endl;
276#endif
277#endif
278          }
279        }
280        // Now we add a test if we did the right thing:
281        // save_denumerator should be a multiple of the leading coeff
282        test1= mydivremt(save_denumerator,lt,a,b);
283        if ( test1 && b == save_denumerator.genZero() ) // Yupp!
284          // We have to multiply one of the factors with
285          // the multiplicity of the save_denumerator <-> lc
286          // the following will do what we want
287          Returnlist= myUnion( CFFList(CFFactor(1/a,1)),Returnlist) ;
288        else {
289#ifdef HAVE_SINGULAR_ERROR
290          WerrorS("libfac: ERROR: not_monic2: case lt is a sum.");
291#else
292#ifndef NOSTREAMIO
293          cerr << "libfac: ERROR: not_monic2: case lt is a sum.\n"
294               << rcsid << errmsg << endl;
295#endif
296#endif
297        }
298      }
299    }
300  }
301  DEBOUTLN(cout,"Returnlist: ", Returnlist);
302  return Returnlist;
303}
304
305///////////////////////////////////////////////////////////////
306// Substitute the (Variable,Value)-Pair(s) from Substitution-//
307// list into the polynomial F. Returns the resulting poly.   //
308///////////////////////////////////////////////////////////////
309static CanonicalForm
310substitutePoly( const CanonicalForm & F, const SFormList & Substitutionlist){
311  CanonicalForm f= F;
312
313  for ( SFormListIterator i=Substitutionlist; i.hasItem(); i++ )
314    f= f(i.getItem().exp(),level(i.getItem().factor()));
315  return f;
316}
317
318///////////////////////////////////////////////////////////////
319// Find specialization values for the poly F. Returns 0 if   //
320// procedure failed, 1 otherwise. On success Substitutionlist//
321// holds (Variable,Value)-pairs. On failure we only have a   //
322// partitial list.                                           //
323///////////////////////////////////////////////////////////////
324//      *** This is the version with extensions ***          //
325///////////////////////////////////////////////////////////////
326
327///////////////////////////////////////////////////////////////
328// is CF g ok?                                               //
329///////////////////////////////////////////////////////////////
330static int
331various_tests( const CanonicalForm & g, int deg, int vars_left){
332  CFMap m;
333
334  if ( degree(g) == deg ) // degrees match
335    if ( level(compress(g,m)) == (vars_left) ) // exactly one variable less
336      if ( SqrFreeTest(g,1) ) // poly is sqrfree
337        if ( mygcd(g,g.deriv()) == 1 ) // Discriminante != 0
338           return 1;
339  return 0;
340}
341
342///////////////////////////////////////////////////////////////
343// specialize one variable over the given field.             //
344///////////////////////////////////////////////////////////////
345// substitutes in poly f of degree deg with former
346// former_nr_of_variables variables the variable nr_of_variable ;
347// this is done in the field of Char getCharacteristic() and
348// Extension given by Extgenerator.
349///////////////////////////////////////////////////////////////
350static int
351specialize_variable( CanonicalForm & f, int deg, SFormList & Substitutionlist, int nr_of_variable,
352                     int former_nr_of_variables, CFGenerator & Extgenerator ){
353  CanonicalForm g;
354  Variable x(nr_of_variable);
355
356  DEBOUTLN(cout, "specialize_variable: called with: ", f);
357  for ( Extgenerator.reset(); Extgenerator.hasItems(); Extgenerator.next() ){
358    DEBOUTLN(cout, "  specialize_variable: trying:  ", Extgenerator.item());
359    g= f( Extgenerator.item(), x );
360    DEBOUTLN(cout, "  specialize_variable: resulting g= ", g);
361    if ( various_tests(g,deg,former_nr_of_variables - nr_of_variable ) ){
362      Substitutionlist.insert(SForm(x,Extgenerator.item())); // append (Var,value) pair
363      f= g;
364      return 1;
365    }
366  }
367  return 0;
368}
369static int
370specialize_agvariable( CanonicalForm & f, int deg, SFormList & Substitutionlist, int nr_of_variable,
371                     int former_nr_of_variables, AlgExtGenerator & Extgenerator ){
372  CanonicalForm g;
373  Variable x(nr_of_variable);
374
375  DEBOUTLN(cout, "specialize_variable: called with: ", f);
376  for ( Extgenerator.reset(); Extgenerator.hasItems(); Extgenerator.next() ){
377    DEBOUTLN(cout, "  specialize_variable: trying:  ", Extgenerator.item());
378    g= f( Extgenerator.item(), x );
379    DEBOUTLN(cout, "  specialize_variable: resulting g= ", g);
380    if ( various_tests(g,deg,former_nr_of_variables - nr_of_variable ) ){
381      Substitutionlist.insert(SForm(x,Extgenerator.item())); // append (Var,value) pair
382      f= g;
383      return 1;
384    }
385  }
386  return 0;
387}
388
389///////////////////////////////////////////////////////////////
390// generate a minpoly of degree degree_of_Extension in the   //
391// field getCharacteristik()^Extension.                      //
392///////////////////////////////////////////////////////////////
393CanonicalForm
394generate_mipo( int degree_of_Extension , const Variable & Extension ){
395  FFRandom gen;
396  if ( degree(Extension) > 0 ) GFRandom gen;
397  else {
398    if ( degree(Extension) == 0 ) FFRandom gen;
399    else {
400#ifdef HAVE_SINGULAR_ERROR
401    WerrorS("libfac: evaluate: Extension not inFF() or inGF() !");
402#else
403#ifndef NOSTREAMIO
404    cerr << "libfac: evaluate: " << Extension << " not inFF() or inGF() !"
405         << endl;
406#endif
407#endif
408    FFRandom gen;
409    }
410  }
411  return find_irreducible( degree_of_Extension, gen, Variable(1) );
412}
413
414///////////////////////////////////////////////////////////////
415// Try to find a specialization for f over the field of char //
416// f.getCharacteristic() and (possible) extension defined by //
417// the variable Extension .                                  //
418// Returns 1 iff specialisation was found, 0 otherwise.      //
419// If 0 is returned there are variables left to substitute.  //
420// We check if Substitutionlist.length() > 0, i.e. we        //
421// previously tried to find specialization values for some   //
422// values. We take them and work with the resulting poly.    //
423///////////////////////////////////////////////////////////////
424static int
425try_specializePoly(const CanonicalForm & f, const Variable & Extension, int deg, SFormList & Substitutionlist, int ii,int j){
426  int ok,i= ii;
427  CanonicalForm ff= f;
428
429  if ( Substitutionlist.length() > 0 ){ // we formerly tried to specialize
430    ff= substitutePoly(f,Substitutionlist); // substitute found values
431    i= Substitutionlist.length() + 1;
432  }
433
434  if ( degree(Extension) > 0 ){ // working over Extensions
435    DEBOUTLN(cout, "try_specializePoly: working over Extensions: ", Extension);
436    AlgExtGenerator g(Extension);
437    for ( int k=i ; k<j ; k++ ){ // try to find specialization for all
438                                 // variables (# = k ) beginning with the
439                                 // starting value i
440      ok= specialize_agvariable( ff, deg, Substitutionlist, k, j, g );
441      if ( ! ok ) return 0; // we failed
442    }
443  }
444  else{ // working over the ground-field
445    FFGenerator g;
446    DEBOUTMSG(cout, "try_specializePoly: working over the ground-field.");
447    for ( int k=i ; k<j ; k++ ){
448      ok= specialize_variable( ff, deg, Substitutionlist, k, j, g );
449      if ( ! ok ) return 0; // we failed
450    }
451  }
452  return 1;
453}
454
455static int
456specializePoly(const CanonicalForm & f, Variable & Extension, int deg, SFormList & Substitutionlist, int i,int j){
457  Variable minpoly= Extension;
458  int ok,extended= degree(Extension), working_over_extension;
459
460  // Remember if we are working over an extension-field
461  if ( extended >= 2 )    { working_over_extension = 1; }
462  else                    { working_over_extension = 0; extended = 1; }
463  // First try:
464  ok = try_specializePoly(f,minpoly,deg,Substitutionlist,i,j);
465  while ( ! ok ){ // we have to extend!
466    extended+= 1;
467    if ( ! working_over_extension ){
468      minpoly= rootOf(generate_mipo( extended,Extension ));
469      Extension= minpoly;
470      ok= try_specializePoly(f,minpoly,deg,Substitutionlist,i,j);
471    }
472    else {
473#ifdef HAVE_SINGULAR_ERROR
474      WerrorS("libfac: spezializePoly ERROR: Working over given extension-field not yet implemented!");
475#else
476#ifndef NOSTREAMIO
477      cerr << "libfac: spezializePoly ERROR: Working over given extension-field not yet implemented!\n"
478           << rcsid << errmsg << endl;
479#endif
480#endif
481      return 0;
482    }
483  }
484  return 1;
485}
486
487
488// This is a procedure to play with: lot's of parameters!
489// returns: 0  iff no success (possibly because Extension isn't great enough
490//          >0 iff g (univariate) splits into n factors;
491// if n>0 BestEvaluationpoint contains the choice of values for the variables
492//
493// tries to find at least maxtries evaluation points
494// if g factored sametries into the same number of poly's the procedure stops
495// if we tried failtries evaluations not found valid, we stop. Perhaps
496// Extension isn't big enough!
497static int
498evaluate( int maxtries, int sametries, int failtries, const CanonicalForm &f , const Variable & Extension, const CanonicalForm &mipo, SFormList & BestEvaluationpoint, CFFList & BestFactorisation ){
499  int minfactors=degree(f),degf=degree(f),n=level(f.mvar())-1;
500  SFormList minEvaluation;
501  CFFList minFactorisation;
502  int samefactors=0, failedfactor=0, tried=0;
503  FFRandom gen;
504  CFFList unilist;
505
506  if ( degree(Extension) >0 ) GFRandom gen;
507  else { if ( degree(Extension) == 0 ) FFRandom gen;
508  else {
509#ifdef HAVE_SINGULAR_ERROR
510    WerrorS("libfac: evaluate: Extension not inFF() or inGF() !");
511#else
512#ifndef NOSTREAMIO
513    cerr << "libfac: evaluate: " << Extension << " not inFF() or inGF() !"
514         << endl;
515#endif
516#endif
517    FFRandom gen; }}
518  REvaluation k(1,n,gen);
519  k.nextpoint();
520  for ( int i=1; i<=maxtries ; i++){
521    // k.nextpoint();
522    SFormList Substitutionlist;
523    for ( int j=1; j<=n; j++ )
524     Substitutionlist.insert(SForm(Variable(j),k[j]));
525    k.nextpoint();
526    CanonicalForm g=substitutePoly(f,Substitutionlist);
527    if ( various_tests(g, degf,1) ){ // found a valid point
528      failedfactor = 0; tried += 1;
529      if ( degree(Extension) == 0   )
530        unilist = factorize(g,1); // poly is sqr-free!
531      else
532      {
533        unilist = factorize2(g,Extension,mipo);
534      }
535      if (unilist.length() <= minfactors ) {
536        minfactors=unilist.length();
537        minEvaluation=Substitutionlist;
538        minFactorisation=unilist;
539      }
540      else samefactors +=1;
541
542      if (unilist.length() == 1 ){ // wow! we found f is irreducible!
543        BestEvaluationpoint=minEvaluation;
544        BestFactorisation=minFactorisation;
545        return 1;
546      }
547
548      if ( samefactors >= sametries ){ // now we stop ( maybe polynomial *has*
549                                       // minfactors factors? )
550        BestEvaluationpoint=minEvaluation;
551        BestFactorisation=minFactorisation;
552        return minfactors;
553      }
554
555    }
556    else failedfactor += 1;
557
558    if ( failedfactor >= failtries ){ // now we stop ( perhaps Extension isn't
559                                      // big enough )
560      if ( tried == 0 )
561        return 0;
562      else{
563        BestEvaluationpoint=minEvaluation;
564        BestFactorisation=minFactorisation;
565        return minfactors;
566      }
567    }
568
569  }
570  BestEvaluationpoint=minEvaluation;
571  BestFactorisation=minFactorisation;
572  return minfactors;
573}
574
575#ifdef EXPERIMENTAL
576static int
577find_evaluation(int maxtries, int sametries, int failtries, const CanonicalForm &f , const Variable & Extension, SFormList & BestEvaluationpoint, CFFList & BestFactorisation ){
578  int success;
579
580  success=evaluate( maxtries, sametries, failtries, f , Extension, BestEvaluationpoint, BestFactorisation );
581  return success;
582}
583#endif
584
585///////////////////////////////////////////////////////////////
586// A factorization routine for a sqrfree polynomial.         //
587// Returns the list of factors.                              //
588///////////////////////////////////////////////////////////////
589CFFList
590Factorized( const CanonicalForm & F, const CanonicalForm & alpha, int Mainvar){
591  CanonicalForm f,lt,ff,ffuni;
592  Variable Extension=alpha.mvar();
593  CFFList Outputlist,UnivariateFactorlist,Outputlist2;
594  SFormList Substitutionlist, Evaluationpoint;
595  CFFactor copy;
596  int mainvar=Mainvar,success,oldmainvar;
597  CFMap m;
598
599  // INTERRUPTHANDLER
600  if ( interrupt_handle() ) return CFFList() ;
601  // INTERRUPTHANDLER
602
603  if ( F.isUnivariate() ){ // could have lost one Variable elsewhere
604    if ( degree(Extension) == 0 ){
605      TIMING_START(evaluate_time);
606      Outputlist = factorize(F,1); // poly is sqr-free
607      TIMING_END(evaluate_time);
608      return Outputlist;
609    }
610    else{
611      if (Extension.level()<0)
612      DEBOUTLN(cout, "Univ. Factorization over extension of degree ",
613               degree(getMipo(Extension,'x')) );
614      else
615      DEBOUTLN(cout, "Univ. Factorization over extension of level ??",
616                Extension.level());
617      TIMING_START(evaluate_time);
618     #if 1
619     Outputlist = factorize2(F,Extension,alpha);
620     #else
621      Variable X;
622      CanonicalForm mipo=getMipo(Extension,X);
623      CFList as(mipo);
624      Outputlist = newfactoras( F, as, 1);
625     #endif
626      TIMING_END(evaluate_time);
627      return Outputlist;
628    }
629  }
630
631  if ( Mainvar ) oldmainvar=Mainvar; else oldmainvar=level(F);
632  // First choose a main variable; this may be revisted in the next step
633  mainvar = choose_main_variable(F);
634  // Let`s look if @f/@mainvar is nonzero
635  mainvar = necessary_condition(F,mainvar);
636  // Now we have definetly choosen a main variable
637  // swap poly such that the mainvar has highest level
638  f=swapvar(F,mainvar,level(F));
639
640  // INTERRUPTHANDLER
641  if ( interrupt_handle() ) return CFFList() ;
642  // INTERRUPTHANDLER
643
644  if ( oldmainvar != mainvar ){
645    DEBOUTSL(cout); DEBOUT(cout,"Swapped poly ", F);
646    DEBOUT(cout, " in ", f); DEBOUTNL(cout);
647    DEBOUTSL(cout); DEBOUT(cout,"Swapped  ", oldmainvar );
648    DEBOUT(cout, " <-- ", mainvar ); DEBOUT(cout, "  Mainvar= ", f.mvar());
649    DEBOUTNL(cout);
650    ff = f.deriv();
651    TIMING_START(discr_time);
652    ffuni = mygcd(f,ff);
653    TIMING_END(discr_time);
654    if ( ffuni != 1 ){ //discriminante nonzero: split poly
655      DEBOUTLN(cout,"Nontrivial GCD of f= ", f);
656      DEBOUTLN(cout,"             and @f= ", ff);
657      DEBOUTLN(cout,"          GCD(f,@f)= ", ffuni);
658      ff=f/ffuni;
659      CFFList Outputlist_a, Outputlist_b;
660      Outputlist_a = Factorized(ff,alpha);
661      DEBOUTLN(cout, "Outputlist_a = ", Outputlist_a);
662      Outputlist_b = Factorized(ffuni,alpha);
663      DEBOUTLN(cout, "Outputlist_b = ", Outputlist_b);
664      Outputlist = myUnion(Outputlist_a, Outputlist_b);
665      // have to back-swapvar the factors....
666      for ( CFFListIterator i=Outputlist; i.hasItem(); i++ ){
667        copy=i.getItem();
668        Outputlist2.append(CFFactor(swapvar(copy.factor(),oldmainvar,mainvar),copy.exp()));
669      }
670      DEBOUTLN(cout, "Outputlist2 (a+b swapped) (to return) = ", Outputlist2);
671      return Outputlist2;
672    }
673  }
674
675  // Check special cases
676  for ( int i=1; i<=level(F); i++)
677    if ( degree(f,Variable(i) ) == 1 ) { //test trivial case; only true iff F is primitiv w.r.t every variable; else check (if F=ax+b) gcd(a,b)=1 ?
678      DEBOUTLN(cout, "Trivial case: ", F);
679      Outputlist.append(CFFactor(F,1));
680      return Outputlist;
681    }
682
683  // Look at the leading term:
684  lt = LC(f);
685  DEBOUTLN(cout, "Leading term: ", lt);
686  if ( lt != f.genOne() ){
687    // make the polynomial monic in the main variable
688    ff = make_monic(f,lt); ffuni = ff;
689    DEBOUTLN(cout, "make_monic returned: ", ff);
690  }
691  else{ ff= f; ffuni= ff; }
692
693  TIMING_START(evaluate_time);
694  success=evaluate(min(10,max(degree(ff), 5)), min(degree(ff),3), min(degree(ff),3), ff, Extension, alpha, Substitutionlist,UnivariateFactorlist);
695  DEBOUTLN(cout,  "Returned from evaluate: success: ", success);
696  for ( SFormListIterator ii=Substitutionlist; ii.hasItem(); ii++ ){
697    DEBOUTLN(cout, "Substituting ", ii.getItem().factor());
698    DEBOUTLN(cout, "       with value: ", ii.getItem().exp());
699  }
700
701  if ( success==0 ){ // evalute wasn't successfull
702    success= specializePoly(ffuni,Extension,degree(ff),Substitutionlist,1,getNumVars(compress(ff,m)));
703    DEBOUTLN(cout,  "Returned from specializePoly: success: ", success);
704    if (success == 0 ){ // No spezialisation could be found
705#ifdef HAVE_SINGULAR_ERROR
706      WarnS("libfac: Factorize: ERROR: Not able to find a valid specialization!");
707#else
708#ifndef NOSTREAMIO
709      cerr << "libfac: Factorize: ERROR: Not able to find a valid specialization!\n"
710           << rcsid << errmsg << endl;
711#else
712       ;
713#endif
714#endif
715      Outputlist.append(CFFactor(F,1));
716      return Outputlist;
717    }
718
719    // INTERRUPTHANDLER
720    if ( interrupt_handle() ) return CFFList() ;
721    // INTERRUPTHANDLER
722
723    ffuni = substitutePoly(ff,Substitutionlist);
724    // We now have an univariat poly; factorize that
725    if ( degree(Extension) == 0   ){
726      DEBOUTMSG(cout, "Univ. Factorization over the ground field");
727      UnivariateFactorlist = factorize(ffuni,1); // univ. poly is sqr-free!
728    }
729    else{
730      DEBOUTLN(cout, "Univ. Factorization over extension of degree ",
731               degree(getMipo(Extension,'x')) );
732     #if 1
733      UnivariateFactorlist = factorize2(ffuni,Extension,alpha);
734     #else
735      Variable X;
736      CanonicalForm mipo=getMipo(Extension,X);
737      CFList as(mipo);
738      UnivariateFactorlist = newfactoras( ffuni, as, 1);
739     #endif
740    }
741  }
742  else{
743    ffuni = substitutePoly(ff,Substitutionlist);
744  }
745    TIMING_END(evaluate_time);
746  if (UnivariateFactorlist.length() == 1){ // poly is irreduzibel
747    DEBOUTLN(cout, "Univ. poly is irreduzible: ", UnivariateFactorlist);
748    Outputlist.append(CFFactor(F,1));
749    return Outputlist;
750  }
751  else{ // we have factors
752    DEBOUTSL(cout);
753    DEBOUT(cout, "Univariate poly has " , UnivariateFactorlist.length());
754    DEBOUT(cout, " factors:  ", ffuni);
755    DEBOUT(cout, " = ", UnivariateFactorlist); DEBOUTNL(cout);
756
757    // INTERRUPTHANDLER
758    if ( interrupt_handle() ) return CFFList() ;
759    // INTERRUPTHANDLER
760
761    TIMING_START(hensel_time);
762    Outputlist = MultiHensel(ff,UnivariateFactorlist,Substitutionlist);
763    DEBOUTLN(cout, "Outputlist after MultiHensel: ", Outputlist);
764    TIMING_END(hensel_time);
765
766    // INTERRUPTHANDLER
767    if ( interrupt_handle() ) return CFFList() ;
768    // INTERRUPTHANDLER
769
770    TIMING_START(truefactor_time);
771    Outputlist = Truefactors(ff, level(ff), Substitutionlist, Outputlist);
772    DEBOUTLN(cout, "Outputlist after Truefactors: ", Outputlist);
773    TIMING_END(truefactor_time);
774
775    // INTERRUPTHANDLER
776    if ( interrupt_handle() ) return CFFList() ;
777    // INTERRUPTHANDLER
778
779    if ( lt != f.genOne() ){
780      Outputlist = not_monic(Outputlist,lt,ff,level(ff));
781      DEBOUTLN(cout, "not_monic returned: ", Outputlist);
782    }
783
784    // have to back-swapvar the factors....
785    for ( CFFListIterator i=Outputlist; i.hasItem(); i++ ){
786        copy=i.getItem();
787        Outputlist2.append(CFFactor(swapvar(copy.factor(),oldmainvar,mainvar),copy.exp()));
788    }
789
790    return Outputlist2;
791  }
792}
793
794// for debuggig:
795int cmpCF( const CFFactor & f, const CFFactor & g );
796
797///////////////////////////////////////////////////////////////
798// The user front-end for a uni/multivariate factorization   //
799// routine. F needs not to be SqrFree.                       //
800// Option of * choosing a  main variable (n.y.i.)            //
801//           * choosing an algebraic extension (n.y.u.)      //
802//           * ensuring poly is sqrfree (n.y.i.)             //
803// use Factorize(F,alpha,is_SqrFree) if not over Zp[x]/Q[x]  //
804///////////////////////////////////////////////////////////////
805int find_mvar(const CanonicalForm &f);
806CFFList
807Factorize(const CanonicalForm & F, int is_SqrFree ){
808  CFFList Outputlist,SqrFreeList,Intermediatelist,Outputlist2;
809  ListIterator<CFFactor> i,j;
810  CanonicalForm g=1,unit=1,r=1;
811  Variable minpoly; // dummy
812  int exp;
813  CFMap m;
814
815  // INTERRUPTHANDLER
816  if ( interrupt_handle() ) return CFFList() ;
817  // INTERRUPTHANDLER
818
819  DEBINCLEVEL(cout, "Factorize");
820  DEBOUTMSG(cout, rcsid);
821  DEBOUTLN(cout, "Called with F= ", F);
822  if ( getCharacteristic() == 0 ) { // char == 0
823    TIMING_START(factorize_time);
824    //cout << "Factoring in char=0 of " << F << " = " << Outputlist << endl;
825    Outputlist= factorize(F);
826    // Factorization in char=0 doesn't sometimes return at least two elements!!!
827    if ( getNumVars(Outputlist.getFirst().factor()) != 0 )
828      Outputlist.insert(CFFactor(1,1));
829    //cout << "  Factorize in char=0: returning with: " << Outputlist << endl;
830    TIMING_END(factorize_time);
831    DEBDECLEVEL(cout, "Factorize");
832    TIMING_PRINT(factorize_time, "\ntime used for factorization   : ");
833    return Outputlist;
834  }
835  TIMING_START(factorize_time);
836  // search an "optimal" main variavble
837  int mv=F.level();
838  if (mv != LEVELBASE && ! F.isUnivariate() )
839  {
840     mv=find_mvar(F);
841     if (mv!=F.level())
842     {
843       swapvar(F,Variable(mv),F.mvar());
844     }
845  }
846
847  ///////
848  // Maybe it`s better to add a sqrfree-test before?
849  // (If gcd is fast...)
850  ///////
851  //  if ( ! SqrFreeTest(F) ){
852  if ( ! is_SqrFree ){
853    TIMING_START(sqrfree_time);
854    SqrFreeList = InternalSqrFree(F) ; // first sqrfree the polynomial
855    // don't use sqrFree(F), factory's internal sqrFree for multiv.
856    // Polynomials; it's wrong!! Ex.: char=p   f= x^p*(y+1);
857    // InternalSqrFree(f)= ( y+1, (x)^p ), sqrFree(f)= ( y+1 ) .
858    TIMING_END(sqrfree_time);
859
860    // INTERRUPTHANDLER
861    if ( interrupt_handle() ) return CFFList() ;
862    // INTERRUPTHANDLER
863
864  }
865  else
866    SqrFreeList.append(CFFactor(F,1));
867  DEBOUTLN(cout, "InternalSqrFreeList= ", SqrFreeList);
868  for ( i=SqrFreeList; i.hasItem(); i++ ){
869    DEBOUTLN(cout, "Factor under consideration: ", i.getItem().factor());
870    // We need a compress on each list item ! Maybe we have less variables!
871    g =compress(i.getItem().factor(),m);
872    exp = i.getItem().exp();
873    if ( getNumVars(g) ==0 ) // a constant; Exp==1
874      Outputlist.append( CFFactor(g,1) ) ;
875    else// a real polynomial
876      if ( g.isUnivariate() ){
877        Intermediatelist=factorize(g,1); // poly is sqr-free!
878        for ( j=Intermediatelist; j.hasItem(); j++ )
879          //Normally j.getItem().exp() should be 1
880          Outputlist.append( CFFactor( m(j.getItem().factor()),exp*j.getItem().exp()));
881      }
882      else{ // multivariate polynomial
883        if ( g.isHomogeneous() ){
884          DEBOUTLN(cout, "Poly is homogeneous! : ", g);
885          // Now we can substitute one variable to 1, factorize and then
886          // look on the resulting factors and their monomials for
887          // backsubstitution of the substituted variable.
888          Intermediatelist = HomogFactor(g, minpoly, 0);
889        }
890        else // not homogeneous
891          Intermediatelist = Factorized(g, minpoly, 0);
892
893        // INTERRUPTHANDLER
894        if ( interrupt_handle() ) return CFFList() ;
895        // INTERRUPTHANDLER
896
897        for ( j=Intermediatelist; j.hasItem(); j++ )
898          //Normally j.getItem().exp() should be 1
899          Outputlist= myappend( Outputlist, CFFactor(m(j.getItem().factor()),exp*j.getItem().exp()));
900      }
901  }
902  g=1; unit=1;
903  DEBOUTLN(cout, "Outputlist is ", Outputlist);
904  for ( i=Outputlist; i.hasItem(); i++ )
905    if ( level(i.getItem().factor()) > 0 ){
906      unit = lc(i.getItem().factor());
907      if ( getNumVars(unit) == 0 ){ // a constant; possibly 1
908        Outputlist2.append(CFFactor(i.getItem().factor()/unit , i.getItem().exp()));
909        g *=power(i.getItem().factor()/unit,i.getItem().exp());
910      }
911      else{
912        Outputlist2.append(i.getItem());
913        g *=power(i.getItem().factor(),i.getItem().exp());
914      }
915    }
916
917  r=F/g;
918  Outputlist2.insert(CFFactor(r,1));
919
920  if ((mv!=F.level()) && (! F.isUnivariate() ))
921  {
922    CFFListIterator J=Outputlist2;
923    for ( ; J.hasItem(); J++)
924    {
925      swapvar(J.getItem().factor(),Variable(mv),F.mvar());
926    }
927    swapvar(F,Variable(mv),F.mvar());
928  }
929
930  DEBDECLEVEL(cout, "Factorize");
931  TIMING_END(factorize_time);
932
933  TIMING_PRINT(sqrfree_time, "\ntime used for sqrfree   : ");
934  TIMING_PRINT(discr_time, "time used for discriminante   : ");
935  TIMING_PRINT(evaluate_time, "time used for evaluation and univ. factorization  : ");
936  TIMING_PRINT(hensel_time, "time used for hensel-lift   : ");
937  TIMING_PRINT(truefactor_time, "time used for truefactors   : ");
938  TIMING_PRINT(factorize_time, "\ntime used for factorization   : ");
939
940  if(isOn(SW_USE_NTL_SORT)) Outputlist2.sort(cmpCF);
941
942  return Outputlist2;
943}
944
945///////////////////////////////////////////////////////////////
946// The user front-end for a uni/multivariate factorization   //
947// routine. F needs not to be SqrFree.                       //
948// Option of * choosing a  main variable (n.y.i.)            //
949//           * choosing an algebraic extension (n.y.u.)      //
950//           * ensuring poly is sqrfree (n.y.i.)             //
951///////////////////////////////////////////////////////////////
952CFFList
953Factorize(const CanonicalForm & F, const CanonicalForm & minpoly, int is_SqrFree ){
954  CFFList Outputlist,SqrFreeList,Intermediatelist,Outputlist2;
955  ListIterator<CFFactor> i,j;
956  CanonicalForm g=1,unit=1,r=1;
957  //Variable minpoly; // reserved (-> Factorisation over algebraic Extensions)
958  int exp;
959  CFMap m;
960
961  // INTERRUPTHANDLER
962  if ( interrupt_handle() ) return CFFList() ;
963  // INTERRUPTHANDLER
964
965  DEBINCLEVEL(cout, "Factorize");
966  DEBOUTMSG(cout, rcsid);
967  DEBOUTLN(cout, "Called with F= ", F);
968  if ( getCharacteristic() == 0 )
969  { // char == 0
970    TIMING_START(factorize_time);
971    //cout << "Factoring in char=0 of " << F << " = " << Outputlist << endl;
972    #if 0
973    // SHOULD: Outputlist= factorize(F,minpoly);
974    Outputlist= factorize(F);
975    #else
976    if (minpoly!=0)
977    {
978      CFList as(minpoly);
979      CFFList sqF=sqrFree(F); // sqrFreeZ
980      CFFList G,H;
981      CanonicalForm fac;
982      int d;
983      ListIterator<CFFactor> i,k;
984      for ( i = sqF; i.hasItem(); ++i )
985      {
986        d = i.getItem().exp();
987        fac = i.getItem().factor();
988        G = newfactoras( fac, as, 1);
989        for ( k = G; k.hasItem(); ++k )
990        {
991          fac = k.getItem().factor();
992          int dd = k.getItem().exp();
993          H.append( CFFactor( fac , d*dd ) );
994        }
995      }
996      //Outputlist = newfactoras( F, as, 1);
997      Outputlist = H;
998    }
999    else
1000      Outputlist=factorize(F);
1001    #endif
1002    // Factorization in char=0 doesn't sometimes return at least two elements!!!
1003    if ( getNumVars(Outputlist.getFirst().factor()) != 0 )
1004      Outputlist.insert(CFFactor(1,1));
1005    //cout << "  Factorize in char=0: returning with: " << Outputlist << endl;
1006    TIMING_END(factorize_time);
1007    DEBDECLEVEL(cout, "Factorize");
1008    TIMING_PRINT(factorize_time, "\ntime used for factorization   : ");
1009    return Outputlist;
1010  }
1011  TIMING_START(factorize_time);
1012  // search an "optimal" main variavble
1013  int mv=F.level();
1014  if (mv != LEVELBASE && ! F.isUnivariate() )
1015  {
1016     mv=find_mvar(F);
1017     if (mv!=F.level())
1018     {
1019       swapvar(F,Variable(mv),F.mvar());
1020     }
1021  }
1022
1023  ///////
1024  // Maybe it`s better to add a sqrfree-test before?
1025  // (If gcd is fast...)
1026  ///////
1027  //  if ( ! SqrFreeTest(F) ){
1028  if ( ! is_SqrFree ){
1029    TIMING_START(sqrfree_time);
1030    SqrFreeList = InternalSqrFree(F, minpoly) ; // first sqrfree the polynomial
1031    // don't use sqrFree(F), factory's internal sqrFree for multiv.
1032    // Polynomials; it's wrong!! Ex.: char=p   f= x^p*(y+1);
1033    // InternalSqrFree(f)= ( y+1, (x)^p ), sqrFree(f)= ( y+1 ) .
1034    TIMING_END(sqrfree_time);
1035
1036    // INTERRUPTHANDLER
1037    if ( interrupt_handle() ) return CFFList() ;
1038    // INTERRUPTHANDLER
1039
1040  }
1041  else
1042    SqrFreeList.append(CFFactor(F,1));
1043  DEBOUTLN(cout, "InternalSqrFreeList= ", SqrFreeList);
1044  for ( i=SqrFreeList; i.hasItem(); i++ ){
1045    DEBOUTLN(cout, "Factor under consideration: ", i.getItem().factor());
1046    // We need a compress on each list item ! Maybe we have less variables!
1047    g =compress(i.getItem().factor(),m);
1048    exp = i.getItem().exp();
1049    if ( getNumVars(g) ==0 ) // a constant; Exp==1
1050      Outputlist.append( CFFactor(g,1) ) ;
1051    else// a real polynomial
1052      if ( g.isUnivariate() ){
1053        Variable alpha=rootOf(minpoly);
1054        Intermediatelist=factorize2(g,alpha,minpoly); // poly is sqr-free!
1055        for ( j=Intermediatelist; j.hasItem(); j++ )
1056          //Normally j.getItem().exp() should be 1
1057          Outputlist.append(
1058           CFFactor( m(replacevar(j.getItem().factor(),alpha,minpoly.mvar())),
1059             exp*j.getItem().exp()));
1060      }
1061      else{ // multivariate polynomial
1062        if ( g.isHomogeneous() ){
1063          DEBOUTLN(cout, "Poly is homogeneous! : ", g);
1064          // Now we can substitute one variable to 1, factorize and then
1065          // look on the resulting factors and their monomials for
1066          // backsubstitution of the substituted variable.
1067          Intermediatelist = HomogFactor(g, minpoly, 0);
1068        }
1069        else // not homogeneous
1070          Intermediatelist = Factorized(g, minpoly, 0);
1071
1072        // INTERRUPTHANDLER
1073        if ( interrupt_handle() ) return CFFList() ;
1074        // INTERRUPTHANDLER
1075
1076        for ( j=Intermediatelist; j.hasItem(); j++ )
1077          //Normally j.getItem().exp() should be 1
1078          Outputlist= myappend( Outputlist, CFFactor(m(j.getItem().factor()),exp*j.getItem().exp()));
1079      }
1080  }
1081  g=1; unit=1;
1082  DEBOUTLN(cout, "Outputlist is ", Outputlist);
1083  for ( i=Outputlist; i.hasItem(); i++ )
1084    if ( level(i.getItem().factor()) > 0 ){
1085      unit = lc(i.getItem().factor());
1086      if ( getNumVars(unit) == 0 ){ // a constant; possibly 1
1087        Outputlist2.append(CFFactor(i.getItem().factor()/unit , i.getItem().exp()));
1088        g *=power(i.getItem().factor()/unit,i.getItem().exp());
1089      }
1090      else{
1091        Outputlist2.append(i.getItem());
1092        g *=power(i.getItem().factor(),i.getItem().exp());
1093      }
1094    }
1095
1096  r=F/g;
1097  Outputlist2.insert(CFFactor(r,1));
1098
1099  if ((mv!=F.level()) && (! F.isUnivariate() ))
1100  {
1101    CFFListIterator J=Outputlist2;
1102    for ( ; J.hasItem(); J++)
1103    {
1104      swapvar(J.getItem().factor(),Variable(mv),F.mvar());
1105    }
1106    swapvar(F,Variable(mv),F.mvar());
1107  }
1108
1109  DEBDECLEVEL(cout, "Factorize");
1110  TIMING_END(factorize_time);
1111
1112  TIMING_PRINT(sqrfree_time, "\ntime used for sqrfree   : ");
1113  TIMING_PRINT(discr_time, "time used for discriminante   : ");
1114  TIMING_PRINT(evaluate_time, "time used for evaluation and univ. factorization  : ");
1115  TIMING_PRINT(hensel_time, "time used for hensel-lift   : ");
1116  TIMING_PRINT(truefactor_time, "time used for truefactors   : ");
1117  TIMING_PRINT(factorize_time, "\ntime used for factorization   : ");
1118
1119  if(isOn(SW_USE_NTL_SORT)) Outputlist2.sort(cmpCF);
1120
1121  return Outputlist2;
1122}
1123
1124/*
1125$Log: not supported by cvs2svn $
1126Revision 1.20  2005/12/05 15:47:32  Singular
1127*hannes: is_homogeneous -> factory: isHomogeneous
1128
1129Revision 1.19  2005/10/17 13:18:44  Singular
1130*hannes: apply sqrFree before newfactoras (Factorize in Q(a))
1131
1132Revision 1.18  2005/10/17 13:17:39  Singular
1133*hannes: aplly sqrFree before newfactoras (Factorize in Q(a))
1134
1135Revision 1.17  2004/12/10 10:15:06  Singular
1136*pohl: AlgExtGenerator etc.
1137
1138Revision 1.16  2003/05/28 11:52:52  Singular
1139*pfister/hannes: newfactoras, alg_gcd, divide (see bug_33)
1140
1141Revision 1.15  2003/02/14 15:51:15  Singular
1142* hannes: bugfix
1143          could not factorize x2+xy+y2 in Fp(a)[x,y], a2+a+1=0
1144          (factorize2 does nor sanity checks)
1145
1146Revision 1.14  2002/08/19 11:11:32  Singular
1147* hannes/pfister: alg_gcd etc.
1148
1149Revision 1.13  2002/07/30 17:06:47  Singular
1150*hannes: uuh - factorize in Q(a)[x] is missing, use Q[a][x].
1151
1152Revision 1.12  2002/07/30 15:10:22  Singular
1153*hannes: added Factorize for alg. ext.
1154
1155Revision 1.11  2001/08/22 14:21:16  Singular
1156*hannes: added search for main var to Factorize
1157
1158Revision 1.10  2001/08/08 14:26:55  Singular
1159*hannes: Dan's HAVE_SINGULAR_ERROR
1160
1161Revision 1.9  2001/08/08 11:59:12  Singular
1162*hannes: Dan's NOSTREAMIO changes
1163
1164Revision 1.8  2001/08/06 08:32:54  Singular
1165* hannes: code cleanup
1166
1167Revision 1.7  2001/06/21 14:57:05  Singular
1168*hannes/GP: Factorize, newfactoras, ...
1169
1170Revision 1.6  2001/06/18 08:44:41  pfister
1171* hannes/GP/michael: factory debug, Factorize
1172
1173Revision 1.5  1999/06/15 12:54:55  Singular
1174* hannes: debug fixes for Singular-interface
1175
1176Revision 1.4  1997/11/18 16:39:04  Singular
1177* hannes: moved WerrorS from C++ to C
1178     (Factor.cc MVMultiHensel.cc SqrFree.cc Truefactor.cc)
1179
1180Revision 1.3  1997/09/12 07:19:46  Singular
1181* hannes/michael: libfac-0.3.0
1182
1183Revision 1.6  1997/04/25 22:18:40  michael
1184changed lc == 1 to lc == unit in choose_mainvar
1185changed cerr and cout messages for use with Singular
1186Version for libfac-0.2.1
1187
1188Revision 1.5  1997/01/17 05:04:03  michael
1189* added support for homogenous polynomials
1190* exported functions to homogfactor.cc
1191
1192*/
Note: See TracBrowser for help on using the repository browser.