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

spielwiese
Last change on this file since c74d6a was c74d6a, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
FIX/ADD: factory/singular wrappers for _HNF and _LLL (from NTL)
  • 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
1090#ifdef HAVE_NTL
1091matrix singntl_HNF(matrix  m, const ring s )
1092{
1093  int r=m->rows();
1094  if (r!=m->cols())
1095  {
1096    Werror("HNF of %d x %d matrix",r,m->cols());
1097    return NULL;
1098  }
1099  matrix res=mpNew(r,r);
1100  if (rField_is_Q(s))
1101  {
1102
1103    CFMatrix M(r,r);
1104    int i,j;
1105    for(i=r;i>0;i--)
1106    {
1107      for(j=r;j>0;j--)
1108      {
1109        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
1110      }
1111    }
1112    CFMatrix *MM=cf_HNF(M);
1113    for(i=r;i>0;i--)
1114    {
1115      for(j=r;j>0;j--)
1116      {
1117        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1118      }
1119    }
1120    delete MM;
1121  }
1122  return res;
1123}
1124intvec* singntl_HNF(intvec*  m)
1125{
1126  int r=m->rows();
1127  if (r!=m->cols())
1128  {
1129    Werror("HNF of %d x %d matrix",r,m->cols());
1130    return NULL;
1131  }
1132  setCharacteristic( 0 );
1133  CFMatrix M(r,r);
1134  int i,j;
1135  for(i=r;i>0;i--)
1136  {
1137    for(j=r;j>0;j--)
1138    {
1139      M(i,j)=IMATELEM(*m,i,j);
1140    }
1141  }
1142  CFMatrix *MM=cf_HNF(M);
1143  intvec *mm=ivCopy(m);
1144  for(i=r;i>0;i--)
1145  {
1146    for(j=r;j>0;j--)
1147    {
1148      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1149    }
1150  }
1151  delete MM;
1152  return mm;
1153}
1154matrix singntl_LLL(matrix  m, const ring s )
1155{
1156  int r=m->rows();
1157  int c=m->cols();
1158  matrix res=mpNew(r,c);
1159  if (rField_is_Q(s))
1160  {
1161    CFMatrix M(r,c);
1162    int i,j;
1163    for(i=r;i>0;i--)
1164    {
1165      for(j=c;j>0;j--)
1166      {
1167        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1168      }
1169    }
1170    CFMatrix *MM=cf_LLL(M);
1171    for(i=r;i>0;i--)
1172    {
1173      for(j=c;j>0;j--)
1174      {
1175        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1176      }
1177    }
1178    delete MM;
1179  }
1180  return res;
1181}
1182intvec* singntl_LLL(intvec*  m)
1183{
1184  int r=m->rows();
1185  int c=m->cols();
1186  setCharacteristic( 0 );
1187  CFMatrix M(r,c);
1188  int i,j;
1189  for(i=r;i>0;i--)
1190  {
1191    for(j=r;j>0;j--)
1192    {
1193      M(i,j)=IMATELEM(*m,i,j);
1194    }
1195  }
1196  CFMatrix *MM=cf_LLL(M);
1197  intvec *mm=ivCopy(m);
1198  for(i=r;i>0;i--)
1199  {
1200    for(j=c;j>0;j--)
1201    {
1202      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1203    }
1204  }
1205  delete MM;
1206  return mm;
1207}
1208#endif
1209
1210/*
1211napoly singclap_alglcm ( napoly f, napoly g )
1212{
1213
1214 // over Q(a) / Fp(a)
1215 if (nGetChar()==1) setCharacteristic( 0 );
1216 else               setCharacteristic( -nGetChar() );
1217 napoly res;
1218
1219 if (currRing->minpoly!=NULL)
1220 {
1221   CanonicalForm mipo=convSingPFactoryP(((lnumber)currRing->minpoly)->z,
1222                                         currRing->algring);
1223   Variable a=rootOf(mipo);
1224   CanonicalForm F( convSingAFactoryA( f,a, currRing ) ),
1225                 G( convSingAFactoryA( g,a, currRing ) );
1226   CanonicalForm GCD;
1227
1228   // calculate gcd
1229   GCD = gcd( F, G );
1230
1231   // calculate lcm
1232   res= convFactoryASingA( (F/GCD)*G,currRing );
1233 }
1234 else
1235 {
1236   CanonicalForm F( convSingPFactoryP( f,currRing->algring ) ),
1237                 G( convSingPFactoryP( g,currRing->algring ) );
1238   CanonicalForm GCD;
1239   // calculate gcd
1240   GCD = gcd( F, G );
1241
1242   // calculate lcm
1243   res= convFactoryPSingP( (F/GCD)*G, currRing->algring );
1244 }
1245
1246 Off(SW_RATIONAL);
1247 return res;
1248}
1249
1250void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
1251{
1252 // over Q(a) / Fp(a)
1253 if (nGetChar()==1) setCharacteristic( 0 );
1254 else               setCharacteristic( -nGetChar() );
1255 ff=gg=NULL;
1256 On(SW_RATIONAL);
1257
1258 if (currRing->minpoly!=NULL)
1259 {
1260   CanonicalForm mipo=convSingPFactoryP(((lnumber)currRing->minpoly)->z,
1261                         currRing->algring);
1262   Variable a=rootOf(mipo);
1263   CanonicalForm F( convSingAFactoryA( f,a, currRing ) ),
1264                 G( convSingAFactoryA( g,a, currRing ) );
1265   CanonicalForm GCD;
1266
1267   GCD=gcd( F, G );
1268
1269   if ((GCD!=1) && (GCD!=0))
1270   {
1271     ff= convFactoryASingA( F/ GCD, currRing );
1272     gg= convFactoryASingA( G/ GCD, currRing );
1273   }
1274 }
1275 else
1276 {
1277   CanonicalForm F( convSingPFactoryP( f,currRing->algring ) ),
1278                 G( convSingPFactoryP( g,currRing->algring ) );
1279   CanonicalForm GCD;
1280
1281   GCD=gcd( F, G );
1282
1283   if ((GCD!=1) && (GCD!=0))
1284   {
1285     ff= convFactoryPSingP( F/ GCD, currRing->algring );
1286     gg= convFactoryPSingP( G/ GCD, currRing->algring );
1287   }
1288 }
1289
1290 Off(SW_RATIONAL);
1291}
1292*/
1293
1294#if 0
1295lists singclap_chineseRemainder(lists x, lists q)
1296{
1297  //assume(x->nr == q->nr);
1298  //assume(x->nr >= 0);
1299  int n=x->nr+1;
1300  if ((x->nr<0) || (x->nr!=q->nr))
1301  {
1302    WerrorS("list are empty or not of equal length");
1303    return NULL;
1304  }
1305  lists res=(lists)omAlloc0Bin(slists_bin);
1306  CFArray X(1,n), Q(1,n);
1307  int i;
1308  for(i=0; i<n; i++)
1309  {
1310    if (x->m[i-1].Typ()==INT_CMD)
1311    {
1312      X[i]=(int)x->m[i-1].Data();
1313    }
1314    else if (x->m[i-1].Typ()==NUMBER_CMD)
1315    {
1316      number N=(number)x->m[i-1].Data();
1317      X[i]=convSingNFactoryN(N);
1318    }
1319    else
1320    {
1321      WerrorS("illegal type in chineseRemainder");
1322      omFreeBin(res,slists_bin);
1323      return NULL;
1324    }
1325    if (q->m[i-1].Typ()==INT_CMD)
1326    {
1327      Q[i]=(int)q->m[i-1].Data();
1328    }
1329    else if (q->m[i-1].Typ()==NUMBER_CMD)
1330    {
1331      number N=(number)x->m[i-1].Data();
1332      Q[i]=convSingNFactoryN(N);
1333    }
1334    else
1335    {
1336      WerrorS("illegal type in chineseRemainder");
1337      omFreeBin(res,slists_bin);
1338      return NULL;
1339    }
1340  }
1341  CanonicalForm r, prod;
1342  chineseRemainder( X, Q, r, prod );
1343  res->Init(2);
1344  res->m[0].rtyp=NUMBER_CMD;
1345  res->m[1].rtyp=NUMBER_CMD;
1346  res->m[0].data=(char *)convFactoryNSingN( r );
1347  res->m[1].data=(char *)convFactoryNSingN( prod );
1348  return res;
1349}
1350#endif
1351#endif
Note: See TracBrowser for help on using the repository browser.