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

spielwiese
Last change on this file since abb4787 was abb4787, checked in by Hans Schoenemann <hannes@…>, 13 years ago
conversion factory <->singular for poly fix coeff tests for factory
  • Property mode set to 100644
File size: 28.6 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5// $Id$
6/*
7* ABSTRACT: interface between Singular and factory
8*/
9
10//#define FACTORIZE2_DEBUG
11#include "config.h"
12#include <misc/auxiliary.h>
13
14
15TODO(Martin, Please adapt the following code for the use in SW)
16#ifdef HAVE_FACTORY
17
18#define SI_DONT_HAVE_GLOBAL_VARS
19#include <omalloc/omalloc.h>
20#include <coeffs/numbers.h>
21#include <coeffs/coeffs.h>
22
23// #include <kernel/ffields.h>
24// #include <kernel/clapconv.h>
25// #include <libfac/factor.h>
26
27#include <factory/factory.h>
28
29#include "clapsing.h"
30#include "monomials/ring.h"
31#include "simpleideals.h"
32//#include "polys.h"
33
34void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
35
36static poly singclap_gcd_r ( poly f, poly g, const ring r )
37{
38  poly res=NULL;
39
40  assume(f!=NULL);
41  assume(g!=NULL);
42
43  if((pNext(f)==NULL) && (pNext(g)==NULL))
44  {
45    poly p=p_One(r);
46    for(int i=rVar(r);i>0;i--)
47      p_SetExp(p,i,si_min(p_GetExp(f,i,r),p_GetExp(g,i,r)),r);
48    p_Setm(p,r);
49    return p;
50  }
51
52  Off(SW_RATIONAL);
53  CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g, r ) );
54  bool b1=isOn(SW_USE_QGCD);
55  bool b2=isOn(SW_USE_fieldGCD);
56  if ( rField_is_Q_a(r) ) On(SW_USE_QGCD);
57  else                   On(SW_USE_fieldGCD);
58  res=convFactoryPSingP( gcd( F, G ) , r);
59  if (!b1) Off(SW_USE_QGCD);
60  if (!b2) Off(SW_USE_fieldGCD);
61  Off(SW_RATIONAL);
62  return res;
63}
64
65poly singclap_gcd ( poly f, poly g, const ring r)
66{
67  poly res=NULL;
68
69  if (f!=NULL) p_Cleardenom(f, r);
70  if (g!=NULL) p_Cleardenom(g, r);
71  else         return f; // g==0 => gcd=f (but do a p_Cleardenom)
72  if (f==NULL) return g; // f==0 => gcd=g (but do a p_Cleardenom)
73
74  res=singclap_gcd_r(f,g,r);
75  p_Delete(&f, r);
76  p_Delete(&g, r);
77  return res;
78}
79
80/*2 find the maximal exponent of var(i) in poly p*/
81int pGetExp_Var(poly p, int i, const ring r)
82{
83  int m=0;
84  int mm;
85  while (p!=NULL)
86  {
87    mm=p_GetExp(p,i,r);
88    if (mm>m) m=mm;
89    pIter(p);
90  }
91  return m;
92}
93
94// destroys f,g,x
95poly singclap_resultant ( poly f, poly g , poly x, const ring r)
96{
97  poly res=NULL;
98  int i=p_IsPurePower(x, r);
99  if (i==0)
100  {
101    WerrorS("3rd argument must be a ring variable");
102    goto resultant_returns_res;
103  }
104  if ((f==NULL) || (g==NULL))
105    goto resultant_returns_res;
106  { 
107    Variable X(i); // TODO: consider extensions
108    CanonicalForm F( convSingPFactoryP( f, r ) ), G( convSingPFactoryP( g, r ) );
109    res=convFactoryPSingP( resultant( F, G, X ), r );
110    Off(SW_RATIONAL);
111  }
112resultant_returns_res:
113  p_Delete(&f,r);
114  p_Delete(&g,r);
115  p_Delete(&x,r);
116  return res;
117}
118//poly singclap_resultant ( poly f, poly g , poly x)
119//{
120//  int i=pVar(x);
121//  if (i==0)
122//  {
123//    WerrorS("ringvar expected");
124//    return NULL;
125//  }
126//  ideal I=idInit(1,1);
127//
128//  // get the coeffs von f wrt. x:
129//  I->m[0]=pCopy(f);
130//  matrix ffi=mpCoeffs(I,i);
131//  ffi->rank=1;
132//  ffi->ncols=ffi->nrows;
133//  ffi->nrows=1;
134//  ideal fi=(ideal)ffi;
135//
136//  // get the coeffs von g wrt. x:
137//  I->m[0]=pCopy(g);
138//  matrix ggi=mpCoeffs(I,i);
139//  ggi->rank=1;
140//  ggi->ncols=ggi->nrows;
141//  ggi->nrows=1;
142//  ideal gi=(ideal)ggi;
143//
144//  // contruct the matrix:
145//  int fn=IDELEMS(fi); //= deg(f,x)+1
146//  int gn=IDELEMS(gi); //= deg(g,x)+1
147//  matrix m=mpNew(fn+gn-2,fn+gn-2);
148//  if(m==NULL)
149//  {
150//    return NULL;
151//  }
152//
153//  // enter the coeffs into m:
154//  int j;
155//  for(i=0;i<gn-1;i++)
156//  {
157//    for(j=0;j<fn;j++)
158//    {
159//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
160//    }
161//  }
162//  for(i=0;i<fn-1;i++)
163//  {
164//    for(j=0;j<gn;j++)
165//    {
166//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
167//    }
168//  }
169//
170//  poly r=mpDet(m);
171//
172//  idDelete(&fi);
173//  idDelete(&gi);
174//  idDelete((ideal *)&m);
175//  return r;
176//}
177
178BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb , const ring r)
179{
180  // for now there is only the possibility to handle univariate
181  // polynomials over
182  // Q and Fp ...
183  res=NULL;pa=NULL;pb=NULL;
184  On(SW_SYMMETRIC_FF);
185  CanonicalForm F( convSingPFactoryP( f, r ) ), G( convSingPFactoryP( g, r ) );
186  CanonicalForm FpG=F+G;
187  if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
188  //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
189  {
190    Off(SW_RATIONAL);
191    WerrorS("not univariate");
192    return TRUE;
193  }
194  CanonicalForm Fa,Gb;
195  On(SW_RATIONAL);
196  res=convFactoryPSingP( extgcd( F, G, Fa, Gb ), r );
197  pa=convFactoryPSingP(Fa, r);
198  pb=convFactoryPSingP(Gb, r);
199  Off(SW_RATIONAL);
200#ifndef NDEBUG
201  // checking the result of extgcd:
202  poly dummy;
203  dummy=p_Sub(p_Add_q(pp_Mult_qq(f,pa,r),pp_Mult_qq(g,pb,r),r),p_Copy(res,r),r);
204  if (dummy!=NULL)
205  {
206    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
207    PrintS("gcd, co-factors:");p_Write(res,r); p_Write(pa,r);p_Write(pb,r);
208    p_Delete(&dummy,r);
209  }
210#endif
211  return FALSE;
212}
213
214poly singclap_pdivide ( poly f, poly g, const ring r )
215{
216  poly res=NULL;
217  On(SW_RATIONAL);
218  CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
219  res = convFactoryPSingP( F / G,r );
220  Off(SW_RATIONAL);
221  return res;
222}
223
224void singclap_divide_content ( poly f, const ring r )
225{
226  if ( f==NULL )
227  {
228    return;
229  }
230  else  if ( pNext( f ) == NULL )
231  {
232    p_SetCoeff( f, n_Init( 1, r->cf ), r );
233    return;
234  }
235  else
236  {
237    if ( rField_is_Q_a(r) )
238      setCharacteristic( 0 );
239    else  if ( rField_is_Zp_a(r) )
240      setCharacteristic( -rChar(r) );
241    else
242      return; /* not implemented*/
243
244    CFList L;
245    CanonicalForm g, h;
246    poly p = pNext(f);
247
248    // first attemp: find 2 smallest g:
249
250    number g1=pGetCoeff(f);
251    number g2=pGetCoeff(p); // p==pNext(f);
252    pIter(p);
253    int sz1=n_Size(g1, r->cf);
254    int sz2=n_Size(g2, r->cf);
255    if (sz1>sz2)
256    {
257      number gg=g1;
258      g1=g2; g2=gg;
259      int sz=sz1;
260      sz1=sz2; sz2=sz;
261    }
262    while (p!=NULL)
263    {
264      int n_sz=n_Size(pGetCoeff(p),r->cf);
265      if (n_sz<sz1)
266      {
267        sz2=sz1;
268        g2=g1;
269        g1=pGetCoeff(p);
270        sz1=n_sz;
271        if (sz1<=3) break;
272      }
273      else if(n_sz<sz2)
274      {
275        sz2=n_sz;
276        g2=pGetCoeff(p);
277        sz2=n_sz;
278      }
279      pIter(p);
280    }
281    g = convSingPFactoryP( ((lnumber)g1)->z, r->cf->algring );
282    g = gcd( g, convSingPFactoryP( ((lnumber)g2)->z , r->cf->algring));
283
284    // second run: gcd's
285
286    p = f;
287    while ( (p != NULL) && (g != 1)  && ( g != 0))
288    {
289      h = convSingPFactoryP( ((lnumber)pGetCoeff(p))->z, r->cf->algring );
290      pIter( p );
291
292      g = gcd( g, h );
293
294      L.append( h );
295    }
296    if (( g == 1 ) || (g == 0))
297    {
298      // pTest(f);
299      return;
300    }
301    else
302    {
303      CFListIterator i;
304      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
305      {
306        lnumber c=(lnumber)pGetCoeff(p);
307        p_Delete(&c->z,r->cf->algring); // 2nd arg used to be nacRing
308        c->z=convFactoryPSingP( i.getItem() / g, r->cf->algring );
309        //nTest((number)c);
310        //#ifdef LDEBUG
311        //number cn=(number)c;
312        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
313        //nWrite(cn);PrintS(StringAppend("\n"));
314        //#endif
315      }
316    }
317    // pTest(f);
318  }
319}
320
321static int primepower(int c, const ring r)
322{
323  int p=1;
324  int cc=c;
325  while(cc!= rChar(r)) { cc*=c; p++; }
326  return p;
327}
328
329BOOLEAN count_Factors(ideal I, intvec *v,int j, poly &f, poly fac, const ring r)
330{
331  p_Test(f,r);
332  p_Test(fac,r);
333  int e=0;
334  if (!p_IsConstantPoly(fac,r))
335  {
336#ifdef FACTORIZE2_DEBUG
337    printf("start count_Factors(%d), Fdeg=%d, factor deg=%d\n",j,pTotaldegree(f),pTotaldegree(fac));
338    p_wrp(fac,currRing);PrintLn();
339#endif
340    On(SW_RATIONAL);
341    CanonicalForm F, FAC,Q,R;
342    Variable a;
343    F=convSingPFactoryP( f,r );
344    FAC=convSingPFactoryP( fac,r );
345
346    poly q;
347    loop
348    {
349      Q=F;
350      Q/=FAC;
351      R=Q;
352      R*=FAC;
353      R-=F;
354      if (R.isZero())
355      {
356        q = convFactoryPSingP( Q,r );
357        e++; p_Delete(&f,r); f=q; q=NULL; F=Q;
358      }
359      else
360      {
361        break;
362      }
363    }
364    if (e==0)
365    {
366      Off(SW_RATIONAL);
367      return FALSE;
368    }
369  }
370  else e=1;
371  I->m[j]=fac;
372  if (v!=NULL) (*v)[j]=e;
373  Off(SW_RATIONAL);
374  return TRUE;
375}
376
377int singclap_factorize_retry;
378extern int libfac_interruptflag;
379
380ideal singclap_factorize ( poly f, intvec ** v , int with_exps, const ring r)
381/* destroys f, sets *v */
382{
383  p_Test(f,r);
384#ifdef FACTORIZE2_DEBUG
385  printf("singclap_factorize, degree %ld\n",pTotaldegree(f));
386#endif
387  // with_exps: 3,1 return only true factors, no exponents
388  //            2 return true factors and exponents
389  //            0 return coeff, factors and exponents
390  BOOLEAN save_errorreported=errorreported;
391
392  ideal res=NULL;
393
394  // handle factorize(0) =========================================
395  if (f==NULL)
396  {
397    res=idInit(1,1);
398    if (with_exps!=1)
399    {
400      (*v)=new intvec(1);
401      (**v)[0]=1;
402    }
403    return res;
404  }
405  // handle factorize(mon) =========================================
406  if (pNext(f)==NULL)
407  {
408    int i=0;
409    int n=0;
410    int e;
411    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
412    if (with_exps==0) n++; // with coeff
413    res=idInit(si_max(n,1),1);
414    switch(with_exps)
415    {
416      case 0: // with coef & exp.
417        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
418        // no break
419      case 2: // with exp.
420        (*v)=new intvec(si_max(1,n));
421        (**v)[0]=1;
422        // no break
423      case 1: ;
424      #ifdef TEST
425      default: ;
426      #endif
427    }
428    if (n==0)
429    {
430      res->m[0]=p_One(r);
431      // (**v)[0]=1; is already done
432    }
433    else
434    {
435      for(i=rVar(r);i>0;i--)
436      {
437        e=p_GetExp(f,i,r);
438        if(e!=0)
439        {
440          n--;
441          poly p=p_One(r);
442          p_SetExp(p,i,1,r);
443          p_Setm(p,r);
444          res->m[n]=p;
445          if (with_exps!=1) (**v)[n]=e;
446        }
447      }
448    }
449    p_Delete(&f,r);
450    return res;
451  }
452  //PrintS("S:");pWrite(f);PrintLn();
453  // use factory/libfac in general ==============================
454  Off(SW_RATIONAL);
455  On(SW_SYMMETRIC_FF);
456  #ifdef HAVE_NTL
457  extern int prime_number;
458  if(rField_is_Q(r)) prime_number=0;
459  #endif
460  CFFList L;
461  number N=NULL;
462  number NN=NULL;
463  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
464
465  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
466  {
467    //if (f!=NULL) // already tested at start of routine
468    {
469      number n0=n_Copy(pGetCoeff(f),r->cf);
470      if (with_exps==0)
471        N=n_Copy(n0,r->cf);
472      p_Cleardenom(f, r);
473      NN=n_Div(n0,pGetCoeff(f),r->cf);
474      n_Delete(&n0,r->cf);
475      if (with_exps==0)
476      {
477        n_Delete(&N,r->cf);
478        N=n_Copy(NN,r->cf);
479      }
480    }
481  }
482  else if (rField_is_Zp_a(r))
483  {
484    //if (f!=NULL) // already tested at start of routine
485    if (singclap_factorize_retry==0)
486    {
487      number n0=n_Copy(pGetCoeff(f),r->cf);
488      if (with_exps==0)
489        N=n_Copy(n0,r->cf);
490      p_Norm(f,r);
491      p_Cleardenom(f, r);
492      NN=n_Div(n0,pGetCoeff(f),r->cf);
493      n_Delete(&n0,r->cf);
494      if (with_exps==0)
495      {
496        n_Delete(&N,r->cf);
497        N=n_Copy(NN,r->cf);
498      }
499    }
500  }
501  if (rField_is_Q(r) || rField_is_Zp(r))
502  {
503    setCharacteristic( rChar(r) );
504    CanonicalForm F( convSingPFactoryP( f,r ) );
505    L = factorize( F );
506  }
507  // and over Q(a) / Fp(a)
508  else if (rField_is_Extension(r))
509  {
510    if (r->cf->algring->minideal!=NULL)
511    {
512      CanonicalForm mipo=convSingPFactoryP(r->cf->algring->minideal->m[0],
513                                           r->cf->algring);
514      Variable a=rootOf(mipo);
515      CanonicalForm F( convSingPFactoryP( f,r ) );
516      if (rField_is_Zp_a(r))
517      {
518        L = factorize( F, a );
519      }
520      else
521      {
522        //  over Q(a)
523        L= factorize (F, a);
524      }
525    }
526    else
527    {
528      CanonicalForm F( convSingPFactoryP( f,r ) );
529      L = factorize( F );
530    }
531  }
532  else
533  {
534    goto notImpl;
535  }
536  {
537    poly ff=p_Copy(f,r); // a copy for the retry stuff
538    // the first factor should be a constant
539    if ( ! L.getFirst().factor().inCoeffDomain() )
540      L.insert(CFFactor(1,1));
541    // convert into ideal
542    int n = L.length();
543    if (n==0) n=1;
544    CFFListIterator J=L;
545    int j=0;
546    if (with_exps!=1)
547    {
548      if ((with_exps==2)&&(n>1))
549      {
550        n--;
551        J++;
552      }
553      *v = new intvec( n );
554    }
555    res = idInit( n ,1);
556    for ( ; J.hasItem(); J++, j++ )
557    {
558      if (with_exps!=1) (**v)[j] = J.getItem().exp();
559      if (rField_is_Zp(r) || rField_is_Q(r))           /* Q, Fp */
560      {
561        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
562        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
563      }
564      #if 0
565      else if (rField_is_GF())
566        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
567      #endif
568      else if (rField_is_Extension(r))     /* Q(a), Fp(a) */
569      {
570        intvec *w=NULL;
571        if (v!=NULL) w=*v;
572        if (r->cf->algring->minideal==NULL)
573        {
574          if(!count_Factors(res,w,j,ff,convFactoryPSingP( J.getItem().factor(),r ),r))
575          {
576            if (w!=NULL)
577              (*w)[j]=1;
578            res->m[j]=p_One(r);
579          }
580        }
581        else
582        {
583          if (!count_Factors(res,w,j,ff,convFactoryPSingP( J.getItem().factor(),r ),r))
584          {
585            if (w!=NULL)
586              (*w)[j]=1;
587            res->m[j]=p_One(r);
588          }
589        }
590      }
591    }
592    if (rField_is_Extension(r) && (!p_IsConstantPoly(ff,r)))
593    {
594      singclap_factorize_retry++;
595      if (singclap_factorize_retry<3)
596      {
597        int jj;
598        #ifdef FACTORIZE2_DEBUG
599        printf("factorize_retry\n");
600        #endif
601        intvec *ww=NULL;
602        id_Test(res,r);
603        ideal h=singclap_factorize ( ff, &ww , with_exps, r );
604        id_Test(h,r);
605        int l=(*v)->length();
606        (*v)->resize(l+ww->length());
607        for(jj=0;jj<ww->length();jj++)
608          (**v)[jj+l]=(*ww)[jj];
609        delete ww;
610        ideal hh=idInit(IDELEMS(res)+IDELEMS(h),1);
611        for(jj=IDELEMS(res)-1;jj>=0;jj--)
612        {
613          hh->m[jj]=res->m[jj];
614          res->m[jj]=NULL;
615        }
616        for(jj=IDELEMS(h)-1;jj>=0;jj--)
617        {
618          hh->m[jj+IDELEMS(res)]=h->m[jj];
619          h->m[jj]=NULL;
620        }
621        id_Delete(&res,r);
622        id_Delete(&h,r);
623        res=hh;
624        id_Test(res,r);
625        ff=NULL;
626      }
627      else
628      {
629        WarnS("problem with factorize");
630        #if 0
631        pWrite(ff);
632        idShow(res);
633        #endif
634        id_Delete(&res,r);
635        res=idInit(2,1);
636        res->m[0]=p_One(r);
637        res->m[1]=ff; ff=NULL;
638      }
639    }
640    p_Delete(&ff,r);
641    if (N!=NULL)
642    {
643      p_Mult_nn(res->m[0],N,r);
644      n_Delete(&N,r->cf);
645      N=NULL;
646    }
647    // delete constants
648    if (res!=NULL)
649    {
650      int i=IDELEMS(res)-1;
651      int j=0;
652      for(;i>=0;i--)
653      {
654        if ((res->m[i]!=NULL)
655        && (pNext(res->m[i])==NULL)
656        && (p_IsConstant(res->m[i],r)))
657        {
658          if (with_exps!=0)
659          {
660            p_Delete(&(res->m[i]),r);
661            if ((v!=NULL) && ((*v)!=NULL))
662              (**v)[i]=0;
663            j++;
664          }
665          else if (i!=0)
666          {
667            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
668            {
669              res->m[0]=p_Mult_q(res->m[0],p_Copy(res->m[i],r),r);
670              (**v)[i]--;
671            }
672            res->m[0]=p_Mult_q(res->m[0],res->m[i],r);
673            res->m[i]=NULL;
674            if ((v!=NULL) && ((*v)!=NULL))
675              (**v)[i]=1;
676            j++;
677          }
678        }
679      }
680      if (j>0)
681      {
682        idSkipZeroes(res);
683        if ((v!=NULL) && ((*v)!=NULL))
684        {
685          intvec *w=*v;
686          int len=IDELEMS(res);
687          *v = new intvec( len );
688          for (i=0,j=0;i<si_min(w->length(),len);i++)
689          {
690            if((*w)[i]!=0)
691            {
692              (**v)[j]=(*w)[i]; j++;
693            }
694          }
695          delete w;
696        }
697      }
698      if (res->m[0]==NULL)
699      {
700        res->m[0]=p_One(r);
701      }
702    }
703  }
704  if (rField_is_Q_a(r) && (r->cf->algring->minideal!=NULL))
705  {
706    int i=IDELEMS(res)-1;
707    int stop=1;
708    if (with_exps!=0) stop=0;
709    for(;i>=stop;i--)
710    {
711      p_Norm(res->m[i],r);
712    }
713    if (with_exps==0) p_SetCoeff(res->m[0],old_lead_coeff,r);
714    else n_Delete(&old_lead_coeff,r->cf);
715  }
716  else
717    n_Delete(&old_lead_coeff,r->cf);
718  errorreported=save_errorreported;
719notImpl:
720  if (res==NULL)
721    WerrorS( feNotImplemented );
722  if (NN!=NULL)
723  {
724    n_Delete(&NN,r->cf);
725  }
726  if (N!=NULL)
727  {
728    n_Delete(&N,r->cf);
729  }
730  if (f!=NULL) p_Delete(&f,r);
731  //PrintS("......S\n");
732  return res;
733}
734ideal singclap_sqrfree ( poly f, const ring r)
735{
736  p_Test(f,r);
737#ifdef FACTORIZE2_DEBUG
738  printf("singclap_sqrfree, degree %d\n",pTotaldegree(f));
739#endif
740  // with_exps: 3,1 return only true factors, no exponents
741  //            2 return true factors and exponents
742  //            0 return coeff, factors and exponents
743  BOOLEAN save_errorreported=errorreported;
744
745  ideal res=NULL;
746
747  // handle factorize(0) =========================================
748  if (f==NULL)
749  {
750    res=idInit(1,1);
751    return res;
752  }
753  // handle factorize(mon) =========================================
754  if (pNext(f)==NULL)
755  {
756    int i=0;
757    int n=0;
758    int e;
759    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
760    n++; // with coeff
761    res=idInit(si_max(n,1),1);
762    res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
763    if (n==0)
764    {
765      res->m[0]=p_One(r);
766      // (**v)[0]=1; is already done
767      return res;
768    }
769    for(i=rVar(r);i>0;i--)
770    {
771      e=p_GetExp(f,i,r);
772      if(e!=0)
773      {
774        n--;
775        poly p=p_One(r);
776        p_SetExp(p,i,1,r);
777        p_Setm(p,r);
778        res->m[n]=p;
779      }
780    }
781    return res;
782  }
783  //PrintS("S:");pWrite(f);PrintLn();
784  // use factory/libfac in general ==============================
785  Off(SW_RATIONAL);
786  On(SW_SYMMETRIC_FF);
787  #ifdef HAVE_NTL
788  extern int prime_number;
789  if(rField_is_Q(r)) prime_number=0;
790  #endif
791  CFFList L;
792
793  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
794  {
795    //if (f!=NULL) // already tested at start of routine
796    {
797      p_Cleardenom(f, r);
798    }
799  }
800  else if (rField_is_Zp_a(r))
801  {
802    //if (f!=NULL) // already tested at start of routine
803    if (singclap_factorize_retry==0)
804    {
805      p_Norm(f,r);
806      p_Cleardenom(f, r);
807    }
808  }
809  if (rField_is_Q(r) || rField_is_Zp(r))
810  {
811    setCharacteristic( rChar(r) );
812    CanonicalForm F( convSingPFactoryP( f,r ) );
813    L = sqrFree( F );
814  }
815  #if 0
816  else if (rField_is_GF())
817  {
818    int c=rChar(r);
819    setCharacteristic( c, primepower(c) );
820    CanonicalForm F( convSingGFFactoryGF( f ) );
821    if (F.isUnivariate())
822    {
823      L = factorize( F );
824    }
825    else
826    {
827      goto notImpl;
828    }
829  }
830  #endif
831  else
832  {
833    goto notImpl;
834  }
835  {
836    // convert into ideal
837    int n = L.length();
838    if (n==0) n=1;
839    CFFListIterator J=L;
840    int j=0;
841    res = idInit( n ,1);
842    for ( ; J.hasItem(); J++, j++ )
843    {
844      res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
845    }
846    if (res->m[0]==NULL)
847    {
848      res->m[0]=p_One(r);
849    }
850  }
851  p_Delete(&f,r);
852  errorreported=save_errorreported;
853notImpl:
854  if (res==NULL)
855    WerrorS( feNotImplemented );
856  return res;
857}
858
859
860TODO(somebody, add libfac)
861/*matrix singclap_irrCharSeries ( ideal I, const ring r)
862{
863  if (idIs0(I)) return mpNew(1,1);
864
865  // for now there is only the possibility to handle polynomials over
866  // Q and Fp ...
867  matrix res=NULL;
868  int i;
869  Off(SW_RATIONAL);
870  On(SW_SYMMETRIC_FF);
871  CFList L;
872  ListCFList LL;
873  if (((rChar(r) == 0) || (rChar(r) > 1) )
874  && (rPar(r)==0))
875  {
876    setCharacteristic( rChar(r) );
877    for(i=0;i<IDELEMS(I);i++)
878    {
879      poly p=I->m[i];
880      if (p!=NULL)
881      {
882        p=p_Copy(p,r);
883        p_Cleardenom(p, r);
884        L.append(convSingPFactoryP(p,r));
885      }
886    }
887  }
888  // and over Q(a) / Fp(a)
889  else if (( rChar(r)==1 ) // Q(a)
890  || (rChar(r) <-1))       // Fp(a)
891  {
892    if (rChar(r)==1) setCharacteristic( 0 );
893    else               setCharacteristic( -rChar(r) );
894    for(i=0;i<IDELEMS(I);i++)
895    {
896      poly p=I->m[i];
897      if (p!=NULL)
898      {
899        p=p_Copy(p,r);
900        p_Cleardenom(p, r);
901        L.append(convSingTrPFactoryP(p,r));
902      }
903    }
904  }
905  else
906  {
907    WerrorS( feNotImplemented );
908    return res;
909  }
910
911  // a very bad work-around --- FIX IT in libfac
912  // should be fixed as of 2001/6/27
913  int tries=0;
914  int m,n;
915  ListIterator<CFList> LLi;
916  loop
917  {
918    LL=IrrCharSeries(L);
919    m= LL.length(); // Anzahl Zeilen
920    n=0;
921    for ( LLi = LL; LLi.hasItem(); LLi++ )
922    {
923      n = si_max(LLi.getItem().length(),n);
924    }
925    if ((m!=0) && (n!=0)) break;
926    tries++;
927    if (tries>=5) break;
928  }
929  if ((m==0) || (n==0))
930  {
931    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
932      m,n,IDELEMS(I)+1,LL.length());
933    iiWriteMatrix((matrix)I,"I",2,0);
934    m=si_max(m,1);
935    n=si_max(n,1);
936  }
937  res=mpNew(m,n);
938  CFListIterator Li;
939  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
940  {
941    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
942    {
943      if ( (rChar(r) == 0) || (rChar(r) > 1) )
944        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem(),r);
945      else
946        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem(),r);
947    }
948  }
949  Off(SW_RATIONAL);
950  return res;
951}*/
952
953/*char* singclap_neworder ( ideal I, const ring r)
954{
955  int i;
956  Off(SW_RATIONAL);
957  On(SW_SYMMETRIC_FF);
958  CFList L;
959  if (((rChar(r) == 0) || (rChar(r) > 1) )
960  && (rPar(r)==0))
961  {
962    setCharacteristic( rChar(r) );
963    for(i=0;i<IDELEMS(I);i++)
964    {
965      L.append(convSingPFactoryP(I->m[i],r));
966    }
967  }
968  // and over Q(a) / Fp(a)
969  else if (( rChar(r)==1 ) // Q(a)
970  || (rChar(r) <-1))       // Fp(a)
971  {
972    if (rChar(r)==1) setCharacteristic( 0 );
973    else               setCharacteristic( -rChar(r) );
974    for(i=0;i<IDELEMS(I);i++)
975    {
976      L.append(convSingTrPFactoryP(I->m[i],r));
977    }
978  }
979  else
980  {
981    WerrorS( feNotImplemented );
982    return NULL;
983  }
984
985  List<int> IL=neworderint(L);
986  ListIterator<int> Li;
987  StringSetS("");
988  Li = IL;
989  int offs=rPar(r);
990  int* mark=(int*)omAlloc0((rVar(r)+offs)*sizeof(int));
991  int cnt=rVar(r)+offs;
992  loop
993  {
994    if(! Li.hasItem()) break;
995    BOOLEAN done=TRUE;
996    i=Li.getItem()-1;
997    mark[i]=1;
998    if (i<offs)
999    {
1000      done=FALSE;
1001      //StringAppendS(r->parameter[i]);
1002    }
1003    else
1004    {
1005      StringAppendS(r->names[i-offs]);
1006    }
1007    Li++;
1008    cnt--;
1009    if(cnt==0) break;
1010    if (done) StringAppendS(",");
1011  }
1012  for(i=0;i<rVar(r)+offs;i++)
1013  {
1014    BOOLEAN done=TRUE;
1015    if(mark[i]==0)
1016    {
1017      if (i<offs)
1018      {
1019        done=FALSE;
1020        //StringAppendS(r->parameter[i]);
1021      }
1022      else
1023      {
1024        StringAppendS(r->names[i-offs]);
1025      }
1026      cnt--;
1027      if(cnt==0) break;
1028      if (done) StringAppendS(",");
1029    }
1030  }
1031  char * s=omStrDup(StringAppendS(""));
1032  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1033  return s;
1034}*/
1035
1036BOOLEAN singclap_isSqrFree(poly f, const ring r)
1037{
1038  BOOLEAN b=FALSE;
1039  CanonicalForm F( convSingPFactoryP( f,r ) );
1040  if((r->cf->type==n_Zp)&&(!F.isUnivariate()))
1041      goto err;
1042  b=(BOOLEAN)isSqrFree(F);
1043  Off(SW_RATIONAL);
1044  return b;
1045err:
1046  WerrorS( feNotImplemented );
1047  return 0;
1048}
1049
1050poly singclap_det( const matrix m, const ring s )
1051{
1052  int r=m->rows();
1053  if (r!=m->cols())
1054  {
1055    Werror("det of %d x %d matrix",r,m->cols());
1056    return NULL;
1057  }
1058  poly res=NULL;
1059  CFMatrix M(r,r);
1060  int i,j;
1061  for(i=r;i>0;i--)
1062  {
1063    for(j=r;j>0;j--)
1064    {
1065      M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1066    }
1067  }
1068  res= convFactoryPSingP( determinant(M,r),s ) ;
1069  Off(SW_RATIONAL);
1070  return res;
1071}
1072
1073int singclap_det_i( intvec * m)
1074{
1075  setCharacteristic( 0 );
1076  CFMatrix M(m->rows(),m->cols());
1077  int i,j;
1078  for(i=m->rows();i>0;i--)
1079  {
1080    for(j=m->cols();j>0;j--)
1081    {
1082      M(i,j)=IMATELEM(*m,i,j);
1083    }
1084  }
1085  int res= convFactoryISingI( determinant(M,m->rows()) ) ;
1086  Off(SW_RATIONAL);
1087  return res;
1088}
1089#ifdef HAVE_NTL
1090matrix singntl_HNF(matrix  m, const ring s )
1091{
1092  int r=m->rows();
1093  if (r!=m->cols())
1094  {
1095    Werror("HNF of %d x %d matrix",r,m->cols());
1096    return NULL;
1097  }
1098  matrix res=mpNew(r,r);
1099  if (rField_is_Q(s))
1100  {
1101
1102    CFMatrix M(r,r);
1103    int i,j;
1104    for(i=r;i>0;i--)
1105    {
1106      for(j=r;j>0;j--)
1107      {
1108        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
1109      }
1110    }
1111    CFMatrix *MM=cf_HNF(M);
1112    for(i=r;i>0;i--)
1113    {
1114      for(j=r;j>0;j--)
1115      {
1116        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1117      }
1118    }
1119    delete MM;
1120  }
1121  return res;
1122}
1123intvec* singntl_HNF(intvec*  m)
1124{
1125  int r=m->rows();
1126  if (r!=m->cols())
1127  {
1128    Werror("HNF of %d x %d matrix",r,m->cols());
1129    return NULL;
1130  }
1131  setCharacteristic( 0 );
1132  CFMatrix M(r,r);
1133  int i,j;
1134  for(i=r;i>0;i--)
1135  {
1136    for(j=r;j>0;j--)
1137    {
1138      M(i,j)=IMATELEM(*m,i,j);
1139    }
1140  }
1141  CFMatrix *MM=cf_HNF(M);
1142  intvec *mm=ivCopy(m);
1143  for(i=r;i>0;i--)
1144  {
1145    for(j=r;j>0;j--)
1146    {
1147      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1148    }
1149  }
1150  delete MM;
1151  return mm;
1152}
1153matrix singntl_LLL(matrix  m, const ring s )
1154{
1155  int r=m->rows();
1156  int c=m->cols();
1157  matrix res=mpNew(r,c);
1158  if (rField_is_Q(s))
1159  {
1160    CFMatrix M(r,c);
1161    int i,j;
1162    for(i=r;i>0;i--)
1163    {
1164      for(j=c;j>0;j--)
1165      {
1166        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1167      }
1168    }
1169    CFMatrix *MM=cf_LLL(M);
1170    for(i=r;i>0;i--)
1171    {
1172      for(j=c;j>0;j--)
1173      {
1174        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1175      }
1176    }
1177    delete MM;
1178  }
1179  return res;
1180}
1181intvec* singntl_LLL(intvec*  m)
1182{
1183  int r=m->rows();
1184  int c=m->cols();
1185  setCharacteristic( 0 );
1186  CFMatrix M(r,c);
1187  int i,j;
1188  for(i=r;i>0;i--)
1189  {
1190    for(j=r;j>0;j--)
1191    {
1192      M(i,j)=IMATELEM(*m,i,j);
1193    }
1194  }
1195  CFMatrix *MM=cf_LLL(M);
1196  intvec *mm=ivCopy(m);
1197  for(i=r;i>0;i--)
1198  {
1199    for(j=c;j>0;j--)
1200    {
1201      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1202    }
1203  }
1204  delete MM;
1205  return mm;
1206}
1207/*
1208napoly singclap_alglcm ( napoly f, napoly g )
1209{
1210
1211 // over Q(a) / Fp(a)
1212 if (nGetChar()==1) setCharacteristic( 0 );
1213 else               setCharacteristic( -nGetChar() );
1214 napoly res;
1215
1216 if (currRing->minpoly!=NULL)
1217 {
1218   CanonicalForm mipo=convSingPFactoryP(((lnumber)currRing->minpoly)->z,
1219                                         currRing->algring);
1220   Variable a=rootOf(mipo);
1221   CanonicalForm F( convSingAFactoryA( f,a, currRing ) ),
1222                 G( convSingAFactoryA( g,a, currRing ) );
1223   CanonicalForm GCD;
1224
1225   // calculate gcd
1226   GCD = gcd( F, G );
1227
1228   // calculate lcm
1229   res= convFactoryASingA( (F/GCD)*G,currRing );
1230 }
1231 else
1232 {
1233   CanonicalForm F( convSingPFactoryP( f,currRing->algring ) ),
1234                 G( convSingPFactoryP( g,currRing->algring ) );
1235   CanonicalForm GCD;
1236   // calculate gcd
1237   GCD = gcd( F, G );
1238
1239   // calculate lcm
1240   res= convFactoryPSingP( (F/GCD)*G, currRing->algring );
1241 }
1242
1243 Off(SW_RATIONAL);
1244 return res;
1245}
1246
1247void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
1248{
1249 // over Q(a) / Fp(a)
1250 if (nGetChar()==1) setCharacteristic( 0 );
1251 else               setCharacteristic( -nGetChar() );
1252 ff=gg=NULL;
1253 On(SW_RATIONAL);
1254
1255 if (currRing->minpoly!=NULL)
1256 {
1257   CanonicalForm mipo=convSingPFactoryP(((lnumber)currRing->minpoly)->z,
1258                         currRing->algring);
1259   Variable a=rootOf(mipo);
1260   CanonicalForm F( convSingAFactoryA( f,a, currRing ) ),
1261                 G( convSingAFactoryA( g,a, currRing ) );
1262   CanonicalForm GCD;
1263
1264   GCD=gcd( F, G );
1265
1266   if ((GCD!=1) && (GCD!=0))
1267   {
1268     ff= convFactoryASingA( F/ GCD, currRing );
1269     gg= convFactoryASingA( G/ GCD, currRing );
1270   }
1271 }
1272 else
1273 {
1274   CanonicalForm F( convSingPFactoryP( f,currRing->algring ) ),
1275                 G( convSingPFactoryP( g,currRing->algring ) );
1276   CanonicalForm GCD;
1277
1278   GCD=gcd( F, G );
1279
1280   if ((GCD!=1) && (GCD!=0))
1281   {
1282     ff= convFactoryPSingP( F/ GCD, currRing->algring );
1283     gg= convFactoryPSingP( G/ GCD, currRing->algring );
1284   }
1285 }
1286
1287 Off(SW_RATIONAL);
1288}
1289*/
1290
1291#if 0
1292lists singclap_chineseRemainder(lists x, lists q)
1293{
1294  //assume(x->nr == q->nr);
1295  //assume(x->nr >= 0);
1296  int n=x->nr+1;
1297  if ((x->nr<0) || (x->nr!=q->nr))
1298  {
1299    WerrorS("list are empty or not of equal length");
1300    return NULL;
1301  }
1302  lists res=(lists)omAlloc0Bin(slists_bin);
1303  CFArray X(1,n), Q(1,n);
1304  int i;
1305  for(i=0; i<n; i++)
1306  {
1307    if (x->m[i-1].Typ()==INT_CMD)
1308    {
1309      X[i]=(int)x->m[i-1].Data();
1310    }
1311    else if (x->m[i-1].Typ()==NUMBER_CMD)
1312    {
1313      number N=(number)x->m[i-1].Data();
1314      X[i]=convSingNFactoryN(N);
1315    }
1316    else
1317    {
1318      WerrorS("illegal type in chineseRemainder");
1319      omFreeBin(res,slists_bin);
1320      return NULL;
1321    }
1322    if (q->m[i-1].Typ()==INT_CMD)
1323    {
1324      Q[i]=(int)q->m[i-1].Data();
1325    }
1326    else if (q->m[i-1].Typ()==NUMBER_CMD)
1327    {
1328      number N=(number)x->m[i-1].Data();
1329      Q[i]=convSingNFactoryN(N);
1330    }
1331    else
1332    {
1333      WerrorS("illegal type in chineseRemainder");
1334      omFreeBin(res,slists_bin);
1335      return NULL;
1336    }
1337  }
1338  CanonicalForm r, prod;
1339  chineseRemainder( X, Q, r, prod );
1340  res->Init(2);
1341  res->m[0].rtyp=NUMBER_CMD;
1342  res->m[1].rtyp=NUMBER_CMD;
1343  res->m[0].data=(char *)convFactoryNSingN( r );
1344  res->m[1].data=(char *)convFactoryNSingN( prod );
1345  return res;
1346}
1347#endif
1348#endif
Note: See TracBrowser for help on using the repository browser.