source: git/Singular/clapsing.cc @ 2166892

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