source: git/Singular/clapsing.cc @ cbc84b

spielwiese
Last change on this file since cbc84b was cbc84b, checked in by Hans Schönemann <hannes@…>, 25 years ago
*hannes: fixed coef bug in gcd git-svn-id: file:///usr/local/Singular/svn/trunk@2920 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 30.2 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5// $Id: clapsing.cc,v 1.47 1999-03-15 13:58:30 Singular 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(StringAppend("\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(StringAppend("\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(StringAppend("\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  // for now there is only the possibility to handle polynomials over
274  // Q and Fp ...
275  if (( nGetChar() == 0 || nGetChar() > 1 )
276  && (currRing->parameter==NULL))
277  {
278    Variable X(i);
279    setCharacteristic( nGetChar() );
280    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
281    poly res=convClapPSingP( resultant( F, G, X ) );
282    Off(SW_RATIONAL);
283    return res;
284  }
285  // and over Q(a) / Fp(a)
286  else if (( nGetChar()==1 ) /* Q(a) */
287  || (nGetChar() <-1))       /* Fp(a) */
288  {
289    if (nGetChar()==1) setCharacteristic( 0 );
290    else               setCharacteristic( -nGetChar() );
291    poly res;
292    if (currRing->minpoly!=NULL)
293    {
294      Variable X(i);
295      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
296      Variable a=rootOf(mipo);
297      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
298      res= convClapAPSingAP( resultant( F, G, X ) );
299    }
300    else
301    {
302      Variable X(i+rPar(currRing));
303      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
304      res= convClapPSingTrP( resultant( F, G, X ) );
305    }
306    Off(SW_RATIONAL);
307    return res;
308  }
309  else
310    WerrorS( feNotImplemented );
311  return NULL;
312}
313//poly singclap_resultant ( poly f, poly g , poly x)
314//{
315//  int i=pVar(x);
316//  if (i==0)
317//  {
318//    WerrorS("ringvar expected");
319//    return NULL;
320//  }
321//  ideal I=idInit(1,1);
322//
323//  // get the coeffs von f wrt. x:
324//  I->m[0]=pCopy(f);
325//  matrix ffi=mpCoeffs(I,i);
326//  ffi->rank=1;
327//  ffi->ncols=ffi->nrows;
328//  ffi->nrows=1;
329//  ideal fi=(ideal)ffi;
330//
331//  // get the coeffs von g wrt. x:
332//  I->m[0]=pCopy(g);
333//  matrix ggi=mpCoeffs(I,i);
334//  ggi->rank=1;
335//  ggi->ncols=ggi->nrows;
336//  ggi->nrows=1;
337//  ideal gi=(ideal)ggi;
338//
339//  // contruct the matrix:
340//  int fn=IDELEMS(fi); //= deg(f,x)+1
341//  int gn=IDELEMS(gi); //= deg(g,x)+1
342//  matrix m=mpNew(fn+gn-2,fn+gn-2);
343//  if(m==NULL)
344//  {
345//    return NULL;
346//  }
347//
348//  // enter the coeffs into m:
349//  int j;
350//  for(i=0;i<gn-1;i++)
351//  {
352//    for(j=0;j<fn;j++)
353//    {
354//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
355//    }
356//  }
357//  for(i=0;i<fn-1;i++)
358//  {
359//    for(j=0;j<gn;j++)
360//    {
361//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
362//    }
363//  }
364//
365//  poly r=mpDet(m);
366//
367//  idDelete(&fi);
368//  idDelete(&gi);
369//  idDelete((ideal *)&m);
370//  return r;
371//}
372
373lists singclap_extgcd ( poly f, poly g )
374{
375  // for now there is only the possibility to handle univariate
376  // polynomials over
377  // Q and Fp ...
378  poly res=NULL,pa=NULL,pb=NULL;
379  On(SW_SYMMETRIC_FF);
380  if (( nGetChar() == 0 || nGetChar() > 1 )
381  && (currRing->parameter==NULL))
382  {
383    setCharacteristic( nGetChar() );
384    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
385    if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
386    {
387      Off(SW_RATIONAL);
388      WerrorS("not univariate");
389      return NULL;
390    }
391    CanonicalForm Fa,Gb;
392    On(SW_RATIONAL);
393    res=convClapPSingP( extgcd( F, G, Fa, Gb ) );
394    pa=convClapPSingP(Fa);
395    pb=convClapPSingP(Gb);
396    Off(SW_RATIONAL);
397  }
398  // and over Q(a) / Fp(a)
399  else if (( nGetChar()==1 ) /* Q(a) */
400  || (nGetChar() <-1))       /* Fp(a) */
401  {
402    if (nGetChar()==1) setCharacteristic( 0 );
403    else               setCharacteristic( -nGetChar() );
404    CanonicalForm Fa,Gb;
405    if (currRing->minpoly!=NULL)
406    {
407      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
408      Variable a=rootOf(mipo);
409      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
410      if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
411      {
412        WerrorS("not univariate");
413        return NULL;
414      }
415      res= convClapAPSingAP( extgcd( F, G, Fa, Gb ) );
416      pa=convClapAPSingAP(Fa);
417      pb=convClapAPSingAP(Gb);
418    }
419    else
420    {
421      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
422      if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
423      {
424        Off(SW_RATIONAL);
425        WerrorS("not univariate");
426        return NULL;
427      }
428      res= convClapPSingTrP( extgcd( F, G, Fa, Gb ) );
429      pa=convClapPSingTrP(Fa);
430      pb=convClapPSingTrP(Gb);
431    }
432    Off(SW_RATIONAL);
433  }
434  else
435  {
436    WerrorS( feNotImplemented );
437    return NULL;
438  }
439  lists L=(lists)Alloc(sizeof(slists));
440  L->Init(3);
441  L->m[0].rtyp=POLY_CMD;
442  L->m[0].data=(void *)res;
443  L->m[1].rtyp=POLY_CMD;
444  L->m[1].data=(void *)pa;
445  L->m[2].rtyp=POLY_CMD;
446  L->m[2].data=(void *)pb;
447  return L;
448}
449
450poly singclap_pdivide ( poly f, poly g )
451{
452  // for now there is only the possibility to handle polynomials over
453  // Q and Fp ...
454  poly res=NULL;
455  On(SW_RATIONAL);
456  if (( nGetChar() == 0 || nGetChar() > 1 )
457  && (currRing->parameter==NULL))
458  {
459    setCharacteristic( nGetChar() );
460    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
461    res = convClapPSingP( F / G );
462  }
463  // and over Q(a) / Fp(a)
464  else if (( nGetChar()==1 ) /* Q(a) */
465  || (nGetChar() <-1))       /* Fp(a) */
466  {
467    if (nGetChar()==1) setCharacteristic( 0 );
468    else               setCharacteristic( -nGetChar() );
469    if (currRing->minpoly!=NULL)
470    {
471      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
472      Variable a=rootOf(mipo);
473      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
474      res= convClapAPSingAP(  F / G  );
475    }
476    else
477    {
478      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
479      res= convClapPSingTrP(  F / G  );
480    }
481  }
482  else
483    WerrorS( feNotImplemented );
484  Off(SW_RATIONAL);
485  return res;
486}
487
488void singclap_divide_content ( poly f )
489{
490  if ( nGetChar() == 1 )
491    setCharacteristic( 0 );
492  else  if ( nGetChar() == -1 )
493    return; /* not implemented for R */
494  else  if ( nGetChar() < 0 )
495    setCharacteristic( -nGetChar() );
496  else if (currRing->parameter==NULL) /* not GF(q) */
497    setCharacteristic( nGetChar() );
498  else
499    return; /* not implemented*/
500  if ( f==NULL )
501  {
502    return;
503  }
504  else  if ( pNext( f ) == NULL )
505  {
506    pSetCoeff( f, nInit( 1 ) );
507    return;
508  }
509  else
510  {
511    CFList L;
512    CanonicalForm g, h;
513    poly p = pNext(f);
514
515    // first attemp: find 2 smallest g:
516
517    number g1=pGetCoeff(f);
518    number g2=pGetCoeff(p); // p==pNext(f);
519    pIter(p);
520    int sz1=nSize(g1);
521    int sz2=nSize(g2);
522    if (sz1>sz2)
523    {
524      number gg=g1;
525      g1=g2; g2=gg;
526      int sz=sz1;
527      sz1=sz2; sz2=sz;
528    }
529    while (p!=NULL)
530    {
531      int n_sz=nSize(pGetCoeff(p));
532      if (n_sz<sz1)
533      {
534        sz2=sz1;
535        g2=g1;
536        g1=pGetCoeff(p);
537        sz1=n_sz;
538        if (sz1<=3) break;
539      }
540      else if(n_sz<sz2)
541      {
542        sz2=n_sz;
543        g2=pGetCoeff(p);
544        sz2=n_sz;
545      }
546      pIter(p);
547    }
548    FACTORY_ALGOUT( "G", ((lnumber)g1)->z );
549    g = convSingTrClapP( ((lnumber)g1)->z );
550    g = gcd( g, convSingTrClapP( ((lnumber)g2)->z ));
551
552    // second run: gcd's
553
554    p = f;
555    TIMING_START( contentTimer );
556    while ( (p != NULL) && (g != 1) )
557    {
558      FACTORY_ALGOUT( "h", (((lnumber)pGetCoeff(p))->z) );
559      h = convSingTrClapP( ((lnumber)pGetCoeff(p))->z );
560      pIter( p );
561#ifdef FACTORY_GCD_STAT
562      // save g
563      CanonicalForm gOld = g;
564#endif
565
566#ifdef FACTORY_GCD_TEST
567      g = CFPrimitiveGcdUtil::gcd( g, h );
568#else
569      g = gcd( g, h );
570#endif
571
572      FACTORY_GCDSTAT( "gcnt:", gOld, h, g );
573      FACTORY_CFTROUT( "g", g );
574      L.append( h );
575    }
576    TIMING_END( contentTimer );
577    FACTORY_CONTSTAT( "cont:", g );
578    if ( g == 1 )
579    {
580      pTest(f);
581      return;
582    }
583    #ifdef LDEBUG
584    else if ( g == 0 )
585    {
586      pTest(f);
587      pWrite(f);
588      PrintS("=> gcd 0 in divide_content\n");
589      return;
590    }
591    #endif
592    else
593    {
594      CFListIterator i;
595      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
596      {
597        lnumber c=(lnumber)pGetCoeff(p);
598        napDelete(&c->z);
599        #ifdef LDEBUG
600        number nt=(number)Alloc0(sizeof(rnumber));
601        lnumber nnt=(lnumber)nt;
602        nnt->z=convClapPSingTr( i.getItem());
603        nTest(nt);
604        #endif
605        c->z=convClapPSingTr( i.getItem() / g );
606        //nTest((number)c);
607        //#ifdef LDEBUG
608        //number cn=(number)c;
609        //StringSet(""); nWrite(nt); StringAppend(" ==> ");
610        //nWrite(cn);PrintS(StringAppend("\n"));
611        //#endif
612      }
613    }
614    pTest(f);
615  }
616}
617
618ideal singclap_factorize ( poly f, intvec ** v , int with_exps)
619{
620  // with_exps: 1 return only true factors
621  //            2 return true factors and exponents
622  //            0 return factors and exponents
623
624  ideal res=NULL;
625  if (f==NULL)
626  {
627    res=idInit(1,1);
628    if (with_exps!=1)
629    {
630      (*v)=new intvec(1);
631      (*v)[1]=1;
632    }
633    return res;
634  }
635  Off(SW_RATIONAL);
636  On(SW_SYMMETRIC_FF);
637  CFFList L;
638  number N=NULL;
639  number NN=NULL;
640
641  if (( (nGetChar() == 0) || (nGetChar() > 1) )
642  && (currRing->parameter==NULL))
643  {
644    setCharacteristic( nGetChar() );
645    if (nGetChar()==0) /* Q */
646    {
647      if (f!=NULL)
648      {
649        number n0=nCopy(pGetCoeff(f));
650        if (with_exps==0)
651          N=nCopy(n0);
652        pCleardenom(f);
653        NN=nDiv(n0,pGetCoeff(f));
654        nDelete(&n0);
655        if (with_exps==0)
656        {
657          nDelete(&N);
658          N=nCopy(NN);
659        }
660      }
661    }
662    CanonicalForm F( convSingPClapP( f ) );
663    if (nGetChar()==0) /* Q */
664    {
665      L = factorize( F );
666    }
667    else /* Fp */
668    {
669#ifdef HAVE_LIBFAC_P
670      L = Factorize( F );
671#else
672      goto notImpl;
673#endif
674    }
675  }
676  // and over Q(a) / Fp(a)
677  else if (( nGetChar()==1 ) /* Q(a) */
678  || (nGetChar() <-1))       /* Fp(a) */
679  {
680    if (nGetChar()==1) setCharacteristic( 0 );
681    else               setCharacteristic( -nGetChar() );
682    if ((currRing->minpoly!=NULL)
683    && (nGetChar()<(-1)))
684    {
685      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
686      Variable a=rootOf(mipo);
687      CanonicalForm F( convSingAPClapAP( f,a ) );
688      if (F.isUnivariate())
689      {
690        L = factorize( F, a );
691      }
692      else
693      {
694        CanonicalForm G( convSingTrPClapP( f ) );
695        L = factorize( G );
696      }
697    }
698    else
699    {
700      CanonicalForm F( convSingTrPClapP( f ) );
701      if (nGetChar()==1) /* Q(a) */
702      {
703        L = factorize( F );
704      }
705      else /* Fp(a) */
706      {
707#ifdef HAVE_LIBFAC_P
708        L = Factorize( F );
709#else
710        goto notImpl;
711#endif
712      }
713    }
714  }
715  else
716  {
717    goto notImpl;
718  }
719  {
720    // the first factor should be a constant
721    if ( ! L.getFirst().factor().inCoeffDomain() )
722      L.insert(CFFactor(1,1));
723    // convert into ideal
724    int n = L.length();
725    CFFListIterator J=L;
726    int j=0;
727    if (with_exps!=1)
728    {
729      if ((with_exps==2)&&(n>1))
730      {
731        n--;
732        J++;
733      }
734      *v = new intvec( n );
735    }
736    res = idInit( n ,1);
737    for ( ; J.hasItem(); J++, j++ )
738    {
739      if (with_exps!=1) (**v)[j] = J.getItem().exp();
740      if ((nGetChar()==0)||(nGetChar()>1))           /* Q, Fp */
741        res->m[j] = convClapPSingP( J.getItem().factor() );
742      else if ((nGetChar()==1)||(nGetChar()<-1))     /* Q(a), Fp(a) */
743      {
744        if (currRing->minpoly==NULL)
745          res->m[j] = convClapPSingTrP( J.getItem().factor() );
746        else
747          res->m[j] = convClapAPSingAP( J.getItem().factor() );
748      }
749    }
750    if (N!=NULL)
751    {
752      pMultN(res->m[0],N);
753      nDelete(&N);
754      N=NULL;
755    }
756    // delete constants
757    if ((with_exps!=0) && (res!=NULL))
758    {
759      int i=IDELEMS(res)-1;
760      int j=0;
761      for(;i>=0;i--)
762      {
763        if (pIsConstant(res->m[i]))
764        {
765          pDelete(&(res->m[i]));
766          if ((v!=NULL) && ((*v)!=NULL))
767            (**v)[i]=0;
768          j++;
769        }
770      }
771      if (j>0)
772      {
773        idSkipZeroes(res);
774        if ((v!=NULL) && ((*v)!=NULL))
775        {
776          intvec *w=*v;
777          *v = new intvec( max(n-j,1) );
778          for (i=0,j=0;i<w->length();i++)
779          {
780            if((*w)[i]!=0)
781            {
782              (**v)[j]=(*w)[i]; j++;
783            }
784          }
785          delete w;
786        }
787      }
788      if (res->m[0]==NULL)
789      {
790        res->m[0]=pOne();
791      }
792    }
793  }
794notImpl:
795  if (res==NULL)
796    WerrorS( feNotImplemented );
797  if (NN!=NULL)
798  {
799    pMultN(f,NN);
800    nDelete(&NN);
801  }
802  if (N!=NULL)
803  {
804    nDelete(&N);
805  }
806  return res;
807}
808
809matrix singclap_irrCharSeries ( ideal I)
810{
811#ifdef HAVE_LIBFAC_P
812  // for now there is only the possibility to handle polynomials over
813  // Q and Fp ...
814  matrix res=NULL;
815  int i;
816  Off(SW_RATIONAL);
817  On(SW_SYMMETRIC_FF);
818  CFList L;
819  ListCFList LL;
820  if (((nGetChar() == 0) || (nGetChar() > 1) )
821  && (currRing->parameter==NULL))
822  {
823    setCharacteristic( nGetChar() );
824    for(i=0;i<IDELEMS(I);i++)
825    {
826      if (I->m[i]!=NULL)
827        L.append(convSingPClapP(I->m[i]));
828    }
829  }
830  // and over Q(a) / Fp(a)
831  else if (( nGetChar()==1 ) /* Q(a) */
832  || (nGetChar() <-1))       /* Fp(a) */
833  {
834    if (nGetChar()==1) setCharacteristic( 0 );
835    else               setCharacteristic( -nGetChar() );
836    for(i=0;i<IDELEMS(I);i++)
837    {
838      if (I->m[i]!=NULL)
839        L.append(convSingTrPClapP(I->m[i]));
840    }
841  }
842  else
843  {
844    WerrorS( feNotImplemented );
845    return res;
846  }
847
848  LL=IrrCharSeries(L);
849  int m= LL.length(); // Anzahl Zeilen
850  int n=0;
851  ListIterator<CFList> LLi;
852  CFListIterator Li;
853  for ( LLi = LL; LLi.hasItem(); LLi++ )
854  {
855    n = max(LLi.getItem().length(),n);
856  }
857  if ((m==0) || (n==0))
858  {
859    Warn("char_series returns %d x %d matrix from %d input polys (%d)\n",m,n,IDELEMS(I)+1,LL.length());
860    iiWriteMatrix((matrix)I,"I",2,0);
861    m=max(m,1);
862    n=max(n,1);
863  }
864  res=mpNew(m,n);
865  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
866  {
867    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
868    {
869      if ( (nGetChar() == 0) || (nGetChar() > 1) )
870        MATELEM(res,m,n)=convClapPSingP(Li.getItem());
871      else
872        MATELEM(res,m,n)=convClapPSingTrP(Li.getItem());
873    }
874  }
875  Off(SW_RATIONAL);
876  return res;
877#else
878  return NULL;
879#endif
880}
881
882char* singclap_neworder ( ideal I)
883{
884#ifdef HAVE_LIBFAC_P
885  int i;
886  Off(SW_RATIONAL);
887  On(SW_SYMMETRIC_FF);
888  CFList L;
889  if (((nGetChar() == 0) || (nGetChar() > 1) )
890  && (currRing->parameter==NULL))
891  {
892    setCharacteristic( nGetChar() );
893    for(i=0;i<IDELEMS(I);i++)
894    {
895      L.append(convSingPClapP(I->m[i]));
896    }
897  }
898  // and over Q(a) / Fp(a)
899  else if (( nGetChar()==1 ) /* Q(a) */
900  || (nGetChar() <-1))       /* Fp(a) */
901  {
902    if (nGetChar()==1) setCharacteristic( 0 );
903    else               setCharacteristic( -nGetChar() );
904    for(i=0;i<IDELEMS(I);i++)
905    {
906      L.append(convSingTrPClapP(I->m[i]));
907    }
908  }
909  else
910  {
911    WerrorS( feNotImplemented );
912    return NULL;
913  }
914
915  List<int> IL=neworderint(L);
916  ListIterator<int> Li;
917  StringSet("");
918  Li = IL;
919  int offs=rPar(currRing);
920  int* mark=(int*)Alloc0((pVariables+offs)*sizeof(int));
921  int cnt=pVariables+offs;
922  loop
923  {
924    i=Li.getItem()-1;
925    mark[i]=1;
926    if (i<offs)
927    {
928      StringAppend(currRing->parameter[i]);
929    }
930    else
931    {
932      StringAppend(currRing->names[i-offs]);
933    }
934    Li++;
935    cnt--;
936    if(cnt==0) break;
937    StringAppend(",");
938    if(! Li.hasItem()) break;
939  }
940  for(i=0;i<pVariables+offs;i++)
941  {
942    if(mark[i]==0)
943    {
944      if (i<offs)
945      {
946        StringAppend(currRing->parameter[i]);
947      }
948      else
949      {
950        StringAppend(currRing->names[i-offs]);
951      }
952      cnt--;
953      if(cnt==0) break;
954      StringAppend(",");
955    }
956  }
957  return mstrdup(StringAppend(""));
958#else
959  return NULL;
960#endif
961}
962
963BOOLEAN singclap_isSqrFree(poly f)
964{
965  BOOLEAN b=FALSE;
966  Off(SW_RATIONAL);
967  //  Q / Fp
968  if (((nGetChar() == 0) || (nGetChar() > 1) )
969  &&(currRing->parameter==NULL))
970  {
971    setCharacteristic( nGetChar() );
972    CanonicalForm F( convSingPClapP( f ) );
973    if((nGetChar()>1)&&(!F.isUnivariate()))
974      goto err;
975    b=(BOOLEAN)isSqrFree(F);
976  }
977  // and over Q(a) / Fp(a)
978  else if (( nGetChar()==1 ) /* Q(a) */
979  || (nGetChar() <-1))       /* Fp(a) */
980  {
981    if (nGetChar()==1) setCharacteristic( 0 );
982    else               setCharacteristic( -nGetChar() );
983    //if (currRing->minpoly!=NULL)
984    //{
985    //  CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
986    //  Variable a=rootOf(mipo);
987    //  CanonicalForm F( convSingAPClapAP( f,a ) );
988    //  ...
989    //}
990    //else
991    {
992      CanonicalForm F( convSingTrPClapP( f ) );
993      b=(BOOLEAN)isSqrFree(F);
994    }
995    Off(SW_RATIONAL);
996  }
997  else
998  {
999err:
1000    WerrorS( feNotImplemented );
1001  }
1002  return b;
1003}
1004
1005poly singclap_det( const matrix m )
1006{
1007  int r=m->rows();
1008  if (r!=m->cols())
1009  {
1010    Werror("det of %d x %d matrix",r,m->cols());
1011    return NULL;
1012  }
1013  poly res=NULL;
1014  if (( nGetChar() == 0 || nGetChar() > 1 )
1015  && (currRing->parameter==NULL))
1016  {
1017    setCharacteristic( nGetChar() );
1018    CFMatrix M(r,r);
1019    int i,j;
1020    for(i=r;i>0;i--)
1021    {
1022      for(j=r;j>0;j--)
1023      {
1024        M(i,j)=convSingPClapP(MATELEM(m,i,j));
1025      }
1026    }
1027    res= convClapPSingP( determinant(M,r) ) ;
1028  }
1029  // and over Q(a) / Fp(a)
1030  else if (( nGetChar()==1 ) /* Q(a) */
1031  || (nGetChar() <-1))       /* Fp(a) */
1032  {
1033    if (nGetChar()==1) setCharacteristic( 0 );
1034    else               setCharacteristic( -nGetChar() );
1035    CFMatrix M(r,r);
1036    poly res;
1037    if (currRing->minpoly!=NULL)
1038    {
1039      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1040      Variable a=rootOf(mipo);
1041      int i,j;
1042      for(i=r;i>0;i--)
1043      {
1044        for(j=r;j>0;j--)
1045        {
1046          M(i,j)=convSingAPClapAP(MATELEM(m,i,j),a);
1047        }
1048      }
1049      res= convClapAPSingAP( determinant(M,r) ) ;
1050    }
1051    else
1052    {
1053      int i,j;
1054      for(i=r;i>0;i--)
1055      {
1056        for(j=r;j>0;j--)
1057        {
1058          M(i,j)=convSingTrPClapP(MATELEM(m,i,j));
1059        }
1060      }
1061      res= convClapPSingTrP( determinant(M,r) );
1062    }
1063  }
1064  else
1065    WerrorS( feNotImplemented );
1066  Off(SW_RATIONAL);
1067  return res;
1068}
1069
1070int singclap_det_i( intvec * m )
1071{
1072  setCharacteristic( 0 );
1073  CFMatrix M(m->rows(),m->cols());
1074  int i,j;
1075  for(i=m->rows();i>0;i--)
1076  {
1077    for(j=m->cols();j>0;j--)
1078    {
1079      M(i,j)=IMATELEM(*m,i,j);
1080    }
1081  }
1082  int res= convClapISingI( determinant(M,m->rows())) ;
1083  Off(SW_RATIONAL);
1084  return res;
1085}
1086/*==============================================================*/
1087/* interpreter interface : */
1088BOOLEAN jjGCD_P(leftv res, leftv u, leftv v)
1089{
1090  res->data=(void *)singclap_gcd((poly)(u->CopyD()),((poly)v->CopyD()));
1091  return FALSE;
1092}
1093
1094BOOLEAN jjFAC_P(leftv res, leftv u)
1095{
1096  intvec *v=NULL;
1097  ideal f=singclap_factorize((poly)(u->Data()), &v, 0);
1098  if (f==NULL) return TRUE;
1099  lists l=(lists)Alloc(sizeof(slists));
1100  l->Init(2);
1101  l->m[0].rtyp=IDEAL_CMD;
1102  l->m[0].data=(void *)f;
1103  l->m[1].rtyp=INTVEC_CMD;
1104  l->m[1].data=(void *)v;
1105  res->data=(void *)l;
1106  return FALSE;
1107}
1108
1109BOOLEAN jjSQR_FREE_DEC(leftv res, leftv u,leftv dummy)
1110{
1111  intvec *v=NULL;
1112  int sw=(int)dummy->Data();
1113  ideal f=singclap_factorize((poly)(u->Data()), &v, sw);
1114  if (f==NULL)
1115    return TRUE;
1116  switch(sw)
1117  {
1118    case 0:
1119    case 2:
1120    {
1121      lists l=(lists)Alloc(sizeof(slists));
1122      l->Init(2);
1123      l->m[0].rtyp=IDEAL_CMD;
1124      l->m[0].data=(void *)f;
1125      l->m[1].rtyp=INTVEC_CMD;
1126      l->m[1].data=(void *)v;
1127      res->data=(void *)l;
1128      res->rtyp=LIST_CMD;
1129      return FALSE;
1130    }
1131    case 1:
1132      res->data=(void *)f;
1133      return FALSE;
1134    case 3:
1135      {
1136        poly p=f->m[0];
1137        int i=IDELEMS(f);
1138        f->m[0]=NULL;
1139        while(i>1)
1140        {
1141          i--;
1142          p=pMult(p,f->m[i]);
1143          f->m[i]=NULL;
1144        }
1145        res->data=(void *)p;
1146        res->rtyp=POLY_CMD;
1147      }
1148      return FALSE;
1149  }
1150  WerrorS("invalid switch");
1151  return TRUE;
1152}
1153
1154#if 0
1155BOOLEAN jjIS_SQR_FREE(leftv res, leftv u)
1156{
1157  BOOLEAN b=singclap_factorize((poly)(u->Data()), &v, 0);
1158  res->data=(void *)b;
1159}
1160#endif
1161
1162BOOLEAN jjEXTGCD_P(leftv res, leftv u, leftv v)
1163{
1164  res->data=singclap_extgcd((poly)u->Data(),(poly)v->Data());
1165  return (res->data==NULL);
1166}
1167BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w)
1168{
1169  res->data=singclap_resultant((poly)u->Data(),(poly)v->Data(), (poly)w->Data());
1170  return errorreported;
1171}
1172BOOLEAN jjCHARSERIES(leftv res, leftv u)
1173{
1174  res->data=singclap_irrCharSeries((ideal)u->Data());
1175  return (res->data==NULL);
1176}
1177
1178alg singclap_alglcm ( alg f, alg g )
1179{
1180 FACTORY_ALGOUT( "f", f );
1181 FACTORY_ALGOUT( "g", g );
1182
1183 // over Q(a) / Fp(a)
1184 if (nGetChar()==1) setCharacteristic( 0 );
1185 else               setCharacteristic( -nGetChar() );
1186 alg res;
1187
1188 if (currRing->minpoly!=NULL)
1189 {
1190   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1191   Variable a=rootOf(mipo);
1192   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1193   CanonicalForm GCD;
1194
1195   TIMING_START( algLcmTimer );
1196   // calculate gcd
1197#ifdef FACTORY_GCD_TEST
1198   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1199#else
1200   GCD = gcd( F, G );
1201#endif
1202   TIMING_END( algLcmTimer );
1203
1204   FACTORY_CFAOUT( "d", GCD );
1205   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1206
1207   // calculate lcm
1208   res= convClapASingA( (F/GCD)*G );
1209 }
1210 else
1211 {
1212   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1213   CanonicalForm GCD;
1214   TIMING_START( algLcmTimer );
1215   // calculate gcd
1216#ifdef FACTORY_GCD_TEST
1217   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1218#else
1219   GCD = gcd( F, G );
1220#endif
1221   TIMING_END( algLcmTimer );
1222
1223   FACTORY_CFTROUT( "d", GCD );
1224   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1225
1226   // calculate lcm
1227   res= convClapPSingTr( (F/GCD)*G );
1228 }
1229
1230 Off(SW_RATIONAL);
1231 return res;
1232}
1233
1234void singclap_algdividecontent ( alg f, alg g, alg &ff, alg &gg )
1235{
1236 FACTORY_ALGOUT( "f", f );
1237 FACTORY_ALGOUT( "g", g );
1238
1239 // over Q(a) / Fp(a)
1240 if (nGetChar()==1) setCharacteristic( 0 );
1241 else               setCharacteristic( -nGetChar() );
1242 ff=gg=NULL;
1243
1244 if (currRing->minpoly!=NULL)
1245 {
1246   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1247   Variable a=rootOf(mipo);
1248   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1249   CanonicalForm GCD;
1250
1251   TIMING_START( algContentTimer );
1252#ifdef FACTORY_GCD_TEST
1253   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1254#else
1255   GCD=gcd( F, G );
1256#endif
1257   TIMING_END( algContentTimer );
1258
1259   FACTORY_CFAOUT( "d", GCD );
1260   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1261
1262   if (GCD!=1)
1263   {
1264     ff= convClapASingA( F/ GCD );
1265     gg= convClapASingA( G/ GCD );
1266   }
1267 }
1268 else
1269 {
1270   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1271   CanonicalForm GCD;
1272
1273   TIMING_START( algContentTimer );
1274#ifdef FACTORY_GCD_TEST
1275   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1276#else
1277   GCD=gcd( F, G );
1278#endif
1279   TIMING_END( algContentTimer );
1280
1281   FACTORY_CFTROUT( "d", GCD );
1282   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1283
1284   if (GCD!=1)
1285   {
1286     ff= convClapPSingTr( F/ GCD );
1287     gg= convClapPSingTr( G/ GCD );
1288   }
1289 }
1290
1291 Off(SW_RATIONAL);
1292}
1293#endif
Note: See TracBrowser for help on using the repository browser.