source: git/libpolys/polys/clapsing.cc @ 4946e3

spielwiese
Last change on this file since 4946e3 was 4946e3, checked in by Hans Schoenemann <hannes@…>, 4 years ago
factory: LL via FLINT
  • Property mode set to 100644
File size: 47.2 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5/*
6* ABSTRACT: interface between Singular and factory
7*/
8
9//#define FACTORIZE2_DEBUG
10
11#include "misc/auxiliary.h"
12#include "clapsing.h"
13
14#include "factory/factory.h"
15
16#include "coeffs/numbers.h"
17#include "coeffs/coeffs.h"
18#include "coeffs/bigintmat.h"
19
20#include "monomials/ring.h"
21#include "simpleideals.h"
22#include "polys/flintconv.h"
23#include "polys/flint_mpoly.h"
24
25
26//#include "polys.h"
27#define TRANSEXT_PRIVATES
28
29#include "ext_fields/transext.h"
30
31
32#include "clapconv.h"
33
34#include "polys/monomials/p_polys.h"
35#include "polys/monomials/ring.h"
36#include "polys/simpleideals.h"
37#include "misc/intvec.h"
38#include "polys/matpol.h"
39#include "coeffs/bigintmat.h"
40
41
42void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
43
44poly singclap_gcd_r ( poly f, poly g, const ring r )
45{
46  poly res=NULL;
47
48  assume(f!=NULL);
49  assume(g!=NULL);
50
51  if(pNext(f)==NULL)
52  {
53    return p_GcdMon(f,g,r);
54  }
55  else if(pNext(g)==NULL)
56  {
57    return p_GcdMon(g,f,r);
58  }
59  #ifdef HAVE_FLINT
60  #if __FLINT_RELEASE >= 20503
61  if (rField_is_Zp(r) && (r->cf->ch>10))
62  {
63    nmod_mpoly_ctx_t ctx;
64    if (!convSingRFlintR(ctx,r))
65    {
66      // leading coef. 1
67      return Flint_GCD_MP(f,pLength(f),g,pLength(g),ctx,r);
68    }
69  }
70  else
71  if (rField_is_Q(r))
72  {
73    fmpq_mpoly_ctx_t ctx;
74    if (!convSingRFlintR(ctx,r))
75    {
76      // leading coef. positive, all coeffs in Z
77      poly res=Flint_GCD_MP(f,pLength(f),g,pLength(g),ctx,r);
78      res=p_Cleardenom(res,r);
79      return res;
80    }
81  }
82  #endif
83  #endif
84  Off(SW_RATIONAL);
85  if (rField_is_Q(r) || rField_is_Zp(r) || rField_is_Z(r)
86  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
87  {
88    setCharacteristic( rChar(r) );
89    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g, r ) );
90    res=convFactoryPSingP( gcd( F, G ) , r);
91    if ( rField_is_Zp(r))
92      p_Norm(res,r); // leading coef. 1
93    else if (rField_is_Q(r) && (!n_GreaterZero(pGetCoeff(res),r->cf)))
94      res = p_Neg(res,r); // leading coef. positive, all coeffs in Z
95  }
96  // and over Q(a) / Fp(a)
97  else if ( r->cf->extRing!=NULL )
98  {
99    if ( rField_is_Q_a(r)) setCharacteristic( 0 );
100    else                   setCharacteristic( rChar(r) );
101    if (r->cf->extRing->qideal!=NULL)
102    {
103      bool b1=isOn(SW_USE_QGCD);
104      if ( rField_is_Q_a(r) ) On(SW_USE_QGCD);
105      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
106                                           r->cf->extRing);
107      Variable a=rootOf(mipo);
108      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
109                    G( convSingAPFactoryAP( g,a,r ) );
110      res= convFactoryAPSingAP( gcd( F, G ),r );
111      prune (a);
112      if (!b1) Off(SW_USE_QGCD);
113      if ( rField_is_Zp_a(r)) p_Norm(res,r); // leading coef. 1
114    }
115    else
116    {
117      convSingTrP(f,r);
118      convSingTrP(g,r);
119      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
120      res= convFactoryPSingTrP( gcd( F, G ),r );
121    }
122  }
123  else if (r->cf->convSingNFactoryN==ndConvSingNFactoryN)
124    WerrorS( feNotImplemented );
125  else
126  { // handle user type coeffs:
127    setCharacteristic( rChar(r) );
128    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g, r ) );
129    res=convFactoryPSingP( gcd( F, G ) , r);
130  }
131  Off(SW_RATIONAL);
132  return res;
133}
134
135poly singclap_gcd_and_divide ( poly& f, poly& g, const ring r)
136{
137  poly res=NULL;
138
139  if (g == NULL)
140  {
141    res= f;
142    f=p_One (r);
143    return res;
144  }
145  if (f==NULL)
146  {
147    res= g;
148    g=p_One (r);
149    return res;
150  }
151  if (pNext(g)==NULL)
152  {
153    poly G=p_GcdMon(g,f,r);
154    if (!n_IsOne(pGetCoeff(G),r->cf)
155    || (!p_IsConstant(G,r)))
156    {
157      f=p_Div_mm(f,G,r);
158      g=p_Div_mm(g,G,r);
159    }
160    return G;
161  }
162  else if (pNext(f)==NULL)
163  {
164    poly G=p_GcdMon(f,g,r);
165    if (!n_IsOne(pGetCoeff(G),r->cf)
166    || (!p_IsConstant(G,r)))
167    {
168      f=p_Div_mm(f,G,r);
169      g=p_Div_mm(g,G,r);
170    }
171    return G;
172  }
173
174  Off(SW_RATIONAL);
175  CanonicalForm F,G,GCD;
176  if (rField_is_Q(r) || (rField_is_Zp(r))
177  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
178  {
179    bool b1=isOn(SW_USE_EZGCD_P);
180    setCharacteristic( rChar(r) );
181    F=convSingPFactoryP( f,r );
182    G=convSingPFactoryP( g,r );
183    GCD=gcd(F,G);
184    if (!GCD.isOne())
185    {
186      p_Delete(&f,r);
187      p_Delete(&g,r);
188      if (getCharacteristic() == 0)
189        On (SW_RATIONAL);
190      F /= GCD;
191      G /= GCD;
192      if (getCharacteristic() == 0)
193      {
194        CanonicalForm denF= bCommonDen (F);
195        CanonicalForm denG= bCommonDen (G);
196        G *= denG;
197        F *= denF;
198        Off (SW_RATIONAL);
199        CanonicalForm gcddenFdenG= gcd (denG, denF);
200        denG /= gcddenFdenG;
201        denF /= gcddenFdenG;
202        On (SW_RATIONAL);
203        G *= denF;
204        F *= denG;
205      }
206      f=convFactoryPSingP( F, r);
207      g=convFactoryPSingP( G, r);
208    }
209    res=convFactoryPSingP( GCD , r);
210    if (!b1) Off (SW_USE_EZGCD_P);
211  }
212  // and over Q(a) / Fp(a)
213  else if ( r->cf->extRing )
214  {
215    if ( rField_is_Q_a(r)) setCharacteristic( 0 );
216    else                   setCharacteristic( rChar(r) );
217    if (r->cf->extRing->qideal!=NULL)
218    {
219      bool b1=isOn(SW_USE_QGCD);
220      if ( rField_is_Q_a(r) ) On(SW_USE_QGCD);
221      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
222                                           r->cf->extRing);
223      Variable a=rootOf(mipo);
224      F=( convSingAPFactoryAP( f,a,r ) );
225      G=( convSingAPFactoryAP( g,a,r ) );
226      GCD=gcd(F,G);
227      if (!GCD.isOne())
228      {
229        p_Delete(&f,r);
230        p_Delete(&g,r);
231        if (getCharacteristic() == 0)
232          On (SW_RATIONAL);
233        F /= GCD;
234        G /= GCD;
235        if (getCharacteristic() == 0)
236        {
237          CanonicalForm denF= bCommonDen (F);
238          CanonicalForm denG= bCommonDen (G);
239          G *= denG;
240          F *= denF;
241          Off (SW_RATIONAL);
242          CanonicalForm gcddenFdenG= gcd (denG, denF);
243          denG /= gcddenFdenG;
244          denF /= gcddenFdenG;
245          On (SW_RATIONAL);
246          G *= denF;
247          F *= denG;
248        }
249        f= convFactoryAPSingAP( F,r );
250        g= convFactoryAPSingAP( G,r );
251      }
252      res= convFactoryAPSingAP( GCD,r );
253      prune (a);
254      if (!b1) Off(SW_USE_QGCD);
255    }
256    else
257    {
258      F=( convSingTrPFactoryP( f,r ) );
259      G=( convSingTrPFactoryP( g,r ) );
260      GCD=gcd(F,G);
261      if (!GCD.isOne())
262      {
263        p_Delete(&f,r);
264        p_Delete(&g,r);
265        if (getCharacteristic() == 0)
266          On (SW_RATIONAL);
267        F /= GCD;
268        G /= GCD;
269        if (getCharacteristic() == 0)
270        {
271          CanonicalForm denF= bCommonDen (F);
272          CanonicalForm denG= bCommonDen (G);
273          G *= denG;
274          F *= denF;
275          Off (SW_RATIONAL);
276          CanonicalForm gcddenFdenG= gcd (denG, denF);
277          denG /= gcddenFdenG;
278          denF /= gcddenFdenG;
279          On (SW_RATIONAL);
280          G *= denF;
281          F *= denG;
282        }
283        f= convFactoryPSingTrP( F,r );
284        g= convFactoryPSingTrP( G,r );
285      }
286      res= convFactoryPSingTrP( GCD,r );
287    }
288  }
289  else
290    WerrorS( feNotImplemented );
291  Off(SW_RATIONAL);
292  return res;
293}
294
295/*2 find the maximal exponent of var(i) in poly p*/
296int pGetExp_Var(poly p, int i, const ring r)
297{
298  int m=0;
299  int mm;
300  while (p!=NULL)
301  {
302    mm=p_GetExp(p,i,r);
303    if (mm>m) m=mm;
304    pIter(p);
305  }
306  return m;
307}
308
309// destroys f,g,x
310poly singclap_resultant ( poly f, poly g , poly x, const ring r)
311{
312  poly res=NULL;
313  int i=p_IsPurePower(x, r);
314  if (i==0)
315  {
316    WerrorS("3rd argument must be a ring variable");
317    goto resultant_returns_res;
318  }
319  if ((f==NULL) || (g==NULL))
320    goto resultant_returns_res;
321  // for now there is only the possibility to handle polynomials over
322  // Q and Fp ...
323  if (rField_is_Zp(r) || rField_is_Q(r)
324  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
325  {
326    Variable X(i);
327    setCharacteristic( rChar(r) );
328    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
329    res=convFactoryPSingP( resultant( F, G, X),r );
330    Off(SW_RATIONAL);
331    goto resultant_returns_res;
332  }
333  // and over Q(a) / Fp(a)
334  else if (r->cf->extRing!=NULL)
335  {
336    if (rField_is_Q_a(r)) setCharacteristic( 0 );
337    else               setCharacteristic( rChar(r) );
338    Variable X(i+rPar(r));
339    if (r->cf->extRing->qideal!=NULL)
340    {
341      //Variable X(i);
342      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
343                                           r->cf->extRing);
344      Variable a=rootOf(mipo);
345      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
346                    G( convSingAPFactoryAP( g,a,r ) );
347      res= convFactoryAPSingAP( resultant( F, G, X ),r );
348      prune (a);
349    }
350    else
351    {
352      //Variable X(i+rPar(currRing));
353      number nf,ng;
354      p_Cleardenom_n(f,r,nf);p_Cleardenom_n(g,r,ng);
355      int ef,eg;
356      ef=pGetExp_Var(f,i,r);
357      eg=pGetExp_Var(g,i,r);
358      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
359      res= convFactoryPSingTrP( resultant( F, G, X ),r );
360      if ((nf!=NULL)&&(!n_IsOne(nf,r->cf)))
361      {
362        number n=n_Invers(nf,r->cf);
363        while(eg>0)
364        {
365          res=__p_Mult_nn(res,n,r);
366          eg--;
367        }
368        n_Delete(&n,r->cf);
369      }
370      n_Delete(&nf,r->cf);
371      if ((ng!=NULL)&&(!n_IsOne(ng,r->cf)))
372      {
373        number n=n_Invers(ng,r->cf);
374        while(ef>0)
375        {
376          res=__p_Mult_nn(res,n,r);
377          ef--;
378        }
379        n_Delete(&n,r->cf);
380      }
381      n_Delete(&ng,r->cf);
382    }
383    Off(SW_RATIONAL);
384    goto resultant_returns_res;
385  }
386  else
387    WerrorS( feNotImplemented );
388resultant_returns_res:
389  p_Delete(&f,r);
390  p_Delete(&g,r);
391  p_Delete(&x,r);
392  return res;
393}
394//poly singclap_resultant ( poly f, poly g , poly x)
395//{
396//  int i=pVar(x);
397//  if (i==0)
398//  {
399//    WerrorS("ringvar expected");
400//    return NULL;
401//  }
402//  ideal I=idInit(1,1);
403//
404//  // get the coeffs von f wrt. x:
405//  I->m[0]=pCopy(f);
406//  matrix ffi=mpCoeffs(I,i);
407//  ffi->rank=1;
408//  ffi->ncols=ffi->nrows;
409//  ffi->nrows=1;
410//  ideal fi=(ideal)ffi;
411//
412//  // get the coeffs von g wrt. x:
413//  I->m[0]=pCopy(g);
414//  matrix ggi=mpCoeffs(I,i);
415//  ggi->rank=1;
416//  ggi->ncols=ggi->nrows;
417//  ggi->nrows=1;
418//  ideal gi=(ideal)ggi;
419//
420//  // contruct the matrix:
421//  int fn=IDELEMS(fi); //= deg(f,x)+1
422//  int gn=IDELEMS(gi); //= deg(g,x)+1
423//  matrix m=mpNew(fn+gn-2,fn+gn-2);
424//  if(m==NULL)
425//  {
426//    return NULL;
427//  }
428//
429//  // enter the coeffs into m:
430//  int j;
431//  for(i=0;i<gn-1;i++)
432//  {
433//    for(j=0;j<fn;j++)
434//    {
435//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
436//    }
437//  }
438//  for(i=0;i<fn-1;i++)
439//  {
440//    for(j=0;j<gn;j++)
441//    {
442//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
443//    }
444//  }
445//
446//  poly r=mpDet(m);
447//
448//  idDelete(&fi);
449//  idDelete(&gi);
450//  idDelete((ideal *)&m);
451//  return r;
452//}
453
454BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb , const ring r)
455{
456  // for now there is only the possibility to handle univariate
457  // polynomials over
458  // Q and Fp ...
459  res=NULL;pa=NULL;pb=NULL;
460  On(SW_SYMMETRIC_FF);
461  if ( rField_is_Q(r) || rField_is_Zp(r)
462  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
463  {
464    setCharacteristic( rChar(r) );
465    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r) );
466    CanonicalForm FpG=F+G;
467    if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
468    //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
469    {
470      Off(SW_RATIONAL);
471      WerrorS("not univariate");
472      return TRUE;
473    }
474    CanonicalForm Fa,Gb;
475    On(SW_RATIONAL);
476    res=convFactoryPSingP( extgcd( F, G, Fa, Gb ),r );
477    pa=convFactoryPSingP(Fa,r);
478    pb=convFactoryPSingP(Gb,r);
479    Off(SW_RATIONAL);
480  }
481  // and over Q(a) / Fp(a)
482  else if ( r->cf->extRing!=NULL )
483  {
484    if (rField_is_Q_a(r)) setCharacteristic( 0 );
485    else                 setCharacteristic( rChar(r) );
486    CanonicalForm Fa,Gb;
487    if (r->cf->extRing->qideal!=NULL)
488    {
489      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
490                                           r->cf->extRing);
491      Variable a=rootOf(mipo);
492      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
493                    G( convSingAPFactoryAP( g,a,r ) );
494      CanonicalForm FpG=F+G;
495      if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
496      //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
497      {
498        WerrorS("not univariate");
499        return TRUE;
500      }
501      res= convFactoryAPSingAP( extgcd( F, G, Fa, Gb ),r );
502      pa=convFactoryAPSingAP(Fa,r);
503      pb=convFactoryAPSingAP(Gb,r);
504      prune (a);
505    }
506    else
507    {
508      CanonicalForm F( convSingTrPFactoryP( f, r ) ), G( convSingTrPFactoryP( g, r ) );
509      CanonicalForm FpG=F+G;
510      if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
511      //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
512      {
513        Off(SW_RATIONAL);
514        WerrorS("not univariate");
515        return TRUE;
516      }
517      res= convFactoryPSingTrP( extgcd( F, G, Fa, Gb ), r );
518      pa=convFactoryPSingTrP(Fa, r);
519      pb=convFactoryPSingTrP(Gb, r);
520    }
521    Off(SW_RATIONAL);
522  }
523  else
524  {
525    WerrorS( feNotImplemented );
526    return TRUE;
527  }
528#ifndef SING_NDEBUG
529  // checking the result of extgcd:
530  poly dummy;
531  dummy=p_Sub(p_Add_q(pp_Mult_qq(f,pa,r),pp_Mult_qq(g,pb,r),r),p_Copy(res,r),r);
532  if (dummy!=NULL)
533  {
534    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
535    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
536    p_Delete(&dummy,r);
537  }
538#endif
539  return FALSE;
540}
541
542poly singclap_pmult ( poly f, poly g, const ring r )
543{
544  poly res=NULL;
545  On(SW_RATIONAL);
546  if (rField_is_Zp(r) || rField_is_Q(r) || rField_is_Z(r)
547  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
548  {
549    if (rField_is_Z(r)) Off(SW_RATIONAL);
550    setCharacteristic( rChar(r) );
551    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
552    res = convFactoryPSingP( F * G,r );
553  }
554  else if (r->cf->extRing!=NULL)
555  {
556    if (rField_is_Q_a(r)) setCharacteristic( 0 );
557    else               setCharacteristic( rChar(r) );
558    if (r->cf->extRing->qideal!=NULL)
559    {
560      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
561                                                 r->cf->extRing);
562      Variable a=rootOf(mipo);
563      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
564                    G( convSingAPFactoryAP( g,a,r ) );
565      res= convFactoryAPSingAP(  F * G, r  );
566      prune (a);
567    }
568    else
569    {
570      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
571      res= convFactoryPSingTrP(  F * G,);
572    }
573  }
574#if 0 // not yet working
575  else if (rField_is_GF())
576  {
577    //Print("GF(%d^%d)\n",nfCharP,nfMinPoly[0]);
578    setCharacteristic( nfCharP,nfMinPoly[0], currRing->parameter[0][0] );
579    CanonicalForm F( convSingGFFactoryGF( f ) ), G( convSingGFFactoryGF( g ) );
580    res = convFactoryGFSingGF( F * G );
581  }
582#endif
583  else
584    WerrorS( feNotImplemented );
585  Off(SW_RATIONAL);
586  return res;
587}
588
589poly singclap_pdivide ( poly f, poly g, const ring r )
590{
591  poly res=NULL;
592
593  #ifdef HAVE_FLINT
594  #if __FLINT_RELEASE >= 20503
595  /*
596    If the division is not exact, control will pass to factory where the
597    polynomials can be divided using the ordering that factory chooses.
598  */
599  if (rField_is_Zp(r))
600  {
601    nmod_mpoly_ctx_t ctx;
602    if (!convSingRFlintR(ctx,r))
603    {
604      res = Flint_Divide_MP(f,0,g,0,ctx,r);
605      if (res != NULL)
606        return res;
607    }
608  }
609  else
610  if (rField_is_Q(r))
611  {
612    fmpq_mpoly_ctx_t ctx;
613    if (!convSingRFlintR(ctx,r))
614    {
615      res = Flint_Divide_MP(f,0,g,0,ctx,r);
616      if (res != NULL)
617        return res;
618    }
619  }
620  #endif
621  #endif
622
623  On(SW_RATIONAL);
624  if (rField_is_Zp(r) || rField_is_Q(r)
625  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
626  {
627    setCharacteristic( rChar(r) );
628    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
629    res = convFactoryPSingP( F / G,r );
630  }
631  // div is not implemented for ZZ coeffs in factory
632  else if (r->cf->extRing!=NULL)
633  {
634    if (rField_is_Q_a(r)) setCharacteristic( 0 );
635    else               setCharacteristic( rChar(r) );
636    if (r->cf->extRing->qideal!=NULL)
637    {
638      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
639                                                 r->cf->extRing);
640      Variable a=rootOf(mipo);
641      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
642                    G( convSingAPFactoryAP( g,a,r ) );
643      res= convFactoryAPSingAP(  F / G, r  );
644      prune (a);
645    }
646    else
647    {
648      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
649      res= convFactoryPSingTrP(  F / G,);
650    }
651  }
652#if 0 // not yet working
653  else if (rField_is_GF())
654  {
655    //Print("GF(%d^%d)\n",nfCharP,nfMinPoly[0]);
656    setCharacteristic( nfCharP,nfMinPoly[0], currRing->parameter[0][0] );
657    CanonicalForm F( convSingGFFactoryGF( f ) ), G( convSingGFFactoryGF( g ) );
658    res = convFactoryGFSingGF( F / G );
659  }
660#endif
661  else
662    WerrorS( feNotImplemented );
663  Off(SW_RATIONAL);
664  return res;
665}
666
667poly singclap_pmod ( poly f, poly g, const ring r )
668{
669  poly res=NULL;
670  On(SW_RATIONAL);
671  if (rField_is_Zp(r) || rField_is_Q(r)
672  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
673  {
674    setCharacteristic( rChar(r) );
675    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
676    CanonicalForm Q,R;
677    divrem(F,G,Q,R);
678    res = convFactoryPSingP(R,r);
679    //res = convFactoryPSingP( F-(F/G)*G,r );
680  }
681  // mod is not implemented for ZZ coeffs in factory
682  else if (r->cf->extRing!=NULL)
683  {
684    if (rField_is_Q_a(r)) setCharacteristic( 0 );
685    else               setCharacteristic( rChar(r) );
686    if (r->cf->extRing->qideal!=NULL)
687    {
688      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
689                                                 r->cf->extRing);
690      Variable a=rootOf(mipo);
691      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
692                    G( convSingAPFactoryAP( g,a,r ) );
693      CanonicalForm Q,R;
694      divrem(F,G,Q,R);
695      res = convFactoryAPSingAP(R,r);
696      //res= convFactoryAPSingAP( F-(F/G)*G, r  );
697      prune (a);
698    }
699    else
700    {
701      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
702      CanonicalForm Q,R;
703      divrem(F,G,Q,R);
704      res = convFactoryPSingTrP(R,r);
705      //res= convFactoryPSingTrP(  F-(F/G)*G,r  );
706    }
707  }
708#if 0 // not yet working
709  else if (rField_is_GF())
710  {
711    //Print("GF(%d^%d)\n",nfCharP,nfMinPoly[0]);
712    setCharacteristic( nfCharP,nfMinPoly[0], currRing->parameter[0][0] );
713    CanonicalForm F( convSingGFFactoryGF( f ) ), G( convSingGFFactoryGF( g ) );
714    res = convFactoryGFSingGF( F / G );
715  }
716#endif
717  else
718    WerrorS( feNotImplemented );
719  Off(SW_RATIONAL);
720  return res;
721}
722
723#if 0
724// unused
725void singclap_divide_content ( poly f, const ring r )
726{
727  if ( f==NULL )
728  {
729    return;
730  }
731  else  if ( pNext( f ) == NULL )
732  {
733    p_SetCoeff( f, n_Init( 1, r->cf ), r );
734    return;
735  }
736  else
737  {
738    if ( rField_is_Q_a(r) )
739      setCharacteristic( 0 );
740    else  if ( rField_is_Zp_a(r) )
741      setCharacteristic( -rChar(r) );
742    else
743      return; /* not implemented*/
744
745    CFList L;
746    CanonicalForm g, h;
747    poly p = pNext(f);
748
749    // first attemp: find 2 smallest g:
750
751    number g1=pGetCoeff(f);
752    number g2=pGetCoeff(p); // p==pNext(f);
753    pIter(p);
754    int sz1=n_Size(g1, r->cf);
755    int sz2=n_Size(g2, r->cf);
756    if (sz1>sz2)
757    {
758      number gg=g1;
759      g1=g2; g2=gg;
760      int sz=sz1;
761      sz1=sz2; sz2=sz;
762    }
763    while (p!=NULL)
764    {
765      int n_sz=n_Size(pGetCoeff(p),r->cf);
766      if (n_sz<sz1)
767      {
768        sz2=sz1;
769        g2=g1;
770        g1=pGetCoeff(p);
771        sz1=n_sz;
772        if (sz1<=3) break;
773      }
774      else if(n_sz<sz2)
775      {
776        sz2=n_sz;
777        g2=pGetCoeff(p);
778        sz2=n_sz;
779      }
780      pIter(p);
781    }
782    g = convSingPFactoryP( NUM(((fraction)g1)), r->cf->extRing );
783    g = gcd( g, convSingPFactoryP( NUM(((fraction)g2)) , r->cf->extRing));
784
785    // second run: gcd's
786
787    p = f;
788    while ( (p != NULL) && (g != 1)  && ( g != 0))
789    {
790      h = convSingPFactoryP( NUM(((fraction)pGetCoeff(p))), r->cf->extRing );
791      pIter( p );
792
793      g = gcd( g, h );
794
795      L.append( h );
796    }
797    if (( g == 1 ) || (g == 0))
798    {
799      // pTest(f);
800      return;
801    }
802    else
803    {
804      CFListIterator i;
805      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
806      {
807        fraction c=(fraction)pGetCoeff(p);
808        p_Delete(&(NUM(c)),r->cf->extRing); // 2nd arg used to be nacRing
809        NUM(c)=convFactoryPSingP( i.getItem() / g, r->cf->extRing );
810        //nTest((number)c);
811        //#ifdef LDEBUG
812        //number cn=(number)c;
813        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
814        //nWrite(cn);PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
815        //#endif
816      }
817    }
818    // pTest(f);
819  }
820}
821#endif
822
823BOOLEAN count_Factors(ideal I, intvec *v,int j, poly &f, poly fac, const ring r)
824{
825  p_Test(f,r);
826  p_Test(fac,r);
827  int e=0;
828  if (!p_IsConstantPoly(fac,r))
829  {
830#ifdef FACTORIZE2_DEBUG
831    printf("start count_Factors(%d), Fdeg=%d, factor deg=%d\n",j,p_Totaldegree(f,r),p_Totaldegree(fac,r));
832    p_wrp(fac,r);PrintLn();
833#endif
834    On(SW_RATIONAL);
835    CanonicalForm F, FAC,Q,R;
836    Variable a;
837    if (rField_is_Zp(r) || rField_is_Q(r)
838    || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
839    {
840      F=convSingPFactoryP( f,r );
841      FAC=convSingPFactoryP( fac,r );
842    }
843    else if (r->cf->extRing!=NULL)
844    {
845      if (r->cf->extRing->qideal!=NULL)
846      {
847        CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
848                                    r->cf->extRing);
849        a=rootOf(mipo);
850        F=convSingAPFactoryAP( f,a,r );
851        FAC=convSingAPFactoryAP( fac,a,r );
852      }
853      else
854      {
855        F=convSingTrPFactoryP( f,r );
856        FAC=convSingTrPFactoryP( fac,r );
857      }
858    }
859    else
860      WerrorS( feNotImplemented );
861
862    poly q;
863    loop
864    {
865      Q=F;
866      Q/=FAC;
867      R=Q;
868      R*=FAC;
869      R-=F;
870      if (R.isZero())
871      {
872        if (rField_is_Zp(r) || rField_is_Q(r)
873        || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
874        {
875          q = convFactoryPSingP( Q,r );
876        }
877        else if (r->cf->extRing!=NULL)
878        {
879          if (r->cf->extRing->qideal!=NULL)
880          {
881            q= convFactoryAPSingAP( Q,r );
882          }
883          else
884          {
885            q= convFactoryPSingTrP( Q,r );
886          }
887        }
888        e++; p_Delete(&f,r); f=q; q=NULL; F=Q;
889      }
890      else
891      {
892        break;
893      }
894    }
895    if (r->cf->extRing!=NULL)
896      if (r->cf->extRing->qideal!=NULL)
897        prune (a);
898    if (e==0)
899    {
900      Off(SW_RATIONAL);
901      return FALSE;
902    }
903  }
904  else e=1;
905  I->m[j]=fac;
906  if (v!=NULL) (*v)[j]=e;
907  Off(SW_RATIONAL);
908  return TRUE;
909}
910
911VAR int singclap_factorize_retry;
912
913ideal singclap_factorize ( poly f, intvec ** v , int with_exps, const ring r)
914/* destroys f, sets *v */
915{
916  p_Test(f,r);
917#ifdef FACTORIZE2_DEBUG
918  printf("singclap_factorize, degree %ld\n",p_Totaldegree(f,r));
919#endif
920  // with_exps: 3,1 return only true factors, no exponents
921  //            2 return true factors and exponents
922  //            0 return coeff, factors and exponents
923  BOOLEAN save_errorreported=errorreported;
924
925  ideal res=NULL;
926
927  // handle factorize(0) =========================================
928  if (f==NULL)
929  {
930    res=idInit(1,1);
931    if (with_exps!=1)
932    {
933      (*v)=new intvec(1);
934      (**v)[0]=1;
935    }
936    return res;
937  }
938  // handle factorize(mon) =========================================
939  if (pNext(f)==NULL)
940  {
941    int i=0;
942    int n=0;
943    int e;
944    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
945    if (with_exps==0) n++; // with coeff
946    res=idInit(si_max(n,1),1);
947    switch(with_exps)
948    {
949      case 0: // with coef & exp.
950        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
951        // no break
952      case 2: // with exp.
953        (*v)=new intvec(si_max(1,n));
954        (**v)[0]=1;
955        // no break
956      case 1: ;
957#ifdef TEST
958      default: ;
959#endif
960    }
961    if (n==0)
962    {
963      if (res->m[0]==NULL) res->m[0]=p_One(r);
964      // (**v)[0]=1; is already done
965    }
966    else
967    {
968      for(i=rVar(r);i>0;i--)
969      {
970        e=p_GetExp(f,i,r);
971        if(e!=0)
972        {
973          n--;
974          poly p=p_One(r);
975          p_SetExp(p,i,1,r);
976          p_Setm(p,r);
977          res->m[n]=p;
978          if (with_exps!=1) (**v)[n]=e;
979        }
980      }
981    }
982    p_Delete(&f,r);
983    return res;
984  }
985  //PrintS("S:");p_Write(f,r);PrintLn();
986  // use factory/libfac in general ==============================
987  Variable dummy(-1); prune(dummy); // remove all (tmp.) extensions
988  Off(SW_RATIONAL);
989  On(SW_SYMMETRIC_FF);
990  CFFList L;
991  number N=NULL;
992  number NN=NULL;
993  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
994
995  Variable a;
996  if (r->cf->convSingNFactoryN!=ndConvSingNFactoryN)
997  {
998    if (rField_is_Q(r) || rField_is_Q_a(r)) /* Q, Q(a) */
999    {
1000      //if (f!=NULL) // already tested at start of routine
1001      {
1002        number n0=n_Copy(pGetCoeff(f),r->cf);
1003        if (with_exps==0)
1004          N=n_Copy(n0,r->cf);
1005        p_Cleardenom(f, r);
1006        //after here f should not have a denominator!!
1007        //PrintS("S:");p_Write(f,r);PrintLn();
1008        NN=n_Div(n0,pGetCoeff(f),r->cf);
1009        n_Delete(&n0,r->cf);
1010        if (with_exps==0)
1011        {
1012          n_Delete(&N,r->cf);
1013          N=n_Copy(NN,r->cf);
1014        }
1015      }
1016    }
1017    else if (rField_is_Zp_a(r))
1018    {
1019      //if (f!=NULL) // already tested at start of routine
1020      if (singclap_factorize_retry==0)
1021      {
1022        number n0=n_Copy(pGetCoeff(f),r->cf);
1023        if (with_exps==0)
1024          N=n_Copy(n0,r->cf);
1025        p_Norm(f,r);
1026        p_Cleardenom(f, r);
1027        NN=n_Div(n0,pGetCoeff(f),r->cf);
1028        n_Delete(&n0,r->cf);
1029        if (with_exps==0)
1030        {
1031          n_Delete(&N,r->cf);
1032          N=n_Copy(NN,r->cf);
1033        }
1034      }
1035    }
1036    if (rField_is_Q(r) || rField_is_Zp(r) || rField_is_Z(r) || rField_is_Zn(r))
1037    {
1038      setCharacteristic( rChar(r) );
1039      CanonicalForm F( convSingPFactoryP( f,r ) );
1040      L = factorize( F );
1041    }
1042    // and over Q(a) / Fp(a)
1043    else if (r->cf->extRing!=NULL)
1044    {
1045      if (rField_is_Q_a (r)) setCharacteristic (0);
1046      else                   setCharacteristic( rChar(r) );
1047      if (r->cf->extRing->qideal!=NULL) /*algebraic extension */
1048      {
1049        CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
1050                                             r->cf->extRing);
1051        a=rootOf(mipo);
1052        CanonicalForm F( convSingAPFactoryAP( f, a, r ) );
1053        L = factorize( F, a );
1054        prune(a);
1055      }
1056      else /* rational functions */
1057      {
1058        CanonicalForm F( convSingTrPFactoryP( f,r ) );
1059        L = factorize( F );
1060      }
1061    }
1062    else
1063    {
1064      goto notImpl;
1065    }
1066  }
1067  else
1068  {
1069    goto notImpl;
1070  }
1071  {
1072    poly ff=p_Copy(f,r); // a copy for the retry stuff
1073    // the first factor should be a constant
1074    if ( ! L.getFirst().factor().inCoeffDomain() )
1075      L.insert(CFFactor(1,1));
1076    // convert into ideal
1077    int n = L.length();
1078    if (n==0) n=1;
1079    CFFListIterator J=L;
1080    int j=0;
1081    if (with_exps!=1)
1082    {
1083      if ((with_exps==2)&&(n>1))
1084      {
1085        n--;
1086        J++;
1087      }
1088      *v = new intvec( n );
1089    }
1090    res = idInit( n ,1);
1091    for ( ; J.hasItem(); J++, j++ )
1092    {
1093      if (with_exps!=1) (**v)[j] = J.getItem().exp();
1094      if (rField_is_Zp(r) || rField_is_Q(r)||  rField_is_Z(r)
1095      || rField_is_Zn(r))           /* Q, Fp, Z */
1096      {
1097        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
1098        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
1099      }
1100#if 0
1101      else if (rField_is_GF())
1102        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
1103#endif
1104      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
1105      {
1106#ifndef SING_NDEBUG
1107        intvec *w=NULL;
1108        if (v!=NULL) w=*v;
1109#endif
1110        if (r->cf->extRing->qideal==NULL)
1111        {
1112#ifdef SING_NDEBUG
1113          res->m[j]= convFactoryPSingTrP( J.getItem().factor(),r );
1114#else
1115          if(!count_Factors(res,w,j,ff,convFactoryPSingTrP( J.getItem().factor(),r ),r))
1116          {
1117            if (w!=NULL)
1118              (*w)[j]=1;
1119            res->m[j]=p_One(r);
1120          }
1121#endif
1122        }
1123        else
1124        {
1125#ifdef SING_NDEBUG
1126          res->m[j]= convFactoryAPSingAP( J.getItem().factor(),r );
1127#else
1128          if (!count_Factors(res,w,j,ff,convFactoryAPSingAP( J.getItem().factor(),r ),r))
1129          {
1130            if (w!=NULL)
1131              (*w)[j]=1;
1132            res->m[j]=p_One(r);
1133          }
1134#endif
1135        }
1136      }
1137    }
1138    if (r->cf->extRing!=NULL)
1139      if (r->cf->extRing->qideal!=NULL)
1140        prune (a);
1141#ifndef SING_NDEBUG
1142    if ((r->cf->extRing!=NULL) && (!p_IsConstantPoly(ff,r)))
1143    {
1144      singclap_factorize_retry++;
1145      if (singclap_factorize_retry<3)
1146      {
1147        int jj;
1148#ifdef FACTORIZE2_DEBUG
1149        printf("factorize_retry\n");
1150#endif
1151        intvec *ww=NULL;
1152        id_Test(res,r);
1153        ideal h=singclap_factorize ( ff, &ww , with_exps, r );
1154        id_Test(h,r);
1155        int l=(*v)->length();
1156        (*v)->resize(l+ww->length());
1157        for(jj=0;jj<ww->length();jj++)
1158          (**v)[jj+l]=(*ww)[jj];
1159        delete ww;
1160        ideal hh=idInit(IDELEMS(res)+IDELEMS(h),1);
1161        for(jj=IDELEMS(res)-1;jj>=0;jj--)
1162        {
1163          hh->m[jj]=res->m[jj];
1164          res->m[jj]=NULL;
1165        }
1166        for(jj=IDELEMS(h)-1;jj>=0;jj--)
1167        {
1168          hh->m[jj+IDELEMS(res)]=h->m[jj];
1169          h->m[jj]=NULL;
1170        }
1171        id_Delete(&res,r);
1172        id_Delete(&h,r);
1173        res=hh;
1174        id_Test(res,r);
1175        ff=NULL;
1176      }
1177      else
1178      {
1179        WarnS("problem with factorize");
1180#if 0
1181        pWrite(ff);
1182        idShow(res);
1183#endif
1184        id_Delete(&res,r);
1185        res=idInit(2,1);
1186        res->m[0]=p_One(r);
1187        res->m[1]=ff; ff=NULL;
1188      }
1189    }
1190#endif
1191    p_Delete(&ff,r);
1192    if (N!=NULL)
1193    {
1194      __p_Mult_nn(res->m[0],N,r);
1195      n_Delete(&N,r->cf);
1196      N=NULL;
1197    }
1198    // delete constants
1199    if (res!=NULL)
1200    {
1201      int i=IDELEMS(res)-1;
1202      int j=0;
1203      for(;i>=0;i--)
1204      {
1205        if ((res->m[i]!=NULL)
1206        && (pNext(res->m[i])==NULL)
1207        && (p_IsConstant(res->m[i],r)))
1208        {
1209          if (with_exps!=0)
1210          {
1211            p_Delete(&(res->m[i]),r);
1212            if ((v!=NULL) && ((*v)!=NULL))
1213              (**v)[i]=0;
1214            j++;
1215          }
1216          else if (i!=0)
1217          {
1218            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
1219            {
1220              res->m[0]=p_Mult_q(res->m[0],p_Copy(res->m[i],r),r);
1221              (**v)[i]--;
1222            }
1223            res->m[0]=p_Mult_q(res->m[0],res->m[i],r);
1224            res->m[i]=NULL;
1225            if ((v!=NULL) && ((*v)!=NULL))
1226              (**v)[i]=1;
1227            j++;
1228          }
1229        }
1230      }
1231      if (j>0)
1232      {
1233        idSkipZeroes(res);
1234        if ((v!=NULL) && ((*v)!=NULL))
1235        {
1236          intvec *w=*v;
1237          int len=IDELEMS(res);
1238          *v = new intvec( len );
1239          for (i=0,j=0;i<si_min(w->length(),len);i++)
1240          {
1241            if((*w)[i]!=0)
1242            {
1243              (**v)[j]=(*w)[i]; j++;
1244            }
1245          }
1246          delete w;
1247        }
1248      }
1249      if (res->m[0]==NULL)
1250      {
1251        res->m[0]=p_One(r);
1252      }
1253    }
1254  }
1255  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
1256  {
1257    int i=IDELEMS(res)-1;
1258    int stop=1;
1259    if (with_exps!=0) stop=0;
1260    for(;i>=stop;i--)
1261    {
1262      p_Norm(res->m[i],r);
1263    }
1264    if (with_exps==0) p_SetCoeff(res->m[0],old_lead_coeff,r);
1265    else n_Delete(&old_lead_coeff,r->cf);
1266  }
1267  else
1268    n_Delete(&old_lead_coeff,r->cf);
1269  errorreported=save_errorreported;
1270notImpl:
1271  prune(a);
1272  if (res==NULL)
1273    WerrorS( feNotImplemented );
1274  if (NN!=NULL)
1275  {
1276    n_Delete(&NN,r->cf);
1277  }
1278  if (N!=NULL)
1279  {
1280    n_Delete(&N,r->cf);
1281  }
1282  if (f!=NULL) p_Delete(&f,r);
1283  //PrintS("......S\n");
1284  return res;
1285}
1286
1287ideal singclap_sqrfree ( poly f, intvec ** v , int with_exps, const ring r)
1288{
1289  p_Test(f,r);
1290#ifdef FACTORIZE2_DEBUG
1291  printf("singclap_sqrfree, degree %d\n",pTotaldegree(f));
1292#endif
1293  // with_exps: 3,1 return only true factors, no exponents
1294  //            2 return true factors and exponents
1295  //            0 return coeff, factors and exponents
1296  BOOLEAN save_errorreported=errorreported;
1297
1298  ideal res=NULL;
1299
1300  // handle factorize(0) =========================================
1301  if (f==NULL)
1302  {
1303    res=idInit(1,1);
1304    if (with_exps!=1 && with_exps!=3)
1305    {
1306      (*v)=new intvec(1);
1307      (**v)[0]=1;
1308    }
1309    return res;
1310  }
1311  // handle factorize(mon) =========================================
1312  if (pNext(f)==NULL)
1313  {
1314    int i=0;
1315    int n=0;
1316    int e;
1317    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
1318    if (with_exps==0 || with_exps==3) n++; // with coeff
1319    res=idInit(si_max(n,1),1);
1320    if(with_exps!=1)
1321    {
1322        (*v)=new intvec(si_max(1,n));
1323        (**v)[0]=1;
1324    }
1325    res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
1326    if (n==0)
1327    {
1328      res->m[0]=p_One(r);
1329      // (**v)[0]=1; is already done
1330    }
1331    else
1332    {
1333      for(i=rVar(r);i>0;i--)
1334      {
1335        e=p_GetExp(f,i,r);
1336        if(e!=0)
1337        {
1338          n--;
1339          poly p=p_One(r);
1340          p_SetExp(p,i,1,r);
1341          p_Setm(p,r);
1342          res->m[n]=p;
1343          if (with_exps!=1) (**v)[n]=e;
1344        }
1345      }
1346    }
1347    p_Delete(&f,r);
1348    return res;
1349  }
1350  //PrintS("S:");pWrite(f);PrintLn();
1351  // use factory/libfac in general ==============================
1352  Off(SW_RATIONAL);
1353  On(SW_SYMMETRIC_FF);
1354  CFFList L;
1355  number N=NULL;
1356  number NN=NULL;
1357  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
1358  Variable a;
1359
1360  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
1361  {
1362    //if (f!=NULL) // already tested at start of routine
1363    number n0=n_Copy(pGetCoeff(f),r->cf);
1364    if (with_exps==0 || with_exps==3)
1365      N=n_Copy(n0,r->cf);
1366    p_Cleardenom(f, r);
1367    //after here f should not have a denominator!!
1368    //PrintS("S:");p_Write(f,r);PrintLn();
1369    NN=n_Div(n0,pGetCoeff(f),r->cf);
1370    n_Delete(&n0,r->cf);
1371    if (with_exps==0 || with_exps==3)
1372    {
1373      n_Delete(&N,r->cf);
1374      N=n_Copy(NN,r->cf);
1375    }
1376  }
1377  else if (rField_is_Zp_a(r))
1378  {
1379    //if (f!=NULL) // already tested at start of routine
1380    if (singclap_factorize_retry==0)
1381    {
1382      number n0=n_Copy(pGetCoeff(f),r->cf);
1383      if (with_exps==0 || with_exps==3)
1384        N=n_Copy(n0,r->cf);
1385      p_Norm(f,r);
1386      p_Cleardenom(f, r);
1387      NN=n_Div(n0,pGetCoeff(f),r->cf);
1388      n_Delete(&n0,r->cf);
1389      if (with_exps==0 || with_exps==3)
1390      {
1391        n_Delete(&N,r->cf);
1392        N=n_Copy(NN,r->cf);
1393      }
1394    }
1395  }
1396  if (rField_is_Q(r) || rField_is_Zp(r)
1397  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1398  {
1399    setCharacteristic( rChar(r) );
1400    CanonicalForm F( convSingPFactoryP( f,r ) );
1401    L = sqrFree( F );
1402  }
1403  else if (r->cf->extRing!=NULL)
1404  {
1405    if (rField_is_Q_a (r)) setCharacteristic (0);
1406    else                   setCharacteristic( rChar(r) );
1407    if (r->cf->extRing->qideal!=NULL)
1408    {
1409      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
1410                                           r->cf->extRing);
1411      a=rootOf(mipo);
1412      CanonicalForm F( convSingAPFactoryAP( f, a, r ) );
1413      L= sqrFree (F);
1414    }
1415    else
1416    {
1417      CanonicalForm F( convSingTrPFactoryP( f,r ) );
1418      L = sqrFree( F );
1419    }
1420  }
1421  #if 0
1422  else if (rField_is_GF())
1423  {
1424    int c=rChar(r);
1425    setCharacteristic( c, primepower(c) );
1426    CanonicalForm F( convSingGFFactoryGF( f ) );
1427    if (F.isUnivariate())
1428    {
1429      L = factorize( F );
1430    }
1431    else
1432    {
1433      goto notImpl;
1434    }
1435  }
1436  #endif
1437  else
1438  {
1439    goto notImpl;
1440  }
1441  {
1442    // convert into ideal
1443    int n = L.length();
1444    if (n==0) n=1;
1445    CFFListIterator J=L;
1446    int j=0;
1447    if (with_exps!=1)
1448    {
1449      if ((with_exps==2)&&(n>1))
1450      {
1451        n--;
1452        J++;
1453      }
1454      *v = new intvec( n );
1455    }
1456    else if (L.getFirst().factor().inCoeffDomain() && with_exps!=3)
1457    {
1458      n--;
1459      J++;
1460    }
1461    res = idInit( n ,1);
1462    for ( ; J.hasItem(); J++, j++ )
1463    {
1464      if (with_exps!=1 && with_exps!=3) (**v)[j] = J.getItem().exp();
1465      if (rField_is_Zp(r) || rField_is_Q(r)
1466      || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1467        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
1468      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
1469      {
1470        if (r->cf->extRing->qideal==NULL)
1471          res->m[j]=convFactoryPSingTrP( J.getItem().factor(),r );
1472        else
1473          res->m[j]=convFactoryAPSingAP( J.getItem().factor(),r );
1474      }
1475    }
1476    if (res->m[0]==NULL)
1477    {
1478      res->m[0]=p_One(r);
1479    }
1480    if (N!=NULL)
1481    {
1482      __p_Mult_nn(res->m[0],N,r);
1483      n_Delete(&N,r->cf);
1484      N=NULL;
1485    }
1486  }
1487  if (r->cf->extRing!=NULL)
1488    if (r->cf->extRing->qideal!=NULL)
1489      prune (a);
1490  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
1491  {
1492    int i=IDELEMS(res)-1;
1493    int stop=1;
1494    if (with_exps!=0 || with_exps==3) stop=0;
1495    for(;i>=stop;i--)
1496    {
1497      p_Norm(res->m[i],r);
1498    }
1499    if (with_exps==0 || with_exps==3) p_SetCoeff(res->m[0],old_lead_coeff,r);
1500    else n_Delete(&old_lead_coeff,r->cf);
1501  }
1502  else
1503    n_Delete(&old_lead_coeff,r->cf);
1504  p_Delete(&f,r);
1505  errorreported=save_errorreported;
1506notImpl:
1507  if (res==NULL)
1508    WerrorS( feNotImplemented );
1509  if (NN!=NULL)
1510  {
1511    n_Delete(&NN,r->cf);
1512  }
1513  if (N!=NULL)
1514  {
1515    n_Delete(&N,r->cf);
1516  }
1517  return res;
1518}
1519
1520matrix singclap_irrCharSeries ( ideal I, const ring r)
1521{
1522  if (idIs0(I)) return mpNew(1,1);
1523
1524  // for now there is only the possibility to handle polynomials over
1525  // Q and Fp ...
1526  matrix res=NULL;
1527  int i;
1528  Off(SW_RATIONAL);
1529  On(SW_SYMMETRIC_FF);
1530  CFList L;
1531  ListCFList LL;
1532  if (rField_is_Q(r) || rField_is_Zp(r)
1533  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1534  {
1535    setCharacteristic( rChar(r) );
1536    for(i=0;i<IDELEMS(I);i++)
1537    {
1538      poly p=I->m[i];
1539      if (p!=NULL)
1540      {
1541        p=p_Copy(p,r);
1542        p_Cleardenom(p, r);
1543        L.append(convSingPFactoryP(p,r));
1544        p_Delete(&p,r);
1545      }
1546    }
1547  }
1548  // and over Q(a) / Fp(a)
1549  else if (nCoeff_is_transExt (r->cf))
1550  {
1551    setCharacteristic( rChar(r) );
1552    for(i=0;i<IDELEMS(I);i++)
1553    {
1554      poly p=I->m[i];
1555      if (p!=NULL)
1556      {
1557        p=p_Copy(p,r);
1558        p_Cleardenom(p, r);
1559        L.append(convSingTrPFactoryP(p,r));
1560        p_Delete(&p,r);
1561      }
1562    }
1563  }
1564  else
1565  {
1566    WerrorS( feNotImplemented );
1567    return res;
1568  }
1569
1570  // a very bad work-around --- FIX IT in libfac
1571  // should be fixed as of 2001/6/27
1572  int tries=0;
1573  int m,n;
1574  ListIterator<CFList> LLi;
1575  loop
1576  {
1577    LL=irrCharSeries(L);
1578    m= LL.length(); // Anzahl Zeilen
1579    n=0;
1580    for ( LLi = LL; LLi.hasItem(); LLi++ )
1581    {
1582      n = si_max(LLi.getItem().length(),n);
1583    }
1584    if ((m!=0) && (n!=0)) break;
1585    tries++;
1586    if (tries>=5) break;
1587  }
1588  if ((m==0) || (n==0))
1589  {
1590    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
1591      m,n,IDELEMS(I)+1,LL.length());
1592    iiWriteMatrix((matrix)I,"I",2,r,0);
1593    m=si_max(m,1);
1594    n=si_max(n,1);
1595  }
1596  res=mpNew(m,n);
1597  CFListIterator Li;
1598  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
1599  {
1600    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
1601    {
1602      if (rField_is_Q(r) || rField_is_Zp(r)
1603      || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1604        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem(),r);
1605      else
1606        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem(),r);
1607    }
1608  }
1609  Off(SW_RATIONAL);
1610  return res;
1611}
1612
1613char* singclap_neworder ( ideal I, const ring r)
1614{
1615  int i;
1616  Off(SW_RATIONAL);
1617  On(SW_SYMMETRIC_FF);
1618  CFList L;
1619  if (rField_is_Q(r) || rField_is_Zp(r)
1620  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1621  {
1622    setCharacteristic( rChar(r) );
1623    for(i=0;i<IDELEMS(I);i++)
1624    {
1625      poly p=I->m[i];
1626      if (p!=NULL)
1627      {
1628        p=p_Copy(p,r);
1629        p_Cleardenom(p, r);
1630        L.append(convSingPFactoryP(p,r));
1631      }
1632    }
1633  }
1634  // and over Q(a) / Fp(a)
1635  else if (nCoeff_is_transExt (r->cf))
1636  {
1637    setCharacteristic( rChar(r) );
1638    for(i=0;i<IDELEMS(I);i++)
1639    {
1640      poly p=I->m[i];
1641      if (p!=NULL)
1642      {
1643        p=p_Copy(p,r);
1644        p_Cleardenom(p, r);
1645        L.append(convSingTrPFactoryP(p,r));
1646      }
1647    }
1648  }
1649  else
1650  {
1651    WerrorS( feNotImplemented );
1652    return NULL;
1653  }
1654
1655  List<int> IL=neworderint(L);
1656  ListIterator<int> Li;
1657  StringSetS("");
1658  Li = IL;
1659  int offs=rPar(r);
1660  int* mark=(int*)omAlloc0((rVar(r)+offs)*sizeof(int));
1661  int cnt=rVar(r)+offs;
1662  loop
1663  {
1664    if(! Li.hasItem()) break;
1665    BOOLEAN done=TRUE;
1666    i=Li.getItem()-1;
1667    mark[i]=1;
1668    if (i<offs)
1669    {
1670      done=FALSE;
1671      //StringAppendS(r->parameter[i]);
1672    }
1673    else
1674    {
1675      StringAppendS(r->names[i-offs]);
1676    }
1677    Li++;
1678    cnt--;
1679    if(cnt==0) break;
1680    if (done) StringAppendS(",");
1681  }
1682  for(i=0;i<rVar(r)+offs;i++)
1683  {
1684    BOOLEAN done=TRUE;
1685    if(mark[i]==0)
1686    {
1687      if (i<offs)
1688      {
1689        done=FALSE;
1690        //StringAppendS(r->parameter[i]);
1691      }
1692      else
1693      {
1694        StringAppendS(r->names[i-offs]);
1695      }
1696      cnt--;
1697      if(cnt==0) break;
1698      if (done) StringAppendS(",");
1699    }
1700  }
1701  char * s=StringEndS();
1702  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1703  return s;
1704}
1705
1706poly singclap_det( const matrix m, const ring s )
1707{
1708  int r=m->rows();
1709  if (r!=m->cols())
1710  {
1711    Werror("det of %d x %d matrix",r,m->cols());
1712    return NULL;
1713  }
1714  poly res=NULL;
1715  CFMatrix M(r,r);
1716  int i,j;
1717  for(i=r;i>0;i--)
1718  {
1719    for(j=r;j>0;j--)
1720    {
1721      M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1722    }
1723  }
1724  res= convFactoryPSingP( determinant(M,r),s ) ;
1725  Off(SW_RATIONAL);
1726  return res;
1727}
1728
1729int singclap_det_i( intvec * m, const ring /*r*/)
1730{
1731//  assume( r == currRing ); // Anything else is not guaranted to work!
1732
1733  setCharacteristic( 0 ); // ?
1734  CFMatrix M(m->rows(),m->cols());
1735  int i,j;
1736  for(i=m->rows();i>0;i--)
1737  {
1738    for(j=m->cols();j>0;j--)
1739    {
1740      M(i,j)=IMATELEM(*m,i,j);
1741    }
1742  }
1743  int res= convFactoryISingI( determinant(M,m->rows()) ) ;
1744  return res;
1745}
1746
1747number singclap_det_bi( bigintmat * m, const coeffs cf)
1748{
1749  assume(m->basecoeffs()==cf);
1750  CFMatrix M(m->rows(),m->cols());
1751  int i,j;
1752  BOOLEAN setchar=TRUE;
1753  for(i=m->rows();i>0;i--)
1754  {
1755    for(j=m->cols();j>0;j--)
1756    {
1757      M(i,j)=n_convSingNFactoryN(BIMATELEM(*m,i,j),setchar,cf);
1758      setchar=FALSE;
1759    }
1760  }
1761  number res=n_convFactoryNSingN( determinant(M,m->rows()),cf ) ;
1762  return res;
1763}
1764
1765#if defined(HAVE_NTL) || defined(AHVE_FLINT)
1766matrix singntl_HNF(matrix  m, const ring s )
1767{
1768  int r=m->rows();
1769  if (r!=m->cols())
1770  {
1771    Werror("HNF of %d x %d matrix",r,m->cols());
1772    return NULL;
1773  }
1774
1775  matrix res=mpNew(r,r);
1776
1777  if (rField_is_Q(s))
1778  {
1779
1780    CFMatrix M(r,r);
1781    int i,j;
1782    for(i=r;i>0;i--)
1783    {
1784      for(j=r;j>0;j--)
1785      {
1786        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
1787      }
1788    }
1789    CFMatrix *MM=cf_HNF(M);
1790    for(i=r;i>0;i--)
1791    {
1792      for(j=r;j>0;j--)
1793      {
1794        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1795      }
1796    }
1797    delete MM;
1798  }
1799  return res;
1800}
1801
1802intvec* singntl_HNF(intvec*  m)
1803{
1804  int r=m->rows();
1805  if (r!=m->cols())
1806  {
1807    Werror("HNF of %d x %d matrix",r,m->cols());
1808    return NULL;
1809  }
1810  setCharacteristic( 0 );
1811  CFMatrix M(r,r);
1812  int i,j;
1813  for(i=r;i>0;i--)
1814  {
1815    for(j=r;j>0;j--)
1816    {
1817      M(i,j)=IMATELEM(*m,i,j);
1818    }
1819  }
1820  CFMatrix *MM=cf_HNF(M);
1821  intvec *mm=ivCopy(m);
1822  for(i=r;i>0;i--)
1823  {
1824    for(j=r;j>0;j--)
1825    {
1826      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1827    }
1828  }
1829  delete MM;
1830  return mm;
1831}
1832
1833bigintmat* singntl_HNF(bigintmat*  b)
1834{
1835  int r=b->rows();
1836  if (r!=b->cols())
1837  {
1838    Werror("HNF of %d x %d matrix",r,b->cols());
1839    return NULL;
1840  }
1841  setCharacteristic( 0 );
1842  CFMatrix M(r,r);
1843  int i,j;
1844  for(i=r;i>0;i--)
1845  {
1846    for(j=r;j>0;j--)
1847    {
1848      M(i,j)=n_convSingNFactoryN(BIMATELEM(*b,i,j),FALSE,b->basecoeffs());
1849    }
1850  }
1851  CFMatrix *MM=cf_HNF(M);
1852  bigintmat *mm=bimCopy(b);
1853  for(i=r;i>0;i--)
1854  {
1855    for(j=r;j>0;j--)
1856    {
1857      BIMATELEM(*mm,i,j)=n_convFactoryNSingN((*MM)(i,j),b->basecoeffs());
1858    }
1859  }
1860  delete MM;
1861  return mm;
1862}
1863
1864matrix singntl_LLL(matrix  m, const ring s )
1865{
1866  int r=m->rows();
1867  int c=m->cols();
1868  matrix res=mpNew(r,c);
1869  if (rField_is_Q(s))
1870  {
1871    CFMatrix M(r,c);
1872    int i,j;
1873    for(i=r;i>0;i--)
1874    {
1875      for(j=c;j>0;j--)
1876      {
1877        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1878      }
1879    }
1880    CFMatrix *MM=cf_LLL(M);
1881    for(i=r;i>0;i--)
1882    {
1883      for(j=c;j>0;j--)
1884      {
1885        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1886      }
1887    }
1888    delete MM;
1889  }
1890  return res;
1891}
1892
1893intvec* singntl_LLL(intvec*  m)
1894{
1895  int r=m->rows();
1896  int c=m->cols();
1897  setCharacteristic( 0 );
1898  CFMatrix M(r,c);
1899  int i,j;
1900  for(i=r;i>0;i--)
1901  {
1902    for(j=c;j>0;j--)
1903    {
1904      M(i,j)=IMATELEM(*m,i,j);
1905    }
1906  }
1907  CFMatrix *MM=cf_LLL(M);
1908  intvec *mm=ivCopy(m);
1909  for(i=r;i>0;i--)
1910  {
1911    for(j=c;j>0;j--)
1912    {
1913      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1914    }
1915  }
1916  delete MM;
1917  return mm;
1918}
1919#else
1920matrix singntl_HNF(matrix  m, const ring s )
1921{
1922  WerrorS("NTL/FLINT missing");
1923  return NULL;
1924}
1925
1926intvec* singntl_HNF(intvec*  m)
1927{
1928  WerrorS("NTL/FLINT missing");
1929  return NULL;
1930}
1931
1932matrix singntl_LLL(matrix  m, const ring s )
1933{
1934  WerrorS("NTL/FLINT missing");
1935  return NULL;
1936}
1937
1938intvec* singntl_LLL(intvec*  m)
1939{
1940  WerrorS("NTL/FLINT missing");
1941  return NULL;
1942}
1943#endif
1944
1945#ifdef HAVE_NTL
1946ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
1947{
1948  p_Test(f, r);
1949
1950  ideal res=NULL;
1951
1952  int offs = rPar(r);
1953  if (f==NULL)
1954  {
1955    res= idInit (1, 1);
1956    mipos= idInit (1, 1);
1957    mipos->m[0]= convFactoryPSingTrP (Variable (offs), r); //overkill
1958    (*exps)=new intvec (1);
1959    (**exps)[0]= 1;
1960    numFactors= 0;
1961    return res;
1962  }
1963  CanonicalForm F( convSingTrPFactoryP( f, r) );
1964
1965  bool isRat= isOn (SW_RATIONAL);
1966  if (!isRat)
1967    On (SW_RATIONAL);
1968
1969  CFAFList absFactors= absFactorize (F);
1970
1971  int n= absFactors.length();
1972  *exps=new intvec (n);
1973
1974  res= idInit (n, 1);
1975
1976  mipos= idInit (n, 1);
1977
1978  Variable x= Variable (offs);
1979  Variable alpha;
1980  int i= 0;
1981  numFactors= 0;
1982  int count;
1983  CFAFListIterator iter= absFactors;
1984  CanonicalForm lead= iter.getItem().factor();
1985  if (iter.getItem().factor().inCoeffDomain())
1986  {
1987    i++;
1988    iter++;
1989  }
1990  for (; iter.hasItem(); iter++, i++)
1991  {
1992    (**exps)[i]= iter.getItem().exp();
1993    alpha= iter.getItem().minpoly().mvar();
1994    if (iter.getItem().minpoly().isOne())
1995      lead /= power (bCommonDen (iter.getItem().factor()), iter.getItem().exp());
1996    else
1997      lead /= power (power (bCommonDen (iter.getItem().factor()), degree (iter.getItem().minpoly())), iter.getItem().exp());
1998    res->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().factor()*bCommonDen (iter.getItem().factor()), alpha, x), r);
1999    if (iter.getItem().minpoly().isOne())
2000    {
2001      count= iter.getItem().exp();
2002      mipos->m[i]= convFactoryPSingTrP (x,r);
2003    }
2004    else
2005    {
2006      count= iter.getItem().exp()*degree (iter.getItem().minpoly());
2007      mipos->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().minpoly(), alpha, x), r);
2008    }
2009    if (!iter.getItem().minpoly().isOne())
2010      prune (alpha);
2011    numFactors += count;
2012  }
2013  if (!isRat)
2014    Off (SW_RATIONAL);
2015
2016  (**exps)[0]= 1;
2017  res->m[0]= convFactoryPSingTrP (lead, r);
2018  mipos->m[0]= convFactoryPSingTrP (x, r);
2019  return res;
2020}
2021
2022#else
2023ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
2024{
2025  WerrorS("NTL missing");
2026  return NULL;
2027}
2028
2029#endif /* HAVE_NTL */
2030
Note: See TracBrowser for help on using the repository browser.