source: git/Singular/clapsing.cc @ 2c694a2

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