source: git/Singular/clapsing.cc @ fc83e4

fieker-DuValspielwiese
Last change on this file since fc83e4 was fc83e4, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* bug fixes for tailRing git-svn-id: file:///usr/local/Singular/svn/trunk@4705 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 32.5 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5// $Id: clapsing.cc,v 1.73 2000-11-08 15:34:48 obachman 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// alg 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    alg 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    alg 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// alg 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        #ifdef LDEBUG
595        number nt=(number)omAlloc0Bin(rnumber_bin);
596        lnumber nnt=(lnumber)nt;
597        nnt->z=convClapPSingTr( i.getItem());
598        nTest(nt);
599        #endif
600        c->z=convClapPSingTr( i.getItem() / g );
601        //nTest((number)c);
602        //#ifdef LDEBUG
603        //number cn=(number)c;
604        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
605        //nWrite(cn);PrintS(StringAppend("\n"));
606        //#endif
607      }
608    }
609    // pTest(f);
610  }
611}
612
613static int primepower(int c)
614{
615  int p=1;
616  int cc=c;
617  while(cc!= rInternalChar(currRing)) { cc*=c; p++; }
618  return p;
619}
620
621ideal singclap_factorize ( poly f, intvec ** v , int with_exps)
622{
623  // with_exps: 1 return only true factors
624  //            2 return true factors and exponents
625  //            0 return factors and exponents
626
627  ideal res=NULL;
628  if (f==NULL)
629  {
630    res=idInit(1,1);
631    if (with_exps!=1)
632    {
633      (*v)=new intvec(1);
634      (**v)[0]=1;
635    }
636    return res;
637  }
638  Off(SW_RATIONAL);
639  On(SW_SYMMETRIC_FF);
640  CFFList L;
641  number N=NULL;
642  number NN=NULL;
643
644  if (rField_is_Q() || rField_is_Zp())
645  {
646    setCharacteristic( nGetChar() );
647    if (nGetChar()==0) /* Q */
648    {
649      //if (f!=NULL) // already tested at start of routine
650      {
651        number n0=nCopy(pGetCoeff(f));
652        if (with_exps==0)
653          N=nCopy(n0);
654        pCleardenom(f);
655        NN=nDiv(n0,pGetCoeff(f));
656        nDelete(&n0);
657        if (with_exps==0)
658        {
659          nDelete(&N);
660          N=nCopy(NN);
661        }
662      }
663    }
664    CanonicalForm F( convSingPClapP( f ) );
665    if (nGetChar()==0) /* Q */
666    {
667      L = factorize( F );
668    }
669    else /* Fp */
670    {
671#ifdef HAVE_LIBFAC_P
672      L = Factorize( F );
673#else
674      goto notImpl;
675#endif
676    }
677  }
678  #if 0
679  else if (rField_is_GF())
680  {
681    int c=rChar(currRing);
682    setCharacteristic( c, primepower(c) );
683    CanonicalForm F( convSingGFClapGF( f ) );
684    if (F.isUnivariate())
685    {
686      L = factorize( F );
687    }
688    else
689    {
690      goto notImpl;
691    }
692  }
693  #endif
694  // and over Q(a) / Fp(a)
695  else if (rField_is_Extension())
696  {
697    if (nGetChar()==1) setCharacteristic( 0 );
698    else               setCharacteristic( -nGetChar() );
699    if ((currRing->minpoly!=NULL)
700    && (nGetChar()<(-1)))
701    {
702      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
703      Variable a=rootOf(mipo);
704      CanonicalForm F( convSingAPClapAP( f,a ) );
705      L.insert(F);
706      if (F.isUnivariate())
707      {
708        L = factorize( F, a );
709      }
710      else
711      {
712        WarnS("complete factorization only for univariate polynomials");
713        CanonicalForm G( convSingTrPClapP( f ) );
714        if (nGetChar()==1) /* Q(a) */
715        {
716          L = factorize( G );
717        }
718        else
719        {
720#ifdef HAVE_LIBFAC_P
721          L = Factorize( G );
722#else
723          goto notImpl;
724#endif
725        }
726      }
727    }
728    else
729    {
730      CanonicalForm F( convSingTrPClapP( f ) );
731      if ((rField_is_Q_a())&&(currRing->minpoly!=NULL))
732      {
733        WarnS("factorization may be incomplete");
734        L = factorize( F );
735      }
736      else /* Fp(a) */
737      {
738#ifdef HAVE_LIBFAC_P
739        L = Factorize( F );
740#else
741        goto notImpl;
742#endif
743      }
744    }
745  }
746  else
747  {
748    goto notImpl;
749  }
750  {
751    // the first factor should be a constant
752    if ( ! L.getFirst().factor().inCoeffDomain() )
753      L.insert(CFFactor(1,1));
754    // convert into ideal
755    int n = L.length();
756    CFFListIterator J=L;
757    int j=0;
758    if (with_exps!=1)
759    {
760      if ((with_exps==2)&&(n>1))
761      {
762        n--;
763        J++;
764      }
765      *v = new intvec( n );
766    }
767    res = idInit( n ,1);
768    for ( ; J.hasItem(); J++, j++ )
769    {
770      if (with_exps!=1) (**v)[j] = J.getItem().exp();
771      if (rField_is_Zp() || rField_is_Q())           /* Q, Fp */
772        res->m[j] = convClapPSingP( J.getItem().factor() );
773      #if 0
774      else if (rField_is_GF())
775        res->m[j] = convClapGFSingGF( J.getItem().factor() );
776      #endif
777      else if (rField_is_Extension())     /* Q(a), Fp(a) */
778      {
779        if (currRing->minpoly==NULL)
780          res->m[j] = convClapPSingTrP( J.getItem().factor() );
781        else
782          res->m[j] = convClapAPSingAP( J.getItem().factor() );
783      }
784    }
785    if (N!=NULL)
786    {
787      pMult_nn(res->m[0],N);
788      nDelete(&N);
789      N=NULL;
790    }
791    // delete constants
792    if ((with_exps!=0) && (res!=NULL))
793    {
794      int i=IDELEMS(res)-1;
795      int j=0;
796      for(;i>=0;i--)
797      {
798        if ((res->m[i]!=NULL) && (pNext(res->m[i])==NULL) && (pIsConstant(res->m[i])))
799        {
800          pDelete(&(res->m[i]));
801          if ((v!=NULL) && ((*v)!=NULL))
802            (**v)[i]=0;
803          j++;
804        }
805      }
806      if (j>0)
807      {
808        idSkipZeroes(res);
809        if ((v!=NULL) && ((*v)!=NULL))
810        {
811          intvec *w=*v;
812          *v = new intvec( max(n-j,1) );
813          for (i=0,j=0;i<w->length();i++)
814          {
815            if((*w)[i]!=0)
816            {
817              (**v)[j]=(*w)[i]; j++;
818            }
819          }
820          delete w;
821        }
822      }
823      if (res->m[0]==NULL)
824      {
825        res->m[0]=pOne();
826      }
827    }
828  }
829notImpl:
830  if (res==NULL)
831    WerrorS( feNotImplemented );
832  if (NN!=NULL)
833  {
834    pMult_nn(f,NN);
835    nDelete(&NN);
836  }
837  if (N!=NULL)
838  {
839    nDelete(&N);
840  }
841  return res;
842}
843
844matrix singclap_irrCharSeries ( ideal I)
845{
846#ifdef HAVE_LIBFAC_P
847  // for now there is only the possibility to handle polynomials over
848  // Q and Fp ...
849  matrix res=NULL;
850  int i;
851  Off(SW_RATIONAL);
852  On(SW_SYMMETRIC_FF);
853  CFList L;
854  ListCFList LL;
855  if (((nGetChar() == 0) || (nGetChar() > 1) )
856  && (currRing->parameter==NULL))
857  {
858    setCharacteristic( nGetChar() );
859    for(i=0;i<IDELEMS(I);i++)
860    {
861      poly p=I->m[i];
862      if (p!=NULL)
863      {
864        p=pCopy(p);
865        pCleardenom(p);
866        L.append(convSingPClapP(p));
867      }
868    }
869  }
870  // and over Q(a) / Fp(a)
871  else if (( nGetChar()==1 ) /* Q(a) */
872  || (nGetChar() <-1))       /* Fp(a) */
873  {
874    if (nGetChar()==1) setCharacteristic( 0 );
875    else               setCharacteristic( -nGetChar() );
876    for(i=0;i<IDELEMS(I);i++)
877    {
878      poly p=I->m[i];
879      if (p!=NULL)
880      {
881        p=pCopy(p);
882        pCleardenom(p);
883        L.append(convSingTrPClapP(p));
884      }
885    }
886  }
887  else
888  {
889    WerrorS( feNotImplemented );
890    return res;
891  }
892
893  LL=IrrCharSeries(L);
894  int m= LL.length(); // Anzahl Zeilen
895  int n=0;
896  ListIterator<CFList> LLi;
897  CFListIterator Li;
898  for ( LLi = LL; LLi.hasItem(); LLi++ )
899  {
900    n = max(LLi.getItem().length(),n);
901  }
902  if ((m==0) || (n==0))
903  {
904    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
905      m,n,IDELEMS(I)+1,LL.length());
906    iiWriteMatrix((matrix)I,"I",2,0);
907    m=max(m,1);
908    n=max(n,1);
909  }
910  res=mpNew(m,n);
911  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
912  {
913    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
914    {
915      if ( (nGetChar() == 0) || (nGetChar() > 1) )
916        MATELEM(res,m,n)=convClapPSingP(Li.getItem());
917      else
918        MATELEM(res,m,n)=convClapPSingTrP(Li.getItem());
919    }
920  }
921  Off(SW_RATIONAL);
922  return res;
923#else
924  return NULL;
925#endif
926}
927
928char* singclap_neworder ( ideal I)
929{
930#ifdef HAVE_LIBFAC_P
931  int i;
932  Off(SW_RATIONAL);
933  On(SW_SYMMETRIC_FF);
934  CFList L;
935  if (((nGetChar() == 0) || (nGetChar() > 1) )
936  && (currRing->parameter==NULL))
937  {
938    setCharacteristic( nGetChar() );
939    for(i=0;i<IDELEMS(I);i++)
940    {
941      L.append(convSingPClapP(I->m[i]));
942    }
943  }
944  // and over Q(a) / Fp(a)
945  else if (( nGetChar()==1 ) /* Q(a) */
946  || (nGetChar() <-1))       /* Fp(a) */
947  {
948    if (nGetChar()==1) setCharacteristic( 0 );
949    else               setCharacteristic( -nGetChar() );
950    for(i=0;i<IDELEMS(I);i++)
951    {
952      L.append(convSingTrPClapP(I->m[i]));
953    }
954  }
955  else
956  {
957    WerrorS( feNotImplemented );
958    return NULL;
959  }
960
961  List<int> IL=neworderint(L);
962  ListIterator<int> Li;
963  StringSetS("");
964  Li = IL;
965  int offs=rPar(currRing);
966  int* mark=(int*)omAlloc0((pVariables+offs)*sizeof(int));
967  int cnt=pVariables+offs;
968  loop
969  {
970    i=Li.getItem()-1;
971    mark[i]=1;
972    if (i<offs)
973    {
974      StringAppendS(currRing->parameter[i]);
975    }
976    else
977    {
978      StringAppendS(currRing->names[i-offs]);
979    }
980    Li++;
981    cnt--;
982    if(cnt==0) break;
983    StringAppendS(",");
984    if(! Li.hasItem()) break;
985  }
986  for(i=0;i<pVariables+offs;i++)
987  {
988    if(mark[i]==0)
989    {
990      if (i<offs)
991      {
992        StringAppendS(currRing->parameter[i]);
993      }
994      else
995      {
996        StringAppendS(currRing->names[i-offs]);
997      }
998      cnt--;
999      if(cnt==0) break;
1000      StringAppendS(",");
1001    }
1002  }
1003  return omStrDup(StringAppendS(""));
1004#else
1005  return NULL;
1006#endif
1007}
1008
1009BOOLEAN singclap_isSqrFree(poly f)
1010{
1011  BOOLEAN b=FALSE;
1012  Off(SW_RATIONAL);
1013  //  Q / Fp
1014  if (((nGetChar() == 0) || (nGetChar() > 1) )
1015  &&(currRing->parameter==NULL))
1016  {
1017    setCharacteristic( nGetChar() );
1018    CanonicalForm F( convSingPClapP( f ) );
1019    if((nGetChar()>1)&&(!F.isUnivariate()))
1020      goto err;
1021    b=(BOOLEAN)isSqrFree(F);
1022  }
1023  // and over Q(a) / Fp(a)
1024  else if (( nGetChar()==1 ) /* Q(a) */
1025  || (nGetChar() <-1))       /* Fp(a) */
1026  {
1027    if (nGetChar()==1) setCharacteristic( 0 );
1028    else               setCharacteristic( -nGetChar() );
1029    //if (currRing->minpoly!=NULL)
1030    //{
1031    //  CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1032    //  Variable a=rootOf(mipo);
1033    //  CanonicalForm F( convSingAPClapAP( f,a ) );
1034    //  ...
1035    //}
1036    //else
1037    {
1038      CanonicalForm F( convSingTrPClapP( f ) );
1039      b=(BOOLEAN)isSqrFree(F);
1040    }
1041    Off(SW_RATIONAL);
1042  }
1043  else
1044  {
1045err:
1046    WerrorS( feNotImplemented );
1047  }
1048  return b;
1049}
1050
1051poly singclap_det( const matrix m )
1052{
1053  int r=m->rows();
1054  if (r!=m->cols())
1055  {
1056    Werror("det of %d x %d matrix",r,m->cols());
1057    return NULL;
1058  }
1059  poly res=NULL;
1060  if (( nGetChar() == 0 || nGetChar() > 1 )
1061  && (currRing->parameter==NULL))
1062  {
1063    setCharacteristic( nGetChar() );
1064    CFMatrix M(r,r);
1065    int i,j;
1066    for(i=r;i>0;i--)
1067    {
1068      for(j=r;j>0;j--)
1069      {
1070        M(i,j)=convSingPClapP(MATELEM(m,i,j));
1071      }
1072    }
1073    res= convClapPSingP( determinant(M,r) ) ;
1074  }
1075  // and over Q(a) / Fp(a)
1076  else if (( nGetChar()==1 ) /* Q(a) */
1077  || (nGetChar() <-1))       /* Fp(a) */
1078  {
1079    if (nGetChar()==1) setCharacteristic( 0 );
1080    else               setCharacteristic( -nGetChar() );
1081    CFMatrix M(r,r);
1082    poly res;
1083    if (currRing->minpoly!=NULL)
1084    {
1085      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1086      Variable a=rootOf(mipo);
1087      int i,j;
1088      for(i=r;i>0;i--)
1089      {
1090        for(j=r;j>0;j--)
1091        {
1092          M(i,j)=convSingAPClapAP(MATELEM(m,i,j),a);
1093        }
1094      }
1095      res= convClapAPSingAP( determinant(M,r) ) ;
1096    }
1097    else
1098    {
1099      int i,j;
1100      for(i=r;i>0;i--)
1101      {
1102        for(j=r;j>0;j--)
1103        {
1104          M(i,j)=convSingTrPClapP(MATELEM(m,i,j));
1105        }
1106      }
1107      res= convClapPSingTrP( determinant(M,r) );
1108    }
1109  }
1110  else
1111    WerrorS( feNotImplemented );
1112  Off(SW_RATIONAL);
1113  return res;
1114}
1115
1116int singclap_det_i( intvec * m )
1117{
1118  setCharacteristic( 0 );
1119  CFMatrix M(m->rows(),m->cols());
1120  int i,j;
1121  for(i=m->rows();i>0;i--)
1122  {
1123    for(j=m->cols();j>0;j--)
1124    {
1125      M(i,j)=IMATELEM(*m,i,j);
1126    }
1127  }
1128  int res= convClapISingI( determinant(M,m->rows())) ;
1129  Off(SW_RATIONAL);
1130  return res;
1131}
1132/*==============================================================*/
1133/* interpreter interface : */
1134BOOLEAN jjGCD_P(leftv res, leftv u, leftv v)
1135{
1136  res->data=(void *)singclap_gcd((poly)(u->CopyD(POLY_CMD)),
1137                                 (poly)(v->CopyD(POLY_CMD)));
1138  return FALSE;
1139}
1140
1141BOOLEAN jjFAC_P(leftv res, leftv u)
1142{
1143  intvec *v=NULL;
1144  ideal f=singclap_factorize((poly)(u->Data()), &v, 0);
1145  if (f==NULL) return TRUE;
1146  ivTest(v);
1147  lists l=(lists)omAllocBin(slists_bin);
1148  l->Init(2);
1149  l->m[0].rtyp=IDEAL_CMD;
1150  l->m[0].data=(void *)f;
1151  l->m[1].rtyp=INTVEC_CMD;
1152  l->m[1].data=(void *)v;
1153  res->data=(void *)l;
1154  return FALSE;
1155}
1156
1157BOOLEAN jjSQR_FREE_DEC(leftv res, leftv u,leftv dummy)
1158{
1159  intvec *v=NULL;
1160  int sw=(int)dummy->Data();
1161  ideal f=singclap_factorize((poly)(u->Data()), &v, sw);
1162  if (f==NULL)
1163    return TRUE;
1164  switch(sw)
1165  {
1166    case 0:
1167    case 2:
1168    {
1169      lists l=(lists)omAllocBin(slists_bin);
1170      l->Init(2);
1171      l->m[0].rtyp=IDEAL_CMD;
1172      l->m[0].data=(void *)f;
1173      l->m[1].rtyp=INTVEC_CMD;
1174      l->m[1].data=(void *)v;
1175      res->data=(void *)l;
1176      res->rtyp=LIST_CMD;
1177      return FALSE;
1178    }
1179    case 1:
1180      res->data=(void *)f;
1181      return FALSE;
1182    case 3:
1183      {
1184        poly p=f->m[0];
1185        int i=IDELEMS(f);
1186        f->m[0]=NULL;
1187        while(i>1)
1188        {
1189          i--;
1190          p=pMult(p,f->m[i]);
1191          f->m[i]=NULL;
1192        }
1193        res->data=(void *)p;
1194        res->rtyp=POLY_CMD;
1195      }
1196      return FALSE;
1197  }
1198  WerrorS("invalid switch");
1199  return TRUE;
1200}
1201
1202#if 0
1203BOOLEAN jjIS_SQR_FREE(leftv res, leftv u)
1204{
1205  BOOLEAN b=singclap_factorize((poly)(u->Data()), &v, 0);
1206  res->data=(void *)b;
1207}
1208#endif
1209
1210BOOLEAN jjEXTGCD_P(leftv res, leftv u, leftv v)
1211{
1212  res->data=singclap_extgcd((poly)u->Data(),(poly)v->Data());
1213  return (res->data==NULL);
1214}
1215BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w)
1216{
1217  res->data=singclap_resultant((poly)u->Data(),(poly)v->Data(), (poly)w->Data());
1218  return errorreported;
1219}
1220BOOLEAN jjCHARSERIES(leftv res, leftv u)
1221{
1222  res->data=singclap_irrCharSeries((ideal)u->Data());
1223  return (res->data==NULL);
1224}
1225
1226alg singclap_alglcm ( alg f, alg g )
1227{
1228 FACTORY_ALGOUT( "f", f );
1229 FACTORY_ALGOUT( "g", g );
1230
1231 // over Q(a) / Fp(a)
1232 if (nGetChar()==1) setCharacteristic( 0 );
1233 else               setCharacteristic( -nGetChar() );
1234 alg res;
1235
1236 if (currRing->minpoly!=NULL)
1237 {
1238   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1239   Variable a=rootOf(mipo);
1240   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1241   CanonicalForm GCD;
1242
1243   TIMING_START( algLcmTimer );
1244   // calculate gcd
1245#ifdef FACTORY_GCD_TEST
1246   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1247#else
1248   GCD = gcd( F, G );
1249#endif
1250   TIMING_END( algLcmTimer );
1251
1252   FACTORY_CFAOUT( "d", GCD );
1253   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1254
1255   // calculate lcm
1256   res= convClapASingA( (F/GCD)*G );
1257 }
1258 else
1259 {
1260   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1261   CanonicalForm GCD;
1262   TIMING_START( algLcmTimer );
1263   // calculate gcd
1264#ifdef FACTORY_GCD_TEST
1265   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1266#else
1267   GCD = gcd( F, G );
1268#endif
1269   TIMING_END( algLcmTimer );
1270
1271   FACTORY_CFTROUT( "d", GCD );
1272   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1273
1274   // calculate lcm
1275   res= convClapPSingTr( (F/GCD)*G );
1276 }
1277
1278 Off(SW_RATIONAL);
1279 return res;
1280}
1281
1282void singclap_algdividecontent ( alg f, alg g, alg &ff, alg &gg )
1283{
1284 FACTORY_ALGOUT( "f", f );
1285 FACTORY_ALGOUT( "g", g );
1286
1287 // over Q(a) / Fp(a)
1288 if (nGetChar()==1) setCharacteristic( 0 );
1289 else               setCharacteristic( -nGetChar() );
1290 ff=gg=NULL;
1291
1292 if (currRing->minpoly!=NULL)
1293 {
1294   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1295   Variable a=rootOf(mipo);
1296   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1297   CanonicalForm GCD;
1298
1299   TIMING_START( algContentTimer );
1300#ifdef FACTORY_GCD_TEST
1301   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1302#else
1303   GCD=gcd( F, G );
1304#endif
1305   TIMING_END( algContentTimer );
1306
1307   FACTORY_CFAOUT( "d", GCD );
1308   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1309
1310   if ((GCD!=1) && (GCD!=0))
1311   {
1312     ff= convClapASingA( F/ GCD );
1313     gg= convClapASingA( G/ GCD );
1314   }
1315 }
1316 else
1317 {
1318   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1319   CanonicalForm GCD;
1320
1321   TIMING_START( algContentTimer );
1322#ifdef FACTORY_GCD_TEST
1323   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1324#else
1325   GCD=gcd( F, G );
1326#endif
1327   TIMING_END( algContentTimer );
1328
1329   FACTORY_CFTROUT( "d", GCD );
1330   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1331
1332   if ((GCD!=1) && (GCD!=0))
1333   {
1334     ff= convClapPSingTr( F/ GCD );
1335     gg= convClapPSingTr( G/ GCD );
1336   }
1337 }
1338
1339 Off(SW_RATIONAL);
1340}
1341
1342lists singclap_chineseRemainder(lists x, lists q)
1343{
1344  //assume(x->nr == q->nr);
1345  //assume(x->nr >= 0);
1346  int n=x->nr+1;
1347  if ((x->nr<0) || (x->nr!=q->nr))
1348  {
1349    WerrorS("list are empty or not of equal length");
1350    return NULL;
1351  }
1352  lists res=(lists)omAlloc0Bin(slists_bin);
1353  CFArray X(1,n), Q(1,n);
1354  int i;
1355  for(i=0; i<n; i++)
1356  {
1357    if (x->m[i-1].Typ()==INT_CMD)
1358    {
1359      X[i]=(int)x->m[i-1].Data();
1360    }
1361    else if (x->m[i-1].Typ()==NUMBER_CMD)
1362    {
1363      number N=(number)x->m[i-1].Data();
1364      X[i]=convSingNClapN(N);
1365    }
1366    else
1367    {
1368      WerrorS("illegal type in chineseRemainder");
1369      omFreeBin(res,slists_bin);
1370      return NULL;
1371    }
1372    if (q->m[i-1].Typ()==INT_CMD)
1373    {
1374      Q[i]=(int)q->m[i-1].Data();
1375    }
1376    else if (q->m[i-1].Typ()==NUMBER_CMD)
1377    {
1378      number N=(number)x->m[i-1].Data();
1379      Q[i]=convSingNClapN(N);
1380    }
1381    else
1382    {
1383      WerrorS("illegal type in chineseRemainder");
1384      omFreeBin(res,slists_bin);
1385      return NULL;
1386    }
1387  }
1388  CanonicalForm r, prod;
1389  chineseRemainder( X, Q, r, prod );
1390  res->Init(2);
1391  res->m[0].rtyp=NUMBER_CMD;
1392  res->m[1].rtyp=NUMBER_CMD;
1393  res->m[0].data=(char *)convClapNSingN( r );
1394  res->m[1].data=(char *)convClapNSingN( prod );
1395  return res;
1396}
1397#endif
Note: See TracBrowser for help on using the repository browser.