source: git/Singular/clapsing.cc @ 8cfee1c

spielwiese
Last change on this file since 8cfee1c was ae545a, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: wrong debug code git-svn-id: file:///usr/local/Singular/svn/trunk@5248 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 32.4 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5// $Id: clapsing.cc,v 1.77 2001-02-21 10:17:57 Singular Exp $
6/*
7* ABSTRACT: interface between Singular and factory
8*/
9
10#include "mod2.h"
11#include "omalloc.h"
12#ifdef HAVE_FACTORY
13#define SI_DONT_HAVE_GLOBAL_VARS
14#include "tok.h"
15#include "clapsing.h"
16#include "ipid.h"
17#include "numbers.h"
18#include "subexpr.h"
19#include "ipshell.h"
20#include "ring.h"
21#include <factory.h>
22#include "clapconv.h"
23#ifdef HAVE_LIBFAC_P
24#include <factor.h>
25#endif
26#include "ring.h"
27
28//
29// FACTORY_GCD_TEST: use new gcd instead of old one.  Does not work
30//   without new gcd-implementation which is not publicly available.
31//
32// FACTORY_GCD_STAT: print statistics on polynomials.  Works only
33//   with the file `gcd_stat.cc' and `gcd_stat.h which may be found
34//   in the repository, module `factory-devel'.
35//   Overall statistics may printed using `system("gcdstat");'.
36//
37// FACTORY_GCD_TIMING: accumulate time used for gcd calculations.
38//   Time may be printed (and reset) with `system("gcdtime");'.
39//   For this define, `timing.h' from the factory source directory
40//   has to be copied to the Singular source directory.
41//   Note: for better readability, the macros `TIMING_START()' and
42//   `TIMING_END()' are used in any case.  However, they expand to
43//   nothing if `FACTORY_GCD_TIMING' is off.
44//
45// FACTORY_GCD_DEBOUT: print polynomials involved in gcd calculations.
46//   The polynomials are printed by means of the macros
47//   `FACTORY_*OUT_POLY' which are defined to be empty if
48//   `FACTORY_GCD_DEBOUT' is off.
49//
50// FACTORY_GCD_DEBOUT_PATTERN: print degree patterns of polynomials
51//   involved in gcd calculations.
52//   The patterns are printed by means of the macros
53//   `FACTORY_*OUT_PAT' which are defined to be empty if
54//   `FACTORY_GCD_DEBOUT_PATTERN' is off.
55//
56//   A degree pattern looks like this:
57//
58//   totDeg  size    deg(v1) deg(v2) ...
59//
60//   where "totDeg" means total degree, "size" the number of terms,
61//   and "deg(vi)" is the degree with respect to variable i.
62//   In univariate case, the "deg(vi)" are missing.  For this feature
63//   you need the files `gcd_stat.cc' and `gcd_stat.h'.
64//
65//
66// And here is what the functions print if `FACTORY_GCD_DEBOUT' (1),
67// `FACTORY_GCD_STAT' (2), or `FACTORY_GCD_DEBOUT_PATTERN' (3) is on:
68//
69// sinclap_divide_content:
70// (1) G = <firstCoeff>
71// (3) G#= <firstCoeff, pattern>
72// (1) h = <nextCoeff>
73// (3) h#= <nextCoeff, pattern>
74// (2) gcnt: <statistics on gcd as explained above>
75// (1) g = <intermediateResult>
76// (3) g#= <intermediateResult, pattern>
77// (1) h = <nextCoeff>
78// (3) h#= <nextCoeff, pattern>
79// (2) gcnt: <statistics on gcd as explained above>
80//  ...
81// (1) h = <lastCoeff>
82// (3) h#= <lastCoeff, pattern>
83// (1) g = <finalResult>
84// (3) g#= <finalResult, pattern>
85// (2) gcnt: <statistics on gcd as explained above>
86// (2) cont: <statistics on content as explained above>
87//
88// singclap_alglcm:
89// (1) f = <inputPolyF>
90// (3) f#= <inputPolyF, pattern>
91// (1) g = <inputPolyG>
92// (3) g#= <inputPolyG, pattern>
93// (1) d = <its gcd>
94// (3) d#= <its gcd, pattern>
95// (2) alcm: <statistics as explained above>
96//
97// singclap_algdividecontent:
98// (1) f = <inputPolyF>
99// (3) f#= <inputPolyF, pattern>
100// (1) g = <inputPolyG>
101// (3) g#= <inputPolyG, pattern>
102// (1) d = <its gcd>
103// (3) d#= <its gcd, pattern>
104// (2) acnt: <statistics as explained above>
105//
106
107#ifdef FACTORY_GCD_STAT
108#include "gcd_stat.h"
109#define FACTORY_GCDSTAT( tag, f, g, d ) \
110  printGcdStat( tag, f, g, d )
111#define FACTORY_CONTSTAT( tag, f ) \
112  printContStat( tag, f )
113#else
114#define FACTORY_GCDSTAT( tag, f, g, d )
115#define FACTORY_CONTSTAT( tag, f )
116#endif
117
118#ifdef FACTORY_GCD_TIMING
119#define TIMING
120#include "timing.h"
121TIMING_DEFINE_PRINT( contentTimer );
122TIMING_DEFINE_PRINT( algContentTimer );
123TIMING_DEFINE_PRINT( algLcmTimer );
124#else
125#define TIMING_START( timer )
126#define TIMING_END( timer )
127#endif
128
129#ifdef FACTORY_GCD_DEBOUT
130#include "longalg.h"
131#include "febase.h"
132// napoly f
133#define FACTORY_ALGOUT_POLY( tag, f ) \
134  StringSetS( tag ); \
135  napWrite( f ); \
136  pRINtS(StringAppendS("\n"));
137// CanonicalForm f, represents transcendent extension
138#define FACTORY_CFTROUT_POLY( tag, f ) \
139  { \
140    napoly F=convClapPSingTr( f ); \
141    StringSetS( tag ); \
142    napWrite( F ); \
143    PrintS(StringAppendS("\n")); \
144    napDelete(&F); \
145  }
146// CanonicalForm f, represents algebraic extension
147#define FACTORY_CFAOUT_POLY( tag, f ) \
148  { \
149    napoly F=convClapASingA( f ); \
150    StringSetS( tag ); \
151    napWrite( F ); \
152    PrintS(StringAppendS("\n")); \
153    napDelete(&F); \
154  }
155#else /* ! FACTORY_GCD_DEBOUT */
156#define FACTORY_ALGOUT_POLY( tag, f )
157#define FACTORY_CFTROUT_POLY( tag, f )
158#define FACTORY_CFAOUT_POLY( tag, f )
159#endif /* ! FACTORY_GCD_DEBOUT */
160
161#ifdef FACTORY_GCD_DEBOUT_PATTERN
162// napoly f
163#define FACTORY_ALGOUT_PAT( tag, f ) \
164  if (currRing->minpoly!=NULL) \
165  { \
166    CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z); \
167    Variable a=rootOf(mipo); \
168    printPolyPattern( tag, convSingAClapA( f,a ), rPar( currRing ) ); \
169  } \
170  else \
171  { \
172    printPolyPattern( tag, convSingTrClapP( f ), rPar( currRing ) ); \
173  }
174// CanonicalForm f, represents transcendent extension
175#define FACTORY_CFTROUT_PAT( tag, f ) printPolyPattern( tag, f, rPar( currRing ) )
176// CanonicalForm f, represents algebraic extension
177#define FACTORY_CFAOUT_PAT( tag, f ) printPolyPattern( tag, f, rPar( currRing ) )
178#else /* ! FACTORY_GCD_DEBOUT_PATTERN */
179#define FACTORY_ALGOUT_PAT( tag, f )
180#define FACTORY_CFTROUT_PAT( tag, f )
181#define FACTORY_CFAOUT_PAT( tag, f )
182#endif /* ! FACTORY_GCD_DEBOUT_PATTERN */
183
184// these macors combine both print macros
185#define FACTORY_ALGOUT( tag, f ) \
186  FACTORY_ALGOUT_POLY( tag " = ", f ); \
187  FACTORY_ALGOUT_PAT( tag "#= ", f )
188#define FACTORY_CFTROUT( tag, f ) \
189  FACTORY_CFTROUT_POLY( tag " = ", f ); \
190  FACTORY_CFTROUT_PAT( tag "#= ", f )
191#define FACTORY_CFAOUT( tag, f ) \
192  FACTORY_CFAOUT_POLY( tag " = ", f ); \
193  FACTORY_CFAOUT_PAT( tag "#= ", f )
194
195
196
197
198
199poly singclap_gcd ( poly f, poly g )
200{
201  poly res=NULL;
202
203  if (f!=NULL) pCleardenom(f);
204  if (g!=NULL) pCleardenom(g);
205  else         return pCopy(f); // g==0 => gcd=f (but do a pCleardenom)
206  if (f==NULL) return pCopy(g); // f==0 => gcd=g (but do a pCleardenom)
207
208  // for now there is only the possibility to handle polynomials over
209  // Q and Fp ...
210  if (( nGetChar() == 0 || nGetChar() > 1 )
211  && (currRing->parameter==NULL))
212  {
213    setCharacteristic( nGetChar() );
214    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
215    res=convClapPSingP( gcd( F, G ) );
216    Off(SW_RATIONAL);
217  }
218  // and over Q(a) / Fp(a)
219  else if (( nGetChar()==1 ) /* Q(a) */
220  || (nGetChar() <-1))       /* Fp(a) */
221  {
222    if (nGetChar()==1) setCharacteristic( 0 );
223    else               setCharacteristic( -nGetChar() );
224    if (currRing->minpoly!=NULL)
225    {
226      if ( nGetChar()==1 ) /* Q(a) */
227      {
228        WerrorS( feNotImplemented );
229      }
230      else
231      {
232        CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
233        Variable a=rootOf(mipo);
234        CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
235        res= convClapAPSingAP( gcd( F, G ) );
236      }
237    }
238    else
239    {
240      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
241      res= convClapPSingTrP( gcd( F, G ) );
242    }
243    Off(SW_RATIONAL);
244  }
245  #if 0
246  else if (( nGetChar()>1 )&&(currRing->parameter!=NULL)) /* GF(q) */
247  {
248    int p=rChar(currRing);
249    int n=2;
250    int t=p*p;
251    while (t!=nChar) { t*=p;n++; }
252    setCharacteristic(p,n,'a');
253    CanonicalForm F( convSingGFClapGF( f ) ), G( convSingGFClapGF( g ) );
254    res= convClapGFSingGF( gcd( F, G ) );
255  }
256  #endif
257  else
258    WerrorS( feNotImplemented );
259
260  pDelete(&f);
261  pDelete(&g);
262  pTest(res);
263  return res;
264}
265
266poly singclap_resultant ( poly f, poly g , poly x)
267{
268  int i=pIsPurePower(x);
269  if (i==0)
270  {
271    WerrorS("3rd argument must be a ring variable");
272    return NULL;
273  }
274  if ((f==NULL) || (g==NULL))
275    return NULL;
276  // for now there is only the possibility to handle polynomials over
277  // Q and Fp ...
278  if (( nGetChar() == 0 || nGetChar() > 1 )
279  && (currRing->parameter==NULL))
280  {
281    Variable X(i);
282    setCharacteristic( nGetChar() );
283    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
284    poly res=convClapPSingP( resultant( F, G, X ) );
285    Off(SW_RATIONAL);
286    return res;
287  }
288  // and over Q(a) / Fp(a)
289  else if (( nGetChar()==1 ) /* Q(a) */
290  || (nGetChar() <-1))       /* Fp(a) */
291  {
292    if (nGetChar()==1) setCharacteristic( 0 );
293    else               setCharacteristic( -nGetChar() );
294    poly res;
295    if (currRing->minpoly!=NULL)
296    {
297      Variable X(i);
298      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
299      Variable a=rootOf(mipo);
300      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
301      res= convClapAPSingAP( resultant( F, G, X ) );
302    }
303    else
304    {
305      Variable X(i+rPar(currRing));
306      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
307      res= convClapPSingTrP( resultant( F, G, X ) );
308    }
309    Off(SW_RATIONAL);
310    return res;
311  }
312  else
313    WerrorS( feNotImplemented );
314  return NULL;
315}
316//poly singclap_resultant ( poly f, poly g , poly x)
317//{
318//  int i=pVar(x);
319//  if (i==0)
320//  {
321//    WerrorS("ringvar expected");
322//    return NULL;
323//  }
324//  ideal I=idInit(1,1);
325//
326//  // get the coeffs von f wrt. x:
327//  I->m[0]=pCopy(f);
328//  matrix ffi=mpCoeffs(I,i);
329//  ffi->rank=1;
330//  ffi->ncols=ffi->nrows;
331//  ffi->nrows=1;
332//  ideal fi=(ideal)ffi;
333//
334//  // get the coeffs von g wrt. x:
335//  I->m[0]=pCopy(g);
336//  matrix ggi=mpCoeffs(I,i);
337//  ggi->rank=1;
338//  ggi->ncols=ggi->nrows;
339//  ggi->nrows=1;
340//  ideal gi=(ideal)ggi;
341//
342//  // contruct the matrix:
343//  int fn=IDELEMS(fi); //= deg(f,x)+1
344//  int gn=IDELEMS(gi); //= deg(g,x)+1
345//  matrix m=mpNew(fn+gn-2,fn+gn-2);
346//  if(m==NULL)
347//  {
348//    return NULL;
349//  }
350//
351//  // enter the coeffs into m:
352//  int j;
353//  for(i=0;i<gn-1;i++)
354//  {
355//    for(j=0;j<fn;j++)
356//    {
357//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
358//    }
359//  }
360//  for(i=0;i<fn-1;i++)
361//  {
362//    for(j=0;j<gn;j++)
363//    {
364//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
365//    }
366//  }
367//
368//  poly r=mpDet(m);
369//
370//  idDelete(&fi);
371//  idDelete(&gi);
372//  idDelete((ideal *)&m);
373//  return r;
374//}
375
376lists singclap_extgcd ( poly f, poly g )
377{
378  // for now there is only the possibility to handle univariate
379  // polynomials over
380  // Q and Fp ...
381  poly res=NULL,pa=NULL,pb=NULL;
382  On(SW_SYMMETRIC_FF);
383  if (( nGetChar() == 0 || nGetChar() > 1 )
384  && (currRing->parameter==NULL))
385  {
386    setCharacteristic( nGetChar() );
387    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
388    if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
389    {
390      Off(SW_RATIONAL);
391      WerrorS("not univariate");
392      return NULL;
393    }
394    CanonicalForm Fa,Gb;
395    On(SW_RATIONAL);
396    res=convClapPSingP( extgcd( F, G, Fa, Gb ) );
397    pa=convClapPSingP(Fa);
398    pb=convClapPSingP(Gb);
399    Off(SW_RATIONAL);
400  }
401  // and over Q(a) / Fp(a)
402  else if (( nGetChar()==1 ) /* Q(a) */
403  || (nGetChar() <-1))       /* Fp(a) */
404  {
405    if (nGetChar()==1) setCharacteristic( 0 );
406    else               setCharacteristic( -nGetChar() );
407    CanonicalForm Fa,Gb;
408    if (currRing->minpoly!=NULL)
409    {
410      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
411      Variable a=rootOf(mipo);
412      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
413      if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
414      {
415        WerrorS("not univariate");
416        return NULL;
417      }
418      res= convClapAPSingAP( extgcd( F, G, Fa, Gb ) );
419      pa=convClapAPSingAP(Fa);
420      pb=convClapAPSingAP(Gb);
421    }
422    else
423    {
424      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
425      if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
426      {
427        Off(SW_RATIONAL);
428        WerrorS("not univariate");
429        return NULL;
430      }
431      res= convClapPSingTrP( extgcd( F, G, Fa, Gb ) );
432      pa=convClapPSingTrP(Fa);
433      pb=convClapPSingTrP(Gb);
434    }
435    Off(SW_RATIONAL);
436  }
437  else
438  {
439    WerrorS( feNotImplemented );
440    return NULL;
441  }
442  lists L=(lists)omAllocBin(slists_bin);
443  L->Init(3);
444  L->m[0].rtyp=POLY_CMD;
445  L->m[0].data=(void *)res;
446  L->m[1].rtyp=POLY_CMD;
447  L->m[1].data=(void *)pa;
448  L->m[2].rtyp=POLY_CMD;
449  L->m[2].data=(void *)pb;
450  return L;
451}
452
453poly singclap_pdivide ( poly f, poly g )
454{
455  // for now there is only the possibility to handle polynomials over
456  // Q and Fp ...
457  poly res=NULL;
458  On(SW_RATIONAL);
459  if (( nGetChar() == 0 || nGetChar() > 1 )
460  && (currRing->parameter==NULL))
461  {
462    setCharacteristic( nGetChar() );
463    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
464    res = convClapPSingP( F / G );
465  }
466  // and over Q(a) / Fp(a)
467  else if (( nGetChar()==1 ) /* Q(a) */
468  || (nGetChar() <-1))       /* Fp(a) */
469  {
470    if (nGetChar()==1) setCharacteristic( 0 );
471    else               setCharacteristic( -nGetChar() );
472    if (currRing->minpoly!=NULL)
473    {
474      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
475      Variable a=rootOf(mipo);
476      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
477      res= convClapAPSingAP(  F / G  );
478    }
479    else
480    {
481      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
482      res= convClapPSingTrP(  F / G  );
483    }
484  }
485  else
486    WerrorS( feNotImplemented );
487  Off(SW_RATIONAL);
488  return res;
489}
490
491void singclap_divide_content ( poly f )
492{
493  if ( f==NULL )
494  {
495    return;
496  }
497  else  if ( pNext( f ) == NULL )
498  {
499    pSetCoeff( f, nInit( 1 ) );
500    return;
501  }
502  else
503  {
504    if ( nGetChar() == 1 )
505      setCharacteristic( 0 );
506    else  if ( nGetChar() == -1 )
507      return; /* not implemented for R */
508    else  if ( nGetChar() < 0 )
509      setCharacteristic( -nGetChar() );
510    else if (currRing->parameter==NULL) /* not GF(q) */
511      setCharacteristic( nGetChar() );
512    else
513      return; /* not implemented*/
514
515    CFList L;
516    CanonicalForm g, h;
517    poly p = pNext(f);
518
519    // first attemp: find 2 smallest g:
520
521    number g1=pGetCoeff(f);
522    number g2=pGetCoeff(p); // p==pNext(f);
523    pIter(p);
524    int sz1=nSize(g1);
525    int sz2=nSize(g2);
526    if (sz1>sz2)
527    {
528      number gg=g1;
529      g1=g2; g2=gg;
530      int sz=sz1;
531      sz1=sz2; sz2=sz;
532    }
533    while (p!=NULL)
534    {
535      int n_sz=nSize(pGetCoeff(p));
536      if (n_sz<sz1)
537      {
538        sz2=sz1;
539        g2=g1;
540        g1=pGetCoeff(p);
541        sz1=n_sz;
542        if (sz1<=3) break;
543      }
544      else if(n_sz<sz2)
545      {
546        sz2=n_sz;
547        g2=pGetCoeff(p);
548        sz2=n_sz;
549      }
550      pIter(p);
551    }
552    FACTORY_ALGOUT( "G", ((lnumber)g1)->z );
553    g = convSingTrClapP( ((lnumber)g1)->z );
554    g = gcd( g, convSingTrClapP( ((lnumber)g2)->z ));
555
556    // second run: gcd's
557
558    p = f;
559    TIMING_START( contentTimer );
560    while ( (p != NULL) && (g != 1)  && ( g != 0))
561    {
562      FACTORY_ALGOUT( "h", (((lnumber)pGetCoeff(p))->z) );
563      h = convSingTrClapP( ((lnumber)pGetCoeff(p))->z );
564      pIter( p );
565#ifdef FACTORY_GCD_STAT
566      // save g
567      CanonicalForm gOld = g;
568#endif
569
570#ifdef FACTORY_GCD_TEST
571      g = CFPrimitiveGcdUtil::gcd( g, h );
572#else
573      g = gcd( g, h );
574#endif
575
576      FACTORY_GCDSTAT( "gcnt:", gOld, h, g );
577      FACTORY_CFTROUT( "g", g );
578      L.append( h );
579    }
580    TIMING_END( contentTimer );
581    FACTORY_CONTSTAT( "cont:", g );
582    if (( g == 1 ) || (g == 0))
583    {
584      // pTest(f);
585      return;
586    }
587    else
588    {
589      CFListIterator i;
590      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
591      {
592        lnumber c=(lnumber)pGetCoeff(p);
593        napDelete(&c->z);
594        c->z=convClapPSingTr( i.getItem() / g );
595        //nTest((number)c);
596        //#ifdef LDEBUG
597        //number cn=(number)c;
598        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
599        //nWrite(cn);PrintS(StringAppend("\n"));
600        //#endif
601      }
602    }
603    // pTest(f);
604  }
605}
606
607static int primepower(int c)
608{
609  int p=1;
610  int cc=c;
611  while(cc!= rInternalChar(currRing)) { cc*=c; p++; }
612  return p;
613}
614
615ideal singclap_factorize ( poly f, intvec ** v , int with_exps)
616{
617  // with_exps: 1 return only true factors
618  //            2 return true factors and exponents
619  //            0 return factors and exponents
620
621  ideal res=NULL;
622  if (f==NULL)
623  {
624    res=idInit(1,1);
625    if (with_exps!=1)
626    {
627      (*v)=new intvec(1);
628      (**v)[0]=1;
629    }
630    return res;
631  }
632  Off(SW_RATIONAL);
633  On(SW_SYMMETRIC_FF);
634  CFFList L;
635  number N=NULL;
636  number NN=NULL;
637
638  if (rField_is_Q() || rField_is_Zp())
639  {
640    setCharacteristic( nGetChar() );
641    if (nGetChar()==0) /* Q */
642    {
643      //if (f!=NULL) // already tested at start of routine
644      {
645        number n0=nCopy(pGetCoeff(f));
646        if (with_exps==0)
647          N=nCopy(n0);
648        pCleardenom(f);
649        NN=nDiv(n0,pGetCoeff(f));
650        nDelete(&n0);
651        if (with_exps==0)
652        {
653          nDelete(&N);
654          N=nCopy(NN);
655        }
656      }
657    }
658    CanonicalForm F( convSingPClapP( f ) );
659    if (nGetChar()==0) /* Q */
660    {
661      L = factorize( F );
662    }
663    else /* Fp */
664    {
665#ifdef HAVE_LIBFAC_P
666      L = Factorize( F );
667#else
668      goto notImpl;
669#endif
670    }
671  }
672  #if 0
673  else if (rField_is_GF())
674  {
675    int c=rChar(currRing);
676    setCharacteristic( c, primepower(c) );
677    CanonicalForm F( convSingGFClapGF( f ) );
678    if (F.isUnivariate())
679    {
680      L = factorize( F );
681    }
682    else
683    {
684      goto notImpl;
685    }
686  }
687  #endif
688  // and over Q(a) / Fp(a)
689  else if (rField_is_Extension())
690  {
691    if (nGetChar()==1) setCharacteristic( 0 );
692    else               setCharacteristic( -nGetChar() );
693    if ((currRing->minpoly!=NULL)
694    && (nGetChar()<(-1)))
695    {
696      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
697      Variable a=rootOf(mipo);
698      CanonicalForm F( convSingAPClapAP( f,a ) );
699      L.insert(F);
700      if (F.isUnivariate())
701      {
702        L = factorize( F, a );
703      }
704      else
705      {
706        WarnS("complete factorization only for univariate polynomials");
707        CanonicalForm G( convSingTrPClapP( f ) );
708        if (nGetChar()==1) /* Q(a) */
709        {
710          L = factorize( G );
711        }
712        else
713        {
714#ifdef HAVE_LIBFAC_P
715          L = Factorize( G );
716#else
717          goto notImpl;
718#endif
719        }
720      }
721    }
722    else
723    {
724      CanonicalForm F( convSingTrPClapP( f ) );
725      if ((rField_is_Q_a())&&(currRing->minpoly!=NULL))
726      {
727        WarnS("factorization may be incomplete");
728        L = factorize( F );
729      }
730      else /* Fp(a) */
731      {
732#ifdef HAVE_LIBFAC_P
733        L = Factorize( F );
734#else
735        goto notImpl;
736#endif
737      }
738    }
739  }
740  else
741  {
742    goto notImpl;
743  }
744  {
745    // the first factor should be a constant
746    if ( ! L.getFirst().factor().inCoeffDomain() )
747      L.insert(CFFactor(1,1));
748    // convert into ideal
749    int n = L.length();
750    CFFListIterator J=L;
751    int j=0;
752    if (with_exps!=1)
753    {
754      if ((with_exps==2)&&(n>1))
755      {
756        n--;
757        J++;
758      }
759      *v = new intvec( n );
760    }
761    res = idInit( n ,1);
762    for ( ; J.hasItem(); J++, j++ )
763    {
764      if (with_exps!=1) (**v)[j] = J.getItem().exp();
765      if (rField_is_Zp() || rField_is_Q())           /* Q, Fp */
766        res->m[j] = convClapPSingP( J.getItem().factor() );
767      #if 0
768      else if (rField_is_GF())
769        res->m[j] = convClapGFSingGF( J.getItem().factor() );
770      #endif
771      else if (rField_is_Extension())     /* Q(a), Fp(a) */
772      {
773        if (currRing->minpoly==NULL)
774          res->m[j] = convClapPSingTrP( J.getItem().factor() );
775        else
776          res->m[j] = convClapAPSingAP( J.getItem().factor() );
777      }
778    }
779    if (N!=NULL)
780    {
781      pMult_nn(res->m[0],N);
782      nDelete(&N);
783      N=NULL;
784    }
785    // delete constants
786    if ((with_exps!=0) && (res!=NULL))
787    {
788      int i=IDELEMS(res)-1;
789      int j=0;
790      for(;i>=0;i--)
791      {
792        if ((res->m[i]!=NULL) && (pNext(res->m[i])==NULL) && (pIsConstant(res->m[i])))
793        {
794          pDelete(&(res->m[i]));
795          if ((v!=NULL) && ((*v)!=NULL))
796            (**v)[i]=0;
797          j++;
798        }
799      }
800      if (j>0)
801      {
802        idSkipZeroes(res);
803        if ((v!=NULL) && ((*v)!=NULL))
804        {
805          intvec *w=*v;
806          *v = new intvec( max(n-j,1) );
807          for (i=0,j=0;i<w->length();i++)
808          {
809            if((*w)[i]!=0)
810            {
811              (**v)[j]=(*w)[i]; j++;
812            }
813          }
814          delete w;
815        }
816      }
817      if (res->m[0]==NULL)
818      {
819        res->m[0]=pOne();
820      }
821    }
822  }
823notImpl:
824  if (res==NULL)
825    WerrorS( feNotImplemented );
826  if (NN!=NULL)
827  {
828    pMult_nn(f,NN);
829    nDelete(&NN);
830  }
831  if (N!=NULL)
832  {
833    nDelete(&N);
834  }
835  return res;
836}
837
838matrix singclap_irrCharSeries ( ideal I)
839{
840#ifdef HAVE_LIBFAC_P
841  // for now there is only the possibility to handle polynomials over
842  // Q and Fp ...
843  matrix res=NULL;
844  int i;
845  Off(SW_RATIONAL);
846  On(SW_SYMMETRIC_FF);
847  CFList L;
848  ListCFList LL;
849  if (((nGetChar() == 0) || (nGetChar() > 1) )
850  && (currRing->parameter==NULL))
851  {
852    setCharacteristic( nGetChar() );
853    for(i=0;i<IDELEMS(I);i++)
854    {
855      poly p=I->m[i];
856      if (p!=NULL)
857      {
858        p=pCopy(p);
859        pCleardenom(p);
860        L.append(convSingPClapP(p));
861      }
862    }
863  }
864  // and over Q(a) / Fp(a)
865  else if (( nGetChar()==1 ) /* Q(a) */
866  || (nGetChar() <-1))       /* Fp(a) */
867  {
868    if (nGetChar()==1) setCharacteristic( 0 );
869    else               setCharacteristic( -nGetChar() );
870    for(i=0;i<IDELEMS(I);i++)
871    {
872      poly p=I->m[i];
873      if (p!=NULL)
874      {
875        p=pCopy(p);
876        pCleardenom(p);
877        L.append(convSingTrPClapP(p));
878      }
879    }
880  }
881  else
882  {
883    WerrorS( feNotImplemented );
884    return res;
885  }
886
887  LL=IrrCharSeries(L);
888  int m= LL.length(); // Anzahl Zeilen
889  int n=0;
890  ListIterator<CFList> LLi;
891  CFListIterator Li;
892  for ( LLi = LL; LLi.hasItem(); LLi++ )
893  {
894    n = max(LLi.getItem().length(),n);
895  }
896  if ((m==0) || (n==0))
897  {
898    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
899      m,n,IDELEMS(I)+1,LL.length());
900    iiWriteMatrix((matrix)I,"I",2,0);
901    m=max(m,1);
902    n=max(n,1);
903  }
904  res=mpNew(m,n);
905  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
906  {
907    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
908    {
909      if ( (nGetChar() == 0) || (nGetChar() > 1) )
910        MATELEM(res,m,n)=convClapPSingP(Li.getItem());
911      else
912        MATELEM(res,m,n)=convClapPSingTrP(Li.getItem());
913    }
914  }
915  Off(SW_RATIONAL);
916  return res;
917#else
918  return NULL;
919#endif
920}
921
922char* singclap_neworder ( ideal I)
923{
924#ifdef HAVE_LIBFAC_P
925  int i;
926  Off(SW_RATIONAL);
927  On(SW_SYMMETRIC_FF);
928  CFList L;
929  if (((nGetChar() == 0) || (nGetChar() > 1) )
930  && (currRing->parameter==NULL))
931  {
932    setCharacteristic( nGetChar() );
933    for(i=0;i<IDELEMS(I);i++)
934    {
935      L.append(convSingPClapP(I->m[i]));
936    }
937  }
938  // and over Q(a) / Fp(a)
939  else if (( nGetChar()==1 ) /* Q(a) */
940  || (nGetChar() <-1))       /* Fp(a) */
941  {
942    if (nGetChar()==1) setCharacteristic( 0 );
943    else               setCharacteristic( -nGetChar() );
944    for(i=0;i<IDELEMS(I);i++)
945    {
946      L.append(convSingTrPClapP(I->m[i]));
947    }
948  }
949  else
950  {
951    WerrorS( feNotImplemented );
952    return NULL;
953  }
954
955  List<int> IL=neworderint(L);
956  ListIterator<int> Li;
957  StringSetS("");
958  Li = IL;
959  int offs=rPar(currRing);
960  int* mark=(int*)omAlloc0((pVariables+offs)*sizeof(int));
961  int cnt=pVariables+offs;
962  loop
963  {
964    i=Li.getItem()-1;
965    mark[i]=1;
966    if (i<offs)
967    {
968      StringAppendS(currRing->parameter[i]);
969    }
970    else
971    {
972      StringAppendS(currRing->names[i-offs]);
973    }
974    Li++;
975    cnt--;
976    if(cnt==0) break;
977    StringAppendS(",");
978    if(! Li.hasItem()) break;
979  }
980  for(i=0;i<pVariables+offs;i++)
981  {
982    if(mark[i]==0)
983    {
984      if (i<offs)
985      {
986        StringAppendS(currRing->parameter[i]);
987      }
988      else
989      {
990        StringAppendS(currRing->names[i-offs]);
991      }
992      cnt--;
993      if(cnt==0) break;
994      StringAppendS(",");
995    }
996  }
997  return omStrDup(StringAppendS(""));
998#else
999  return NULL;
1000#endif
1001}
1002
1003BOOLEAN singclap_isSqrFree(poly f)
1004{
1005  BOOLEAN b=FALSE;
1006  Off(SW_RATIONAL);
1007  //  Q / Fp
1008  if (((nGetChar() == 0) || (nGetChar() > 1) )
1009  &&(currRing->parameter==NULL))
1010  {
1011    setCharacteristic( nGetChar() );
1012    CanonicalForm F( convSingPClapP( f ) );
1013    if((nGetChar()>1)&&(!F.isUnivariate()))
1014      goto err;
1015    b=(BOOLEAN)isSqrFree(F);
1016  }
1017  // and over Q(a) / Fp(a)
1018  else if (( nGetChar()==1 ) /* Q(a) */
1019  || (nGetChar() <-1))       /* Fp(a) */
1020  {
1021    if (nGetChar()==1) setCharacteristic( 0 );
1022    else               setCharacteristic( -nGetChar() );
1023    //if (currRing->minpoly!=NULL)
1024    //{
1025    //  CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1026    //  Variable a=rootOf(mipo);
1027    //  CanonicalForm F( convSingAPClapAP( f,a ) );
1028    //  ...
1029    //}
1030    //else
1031    {
1032      CanonicalForm F( convSingTrPClapP( f ) );
1033      b=(BOOLEAN)isSqrFree(F);
1034    }
1035    Off(SW_RATIONAL);
1036  }
1037  else
1038  {
1039err:
1040    WerrorS( feNotImplemented );
1041  }
1042  return b;
1043}
1044
1045poly singclap_det( const matrix m )
1046{
1047  int r=m->rows();
1048  if (r!=m->cols())
1049  {
1050    Werror("det of %d x %d matrix",r,m->cols());
1051    return NULL;
1052  }
1053  poly res=NULL;
1054  if (( nGetChar() == 0 || nGetChar() > 1 )
1055  && (currRing->parameter==NULL))
1056  {
1057    setCharacteristic( nGetChar() );
1058    CFMatrix M(r,r);
1059    int i,j;
1060    for(i=r;i>0;i--)
1061    {
1062      for(j=r;j>0;j--)
1063      {
1064        M(i,j)=convSingPClapP(MATELEM(m,i,j));
1065      }
1066    }
1067    res= convClapPSingP( determinant(M,r) ) ;
1068  }
1069  // and over Q(a) / Fp(a)
1070  else if (( nGetChar()==1 ) /* Q(a) */
1071  || (nGetChar() <-1))       /* Fp(a) */
1072  {
1073    if (nGetChar()==1) setCharacteristic( 0 );
1074    else               setCharacteristic( -nGetChar() );
1075    CFMatrix M(r,r);
1076    poly res;
1077    if (currRing->minpoly!=NULL)
1078    {
1079      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1080      Variable a=rootOf(mipo);
1081      int i,j;
1082      for(i=r;i>0;i--)
1083      {
1084        for(j=r;j>0;j--)
1085        {
1086          M(i,j)=convSingAPClapAP(MATELEM(m,i,j),a);
1087        }
1088      }
1089      res= convClapAPSingAP( determinant(M,r) ) ;
1090    }
1091    else
1092    {
1093      int i,j;
1094      for(i=r;i>0;i--)
1095      {
1096        for(j=r;j>0;j--)
1097        {
1098          M(i,j)=convSingTrPClapP(MATELEM(m,i,j));
1099        }
1100      }
1101      res= convClapPSingTrP( determinant(M,r) );
1102    }
1103  }
1104  else
1105    WerrorS( feNotImplemented );
1106  Off(SW_RATIONAL);
1107  return res;
1108}
1109
1110int singclap_det_i( intvec * m )
1111{
1112  setCharacteristic( 0 );
1113  CFMatrix M(m->rows(),m->cols());
1114  int i,j;
1115  for(i=m->rows();i>0;i--)
1116  {
1117    for(j=m->cols();j>0;j--)
1118    {
1119      M(i,j)=IMATELEM(*m,i,j);
1120    }
1121  }
1122  int res= convClapISingI( determinant(M,m->rows())) ;
1123  Off(SW_RATIONAL);
1124  return res;
1125}
1126/*==============================================================*/
1127/* interpreter interface : */
1128BOOLEAN jjGCD_P(leftv res, leftv u, leftv v)
1129{
1130  res->data=(void *)singclap_gcd((poly)(u->CopyD(POLY_CMD)),
1131                                 (poly)(v->CopyD(POLY_CMD)));
1132  return FALSE;
1133}
1134
1135BOOLEAN jjFAC_P(leftv res, leftv u)
1136{
1137  intvec *v=NULL;
1138  ideal f=singclap_factorize((poly)(u->Data()), &v, 0);
1139  if (f==NULL) return TRUE;
1140  ivTest(v);
1141  lists l=(lists)omAllocBin(slists_bin);
1142  l->Init(2);
1143  l->m[0].rtyp=IDEAL_CMD;
1144  l->m[0].data=(void *)f;
1145  l->m[1].rtyp=INTVEC_CMD;
1146  l->m[1].data=(void *)v;
1147  res->data=(void *)l;
1148  return FALSE;
1149}
1150
1151BOOLEAN jjSQR_FREE_DEC(leftv res, leftv u,leftv dummy)
1152{
1153  intvec *v=NULL;
1154  int sw=(int)dummy->Data();
1155  ideal f=singclap_factorize((poly)(u->Data()), &v, sw);
1156  if (f==NULL)
1157    return TRUE;
1158  switch(sw)
1159  {
1160    case 0:
1161    case 2:
1162    {
1163      lists l=(lists)omAllocBin(slists_bin);
1164      l->Init(2);
1165      l->m[0].rtyp=IDEAL_CMD;
1166      l->m[0].data=(void *)f;
1167      l->m[1].rtyp=INTVEC_CMD;
1168      l->m[1].data=(void *)v;
1169      res->data=(void *)l;
1170      res->rtyp=LIST_CMD;
1171      return FALSE;
1172    }
1173    case 1:
1174      res->data=(void *)f;
1175      return FALSE;
1176    case 3:
1177      {
1178        poly p=f->m[0];
1179        int i=IDELEMS(f);
1180        f->m[0]=NULL;
1181        while(i>1)
1182        {
1183          i--;
1184          p=pMult(p,f->m[i]);
1185          f->m[i]=NULL;
1186        }
1187        res->data=(void *)p;
1188        res->rtyp=POLY_CMD;
1189      }
1190      return FALSE;
1191  }
1192  WerrorS("invalid switch");
1193  return TRUE;
1194}
1195
1196#if 0
1197BOOLEAN jjIS_SQR_FREE(leftv res, leftv u)
1198{
1199  BOOLEAN b=singclap_factorize((poly)(u->Data()), &v, 0);
1200  res->data=(void *)b;
1201}
1202#endif
1203
1204BOOLEAN jjEXTGCD_P(leftv res, leftv u, leftv v)
1205{
1206  res->data=singclap_extgcd((poly)u->Data(),(poly)v->Data());
1207  return (res->data==NULL);
1208}
1209BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w)
1210{
1211  res->data=singclap_resultant((poly)u->Data(),(poly)v->Data(), (poly)w->Data());
1212  return errorreported;
1213}
1214BOOLEAN jjCHARSERIES(leftv res, leftv u)
1215{
1216  res->data=singclap_irrCharSeries((ideal)u->Data());
1217  return (res->data==NULL);
1218}
1219
1220napoly singclap_alglcm ( napoly f, napoly g )
1221{
1222 FACTORY_ALGOUT( "f", f );
1223 FACTORY_ALGOUT( "g", g );
1224
1225 // over Q(a) / Fp(a)
1226 if (nGetChar()==1) setCharacteristic( 0 );
1227 else               setCharacteristic( -nGetChar() );
1228 napoly res;
1229
1230 if (currRing->minpoly!=NULL)
1231 {
1232   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1233   Variable a=rootOf(mipo);
1234   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1235   CanonicalForm GCD;
1236
1237   TIMING_START( algLcmTimer );
1238   // calculate gcd
1239#ifdef FACTORY_GCD_TEST
1240   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1241#else
1242   GCD = gcd( F, G );
1243#endif
1244   TIMING_END( algLcmTimer );
1245
1246   FACTORY_CFAOUT( "d", GCD );
1247   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1248
1249   // calculate lcm
1250   res= convClapASingA( (F/GCD)*G );
1251 }
1252 else
1253 {
1254   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1255   CanonicalForm GCD;
1256   TIMING_START( algLcmTimer );
1257   // calculate gcd
1258#ifdef FACTORY_GCD_TEST
1259   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1260#else
1261   GCD = gcd( F, G );
1262#endif
1263   TIMING_END( algLcmTimer );
1264
1265   FACTORY_CFTROUT( "d", GCD );
1266   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1267
1268   // calculate lcm
1269   res= convClapPSingTr( (F/GCD)*G );
1270 }
1271
1272 Off(SW_RATIONAL);
1273 return res;
1274}
1275
1276void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
1277{
1278 FACTORY_ALGOUT( "f", f );
1279 FACTORY_ALGOUT( "g", g );
1280
1281 // over Q(a) / Fp(a)
1282 if (nGetChar()==1) setCharacteristic( 0 );
1283 else               setCharacteristic( -nGetChar() );
1284 ff=gg=NULL;
1285 On(SW_RATIONAL);
1286
1287 if (currRing->minpoly!=NULL)
1288 {
1289   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1290   Variable a=rootOf(mipo);
1291   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1292   CanonicalForm GCD;
1293
1294   TIMING_START( algContentTimer );
1295#ifdef FACTORY_GCD_TEST
1296   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1297#else
1298   GCD=gcd( F, G );
1299#endif
1300   TIMING_END( algContentTimer );
1301
1302   FACTORY_CFAOUT( "d", GCD );
1303   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1304
1305   if ((GCD!=1) && (GCD!=0))
1306   {
1307     ff= convClapASingA( F/ GCD );
1308     gg= convClapASingA( G/ GCD );
1309   }
1310 }
1311 else
1312 {
1313   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1314   CanonicalForm GCD;
1315
1316   TIMING_START( algContentTimer );
1317#ifdef FACTORY_GCD_TEST
1318   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1319#else
1320   GCD=gcd( F, G );
1321#endif
1322   TIMING_END( algContentTimer );
1323
1324   FACTORY_CFTROUT( "d", GCD );
1325   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1326
1327   if ((GCD!=1) && (GCD!=0))
1328   {
1329     ff= convClapPSingTr( F/ GCD );
1330     gg= convClapPSingTr( G/ GCD );
1331   }
1332 }
1333
1334 Off(SW_RATIONAL);
1335}
1336
1337lists singclap_chineseRemainder(lists x, lists q)
1338{
1339  //assume(x->nr == q->nr);
1340  //assume(x->nr >= 0);
1341  int n=x->nr+1;
1342  if ((x->nr<0) || (x->nr!=q->nr))
1343  {
1344    WerrorS("list are empty or not of equal length");
1345    return NULL;
1346  }
1347  lists res=(lists)omAlloc0Bin(slists_bin);
1348  CFArray X(1,n), Q(1,n);
1349  int i;
1350  for(i=0; i<n; i++)
1351  {
1352    if (x->m[i-1].Typ()==INT_CMD)
1353    {
1354      X[i]=(int)x->m[i-1].Data();
1355    }
1356    else if (x->m[i-1].Typ()==NUMBER_CMD)
1357    {
1358      number N=(number)x->m[i-1].Data();
1359      X[i]=convSingNClapN(N);
1360    }
1361    else
1362    {
1363      WerrorS("illegal type in chineseRemainder");
1364      omFreeBin(res,slists_bin);
1365      return NULL;
1366    }
1367    if (q->m[i-1].Typ()==INT_CMD)
1368    {
1369      Q[i]=(int)q->m[i-1].Data();
1370    }
1371    else if (q->m[i-1].Typ()==NUMBER_CMD)
1372    {
1373      number N=(number)x->m[i-1].Data();
1374      Q[i]=convSingNClapN(N);
1375    }
1376    else
1377    {
1378      WerrorS("illegal type in chineseRemainder");
1379      omFreeBin(res,slists_bin);
1380      return NULL;
1381    }
1382  }
1383  CanonicalForm r, prod;
1384  chineseRemainder( X, Q, r, prod );
1385  res->Init(2);
1386  res->m[0].rtyp=NUMBER_CMD;
1387  res->m[1].rtyp=NUMBER_CMD;
1388  res->m[0].data=(char *)convClapNSingN( r );
1389  res->m[1].data=(char *)convClapNSingN( prod );
1390  return res;
1391}
1392#endif
Note: See TracBrowser for help on using the repository browser.