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

spielwiese
Last change on this file since 5348866 was 5348866, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
FIX: guarding all libfac_* variables with HAVE_LIBFAC
  • Property mode set to 100644
File size: 29.8 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,r);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# ifdef HAVE_LIBFAC
387  extern 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/*
965char* singclap_neworder ( ideal I, const ring r)
966{
967  int i;
968  Off(SW_RATIONAL);
969  On(SW_SYMMETRIC_FF);
970  CFList L;
971  if (((rChar(r) == 0) || (rChar(r) > 1) )
972  && (rPar(r)==0))
973  {
974    setCharacteristic( rChar(r) );
975    for(i=0;i<IDELEMS(I);i++)
976    {
977      L.append(convSingPFactoryP(I->m[i],r));
978    }
979  }
980  // and over Q(a) / Fp(a)
981  else if (( rChar(r)==1 ) // Q(a)
982  || (rChar(r) <-1))       // Fp(a)
983  {
984    if (rChar(r)==1) setCharacteristic( 0 );
985    else               setCharacteristic( -rChar(r) );
986    for(i=0;i<IDELEMS(I);i++)
987    {
988      L.append(convSingTrPFactoryP(I->m[i],r));
989    }
990  }
991  else
992  {
993    WerrorS( feNotImplemented );
994    return NULL;
995  }
996
997  List<int> IL=neworderint(L);
998  ListIterator<int> Li;
999  StringSetS("");
1000  Li = IL;
1001  int offs=rPar(r);
1002  int* mark=(int*)omAlloc0((rVar(r)+offs)*sizeof(int));
1003  int cnt=rVar(r)+offs;
1004  loop
1005  {
1006    if(! Li.hasItem()) break;
1007    BOOLEAN done=TRUE;
1008    i=Li.getItem()-1;
1009    mark[i]=1;
1010    if (i<offs)
1011    {
1012      done=FALSE;
1013      //StringAppendS(r->parameter[i]);
1014    }
1015    else
1016    {
1017      StringAppendS(r->names[i-offs]);
1018    }
1019    Li++;
1020    cnt--;
1021    if(cnt==0) break;
1022    if (done) StringAppendS(",");
1023  }
1024  for(i=0;i<rVar(r)+offs;i++)
1025  {
1026    BOOLEAN done=TRUE;
1027    if(mark[i]==0)
1028    {
1029      if (i<offs)
1030      {
1031        done=FALSE;
1032        //StringAppendS(r->parameter[i]);
1033      }
1034      else
1035      {
1036        StringAppendS(r->names[i-offs]);
1037      }
1038      cnt--;
1039      if(cnt==0) break;
1040      if (done) StringAppendS(",");
1041    }
1042  }
1043  char * s=omStrDup(StringAppendS(""));
1044  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1045  return s;
1046}*/
1047
1048BOOLEAN singclap_isSqrFree(poly f, const ring r)
1049{
1050  BOOLEAN b=FALSE;
1051  CanonicalForm F( convSingPFactoryP( f,r ) );
1052  if((r->cf->type==n_Zp)&&(!F.isUnivariate()))
1053      goto err;
1054  b=(BOOLEAN)isSqrFree(F);
1055  Off(SW_RATIONAL);
1056  return b;
1057err:
1058  WerrorS( feNotImplemented );
1059  return 0;
1060}
1061
1062poly singclap_det( const matrix m, const ring s )
1063{
1064  int r=m->rows();
1065  if (r!=m->cols())
1066  {
1067    Werror("det of %d x %d matrix",r,m->cols());
1068    return NULL;
1069  }
1070  poly res=NULL;
1071  CFMatrix M(r,r);
1072  int i,j;
1073  for(i=r;i>0;i--)
1074  {
1075    for(j=r;j>0;j--)
1076    {
1077      M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1078    }
1079  }
1080  res= convFactoryPSingP( determinant(M,r),s ) ;
1081  Off(SW_RATIONAL);
1082  return res;
1083}
1084
1085int singclap_det_i( intvec * m, const ring r)
1086{
1087//  assume( r == currRing ); // Anything else is not guaranted to work!
1088   
1089  setCharacteristic( 0 ); // ?
1090  CFMatrix M(m->rows(),m->cols());
1091  int i,j;
1092  for(i=m->rows();i>0;i--)
1093  {
1094    for(j=m->cols();j>0;j--)
1095    {
1096      M(i,j)=IMATELEM(*m,i,j);
1097    }
1098  }
1099  int res= convFactoryISingI( determinant(M,m->rows()) ) ;
1100  Off(SW_RATIONAL); // ?
1101  return res;
1102}
1103
1104#ifdef HAVE_NTL
1105#if 1
1106matrix singntl_HNF(matrix  m, const ring s )
1107{
1108  int r=m->rows();
1109  if (r!=m->cols())
1110  {
1111    Werror("HNF of %d x %d matrix",r,m->cols());
1112    return NULL;
1113  }
1114   
1115  matrix res=mp_New(r,r);
1116   
1117  if (rField_is_Q(s))
1118  {
1119
1120    CFMatrix M(r,r);
1121    int i,j;
1122    for(i=r;i>0;i--)
1123    {
1124      for(j=r;j>0;j--)
1125      {
1126        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
1127      }
1128    }
1129    CFMatrix *MM=cf_HNF(M);
1130    for(i=r;i>0;i--)
1131    {
1132      for(j=r;j>0;j--)
1133      {
1134        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1135      }
1136    }
1137    delete MM;
1138  }
1139  return res;
1140}
1141
1142intvec* singntl_HNF(intvec*  m, const ring)
1143{
1144  int r=m->rows();
1145  if (r!=m->cols())
1146  {
1147    Werror("HNF of %d x %d matrix",r,m->cols());
1148    return NULL;
1149  }
1150  setCharacteristic( 0 );
1151  CFMatrix M(r,r);
1152  int i,j;
1153  for(i=r;i>0;i--)
1154  {
1155    for(j=r;j>0;j--)
1156    {
1157      M(i,j)=IMATELEM(*m,i,j);
1158    }
1159  }
1160  CFMatrix *MM=cf_HNF(M);
1161  intvec *mm=ivCopy(m);
1162  for(i=r;i>0;i--)
1163  {
1164    for(j=r;j>0;j--)
1165    {
1166      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1167    }
1168  }
1169  delete MM;
1170  return mm;
1171}
1172
1173matrix singntl_LLL(matrix  m, const ring s )
1174{
1175  int r=m->rows();
1176  int c=m->cols();
1177  matrix res=mp_New(r,c);
1178  if (rField_is_Q(s))
1179  {
1180    CFMatrix M(r,c);
1181    int i,j;
1182    for(i=r;i>0;i--)
1183    {
1184      for(j=c;j>0;j--)
1185      {
1186        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1187      }
1188    }
1189    CFMatrix *MM=cf_LLL(M);
1190    for(i=r;i>0;i--)
1191    {
1192      for(j=c;j>0;j--)
1193      {
1194        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1195      }
1196    }
1197    delete MM;
1198  }
1199  return res;
1200}
1201
1202intvec* singntl_LLL(intvec*  m, const ring)
1203{
1204  int r=m->rows();
1205  int c=m->cols();
1206  setCharacteristic( 0 );
1207  CFMatrix M(r,c);
1208  int i,j;
1209  for(i=r;i>0;i--)
1210  {
1211    for(j=r;j>0;j--)
1212    {
1213      M(i,j)=IMATELEM(*m,i,j);
1214    }
1215  }
1216  CFMatrix *MM=cf_LLL(M);
1217  intvec *mm=ivCopy(m);
1218  for(i=r;i>0;i--)
1219  {
1220    for(j=c;j>0;j--)
1221    {
1222      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1223    }
1224  }
1225  delete MM;
1226  return mm;
1227}
1228#endif
1229#endif
1230
1231/*
1232napoly singclap_alglcm ( napoly f, napoly g )
1233{
1234
1235 // over Q(a) / Fp(a)
1236 if (nGetChar()==1) setCharacteristic( 0 );
1237 else               setCharacteristic( -nGetChar() );
1238 napoly res;
1239
1240 if (currRing->minpoly!=NULL)
1241 {
1242   CanonicalForm mipo=convSingPFactoryP(((lnumber)currRing->minpoly)->z,
1243                                         currRing->extRing);
1244   Variable a=rootOf(mipo);
1245   CanonicalForm F( convSingAFactoryA( f,a, currRing ) ),
1246                 G( convSingAFactoryA( g,a, currRing ) );
1247   CanonicalForm GCD;
1248
1249   // calculate gcd
1250   GCD = gcd( F, G );
1251
1252   // calculate lcm
1253   res= convFactoryASingA( (F/GCD)*G,currRing );
1254 }
1255 else
1256 {
1257   CanonicalForm F( convSingPFactoryP( f,currRing->extRing ) ),
1258                 G( convSingPFactoryP( g,currRing->extRing ) );
1259   CanonicalForm GCD;
1260   // calculate gcd
1261   GCD = gcd( F, G );
1262
1263   // calculate lcm
1264   res= convFactoryPSingP( (F/GCD)*G, currRing->extRing );
1265 }
1266
1267 Off(SW_RATIONAL);
1268 return res;
1269}
1270
1271void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
1272{
1273 // over Q(a) / Fp(a)
1274 if (nGetChar()==1) setCharacteristic( 0 );
1275 else               setCharacteristic( -nGetChar() );
1276 ff=gg=NULL;
1277 On(SW_RATIONAL);
1278
1279 if (currRing->minpoly!=NULL)
1280 {
1281   CanonicalForm mipo=convSingPFactoryP(((lnumber)currRing->minpoly)->z,
1282                         currRing->extRing);
1283   Variable a=rootOf(mipo);
1284   CanonicalForm F( convSingAFactoryA( f,a, currRing ) ),
1285                 G( convSingAFactoryA( g,a, currRing ) );
1286   CanonicalForm GCD;
1287
1288   GCD=gcd( F, G );
1289
1290   if ((GCD!=1) && (GCD!=0))
1291   {
1292     ff= convFactoryASingA( F/ GCD, currRing );
1293     gg= convFactoryASingA( G/ GCD, currRing );
1294   }
1295 }
1296 else
1297 {
1298   CanonicalForm F( convSingPFactoryP( f,currRing->extRing ) ),
1299                 G( convSingPFactoryP( g,currRing->extRing ) );
1300   CanonicalForm GCD;
1301
1302   GCD=gcd( F, G );
1303
1304   if ((GCD!=1) && (GCD!=0))
1305   {
1306     ff= convFactoryPSingP( F/ GCD, currRing->extRing );
1307     gg= convFactoryPSingP( G/ GCD, currRing->extRing );
1308   }
1309 }
1310
1311 Off(SW_RATIONAL);
1312}
1313*/
1314
1315#if 0
1316lists singclap_chineseRemainder(lists x, lists q)
1317{
1318  //assume(x->nr == q->nr);
1319  //assume(x->nr >= 0);
1320  int n=x->nr+1;
1321  if ((x->nr<0) || (x->nr!=q->nr))
1322  {
1323    WerrorS("list are empty or not of equal length");
1324    return NULL;
1325  }
1326  lists res=(lists)omAlloc0Bin(slists_bin);
1327  CFArray X(1,n), Q(1,n);
1328  int i;
1329  for(i=0; i<n; i++)
1330  {
1331    if (x->m[i-1].Typ()==INT_CMD)
1332    {
1333      X[i]=(int)x->m[i-1].Data();
1334    }
1335    else if (x->m[i-1].Typ()==NUMBER_CMD)
1336    {
1337      number N=(number)x->m[i-1].Data();
1338      X[i]=convSingNFactoryN(N);
1339    }
1340    else
1341    {
1342      WerrorS("illegal type in chineseRemainder");
1343      omFreeBin(res,slists_bin);
1344      return NULL;
1345    }
1346    if (q->m[i-1].Typ()==INT_CMD)
1347    {
1348      Q[i]=(int)q->m[i-1].Data();
1349    }
1350    else if (q->m[i-1].Typ()==NUMBER_CMD)
1351    {
1352      number N=(number)x->m[i-1].Data();
1353      Q[i]=convSingNFactoryN(N);
1354    }
1355    else
1356    {
1357      WerrorS("illegal type in chineseRemainder");
1358      omFreeBin(res,slists_bin);
1359      return NULL;
1360    }
1361  }
1362  CanonicalForm r, prod;
1363  chineseRemainder( X, Q, r, prod );
1364  res->Init(2);
1365  res->m[0].rtyp=NUMBER_CMD;
1366  res->m[1].rtyp=NUMBER_CMD;
1367  res->m[0].data=(char *)convFactoryNSingN( r );
1368  res->m[1].data=(char *)convFactoryNSingN( prod );
1369  return res;
1370}
1371#endif
1372
1373number   nChineseRemainder(number *x, number *q,int rl, const coeffs r)
1374// elemenst in the array are x[0..(rl-1)], q[0..(rl-1)]
1375{
1376#ifdef HAVE_FACTORY
1377  if (r->type!=n_Q)
1378  { Werror("nChineseRemainder only for integers"); return NULL; }
1379  setCharacteristic( 0 ); // only in char 0
1380  CFArray X(rl), Q(rl);
1381  int i;
1382  for(i=rl-1;i>=0;i--)
1383  {
1384    X[i]=r->convSingNFactoryN(x[i],FALSE,r); // may be larger MAX_INT
1385    Q[i]=r->convSingNFactoryN(q[i],FALSE,r); // may be larger MAX_INT
1386  }
1387  CanonicalForm xnew,qnew;
1388  chineseRemainder(X,Q,xnew,qnew);
1389  number n=r->convFactoryNSingN(xnew,r);
1390  number p=r->convFactoryNSingN(qnew,r);
1391  number p2=n_IntDiv(p,n_Init(2, r),r);
1392  if (n_Greater(n,p2,r))
1393  {
1394     number n2=n_Sub(n,p,r);
1395     n_Delete(&n,r);
1396     n=n2;
1397  }
1398  n_Delete(&p,r);
1399  n_Delete(&p2,r);
1400  return n;
1401#else
1402  WerrorS("not implemented");
1403  return n_Init(0,r);
1404#endif
1405}
Note: See TracBrowser for help on using the repository browser.