source: git/libpolys/polys/clapsing.cc @ 1f414c8

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