source: git/libpolys/polys/clapsing.cc @ 529fa4

spielwiese
Last change on this file since 529fa4 was 529fa4, checked in by Hans Schoenemann <hannes@…>, 13 years ago
add: nChineseRemainder/idChineseRemainder
  • Property mode set to 100644
File size: 29.5 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
377#ifdef HAVE_FACTORY
378int singclap_factorize_retry;
379#if 0
380extern int libfac_interruptflag;
381#endif
382#endif
383
384ideal singclap_factorize ( poly f, intvec ** v , int with_exps, const ring r)
385/* destroys f, sets *v */
386{
387  p_Test(f,r);
388#ifdef FACTORIZE2_DEBUG
389  printf("singclap_factorize, degree %ld\n",pTotaldegree(f));
390#endif
391  // with_exps: 3,1 return only true factors, no exponents
392  //            2 return true factors and exponents
393  //            0 return coeff, factors and exponents
394  BOOLEAN save_errorreported=errorreported;
395
396  ideal res=NULL;
397
398  // handle factorize(0) =========================================
399  if (f==NULL)
400  {
401    res=idInit(1,1);
402    if (with_exps!=1)
403    {
404      (*v)=new intvec(1);
405      (**v)[0]=1;
406    }
407    return res;
408  }
409  // handle factorize(mon) =========================================
410  if (pNext(f)==NULL)
411  {
412    int i=0;
413    int n=0;
414    int e;
415    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
416    if (with_exps==0) n++; // with coeff
417    res=idInit(si_max(n,1),1);
418    switch(with_exps)
419    {
420      case 0: // with coef & exp.
421        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
422        // no break
423      case 2: // with exp.
424        (*v)=new intvec(si_max(1,n));
425        (**v)[0]=1;
426        // no break
427      case 1: ;
428      #ifdef TEST
429      default: ;
430      #endif
431    }
432    if (n==0)
433    {
434      res->m[0]=p_One(r);
435      // (**v)[0]=1; is already done
436    }
437    else
438    {
439      for(i=rVar(r);i>0;i--)
440      {
441        e=p_GetExp(f,i,r);
442        if(e!=0)
443        {
444          n--;
445          poly p=p_One(r);
446          p_SetExp(p,i,1,r);
447          p_Setm(p,r);
448          res->m[n]=p;
449          if (with_exps!=1) (**v)[n]=e;
450        }
451      }
452    }
453    p_Delete(&f,r);
454    return res;
455  }
456  //PrintS("S:");pWrite(f);PrintLn();
457  // use factory/libfac in general ==============================
458  Off(SW_RATIONAL);
459  On(SW_SYMMETRIC_FF);
460  #ifdef HAVE_NTL
461  extern int prime_number;
462  if(rField_is_Q(r)) prime_number=0;
463  #endif
464  CFFList L;
465  number N=NULL;
466  number NN=NULL;
467  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
468
469  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
470  {
471    //if (f!=NULL) // already tested at start of routine
472    {
473      number n0=n_Copy(pGetCoeff(f),r->cf);
474      if (with_exps==0)
475        N=n_Copy(n0,r->cf);
476      p_Cleardenom(f, r);
477      NN=n_Div(n0,pGetCoeff(f),r->cf);
478      n_Delete(&n0,r->cf);
479      if (with_exps==0)
480      {
481        n_Delete(&N,r->cf);
482        N=n_Copy(NN,r->cf);
483      }
484    }
485  }
486  else if (rField_is_Zp_a(r))
487  {
488    //if (f!=NULL) // already tested at start of routine
489    if (singclap_factorize_retry==0)
490    {
491      number n0=n_Copy(pGetCoeff(f),r->cf);
492      if (with_exps==0)
493        N=n_Copy(n0,r->cf);
494      p_Norm(f,r);
495      p_Cleardenom(f, r);
496      NN=n_Div(n0,pGetCoeff(f),r->cf);
497      n_Delete(&n0,r->cf);
498      if (with_exps==0)
499      {
500        n_Delete(&N,r->cf);
501        N=n_Copy(NN,r->cf);
502      }
503    }
504  }
505  if (rField_is_Q(r) || rField_is_Zp(r))
506  {
507    setCharacteristic( rChar(r) );
508    CanonicalForm F( convSingPFactoryP( f,r ) );
509    L = factorize( F );
510  }
511  // and over Q(a) / Fp(a)
512  else if (rField_is_Extension(r))
513  {
514    if (r->cf->algring->minideal!=NULL)
515    {
516      CanonicalForm mipo=convSingPFactoryP(r->cf->algring->minideal->m[0],
517                                           r->cf->algring);
518      Variable a=rootOf(mipo);
519      CanonicalForm F( convSingPFactoryP( f,r ) );
520      if (rField_is_Zp_a(r))
521      {
522        L = factorize( F, a );
523      }
524      else
525      {
526        //  over Q(a)
527        L= factorize (F, a);
528      }
529    }
530    else
531    {
532      CanonicalForm F( convSingPFactoryP( f,r ) );
533      L = factorize( F );
534    }
535  }
536  else
537  {
538    goto notImpl;
539  }
540  {
541    poly ff=p_Copy(f,r); // a copy for the retry stuff
542    // the first factor should be a constant
543    if ( ! L.getFirst().factor().inCoeffDomain() )
544      L.insert(CFFactor(1,1));
545    // convert into ideal
546    int n = L.length();
547    if (n==0) n=1;
548    CFFListIterator J=L;
549    int j=0;
550    if (with_exps!=1)
551    {
552      if ((with_exps==2)&&(n>1))
553      {
554        n--;
555        J++;
556      }
557      *v = new intvec( n );
558    }
559    res = idInit( n ,1);
560    for ( ; J.hasItem(); J++, j++ )
561    {
562      if (with_exps!=1) (**v)[j] = J.getItem().exp();
563      if (rField_is_Zp(r) || rField_is_Q(r))           /* Q, Fp */
564      {
565        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
566        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
567      }
568      #if 0
569      else if (rField_is_GF())
570        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
571      #endif
572      else if (rField_is_Extension(r))     /* Q(a), Fp(a) */
573      {
574        intvec *w=NULL;
575        if (v!=NULL) w=*v;
576        if (r->cf->algring->minideal==NULL)
577        {
578          if(!count_Factors(res,w,j,ff,convFactoryPSingP( J.getItem().factor(),r ),r))
579          {
580            if (w!=NULL)
581              (*w)[j]=1;
582            res->m[j]=p_One(r);
583          }
584        }
585        else
586        {
587          if (!count_Factors(res,w,j,ff,convFactoryPSingP( J.getItem().factor(),r ),r))
588          {
589            if (w!=NULL)
590              (*w)[j]=1;
591            res->m[j]=p_One(r);
592          }
593        }
594      }
595    }
596    if (rField_is_Extension(r) && (!p_IsConstantPoly(ff,r)))
597    {
598      singclap_factorize_retry++;
599      if (singclap_factorize_retry<3)
600      {
601        int jj;
602        #ifdef FACTORIZE2_DEBUG
603        printf("factorize_retry\n");
604        #endif
605        intvec *ww=NULL;
606        id_Test(res,r);
607        ideal h=singclap_factorize ( ff, &ww , with_exps, r );
608        id_Test(h,r);
609        int l=(*v)->length();
610        (*v)->resize(l+ww->length());
611        for(jj=0;jj<ww->length();jj++)
612          (**v)[jj+l]=(*ww)[jj];
613        delete ww;
614        ideal hh=idInit(IDELEMS(res)+IDELEMS(h),1);
615        for(jj=IDELEMS(res)-1;jj>=0;jj--)
616        {
617          hh->m[jj]=res->m[jj];
618          res->m[jj]=NULL;
619        }
620        for(jj=IDELEMS(h)-1;jj>=0;jj--)
621        {
622          hh->m[jj+IDELEMS(res)]=h->m[jj];
623          h->m[jj]=NULL;
624        }
625        id_Delete(&res,r);
626        id_Delete(&h,r);
627        res=hh;
628        id_Test(res,r);
629        ff=NULL;
630      }
631      else
632      {
633        WarnS("problem with factorize");
634        #if 0
635        pWrite(ff);
636        idShow(res);
637        #endif
638        id_Delete(&res,r);
639        res=idInit(2,1);
640        res->m[0]=p_One(r);
641        res->m[1]=ff; ff=NULL;
642      }
643    }
644    p_Delete(&ff,r);
645    if (N!=NULL)
646    {
647      p_Mult_nn(res->m[0],N,r);
648      n_Delete(&N,r->cf);
649      N=NULL;
650    }
651    // delete constants
652    if (res!=NULL)
653    {
654      int i=IDELEMS(res)-1;
655      int j=0;
656      for(;i>=0;i--)
657      {
658        if ((res->m[i]!=NULL)
659        && (pNext(res->m[i])==NULL)
660        && (p_IsConstant(res->m[i],r)))
661        {
662          if (with_exps!=0)
663          {
664            p_Delete(&(res->m[i]),r);
665            if ((v!=NULL) && ((*v)!=NULL))
666              (**v)[i]=0;
667            j++;
668          }
669          else if (i!=0)
670          {
671            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
672            {
673              res->m[0]=p_Mult_q(res->m[0],p_Copy(res->m[i],r),r);
674              (**v)[i]--;
675            }
676            res->m[0]=p_Mult_q(res->m[0],res->m[i],r);
677            res->m[i]=NULL;
678            if ((v!=NULL) && ((*v)!=NULL))
679              (**v)[i]=1;
680            j++;
681          }
682        }
683      }
684      if (j>0)
685      {
686        idSkipZeroes(res);
687        if ((v!=NULL) && ((*v)!=NULL))
688        {
689          intvec *w=*v;
690          int len=IDELEMS(res);
691          *v = new intvec( len );
692          for (i=0,j=0;i<si_min(w->length(),len);i++)
693          {
694            if((*w)[i]!=0)
695            {
696              (**v)[j]=(*w)[i]; j++;
697            }
698          }
699          delete w;
700        }
701      }
702      if (res->m[0]==NULL)
703      {
704        res->m[0]=p_One(r);
705      }
706    }
707  }
708  if (rField_is_Q_a(r) && (r->cf->algring->minideal!=NULL))
709  {
710    int i=IDELEMS(res)-1;
711    int stop=1;
712    if (with_exps!=0) stop=0;
713    for(;i>=stop;i--)
714    {
715      p_Norm(res->m[i],r);
716    }
717    if (with_exps==0) p_SetCoeff(res->m[0],old_lead_coeff,r);
718    else n_Delete(&old_lead_coeff,r->cf);
719  }
720  else
721    n_Delete(&old_lead_coeff,r->cf);
722  errorreported=save_errorreported;
723notImpl:
724  if (res==NULL)
725    WerrorS( feNotImplemented );
726  if (NN!=NULL)
727  {
728    n_Delete(&NN,r->cf);
729  }
730  if (N!=NULL)
731  {
732    n_Delete(&N,r->cf);
733  }
734  if (f!=NULL) p_Delete(&f,r);
735  //PrintS("......S\n");
736  return res;
737}
738ideal singclap_sqrfree ( poly f, const ring r)
739{
740  p_Test(f,r);
741#ifdef FACTORIZE2_DEBUG
742  printf("singclap_sqrfree, degree %d\n",pTotaldegree(f));
743#endif
744  // with_exps: 3,1 return only true factors, no exponents
745  //            2 return true factors and exponents
746  //            0 return coeff, factors and exponents
747  BOOLEAN save_errorreported=errorreported;
748
749  ideal res=NULL;
750
751  // handle factorize(0) =========================================
752  if (f==NULL)
753  {
754    res=idInit(1,1);
755    return res;
756  }
757  // handle factorize(mon) =========================================
758  if (pNext(f)==NULL)
759  {
760    int i=0;
761    int n=0;
762    int e;
763    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
764    n++; // with coeff
765    res=idInit(si_max(n,1),1);
766    res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
767    if (n==0)
768    {
769      res->m[0]=p_One(r);
770      // (**v)[0]=1; is already done
771      return res;
772    }
773    for(i=rVar(r);i>0;i--)
774    {
775      e=p_GetExp(f,i,r);
776      if(e!=0)
777      {
778        n--;
779        poly p=p_One(r);
780        p_SetExp(p,i,1,r);
781        p_Setm(p,r);
782        res->m[n]=p;
783      }
784    }
785    return res;
786  }
787  //PrintS("S:");pWrite(f);PrintLn();
788  // use factory/libfac in general ==============================
789  Off(SW_RATIONAL);
790  On(SW_SYMMETRIC_FF);
791  #ifdef HAVE_NTL
792  extern int prime_number;
793  if(rField_is_Q(r)) prime_number=0;
794  #endif
795  CFFList L;
796
797  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
798  {
799    //if (f!=NULL) // already tested at start of routine
800    {
801      p_Cleardenom(f, r);
802    }
803  }
804  else if (rField_is_Zp_a(r))
805  {
806    //if (f!=NULL) // already tested at start of routine
807    if (singclap_factorize_retry==0)
808    {
809      p_Norm(f,r);
810      p_Cleardenom(f, r);
811    }
812  }
813  if (rField_is_Q(r) || rField_is_Zp(r))
814  {
815    setCharacteristic( rChar(r) );
816    CanonicalForm F( convSingPFactoryP( f,r ) );
817    L = sqrFree( F );
818  }
819  #if 0
820  else if (rField_is_GF())
821  {
822    int c=rChar(r);
823    setCharacteristic( c, primepower(c) );
824    CanonicalForm F( convSingGFFactoryGF( f ) );
825    if (F.isUnivariate())
826    {
827      L = factorize( F );
828    }
829    else
830    {
831      goto notImpl;
832    }
833  }
834  #endif
835  else
836  {
837    goto notImpl;
838  }
839  {
840    // convert into ideal
841    int n = L.length();
842    if (n==0) n=1;
843    CFFListIterator J=L;
844    int j=0;
845    res = idInit( n ,1);
846    for ( ; J.hasItem(); J++, j++ )
847    {
848      res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
849    }
850    if (res->m[0]==NULL)
851    {
852      res->m[0]=p_One(r);
853    }
854  }
855  p_Delete(&f,r);
856  errorreported=save_errorreported;
857notImpl:
858  if (res==NULL)
859    WerrorS( feNotImplemented );
860  return res;
861}
862
863
864TODO(somebody, add libfac)
865/*matrix singclap_irrCharSeries ( ideal I, const ring r)
866{
867  if (idIs0(I)) return mpNew(1,1);
868
869  // for now there is only the possibility to handle polynomials over
870  // Q and Fp ...
871  matrix res=NULL;
872  int i;
873  Off(SW_RATIONAL);
874  On(SW_SYMMETRIC_FF);
875  CFList L;
876  ListCFList LL;
877  if (((rChar(r) == 0) || (rChar(r) > 1) )
878  && (rPar(r)==0))
879  {
880    setCharacteristic( rChar(r) );
881    for(i=0;i<IDELEMS(I);i++)
882    {
883      poly p=I->m[i];
884      if (p!=NULL)
885      {
886        p=p_Copy(p,r);
887        p_Cleardenom(p, r);
888        L.append(convSingPFactoryP(p,r));
889      }
890    }
891  }
892  // and over Q(a) / Fp(a)
893  else if (( rChar(r)==1 ) // Q(a)
894  || (rChar(r) <-1))       // Fp(a)
895  {
896    if (rChar(r)==1) setCharacteristic( 0 );
897    else               setCharacteristic( -rChar(r) );
898    for(i=0;i<IDELEMS(I);i++)
899    {
900      poly p=I->m[i];
901      if (p!=NULL)
902      {
903        p=p_Copy(p,r);
904        p_Cleardenom(p, r);
905        L.append(convSingTrPFactoryP(p,r));
906      }
907    }
908  }
909  else
910  {
911    WerrorS( feNotImplemented );
912    return res;
913  }
914
915  // a very bad work-around --- FIX IT in libfac
916  // should be fixed as of 2001/6/27
917  int tries=0;
918  int m,n;
919  ListIterator<CFList> LLi;
920  loop
921  {
922    LL=IrrCharSeries(L);
923    m= LL.length(); // Anzahl Zeilen
924    n=0;
925    for ( LLi = LL; LLi.hasItem(); LLi++ )
926    {
927      n = si_max(LLi.getItem().length(),n);
928    }
929    if ((m!=0) && (n!=0)) break;
930    tries++;
931    if (tries>=5) break;
932  }
933  if ((m==0) || (n==0))
934  {
935    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
936      m,n,IDELEMS(I)+1,LL.length());
937    iiWriteMatrix((matrix)I,"I",2,0);
938    m=si_max(m,1);
939    n=si_max(n,1);
940  }
941  res=mpNew(m,n);
942  CFListIterator Li;
943  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
944  {
945    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
946    {
947      if ( (rChar(r) == 0) || (rChar(r) > 1) )
948        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem(),r);
949      else
950        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem(),r);
951    }
952  }
953  Off(SW_RATIONAL);
954  return res;
955}*/
956
957/*char* singclap_neworder ( ideal I, const ring r)
958{
959  int i;
960  Off(SW_RATIONAL);
961  On(SW_SYMMETRIC_FF);
962  CFList L;
963  if (((rChar(r) == 0) || (rChar(r) > 1) )
964  && (rPar(r)==0))
965  {
966    setCharacteristic( rChar(r) );
967    for(i=0;i<IDELEMS(I);i++)
968    {
969      L.append(convSingPFactoryP(I->m[i],r));
970    }
971  }
972  // and over Q(a) / Fp(a)
973  else if (( rChar(r)==1 ) // Q(a)
974  || (rChar(r) <-1))       // Fp(a)
975  {
976    if (rChar(r)==1) setCharacteristic( 0 );
977    else               setCharacteristic( -rChar(r) );
978    for(i=0;i<IDELEMS(I);i++)
979    {
980      L.append(convSingTrPFactoryP(I->m[i],r));
981    }
982  }
983  else
984  {
985    WerrorS( feNotImplemented );
986    return NULL;
987  }
988
989  List<int> IL=neworderint(L);
990  ListIterator<int> Li;
991  StringSetS("");
992  Li = IL;
993  int offs=rPar(r);
994  int* mark=(int*)omAlloc0((rVar(r)+offs)*sizeof(int));
995  int cnt=rVar(r)+offs;
996  loop
997  {
998    if(! Li.hasItem()) break;
999    BOOLEAN done=TRUE;
1000    i=Li.getItem()-1;
1001    mark[i]=1;
1002    if (i<offs)
1003    {
1004      done=FALSE;
1005      //StringAppendS(r->parameter[i]);
1006    }
1007    else
1008    {
1009      StringAppendS(r->names[i-offs]);
1010    }
1011    Li++;
1012    cnt--;
1013    if(cnt==0) break;
1014    if (done) StringAppendS(",");
1015  }
1016  for(i=0;i<rVar(r)+offs;i++)
1017  {
1018    BOOLEAN done=TRUE;
1019    if(mark[i]==0)
1020    {
1021      if (i<offs)
1022      {
1023        done=FALSE;
1024        //StringAppendS(r->parameter[i]);
1025      }
1026      else
1027      {
1028        StringAppendS(r->names[i-offs]);
1029      }
1030      cnt--;
1031      if(cnt==0) break;
1032      if (done) StringAppendS(",");
1033    }
1034  }
1035  char * s=omStrDup(StringAppendS(""));
1036  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1037  return s;
1038}*/
1039
1040BOOLEAN singclap_isSqrFree(poly f, const ring r)
1041{
1042  BOOLEAN b=FALSE;
1043  CanonicalForm F( convSingPFactoryP( f,r ) );
1044  if((r->cf->type==n_Zp)&&(!F.isUnivariate()))
1045      goto err;
1046  b=(BOOLEAN)isSqrFree(F);
1047  Off(SW_RATIONAL);
1048  return b;
1049err:
1050  WerrorS( feNotImplemented );
1051  return 0;
1052}
1053
1054poly singclap_det( const matrix m, const ring s )
1055{
1056  int r=m->rows();
1057  if (r!=m->cols())
1058  {
1059    Werror("det of %d x %d matrix",r,m->cols());
1060    return NULL;
1061  }
1062  poly res=NULL;
1063  CFMatrix M(r,r);
1064  int i,j;
1065  for(i=r;i>0;i--)
1066  {
1067    for(j=r;j>0;j--)
1068    {
1069      M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1070    }
1071  }
1072  res= convFactoryPSingP( determinant(M,r),s ) ;
1073  Off(SW_RATIONAL);
1074  return res;
1075}
1076
1077int singclap_det_i( intvec * m)
1078{
1079  setCharacteristic( 0 );
1080  CFMatrix M(m->rows(),m->cols());
1081  int i,j;
1082  for(i=m->rows();i>0;i--)
1083  {
1084    for(j=m->cols();j>0;j--)
1085    {
1086      M(i,j)=IMATELEM(*m,i,j);
1087    }
1088  }
1089  int res= convFactoryISingI( determinant(M,m->rows()) ) ;
1090  Off(SW_RATIONAL);
1091  return res;
1092}
1093
1094#ifdef HAVE_NTL
1095#if 0
1096matrix singntl_HNF(matrix  m, const ring s )
1097{
1098  int r=m->rows();
1099  if (r!=m->cols())
1100  {
1101    Werror("HNF of %d x %d matrix",r,m->cols());
1102    return NULL;
1103  }
1104  matrix res=mpNew(r,r);
1105  if (rField_is_Q(s))
1106  {
1107
1108    CFMatrix M(r,r);
1109    int i,j;
1110    for(i=r;i>0;i--)
1111    {
1112      for(j=r;j>0;j--)
1113      {
1114        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
1115      }
1116    }
1117    CFMatrix *MM=cf_HNF(M);
1118    for(i=r;i>0;i--)
1119    {
1120      for(j=r;j>0;j--)
1121      {
1122        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1123      }
1124    }
1125    delete MM;
1126  }
1127  return res;
1128}
1129intvec* singntl_HNF(intvec*  m)
1130{
1131  int r=m->rows();
1132  if (r!=m->cols())
1133  {
1134    Werror("HNF of %d x %d matrix",r,m->cols());
1135    return NULL;
1136  }
1137  setCharacteristic( 0 );
1138  CFMatrix M(r,r);
1139  int i,j;
1140  for(i=r;i>0;i--)
1141  {
1142    for(j=r;j>0;j--)
1143    {
1144      M(i,j)=IMATELEM(*m,i,j);
1145    }
1146  }
1147  CFMatrix *MM=cf_HNF(M);
1148  intvec *mm=ivCopy(m);
1149  for(i=r;i>0;i--)
1150  {
1151    for(j=r;j>0;j--)
1152    {
1153      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1154    }
1155  }
1156  delete MM;
1157  return mm;
1158}
1159matrix singntl_LLL(matrix  m, const ring s )
1160{
1161  int r=m->rows();
1162  int c=m->cols();
1163  matrix res=mpNew(r,c);
1164  if (rField_is_Q(s))
1165  {
1166    CFMatrix M(r,c);
1167    int i,j;
1168    for(i=r;i>0;i--)
1169    {
1170      for(j=c;j>0;j--)
1171      {
1172        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1173      }
1174    }
1175    CFMatrix *MM=cf_LLL(M);
1176    for(i=r;i>0;i--)
1177    {
1178      for(j=c;j>0;j--)
1179      {
1180        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1181      }
1182    }
1183    delete MM;
1184  }
1185  return res;
1186}
1187intvec* singntl_LLL(intvec*  m)
1188{
1189  int r=m->rows();
1190  int c=m->cols();
1191  setCharacteristic( 0 );
1192  CFMatrix M(r,c);
1193  int i,j;
1194  for(i=r;i>0;i--)
1195  {
1196    for(j=r;j>0;j--)
1197    {
1198      M(i,j)=IMATELEM(*m,i,j);
1199    }
1200  }
1201  CFMatrix *MM=cf_LLL(M);
1202  intvec *mm=ivCopy(m);
1203  for(i=r;i>0;i--)
1204  {
1205    for(j=c;j>0;j--)
1206    {
1207      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1208    }
1209  }
1210  delete MM;
1211  return mm;
1212}
1213#endif
1214#endif
1215
1216/*
1217napoly singclap_alglcm ( napoly f, napoly g )
1218{
1219
1220 // over Q(a) / Fp(a)
1221 if (nGetChar()==1) setCharacteristic( 0 );
1222 else               setCharacteristic( -nGetChar() );
1223 napoly res;
1224
1225 if (currRing->minpoly!=NULL)
1226 {
1227   CanonicalForm mipo=convSingPFactoryP(((lnumber)currRing->minpoly)->z,
1228                                         currRing->algring);
1229   Variable a=rootOf(mipo);
1230   CanonicalForm F( convSingAFactoryA( f,a, currRing ) ),
1231                 G( convSingAFactoryA( g,a, currRing ) );
1232   CanonicalForm GCD;
1233
1234   // calculate gcd
1235   GCD = gcd( F, G );
1236
1237   // calculate lcm
1238   res= convFactoryASingA( (F/GCD)*G,currRing );
1239 }
1240 else
1241 {
1242   CanonicalForm F( convSingPFactoryP( f,currRing->algring ) ),
1243                 G( convSingPFactoryP( g,currRing->algring ) );
1244   CanonicalForm GCD;
1245   // calculate gcd
1246   GCD = gcd( F, G );
1247
1248   // calculate lcm
1249   res= convFactoryPSingP( (F/GCD)*G, currRing->algring );
1250 }
1251
1252 Off(SW_RATIONAL);
1253 return res;
1254}
1255
1256void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
1257{
1258 // over Q(a) / Fp(a)
1259 if (nGetChar()==1) setCharacteristic( 0 );
1260 else               setCharacteristic( -nGetChar() );
1261 ff=gg=NULL;
1262 On(SW_RATIONAL);
1263
1264 if (currRing->minpoly!=NULL)
1265 {
1266   CanonicalForm mipo=convSingPFactoryP(((lnumber)currRing->minpoly)->z,
1267                         currRing->algring);
1268   Variable a=rootOf(mipo);
1269   CanonicalForm F( convSingAFactoryA( f,a, currRing ) ),
1270                 G( convSingAFactoryA( g,a, currRing ) );
1271   CanonicalForm GCD;
1272
1273   GCD=gcd( F, G );
1274
1275   if ((GCD!=1) && (GCD!=0))
1276   {
1277     ff= convFactoryASingA( F/ GCD, currRing );
1278     gg= convFactoryASingA( G/ GCD, currRing );
1279   }
1280 }
1281 else
1282 {
1283   CanonicalForm F( convSingPFactoryP( f,currRing->algring ) ),
1284                 G( convSingPFactoryP( g,currRing->algring ) );
1285   CanonicalForm GCD;
1286
1287   GCD=gcd( F, G );
1288
1289   if ((GCD!=1) && (GCD!=0))
1290   {
1291     ff= convFactoryPSingP( F/ GCD, currRing->algring );
1292     gg= convFactoryPSingP( G/ GCD, currRing->algring );
1293   }
1294 }
1295
1296 Off(SW_RATIONAL);
1297}
1298*/
1299
1300#if 0
1301lists singclap_chineseRemainder(lists x, lists q)
1302{
1303  //assume(x->nr == q->nr);
1304  //assume(x->nr >= 0);
1305  int n=x->nr+1;
1306  if ((x->nr<0) || (x->nr!=q->nr))
1307  {
1308    WerrorS("list are empty or not of equal length");
1309    return NULL;
1310  }
1311  lists res=(lists)omAlloc0Bin(slists_bin);
1312  CFArray X(1,n), Q(1,n);
1313  int i;
1314  for(i=0; i<n; i++)
1315  {
1316    if (x->m[i-1].Typ()==INT_CMD)
1317    {
1318      X[i]=(int)x->m[i-1].Data();
1319    }
1320    else if (x->m[i-1].Typ()==NUMBER_CMD)
1321    {
1322      number N=(number)x->m[i-1].Data();
1323      X[i]=convSingNFactoryN(N);
1324    }
1325    else
1326    {
1327      WerrorS("illegal type in chineseRemainder");
1328      omFreeBin(res,slists_bin);
1329      return NULL;
1330    }
1331    if (q->m[i-1].Typ()==INT_CMD)
1332    {
1333      Q[i]=(int)q->m[i-1].Data();
1334    }
1335    else if (q->m[i-1].Typ()==NUMBER_CMD)
1336    {
1337      number N=(number)x->m[i-1].Data();
1338      Q[i]=convSingNFactoryN(N);
1339    }
1340    else
1341    {
1342      WerrorS("illegal type in chineseRemainder");
1343      omFreeBin(res,slists_bin);
1344      return NULL;
1345    }
1346  }
1347  CanonicalForm r, prod;
1348  chineseRemainder( X, Q, r, prod );
1349  res->Init(2);
1350  res->m[0].rtyp=NUMBER_CMD;
1351  res->m[1].rtyp=NUMBER_CMD;
1352  res->m[0].data=(char *)convFactoryNSingN( r );
1353  res->m[1].data=(char *)convFactoryNSingN( prod );
1354  return res;
1355}
1356#endif
1357#endif
1358
1359number   nChineseRemainder(number *x, number *q,int rl, const coeffs r)
1360// elemenst in the array are x[0..(rl-1)], q[0..(rl-1)]
1361{
1362#ifdef HAVE_FACTORY
1363  if (r->type!=n_Q)
1364  { Werror("nChineseRemainder only for integers"); return NULL; }
1365  setCharacteristic( 0 ); // only in char 0
1366  CFArray X(rl), Q(rl);
1367  int i;
1368  for(i=rl-1;i>=0;i--)
1369  {
1370    X[i]=r->convSingNFactoryN(x[i],FALSE,r); // may be larger MAX_INT
1371    Q[i]=r->convSingNFactoryN(q[i],FALSE,r); // may be larger MAX_INT
1372  }
1373  CanonicalForm xnew,qnew;
1374  chineseRemainder(X,Q,xnew,qnew);
1375  number n=r->convFactoryNSingN(xnew,r);
1376  number p=r->convFactoryNSingN(qnew,r);
1377  number p2=n_IntDiv(p,n_Init(2, r),r);
1378  if (n_Greater(n,p2,r))
1379  {
1380     number n2=n_Sub(n,p,r);
1381     n_Delete(&n,r);
1382     n=n2;
1383  }
1384  n_Delete(&p,r);
1385  n_Delete(&p2,r);
1386  return n;
1387#else
1388  WerrorS("not implemented");
1389  return n_Init(0,r);
1390#endif
1391}
Note: See TracBrowser for help on using the repository browser.