source: git/libpolys/polys/clapsing.cc @ 417a91a

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