source: git/libfac/charset/algfactor.cc @ 36b7a3

spielwiese
Last change on this file since 36b7a3 was 36b7a3, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: gcc 4.2 git-svn-id: file:///usr/local/Singular/svn/trunk@10633 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.1 KB
Line 
1/* Copyright 1997 Michael Messollen. All rights reserved. */
2////////////////////////////////////////////////////////////
3// emacs edit mode for this file is -*- C++ -*-
4////////////////////////////////////////////////////////////
5/* $Id: algfactor.cc,v 1.11 2008-03-18 17:46:14 Singular Exp $ */
6////////////////////////////////////////////////////////////
7// FACTORY - Includes
8#include <factory.h>
9// Factor - Includes
10#include <tmpl_inst.h>
11#include <Factor.h>
12#include <helpstuff.h>
13// Charset - Includes
14#include "csutil.h"
15#include "charset.h"
16#include "reorder.h"
17#include "alg_factor.h"
18// some CC's need this:
19#include "algfactor.h"
20
21#ifdef ALGFACTORDEBUG
22#  define DEBUGOUTPUT
23#else
24#  undef DEBUGOUTPUT
25#endif
26
27#include "debug.h"
28#include "timing.h"
29TIMING_DEFINE_PRINT(newfactoras_time);
30
31int hasVar(const CanonicalForm &f, const Variable &v);
32
33static CFFList
34myminus( const CFFList & Inputlist, const CFFactor & TheFactor){
35  CFFList Outputlist ;
36  CFFactor copy;
37
38  for ( CFFListIterator i=Inputlist ; i.hasItem() ; i++ ){
39    copy = i.getItem();
40    if ( copy.factor() != TheFactor.factor() ){
41      Outputlist.append( copy );
42    }
43  }
44  return Outputlist;
45}
46
47static CFFList
48myDifference(const CFFList & Inputlist1,const CFFList & Inputlist2){
49  CFFList Outputlist=Inputlist1;
50
51  for ( CFFListIterator i=Inputlist2 ; i.hasItem() ; i++ )
52    Outputlist = myminus(Outputlist, i.getItem() );
53
54  return Outputlist;
55}
56
57
58// return 1 if as is quasilinear; 0 if not.
59static int
60isquasilinear( const CFList & as ){
61  if (as.length() <= 1) { return 1; }
62  else {
63    CFList AS=as;
64    AS.removeFirst(); // we are not interested in the first elem
65    for ( CFListIterator i=AS; i.hasItem(); i++)
66      if ( degree(i.getItem()) > 1 ) return 0;
67  }
68return 1;
69}
70
71#ifdef CHARSETNADEBUG
72#  define DEBUGOUTPUT
73#else
74#  undef DEBUGOUTPUT
75#endif
76#include "debug.h"
77static CFList
78charsetnA(const CFList & AS, const CFList &PS, PremForm & Remembern, const Variable & vf ){
79  CFList QS = PS, RS = PS, Cset;
80  int nas= AS.length() +1;
81
82  DEBOUTLN(CERR, "charsetnA: called with ps= ", PS);
83  while ( ! RS.isEmpty() ) {
84    Cset = BasicSet( QS );
85    DEBOUTLN(CERR, "charsetnA: Cset= ", Cset);
86    Cset=Union(Cset,AS);
87    DEBOUTLN(CERR, "charsetnA: Cset= ", Cset);
88    Remembern.FS1 = Union(Remembern.FS1, initalset1(Cset));
89    DEBOUTLN(CERR, "charsetnA: Remembern.FS1= ", Remembern.FS1);
90    DEBOUTLN(CERR, "charsetnA: Remembern.FS2= ", Remembern.FS2);
91    RS = CFList();
92    if ( Cset.length() == nas && degree(Cset.getLast(),vf) > 0 ) {
93      CFList D = Difference( QS, Cset );
94      DEBOUT(CERR, "charsetnA: Difference( ", QS);
95      DEBOUT(CERR, " , ", Cset);
96      DEBOUTLN(CERR, " ) = ", D);
97      for ( CFListIterator i = D; i.hasItem(); ++i ) {
98        CanonicalForm r = Prem( i.getItem(), Cset );
99        DEBOUT(CERR,"charsetnA: Prem(", i.getItem()  );
100        DEBOUT(CERR, ",", Cset);
101        DEBOUTLN(CERR,") = ", r);
102        if ( r != 0 ){
103          //removefactor( r, Remembern );
104            RS=Union(RS,CFList(r));
105        }
106      }
107      if ( ! checkok(RS,Remembern.FS2)) return CFList(CanonicalForm(1));
108      DEBOUTLN(CERR, "charsetnA: RS= ", RS);
109      //QS = Union( QS, RS );
110      QS=Union(AS,RS); QS.append(Cset.getLast());
111      DEBOUTLN(CERR, "charsetnA: QS= Union(QS,RS)= ", QS);
112    }
113    else{ return CFList(CanonicalForm(1)); }
114  }
115  DEBOUTLN(CERR, "charsetnA: Removed factors: ", Remembern.FS2);
116  DEBOUTLN(CERR, "charsetnA: Remembern.FS1: ", Remembern.FS1);
117
118  return Cset;
119}
120
121#ifdef ALGFACTORDEBUG
122#  define DEBUGOUTPUT
123#else
124#  undef DEBUGOUTPUT
125#endif
126#include "debug.h"
127// compute the GCD of f and g over the algebraic field having
128// adjoing ascending set as
129CanonicalForm
130algcd(const CanonicalForm & F, const CanonicalForm & g, const CFList & as, const Varlist & order){
131  CanonicalForm f=F;
132  int nas= as.length()+1; // the length the new char. set should have!
133  Variable vf=f.mvar();
134
135//   for ( VarlistIterator i=order; i.hasItem() ; i++ ){
136//     vf= i.getItem();
137//     nas--;
138//     if ( nas==0 ) break;
139//   }
140//   nas= as.length()+1;
141
142  DEBOUTLN(CERR, "algcd called with f= ", f);
143  DEBOUTLN(CERR, "                  g= ", g);
144  DEBOUTLN(CERR, "                 as= ", as);
145  DEBOUTLN(CERR, "              order= ", order);
146  DEBOUTLN(CERR, "         choosen vf= ", vf);
147
148  // check trivial case:
149  if ( degree(f, order.getLast())==0 || degree(g, order.getLast())==0)
150  {
151    DEBOUTLN(CERR, "algcd Result= ", 1);
152    return CanonicalForm(1);
153  }
154
155  CFList bs; bs.append(f); bs.append(g);
156  PremForm Remembern;
157  CFList cs=charsetnA(as,bs,Remembern,vf);
158  DEBOUTLN(CERR, "CharSetA((as,bs))= ", cs);
159
160//    for ( VarlistIterator i=order; i.hasItem() ; i++ ){
161//      DEBOUTLN(CERR, "vf= ", i.getItem());
162//      DEBOUTLN(CERR, "CharSetA((as,bs))= " , charsetnA(as,bs,Remembern,i.getItem()));
163//    }
164
165  CanonicalForm result;
166  if (cs.length()==nas)
167  {
168    result= cs.getLast();
169    CanonicalForm c=vcontent(result,Variable(1));
170    //CanonicalForm c=result.Lc();
171    result/=c;
172    for(CFListIterator i=as;i.hasItem(); i++ )
173    {
174      if(hasVar(result,i.getItem().mvar()))
175      {
176        c=vcontent(result,Variable(i.getItem().level()+1));
177        result/=c;
178      }
179    }
180  }
181  else result= CanonicalForm(1);
182  DEBOUTLN(CERR, "algcd Result= ", result);
183  return result;
184}
185
186CFFList
187factoras( const CanonicalForm & f, const CFList & as, int & success ){
188  Variable vf=f.mvar();
189  CFListIterator i;
190  CFFListIterator jj;
191  CFList reduceresult;
192  CFFList result;
193
194  DEBINCLEVEL(CERR, "factoras");
195  DEBOUTMSG(CERR, rcsid);
196  DEBOUTLN(CERR, "factoras called with f= ", f);
197  DEBOUTLN(CERR, "               content(f)= ", content(f));
198  DEBOUTLN(CERR, "                       as= ", as);
199  DEBOUTLN(CERR, "factoras: cls(vf)= ", cls(vf));
200  DEBOUTLN(CERR, "factoras: cls(as.getLast())= ", cls(as.getLast()));
201  DEBOUTLN(CERR, "factoras: degree(f,vf)= ", degree(f,vf));
202
203// F1: [Test trivial cases]
204// 1) first trivial cases:
205  if ( (cls(vf) <= cls(as.getLast())) ||
206       degree(f,vf)<=1
207// ||( (as.length()==1) && (degree(f,vf)==3) && (degree(as.getFirst()==2)) )
208       ){
209    success=1;
210    DEBDECLEVEL(CERR,"factoras");
211    return CFFList(CFFactor(f,1));
212  }
213
214
215// 2) List of variables:
216// 2a) Setup list of those polys in AS having degree(AS[i], AS[i].mvar()) > 1
217// 2b) Setup variableordering
218  CFList Astar;
219  Variable x;
220  CanonicalForm elem;
221  Varlist ord, uord,oldord;
222  for ( int ii=1; ii< level(vf) ; ii++ ) { uord.append(Variable(ii));  }
223  oldord= uord; oldord.append(vf);
224
225  for ( i=as; i.hasItem(); i++ ){
226    elem= i.getItem();
227    x= elem.mvar();
228    if ( degree(elem,x) > 1){ // otherwise it's not an extension
229      //if ( degree(f,x) > 0 ){ // does it occure in f? RICHTIG?
230        Astar.append(elem);
231        ord.append(x);
232        //}
233    }
234  }
235  uord= Difference(uord,ord);
236  DEBOUTLN(CERR, "Astar is: ", Astar);
237  DEBOUTLN(CERR, "ord is: ", ord);
238  DEBOUTLN(CERR, "uord is: ", uord);
239
240// 3) second trivial cases
241  if ( Astar.length() == 0 ){
242    success=1;
243    DEBDECLEVEL(CERR,"factoras");
244    return CFFList(CFFactor(f,1));
245  }
246
247// 4) Try to obtain a partial factorization using prop2 and prop3
248  // Not yet implemented
249
250// 5) choose (d_1, ..., d_s)
251  FFRandom gen;
252  if ( getCharacteristic() == 0 ) IntRandom gen(100);
253  REvaluation D(1, ord.length(), gen);
254  //D.nextpoint(); // first we use 0 as evaluation point
255
256F2: //[Characteristic set computation]
257// 6) Compute f^* (<- fstar)
258  CanonicalForm substhin=CanonicalForm(vf), substback=CanonicalForm(vf);
259  CanonicalForm monom;
260  DEBOUTLN(CERR, "substhin= ", substhin);
261  DEBOUTLN(CERR, "substback= ", substback);
262  int j=1;
263  for ( VarlistIterator jjj=ord; jjj.hasItem(); jjj++){
264    if ( getCharacteristic() > 0 ) monom= jjj.getItem()*D[j];
265    else  monom= mapinto(jjj.getItem()*mapinto(D[j]));
266    j++;
267    substhin-= monom; substback+= monom;
268  }
269  DEBOUTLN(CERR, "substhin= ", substhin);
270  DEBOUTLN(CERR, "substback= ", substback);
271  CanonicalForm fstar=f(substhin,vf);
272  DEBOUTLN(CERR, "fstar= ", fstar);
273
274// 7) Set up Variable ordering from ord,vf to vf,ord ! i.e. vf is the variable
275//    with lowest level.
276  Varlist nord=uord;
277  nord.append(vf); nord= Union(ord,nord);
278  DEBOUTLN(CERR, "          nord= ", nord);
279  CFList Astarnord= Astar; Astarnord.insert(fstar);
280  DEBOUTLN(CERR, "     Astarnord= ", Astarnord);
281  Astarnord= reorder(nord,Astarnord);
282  DEBOUTLN(CERR, "original Astar= ", Astar);
283  DEBOUTLN(CERR, "reorderd Astar= ", Astarnord);
284  DEBOUTLN(CERR, "             f= ", f);
285  DEBOUTLN(CERR, "         fstar= ", fstar);
286
287// 8) Compute Charset Cstar of Astar \cup { fstar } wrt. ordering {vf, ord}
288  PremForm Remembern;
289  CFList Cstar= MCharSetN(Astarnord, Remembern);
290  DEBOUTLN(CERR, " Cstar= ", Cstar );
291  DEBOUTLN(CERR, " Factors removed= ", Remembern.FS2 );
292  DEBOUTLN(CERR, " Possible Factors considered:= ", Remembern.FS1 );
293  DEBOUTLN(CERR, " Reorderd Cstar= ", reorder(nord,Cstar));
294
295// 9) Compute Delta: the set of all irr. factors (over K_0) of initials of
296//    Cstar
297  CFList iniset= initalset1(Cstar);
298  DEBOUTLN(CERR, "Set of initials: ", iniset);
299  CFFList Delta;
300  CFFList temp;
301  for ( i=iniset; i.hasItem(); i++){
302    Off(SW_RATIONAL);
303    temp= Factorize(i.getItem());
304    On(SW_RATIONAL);
305    temp.removeFirst();
306    Delta= Union(temp,Delta);
307  }
308  DEBOUTLN(CERR, "Delta= ", Delta);
309
310// 10) Compute Psi: the irreduzible factors (over K_0) of the first polynomial
311//     in Cstar, which are not factors of any polynomial in Delta
312  Off(SW_RATIONAL);
313  CFFList Psi=Factorize(Cstar.getFirst());
314  On(SW_RATIONAL);
315  Psi.removeFirst();
316  Psi= myDifference(Psi,Delta);
317  DEBOUTLN(CERR, "Psi= ", Psi);
318
319// F3: [Test quasilinearity]
320// If Cstar is quasilinear -> F4
321// else if Psi.length() > 1 then Delta<- Delta \cup Psi; Psi<- \emptyset -> F4
322// else D.nextpoint() -> F2
323  if ( isquasilinear(Cstar) ) {
324    DEBOUTLN(CERR, "Cstar is quasilinear; going to F4, Cstar= ", Cstar);
325    goto F4;
326  }
327  else if ( Psi.length() > 1 ){
328    Delta= Union(Psi,Delta);
329    Psi= CFFList();
330    DEBOUTMSG(CERR, "Psi.length() == 1; going to F4");
331    goto F4;
332  }
333  else{
334    D.nextpoint();
335    DEBOUTMSG(CERR, "Choosing next evaluation point. going to F2");
336    goto F2;
337  }
338
339F4: //[GCD Computation]
340  CanonicalForm g=f;
341  Delta= reorder(nord,Delta);
342  Psi= reorder(nord,Psi);
343  DEBOUTLN(CERR, "Reordered: Delta= ", Delta);
344  DEBOUTLN(CERR, "             Psi= ", Psi);
345  CanonicalForm fp;
346
347  DEBOUTMSG(CERR, "Testing Psi: this gives irreducible Factors!");
348  for (jj=Psi; jj.hasItem(); jj++){
349    if ( degree(g,vf) == 1 ) { // g is linear
350      break;
351    }
352    fp= jj.getItem().factor();
353    DEBOUT(CERR, "Calculating fp= gcd(", g);
354    DEBOUT(CERR, ",", fp(substback,vf));
355    DEBOUT(CERR, ") over K_r wrt ", vf);
356    fp=alg_gcd(g,fp(substback,vf), as);
357    //fp= algcd(g,fp(substback,vf), as, oldord);
358    DEBOUTLN(CERR, " = ", fp);
359    if ( degree(fp,vf) > 0 ){ //otherwise it's a constant
360      g= divide(g, fp,as);
361      DEBOUTLN(CERR, "f/fp= ", g);
362      result.append(CFFactor(fp,1));
363    }
364  }
365
366  DEBOUTMSG(CERR, "Testing Delta: this gives Factors (not nec. irreduzible!)");
367  for (jj=Delta; jj.hasItem(); jj++){
368    if ( degree(g,vf) <= 1 ) { // g is linear (or a constant..)
369      break;
370    }
371    fp= jj.getItem().factor();
372    DEBOUT(CERR, "Calculating fp= gcd(", g);
373    DEBOUT(CERR, ",", fp(substback,vf));
374    DEBOUT(CERR, ") over K_r wrt ", vf);
375    fp= alg_gcd(g,fp(substback,vf), as);
376    //fp= algcd(g,fp(substback,vf), as, oldord);
377    DEBOUTLN(CERR, " = ", fp);
378    if ( degree(fp,vf) > 0 ){ //otherwise it's a constant
379      g= divide(g, fp,as);
380      DEBOUTLN(CERR, "f/fp= ", g);
381//      reduceresult.append(fp); // a facctor but not nec. irreduzible
382      result.append(CFFactor(fp,1));
383      success=0;
384    }
385  }
386
387//  if (reduceresult.length() > 0){ //we have factors;
388//    for ( CFListIterator I=reduceresult; I.hasItem(); I++ ){
389//      // try to obtain an irreducible factorization
390//      result= Union( result,
391//                     factoras(I.getItem(), Astar, success) );
392//    }
393//  }
394
395  if ( result.length()==0 ){
396    if ( isquasilinear(Cstar) ){ // Cstar quasilinear => f is irreduzible
397      success=1;
398      DEBDECLEVEL(CERR,"factoras");
399      return CFFList(CFFactor(f,1));
400    }
401    else {
402      DEBOUTMSG(CERR, "Going to F2!");
403      D.nextpoint(); // choose a new set of int's.
404      goto F2;
405    }
406  }
407  // result.length() > 0 ==> we have factors!
408  success=1;
409  result.append(CFFactor(g,1)); //append the rest
410  DEBDECLEVEL(CERR,"factoras");
411  return result;
412}
413
414// for now: success=-1 no success, success=1   factored poly,
415// success = 0 factored poly partially
416CFFList
417cfactor(const CanonicalForm & f, const CFList & as, int success ){
418  Off(SW_RATIONAL);
419  CFFList Output, output, Factors=Factorize(f); On(SW_RATIONAL);
420  int csuccess=0;
421  Factors.removeFirst();
422
423  if ( as.length() == 0 ){ success=1; return Factors;}
424  if ( cls(f) <= cls(as.getLast()) ) { success=1; return Factors;}
425
426  success=1;
427  for ( CFFListIterator i=Factors; i.hasItem(); i++ ){
428    CFFList CERR=factoras(i.getItem().factor(),as,csuccess);
429    success= min(success,csuccess);
430    for ( CFFListIterator j=CERR; j.hasItem(); j++)
431      Output = myappend(Output,CFFactor(j.getItem().factor(),j.getItem().exp()*i.getItem().exp()));
432  }
433  return Output;
434}
435
436// Gegenbeispiel: char(k)=0 (original maple von wang):
437// f:= x^2*z^2-6909*x*z^2-3537*z^2-14344*x^2;
438// as:= [x^3-9977*x^2+15570*x-961]
439// ord:= [x,z]
440// cfactor(f,as,ord)=
441// -1/153600624478379*(-153600624478379*z^2+96784194432*x^2-246879593179080*x+
442// 13599716437688)*(x^2-6909*x-3537)
443//
444// maple:
445//  alias(alpha=RootOf(x^3-9977*x^2+15570*x-961,x));
446//  factor(f,alpha); // faktorisierung in char=0
447// x^2*z^2-6909*x*z^2-3537*z^2-14344*x^2
448
449
450/*
451$Log: not supported by cvs2svn $
452Revision 1.10  2008/03/17 17:44:16  Singular
453*hannes: fact.tst
454
455Revision 1.8  2006/06/19 13:37:46  Singular
456*hannes: more CS renamed
457
458Revision 1.7  2006/05/16 14:46:48  Singular
459*hannes: gcc 4.1 fixes
460
461Revision 1.6  2002/08/19 11:11:30  Singular
462* hannes/pfister: alg_gcd etc.
463
464Revision 1.5  2001/06/27 13:58:05  Singular
465*hannes/GP: debug newfactoras, char_series, ...
466
467Revision 1.4  2001/06/21 14:57:04  Singular
468*hannes/GP: Factorize, newfactoras, ...
469
470Revision 1.3  2001/06/18 08:44:40  pfister
471* hannes/GP/michael: factory debug, Factorize
472
473Revision 1.2  1997/09/12 07:19:38  Singular
474* hannes/michael: libfac-0.3.0
475
476*/
Note: See TracBrowser for help on using the repository browser.