source: git/kernel/clapsing.cc @ 46f6af6

spielwiese
Last change on this file since 46f6af6 was 46f6af6, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: buckte for conversions git-svn-id: file:///usr/local/Singular/svn/trunk@10491 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.24 2008-01-07 13:36:16 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    CFFListIterator J=L;
998    int j=0;
999    if (with_exps!=1)
1000    {
1001      if ((with_exps==2)&&(n>1))
1002      {
1003        n--;
1004        J++;
1005      }
1006      *v = new intvec( n );
1007    }
1008    res = idInit( n ,1);
1009    for ( ; J.hasItem(); J++, j++ )
1010    {
1011      poly p;
1012      if (with_exps!=1) (**v)[j] = J.getItem().exp();
1013      if (rField_is_Zp() || rField_is_Q())           /* Q, Fp */
1014        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
1015        res->m[j] = convFactoryPSingP( J.getItem().factor() );
1016      #if 0
1017      else if (rField_is_GF())
1018        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
1019      #endif
1020      else if (rField_is_Extension())     /* Q(a), Fp(a) */
1021      {
1022        intvec *w=NULL;
1023        if (v!=NULL) w=*v;
1024        if (currRing->minpoly==NULL)
1025          count_Factors(res,w,j,ff,convFactoryPSingTrP( J.getItem().factor() ));
1026        else
1027          count_Factors(res,w,j,ff,convFactoryAPSingAP( J.getItem().factor() ));
1028      }
1029    }
1030    if (rField_is_Extension() && (!pIsConstantPoly(ff)))
1031    {
1032      singclap_factorize_retry++;
1033      if (singclap_factorize_retry<3)
1034      {
1035        int jj;
1036        #ifdef FACTORIZE2_DEBUG
1037        printf("factorize_retry\n");
1038        #endif
1039        intvec *ww=NULL;
1040        idTest(res);
1041        ideal h=singclap_factorize ( ff, &ww , with_exps);
1042        idTest(h);
1043        int l=(*v)->length();
1044        (*v)->resize(l+ww->length()-1);
1045        for(jj=0;jj<ww->length();jj++)
1046          (*v)[jj+l]=(*ww)[jj];
1047        delete ww;
1048        ideal hh=idInit(IDELEMS(res)+IDELEMS(h),1);
1049        for(jj=IDELEMS(res)-1;jj>=0;jj--)
1050        {
1051          hh->m[jj]=res->m[jj];
1052          res->m[jj]=NULL;
1053        }
1054        for(jj=IDELEMS(h)-1;jj>=0;jj--)
1055        {
1056          hh->m[jj+IDELEMS(res)]=h->m[jj];
1057          h->m[jj]=NULL;
1058        }
1059        idDelete(&res);
1060        idDelete(&h);
1061        res=hh;
1062        idTest(res);
1063        ff=NULL;
1064      }
1065      else
1066      {
1067        WarnS("problem with factorize");
1068      }
1069    }
1070    pDelete(&ff);
1071    if (N!=NULL)
1072    {
1073      pMult_nn(res->m[0],N);
1074      nDelete(&N);
1075      N=NULL;
1076    }
1077    // delete constants
1078    if (res!=NULL)
1079    {
1080      int i=IDELEMS(res)-1;
1081      int j=0;
1082      for(;i>=0;i--)
1083      {
1084        if ((res->m[i]!=NULL)
1085        && (pNext(res->m[i])==NULL)
1086        && (pIsConstant(res->m[i])))
1087        {
1088          if (with_exps!=0)
1089          {
1090            pDelete(&(res->m[i]));
1091            if ((v!=NULL) && ((*v)!=NULL))
1092              (**v)[i]=0;
1093            j++;
1094          }
1095          else if (i!=0)
1096          {
1097            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
1098            {
1099              res->m[0]=pMult(res->m[0],pCopy(res->m[i]));
1100              (**v)[i]--;
1101            }
1102            res->m[0]=pMult(res->m[0],res->m[i]);
1103            res->m[i]=NULL;
1104            if ((v!=NULL) && ((*v)!=NULL))
1105              (**v)[i]=0;
1106            j++;
1107          }
1108        }
1109      }
1110      if (j>0)
1111      {
1112        idSkipZeroes(res);
1113        if ((v!=NULL) && ((*v)!=NULL))
1114        {
1115          intvec *w=*v;
1116          int len=si_max(n-j,1);
1117          *v = new intvec( len /*si_max(n-j,1)*/ );
1118          for (i=0,j=0;i<si_min(w->length(),len);i++)
1119          {
1120            if((*w)[i]!=0)
1121            {
1122              (**v)[j]=(*w)[i]; j++;
1123            }
1124          }
1125          delete w;
1126        }
1127      }
1128      if (res->m[0]==NULL)
1129      {
1130        res->m[0]=pOne();
1131      }
1132    }
1133  }
1134  if (rField_is_Q_a() && (currRing->minpoly!=NULL))
1135  {
1136    int i=IDELEMS(res)-1;
1137    int stop=1;
1138    if (with_exps!=0) stop=0;
1139    for(;i>=stop;i--)
1140    {
1141      pNorm(res->m[i]);
1142    }
1143    if (with_exps==0) pSetCoeff(res->m[0],old_lead_coeff);
1144    else nDelete(&old_lead_coeff);
1145  }
1146  else
1147    nDelete(&old_lead_coeff);
1148  errorreported=save_errorreported;
1149notImpl:
1150  if (res==NULL)
1151    WerrorS( feNotImplemented );
1152  if (NN!=NULL)
1153  {
1154    nDelete(&NN);
1155  }
1156  if (N!=NULL)
1157  {
1158    nDelete(&N);
1159  }
1160  //if (f!=NULL) pDelete(&f);
1161  //PrintS("......S\n");
1162  return res;
1163}
1164matrix singclap_irrCharSeries ( ideal I)
1165{
1166#ifdef HAVE_LIBFAC_P
1167  if (idIs0(I)) return mpNew(1,1);
1168
1169  // for now there is only the possibility to handle polynomials over
1170  // Q and Fp ...
1171  matrix res=NULL;
1172  int i;
1173  Off(SW_RATIONAL);
1174  On(SW_SYMMETRIC_FF);
1175  CFList L;
1176  ListCFList LL;
1177  if (((nGetChar() == 0) || (nGetChar() > 1) )
1178  && (currRing->parameter==NULL))
1179  {
1180    setCharacteristic( nGetChar() );
1181    for(i=0;i<IDELEMS(I);i++)
1182    {
1183      poly p=I->m[i];
1184      if (p!=NULL)
1185      {
1186        p=pCopy(p);
1187        pCleardenom(p);
1188        L.append(convSingPFactoryP(p));
1189      }
1190    }
1191  }
1192  // and over Q(a) / Fp(a)
1193  else if (( nGetChar()==1 ) /* Q(a) */
1194  || (nGetChar() <-1))       /* Fp(a) */
1195  {
1196    if (nGetChar()==1) setCharacteristic( 0 );
1197    else               setCharacteristic( -nGetChar() );
1198    for(i=0;i<IDELEMS(I);i++)
1199    {
1200      poly p=I->m[i];
1201      if (p!=NULL)
1202      {
1203        p=pCopy(p);
1204        pCleardenom(p);
1205        L.append(convSingTrPFactoryP(p));
1206      }
1207    }
1208  }
1209  else
1210  {
1211    WerrorS( feNotImplemented );
1212    return res;
1213  }
1214
1215  // a very bad work-around --- FIX IT in libfac
1216  // should be fixed as of 2001/6/27
1217  int tries=0;
1218  int m,n;
1219  ListIterator<CFList> LLi;
1220  loop
1221  {
1222    LL=IrrCharSeries(L);
1223    m= LL.length(); // Anzahl Zeilen
1224    n=0;
1225    for ( LLi = LL; LLi.hasItem(); LLi++ )
1226    {
1227      n = si_max(LLi.getItem().length(),n);
1228    }
1229    if ((m!=0) && (n!=0)) break;
1230    tries++;
1231    if (tries>=5) break;
1232  }
1233  if ((m==0) || (n==0))
1234  {
1235    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
1236      m,n,IDELEMS(I)+1,LL.length());
1237    iiWriteMatrix((matrix)I,"I",2,0);
1238    m=si_max(m,1);
1239    n=si_max(n,1);
1240  }
1241  res=mpNew(m,n);
1242  CFListIterator Li;
1243  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
1244  {
1245    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
1246    {
1247      if ( (nGetChar() == 0) || (nGetChar() > 1) )
1248        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem());
1249      else
1250        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem());
1251    }
1252  }
1253  Off(SW_RATIONAL);
1254  return res;
1255#else
1256  return NULL;
1257#endif
1258}
1259
1260char* singclap_neworder ( ideal I)
1261{
1262#ifdef HAVE_LIBFAC_P
1263  int i;
1264  Off(SW_RATIONAL);
1265  On(SW_SYMMETRIC_FF);
1266  CFList L;
1267  if (((nGetChar() == 0) || (nGetChar() > 1) )
1268  && (currRing->parameter==NULL))
1269  {
1270    setCharacteristic( nGetChar() );
1271    for(i=0;i<IDELEMS(I);i++)
1272    {
1273      L.append(convSingPFactoryP(I->m[i]));
1274    }
1275  }
1276  // and over Q(a) / Fp(a)
1277  else if (( nGetChar()==1 ) /* Q(a) */
1278  || (nGetChar() <-1))       /* Fp(a) */
1279  {
1280    if (nGetChar()==1) setCharacteristic( 0 );
1281    else               setCharacteristic( -nGetChar() );
1282    for(i=0;i<IDELEMS(I);i++)
1283    {
1284      L.append(convSingTrPFactoryP(I->m[i]));
1285    }
1286  }
1287  else
1288  {
1289    WerrorS( feNotImplemented );
1290    return NULL;
1291  }
1292
1293  List<int> IL=neworderint(L);
1294  ListIterator<int> Li;
1295  StringSetS("");
1296  Li = IL;
1297  int offs=rPar(currRing);
1298  int* mark=(int*)omAlloc0((pVariables+offs)*sizeof(int));
1299  int cnt=pVariables+offs;
1300  loop
1301  {
1302    if(! Li.hasItem()) break;
1303    BOOLEAN done=TRUE;
1304    i=Li.getItem()-1;
1305    mark[i]=1;
1306    if (i<offs)
1307    {
1308      done=FALSE;
1309      //StringAppendS(currRing->parameter[i]);
1310    }
1311    else
1312    {
1313      StringAppendS(currRing->names[i-offs]);
1314    }
1315    Li++;
1316    cnt--;
1317    if(cnt==0) break;
1318    if (done) StringAppendS(",");
1319  }
1320  for(i=0;i<pVariables+offs;i++)
1321  {
1322    BOOLEAN done=TRUE;
1323    if(mark[i]==0)
1324    {
1325      if (i<offs)
1326      {
1327        done=FALSE;
1328        //StringAppendS(currRing->parameter[i]);
1329      }
1330      else
1331      {
1332        StringAppendS(currRing->names[i-offs]);
1333      }
1334      cnt--;
1335      if(cnt==0) break;
1336      if (done) StringAppendS(",");
1337    }
1338  }
1339  char * s=omStrDup(StringAppendS(""));
1340  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1341  return s;
1342#else
1343  return NULL;
1344#endif
1345}
1346
1347BOOLEAN singclap_isSqrFree(poly f)
1348{
1349  BOOLEAN b=FALSE;
1350  Off(SW_RATIONAL);
1351  //  Q / Fp
1352  if (((nGetChar() == 0) || (nGetChar() > 1) )
1353  &&(currRing->parameter==NULL))
1354  {
1355    setCharacteristic( nGetChar() );
1356    CanonicalForm F( convSingPFactoryP( f ) );
1357    if((nGetChar()>1)&&(!F.isUnivariate()))
1358      goto err;
1359    b=(BOOLEAN)isSqrFree(F);
1360  }
1361  // and over Q(a) / Fp(a)
1362  else if (( nGetChar()==1 ) /* Q(a) */
1363  || (nGetChar() <-1))       /* Fp(a) */
1364  {
1365    if (nGetChar()==1) setCharacteristic( 0 );
1366    else               setCharacteristic( -nGetChar() );
1367    //if (currRing->minpoly!=NULL)
1368    //{
1369    //  CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
1370    //  Variable a=rootOf(mipo);
1371    //  CanonicalForm F( convSingAPFactoryAP( f,a ) );
1372    //  ...
1373    //}
1374    //else
1375    {
1376      CanonicalForm F( convSingTrPFactoryP( f ) );
1377      b=(BOOLEAN)isSqrFree(F);
1378    }
1379    Off(SW_RATIONAL);
1380  }
1381  else
1382  {
1383err:
1384    WerrorS( feNotImplemented );
1385  }
1386  return b;
1387}
1388
1389poly singclap_det( const matrix m )
1390{
1391  int r=m->rows();
1392  if (r!=m->cols())
1393  {
1394    Werror("det of %d x %d matrix",r,m->cols());
1395    return NULL;
1396  }
1397  poly res=NULL;
1398  if (( nGetChar() == 0 || nGetChar() > 1 )
1399  && (currRing->parameter==NULL))
1400  {
1401    setCharacteristic( nGetChar() );
1402    CFMatrix M(r,r);
1403    int i,j;
1404    for(i=r;i>0;i--)
1405    {
1406      for(j=r;j>0;j--)
1407      {
1408        M(i,j)=convSingPFactoryP(MATELEM(m,i,j));
1409      }
1410    }
1411    res= convFactoryPSingP( determinant(M,r) ) ;
1412  }
1413  // and over Q(a) / Fp(a)
1414  else if (( nGetChar()==1 ) /* Q(a) */
1415  || (nGetChar() <-1))       /* Fp(a) */
1416  {
1417    if (nGetChar()==1) setCharacteristic( 0 );
1418    else               setCharacteristic( -nGetChar() );
1419    CFMatrix M(r,r);
1420    poly res;
1421    if (currRing->minpoly!=NULL)
1422    {
1423      CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
1424      Variable a=rootOf(mipo);
1425      int i,j;
1426      for(i=r;i>0;i--)
1427      {
1428        for(j=r;j>0;j--)
1429        {
1430          M(i,j)=convSingAPFactoryAP(MATELEM(m,i,j),a);
1431        }
1432      }
1433      res= convFactoryAPSingAP( determinant(M,r) ) ;
1434    }
1435    else
1436    {
1437      int i,j;
1438      for(i=r;i>0;i--)
1439      {
1440        for(j=r;j>0;j--)
1441        {
1442          M(i,j)=convSingTrPFactoryP(MATELEM(m,i,j));
1443        }
1444      }
1445      res= convFactoryPSingTrP( determinant(M,r) );
1446    }
1447  }
1448  else
1449    WerrorS( feNotImplemented );
1450  Off(SW_RATIONAL);
1451  return res;
1452}
1453
1454int singclap_det_i( intvec * m )
1455{
1456  setCharacteristic( 0 );
1457  CFMatrix M(m->rows(),m->cols());
1458  int i,j;
1459  for(i=m->rows();i>0;i--)
1460  {
1461    for(j=m->cols();j>0;j--)
1462    {
1463      M(i,j)=IMATELEM(*m,i,j);
1464    }
1465  }
1466  int res= convFactoryISingI( determinant(M,m->rows())) ;
1467  Off(SW_RATIONAL);
1468  return res;
1469}
1470napoly singclap_alglcm ( napoly f, napoly g )
1471{
1472 FACTORY_ALGOUT( "f", f );
1473 FACTORY_ALGOUT( "g", g );
1474
1475 // over Q(a) / Fp(a)
1476 if (nGetChar()==1) setCharacteristic( 0 );
1477 else               setCharacteristic( -nGetChar() );
1478 napoly res;
1479
1480 if (currRing->minpoly!=NULL)
1481 {
1482   CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
1483   Variable a=rootOf(mipo);
1484   CanonicalForm F( convSingAFactoryA( f,a ) ), G( convSingAFactoryA( g,a ) );
1485   CanonicalForm GCD;
1486
1487   TIMING_START( algLcmTimer );
1488   // calculate gcd
1489#ifdef FACTORY_GCD_TEST
1490   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1491#else
1492   GCD = gcd( F, G );
1493#endif
1494   TIMING_END( algLcmTimer );
1495
1496   FACTORY_CFAOUT( "d", GCD );
1497   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1498
1499   // calculate lcm
1500   res= convFactoryASingA( (F/GCD)*G );
1501 }
1502 else
1503 {
1504   CanonicalForm F( convSingTrFactoryP( f ) ), G( convSingTrFactoryP( g ) );
1505   CanonicalForm GCD;
1506   TIMING_START( algLcmTimer );
1507   // calculate gcd
1508#ifdef FACTORY_GCD_TEST
1509   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1510#else
1511   GCD = gcd( F, G );
1512#endif
1513   TIMING_END( algLcmTimer );
1514
1515   FACTORY_CFTROUT( "d", GCD );
1516   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1517
1518   // calculate lcm
1519   res= convFactoryPSingTr( (F/GCD)*G );
1520 }
1521
1522 Off(SW_RATIONAL);
1523 return res;
1524}
1525
1526void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
1527{
1528 FACTORY_ALGOUT( "f", f );
1529 FACTORY_ALGOUT( "g", g );
1530
1531 // over Q(a) / Fp(a)
1532 if (nGetChar()==1) setCharacteristic( 0 );
1533 else               setCharacteristic( -nGetChar() );
1534 ff=gg=NULL;
1535 On(SW_RATIONAL);
1536
1537 if (currRing->minpoly!=NULL)
1538 {
1539   CanonicalForm mipo=convSingTrFactoryP(((lnumber)currRing->minpoly)->z);
1540   Variable a=rootOf(mipo);
1541   CanonicalForm F( convSingAFactoryA( f,a ) ), G( convSingAFactoryA( g,a ) );
1542   CanonicalForm GCD;
1543
1544   TIMING_START( algContentTimer );
1545#ifdef FACTORY_GCD_TEST
1546   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1547#else
1548   GCD=gcd( F, G );
1549#endif
1550   TIMING_END( algContentTimer );
1551
1552   FACTORY_CFAOUT( "d", GCD );
1553   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1554
1555   if ((GCD!=1) && (GCD!=0))
1556   {
1557     ff= convFactoryASingA( F/ GCD );
1558     gg= convFactoryASingA( G/ GCD );
1559   }
1560 }
1561 else
1562 {
1563   CanonicalForm F( convSingTrFactoryP( f ) ), G( convSingTrFactoryP( g ) );
1564   CanonicalForm GCD;
1565
1566   TIMING_START( algContentTimer );
1567#ifdef FACTORY_GCD_TEST
1568   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1569#else
1570   GCD=gcd( F, G );
1571#endif
1572   TIMING_END( algContentTimer );
1573
1574   FACTORY_CFTROUT( "d", GCD );
1575   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1576
1577   if ((GCD!=1) && (GCD!=0))
1578   {
1579     ff= convFactoryPSingTr( F/ GCD );
1580     gg= convFactoryPSingTr( G/ GCD );
1581   }
1582 }
1583
1584 Off(SW_RATIONAL);
1585}
1586
1587#if 0
1588lists singclap_chineseRemainder(lists x, lists q)
1589{
1590  //assume(x->nr == q->nr);
1591  //assume(x->nr >= 0);
1592  int n=x->nr+1;
1593  if ((x->nr<0) || (x->nr!=q->nr))
1594  {
1595    WerrorS("list are empty or not of equal length");
1596    return NULL;
1597  }
1598  lists res=(lists)omAlloc0Bin(slists_bin);
1599  CFArray X(1,n), Q(1,n);
1600  int i;
1601  for(i=0; i<n; i++)
1602  {
1603    if (x->m[i-1].Typ()==INT_CMD)
1604    {
1605      X[i]=(int)x->m[i-1].Data();
1606    }
1607    else if (x->m[i-1].Typ()==NUMBER_CMD)
1608    {
1609      number N=(number)x->m[i-1].Data();
1610      X[i]=convSingNFactoryN(N);
1611    }
1612    else
1613    {
1614      WerrorS("illegal type in chineseRemainder");
1615      omFreeBin(res,slists_bin);
1616      return NULL;
1617    }
1618    if (q->m[i-1].Typ()==INT_CMD)
1619    {
1620      Q[i]=(int)q->m[i-1].Data();
1621    }
1622    else if (q->m[i-1].Typ()==NUMBER_CMD)
1623    {
1624      number N=(number)x->m[i-1].Data();
1625      Q[i]=convSingNFactoryN(N);
1626    }
1627    else
1628    {
1629      WerrorS("illegal type in chineseRemainder");
1630      omFreeBin(res,slists_bin);
1631      return NULL;
1632    }
1633  }
1634  CanonicalForm r, prod;
1635  chineseRemainder( X, Q, r, prod );
1636  res->Init(2);
1637  res->m[0].rtyp=NUMBER_CMD;
1638  res->m[1].rtyp=NUMBER_CMD;
1639  res->m[0].data=(char *)convFactoryNSingN( r );
1640  res->m[1].data=(char *)convFactoryNSingN( prod );
1641  return res;
1642}
1643#endif
1644#endif
Note: See TracBrowser for help on using the repository browser.