source: git/kernel/clapsing.cc @ 91cb92

spielwiese
Last change on this file since 91cb92 was 91cb92, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: off-by-1 git-svn-id: file:///usr/local/Singular/svn/trunk@10507 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 39.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.25 2008-01-15 15:25:44 Singular Exp $
6/*
7* ABSTRACT: interface between Singular and factory
8*/
9
10//#define FACTORIZE2_DEBUG
11#include "mod2.h"
12#include "omalloc.h"
13#ifdef HAVE_FACTORY
14#define SI_DONT_HAVE_GLOBAL_VARS
15#include "structs.h"
16#include "clapsing.h"
17#include "numbers.h"
18#include "ring.h"
19#include <factory.h>
20#include "clapconv.h"
21#ifdef HAVE_LIBFAC_P
22#include <factor.h>
23//CanonicalForm algcd(const CanonicalForm & F, const CanonicalForm & g, const CFList & as, const Varlist & order);
24CanonicalForm alg_gcd(const CanonicalForm &, const CanonicalForm &, const CFList &);
25#endif
26#include "ring.h"
27
28//
29// FACTORY_GCD_TEST: use new gcd instead of old one.  Does not work
30//   without new gcd-implementation which is not publicly available.
31//
32// FACTORY_GCD_STAT: print statistics on polynomials.  Works only
33//   with the file `gcd_stat.cc' and `gcd_stat.h which may be found
34//   in the repository, module `factory-devel'.
35//   Overall statistics may printed using `system("gcdstat");'.
36//
37// FACTORY_GCD_TIMING: accumulate time used for gcd calculations.
38//   Time may be printed (and reset) with `system("gcdtime");'.
39//   For this define, `timing.h' from the factory source directory
40//   has to be copied to the Singular source directory.
41//   Note: for better readability, the macros `TIMING_START()' and
42//   `TIMING_END()' are used in any case.  However, they expand to
43//   nothing if `FACTORY_GCD_TIMING' is off.
44//
45// FACTORY_GCD_DEBOUT: print polynomials involved in gcd calculations.
46//   The polynomials are printed by means of the macros
47//   `FACTORY_*OUT_POLY' which are defined to be empty if
48//   `FACTORY_GCD_DEBOUT' is off.
49//
50// FACTORY_GCD_DEBOUT_PATTERN: print degree patterns of polynomials
51//   involved in gcd calculations.
52//   The patterns are printed by means of the macros
53//   `FACTORY_*OUT_PAT' which are defined to be empty if
54//   `FACTORY_GCD_DEBOUT_PATTERN' is off.
55//
56//   A degree pattern looks like this:
57//
58//   totDeg  size    deg(v1) deg(v2) ...
59//
60//   where "totDeg" means total degree, "size" the number of terms,
61//   and "deg(vi)" is the degree with respect to variable i.
62//   In univariate case, the "deg(vi)" are missing.  For this feature
63//   you need the files `gcd_stat.cc' and `gcd_stat.h'.
64//
65//
66// And here is what the functions print if `FACTORY_GCD_DEBOUT' (1),
67// `FACTORY_GCD_STAT' (2), or `FACTORY_GCD_DEBOUT_PATTERN' (3) is on:
68//
69// sinclap_divide_content:
70// (1) G = <firstCoeff>
71// (3) G#= <firstCoeff, pattern>
72// (1) h = <nextCoeff>
73// (3) h#= <nextCoeff, pattern>
74// (2) gcnt: <statistics on gcd as explained above>
75// (1) g = <intermediateResult>
76// (3) g#= <intermediateResult, pattern>
77// (1) h = <nextCoeff>
78// (3) h#= <nextCoeff, pattern>
79// (2) gcnt: <statistics on gcd as explained above>
80//  ...
81// (1) h = <lastCoeff>
82// (3) h#= <lastCoeff, pattern>
83// (1) g = <finalResult>
84// (3) g#= <finalResult, pattern>
85// (2) gcnt: <statistics on gcd as explained above>
86// (2) cont: <statistics on content as explained above>
87//
88// singclap_alglcm:
89// (1) f = <inputPolyF>
90// (3) f#= <inputPolyF, pattern>
91// (1) g = <inputPolyG>
92// (3) g#= <inputPolyG, pattern>
93// (1) d = <its gcd>
94// (3) d#= <its gcd, pattern>
95// (2) alcm: <statistics as explained above>
96//
97// singclap_algdividecontent:
98// (1) f = <inputPolyF>
99// (3) f#= <inputPolyF, pattern>
100// (1) g = <inputPolyG>
101// (3) g#= <inputPolyG, pattern>
102// (1) d = <its gcd>
103// (3) d#= <its gcd, pattern>
104// (2) acnt: <statistics as explained above>
105//
106
107#ifdef FACTORY_GCD_STAT
108#include "gcd_stat.h"
109#define FACTORY_GCDSTAT( tag, f, g, d ) \
110  printGcdStat( tag, f, g, d )
111#define FACTORY_CONTSTAT( tag, f ) \
112  printContStat( tag, f )
113#else
114#define FACTORY_GCDSTAT( tag, f, g, d )
115#define FACTORY_CONTSTAT( tag, f )
116#endif
117
118#ifdef FACTORY_GCD_TIMING
119#define TIMING
120#include "timing.h"
121TIMING_DEFINE_PRINT( contentTimer );
122TIMING_DEFINE_PRINT( algContentTimer );
123TIMING_DEFINE_PRINT( algLcmTimer );
124#else
125#define TIMING_START( timer )
126#define TIMING_END( timer )
127#endif
128
129#ifdef FACTORY_GCD_DEBOUT
130#include "longalg.h"
131#include "febase.h"
132// napoly f
133#define FACTORY_ALGOUT_POLY( tag, f ) \
134  StringSetS( tag ); \
135  napWrite( f ); \
136  pRINtS(StringAppendS("\n"));
137// CanonicalForm f, represents transcendent extension
138#define FACTORY_CFTROUT_POLY( tag, f ) \
139  { \
140    napoly F=convFactoryPSingTr( f ); \
141    StringSetS( tag ); \
142    napWrite( F ); \
143    PrintS(StringAppendS("\n")); \
144    napDelete(&F); \
145  }
146// CanonicalForm f, represents algebraic extension
147#define FACTORY_CFAOUT_POLY( tag, f ) \
148  { \
149    napoly F=convFactoryASingA( f ); \
150    StringSetS( tag ); \
151    napWrite( F ); \
152    PrintS(StringAppendS("\n")); \
153    napDelete(&F); \
154  }
155#else /* ! FACTORY_GCD_DEBOUT */
156#define FACTORY_ALGOUT_POLY( tag, f )
157#define FACTORY_CFTROUT_POLY( tag, f )
158#define FACTORY_CFAOUT_POLY( tag, f )
159#endif /* ! FACTORY_GCD_DEBOUT */
160
161#ifdef FACTORY_GCD_DEBOUT_PATTERN
162// napoly f
163#define FACTORY_ALGOUT_PAT( tag, f ) \
164  if (currRing->minpoly!=NULL) \
165  { \
166    CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z); \
167    Variable a=rootOf(mipo); \
168    printPolyPattern( tag, convSingAFactoryA( f,a ), rPar( currRing ) ); \
169  } \
170  else \
171  { \
172    printPolyPattern( tag, convSingTrFactoryP( f ), rPar( currRing ) ); \
173  }
174// CanonicalForm f, represents transcendent extension
175#define FACTORY_CFTROUT_PAT( tag, f ) printPolyPattern( tag, f, rPar( currRing ) )
176// CanonicalForm f, represents algebraic extension
177#define FACTORY_CFAOUT_PAT( tag, f ) printPolyPattern( tag, f, rPar( currRing ) )
178#else /* ! FACTORY_GCD_DEBOUT_PATTERN */
179#define FACTORY_ALGOUT_PAT( tag, f )
180#define FACTORY_CFTROUT_PAT( tag, f )
181#define FACTORY_CFAOUT_PAT( tag, f )
182#endif /* ! FACTORY_GCD_DEBOUT_PATTERN */
183
184// these macors combine both print macros
185#define FACTORY_ALGOUT( tag, f ) \
186  FACTORY_ALGOUT_POLY( tag " = ", f ); \
187  FACTORY_ALGOUT_PAT( tag "#= ", f )
188#define FACTORY_CFTROUT( tag, f ) \
189  FACTORY_CFTROUT_POLY( tag " = ", f ); \
190  FACTORY_CFTROUT_PAT( tag "#= ", f )
191#define FACTORY_CFAOUT( tag, f ) \
192  FACTORY_CFAOUT_POLY( tag " = ", f ); \
193  FACTORY_CFAOUT_PAT( tag "#= ", f )
194
195
196
197
198
199poly singclap_gcd ( poly f, poly g )
200{
201  poly res=NULL;
202
203  if (f!=NULL) pCleardenom(f);
204  if (g!=NULL) pCleardenom(g);
205  else         return pCopy(f); // g==0 => gcd=f (but do a pCleardenom)
206  if (f==NULL) return pCopy(g); // f==0 => gcd=g (but do a pCleardenom)
207
208  if (pIsConstantPoly(f) || pIsConstantPoly(g)) return pOne();
209
210  // for now there is only the possibility to handle polynomials over
211  // Q and Fp ...
212  Off(SW_RATIONAL);
213  if (( nGetChar() == 0 || nGetChar() > 1 )
214  && (currRing->parameter==NULL))
215  {
216    CanonicalForm newGCD(const CanonicalForm & A, const CanonicalForm & B);
217    setCharacteristic( nGetChar() );
218    CanonicalForm F( convSingPFactoryP( f ) ), G( convSingPFactoryP( g ) );
219    //if (nGetChar() > 1 )
220    //{
221    //  res=convFactoryPSingP( newGCD( F,G ));
222    //  if (!nGreaterZero(pGetCoeff(res))) res=pNeg(res);
223    //}
224    //else
225      res=convFactoryPSingP( gcd( F, G ) );
226  }
227  // and over Q(a) / Fp(a)
228  else if (( nGetChar()==1 ) /* Q(a) */
229  || (nGetChar() <-1))       /* Fp(a) */
230  {
231    if (nGetChar()==1) setCharacteristic( 0 );
232    else               setCharacteristic( -nGetChar() );
233    if (currRing->minpoly!=NULL)
234    {
235    #ifdef HAVE_LIBFAC_P
236      if ( nGetChar()==1 ) /* Q(a) */
237      {
238      //  WerrorS( feNotImplemented );
239        CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
240        //Varlist ord;
241        //ord.append(mipo.mvar());
242        CFList as(mipo);
243        Variable a=rootOf(mipo);
244        //CanonicalForm F( convSingAPFactoryAP( f,a ) ), G( convSingAPFactoryAP( g,a ) );
245        CanonicalForm F( convSingTrPFactoryP(f) ), G( convSingTrPFactoryP(g) );
246        //res= convFactoryAPSingAP( algcd( F, G, as, ord) );
247        //res= convFactoryAPSingAP( alg_gcd( F, G, as) );
248        res= convFactoryAPSingAP( alg_gcd( F, G, as) );
249      }
250      else
251      #endif
252      {
253        CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
254        Variable a=rootOf(mipo);
255        CanonicalForm F( convSingAPFactoryAP( f,a ) ), G( convSingAPFactoryAP( g,a ) );
256        res= convFactoryAPSingAP( gcd( F, G ) );
257      }
258    }
259    else
260    {
261      CanonicalForm F( convSingTrPFactoryP( f ) ), G( convSingTrPFactoryP( g ) );
262      res= convFactoryPSingTrP( gcd( F, G ) );
263    }
264  }
265  #if 0
266  else if (( nGetChar()>1 )&&(currRing->parameter!=NULL)) /* GF(q) */
267  {
268    int p=rChar(currRing);
269    int n=2;
270    int t=p*p;
271    while (t!=nChar) { t*=p;n++; }
272    setCharacteristic(p,n,'a');
273    CanonicalForm F( convSingGFFactoryGF( f ) ), G( convSingGFFactoryGF( g ) );
274    res= convFactoryGFSingGF( gcd( F, G ) );
275  }
276  #endif
277  else
278    WerrorS( feNotImplemented );
279
280  Off(SW_RATIONAL);
281  pDelete(&f);
282  pDelete(&g);
283  pTest(res);
284  return res;
285}
286
287/*2 find the maximal exponent of var(i) in poly p*/
288int pGetExp_Var(poly p, int i)
289{
290  int m=0;
291  int mm;
292  while (p!=NULL)
293  {
294    mm=pGetExp(p,i);
295    if (mm>m) m=mm;
296    pIter(p);
297  }
298  return m;
299}
300
301poly singclap_resultant ( poly f, poly g , poly x)
302{
303  int i=pIsPurePower(x);
304  if (i==0)
305  {
306    WerrorS("3rd argument must be a ring variable");
307    return NULL;
308  }
309  if ((f==NULL) || (g==NULL))
310    return NULL;
311  // for now there is only the possibility to handle polynomials over
312  // Q and Fp ...
313  if (( nGetChar() == 0 || nGetChar() > 1 )
314  && (currRing->parameter==NULL))
315  {
316    Variable X(i);
317    setCharacteristic( nGetChar() );
318    CanonicalForm F( convSingPFactoryP( f ) ), G( convSingPFactoryP( g ) );
319    poly res=convFactoryPSingP( resultant( F, G, X ) );
320    Off(SW_RATIONAL);
321    return res;
322  }
323  // and over Q(a) / Fp(a)
324  else if (( nGetChar()==1 ) /* Q(a) */
325  || (nGetChar() <-1))       /* Fp(a) */
326  {
327    if (nGetChar()==1) setCharacteristic( 0 );
328    else               setCharacteristic( -nGetChar() );
329    poly res;
330    Variable X(i+rPar(currRing));
331    if (currRing->minpoly!=NULL)
332    {
333      //Variable X(i);
334      CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
335      Variable a=rootOf(mipo);
336      CanonicalForm F( convSingAPFactoryAP( f,a ) ), G( convSingAPFactoryAP( g,a ) );
337      res= convFactoryAPSingAP( resultant( F, G, X ) );
338    }
339    else
340    {
341      //Variable X(i+rPar(currRing));
342      number nf,ng;
343      pCleardenom_n(f,nf);pCleardenom_n(g,ng);
344      int ef,eg;
345      ef=pGetExp_Var(f,i);
346      eg=pGetExp_Var(g,i);
347      CanonicalForm F( convSingTrPFactoryP( f ) ), G( convSingTrPFactoryP( g ) );
348      res= convFactoryPSingTrP( resultant( F, G, X ) );
349      if ((nf!=NULL)&&(!nIsOne(nf))&&(!nIsZero(nf)))
350      {
351        number n=nInvers(nf);
352        while(eg>0)
353        {
354          res=pMult_nn(res,n);
355          eg--;
356        }
357        nDelete(&n);
358      }
359      nDelete(&nf);
360      if ((ng!=NULL)&&(!nIsOne(ng))&&(!nIsZero(ng)))
361      {
362        number n=nInvers(ng);
363        while(ef>0)
364        {
365          res=pMult_nn(res,n);
366          ef--;
367        }
368        nDelete(&n);
369      }
370      nDelete(&ng);
371    }
372    Off(SW_RATIONAL);
373    return res;
374  }
375  else
376    WerrorS( feNotImplemented );
377  return NULL;
378}
379//poly singclap_resultant ( poly f, poly g , poly x)
380//{
381//  int i=pVar(x);
382//  if (i==0)
383//  {
384//    WerrorS("ringvar expected");
385//    return NULL;
386//  }
387//  ideal I=idInit(1,1);
388//
389//  // get the coeffs von f wrt. x:
390//  I->m[0]=pCopy(f);
391//  matrix ffi=mpCoeffs(I,i);
392//  ffi->rank=1;
393//  ffi->ncols=ffi->nrows;
394//  ffi->nrows=1;
395//  ideal fi=(ideal)ffi;
396//
397//  // get the coeffs von g wrt. x:
398//  I->m[0]=pCopy(g);
399//  matrix ggi=mpCoeffs(I,i);
400//  ggi->rank=1;
401//  ggi->ncols=ggi->nrows;
402//  ggi->nrows=1;
403//  ideal gi=(ideal)ggi;
404//
405//  // contruct the matrix:
406//  int fn=IDELEMS(fi); //= deg(f,x)+1
407//  int gn=IDELEMS(gi); //= deg(g,x)+1
408//  matrix m=mpNew(fn+gn-2,fn+gn-2);
409//  if(m==NULL)
410//  {
411//    return NULL;
412//  }
413//
414//  // enter the coeffs into m:
415//  int j;
416//  for(i=0;i<gn-1;i++)
417//  {
418//    for(j=0;j<fn;j++)
419//    {
420//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
421//    }
422//  }
423//  for(i=0;i<fn-1;i++)
424//  {
425//    for(j=0;j<gn;j++)
426//    {
427//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
428//    }
429//  }
430//
431//  poly r=mpDet(m);
432//
433//  idDelete(&fi);
434//  idDelete(&gi);
435//  idDelete((ideal *)&m);
436//  return r;
437//}
438
439BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb )
440{
441  // for now there is only the possibility to handle univariate
442  // polynomials over
443  // Q and Fp ...
444  res=NULL;pa=NULL;pb=NULL;
445  On(SW_SYMMETRIC_FF);
446  if (( nGetChar() == 0 || nGetChar() > 1 )
447  && (currRing->parameter==NULL))
448  {
449    setCharacteristic( nGetChar() );
450    CanonicalForm F( convSingPFactoryP( f ) ), G( convSingPFactoryP( g ) );
451    CanonicalForm FpG=F+G;
452    if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
453    //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
454    {
455      Off(SW_RATIONAL);
456      WerrorS("not univariate");
457      return TRUE;
458    }
459    CanonicalForm Fa,Gb;
460    On(SW_RATIONAL);
461    res=convFactoryPSingP( extgcd( F, G, Fa, Gb ) );
462    pa=convFactoryPSingP(Fa);
463    pb=convFactoryPSingP(Gb);
464    Off(SW_RATIONAL);
465  }
466  // and over Q(a) / Fp(a)
467  else if (( nGetChar()==1 ) /* Q(a) */
468  || (nGetChar() <-1))       /* Fp(a) */
469  {
470    if (nGetChar()==1) setCharacteristic( 0 );
471    else               setCharacteristic( -nGetChar() );
472    CanonicalForm Fa,Gb;
473    if (currRing->minpoly!=NULL)
474    {
475      CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
476      Variable a=rootOf(mipo);
477      CanonicalForm F( convSingAPFactoryAP( f,a ) ), G( convSingAPFactoryAP( g,a ) );
478      CanonicalForm FpG=F+G;
479      if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
480      //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
481      {
482        WerrorS("not univariate");
483        return TRUE;
484      }
485      res= convFactoryAPSingAP( extgcd( F, G, Fa, Gb ) );
486      pa=convFactoryAPSingAP(Fa);
487      pb=convFactoryAPSingAP(Gb);
488    }
489    else
490    {
491      CanonicalForm F( convSingTrPFactoryP( f ) ), G( convSingTrPFactoryP( g ) );
492      CanonicalForm FpG=F+G;
493      if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
494      //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
495      {
496        Off(SW_RATIONAL);
497        WerrorS("not univariate");
498        return TRUE;
499      }
500      res= convFactoryPSingTrP( extgcd( F, G, Fa, Gb ) );
501      pa=convFactoryPSingTrP(Fa);
502      pb=convFactoryPSingTrP(Gb);
503    }
504    Off(SW_RATIONAL);
505  }
506  else
507  {
508    WerrorS( feNotImplemented );
509    return TRUE;
510  }
511  return FALSE;
512}
513
514poly singclap_pdivide ( poly f, poly g )
515{
516  // for now there is only the possibility to handle polynomials over
517  // Q and Fp ...
518  poly res=NULL;
519  On(SW_RATIONAL);
520  if (( nGetChar() == 0 || nGetChar() > 1 )
521  && (currRing->parameter==NULL))
522  {
523    setCharacteristic( nGetChar() );
524    CanonicalForm F( convSingPFactoryP( f ) ), G( convSingPFactoryP( g ) );
525    res = convFactoryPSingP( F / G );
526  }
527  // and over Q(a) / Fp(a)
528  else if (( nGetChar()==1 ) /* Q(a) */
529  || (nGetChar() <-1))       /* Fp(a) */
530  {
531    if (nGetChar()==1) setCharacteristic( 0 );
532    else               setCharacteristic( -nGetChar() );
533    if (currRing->minpoly!=NULL)
534    {
535      CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
536      Variable a=rootOf(mipo);
537      CanonicalForm F( convSingAPFactoryAP( f,a ) ), G( convSingAPFactoryAP( g,a ) );
538      res= convFactoryAPSingAP(  F / G  );
539    }
540    else
541    {
542      CanonicalForm F( convSingTrPFactoryP( f ) ), G( convSingTrPFactoryP( g ) );
543      res= convFactoryPSingTrP(  F / G  );
544    }
545  }
546  else
547    WerrorS( feNotImplemented );
548  Off(SW_RATIONAL);
549  return res;
550}
551
552void singclap_divide_content ( poly f )
553{
554  if ( f==NULL )
555  {
556    return;
557  }
558  else  if ( pNext( f ) == NULL )
559  {
560    pSetCoeff( f, nInit( 1 ) );
561    return;
562  }
563  else
564  {
565    if ( nGetChar() == 1 )
566      setCharacteristic( 0 );
567    else  if ( nGetChar() == -1 )
568      return; /* not implemented for R */
569    else  if ( nGetChar() < 0 )
570      setCharacteristic( -nGetChar() );
571    else if (currRing->parameter==NULL) /* not GF(q) */
572      setCharacteristic( nGetChar() );
573    else
574      return; /* not implemented*/
575
576    CFList L;
577    CanonicalForm g, h;
578    poly p = pNext(f);
579
580    // first attemp: find 2 smallest g:
581
582    number g1=pGetCoeff(f);
583    number g2=pGetCoeff(p); // p==pNext(f);
584    pIter(p);
585    int sz1=nSize(g1);
586    int sz2=nSize(g2);
587    if (sz1>sz2)
588    {
589      number gg=g1;
590      g1=g2; g2=gg;
591      int sz=sz1;
592      sz1=sz2; sz2=sz;
593    }
594    while (p!=NULL)
595    {
596      int n_sz=nSize(pGetCoeff(p));
597      if (n_sz<sz1)
598      {
599        sz2=sz1;
600        g2=g1;
601        g1=pGetCoeff(p);
602        sz1=n_sz;
603        if (sz1<=3) break;
604      }
605      else if(n_sz<sz2)
606      {
607        sz2=n_sz;
608        g2=pGetCoeff(p);
609        sz2=n_sz;
610      }
611      pIter(p);
612    }
613    FACTORY_ALGOUT( "G", ((lnumber)g1)->z );
614    g = convSingTrFactoryP( ((lnumber)g1)->z );
615    g = gcd( g, convSingTrFactoryP( ((lnumber)g2)->z ));
616
617    // second run: gcd's
618
619    p = f;
620    TIMING_START( contentTimer );
621    while ( (p != NULL) && (g != 1)  && ( g != 0))
622    {
623      FACTORY_ALGOUT( "h", (((lnumber)pGetCoeff(p))->z) );
624      h = convSingTrFactoryP( ((lnumber)pGetCoeff(p))->z );
625      pIter( p );
626#ifdef FACTORY_GCD_STAT
627      // save g
628      CanonicalForm gOld = g;
629#endif
630
631#ifdef FACTORY_GCD_TEST
632      g = CFPrimitiveGcdUtil::gcd( g, h );
633#else
634      g = gcd( g, h );
635#endif
636
637      FACTORY_GCDSTAT( "gcnt:", gOld, h, g );
638      FACTORY_CFTROUT( "g", g );
639      L.append( h );
640    }
641    TIMING_END( contentTimer );
642    FACTORY_CONTSTAT( "cont:", g );
643    if (( g == 1 ) || (g == 0))
644    {
645      // pTest(f);
646      return;
647    }
648    else
649    {
650      CFListIterator i;
651      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
652      {
653        lnumber c=(lnumber)pGetCoeff(p);
654        napDelete(&c->z);
655        c->z=convFactoryPSingTr( i.getItem() / g );
656        //nTest((number)c);
657        //#ifdef LDEBUG
658        //number cn=(number)c;
659        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
660        //nWrite(cn);PrintS(StringAppend("\n"));
661        //#endif
662      }
663    }
664    // pTest(f);
665  }
666}
667
668static int primepower(int c)
669{
670  int p=1;
671  int cc=c;
672  while(cc!= rInternalChar(currRing)) { cc*=c; p++; }
673  return p;
674}
675
676BOOLEAN count_Factors(ideal I, intvec *v,int j, poly &f, poly fac)
677{
678  pTest(f);
679  pTest(fac);
680  int e=0;
681  if (!pIsConstantPoly(fac))
682  {
683#ifdef FACTORIZE2_DEBUG
684    printf("start count_Factors(%d), Fdeg=%d, factor deg=%d\n",j,pTotaldegree(f),pTotaldegree(fac));
685    p_wrp(fac,currRing);PrintLn();
686#endif
687    On(SW_RATIONAL);
688    CanonicalForm F, FAC,Q,R;
689    Variable a;
690    if (( nGetChar() == 0 || nGetChar() > 1 )
691    && (currRing->parameter==NULL))
692    {
693      F=convSingPFactoryP( f );
694      FAC=convSingPFactoryP( fac );
695    }
696    // and over Q(a) / Fp(a)
697    else if (( nGetChar()==1 ) /* Q(a) */
698    || (nGetChar() <-1))       /* Fp(a) */
699    {
700      if (currRing->minpoly!=NULL)
701      {
702        CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
703        a=rootOf(mipo);
704        F=convSingAPFactoryAP( f,a );
705        FAC=convSingAPFactoryAP( fac,a );
706      }
707      else
708      {
709        F=convSingTrPFactoryP( f );
710        FAC=convSingTrPFactoryP( fac );
711      }
712    }
713    else
714      WerrorS( feNotImplemented );
715
716    poly q;
717    loop
718    {
719      Q=F;
720      Q/=FAC;
721      R=Q;
722      R*=FAC;
723      R-=F;
724      if (R.isZero())
725      {
726        if (( nGetChar() == 0 || nGetChar() > 1 )
727        && (currRing->parameter==NULL))
728        {
729          q = convFactoryPSingP( Q );
730        }
731        else if (( nGetChar()==1 ) /* Q(a) */
732        || (nGetChar() <-1))       /* Fp(a) */
733        {
734          if (currRing->minpoly!=NULL)
735          {
736            q= convFactoryAPSingAP(  Q  );
737          }
738          else
739          {
740            q= convFactoryPSingTrP(  Q  );
741          }
742        }
743        e++; pDelete(&f); f=q; q=NULL; F=Q;
744      }
745      else
746      {
747        break;
748      }
749    }
750    if (e==0)
751    {
752      Off(SW_RATIONAL);
753      return FALSE;
754    }
755  }
756  else e=1;
757  I->m[j]=fac;
758  if (v!=NULL) (*v)[j]=e;
759  Off(SW_RATIONAL);
760  return TRUE;
761}
762
763int singclap_factorize_retry;
764#ifdef HAVE_LIBFAC_P
765extern int libfac_interruptflag;
766#endif
767
768ideal singclap_factorize ( poly f, intvec ** v , int with_exps)
769{
770  pTest(f);
771#ifdef FACTORIZE2_DEBUG
772  printf("singclap_factorize, degree %d\n",pTotaldegree(f));
773#endif
774  // with_exps: 3,1 return only true factors, no exponents
775  //            2 return true factors and exponents
776  //            0 return coeff, factors and exponents
777  BOOLEAN save_errorreported=errorreported;
778
779  ideal res=NULL;
780
781  // handle factorize(0) =========================================
782  if (f==NULL)
783  {
784    res=idInit(1,1);
785    if (with_exps!=1)
786    {
787      (*v)=new intvec(1);
788      (**v)[0]=1;
789    }
790    return res;
791  }
792  // handle factorize(mon) =========================================
793  if (pNext(f)==NULL)
794  {
795    int i=0;
796    int n=0;
797    int e;
798    for(i=pVariables;i>0;i--) if(pGetExp(f,i)!=0) n++;
799    if (with_exps==0) n++; // with coeff
800    res=idInit(si_max(n,1),1);
801    switch(with_exps)
802    {
803      case 0: // with coef & exp.
804        res->m[0]=pOne();
805        pSetCoeff(res->m[0],nCopy(pGetCoeff(f)));
806        // no break
807      case 2: // with exp.
808        (*v)=new intvec(si_max(1,n));
809        (**v)[0]=1;
810        // no break
811      case 1: ;
812      #ifdef TEST
813      default: ;
814      #endif
815    }
816    if (n==0)
817    {
818      res->m[0]=pOne();
819      // (**v)[0]=1; is already done
820      return res;
821    }
822    for(i=pVariables;i>0;i--)
823    {
824      e=pGetExp(f,i);
825      if(e!=0)
826      {
827        n--;
828        poly p=pOne();
829        pSetExp(p,i,1);
830        pSetm(p);
831        res->m[n]=p;
832        if (with_exps!=1) (**v)[n]=e;
833      }
834    }
835    return res;
836  }
837  //PrintS("S:");pWrite(f);PrintLn();
838  // use factory/libfac in general ==============================
839  Off(SW_RATIONAL);
840  On(SW_SYMMETRIC_FF);
841  #ifdef HAVE_NTL
842  extern int prime_number;
843  if(rField_is_Q()) prime_number=0;
844  #endif
845  CFFList L;
846  number N=NULL;
847  number NN=NULL;
848  number old_lead_coeff=nCopy(pGetCoeff(f));
849
850  if (!rField_is_Zp() && !rField_is_Zp_a()) /* Q, Q(a) */
851  {
852    //if (f!=NULL) // already tested at start of routine
853    {
854      number n0=nCopy(pGetCoeff(f));
855      if (with_exps==0)
856        N=nCopy(n0);
857      pCleardenom(f);
858      NN=nDiv(n0,pGetCoeff(f));
859      nDelete(&n0);
860      if (with_exps==0)
861      {
862        nDelete(&N);
863        N=nCopy(NN);
864      }
865    }
866  }
867  else if (rField_is_Zp_a())
868  {
869    //if (f!=NULL) // already tested at start of routine
870    if (singclap_factorize_retry==0)
871    {
872      number n0=nCopy(pGetCoeff(f));
873      if (with_exps==0)
874        N=nCopy(n0);
875      pNorm(f);
876      pCleardenom(f);
877      NN=nDiv(n0,pGetCoeff(f));
878      nDelete(&n0);
879      if (with_exps==0)
880      {
881        nDelete(&N);
882        N=nCopy(NN);
883      }
884    }
885  }
886  if (rField_is_Q() || rField_is_Zp())
887  {
888    setCharacteristic( nGetChar() );
889    CanonicalForm F( convSingPFactoryP( f ) );
890    if (nGetChar()==0) /* Q */
891    {
892      L = factorize( F );
893    }
894    else /* Fp */
895    {
896#ifdef HAVE_LIBFAC_P
897      do
898      {
899        libfac_interruptflag=0;
900        L = Factorize( F );
901      }
902      while ((libfac_interruptflag!=0) ||(L.isEmpty()));
903#else
904      goto notImpl;
905#endif
906    }
907  }
908  #if 0
909  else if (rField_is_GF())
910  {
911    int c=rChar(currRing);
912    setCharacteristic( c, primepower(c) );
913    CanonicalForm F( convSingGFFactoryGF( f ) );
914    if (F.isUnivariate())
915    {
916      L = factorize( F );
917    }
918    else
919    {
920      goto notImpl;
921    }
922  }
923  #endif
924  // and over Q(a) / Fp(a)
925  else if (rField_is_Extension())
926  {
927    if (rField_is_Q_a()) setCharacteristic( 0 );
928    else                 setCharacteristic( -nGetChar() );
929    if (currRing->minpoly!=NULL)
930    {
931      CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
932      Variable a=rootOf(mipo);
933      CanonicalForm F( convSingAPFactoryAP( f,a ) );
934      L.insert(F);
935      if (rField_is_Zp_a() && F.isUnivariate())
936      {
937        L = factorize( F, a );
938      }
939      else
940      {
941        CanonicalForm G( convSingTrPFactoryP( f ) );
942#ifdef HAVE_LIBFAC_P
943        //  over Q(a) / multivariate over Fp(a)
944        do
945        {
946          libfac_interruptflag=0;
947          L=Factorize2(G, mipo);
948        }
949        while ((libfac_interruptflag!=0) ||(L.isEmpty()));
950        #ifdef FACTORIZE2_DEBUG
951        printf("while okay\n");
952        #endif
953        libfac_interruptflag=0;
954        //else
955        //  L=Factorize(G, mipo);
956#else
957        WarnS("complete factorization only for univariate polynomials");
958        if (rField_is_Q_a() ||(!F.isUnivariate())) /* Q(a) */
959        {
960          L = factorize( G );
961        }
962        else
963        {
964          L = factorize( G, a );
965        }
966#endif
967      }
968    }
969    else
970    {
971      CanonicalForm F( convSingTrPFactoryP( f ) );
972      if (rField_is_Q_a())
973      {
974        L = factorize( F );
975      }
976      else /* Fp(a) */
977      {
978#ifdef HAVE_LIBFAC_P
979        L = Factorize( F );
980#else
981        goto notImpl;
982#endif
983      }
984    }
985  }
986  else
987  {
988    goto notImpl;
989  }
990  {
991    poly ff=pCopy(f); // a copy for the retry stuff
992    // the first factor should be a constant
993    if ( ! L.getFirst().factor().inCoeffDomain() )
994      L.insert(CFFactor(1,1));
995    // convert into ideal
996    int n = L.length();
997    if (n==0) n=1;
998    CFFListIterator J=L;
999    int j=0;
1000    if (with_exps!=1)
1001    {
1002      if ((with_exps==2)&&(n>1))
1003      {
1004        n--;
1005        J++;
1006      }
1007      *v = new intvec( n );
1008    }
1009    res = idInit( n ,1);
1010    for ( ; J.hasItem(); J++, j++ )
1011    {
1012      poly p;
1013      if (with_exps!=1) (**v)[j] = J.getItem().exp();
1014      if (rField_is_Zp() || rField_is_Q())           /* Q, Fp */
1015        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
1016        res->m[j] = convFactoryPSingP( J.getItem().factor() );
1017      #if 0
1018      else if (rField_is_GF())
1019        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
1020      #endif
1021      else if (rField_is_Extension())     /* Q(a), Fp(a) */
1022      {
1023        intvec *w=NULL;
1024        if (v!=NULL) w=*v;
1025        if (currRing->minpoly==NULL)
1026          count_Factors(res,w,j,ff,convFactoryPSingTrP( J.getItem().factor() ));
1027        else
1028          count_Factors(res,w,j,ff,convFactoryAPSingAP( J.getItem().factor() ));
1029      }
1030    }
1031    if (rField_is_Extension() && (!pIsConstantPoly(ff)))
1032    {
1033      singclap_factorize_retry++;
1034      if (singclap_factorize_retry<3)
1035      {
1036        int jj;
1037        #ifdef FACTORIZE2_DEBUG
1038        printf("factorize_retry\n");
1039        #endif
1040        intvec *ww=NULL;
1041        idTest(res);
1042        ideal h=singclap_factorize ( ff, &ww , with_exps);
1043        idTest(h);
1044        int l=(*v)->length();
1045        (*v)->resize(l+ww->length());
1046        for(jj=0;jj<ww->length();jj++)
1047          (**v)[jj+l]=(*ww)[jj];
1048        delete ww;
1049        ideal hh=idInit(IDELEMS(res)+IDELEMS(h),1);
1050        for(jj=IDELEMS(res)-1;jj>=0;jj--)
1051        {
1052          hh->m[jj]=res->m[jj];
1053          res->m[jj]=NULL;
1054        }
1055        for(jj=IDELEMS(h)-1;jj>=0;jj--)
1056        {
1057          hh->m[jj+IDELEMS(res)]=h->m[jj];
1058          h->m[jj]=NULL;
1059        }
1060        idDelete(&res);
1061        idDelete(&h);
1062        res=hh;
1063        idTest(res);
1064        ff=NULL;
1065      }
1066      else
1067      {
1068        WarnS("problem with factorize");
1069      }
1070    }
1071    pDelete(&ff);
1072    if (N!=NULL)
1073    {
1074      pMult_nn(res->m[0],N);
1075      nDelete(&N);
1076      N=NULL;
1077    }
1078    // delete constants
1079    if (res!=NULL)
1080    {
1081      int i=IDELEMS(res)-1;
1082      int j=0;
1083      for(;i>=0;i--)
1084      {
1085        if ((res->m[i]!=NULL)
1086        && (pNext(res->m[i])==NULL)
1087        && (pIsConstant(res->m[i])))
1088        {
1089          if (with_exps!=0)
1090          {
1091            pDelete(&(res->m[i]));
1092            if ((v!=NULL) && ((*v)!=NULL))
1093              (**v)[i]=0;
1094            j++;
1095          }
1096          else if (i!=0)
1097          {
1098            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
1099            {
1100              res->m[0]=pMult(res->m[0],pCopy(res->m[i]));
1101              (**v)[i]--;
1102            }
1103            res->m[0]=pMult(res->m[0],res->m[i]);
1104            res->m[i]=NULL;
1105            if ((v!=NULL) && ((*v)!=NULL))
1106              (**v)[i]=0;
1107            j++;
1108          }
1109        }
1110      }
1111      if (j>0)
1112      {
1113        idSkipZeroes(res);
1114        if ((v!=NULL) && ((*v)!=NULL))
1115        {
1116          intvec *w=*v;
1117          int len=si_max(n-j,1);
1118          *v = new intvec( len /*si_max(n-j,1)*/ );
1119          for (i=0,j=0;i<si_min(w->length(),len);i++)
1120          {
1121            if((*w)[i]!=0)
1122            {
1123              (**v)[j]=(*w)[i]; j++;
1124            }
1125          }
1126          delete w;
1127        }
1128      }
1129      if (res->m[0]==NULL)
1130      {
1131        res->m[0]=pOne();
1132      }
1133    }
1134  }
1135  if (rField_is_Q_a() && (currRing->minpoly!=NULL))
1136  {
1137    int i=IDELEMS(res)-1;
1138    int stop=1;
1139    if (with_exps!=0) stop=0;
1140    for(;i>=stop;i--)
1141    {
1142      pNorm(res->m[i]);
1143    }
1144    if (with_exps==0) pSetCoeff(res->m[0],old_lead_coeff);
1145    else nDelete(&old_lead_coeff);
1146  }
1147  else
1148    nDelete(&old_lead_coeff);
1149  errorreported=save_errorreported;
1150notImpl:
1151  if (res==NULL)
1152    WerrorS( feNotImplemented );
1153  if (NN!=NULL)
1154  {
1155    nDelete(&NN);
1156  }
1157  if (N!=NULL)
1158  {
1159    nDelete(&N);
1160  }
1161  //if (f!=NULL) pDelete(&f);
1162  //PrintS("......S\n");
1163  return res;
1164}
1165matrix singclap_irrCharSeries ( ideal I)
1166{
1167#ifdef HAVE_LIBFAC_P
1168  if (idIs0(I)) return mpNew(1,1);
1169
1170  // for now there is only the possibility to handle polynomials over
1171  // Q and Fp ...
1172  matrix res=NULL;
1173  int i;
1174  Off(SW_RATIONAL);
1175  On(SW_SYMMETRIC_FF);
1176  CFList L;
1177  ListCFList LL;
1178  if (((nGetChar() == 0) || (nGetChar() > 1) )
1179  && (currRing->parameter==NULL))
1180  {
1181    setCharacteristic( nGetChar() );
1182    for(i=0;i<IDELEMS(I);i++)
1183    {
1184      poly p=I->m[i];
1185      if (p!=NULL)
1186      {
1187        p=pCopy(p);
1188        pCleardenom(p);
1189        L.append(convSingPFactoryP(p));
1190      }
1191    }
1192  }
1193  // and over Q(a) / Fp(a)
1194  else if (( nGetChar()==1 ) /* Q(a) */
1195  || (nGetChar() <-1))       /* Fp(a) */
1196  {
1197    if (nGetChar()==1) setCharacteristic( 0 );
1198    else               setCharacteristic( -nGetChar() );
1199    for(i=0;i<IDELEMS(I);i++)
1200    {
1201      poly p=I->m[i];
1202      if (p!=NULL)
1203      {
1204        p=pCopy(p);
1205        pCleardenom(p);
1206        L.append(convSingTrPFactoryP(p));
1207      }
1208    }
1209  }
1210  else
1211  {
1212    WerrorS( feNotImplemented );
1213    return res;
1214  }
1215
1216  // a very bad work-around --- FIX IT in libfac
1217  // should be fixed as of 2001/6/27
1218  int tries=0;
1219  int m,n;
1220  ListIterator<CFList> LLi;
1221  loop
1222  {
1223    LL=IrrCharSeries(L);
1224    m= LL.length(); // Anzahl Zeilen
1225    n=0;
1226    for ( LLi = LL; LLi.hasItem(); LLi++ )
1227    {
1228      n = si_max(LLi.getItem().length(),n);
1229    }
1230    if ((m!=0) && (n!=0)) break;
1231    tries++;
1232    if (tries>=5) break;
1233  }
1234  if ((m==0) || (n==0))
1235  {
1236    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
1237      m,n,IDELEMS(I)+1,LL.length());
1238    iiWriteMatrix((matrix)I,"I",2,0);
1239    m=si_max(m,1);
1240    n=si_max(n,1);
1241  }
1242  res=mpNew(m,n);
1243  CFListIterator Li;
1244  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
1245  {
1246    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
1247    {
1248      if ( (nGetChar() == 0) || (nGetChar() > 1) )
1249        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem());
1250      else
1251        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem());
1252    }
1253  }
1254  Off(SW_RATIONAL);
1255  return res;
1256#else
1257  return NULL;
1258#endif
1259}
1260
1261char* singclap_neworder ( ideal I)
1262{
1263#ifdef HAVE_LIBFAC_P
1264  int i;
1265  Off(SW_RATIONAL);
1266  On(SW_SYMMETRIC_FF);
1267  CFList L;
1268  if (((nGetChar() == 0) || (nGetChar() > 1) )
1269  && (currRing->parameter==NULL))
1270  {
1271    setCharacteristic( nGetChar() );
1272    for(i=0;i<IDELEMS(I);i++)
1273    {
1274      L.append(convSingPFactoryP(I->m[i]));
1275    }
1276  }
1277  // and over Q(a) / Fp(a)
1278  else if (( nGetChar()==1 ) /* Q(a) */
1279  || (nGetChar() <-1))       /* Fp(a) */
1280  {
1281    if (nGetChar()==1) setCharacteristic( 0 );
1282    else               setCharacteristic( -nGetChar() );
1283    for(i=0;i<IDELEMS(I);i++)
1284    {
1285      L.append(convSingTrPFactoryP(I->m[i]));
1286    }
1287  }
1288  else
1289  {
1290    WerrorS( feNotImplemented );
1291    return NULL;
1292  }
1293
1294  List<int> IL=neworderint(L);
1295  ListIterator<int> Li;
1296  StringSetS("");
1297  Li = IL;
1298  int offs=rPar(currRing);
1299  int* mark=(int*)omAlloc0((pVariables+offs)*sizeof(int));
1300  int cnt=pVariables+offs;
1301  loop
1302  {
1303    if(! Li.hasItem()) break;
1304    BOOLEAN done=TRUE;
1305    i=Li.getItem()-1;
1306    mark[i]=1;
1307    if (i<offs)
1308    {
1309      done=FALSE;
1310      //StringAppendS(currRing->parameter[i]);
1311    }
1312    else
1313    {
1314      StringAppendS(currRing->names[i-offs]);
1315    }
1316    Li++;
1317    cnt--;
1318    if(cnt==0) break;
1319    if (done) StringAppendS(",");
1320  }
1321  for(i=0;i<pVariables+offs;i++)
1322  {
1323    BOOLEAN done=TRUE;
1324    if(mark[i]==0)
1325    {
1326      if (i<offs)
1327      {
1328        done=FALSE;
1329        //StringAppendS(currRing->parameter[i]);
1330      }
1331      else
1332      {
1333        StringAppendS(currRing->names[i-offs]);
1334      }
1335      cnt--;
1336      if(cnt==0) break;
1337      if (done) StringAppendS(",");
1338    }
1339  }
1340  char * s=omStrDup(StringAppendS(""));
1341  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1342  return s;
1343#else
1344  return NULL;
1345#endif
1346}
1347
1348BOOLEAN singclap_isSqrFree(poly f)
1349{
1350  BOOLEAN b=FALSE;
1351  Off(SW_RATIONAL);
1352  //  Q / Fp
1353  if (((nGetChar() == 0) || (nGetChar() > 1) )
1354  &&(currRing->parameter==NULL))
1355  {
1356    setCharacteristic( nGetChar() );
1357    CanonicalForm F( convSingPFactoryP( f ) );
1358    if((nGetChar()>1)&&(!F.isUnivariate()))
1359      goto err;
1360    b=(BOOLEAN)isSqrFree(F);
1361  }
1362  // and over Q(a) / Fp(a)
1363  else if (( nGetChar()==1 ) /* Q(a) */
1364  || (nGetChar() <-1))       /* Fp(a) */
1365  {
1366    if (nGetChar()==1) setCharacteristic( 0 );
1367    else               setCharacteristic( -nGetChar() );
1368    //if (currRing->minpoly!=NULL)
1369    //{
1370    //  CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
1371    //  Variable a=rootOf(mipo);
1372    //  CanonicalForm F( convSingAPFactoryAP( f,a ) );
1373    //  ...
1374    //}
1375    //else
1376    {
1377      CanonicalForm F( convSingTrPFactoryP( f ) );
1378      b=(BOOLEAN)isSqrFree(F);
1379    }
1380    Off(SW_RATIONAL);
1381  }
1382  else
1383  {
1384err:
1385    WerrorS( feNotImplemented );
1386  }
1387  return b;
1388}
1389
1390poly singclap_det( const matrix m )
1391{
1392  int r=m->rows();
1393  if (r!=m->cols())
1394  {
1395    Werror("det of %d x %d matrix",r,m->cols());
1396    return NULL;
1397  }
1398  poly res=NULL;
1399  if (( nGetChar() == 0 || nGetChar() > 1 )
1400  && (currRing->parameter==NULL))
1401  {
1402    setCharacteristic( nGetChar() );
1403    CFMatrix M(r,r);
1404    int i,j;
1405    for(i=r;i>0;i--)
1406    {
1407      for(j=r;j>0;j--)
1408      {
1409        M(i,j)=convSingPFactoryP(MATELEM(m,i,j));
1410      }
1411    }
1412    res= convFactoryPSingP( determinant(M,r) ) ;
1413  }
1414  // and over Q(a) / Fp(a)
1415  else if (( nGetChar()==1 ) /* Q(a) */
1416  || (nGetChar() <-1))       /* Fp(a) */
1417  {
1418    if (nGetChar()==1) setCharacteristic( 0 );
1419    else               setCharacteristic( -nGetChar() );
1420    CFMatrix M(r,r);
1421    poly res;
1422    if (currRing->minpoly!=NULL)
1423    {
1424      CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
1425      Variable a=rootOf(mipo);
1426      int i,j;
1427      for(i=r;i>0;i--)
1428      {
1429        for(j=r;j>0;j--)
1430        {
1431          M(i,j)=convSingAPFactoryAP(MATELEM(m,i,j),a);
1432        }
1433      }
1434      res= convFactoryAPSingAP( determinant(M,r) ) ;
1435    }
1436    else
1437    {
1438      int i,j;
1439      for(i=r;i>0;i--)
1440      {
1441        for(j=r;j>0;j--)
1442        {
1443          M(i,j)=convSingTrPFactoryP(MATELEM(m,i,j));
1444        }
1445      }
1446      res= convFactoryPSingTrP( determinant(M,r) );
1447    }
1448  }
1449  else
1450    WerrorS( feNotImplemented );
1451  Off(SW_RATIONAL);
1452  return res;
1453}
1454
1455int singclap_det_i( intvec * m )
1456{
1457  setCharacteristic( 0 );
1458  CFMatrix M(m->rows(),m->cols());
1459  int i,j;
1460  for(i=m->rows();i>0;i--)
1461  {
1462    for(j=m->cols();j>0;j--)
1463    {
1464      M(i,j)=IMATELEM(*m,i,j);
1465    }
1466  }
1467  int res= convFactoryISingI( determinant(M,m->rows())) ;
1468  Off(SW_RATIONAL);
1469  return res;
1470}
1471napoly singclap_alglcm ( napoly f, napoly g )
1472{
1473 FACTORY_ALGOUT( "f", f );
1474 FACTORY_ALGOUT( "g", g );
1475
1476 // over Q(a) / Fp(a)
1477 if (nGetChar()==1) setCharacteristic( 0 );
1478 else               setCharacteristic( -nGetChar() );
1479 napoly res;
1480
1481 if (currRing->minpoly!=NULL)
1482 {
1483   CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
1484   Variable a=rootOf(mipo);
1485   CanonicalForm F( convSingAFactoryA( f,a ) ), G( convSingAFactoryA( g,a ) );
1486   CanonicalForm GCD;
1487
1488   TIMING_START( algLcmTimer );
1489   // calculate gcd
1490#ifdef FACTORY_GCD_TEST
1491   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1492#else
1493   GCD = gcd( F, G );
1494#endif
1495   TIMING_END( algLcmTimer );
1496
1497   FACTORY_CFAOUT( "d", GCD );
1498   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1499
1500   // calculate lcm
1501   res= convFactoryASingA( (F/GCD)*G );
1502 }
1503 else
1504 {
1505   CanonicalForm F( convSingTrFactoryP( f ) ), G( convSingTrFactoryP( g ) );
1506   CanonicalForm GCD;
1507   TIMING_START( algLcmTimer );
1508   // calculate gcd
1509#ifdef FACTORY_GCD_TEST
1510   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1511#else
1512   GCD = gcd( F, G );
1513#endif
1514   TIMING_END( algLcmTimer );
1515
1516   FACTORY_CFTROUT( "d", GCD );
1517   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1518
1519   // calculate lcm
1520   res= convFactoryPSingTr( (F/GCD)*G );
1521 }
1522
1523 Off(SW_RATIONAL);
1524 return res;
1525}
1526
1527void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
1528{
1529 FACTORY_ALGOUT( "f", f );
1530 FACTORY_ALGOUT( "g", g );
1531
1532 // over Q(a) / Fp(a)
1533 if (nGetChar()==1) setCharacteristic( 0 );
1534 else               setCharacteristic( -nGetChar() );
1535 ff=gg=NULL;
1536 On(SW_RATIONAL);
1537
1538 if (currRing->minpoly!=NULL)
1539 {
1540   CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
1541   Variable a=rootOf(mipo);
1542   CanonicalForm F( convSingAFactoryA( f,a ) ), G( convSingAFactoryA( g,a ) );
1543   CanonicalForm GCD;
1544
1545   TIMING_START( algContentTimer );
1546#ifdef FACTORY_GCD_TEST
1547   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1548#else
1549   GCD=gcd( F, G );
1550#endif
1551   TIMING_END( algContentTimer );
1552
1553   FACTORY_CFAOUT( "d", GCD );
1554   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1555
1556   if ((GCD!=1) && (GCD!=0))
1557   {
1558     ff= convFactoryASingA( F/ GCD );
1559     gg= convFactoryASingA( G/ GCD );
1560   }
1561 }
1562 else
1563 {
1564   CanonicalForm F( convSingTrFactoryP( f ) ), G( convSingTrFactoryP( g ) );
1565   CanonicalForm GCD;
1566
1567   TIMING_START( algContentTimer );
1568#ifdef FACTORY_GCD_TEST
1569   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1570#else
1571   GCD=gcd( F, G );
1572#endif
1573   TIMING_END( algContentTimer );
1574
1575   FACTORY_CFTROUT( "d", GCD );
1576   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1577
1578   if ((GCD!=1) && (GCD!=0))
1579   {
1580     ff= convFactoryPSingTr( F/ GCD );
1581     gg= convFactoryPSingTr( G/ GCD );
1582   }
1583 }
1584
1585 Off(SW_RATIONAL);
1586}
1587
1588#if 0
1589lists singclap_chineseRemainder(lists x, lists q)
1590{
1591  //assume(x->nr == q->nr);
1592  //assume(x->nr >= 0);
1593  int n=x->nr+1;
1594  if ((x->nr<0) || (x->nr!=q->nr))
1595  {
1596    WerrorS("list are empty or not of equal length");
1597    return NULL;
1598  }
1599  lists res=(lists)omAlloc0Bin(slists_bin);
1600  CFArray X(1,n), Q(1,n);
1601  int i;
1602  for(i=0; i<n; i++)
1603  {
1604    if (x->m[i-1].Typ()==INT_CMD)
1605    {
1606      X[i]=(int)x->m[i-1].Data();
1607    }
1608    else if (x->m[i-1].Typ()==NUMBER_CMD)
1609    {
1610      number N=(number)x->m[i-1].Data();
1611      X[i]=convSingNFactoryN(N);
1612    }
1613    else
1614    {
1615      WerrorS("illegal type in chineseRemainder");
1616      omFreeBin(res,slists_bin);
1617      return NULL;
1618    }
1619    if (q->m[i-1].Typ()==INT_CMD)
1620    {
1621      Q[i]=(int)q->m[i-1].Data();
1622    }
1623    else if (q->m[i-1].Typ()==NUMBER_CMD)
1624    {
1625      number N=(number)x->m[i-1].Data();
1626      Q[i]=convSingNFactoryN(N);
1627    }
1628    else
1629    {
1630      WerrorS("illegal type in chineseRemainder");
1631      omFreeBin(res,slists_bin);
1632      return NULL;
1633    }
1634  }
1635  CanonicalForm r, prod;
1636  chineseRemainder( X, Q, r, prod );
1637  res->Init(2);
1638  res->m[0].rtyp=NUMBER_CMD;
1639  res->m[1].rtyp=NUMBER_CMD;
1640  res->m[0].data=(char *)convFactoryNSingN( r );
1641  res->m[1].data=(char *)convFactoryNSingN( prod );
1642  return res;
1643}
1644#endif
1645#endif
Note: See TracBrowser for help on using the repository browser.