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

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