source: git/libfac/charset/algfactor.cc @ 405ebc

spielwiese
Last change on this file since 405ebc was 405ebc, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes/GP: debug newfactoras, char_series, ... git-svn-id: file:///usr/local/Singular/svn/trunk@5515 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.6 KB
Line 
1/* Copyright 1997 Michael Messollen. All rights reserved. */
2////////////////////////////////////////////////////////////
3// emacs edit mode for this file is -*- C++ -*-
4////////////////////////////////////////////////////////////
5static char * rcsid = "$Id: algfactor.cc,v 1.5 2001-06-27 13:58:05 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, CS;
80  int nas= AS.length() +1;
81
82  DEBOUTLN(cout, "charsetnA: called with ps= ", PS);
83  while ( ! RS.isEmpty() ) {
84    CS = BasicSet( QS );
85    DEBOUTLN(cout, "charsetnA: CS= ", CS);
86    CS=Union(CS,AS);
87    DEBOUTLN(cout, "charsetnA: CS= ", CS);
88    Remembern.FS1 = Union(Remembern.FS1, initalset1(CS));
89    DEBOUTLN(cout, "charsetnA: Remembern.FS1= ", Remembern.FS1);
90    DEBOUTLN(cout, "charsetnA: Remembern.FS2= ", Remembern.FS2);
91    RS = CFList();
92    if ( CS.length() == nas && degree(CS.getLast(),vf) > 0 ) {
93      CFList D = Difference( QS, CS );
94      DEBOUT(cout, "charsetnA: Difference( ", QS);
95      DEBOUT(cout, " , ", CS);
96      DEBOUTLN(cout, " ) = ", D);
97      for ( CFListIterator i = D; i.hasItem(); ++i ) {
98        CanonicalForm r = Prem( i.getItem(), CS );
99        DEBOUT(cout,"charsetnA: Prem(", i.getItem()  );
100        DEBOUT(cout, ",", CS);
101        DEBOUTLN(cout,") = ", 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(cout, "charsetnA: RS= ", RS);
109      //QS = Union( QS, RS );
110      QS=Union(AS,RS); QS.append(CS.getLast());
111      DEBOUTLN(cout, "charsetnA: QS= Union(QS,RS)= ", QS);
112    }
113    else{ return CFList(CanonicalForm(1)); }
114  }
115  DEBOUTLN(cout, "charsetnA: Removed factors: ", Remembern.FS2);
116  DEBOUTLN(cout, "charsetnA: Remembern.FS1: ", Remembern.FS1);
117
118  return CS;
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(cout, "algcd called with f= ", f);
143  DEBOUTLN(cout, "                  g= ", g);
144  DEBOUTLN(cout, "                 as= ", as);
145  DEBOUTLN(cout, "              order= ", order);
146  DEBOUTLN(cout, "         choosen vf= ", vf);
147
148  // check trivial case:
149  if ( degree(f, order.getLast())==0 || degree(g, order.getLast())==0)
150  {
151    DEBOUTLN(cout, "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(cout, "CharSetA((as,bs))= ", cs);
159
160//    for ( VarlistIterator i=order; i.hasItem() ; i++ ){
161//      DEBOUTLN(cout, "vf= ", i.getItem());
162//      DEBOUTLN(cout, "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(cout, "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(cout, "factoras");
195  DEBOUTMSG(cerr, rcsid);
196  DEBOUTLN(cout, "factoras called with f= ", f);
197  DEBOUTLN(cout, "               content(f)= ", content(f));
198  DEBOUTLN(cout, "                       as= ", as);
199  DEBOUTLN(cout, "factoras: cls(vf)= ", cls(vf));
200  DEBOUTLN(cout, "factoras: cls(as.getLast())= ", cls(as.getLast()));
201  DEBOUTLN(cout, "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(cout,"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(cout, "Astar is: ", Astar);
237  DEBOUTLN(cout, "ord is: ", ord);
238  DEBOUTLN(cout, "uord is: ", uord);
239
240// 3) second trivial cases
241  if ( Astar.length() == 0 ){
242    success=1;
243    DEBDECLEVEL(cout,"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(cout, "substhin= ", substhin);
261  DEBOUTLN(cout, "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(cout, "substhin= ", substhin);
270  DEBOUTLN(cout, "substback= ", substback);
271  CanonicalForm fstar=f(substhin,vf);
272  DEBOUTLN(cout, "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(cout, "          nord= ", nord);
279  CFList Astarnord= Astar; Astarnord.insert(fstar);
280  DEBOUTLN(cout, "     Astarnord= ", Astarnord);
281  Astarnord= reorder(nord,Astarnord);
282  DEBOUTLN(cout, "original Astar= ", Astar);
283  DEBOUTLN(cout, "reorderd Astar= ", Astarnord);
284  DEBOUTLN(cout, "             f= ", f);
285  DEBOUTLN(cout, "         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(cout, " Cstar= ", Cstar );
291  DEBOUTLN(cout, " Factors removed= ", Remembern.FS2 );
292  DEBOUTLN(cout, " Possible Factors considered:= ", Remembern.FS1 );
293  DEBOUTLN(cout, " 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(cout, "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(cout, "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(cout, "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(cout, "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(cout, "Psi.length() == 1; going to F4");
331    goto F4;
332  }
333  else{
334    D.nextpoint();
335    DEBOUTMSG(cout, "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(cout, "Reordered: Delta= ", Delta);
344  DEBOUTLN(cout, "             Psi= ", Psi);
345  CanonicalForm fp;
346
347  DEBOUTMSG(cout, "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(cout, "Calculating fp= gcd(", g);
354    DEBOUT(cout, ",", fp(substback,vf));
355    DEBOUT(cout, ") over K_r wrt ", vf);
356    fp= algcd(g,fp(substback,vf), as, oldord);
357    DEBOUTLN(cout, " = ", fp);
358    if ( degree(fp,vf) > 0 ){ //otherwise it's a constant
359      g= divide(g, fp,as);
360      DEBOUTLN(cout, "f/fp= ", g);
361      result.append(CFFactor(fp,1));
362    }
363  }
364
365  DEBOUTMSG(cout, "Testing Delta: this gives Factors (not nec. irreduzible!)");
366  for (jj=Delta; jj.hasItem(); jj++){
367    if ( degree(g,vf) <= 1 ) { // g is linear (or a constant..)
368      break;
369    }
370    fp= jj.getItem().factor();
371    DEBOUT(cout, "Calculating fp= gcd(", g);
372    DEBOUT(cout, ",", fp(substback,vf));
373    DEBOUT(cout, ") over K_r wrt ", vf);
374    fp= algcd(g,fp(substback,vf), as, oldord);
375    DEBOUTLN(cout, " = ", fp);
376    if ( degree(fp,vf) > 0 ){ //otherwise it's a constant
377      g= divide(g, fp,as);
378      DEBOUTLN(cout, "f/fp= ", g);
379//      reduceresult.append(fp); // a facctor but not nec. irreduzible
380      result.append(CFFactor(fp,1));
381      success=0;
382    }
383  }
384
385//  if (reduceresult.length() > 0){ //we have factors;
386//    for ( CFListIterator I=reduceresult; I.hasItem(); I++ ){
387//      // try to obtain an irreducible factorization
388//      result= Union( result,
389//                     factoras(I.getItem(), Astar, success) );
390//    }
391//  }
392
393  if ( result.length()==0 ){
394    if ( isquasilinear(Cstar) ){ // Cstar quasilinear => f is irreduzible
395      success=1;
396      DEBDECLEVEL(cout,"factoras");
397      return CFFList(CFFactor(f,1));
398    }
399    else {
400      DEBOUTMSG(cout, "Going to F2!");
401      D.nextpoint(); // choose a new set of int's.
402      goto F2;
403    }
404  }
405  // result.length() > 0 ==> we have factors!
406  success=1;
407  result.append(CFFactor(g,1)); //append the rest
408  DEBDECLEVEL(cout,"factoras");
409  return result;
410}
411
412// for now: success=-1 no success, success=1   factored poly,
413// success = 0 factored poly partially
414CFFList
415cfactor(const CanonicalForm & f, const CFList & as, int success ){
416  Off(SW_RATIONAL);
417  CFFList Output, output, Factors=Factorize(f); On(SW_RATIONAL);
418  int csuccess=0;
419  Factors.removeFirst();
420
421  if ( as.length() == 0 ){ success=1; return Factors;}
422  if ( cls(f) <= cls(as.getLast()) ) { success=1; return Factors;}
423
424  success=1;
425  for ( CFFListIterator i=Factors; i.hasItem(); i++ ){
426    CFFList coutput=factoras(i.getItem().factor(),as,csuccess);
427    success= min(success,csuccess);
428    for ( CFFListIterator j=coutput; j.hasItem(); j++)
429      Output = myappend(Output,CFFactor(j.getItem().factor(),j.getItem().exp()*i.getItem().exp()));
430  }
431  return Output;
432}
433
434// Gegenbeispiel: char(k)=0 (original maple von wang):
435// f:= x^2*z^2-6909*x*z^2-3537*z^2-14344*x^2;
436// as:= [x^3-9977*x^2+15570*x-961]
437// ord:= [x,z]
438// cfactor(f,as,ord)=
439// -1/153600624478379*(-153600624478379*z^2+96784194432*x^2-246879593179080*x+
440// 13599716437688)*(x^2-6909*x-3537)
441//
442// maple:
443//  alias(alpha=RootOf(x^3-9977*x^2+15570*x-961,x));
444//  factor(f,alpha); // faktorisierung in char=0
445// x^2*z^2-6909*x*z^2-3537*z^2-14344*x^2
446
447
448/*
449$Log: not supported by cvs2svn $
450Revision 1.4  2001/06/21 14:57:04  Singular
451*hannes/GP: Factorize, newfactoras, ...
452
453Revision 1.3  2001/06/18 08:44:40  pfister
454* hannes/GP/michael: factory debug, Factorize
455
456Revision 1.2  1997/09/12 07:19:38  Singular
457* hannes/michael: libfac-0.3.0
458
459*/
Note: See TracBrowser for help on using the repository browser.