source: git/libpolys/polys/clapsing.cc @ 171070

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