source: git/libpolys/polys/clapsing.cc @ 647b762

spielwiese
Last change on this file since 647b762 was 647b762, checked in by Hans Schoenemann <hannes@…>, 4 years ago
fix: trac #861: removed NTL references from libpolys
  • Property mode set to 100644
File size: 47.2 KB
RevLine 
[35aab3]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
[b963c5]9//#define FACTORIZE2_DEBUG
[3426545]10
[aadd638]11#include "misc/auxiliary.h"
[3426545]12#include "clapsing.h"
13
[aadd638]14#include "factory/factory.h"
[fea2af]15
[aadd638]16#include "coeffs/numbers.h"
17#include "coeffs/coeffs.h"
18#include "coeffs/bigintmat.h"
[af598e]19
20#include "monomials/ring.h"
21#include "simpleideals.h"
[4abcd2]22#include "polys/flintconv.h"
23#include "polys/flint_mpoly.h"
[35aab3]24
[9144617]25
[1f414c8]26//#include "polys.h"
27#define TRANSEXT_PRIVATES
[3426545]28
[1f414c8]29#include "ext_fields/transext.h"
30
[9144617]31
32#include "clapconv.h"
[aadd638]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"
[3426545]40
[9144617]41
[a86cda]42void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
[35aab3]43
[5a4e17]44poly singclap_gcd_r ( poly f, poly g, const ring r )
[35aab3]45{
46  poly res=NULL;
47
[36586bb]48  assume(f!=NULL);
49  assume(g!=NULL);
50
[255be23]51  if(pNext(f)==NULL)
[9b9b5a]52  {
[255be23]53    return p_GcdMon(f,g,r);
[5a4e17]54  }
[255be23]55  else if(pNext(g)==NULL)
[5a4e17]56  {
[255be23]57    return p_GcdMon(g,f,r);
[9b9b5a]58  }
[4abcd2]59  #ifdef HAVE_FLINT
60  #if __FLINT_RELEASE >= 20503
[5cf3215]61  if (rField_is_Zp(r) && (r->cf->ch>10))
[4abcd2]62  {
63    nmod_mpoly_ctx_t ctx;
64    if (!convSingRFlintR(ctx,r))
65    {
[d90ef2]66      // leading coef. 1
[4abcd2]67      return Flint_GCD_MP(f,pLength(f),g,pLength(g),ctx,r);
68    }
69  }
[0a0bfe]70  else
[919490]71  if (rField_is_Q(r))
[4abcd2]72  {
73    fmpq_mpoly_ctx_t ctx;
74    if (!convSingRFlintR(ctx,r))
75    {
[d90ef2]76      // leading coef. positive, all coeffs in Z
[4abcd2]77      poly res=Flint_GCD_MP(f,pLength(f),g,pLength(g),ctx,r);
78      res=p_Cleardenom(res,r);
[d90ef2]79      return res;
[4abcd2]80    }
81  }
82  #endif
83  #endif
[ea48f7d]84  Off(SW_RATIONAL);
[353a42]85  if (rField_is_Q(r) || rField_is_Zp(r) || rField_is_Z(r)
[417a91a]86  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[ce2576]87  {
88    setCharacteristic( rChar(r) );
89    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g, r ) );
90    res=convFactoryPSingP( gcd( F, G ) , r);
[d90ef2]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
[ce2576]95  }
96  // and over Q(a) / Fp(a)
[e72a9a]97  else if ( r->cf->extRing!=NULL )
[ce2576]98  {
99    if ( rField_is_Q_a(r)) setCharacteristic( 0 );
100    else                   setCharacteristic( rChar(r) );
[dd668f]101    if (r->cf->extRing->qideal!=NULL)
[ce2576]102    {
103      bool b1=isOn(SW_USE_QGCD);
104      if ( rField_is_Q_a(r) ) On(SW_USE_QGCD);
[dd668f]105      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
[ce2576]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 );
[8b00ca]111      prune (a);
[ce2576]112      if (!b1) Off(SW_USE_QGCD);
[85e90d]113      if ( rField_is_Zp_a(r)) p_Norm(res,r); // leading coef. 1
[ce2576]114    }
115    else
116    {
[184739]117      convSingTrP(f,r);
118      convSingTrP(g,r);
[ce2576]119      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
120      res= convFactoryPSingTrP( gcd( F, G ),r );
121    }
122  }
[6462a0]123  else if (r->cf->convSingNFactoryN==ndConvSingNFactoryN)
[ce2576]124    WerrorS( feNotImplemented );
[6462a0]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  }
[ea48f7d]131  Off(SW_RATIONAL);
[35aab3]132  return res;
133}
134
[2de7b0]135poly singclap_gcd_and_divide ( poly& f, poly& g, const ring r)
[91d0e6]136{
137  poly res=NULL;
138
[2de7b0]139  if (g == NULL)
140  {
[7f7808]141    res= f;
[2de7b0]142    f=p_One (r);
143    return res;
144  }
145  if (f==NULL)
146  {
[7f7808]147    res= g;
[2de7b0]148    g=p_One (r);
149    return res;
150  }
[7b4ca1f]151  if (pNext(g)==NULL)
[061eacd]152  {
[7b4ca1f]153    poly G=p_GcdMon(g,f,r);
154    if (!n_IsOne(pGetCoeff(G),r->cf)
155    || (!p_IsConstant(G,r)))
[061eacd]156    {
[7b4ca1f]157      f=p_Div_mm(f,G,r);
158      g=p_Div_mm(g,G,r);
159    }
160    return G;
[061eacd]161  }
[7b4ca1f]162  else if (pNext(f)==NULL)
[061eacd]163  {
[7b4ca1f]164    poly G=p_GcdMon(f,g,r);
165    if (!n_IsOne(pGetCoeff(G),r->cf)
166    || (!p_IsConstant(G,r)))
[061eacd]167    {
[7b4ca1f]168      f=p_Div_mm(f,G,r);
169      g=p_Div_mm(g,G,r);
170    }
171    return G;
[061eacd]172  }
[cd964c]173
174  Off(SW_RATIONAL);
175  CanonicalForm F,G,GCD;
[417a91a]176  if (rField_is_Q(r) || (rField_is_Zp(r))
177  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[cd964c]178  {
179    bool b1=isOn(SW_USE_EZGCD_P);
[88b655]180    setCharacteristic( rChar(r) );
[cd964c]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);
[2de7b0]188      if (getCharacteristic() == 0)
189        On (SW_RATIONAL);
[57f6787]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);
[cd964c]208    }
[2de7b0]209    res=convFactoryPSingP( GCD , r);
[cd964c]210    if (!b1) Off (SW_USE_EZGCD_P);
211  }
212  // and over Q(a) / Fp(a)
[e72a9a]213  else if ( r->cf->extRing )
[cd964c]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);
[2de7b0]231        if (getCharacteristic() == 0)
232          On (SW_RATIONAL);
[57f6787]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 );
[cd964c]251      }
[2de7b0]252      res= convFactoryAPSingAP( GCD,r );
[8b00ca]253      prune (a);
[cd964c]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);
[2de7b0]265        if (getCharacteristic() == 0)
266          On (SW_RATIONAL);
[57f6787]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 );
[cd964c]285      }
[2de7b0]286      res= convFactoryPSingTrP( GCD,r );
[cd964c]287    }
288  }
289  else
290    WerrorS( feNotImplemented );
291  Off(SW_RATIONAL);
[2de7b0]292  return res;
[cd964c]293}
294
[c95632f]295/*2 find the maximal exponent of var(i) in poly p*/
[ce3f53c]296int pGetExp_Var(poly p, int i, const ring r)
[c95632f]297{
298  int m=0;
299  int mm;
300  while (p!=NULL)
301  {
[ce3f53c]302    mm=p_GetExp(p,i,r);
[c95632f]303    if (mm>m) m=mm;
304    pIter(p);
305  }
306  return m;
307}
308
[9d9078]309// destroys f,g,x
[ce3f53c]310poly singclap_resultant ( poly f, poly g , poly x, const ring r)
[35aab3]311{
[9d9078]312  poly res=NULL;
[ce3f53c]313  int i=p_IsPurePower(x, r);
[35aab3]314  if (i==0)
315  {
316    WerrorS("3rd argument must be a ring variable");
[9d9078]317    goto resultant_returns_res;
[35aab3]318  }
319  if ((f==NULL) || (g==NULL))
[9d9078]320    goto resultant_returns_res;
[ce2576]321  // for now there is only the possibility to handle polynomials over
322  // Q and Fp ...
[417a91a]323  if (rField_is_Zp(r) || rField_is_Q(r)
324  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[ce2576]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 );
[35aab3]330    Off(SW_RATIONAL);
[ce2576]331    goto resultant_returns_res;
[35aab3]332  }
[ce2576]333  // and over Q(a) / Fp(a)
[e72a9a]334  else if (r->cf->extRing!=NULL)
[ce2576]335  {
336    if (rField_is_Q_a(r)) setCharacteristic( 0 );
337    else               setCharacteristic( rChar(r) );
338    Variable X(i+rPar(r));
[dd668f]339    if (r->cf->extRing->qideal!=NULL)
[ce2576]340    {
341      //Variable X(i);
[dd668f]342      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
[ce2576]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 );
[8b00ca]348      prune (a);
[ce2576]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 );
[a355723]360      if ((nf!=NULL)&&(!n_IsOne(nf,r->cf)))
[ce2576]361      {
362        number n=n_Invers(nf,r->cf);
363        while(eg>0)
364        {
[3d1222a]365          res=__p_Mult_nn(res,n,r);
[ce2576]366          eg--;
367        }
368        n_Delete(&n,r->cf);
369      }
370      n_Delete(&nf,r->cf);
[a355723]371      if ((ng!=NULL)&&(!n_IsOne(ng,r->cf)))
[ce2576]372      {
373        number n=n_Invers(ng,r->cf);
374        while(ef>0)
375        {
[3d1222a]376          res=__p_Mult_nn(res,n,r);
[ce2576]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 );
[9d9078]388resultant_returns_res:
[ce3f53c]389  p_Delete(&f,r);
390  p_Delete(&g,r);
391  p_Delete(&x,r);
[9d9078]392  return res;
[35aab3]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
[ce3f53c]454BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb , const ring r)
[35aab3]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);
[417a91a]461  if ( rField_is_Q(r) || rField_is_Zp(r)
462  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[35aab3]463  {
[ce2576]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)
[e72a9a]482  else if ( r->cf->extRing!=NULL )
[ce2576]483  {
484    if (rField_is_Q_a(r)) setCharacteristic( 0 );
485    else                 setCharacteristic( rChar(r) );
486    CanonicalForm Fa,Gb;
[dd668f]487    if (r->cf->extRing->qideal!=NULL)
[ce2576]488    {
[dd668f]489      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
[ce2576]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);
[8b00ca]504      prune (a);
[ce2576]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    }
[35aab3]521    Off(SW_RATIONAL);
[ce2576]522  }
523  else
524  {
525    WerrorS( feNotImplemented );
[35aab3]526    return TRUE;
527  }
[7fe9e13]528#ifndef SING_NDEBUG
[a86cda]529  // checking the result of extgcd:
530  poly dummy;
[ce3f53c]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);
[a86cda]532  if (dummy!=NULL)
533  {
[ce3f53c]534    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
[ce2576]535    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
[ce3f53c]536    p_Delete(&dummy,r);
[a86cda]537  }
[9d9078]538#endif
[35aab3]539  return FALSE;
540}
541
[0ec309]542poly singclap_pmult ( poly f, poly g, const ring r )
543{
544  poly res=NULL;
545  On(SW_RATIONAL);
[353a42]546  if (rField_is_Zp(r) || rField_is_Q(r) || rField_is_Z(r)
[417a91a]547  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[0ec309]548  {
[353a42]549    if (rField_is_Z(r)) Off(SW_RATIONAL);
[0ec309]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
[ce3f53c]589poly singclap_pdivide ( poly f, poly g, const ring r )
[35aab3]590{
591  poly res=NULL;
[2fb52df]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    {
[a631cdc]604      res = Flint_Divide_MP(f,0,g,0,ctx,r);
[2fb52df]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    {
[a631cdc]615      res = Flint_Divide_MP(f,0,g,0,ctx,r);
[2fb52df]616      if (res != NULL)
617        return res;
618    }
619  }
620  #endif
621  #endif
622
[35aab3]623  On(SW_RATIONAL);
[417a91a]624  if (rField_is_Zp(r) || rField_is_Q(r)
625  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[ce2576]626  {
627    setCharacteristic( rChar(r) );
628    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
629    res = convFactoryPSingP( F / G,r );
630  }
[4c1e770]631  // div is not implemented for ZZ coeffs in factory
[e72a9a]632  else if (r->cf->extRing!=NULL)
[ce2576]633  {
634    if (rField_is_Q_a(r)) setCharacteristic( 0 );
635    else               setCharacteristic( rChar(r) );
[dd668f]636    if (r->cf->extRing->qideal!=NULL)
[ce2576]637    {
[dd668f]638      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
[ce2576]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  );
[8b00ca]644      prune (a);
[ce2576]645    }
646    else
647    {
648      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
649      res= convFactoryPSingTrP(  F / G,);
650    }
651  }
[3d5596]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);
[417a91a]671  if (rField_is_Zp(r) || rField_is_Q(r)
672  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[3d5596]673  {
674    setCharacteristic( rChar(r) );
675    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
[8f9132]676    CanonicalForm Q,R;
677    divrem(F,G,Q,R);
678    res = convFactoryPSingP(R,r);
679    //res = convFactoryPSingP( F-(F/G)*G,r );
[3d5596]680  }
[4c1e770]681  // mod is not implemented for ZZ coeffs in factory
[3d5596]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 ) );
[8f9132]693      CanonicalForm Q,R;
694      divrem(F,G,Q,R);
695      res = convFactoryAPSingAP(R,r);
696      //res= convFactoryAPSingAP( F-(F/G)*G, r  );
[3d5596]697      prune (a);
698    }
699    else
700    {
701      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
[8f9132]702      CanonicalForm Q,R;
703      divrem(F,G,Q,R);
704      res = convFactoryPSingTrP(R,r);
705      //res= convFactoryPSingTrP(  F-(F/G)*G,r  );
[3d5596]706    }
707  }
[3426545]708#if 0 // not yet working
[ce2576]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  }
[3426545]716#endif
[ce2576]717  else
718    WerrorS( feNotImplemented );
[d1f231]719  Off(SW_RATIONAL);
720  return res;
721}
722
[9ac00d]723#if 0
724// unused
[ce3f53c]725void singclap_divide_content ( poly f, const ring r )
[35aab3]726{
727  if ( f==NULL )
728  {
729    return;
730  }
731  else  if ( pNext( f ) == NULL )
732  {
[ce3f53c]733    p_SetCoeff( f, n_Init( 1, r->cf ), r );
[35aab3]734    return;
735  }
736  else
737  {
[ce3f53c]738    if ( rField_is_Q_a(r) )
[35aab3]739      setCharacteristic( 0 );
[ce3f53c]740    else  if ( rField_is_Zp_a(r) )
741      setCharacteristic( -rChar(r) );
[35aab3]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);
[ce3f53c]754    int sz1=n_Size(g1, r->cf);
755    int sz2=n_Size(g2, r->cf);
[35aab3]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    {
[ce3f53c]765      int n_sz=n_Size(pGetCoeff(p),r->cf);
[35aab3]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    }
[7b2b05]782    g = convSingPFactoryP( NUM(((fraction)g1)), r->cf->extRing );
783    g = gcd( g, convSingPFactoryP( NUM(((fraction)g2)) , r->cf->extRing));
[35aab3]784
785    // second run: gcd's
786
787    p = f;
788    while ( (p != NULL) && (g != 1)  && ( g != 0))
789    {
[7b2b05]790      h = convSingPFactoryP( NUM(((fraction)pGetCoeff(p))), r->cf->extRing );
[35aab3]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      {
[7b2b05]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 );
[35aab3]810        //nTest((number)c);
811        //#ifdef LDEBUG
812        //number cn=(number)c;
813        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
[54fc4e]814        //nWrite(cn);PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
[35aab3]815        //#endif
816      }
817    }
818    // pTest(f);
819  }
820}
[9ac00d]821#endif
[35aab3]822
[ce3f53c]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);
[0a55e5]827  int e=0;
[ce3f53c]828  if (!p_IsConstantPoly(fac,r))
[0a55e5]829  {
830#ifdef FACTORIZE2_DEBUG
[ce2576]831    printf("start count_Factors(%d), Fdeg=%d, factor deg=%d\n",j,p_Totaldegree(f,r),p_Totaldegree(fac,r));
[1db880]832    p_wrp(fac,r);PrintLn();
[0a55e5]833#endif
834    On(SW_RATIONAL);
835    CanonicalForm F, FAC,Q,R;
836    Variable a;
[417a91a]837    if (rField_is_Zp(r) || rField_is_Q(r)
838    || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[ce2576]839    {
840      F=convSingPFactoryP( f,r );
841      FAC=convSingPFactoryP( fac,r );
842    }
[e72a9a]843    else if (r->cf->extRing!=NULL)
[ce2576]844    {
[dd668f]845      if (r->cf->extRing->qideal!=NULL)
[ce2576]846      {
[dd668f]847        CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
[ce2576]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 );
[0a55e5]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      {
[417a91a]872        if (rField_is_Zp(r) || rField_is_Q(r)
873        || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[ce2576]874        {
875          q = convFactoryPSingP( Q,r );
876        }
[e72a9a]877        else if (r->cf->extRing!=NULL)
[ce2576]878        {
[dd668f]879          if (r->cf->extRing->qideal!=NULL)
[ce2576]880          {
881            q= convFactoryAPSingAP( Q,r );
882          }
883          else
884          {
885            q= convFactoryPSingTrP( Q,r );
886          }
887        }
[ce3f53c]888        e++; p_Delete(&f,r); f=q; q=NULL; F=Q;
[0a55e5]889      }
890      else
891      {
892        break;
893      }
894    }
[8b00ca]895    if (r->cf->extRing!=NULL)
896      if (r->cf->extRing->qideal!=NULL)
897        prune (a);
[0a55e5]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
[a3f0fea]911VAR int singclap_factorize_retry;
[a5d9313]912
[ce3f53c]913ideal singclap_factorize ( poly f, intvec ** v , int with_exps, const ring r)
[93e7e91]914/* destroys f, sets *v */
[35aab3]915{
[ce3f53c]916  p_Test(f,r);
[0a55e5]917#ifdef FACTORIZE2_DEBUG
[ce2576]918  printf("singclap_factorize, degree %ld\n",p_Totaldegree(f,r));
[0a55e5]919#endif
[35aab3]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
[ee5d91]923  BOOLEAN save_errorreported=errorreported;
[35aab3]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;
[ce3f53c]944    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
[35aab3]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.
[ce3f53c]950        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
[35aab3]951        // no break
952      case 2: // with exp.
[54ff35]953        (*v)=new intvec(si_max(1,n));
[35aab3]954        (**v)[0]=1;
955        // no break
956      case 1: ;
[3426545]957#ifdef TEST
[35aab3]958      default: ;
[3426545]959#endif
[35aab3]960    }
961    if (n==0)
962    {
[2956e79]963      if (res->m[0]==NULL) res->m[0]=p_One(r);
[35aab3]964      // (**v)[0]=1; is already done
965    }
[93e7e91]966    else
[35aab3]967    {
[ce3f53c]968      for(i=rVar(r);i>0;i--)
[35aab3]969      {
[ce3f53c]970        e=p_GetExp(f,i,r);
[93e7e91]971        if(e!=0)
972        {
973          n--;
[ce3f53c]974          poly p=p_One(r);
975          p_SetExp(p,i,1,r);
976          p_Setm(p,r);
[93e7e91]977          res->m[n]=p;
978          if (with_exps!=1) (**v)[n]=e;
979        }
[35aab3]980      }
981    }
[ce3f53c]982    p_Delete(&f,r);
[35aab3]983    return res;
984  }
[ce2576]985  //PrintS("S:");p_Write(f,r);PrintLn();
[54ff35]986  // use factory/libfac in general ==============================
[2956e79]987  Variable dummy(-1); prune(dummy); // remove all (tmp.) extensions
[35aab3]988  Off(SW_RATIONAL);
989  On(SW_SYMMETRIC_FF);
990  CFFList L;
991  number N=NULL;
[ffdd694]992  number NN=NULL;
[ce3f53c]993  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
[35aab3]994
[8b00ca]995  Variable a;
[67c922]996  if (r->cf->convSingNFactoryN!=ndConvSingNFactoryN)
[0a55e5]997  {
[67c922]998    if (rField_is_Q(r) || rField_is_Q_a(r)) /* Q, Q(a) */
[0a55e5]999    {
[67c922]1000      //if (f!=NULL) // already tested at start of routine
[0a55e5]1001      {
[67c922]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        }
[0a55e5]1015      }
1016    }
[67c922]1017    else if (rField_is_Zp_a(r))
[35aab3]1018    {
[67c922]1019      //if (f!=NULL) // already tested at start of routine
1020      if (singclap_factorize_retry==0)
[35aab3]1021      {
[67c922]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        }
[35aab3]1034      }
1035    }
[67c922]1036    if (rField_is_Q(r) || rField_is_Zp(r) || rField_is_Z(r) || rField_is_Zn(r))
[35aab3]1037    {
[67c922]1038      setCharacteristic( rChar(r) );
1039      CanonicalForm F( convSingPFactoryP( f,r ) );
1040      L = factorize( F );
[35aab3]1041    }
[67c922]1042    // and over Q(a) / Fp(a)
1043    else if (r->cf->extRing!=NULL)
[35aab3]1044    {
[67c922]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;
[35aab3]1065    }
1066  }
1067  else
1068  {
1069    goto notImpl;
1070  }
1071  {
[ce3f53c]1072    poly ff=p_Copy(f,r); // a copy for the retry stuff
[35aab3]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();
[91cb92]1078    if (n==0) n=1;
[35aab3]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();
[417a91a]1094      if (rField_is_Zp(r) || rField_is_Q(r)||  rField_is_Z(r)
[67c922]1095      || rField_is_Zn(r))           /* Q, Fp, Z */
[8fc55e2]1096      {
[46f6af6]1097        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
[ce3f53c]1098        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
[8fc55e2]1099      }
[3426545]1100#if 0
[35aab3]1101      else if (rField_is_GF())
[46f6af6]1102        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
[3426545]1103#endif
[e72a9a]1104      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
[35aab3]1105      {
[7fe9e13]1106#ifndef SING_NDEBUG
[5d491d]1107        intvec *w=NULL;
1108        if (v!=NULL) w=*v;
[ea1d44c]1109#endif
[dd668f]1110        if (r->cf->extRing->qideal==NULL)
[8fc55e2]1111        {
[7fe9e13]1112#ifdef SING_NDEBUG
[ea1d44c]1113          res->m[j]= convFactoryPSingTrP( J.getItem().factor(),r );
1114#else
[ce2576]1115          if(!count_Factors(res,w,j,ff,convFactoryPSingTrP( J.getItem().factor(),r ),r))
[d499d1]1116          {
[a86cda]1117            if (w!=NULL)
[e080ab]1118              (*w)[j]=1;
[ce3f53c]1119            res->m[j]=p_One(r);
[d499d1]1120          }
[ea1d44c]1121#endif
[8fc55e2]1122        }
[35aab3]1123        else
[8fc55e2]1124        {
[7fe9e13]1125#ifdef SING_NDEBUG
[ea1d44c]1126          res->m[j]= convFactoryAPSingAP( J.getItem().factor(),r );
1127#else
[ce2576]1128          if (!count_Factors(res,w,j,ff,convFactoryAPSingAP( J.getItem().factor(),r ),r))
[d499d1]1129          {
[a86cda]1130            if (w!=NULL)
[e080ab]1131              (*w)[j]=1;
[ce3f53c]1132            res->m[j]=p_One(r);
[d499d1]1133          }
[ea1d44c]1134#endif
[8fc55e2]1135        }
[0a55e5]1136      }
1137    }
[8b00ca]1138    if (r->cf->extRing!=NULL)
1139      if (r->cf->extRing->qideal!=NULL)
1140        prune (a);
[7fe9e13]1141#ifndef SING_NDEBUG
[e72a9a]1142    if ((r->cf->extRing!=NULL) && (!p_IsConstantPoly(ff,r)))
[0a55e5]1143    {
1144      singclap_factorize_retry++;
1145      if (singclap_factorize_retry<3)
1146      {
1147        int jj;
[3426545]1148#ifdef FACTORIZE2_DEBUG
[0a55e5]1149        printf("factorize_retry\n");
[3426545]1150#endif
[0a55e5]1151        intvec *ww=NULL;
[ce3f53c]1152        id_Test(res,r);
1153        ideal h=singclap_factorize ( ff, &ww , with_exps, r );
1154        id_Test(h,r);
[0a55e5]1155        int l=(*v)->length();
[91cb92]1156        (*v)->resize(l+ww->length());
[0a55e5]1157        for(jj=0;jj<ww->length();jj++)
[91cb92]1158          (**v)[jj+l]=(*ww)[jj];
[0a55e5]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        }
[ce3f53c]1171        id_Delete(&res,r);
1172        id_Delete(&h,r);
[0a55e5]1173        res=hh;
[ce3f53c]1174        id_Test(res,r);
[0a55e5]1175        ff=NULL;
1176      }
1177      else
1178      {
1179        WarnS("problem with factorize");
[3426545]1180#if 0
[226dd7]1181        pWrite(ff);
1182        idShow(res);
[3426545]1183#endif
[ce3f53c]1184        id_Delete(&res,r);
[226dd7]1185        res=idInit(2,1);
[ce3f53c]1186        res->m[0]=p_One(r);
[226dd7]1187        res->m[1]=ff; ff=NULL;
[35aab3]1188      }
1189    }
[ea1d44c]1190#endif
[ce3f53c]1191    p_Delete(&ff,r);
[35aab3]1192    if (N!=NULL)
1193    {
[3d1222a]1194      __p_Mult_nn(res->m[0],N,r);
[ce3f53c]1195      n_Delete(&N,r->cf);
[ffdd694]1196      N=NULL;
[35aab3]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)
[ce3f53c]1207        && (p_IsConstant(res->m[i],r)))
[35aab3]1208        {
1209          if (with_exps!=0)
1210          {
[ce3f53c]1211            p_Delete(&(res->m[i]),r);
[35aab3]1212            if ((v!=NULL) && ((*v)!=NULL))
1213              (**v)[i]=0;
1214            j++;
1215          }
1216          else if (i!=0)
1217          {
[d8932ed]1218            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
1219            {
[ce3f53c]1220              res->m[0]=p_Mult_q(res->m[0],p_Copy(res->m[i],r),r);
[d8932ed]1221              (**v)[i]--;
1222            }
[ce3f53c]1223            res->m[0]=p_Mult_q(res->m[0],res->m[i],r);
[35aab3]1224            res->m[i]=NULL;
1225            if ((v!=NULL) && ((*v)!=NULL))
[d499d1]1226              (**v)[i]=1;
[35aab3]1227            j++;
1228          }
1229        }
1230      }
1231      if (j>0)
1232      {
1233        idSkipZeroes(res);
1234        if ((v!=NULL) && ((*v)!=NULL))
1235        {
1236          intvec *w=*v;
[f12cd23]1237          int len=IDELEMS(res);
1238          *v = new intvec( len );
[0a55e5]1239          for (i=0,j=0;i<si_min(w->length(),len);i++)
[35aab3]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      {
[ce3f53c]1251        res->m[0]=p_One(r);
[35aab3]1252      }
1253    }
1254  }
[dd668f]1255  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
[35aab3]1256  {
1257    int i=IDELEMS(res)-1;
1258    int stop=1;
1259    if (with_exps!=0) stop=0;
1260    for(;i>=stop;i--)
1261    {
[ce3f53c]1262      p_Norm(res->m[i],r);
[35aab3]1263    }
[ce3f53c]1264    if (with_exps==0) p_SetCoeff(res->m[0],old_lead_coeff,r);
1265    else n_Delete(&old_lead_coeff,r->cf);
[35aab3]1266  }
1267  else
[ce3f53c]1268    n_Delete(&old_lead_coeff,r->cf);
[ee5d91]1269  errorreported=save_errorreported;
[35aab3]1270notImpl:
[2956e79]1271  prune(a);
[35aab3]1272  if (res==NULL)
1273    WerrorS( feNotImplemented );
[ffdd694]1274  if (NN!=NULL)
[35aab3]1275  {
[ce3f53c]1276    n_Delete(&NN,r->cf);
[ffdd694]1277  }
1278  if (N!=NULL)
1279  {
[ce3f53c]1280    n_Delete(&N,r->cf);
[35aab3]1281  }
[ce3f53c]1282  if (f!=NULL) p_Delete(&f,r);
[35aab3]1283  //PrintS("......S\n");
1284  return res;
1285}
[feed237]1286
[3ef9c8]1287ideal singclap_sqrfree ( poly f, intvec ** v , int with_exps, const ring r)
[0dd641]1288{
[ce3f53c]1289  p_Test(f,r);
[0dd641]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);
[c92097b]1304    if (with_exps!=1 && with_exps!=3)
[3ef9c8]1305    {
1306      (*v)=new intvec(1);
1307      (**v)[0]=1;
1308    }
[0dd641]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;
[ce3f53c]1317    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
[c92097b]1318    if (with_exps==0 || with_exps==3) n++; // with coeff
[0dd641]1319    res=idInit(si_max(n,1),1);
[571544]1320    if(with_exps!=1)
[3ef9c8]1321    {
1322        (*v)=new intvec(si_max(1,n));
1323        (**v)[0]=1;
1324    }
[ce3f53c]1325    res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
[0dd641]1326    if (n==0)
1327    {
[ce3f53c]1328      res->m[0]=p_One(r);
[0dd641]1329      // (**v)[0]=1; is already done
1330    }
[3ef9c8]1331    else
[0dd641]1332    {
[3ef9c8]1333      for(i=rVar(r);i>0;i--)
[0dd641]1334      {
[3ef9c8]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        }
[0dd641]1345      }
1346    }
[3ef9c8]1347    p_Delete(&f,r);
[0dd641]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;
[3ef9c8]1355  number N=NULL;
1356  number NN=NULL;
[f78374]1357  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
[8b00ca]1358  Variable a;
[0dd641]1359
[ce3f53c]1360  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
[0dd641]1361  {
1362    //if (f!=NULL) // already tested at start of routine
[3ef9c8]1363    number n0=n_Copy(pGetCoeff(f),r->cf);
[c92097b]1364    if (with_exps==0 || with_exps==3)
[3ef9c8]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);
[c92097b]1371    if (with_exps==0 || with_exps==3)
[0dd641]1372    {
[3ef9c8]1373      n_Delete(&N,r->cf);
1374      N=n_Copy(NN,r->cf);
[0dd641]1375    }
1376  }
[ce3f53c]1377  else if (rField_is_Zp_a(r))
[0dd641]1378  {
1379    //if (f!=NULL) // already tested at start of routine
1380    if (singclap_factorize_retry==0)
1381    {
[3ef9c8]1382      number n0=n_Copy(pGetCoeff(f),r->cf);
[c92097b]1383      if (with_exps==0 || with_exps==3)
[3ef9c8]1384        N=n_Copy(n0,r->cf);
[ce3f53c]1385      p_Norm(f,r);
1386      p_Cleardenom(f, r);
[3ef9c8]1387      NN=n_Div(n0,pGetCoeff(f),r->cf);
1388      n_Delete(&n0,r->cf);
[c92097b]1389      if (with_exps==0 || with_exps==3)
[3ef9c8]1390      {
1391        n_Delete(&N,r->cf);
1392        N=n_Copy(NN,r->cf);
1393      }
[0dd641]1394    }
1395  }
[417a91a]1396  if (rField_is_Q(r) || rField_is_Zp(r)
1397  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[0dd641]1398  {
[ce3f53c]1399    setCharacteristic( rChar(r) );
1400    CanonicalForm F( convSingPFactoryP( f,r ) );
[85194f2]1401    L = sqrFree( F );
[0dd641]1402  }
[e72a9a]1403  else if (r->cf->extRing!=NULL)
[3ef9c8]1404  {
1405    if (rField_is_Q_a (r)) setCharacteristic (0);
1406    else                   setCharacteristic( rChar(r) );
[dd668f]1407    if (r->cf->extRing->qideal!=NULL)
[3ef9c8]1408    {
[dd668f]1409      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
[3ef9c8]1410                                           r->cf->extRing);
[8b00ca]1411      a=rootOf(mipo);
[3ef9c8]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  }
[0dd641]1421  #if 0
1422  else if (rField_is_GF())
1423  {
[ce3f53c]1424    int c=rChar(r);
[0dd641]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;
[3ef9c8]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    }
[c92097b]1456    else if (L.getFirst().factor().inCoeffDomain() && with_exps!=3)
[3ef9c8]1457    {
1458      n--;
1459      J++;
1460    }
[0dd641]1461    res = idInit( n ,1);
1462    for ( ; J.hasItem(); J++, j++ )
1463    {
[c92097b]1464      if (with_exps!=1 && with_exps!=3) (**v)[j] = J.getItem().exp();
[417a91a]1465      if (rField_is_Zp(r) || rField_is_Q(r)
1466      || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[3ef9c8]1467        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
[e72a9a]1468      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
[3ef9c8]1469      {
[dd668f]1470        if (r->cf->extRing->qideal==NULL)
[3ef9c8]1471          res->m[j]=convFactoryPSingTrP( J.getItem().factor(),r );
1472        else
1473          res->m[j]=convFactoryAPSingAP( J.getItem().factor(),r );
1474      }
[0dd641]1475    }
1476    if (res->m[0]==NULL)
1477    {
[ce3f53c]1478      res->m[0]=p_One(r);
[0dd641]1479    }
[f78374]1480    if (N!=NULL)
1481    {
[3d1222a]1482      __p_Mult_nn(res->m[0],N,r);
[f78374]1483      n_Delete(&N,r->cf);
1484      N=NULL;
1485    }
[0dd641]1486  }
[8b00ca]1487  if (r->cf->extRing!=NULL)
1488    if (r->cf->extRing->qideal!=NULL)
1489      prune (a);
[dd668f]1490  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
[f78374]1491  {
1492    int i=IDELEMS(res)-1;
1493    int stop=1;
[c92097b]1494    if (with_exps!=0 || with_exps==3) stop=0;
[f78374]1495    for(;i>=stop;i--)
1496    {
1497      p_Norm(res->m[i],r);
1498    }
[c92097b]1499    if (with_exps==0 || with_exps==3) p_SetCoeff(res->m[0],old_lead_coeff,r);
[f78374]1500    else n_Delete(&old_lead_coeff,r->cf);
1501  }
1502  else
1503    n_Delete(&old_lead_coeff,r->cf);
[ce3f53c]1504  p_Delete(&f,r);
[0dd641]1505  errorreported=save_errorreported;
1506notImpl:
1507  if (res==NULL)
1508    WerrorS( feNotImplemented );
[f78374]1509  if (NN!=NULL)
1510  {
1511    n_Delete(&NN,r->cf);
1512  }
1513  if (N!=NULL)
1514  {
1515    n_Delete(&N,r->cf);
1516  }
[0dd641]1517  return res;
1518}
[ce3f53c]1519
[67c1dc]1520matrix singclap_irrCharSeries ( ideal I, const ring r)
[35aab3]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;
[417a91a]1532  if (rField_is_Q(r) || rField_is_Zp(r)
1533  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[35aab3]1534  {
[ce3f53c]1535    setCharacteristic( rChar(r) );
[35aab3]1536    for(i=0;i<IDELEMS(I);i++)
1537    {
1538      poly p=I->m[i];
1539      if (p!=NULL)
1540      {
[ce3f53c]1541        p=p_Copy(p,r);
1542        p_Cleardenom(p, r);
1543        L.append(convSingPFactoryP(p,r));
[2956e79]1544        p_Delete(&p,r);
[35aab3]1545      }
1546    }
1547  }
1548  // and over Q(a) / Fp(a)
[44f78d3]1549  else if (nCoeff_is_transExt (r->cf))
[35aab3]1550  {
[44f78d3]1551    setCharacteristic( rChar(r) );
[35aab3]1552    for(i=0;i<IDELEMS(I);i++)
1553    {
1554      poly p=I->m[i];
1555      if (p!=NULL)
1556      {
[ce3f53c]1557        p=p_Copy(p,r);
1558        p_Cleardenom(p, r);
1559        L.append(convSingTrPFactoryP(p,r));
[2956e79]1560        p_Delete(&p,r);
[35aab3]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  {
[d083a8]1577    LL=irrCharSeries(L);
[35aab3]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());
[fc2746]1592    iiWriteMatrix((matrix)I,"I",2,r,0);
[35aab3]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    {
[417a91a]1602      if (rField_is_Q(r) || rField_is_Zp(r)
1603      || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[ce3f53c]1604        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem(),r);
[35aab3]1605      else
[ce3f53c]1606        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem(),r);
[35aab3]1607    }
1608  }
1609  Off(SW_RATIONAL);
1610  return res;
[67c1dc]1611}
[35aab3]1612
[3aa9b6]1613char* singclap_neworder ( ideal I, const ring r)
[35aab3]1614{
1615  int i;
1616  Off(SW_RATIONAL);
1617  On(SW_SYMMETRIC_FF);
1618  CFList L;
[417a91a]1619  if (rField_is_Q(r) || rField_is_Zp(r)
1620  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
[35aab3]1621  {
[ce3f53c]1622    setCharacteristic( rChar(r) );
[35aab3]1623    for(i=0;i<IDELEMS(I);i++)
1624    {
[44f78d3]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      }
[35aab3]1632    }
1633  }
1634  // and over Q(a) / Fp(a)
[44f78d3]1635  else if (nCoeff_is_transExt (r->cf))
[35aab3]1636  {
[44f78d3]1637    setCharacteristic( rChar(r) );
[35aab3]1638    for(i=0;i<IDELEMS(I);i++)
1639    {
[44f78d3]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      }
[35aab3]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;
[ce3f53c]1659  int offs=rPar(r);
1660  int* mark=(int*)omAlloc0((rVar(r)+offs)*sizeof(int));
1661  int cnt=rVar(r)+offs;
[35aab3]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;
[ce3f53c]1671      //StringAppendS(r->parameter[i]);
[35aab3]1672    }
1673    else
1674    {
[ce3f53c]1675      StringAppendS(r->names[i-offs]);
[35aab3]1676    }
1677    Li++;
1678    cnt--;
1679    if(cnt==0) break;
1680    if (done) StringAppendS(",");
1681  }
[ce3f53c]1682  for(i=0;i<rVar(r)+offs;i++)
[35aab3]1683  {
1684    BOOLEAN done=TRUE;
1685    if(mark[i]==0)
1686    {
1687      if (i<offs)
1688      {
1689        done=FALSE;
[ce3f53c]1690        //StringAppendS(r->parameter[i]);
[35aab3]1691      }
1692      else
1693      {
[ce3f53c]1694        StringAppendS(r->names[i-offs]);
[35aab3]1695      }
1696      cnt--;
1697      if(cnt==0) break;
1698      if (done) StringAppendS(",");
1699    }
1700  }
[538512]1701  char * s=StringEndS();
[35aab3]1702  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1703  return s;
[67c1dc]1704}
[35aab3]1705
[ce3f53c]1706poly singclap_det( const matrix m, const ring s )
[35aab3]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;
[abb4787]1715  CFMatrix M(r,r);
1716  int i,j;
1717  for(i=r;i>0;i--)
[35aab3]1718  {
[abb4787]1719    for(j=r;j>0;j--)
[35aab3]1720    {
[abb4787]1721      M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
[35aab3]1722    }
1723  }
[abb4787]1724  res= convFactoryPSingP( determinant(M,r),s ) ;
[35aab3]1725  Off(SW_RATIONAL);
1726  return res;
1727}
1728
[2e4ec14]1729int singclap_det_i( intvec * m, const ring /*r*/)
[35aab3]1730{
[9d5ba2]1731//  assume( r == currRing ); // Anything else is not guaranted to work!
[54fc4e]1732
[9d5ba2]1733  setCharacteristic( 0 ); // ?
[35aab3]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  }
[ce3f53c]1743  int res= convFactoryISingI( determinant(M,m->rows()) ) ;
[24a9587]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    {
[ca90c60]1757      M(i,j)=n_convSingNFactoryN(BIMATELEM(*m,i,j),setchar,cf);
[24a9587]1758      setchar=FALSE;
1759    }
1760  }
[ca90c60]1761  number res=n_convFactoryNSingN( determinant(M,m->rows()),cf ) ;
[35aab3]1762  return res;
1763}
[c74d6a]1764
[647b762]1765#ifdef HAVE_NTL   /*define derived from factory*/
[ce3f53c]1766matrix singntl_HNF(matrix  m, const ring s )
[9d9078]1767{
[af8863]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  }
[54fc4e]1774
[42e2db]1775  matrix res=mpNew(r,r);
[54fc4e]1776
[ce3f53c]1777  if (rField_is_Q(s))
[af8863]1778  {
[9d9078]1779
[af8863]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      {
[ce3f53c]1786        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
[af8863]1787      }
1788    }
1789    CFMatrix *MM=cf_HNF(M);
1790    for(i=r;i>0;i--)
1791    {
1792      for(j=r;j>0;j--)
[9d9078]1793      {
[ce3f53c]1794        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
[af8863]1795      }
1796    }
1797    delete MM;
1798  }
1799  return res;
1800}
[895b31c]1801
[d085e06]1802intvec* singntl_HNF(intvec*  m)
[af8863]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}
[895b31c]1832
[503bfc1]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
[ce3f53c]1864matrix singntl_LLL(matrix  m, const ring s )
[9d9078]1865{
[9c0b20a]1866  int r=m->rows();
1867  int c=m->cols();
[42e2db]1868  matrix res=mpNew(r,c);
[ce3f53c]1869  if (rField_is_Q(s))
[9c0b20a]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      {
[ce3f53c]1877        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
[9c0b20a]1878      }
1879    }
1880    CFMatrix *MM=cf_LLL(M);
1881    for(i=r;i>0;i--)
1882    {
1883      for(j=c;j>0;j--)
[9d9078]1884      {
[ce3f53c]1885        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
[9c0b20a]1886      }
1887    }
1888    delete MM;
1889  }
1890  return res;
1891}
[895b31c]1892
[d085e06]1893intvec* singntl_LLL(intvec*  m)
[9c0b20a]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  {
[a002227]1902    for(j=c;j>0;j--)
[9c0b20a]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}
[3426545]1919
[d2fc749]1920ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
[3426545]1921{
1922  p_Test(f, r);
1923
1924  ideal res=NULL;
1925
1926  int offs = rPar(r);
1927  if (f==NULL)
1928  {
1929    res= idInit (1, 1);
1930    mipos= idInit (1, 1);
1931    mipos->m[0]= convFactoryPSingTrP (Variable (offs), r); //overkill
1932    (*exps)=new intvec (1);
1933    (**exps)[0]= 1;
1934    numFactors= 0;
1935    return res;
1936  }
1937  CanonicalForm F( convSingTrPFactoryP( f, r) );
1938
[09dbf3]1939  bool isRat= isOn (SW_RATIONAL);
1940  if (!isRat)
1941    On (SW_RATIONAL);
1942
[3426545]1943  CFAFList absFactors= absFactorize (F);
1944
1945  int n= absFactors.length();
1946  *exps=new intvec (n);
1947
1948  res= idInit (n, 1);
1949
1950  mipos= idInit (n, 1);
1951
1952  Variable x= Variable (offs);
1953  Variable alpha;
1954  int i= 0;
1955  numFactors= 0;
1956  int count;
1957  CFAFListIterator iter= absFactors;
1958  CanonicalForm lead= iter.getItem().factor();
1959  if (iter.getItem().factor().inCoeffDomain())
1960  {
1961    i++;
1962    iter++;
1963  }
1964  for (; iter.hasItem(); iter++, i++)
1965  {
1966    (**exps)[i]= iter.getItem().exp();
1967    alpha= iter.getItem().minpoly().mvar();
1968    if (iter.getItem().minpoly().isOne())
1969      lead /= power (bCommonDen (iter.getItem().factor()), iter.getItem().exp());
1970    else
1971      lead /= power (power (bCommonDen (iter.getItem().factor()), degree (iter.getItem().minpoly())), iter.getItem().exp());
1972    res->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().factor()*bCommonDen (iter.getItem().factor()), alpha, x), r);
1973    if (iter.getItem().minpoly().isOne())
1974    {
1975      count= iter.getItem().exp();
1976      mipos->m[i]= convFactoryPSingTrP (x,r);
1977    }
1978    else
1979    {
1980      count= iter.getItem().exp()*degree (iter.getItem().minpoly());
1981      mipos->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().minpoly(), alpha, x), r);
1982    }
[8b00ca]1983    if (!iter.getItem().minpoly().isOne())
1984      prune (alpha);
[3426545]1985    numFactors += count;
1986  }
1987  if (!isRat)
1988    Off (SW_RATIONAL);
1989
1990  (**exps)[0]= 1;
1991  res->m[0]= convFactoryPSingTrP (lead, r);
1992  mipos->m[0]= convFactoryPSingTrP (x, r);
1993  return res;
1994}
1995
[102a906]1996#else
1997matrix singntl_HNF(matrix  m, const ring s )
1998{
1999  WerrorS("NTL missing");
2000  return NULL;
2001}
2002
2003intvec* singntl_HNF(intvec*  m)
2004{
2005  WerrorS("NTL missing");
2006  return NULL;
2007}
2008
2009matrix singntl_LLL(matrix  m, const ring s )
2010{
2011  WerrorS("NTL missing");
2012  return NULL;
2013}
2014
2015intvec* singntl_LLL(intvec*  m)
2016{
2017  WerrorS("NTL missing");
2018  return NULL;
2019}
2020
2021ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
2022{
2023  WerrorS("NTL missing");
2024  return NULL;
2025}
2026
[3426545]2027#endif /* HAVE_NTL */
[c74d6a]2028
Note: See TracBrowser for help on using the repository browser.