source: git/libpolys/polys/clapsing.cc @ 85e90d

spielwiese
Last change on this file since 85e90d was 85e90d, checked in by Hans Schoenemann <hannes@…>, 5 years ago
chg: make gcd monic for Zp_a (also in factory:gcd_poly)
  • Property mode set to 100644
File size: 47.3 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>500))
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,pLength(f),g,pLength(g),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,pLength(f),g,pLength(g),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 (!rField_is_Zp(r) && !rField_is_Zp_a(r) && !rField_is_Z(r)
997  && !(rField_is_Zn(r) && (r->cf->convSingNFactoryN!=ndConvSingNFactoryN))) /* Q, Q(a) */
998  {
999    //if (f!=NULL) // already tested at start of routine
1000    {
1001      number n0=n_Copy(pGetCoeff(f),r->cf);
1002      if (with_exps==0)
1003        N=n_Copy(n0,r->cf);
1004      p_Cleardenom(f, r);
1005      //after here f should not have a denominator!!
1006      //PrintS("S:");p_Write(f,r);PrintLn();
1007      NN=n_Div(n0,pGetCoeff(f),r->cf);
1008      n_Delete(&n0,r->cf);
1009      if (with_exps==0)
1010      {
1011        n_Delete(&N,r->cf);
1012        N=n_Copy(NN,r->cf);
1013      }
1014    }
1015  }
1016  else if (rField_is_Zp_a(r))
1017  {
1018    //if (f!=NULL) // already tested at start of routine
1019    if (singclap_factorize_retry==0)
1020    {
1021      number n0=n_Copy(pGetCoeff(f),r->cf);
1022      if (with_exps==0)
1023        N=n_Copy(n0,r->cf);
1024      p_Norm(f,r);
1025      p_Cleardenom(f, r);
1026      NN=n_Div(n0,pGetCoeff(f),r->cf);
1027      n_Delete(&n0,r->cf);
1028      if (with_exps==0)
1029      {
1030        n_Delete(&N,r->cf);
1031        N=n_Copy(NN,r->cf);
1032      }
1033    }
1034  }
1035  if ((rField_is_Q(r) || rField_is_Zp(r) || (rField_is_Z(r)))
1036  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
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  &&(r->cf->extRing->cf->convSingNFactoryN!=ndConvSingNFactoryN))
1045  {
1046    if (rField_is_Q_a (r)) setCharacteristic (0);
1047    else                   setCharacteristic( rChar(r) );
1048    if (r->cf->extRing->qideal!=NULL)
1049    {
1050      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
1051                                           r->cf->extRing);
1052      a=rootOf(mipo);
1053      CanonicalForm F( convSingAPFactoryAP( f, a, r ) );
1054      if (rField_is_Zp_a(r))
1055      {
1056        L = factorize( F, a );
1057      }
1058      else
1059      {
1060        //  over Q(a)
1061        L= factorize (F, a);
1062      }
1063      prune(a);
1064    }
1065    else
1066    {
1067      CanonicalForm F( convSingTrPFactoryP( f,r ) );
1068      L = factorize( F );
1069    }
1070  }
1071  else
1072  {
1073    goto notImpl;
1074  }
1075  {
1076    poly ff=p_Copy(f,r); // a copy for the retry stuff
1077    // the first factor should be a constant
1078    if ( ! L.getFirst().factor().inCoeffDomain() )
1079      L.insert(CFFactor(1,1));
1080    // convert into ideal
1081    int n = L.length();
1082    if (n==0) n=1;
1083    CFFListIterator J=L;
1084    int j=0;
1085    if (with_exps!=1)
1086    {
1087      if ((with_exps==2)&&(n>1))
1088      {
1089        n--;
1090        J++;
1091      }
1092      *v = new intvec( n );
1093    }
1094    res = idInit( n ,1);
1095    for ( ; J.hasItem(); J++, j++ )
1096    {
1097      if (with_exps!=1) (**v)[j] = J.getItem().exp();
1098      if (rField_is_Zp(r) || rField_is_Q(r)||  rField_is_Z(r)
1099      || (rField_is_Zn(r) && r->cf->convSingNFactoryN!=ndConvSingNFactoryN))           /* Q, Fp, Z */
1100      {
1101        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
1102        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
1103      }
1104#if 0
1105      else if (rField_is_GF())
1106        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
1107#endif
1108      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
1109      {
1110#ifndef SING_NDEBUG
1111        intvec *w=NULL;
1112        if (v!=NULL) w=*v;
1113#endif
1114        if (r->cf->extRing->qideal==NULL)
1115        {
1116#ifdef SING_NDEBUG
1117          res->m[j]= convFactoryPSingTrP( J.getItem().factor(),r );
1118#else
1119          if(!count_Factors(res,w,j,ff,convFactoryPSingTrP( J.getItem().factor(),r ),r))
1120          {
1121            if (w!=NULL)
1122              (*w)[j]=1;
1123            res->m[j]=p_One(r);
1124          }
1125#endif
1126        }
1127        else
1128        {
1129#ifdef SING_NDEBUG
1130          res->m[j]= convFactoryAPSingAP( J.getItem().factor(),r );
1131#else
1132          if (!count_Factors(res,w,j,ff,convFactoryAPSingAP( J.getItem().factor(),r ),r))
1133          {
1134            if (w!=NULL)
1135              (*w)[j]=1;
1136            res->m[j]=p_One(r);
1137          }
1138#endif
1139        }
1140      }
1141    }
1142    if (r->cf->extRing!=NULL)
1143      if (r->cf->extRing->qideal!=NULL)
1144        prune (a);
1145#ifndef SING_NDEBUG
1146    if ((r->cf->extRing!=NULL) && (!p_IsConstantPoly(ff,r)))
1147    {
1148      singclap_factorize_retry++;
1149      if (singclap_factorize_retry<3)
1150      {
1151        int jj;
1152#ifdef FACTORIZE2_DEBUG
1153        printf("factorize_retry\n");
1154#endif
1155        intvec *ww=NULL;
1156        id_Test(res,r);
1157        ideal h=singclap_factorize ( ff, &ww , with_exps, r );
1158        id_Test(h,r);
1159        int l=(*v)->length();
1160        (*v)->resize(l+ww->length());
1161        for(jj=0;jj<ww->length();jj++)
1162          (**v)[jj+l]=(*ww)[jj];
1163        delete ww;
1164        ideal hh=idInit(IDELEMS(res)+IDELEMS(h),1);
1165        for(jj=IDELEMS(res)-1;jj>=0;jj--)
1166        {
1167          hh->m[jj]=res->m[jj];
1168          res->m[jj]=NULL;
1169        }
1170        for(jj=IDELEMS(h)-1;jj>=0;jj--)
1171        {
1172          hh->m[jj+IDELEMS(res)]=h->m[jj];
1173          h->m[jj]=NULL;
1174        }
1175        id_Delete(&res,r);
1176        id_Delete(&h,r);
1177        res=hh;
1178        id_Test(res,r);
1179        ff=NULL;
1180      }
1181      else
1182      {
1183        WarnS("problem with factorize");
1184#if 0
1185        pWrite(ff);
1186        idShow(res);
1187#endif
1188        id_Delete(&res,r);
1189        res=idInit(2,1);
1190        res->m[0]=p_One(r);
1191        res->m[1]=ff; ff=NULL;
1192      }
1193    }
1194#endif
1195    p_Delete(&ff,r);
1196    if (N!=NULL)
1197    {
1198      __p_Mult_nn(res->m[0],N,r);
1199      n_Delete(&N,r->cf);
1200      N=NULL;
1201    }
1202    // delete constants
1203    if (res!=NULL)
1204    {
1205      int i=IDELEMS(res)-1;
1206      int j=0;
1207      for(;i>=0;i--)
1208      {
1209        if ((res->m[i]!=NULL)
1210        && (pNext(res->m[i])==NULL)
1211        && (p_IsConstant(res->m[i],r)))
1212        {
1213          if (with_exps!=0)
1214          {
1215            p_Delete(&(res->m[i]),r);
1216            if ((v!=NULL) && ((*v)!=NULL))
1217              (**v)[i]=0;
1218            j++;
1219          }
1220          else if (i!=0)
1221          {
1222            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
1223            {
1224              res->m[0]=p_Mult_q(res->m[0],p_Copy(res->m[i],r),r);
1225              (**v)[i]--;
1226            }
1227            res->m[0]=p_Mult_q(res->m[0],res->m[i],r);
1228            res->m[i]=NULL;
1229            if ((v!=NULL) && ((*v)!=NULL))
1230              (**v)[i]=1;
1231            j++;
1232          }
1233        }
1234      }
1235      if (j>0)
1236      {
1237        idSkipZeroes(res);
1238        if ((v!=NULL) && ((*v)!=NULL))
1239        {
1240          intvec *w=*v;
1241          int len=IDELEMS(res);
1242          *v = new intvec( len );
1243          for (i=0,j=0;i<si_min(w->length(),len);i++)
1244          {
1245            if((*w)[i]!=0)
1246            {
1247              (**v)[j]=(*w)[i]; j++;
1248            }
1249          }
1250          delete w;
1251        }
1252      }
1253      if (res->m[0]==NULL)
1254      {
1255        res->m[0]=p_One(r);
1256      }
1257    }
1258  }
1259  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
1260  {
1261    int i=IDELEMS(res)-1;
1262    int stop=1;
1263    if (with_exps!=0) stop=0;
1264    for(;i>=stop;i--)
1265    {
1266      p_Norm(res->m[i],r);
1267    }
1268    if (with_exps==0) p_SetCoeff(res->m[0],old_lead_coeff,r);
1269    else n_Delete(&old_lead_coeff,r->cf);
1270  }
1271  else
1272    n_Delete(&old_lead_coeff,r->cf);
1273  errorreported=save_errorreported;
1274notImpl:
1275  prune(a);
1276  if (res==NULL)
1277    WerrorS( feNotImplemented );
1278  if (NN!=NULL)
1279  {
1280    n_Delete(&NN,r->cf);
1281  }
1282  if (N!=NULL)
1283  {
1284    n_Delete(&N,r->cf);
1285  }
1286  if (f!=NULL) p_Delete(&f,r);
1287  //PrintS("......S\n");
1288  return res;
1289}
1290
1291ideal singclap_sqrfree ( poly f, intvec ** v , int with_exps, const ring r)
1292{
1293  p_Test(f,r);
1294#ifdef FACTORIZE2_DEBUG
1295  printf("singclap_sqrfree, degree %d\n",pTotaldegree(f));
1296#endif
1297  // with_exps: 3,1 return only true factors, no exponents
1298  //            2 return true factors and exponents
1299  //            0 return coeff, factors and exponents
1300  BOOLEAN save_errorreported=errorreported;
1301
1302  ideal res=NULL;
1303
1304  // handle factorize(0) =========================================
1305  if (f==NULL)
1306  {
1307    res=idInit(1,1);
1308    if (with_exps!=1 && with_exps!=3)
1309    {
1310      (*v)=new intvec(1);
1311      (**v)[0]=1;
1312    }
1313    return res;
1314  }
1315  // handle factorize(mon) =========================================
1316  if (pNext(f)==NULL)
1317  {
1318    int i=0;
1319    int n=0;
1320    int e;
1321    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
1322    if (with_exps==0 || with_exps==3) n++; // with coeff
1323    res=idInit(si_max(n,1),1);
1324    if(with_exps!=1)
1325    {
1326        (*v)=new intvec(si_max(1,n));
1327        (**v)[0]=1;
1328    }
1329    res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
1330    if (n==0)
1331    {
1332      res->m[0]=p_One(r);
1333      // (**v)[0]=1; is already done
1334    }
1335    else
1336    {
1337      for(i=rVar(r);i>0;i--)
1338      {
1339        e=p_GetExp(f,i,r);
1340        if(e!=0)
1341        {
1342          n--;
1343          poly p=p_One(r);
1344          p_SetExp(p,i,1,r);
1345          p_Setm(p,r);
1346          res->m[n]=p;
1347          if (with_exps!=1) (**v)[n]=e;
1348        }
1349      }
1350    }
1351    p_Delete(&f,r);
1352    return res;
1353  }
1354  //PrintS("S:");pWrite(f);PrintLn();
1355  // use factory/libfac in general ==============================
1356  Off(SW_RATIONAL);
1357  On(SW_SYMMETRIC_FF);
1358  CFFList L;
1359  number N=NULL;
1360  number NN=NULL;
1361  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
1362  Variable a;
1363
1364  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
1365  {
1366    //if (f!=NULL) // already tested at start of routine
1367    number n0=n_Copy(pGetCoeff(f),r->cf);
1368    if (with_exps==0 || with_exps==3)
1369      N=n_Copy(n0,r->cf);
1370    p_Cleardenom(f, r);
1371    //after here f should not have a denominator!!
1372    //PrintS("S:");p_Write(f,r);PrintLn();
1373    NN=n_Div(n0,pGetCoeff(f),r->cf);
1374    n_Delete(&n0,r->cf);
1375    if (with_exps==0 || with_exps==3)
1376    {
1377      n_Delete(&N,r->cf);
1378      N=n_Copy(NN,r->cf);
1379    }
1380  }
1381  else if (rField_is_Zp_a(r))
1382  {
1383    //if (f!=NULL) // already tested at start of routine
1384    if (singclap_factorize_retry==0)
1385    {
1386      number n0=n_Copy(pGetCoeff(f),r->cf);
1387      if (with_exps==0 || with_exps==3)
1388        N=n_Copy(n0,r->cf);
1389      p_Norm(f,r);
1390      p_Cleardenom(f, r);
1391      NN=n_Div(n0,pGetCoeff(f),r->cf);
1392      n_Delete(&n0,r->cf);
1393      if (with_exps==0 || with_exps==3)
1394      {
1395        n_Delete(&N,r->cf);
1396        N=n_Copy(NN,r->cf);
1397      }
1398    }
1399  }
1400  if (rField_is_Q(r) || rField_is_Zp(r)
1401  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1402  {
1403    setCharacteristic( rChar(r) );
1404    CanonicalForm F( convSingPFactoryP( f,r ) );
1405    L = sqrFree( F );
1406  }
1407  else if (r->cf->extRing!=NULL)
1408  {
1409    if (rField_is_Q_a (r)) setCharacteristic (0);
1410    else                   setCharacteristic( rChar(r) );
1411    if (r->cf->extRing->qideal!=NULL)
1412    {
1413      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
1414                                           r->cf->extRing);
1415      a=rootOf(mipo);
1416      CanonicalForm F( convSingAPFactoryAP( f, a, r ) );
1417      L= sqrFree (F);
1418    }
1419    else
1420    {
1421      CanonicalForm F( convSingTrPFactoryP( f,r ) );
1422      L = sqrFree( F );
1423    }
1424  }
1425  #if 0
1426  else if (rField_is_GF())
1427  {
1428    int c=rChar(r);
1429    setCharacteristic( c, primepower(c) );
1430    CanonicalForm F( convSingGFFactoryGF( f ) );
1431    if (F.isUnivariate())
1432    {
1433      L = factorize( F );
1434    }
1435    else
1436    {
1437      goto notImpl;
1438    }
1439  }
1440  #endif
1441  else
1442  {
1443    goto notImpl;
1444  }
1445  {
1446    // convert into ideal
1447    int n = L.length();
1448    if (n==0) n=1;
1449    CFFListIterator J=L;
1450    int j=0;
1451    if (with_exps!=1)
1452    {
1453      if ((with_exps==2)&&(n>1))
1454      {
1455        n--;
1456        J++;
1457      }
1458      *v = new intvec( n );
1459    }
1460    else if (L.getFirst().factor().inCoeffDomain() && with_exps!=3)
1461    {
1462      n--;
1463      J++;
1464    }
1465    res = idInit( n ,1);
1466    for ( ; J.hasItem(); J++, j++ )
1467    {
1468      if (with_exps!=1 && with_exps!=3) (**v)[j] = J.getItem().exp();
1469      if (rField_is_Zp(r) || rField_is_Q(r)
1470      || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1471        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
1472      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
1473      {
1474        if (r->cf->extRing->qideal==NULL)
1475          res->m[j]=convFactoryPSingTrP( J.getItem().factor(),r );
1476        else
1477          res->m[j]=convFactoryAPSingAP( J.getItem().factor(),r );
1478      }
1479    }
1480    if (res->m[0]==NULL)
1481    {
1482      res->m[0]=p_One(r);
1483    }
1484    if (N!=NULL)
1485    {
1486      __p_Mult_nn(res->m[0],N,r);
1487      n_Delete(&N,r->cf);
1488      N=NULL;
1489    }
1490  }
1491  if (r->cf->extRing!=NULL)
1492    if (r->cf->extRing->qideal!=NULL)
1493      prune (a);
1494  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
1495  {
1496    int i=IDELEMS(res)-1;
1497    int stop=1;
1498    if (with_exps!=0 || with_exps==3) stop=0;
1499    for(;i>=stop;i--)
1500    {
1501      p_Norm(res->m[i],r);
1502    }
1503    if (with_exps==0 || with_exps==3) p_SetCoeff(res->m[0],old_lead_coeff,r);
1504    else n_Delete(&old_lead_coeff,r->cf);
1505  }
1506  else
1507    n_Delete(&old_lead_coeff,r->cf);
1508  p_Delete(&f,r);
1509  errorreported=save_errorreported;
1510notImpl:
1511  if (res==NULL)
1512    WerrorS( feNotImplemented );
1513  if (NN!=NULL)
1514  {
1515    n_Delete(&NN,r->cf);
1516  }
1517  if (N!=NULL)
1518  {
1519    n_Delete(&N,r->cf);
1520  }
1521  return res;
1522}
1523
1524matrix singclap_irrCharSeries ( ideal I, const ring r)
1525{
1526  if (idIs0(I)) return mpNew(1,1);
1527
1528  // for now there is only the possibility to handle polynomials over
1529  // Q and Fp ...
1530  matrix res=NULL;
1531  int i;
1532  Off(SW_RATIONAL);
1533  On(SW_SYMMETRIC_FF);
1534  CFList L;
1535  ListCFList LL;
1536  if (rField_is_Q(r) || rField_is_Zp(r)
1537  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1538  {
1539    setCharacteristic( rChar(r) );
1540    for(i=0;i<IDELEMS(I);i++)
1541    {
1542      poly p=I->m[i];
1543      if (p!=NULL)
1544      {
1545        p=p_Copy(p,r);
1546        p_Cleardenom(p, r);
1547        L.append(convSingPFactoryP(p,r));
1548        p_Delete(&p,r);
1549      }
1550    }
1551  }
1552  // and over Q(a) / Fp(a)
1553  else if (nCoeff_is_transExt (r->cf))
1554  {
1555    setCharacteristic( rChar(r) );
1556    for(i=0;i<IDELEMS(I);i++)
1557    {
1558      poly p=I->m[i];
1559      if (p!=NULL)
1560      {
1561        p=p_Copy(p,r);
1562        p_Cleardenom(p, r);
1563        L.append(convSingTrPFactoryP(p,r));
1564        p_Delete(&p,r);
1565      }
1566    }
1567  }
1568  else
1569  {
1570    WerrorS( feNotImplemented );
1571    return res;
1572  }
1573
1574  // a very bad work-around --- FIX IT in libfac
1575  // should be fixed as of 2001/6/27
1576  int tries=0;
1577  int m,n;
1578  ListIterator<CFList> LLi;
1579  loop
1580  {
1581    LL=irrCharSeries(L);
1582    m= LL.length(); // Anzahl Zeilen
1583    n=0;
1584    for ( LLi = LL; LLi.hasItem(); LLi++ )
1585    {
1586      n = si_max(LLi.getItem().length(),n);
1587    }
1588    if ((m!=0) && (n!=0)) break;
1589    tries++;
1590    if (tries>=5) break;
1591  }
1592  if ((m==0) || (n==0))
1593  {
1594    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
1595      m,n,IDELEMS(I)+1,LL.length());
1596    iiWriteMatrix((matrix)I,"I",2,r,0);
1597    m=si_max(m,1);
1598    n=si_max(n,1);
1599  }
1600  res=mpNew(m,n);
1601  CFListIterator Li;
1602  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
1603  {
1604    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
1605    {
1606      if (rField_is_Q(r) || rField_is_Zp(r)
1607      || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1608        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem(),r);
1609      else
1610        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem(),r);
1611    }
1612  }
1613  Off(SW_RATIONAL);
1614  return res;
1615}
1616
1617char* singclap_neworder ( ideal I, const ring r)
1618{
1619  int i;
1620  Off(SW_RATIONAL);
1621  On(SW_SYMMETRIC_FF);
1622  CFList L;
1623  if (rField_is_Q(r) || rField_is_Zp(r)
1624  || (rField_is_Zn(r)&&(r->cf->convSingNFactoryN!=ndConvSingNFactoryN)))
1625  {
1626    setCharacteristic( rChar(r) );
1627    for(i=0;i<IDELEMS(I);i++)
1628    {
1629      poly p=I->m[i];
1630      if (p!=NULL)
1631      {
1632        p=p_Copy(p,r);
1633        p_Cleardenom(p, r);
1634        L.append(convSingPFactoryP(p,r));
1635      }
1636    }
1637  }
1638  // and over Q(a) / Fp(a)
1639  else if (nCoeff_is_transExt (r->cf))
1640  {
1641    setCharacteristic( rChar(r) );
1642    for(i=0;i<IDELEMS(I);i++)
1643    {
1644      poly p=I->m[i];
1645      if (p!=NULL)
1646      {
1647        p=p_Copy(p,r);
1648        p_Cleardenom(p, r);
1649        L.append(convSingTrPFactoryP(p,r));
1650      }
1651    }
1652  }
1653  else
1654  {
1655    WerrorS( feNotImplemented );
1656    return NULL;
1657  }
1658
1659  List<int> IL=neworderint(L);
1660  ListIterator<int> Li;
1661  StringSetS("");
1662  Li = IL;
1663  int offs=rPar(r);
1664  int* mark=(int*)omAlloc0((rVar(r)+offs)*sizeof(int));
1665  int cnt=rVar(r)+offs;
1666  loop
1667  {
1668    if(! Li.hasItem()) break;
1669    BOOLEAN done=TRUE;
1670    i=Li.getItem()-1;
1671    mark[i]=1;
1672    if (i<offs)
1673    {
1674      done=FALSE;
1675      //StringAppendS(r->parameter[i]);
1676    }
1677    else
1678    {
1679      StringAppendS(r->names[i-offs]);
1680    }
1681    Li++;
1682    cnt--;
1683    if(cnt==0) break;
1684    if (done) StringAppendS(",");
1685  }
1686  for(i=0;i<rVar(r)+offs;i++)
1687  {
1688    BOOLEAN done=TRUE;
1689    if(mark[i]==0)
1690    {
1691      if (i<offs)
1692      {
1693        done=FALSE;
1694        //StringAppendS(r->parameter[i]);
1695      }
1696      else
1697      {
1698        StringAppendS(r->names[i-offs]);
1699      }
1700      cnt--;
1701      if(cnt==0) break;
1702      if (done) StringAppendS(",");
1703    }
1704  }
1705  char * s=StringEndS();
1706  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1707  return s;
1708}
1709
1710poly singclap_det( const matrix m, const ring s )
1711{
1712  int r=m->rows();
1713  if (r!=m->cols())
1714  {
1715    Werror("det of %d x %d matrix",r,m->cols());
1716    return NULL;
1717  }
1718  poly res=NULL;
1719  CFMatrix M(r,r);
1720  int i,j;
1721  for(i=r;i>0;i--)
1722  {
1723    for(j=r;j>0;j--)
1724    {
1725      M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1726    }
1727  }
1728  res= convFactoryPSingP( determinant(M,r),s ) ;
1729  Off(SW_RATIONAL);
1730  return res;
1731}
1732
1733int singclap_det_i( intvec * m, const ring /*r*/)
1734{
1735//  assume( r == currRing ); // Anything else is not guaranted to work!
1736
1737  setCharacteristic( 0 ); // ?
1738  CFMatrix M(m->rows(),m->cols());
1739  int i,j;
1740  for(i=m->rows();i>0;i--)
1741  {
1742    for(j=m->cols();j>0;j--)
1743    {
1744      M(i,j)=IMATELEM(*m,i,j);
1745    }
1746  }
1747  int res= convFactoryISingI( determinant(M,m->rows()) ) ;
1748  return res;
1749}
1750
1751number singclap_det_bi( bigintmat * m, const coeffs cf)
1752{
1753  assume(m->basecoeffs()==cf);
1754  CFMatrix M(m->rows(),m->cols());
1755  int i,j;
1756  BOOLEAN setchar=TRUE;
1757  for(i=m->rows();i>0;i--)
1758  {
1759    for(j=m->cols();j>0;j--)
1760    {
1761      M(i,j)=n_convSingNFactoryN(BIMATELEM(*m,i,j),setchar,cf);
1762      setchar=FALSE;
1763    }
1764  }
1765  number res=n_convFactoryNSingN( determinant(M,m->rows()),cf ) ;
1766  return res;
1767}
1768
1769#ifdef HAVE_NTL
1770matrix singntl_HNF(matrix  m, const ring s )
1771{
1772  int r=m->rows();
1773  if (r!=m->cols())
1774  {
1775    Werror("HNF of %d x %d matrix",r,m->cols());
1776    return NULL;
1777  }
1778
1779  matrix res=mpNew(r,r);
1780
1781  if (rField_is_Q(s))
1782  {
1783
1784    CFMatrix M(r,r);
1785    int i,j;
1786    for(i=r;i>0;i--)
1787    {
1788      for(j=r;j>0;j--)
1789      {
1790        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
1791      }
1792    }
1793    CFMatrix *MM=cf_HNF(M);
1794    for(i=r;i>0;i--)
1795    {
1796      for(j=r;j>0;j--)
1797      {
1798        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1799      }
1800    }
1801    delete MM;
1802  }
1803  return res;
1804}
1805
1806intvec* singntl_HNF(intvec*  m)
1807{
1808  int r=m->rows();
1809  if (r!=m->cols())
1810  {
1811    Werror("HNF of %d x %d matrix",r,m->cols());
1812    return NULL;
1813  }
1814  setCharacteristic( 0 );
1815  CFMatrix M(r,r);
1816  int i,j;
1817  for(i=r;i>0;i--)
1818  {
1819    for(j=r;j>0;j--)
1820    {
1821      M(i,j)=IMATELEM(*m,i,j);
1822    }
1823  }
1824  CFMatrix *MM=cf_HNF(M);
1825  intvec *mm=ivCopy(m);
1826  for(i=r;i>0;i--)
1827  {
1828    for(j=r;j>0;j--)
1829    {
1830      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1831    }
1832  }
1833  delete MM;
1834  return mm;
1835}
1836
1837bigintmat* singntl_HNF(bigintmat*  b)
1838{
1839  int r=b->rows();
1840  if (r!=b->cols())
1841  {
1842    Werror("HNF of %d x %d matrix",r,b->cols());
1843    return NULL;
1844  }
1845  setCharacteristic( 0 );
1846  CFMatrix M(r,r);
1847  int i,j;
1848  for(i=r;i>0;i--)
1849  {
1850    for(j=r;j>0;j--)
1851    {
1852      M(i,j)=n_convSingNFactoryN(BIMATELEM(*b,i,j),FALSE,b->basecoeffs());
1853    }
1854  }
1855  CFMatrix *MM=cf_HNF(M);
1856  bigintmat *mm=bimCopy(b);
1857  for(i=r;i>0;i--)
1858  {
1859    for(j=r;j>0;j--)
1860    {
1861      BIMATELEM(*mm,i,j)=n_convFactoryNSingN((*MM)(i,j),b->basecoeffs());
1862    }
1863  }
1864  delete MM;
1865  return mm;
1866}
1867
1868matrix singntl_LLL(matrix  m, const ring s )
1869{
1870  int r=m->rows();
1871  int c=m->cols();
1872  matrix res=mpNew(r,c);
1873  if (rField_is_Q(s))
1874  {
1875    CFMatrix M(r,c);
1876    int i,j;
1877    for(i=r;i>0;i--)
1878    {
1879      for(j=c;j>0;j--)
1880      {
1881        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1882      }
1883    }
1884    CFMatrix *MM=cf_LLL(M);
1885    for(i=r;i>0;i--)
1886    {
1887      for(j=c;j>0;j--)
1888      {
1889        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1890      }
1891    }
1892    delete MM;
1893  }
1894  return res;
1895}
1896
1897intvec* singntl_LLL(intvec*  m)
1898{
1899  int r=m->rows();
1900  int c=m->cols();
1901  setCharacteristic( 0 );
1902  CFMatrix M(r,c);
1903  int i,j;
1904  for(i=r;i>0;i--)
1905  {
1906    for(j=c;j>0;j--)
1907    {
1908      M(i,j)=IMATELEM(*m,i,j);
1909    }
1910  }
1911  CFMatrix *MM=cf_LLL(M);
1912  intvec *mm=ivCopy(m);
1913  for(i=r;i>0;i--)
1914  {
1915    for(j=c;j>0;j--)
1916    {
1917      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1918    }
1919  }
1920  delete MM;
1921  return mm;
1922}
1923
1924ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
1925{
1926  p_Test(f, r);
1927
1928  ideal res=NULL;
1929
1930  int offs = rPar(r);
1931  if (f==NULL)
1932  {
1933    res= idInit (1, 1);
1934    mipos= idInit (1, 1);
1935    mipos->m[0]= convFactoryPSingTrP (Variable (offs), r); //overkill
1936    (*exps)=new intvec (1);
1937    (**exps)[0]= 1;
1938    numFactors= 0;
1939    return res;
1940  }
1941  CanonicalForm F( convSingTrPFactoryP( f, r) );
1942
1943  bool isRat= isOn (SW_RATIONAL);
1944  if (!isRat)
1945    On (SW_RATIONAL);
1946
1947  CFAFList absFactors= absFactorize (F);
1948
1949  int n= absFactors.length();
1950  *exps=new intvec (n);
1951
1952  res= idInit (n, 1);
1953
1954  mipos= idInit (n, 1);
1955
1956  Variable x= Variable (offs);
1957  Variable alpha;
1958  int i= 0;
1959  numFactors= 0;
1960  int count;
1961  CFAFListIterator iter= absFactors;
1962  CanonicalForm lead= iter.getItem().factor();
1963  if (iter.getItem().factor().inCoeffDomain())
1964  {
1965    i++;
1966    iter++;
1967  }
1968  for (; iter.hasItem(); iter++, i++)
1969  {
1970    (**exps)[i]= iter.getItem().exp();
1971    alpha= iter.getItem().minpoly().mvar();
1972    if (iter.getItem().minpoly().isOne())
1973      lead /= power (bCommonDen (iter.getItem().factor()), iter.getItem().exp());
1974    else
1975      lead /= power (power (bCommonDen (iter.getItem().factor()), degree (iter.getItem().minpoly())), iter.getItem().exp());
1976    res->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().factor()*bCommonDen (iter.getItem().factor()), alpha, x), r);
1977    if (iter.getItem().minpoly().isOne())
1978    {
1979      count= iter.getItem().exp();
1980      mipos->m[i]= convFactoryPSingTrP (x,r);
1981    }
1982    else
1983    {
1984      count= iter.getItem().exp()*degree (iter.getItem().minpoly());
1985      mipos->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().minpoly(), alpha, x), r);
1986    }
1987    if (!iter.getItem().minpoly().isOne())
1988      prune (alpha);
1989    numFactors += count;
1990  }
1991  if (!isRat)
1992    Off (SW_RATIONAL);
1993
1994  (**exps)[0]= 1;
1995  res->m[0]= convFactoryPSingTrP (lead, r);
1996  mipos->m[0]= convFactoryPSingTrP (x, r);
1997  return res;
1998}
1999
2000#else
2001matrix singntl_HNF(matrix  m, const ring s )
2002{
2003  WerrorS("NTL missing");
2004  return NULL;
2005}
2006
2007intvec* singntl_HNF(intvec*  m)
2008{
2009  WerrorS("NTL missing");
2010  return NULL;
2011}
2012
2013matrix singntl_LLL(matrix  m, const ring s )
2014{
2015  WerrorS("NTL missing");
2016  return NULL;
2017}
2018
2019intvec* singntl_LLL(intvec*  m)
2020{
2021  WerrorS("NTL missing");
2022  return NULL;
2023}
2024
2025ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
2026{
2027  WerrorS("NTL missing");
2028  return NULL;
2029}
2030
2031#endif /* HAVE_NTL */
2032
Note: See TracBrowser for help on using the repository browser.