source: git/libpolys/polys/clapsing.cc @ 6ccdd3a

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