source: git/Singular/clapsing.cc @ a79a128

spielwiese
Last change on this file since a79a128 was a79a128, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* use vsnprintf, instead of vsprintf, when possible * new string and print implementation * small bug fixes in iparith.cc git-svn-id: file:///usr/local/Singular/svn/trunk@2990 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 30.3 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5// $Id: clapsing.cc,v 1.50 1999-04-17 14:58:38 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)Alloc(sizeof(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)Alloc0(sizeof(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
620ideal singclap_factorize ( poly f, intvec ** v , int with_exps)
621{
622  // with_exps: 1 return only true factors
623  //            2 return true factors and exponents
624  //            0 return factors and exponents
625
626  ideal res=NULL;
627  if (f==NULL)
628  {
629    res=idInit(1,1);
630    if (with_exps!=1)
631    {
632      (*v)=new intvec(1);
633      (*v)[1]=1;
634    }
635    return res;
636  }
637  Off(SW_RATIONAL);
638  On(SW_SYMMETRIC_FF);
639  CFFList L;
640  number N=NULL;
641  number NN=NULL;
642
643  if (( (nGetChar() == 0) || (nGetChar() > 1) )
644  && (currRing->parameter==NULL))
645  {
646    setCharacteristic( nGetChar() );
647    if (nGetChar()==0) /* Q */
648    {
649      if (f!=NULL)
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  // and over Q(a) / Fp(a)
679  else if (( nGetChar()==1 ) /* Q(a) */
680  || (nGetChar() <-1))       /* Fp(a) */
681  {
682    if (nGetChar()==1) setCharacteristic( 0 );
683    else               setCharacteristic( -nGetChar() );
684    if ((currRing->minpoly!=NULL)
685    && (nGetChar()<(-1)))
686    {
687      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
688      Variable a=rootOf(mipo);
689      CanonicalForm F( convSingAPClapAP( f,a ) );
690      if (F.isUnivariate())
691      {
692        L = factorize( F, a );
693      }
694      else
695      {
696        CanonicalForm G( convSingTrPClapP( f ) );
697        L = factorize( G );
698      }
699    }
700    else
701    {
702      CanonicalForm F( convSingTrPClapP( f ) );
703      if (nGetChar()==1) /* Q(a) */
704      {
705        L = factorize( F );
706      }
707      else /* Fp(a) */
708      {
709#ifdef HAVE_LIBFAC_P
710        L = Factorize( F );
711#else
712        goto notImpl;
713#endif
714      }
715    }
716  }
717  else
718  {
719    goto notImpl;
720  }
721  {
722    // the first factor should be a constant
723    if ( ! L.getFirst().factor().inCoeffDomain() )
724      L.insert(CFFactor(1,1));
725    // convert into ideal
726    int n = L.length();
727    CFFListIterator J=L;
728    int j=0;
729    if (with_exps!=1)
730    {
731      if ((with_exps==2)&&(n>1))
732      {
733        n--;
734        J++;
735      }
736      *v = new intvec( n );
737    }
738    res = idInit( n ,1);
739    for ( ; J.hasItem(); J++, j++ )
740    {
741      if (with_exps!=1) (**v)[j] = J.getItem().exp();
742      if ((nGetChar()==0)||(nGetChar()>1))           /* Q, Fp */
743        res->m[j] = convClapPSingP( J.getItem().factor() );
744      else if ((nGetChar()==1)||(nGetChar()<-1))     /* Q(a), Fp(a) */
745      {
746        if (currRing->minpoly==NULL)
747          res->m[j] = convClapPSingTrP( J.getItem().factor() );
748        else
749          res->m[j] = convClapAPSingAP( J.getItem().factor() );
750      }
751    }
752    if (N!=NULL)
753    {
754      pMultN(res->m[0],N);
755      nDelete(&N);
756      N=NULL;
757    }
758    // delete constants
759    if ((with_exps!=0) && (res!=NULL))
760    {
761      int i=IDELEMS(res)-1;
762      int j=0;
763      for(;i>=0;i--)
764      {
765        if (pIsConstant(res->m[i]))
766        {
767          pDelete(&(res->m[i]));
768          if ((v!=NULL) && ((*v)!=NULL))
769            (**v)[i]=0;
770          j++;
771        }
772      }
773      if (j>0)
774      {
775        idSkipZeroes(res);
776        if ((v!=NULL) && ((*v)!=NULL))
777        {
778          intvec *w=*v;
779          *v = new intvec( max(n-j,1) );
780          for (i=0,j=0;i<w->length();i++)
781          {
782            if((*w)[i]!=0)
783            {
784              (**v)[j]=(*w)[i]; j++;
785            }
786          }
787          delete w;
788        }
789      }
790      if (res->m[0]==NULL)
791      {
792        res->m[0]=pOne();
793      }
794    }
795  }
796notImpl:
797  if (res==NULL)
798    WerrorS( feNotImplemented );
799  if (NN!=NULL)
800  {
801    pMultN(f,NN);
802    nDelete(&NN);
803  }
804  if (N!=NULL)
805  {
806    nDelete(&N);
807  }
808  return res;
809}
810
811matrix singclap_irrCharSeries ( ideal I)
812{
813#ifdef HAVE_LIBFAC_P
814  // for now there is only the possibility to handle polynomials over
815  // Q and Fp ...
816  matrix res=NULL;
817  int i;
818  Off(SW_RATIONAL);
819  On(SW_SYMMETRIC_FF);
820  CFList L;
821  ListCFList LL;
822  if (((nGetChar() == 0) || (nGetChar() > 1) )
823  && (currRing->parameter==NULL))
824  {
825    setCharacteristic( nGetChar() );
826    for(i=0;i<IDELEMS(I);i++)
827    {
828      if (I->m[i]!=NULL)
829        L.append(convSingPClapP(I->m[i]));
830    }
831  }
832  // and over Q(a) / Fp(a)
833  else if (( nGetChar()==1 ) /* Q(a) */
834  || (nGetChar() <-1))       /* Fp(a) */
835  {
836    if (nGetChar()==1) setCharacteristic( 0 );
837    else               setCharacteristic( -nGetChar() );
838    for(i=0;i<IDELEMS(I);i++)
839    {
840      if (I->m[i]!=NULL)
841        L.append(convSingTrPClapP(I->m[i]));
842    }
843  }
844  else
845  {
846    WerrorS( feNotImplemented );
847    return res;
848  }
849
850  LL=IrrCharSeries(L);
851  int m= LL.length(); // Anzahl Zeilen
852  int n=0;
853  ListIterator<CFList> LLi;
854  CFListIterator Li;
855  for ( LLi = LL; LLi.hasItem(); LLi++ )
856  {
857    n = max(LLi.getItem().length(),n);
858  }
859  if ((m==0) || (n==0))
860  {
861    Warn("char_series returns %d x %d matrix from %d input polys (%d)\n",m,n,IDELEMS(I)+1,LL.length());
862    iiWriteMatrix((matrix)I,"I",2,0);
863    m=max(m,1);
864    n=max(n,1);
865  }
866  res=mpNew(m,n);
867  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
868  {
869    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
870    {
871      if ( (nGetChar() == 0) || (nGetChar() > 1) )
872        MATELEM(res,m,n)=convClapPSingP(Li.getItem());
873      else
874        MATELEM(res,m,n)=convClapPSingTrP(Li.getItem());
875    }
876  }
877  Off(SW_RATIONAL);
878  return res;
879#else
880  return NULL;
881#endif
882}
883
884char* singclap_neworder ( ideal I)
885{
886#ifdef HAVE_LIBFAC_P
887  int i;
888  Off(SW_RATIONAL);
889  On(SW_SYMMETRIC_FF);
890  CFList L;
891  if (((nGetChar() == 0) || (nGetChar() > 1) )
892  && (currRing->parameter==NULL))
893  {
894    setCharacteristic( nGetChar() );
895    for(i=0;i<IDELEMS(I);i++)
896    {
897      L.append(convSingPClapP(I->m[i]));
898    }
899  }
900  // and over Q(a) / Fp(a)
901  else if (( nGetChar()==1 ) /* Q(a) */
902  || (nGetChar() <-1))       /* Fp(a) */
903  {
904    if (nGetChar()==1) setCharacteristic( 0 );
905    else               setCharacteristic( -nGetChar() );
906    for(i=0;i<IDELEMS(I);i++)
907    {
908      L.append(convSingTrPClapP(I->m[i]));
909    }
910  }
911  else
912  {
913    WerrorS( feNotImplemented );
914    return NULL;
915  }
916
917  List<int> IL=neworderint(L);
918  ListIterator<int> Li;
919  StringSetS("");
920  Li = IL;
921  int offs=rPar(currRing);
922  int* mark=(int*)Alloc0((pVariables+offs)*sizeof(int));
923  int cnt=pVariables+offs;
924  loop
925  {
926    i=Li.getItem()-1;
927    mark[i]=1;
928    if (i<offs)
929    {
930      StringAppendS(currRing->parameter[i]);
931    }
932    else
933    {
934      StringAppendS(currRing->names[i-offs]);
935    }
936    Li++;
937    cnt--;
938    if(cnt==0) break;
939    StringAppendS(",");
940    if(! Li.hasItem()) break;
941  }
942  for(i=0;i<pVariables+offs;i++)
943  {
944    if(mark[i]==0)
945    {
946      if (i<offs)
947      {
948        StringAppendS(currRing->parameter[i]);
949      }
950      else
951      {
952        StringAppendS(currRing->names[i-offs]);
953      }
954      cnt--;
955      if(cnt==0) break;
956      StringAppendS(",");
957    }
958  }
959  return mstrdup(StringAppendS(""));
960#else
961  return NULL;
962#endif
963}
964
965BOOLEAN singclap_isSqrFree(poly f)
966{
967  BOOLEAN b=FALSE;
968  Off(SW_RATIONAL);
969  //  Q / Fp
970  if (((nGetChar() == 0) || (nGetChar() > 1) )
971  &&(currRing->parameter==NULL))
972  {
973    setCharacteristic( nGetChar() );
974    CanonicalForm F( convSingPClapP( f ) );
975    if((nGetChar()>1)&&(!F.isUnivariate()))
976      goto err;
977    b=(BOOLEAN)isSqrFree(F);
978  }
979  // and over Q(a) / Fp(a)
980  else if (( nGetChar()==1 ) /* Q(a) */
981  || (nGetChar() <-1))       /* Fp(a) */
982  {
983    if (nGetChar()==1) setCharacteristic( 0 );
984    else               setCharacteristic( -nGetChar() );
985    //if (currRing->minpoly!=NULL)
986    //{
987    //  CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
988    //  Variable a=rootOf(mipo);
989    //  CanonicalForm F( convSingAPClapAP( f,a ) );
990    //  ...
991    //}
992    //else
993    {
994      CanonicalForm F( convSingTrPClapP( f ) );
995      b=(BOOLEAN)isSqrFree(F);
996    }
997    Off(SW_RATIONAL);
998  }
999  else
1000  {
1001err:
1002    WerrorS( feNotImplemented );
1003  }
1004  return b;
1005}
1006
1007poly singclap_det( const matrix m )
1008{
1009  int r=m->rows();
1010  if (r!=m->cols())
1011  {
1012    Werror("det of %d x %d matrix",r,m->cols());
1013    return NULL;
1014  }
1015  poly res=NULL;
1016  if (( nGetChar() == 0 || nGetChar() > 1 )
1017  && (currRing->parameter==NULL))
1018  {
1019    setCharacteristic( nGetChar() );
1020    CFMatrix M(r,r);
1021    int i,j;
1022    for(i=r;i>0;i--)
1023    {
1024      for(j=r;j>0;j--)
1025      {
1026        M(i,j)=convSingPClapP(MATELEM(m,i,j));
1027      }
1028    }
1029    res= convClapPSingP( determinant(M,r) ) ;
1030  }
1031  // and over Q(a) / Fp(a)
1032  else if (( nGetChar()==1 ) /* Q(a) */
1033  || (nGetChar() <-1))       /* Fp(a) */
1034  {
1035    if (nGetChar()==1) setCharacteristic( 0 );
1036    else               setCharacteristic( -nGetChar() );
1037    CFMatrix M(r,r);
1038    poly res;
1039    if (currRing->minpoly!=NULL)
1040    {
1041      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1042      Variable a=rootOf(mipo);
1043      int i,j;
1044      for(i=r;i>0;i--)
1045      {
1046        for(j=r;j>0;j--)
1047        {
1048          M(i,j)=convSingAPClapAP(MATELEM(m,i,j),a);
1049        }
1050      }
1051      res= convClapAPSingAP( determinant(M,r) ) ;
1052    }
1053    else
1054    {
1055      int i,j;
1056      for(i=r;i>0;i--)
1057      {
1058        for(j=r;j>0;j--)
1059        {
1060          M(i,j)=convSingTrPClapP(MATELEM(m,i,j));
1061        }
1062      }
1063      res= convClapPSingTrP( determinant(M,r) );
1064    }
1065  }
1066  else
1067    WerrorS( feNotImplemented );
1068  Off(SW_RATIONAL);
1069  return res;
1070}
1071
1072int singclap_det_i( intvec * m )
1073{
1074  setCharacteristic( 0 );
1075  CFMatrix M(m->rows(),m->cols());
1076  int i,j;
1077  for(i=m->rows();i>0;i--)
1078  {
1079    for(j=m->cols();j>0;j--)
1080    {
1081      M(i,j)=IMATELEM(*m,i,j);
1082    }
1083  }
1084  int res= convClapISingI( determinant(M,m->rows())) ;
1085  Off(SW_RATIONAL);
1086  return res;
1087}
1088/*==============================================================*/
1089/* interpreter interface : */
1090BOOLEAN jjGCD_P(leftv res, leftv u, leftv v)
1091{
1092  res->data=(void *)singclap_gcd((poly)(u->CopyD()),((poly)v->CopyD()));
1093  return FALSE;
1094}
1095
1096BOOLEAN jjFAC_P(leftv res, leftv u)
1097{
1098  intvec *v=NULL;
1099  ideal f=singclap_factorize((poly)(u->Data()), &v, 0);
1100  if (f==NULL) return TRUE;
1101  lists l=(lists)Alloc(sizeof(slists));
1102  l->Init(2);
1103  l->m[0].rtyp=IDEAL_CMD;
1104  l->m[0].data=(void *)f;
1105  l->m[1].rtyp=INTVEC_CMD;
1106  l->m[1].data=(void *)v;
1107  res->data=(void *)l;
1108  return FALSE;
1109}
1110
1111BOOLEAN jjSQR_FREE_DEC(leftv res, leftv u,leftv dummy)
1112{
1113  intvec *v=NULL;
1114  int sw=(int)dummy->Data();
1115  ideal f=singclap_factorize((poly)(u->Data()), &v, sw);
1116  if (f==NULL)
1117    return TRUE;
1118  switch(sw)
1119  {
1120    case 0:
1121    case 2:
1122    {
1123      lists l=(lists)Alloc(sizeof(slists));
1124      l->Init(2);
1125      l->m[0].rtyp=IDEAL_CMD;
1126      l->m[0].data=(void *)f;
1127      l->m[1].rtyp=INTVEC_CMD;
1128      l->m[1].data=(void *)v;
1129      res->data=(void *)l;
1130      res->rtyp=LIST_CMD;
1131      return FALSE;
1132    }
1133    case 1:
1134      res->data=(void *)f;
1135      return FALSE;
1136    case 3:
1137      {
1138        poly p=f->m[0];
1139        int i=IDELEMS(f);
1140        f->m[0]=NULL;
1141        while(i>1)
1142        {
1143          i--;
1144          p=pMult(p,f->m[i]);
1145          f->m[i]=NULL;
1146        }
1147        res->data=(void *)p;
1148        res->rtyp=POLY_CMD;
1149      }
1150      return FALSE;
1151  }
1152  WerrorS("invalid switch");
1153  return TRUE;
1154}
1155
1156#if 0
1157BOOLEAN jjIS_SQR_FREE(leftv res, leftv u)
1158{
1159  BOOLEAN b=singclap_factorize((poly)(u->Data()), &v, 0);
1160  res->data=(void *)b;
1161}
1162#endif
1163
1164BOOLEAN jjEXTGCD_P(leftv res, leftv u, leftv v)
1165{
1166  res->data=singclap_extgcd((poly)u->Data(),(poly)v->Data());
1167  return (res->data==NULL);
1168}
1169BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w)
1170{
1171  res->data=singclap_resultant((poly)u->Data(),(poly)v->Data(), (poly)w->Data());
1172  return errorreported;
1173}
1174BOOLEAN jjCHARSERIES(leftv res, leftv u)
1175{
1176  res->data=singclap_irrCharSeries((ideal)u->Data());
1177  return (res->data==NULL);
1178}
1179
1180alg singclap_alglcm ( alg f, alg g )
1181{
1182 FACTORY_ALGOUT( "f", f );
1183 FACTORY_ALGOUT( "g", g );
1184
1185 // over Q(a) / Fp(a)
1186 if (nGetChar()==1) setCharacteristic( 0 );
1187 else               setCharacteristic( -nGetChar() );
1188 alg res;
1189
1190 if (currRing->minpoly!=NULL)
1191 {
1192   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1193   Variable a=rootOf(mipo);
1194   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1195   CanonicalForm GCD;
1196
1197   TIMING_START( algLcmTimer );
1198   // calculate gcd
1199#ifdef FACTORY_GCD_TEST
1200   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1201#else
1202   GCD = gcd( F, G );
1203#endif
1204   TIMING_END( algLcmTimer );
1205
1206   FACTORY_CFAOUT( "d", GCD );
1207   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1208
1209   // calculate lcm
1210   res= convClapASingA( (F/GCD)*G );
1211 }
1212 else
1213 {
1214   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1215   CanonicalForm GCD;
1216   TIMING_START( algLcmTimer );
1217   // calculate gcd
1218#ifdef FACTORY_GCD_TEST
1219   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1220#else
1221   GCD = gcd( F, G );
1222#endif
1223   TIMING_END( algLcmTimer );
1224
1225   FACTORY_CFTROUT( "d", GCD );
1226   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1227
1228   // calculate lcm
1229   res= convClapPSingTr( (F/GCD)*G );
1230 }
1231
1232 Off(SW_RATIONAL);
1233 return res;
1234}
1235
1236void singclap_algdividecontent ( alg f, alg g, alg &ff, alg &gg )
1237{
1238 FACTORY_ALGOUT( "f", f );
1239 FACTORY_ALGOUT( "g", g );
1240
1241 // over Q(a) / Fp(a)
1242 if (nGetChar()==1) setCharacteristic( 0 );
1243 else               setCharacteristic( -nGetChar() );
1244 ff=gg=NULL;
1245
1246 if (currRing->minpoly!=NULL)
1247 {
1248   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1249   Variable a=rootOf(mipo);
1250   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1251   CanonicalForm GCD;
1252
1253   TIMING_START( algContentTimer );
1254#ifdef FACTORY_GCD_TEST
1255   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1256#else
1257   GCD=gcd( F, G );
1258#endif
1259   TIMING_END( algContentTimer );
1260
1261   FACTORY_CFAOUT( "d", GCD );
1262   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1263
1264   if (GCD!=1)
1265   {
1266     ff= convClapASingA( F/ GCD );
1267     gg= convClapASingA( G/ GCD );
1268   }
1269 }
1270 else
1271 {
1272   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1273   CanonicalForm GCD;
1274
1275   TIMING_START( algContentTimer );
1276#ifdef FACTORY_GCD_TEST
1277   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1278#else
1279   GCD=gcd( F, G );
1280#endif
1281   TIMING_END( algContentTimer );
1282
1283   FACTORY_CFTROUT( "d", GCD );
1284   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1285
1286   if (GCD!=1)
1287   {
1288     ff= convClapPSingTr( F/ GCD );
1289     gg= convClapPSingTr( G/ GCD );
1290   }
1291 }
1292
1293 Off(SW_RATIONAL);
1294}
1295#endif
Note: See TracBrowser for help on using the repository browser.