Changeset 6e62ce in git


Ignore:
Timestamp:
Jul 23, 2019, 4:16:39 PM (5 years ago)
Author:
Hans Schoenemann <hannes@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
fa1cd304b94fb2782b47874564b731a57670c34c
Parents:
b2359cfe3b7b393982685c8605f2181e5871eeec
Message:
use Flints mpoly for *= and gcd over ZZ/p, QQ, ZZ
Location:
factory
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • factory/FLINTconvert.cc

    rb2359c r6e62ce  
    2424#include "singext.h"
    2525#include "cf_algorithm.h"
     26
     27#ifdef HAVE_OMALLOC
     28#define Alloc(L) omAlloc(L)
     29#define Free(A,L) omFreeSize(A,L)
     30#else
     31#define Alloc(L) malloc(L)
     32#define Free(A,L) free(A)
     33#endif
    2634
    2735#ifdef HAVE_FLINT
     
    5361#include <flint/fq_nmod_mat.h>
    5462#endif
     63#if ( __FLINT_RELEASE >= 20503)
     64#include <flint/fmpq_mpoly.h>
     65#endif
    5566#ifdef __cplusplus
    5667}
     
    152163  if (f.isImm ())
    153164  {
    154     fmpz_set_si (fmpq_numref (result), f.num().intval());
    155     fmpz_set_si (fmpq_denref (result), f.den().intval());
    156   }
    157   else
     165    fmpz_set_si (fmpq_numref (result), f.intval());
     166    fmpz_set_si (fmpq_denref (result), 1);
     167  }
     168  else if(f.inQ())
    158169  {
    159170    mpz_t gmp_val;
     
    165176    mpz_clear (gmp_val);
    166177  }
     178  else if(f.inZ())
     179  {
     180    mpz_t gmp_val;
     181    f.mpzval(gmp_val);
     182    fmpz_set_mpz (fmpq_numref (result), gmp_val);
     183    mpz_clear (gmp_val);
     184    fmpz_set_si (fmpq_denref (result), 1);
     185  }
     186  else
     187  {
     188    printf("wrong type\n");
     189  }
    167190}
    168191
     
    181204
    182205  CanonicalForm result;
    183   if (mpz_is_imm (nnum) && mpz_is_imm (nden))
    184   {
    185     num= CanonicalForm (mpz_get_si(nnum));
    186     den= CanonicalForm (mpz_get_si(nden));
    187     mpz_clear (nnum);
    188     mpz_clear (nden);
    189     result= num/den;
    190     if (!isRat)
    191       Off (SW_RATIONAL);
    192     return result;
     206  if (mpz_is_imm (nden))
     207  {
     208    if (mpz_is_imm(nnum))
     209    {
     210      num= CanonicalForm (mpz_get_si(nnum));
     211      den= CanonicalForm (mpz_get_si(nden));
     212      mpz_clear (nnum);
     213      mpz_clear (nden);
     214      result= num/den;
     215    }
     216    else if (mpz_cmp_si(nden,1)==0)
     217    {
     218      result= make_cf(nnum);
     219      mpz_clear (nden);
     220    }
     221    else
     222      result= make_cf (nnum, nden, false);
    193223  }
    194224  else
    195225  {
    196226    result= make_cf (nnum, nden, false);
    197     if (!isRat)
    198       Off (SW_RATIONAL);
    199     return result;
    200   }
     227  }
     228  if (!isRat)
     229    Off (SW_RATIONAL);
     230  return result;
    201231}
    202232
     
    528558}
    529559#endif
    530 
    531 #endif
    532 
    533 
     560#if __FLINT_RELEASE >= 20503
     561static void convFlint_RecPP ( const CanonicalForm & f, ulong * exp, nmod_mpoly_t result, nmod_mpoly_ctx_t ctx, int N )
     562{
     563  // assume f!=0
     564  if ( ! f.inCoeffDomain() )
     565  {
     566    int l = f.level();
     567    for ( CFIterator i = f; i.hasTerms(); i++ )
     568    {
     569      exp[N-l] = i.exp();
     570      convFlint_RecPP( i.coeff(), exp, result, ctx, N );
     571    }
     572    exp[N-l] = 0;
     573  }
     574  else
     575  {
     576    int c=f.intval();
     577    if (c<0) c+=getCharacteristic();
     578    nmod_mpoly_push_term_ui_ui(result,c,exp,ctx);
     579  }
     580}
     581
     582static void convFlint_RecPP ( const CanonicalForm & f, ulong * exp, fmpq_mpoly_t result, fmpq_mpoly_ctx_t ctx, int N )
     583{
     584  // assume f!=0
     585  if ( ! f.inBaseDomain() )
     586  {
     587    int l = f.level();
     588    for ( CFIterator i = f; i.hasTerms(); i++ )
     589    {
     590      exp[N-l] = i.exp();
     591      convFlint_RecPP( i.coeff(), exp, result, ctx, N );
     592    }
     593    exp[N-l] = 0;
     594  }
     595  else
     596  {
     597    fmpq_t c;
     598    fmpq_init(c);
     599    convertCF2Fmpq(c,f);
     600    fmpq_mpoly_push_term_fmpq_ui(result,c,exp,ctx);
     601    fmpq_clear(c);
     602  }
     603}
     604
     605void convFactoryPFlintMP ( const CanonicalForm & f, nmod_mpoly_t res, nmod_mpoly_ctx_t ctx, int N )
     606{
     607  if (f.isZero()) return;
     608  ulong * exp = (ulong*)Alloc(N*sizeof(ulong));
     609  memset(exp,0,N*sizeof(ulong));
     610  convFlint_RecPP( f, exp, res, ctx, N );
     611  Free(exp,N*sizeof(ulong));
     612}
     613
     614void convFactoryPFlintMP ( const CanonicalForm & f, fmpq_mpoly_t res, fmpq_mpoly_ctx_t ctx, int N )
     615{
     616  if (f.isZero()) return;
     617  ulong * exp = (ulong*)Alloc(N*sizeof(ulong));
     618  memset(exp,0,N*sizeof(ulong));
     619  convFlint_RecPP( f, exp, res, ctx, N );
     620  Free(exp,N*sizeof(ulong));
     621}
     622
     623CanonicalForm convFlintMPFactoryP(nmod_mpoly_t f, nmod_mpoly_ctx_t ctx, int N)
     624{
     625  CanonicalForm result;
     626  int d=nmod_mpoly_length(f,ctx)-1;
     627  ulong* exp=(ulong*)Alloc(N*sizeof(ulong));
     628  for(int i=d; i>=0; i--)
     629  {
     630    ulong c=nmod_mpoly_get_term_coeff_ui(f,i,ctx);
     631    nmod_mpoly_get_term_exp_ui(exp,f,i,ctx);
     632    CanonicalForm term=(int)c;
     633    for ( int i = 0; i <N; i++ )
     634    {
     635      if (exp[i]!=0) term*=CanonicalForm( Variable( N-i ), exp[i] );
     636    }
     637    result+=term;
     638  }
     639  Free(exp,N*sizeof(ulong));
     640  return result;
     641}
     642
     643CanonicalForm convFlintMPFactoryP(fmpq_mpoly_t f, fmpq_mpoly_ctx_t ctx, int N)
     644{
     645  CanonicalForm result;
     646  int d=fmpq_mpoly_length(f,ctx)-1;
     647  ulong* exp=(ulong*)Alloc(N*sizeof(ulong));
     648  fmpq_t c;
     649  fmpq_init(c);
     650  for(int i=d; i>=0; i--)
     651  {
     652    fmpq_mpoly_get_term_coeff_fmpq(c,f,i,ctx);
     653    fmpq_mpoly_get_term_exp_ui(exp,f,i,ctx);
     654    CanonicalForm term=convertFmpq_t2CF(c);
     655    for ( int i = 0; i <N; i++ )
     656    {
     657      if (exp[i]!=0) term*=CanonicalForm( Variable( N-i ), exp[i] );
     658    }
     659    result+=term;
     660  }
     661  fmpq_clear(c);
     662  Free(exp,N*sizeof(ulong));
     663  return result;
     664}
     665
     666// stolen from:
     667// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
     668static inline int SI_LOG2(int v)
     669{
     670  const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
     671  const unsigned int S[] = {1, 2, 4, 8, 16};
     672
     673  unsigned int r = 0; // result of log2(v) will go here
     674  if (v & b[4]) { v >>= S[4]; r |= S[4]; }
     675  if (v & b[3]) { v >>= S[3]; r |= S[3]; }
     676  if (v & b[2]) { v >>= S[2]; r |= S[2]; }
     677  if (v & b[1]) { v >>= S[1]; r |= S[1]; }
     678  if (v & b[0]) { v >>= S[0]; r |= S[0]; }
     679  return (int)r;
     680}
     681
     682CanonicalForm mulFlintMP_Zp(const CanonicalForm& F,int lF, const CanonicalForm& G, int lG,int m)
     683{
     684  int bits=SI_LOG2(m)+1;
     685  int N=F.level();
     686  nmod_mpoly_ctx_t ctx;
     687  nmod_mpoly_ctx_init(ctx,N,ORD_LEX,getCharacteristic());
     688  nmod_mpoly_t f,g,res;
     689  nmod_mpoly_init3(f,lF,bits,ctx);
     690  nmod_mpoly_init3(g,lG,bits,ctx);
     691  convFactoryPFlintMP(F,f,ctx,N);
     692  convFactoryPFlintMP(G,g,ctx,N);
     693  nmod_mpoly_init3(res,lF+lG,bits+1,ctx);
     694  nmod_mpoly_mul(res,f,g,ctx);
     695  nmod_mpoly_clear(g,ctx);
     696  nmod_mpoly_clear(f,ctx);
     697  CanonicalForm RES=convFlintMPFactoryP(res,ctx,N);
     698  nmod_mpoly_clear(res,ctx);
     699  nmod_mpoly_ctx_clear(ctx);
     700  return RES;
     701}
     702
     703CanonicalForm mulFlintMP_QQ(const CanonicalForm& F,int lF, const CanonicalForm& G, int lG, int m)
     704{
     705  int bits=SI_LOG2(m)+1;
     706  int N=F.level();
     707  fmpq_mpoly_ctx_t ctx;
     708  fmpq_mpoly_ctx_init(ctx,N,ORD_LEX);
     709  fmpq_mpoly_t f,g,res;
     710  fmpq_mpoly_init3(f,lF,bits,ctx);
     711  fmpq_mpoly_init3(g,lG,bits,ctx);
     712  convFactoryPFlintMP(F,f,ctx,N);
     713  convFactoryPFlintMP(G,g,ctx,N);
     714  fmpq_mpoly_init3(res,lF+lG,bits+1,ctx);
     715  fmpq_mpoly_mul(res,f,g,ctx);
     716  fmpq_mpoly_clear(g,ctx);
     717  fmpq_mpoly_clear(f,ctx);
     718  CanonicalForm RES=convFlintMPFactoryP(res,ctx,N);
     719  fmpq_mpoly_clear(res,ctx);
     720  fmpq_mpoly_ctx_clear(ctx);
     721  return RES;
     722}
     723
     724CanonicalForm gcdFlintMP_Zp(const CanonicalForm& F, const CanonicalForm& G)
     725{
     726  int N=F.level();
     727  int lf,lg,m=1<<MPOLY_MIN_BITS;
     728  lf=size_maxexp(F,m);
     729  lg=size_maxexp(G,m);
     730  int bits=SI_LOG2(m)+1;
     731  nmod_mpoly_ctx_t ctx;
     732  nmod_mpoly_ctx_init(ctx,N,ORD_LEX,getCharacteristic());
     733  nmod_mpoly_t f,g,res;
     734  nmod_mpoly_init3(f,lf,bits,ctx);
     735  nmod_mpoly_init3(g,lg,bits,ctx);
     736  convFactoryPFlintMP(F,f,ctx,N);
     737  convFactoryPFlintMP(G,g,ctx,N);
     738  nmod_mpoly_init3(res,lf,bits,ctx);
     739  int ok=nmod_mpoly_gcd(res,f,g,ctx);
     740  nmod_mpoly_clear(g,ctx);
     741  nmod_mpoly_clear(f,ctx);
     742  CanonicalForm RES=1;
     743  if (ok)
     744  {
     745    RES=convFlintMPFactoryP(res,ctx,N);
     746  }
     747  nmod_mpoly_clear(res,ctx);
     748  nmod_mpoly_ctx_clear(ctx);
     749  return RES;
     750}
     751
     752CanonicalForm gcdFlintMP_QQ(const CanonicalForm& F, const CanonicalForm& G)
     753{
     754  int N=F.level();
     755  fmpq_mpoly_ctx_t ctx;
     756  fmpq_mpoly_ctx_init(ctx,N,ORD_LEX);
     757  fmpq_mpoly_t f,g,res;
     758  fmpq_mpoly_init(f,ctx);
     759  fmpq_mpoly_init(g,ctx);
     760  convFactoryPFlintMP(F,f,ctx,N);
     761  convFactoryPFlintMP(G,g,ctx,N);
     762  fmpq_mpoly_init(res,ctx);
     763  int ok=fmpq_mpoly_gcd(res,f,g,ctx);
     764  fmpq_mpoly_clear(g,ctx);
     765  fmpq_mpoly_clear(f,ctx);
     766  CanonicalForm RES=1;
     767  if (ok)
     768  {
     769    // Flint normalizes the gcd to be monic.
     770    // Singular wants a gcd defined over ZZ that is primitive and has a positive leading coeff.
     771    if (!fmpq_mpoly_is_zero(res, ctx))
     772    {
     773      fmpq_t content;
     774      fmpq_init(content);
     775      fmpq_mpoly_content(content, res, ctx);
     776      fmpq_mpoly_scalar_div_fmpq(res, res, content, ctx);
     777      fmpq_clear(content);
     778    }
     779    RES=convFlintMPFactoryP(res,ctx,N);
     780  }
     781  fmpq_mpoly_clear(res,ctx);
     782  fmpq_mpoly_ctx_clear(ctx);
     783  return RES;
     784}
     785
     786#endif
     787
     788#endif
     789
     790
  • factory/FLINTconvert.h

    rb2359c r6e62ce  
    250250
    251251
    252 #endif
    253 #endif
     252#if __FLINT_RELEASE >= 20503
     253CanonicalForm mulFlintMP_Zp(const CanonicalForm& F,int lF, const CanonicalForm& Gi, int lG, int m);
     254CanonicalForm mulFlintMP_QQ(const CanonicalForm& F,int lF, const CanonicalForm& Gi, int lG, int m);
     255CanonicalForm gcdFlintMP_Zp(const CanonicalForm& F, const CanonicalForm& G);
     256CanonicalForm gcdFlintMP_QQ(const CanonicalForm& F, const CanonicalForm& G);
     257#endif
     258#endif
     259#endif
  • factory/NTLconvert.cc

    rb2359c r6e62ce  
    3333#include "NTLconvert.h"
    3434
     35#ifdef HAVE_OMALLOC
     36#define Alloc(L) omAlloc(L)
     37#define Free(A,L) omFreeSize(A,L)
     38#else
    3539#define Alloc(L) malloc(L)
    3640#define Free(A,L) free(A)
     41#endif
    3742
    3843void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
  • factory/canonicalform.cc

    rb2359c r6e62ce  
    1717#include "gfops.h"
    1818#include "facMul.h"
     19#include "facAlgFuncUtil.h"
    1920#include "FLINTconvert.h"
    2021
     
    707708    else  if ( value->level() == cf.value->level() ) {
    708709#if (HAVE_NTL && HAVE_FLINT && __FLINT_RELEASE >= 20400)
     710#if (__FLINT_RELEASE >= 20503)
     711        int l_this,l_cf,m=1;
     712        if ((getCharacteristic()>0)
     713        && (CFFactory::gettype() != GaloisFieldDomain)
     714        &&(!hasAlgVar(*this))
     715        &&(!hasAlgVar(cf))
     716        &&((l_cf=size_maxexp(cf,m))>10)
     717        &&((l_this=size_maxexp(*this,m))>10)
     718        )
     719        {
     720          *this=mulFlintMP_Zp(*this,l_this,cf,l_cf,m);
     721        }
     722        else
     723        /*-----------------------------------------------------*/
     724        if ((getCharacteristic()==0)
     725        &&(!hasAlgVar(*this))
     726        &&(!hasAlgVar(cf))
     727        &&((l_cf=size_maxexp(cf,m))>10)
     728        &&((l_this=size_maxexp(*this,m))>10)
     729        )
     730        {
     731          *this=mulFlintMP_QQ(*this,l_this,cf,l_cf,m);
     732        }
     733        else
     734#endif
     735
    709736        if (value->levelcoeff() == cf.value->levelcoeff() && cf.isUnivariate() && (*this).isUnivariate())
    710737        {
  • factory/cf_gcd.cc

    rb2359c r6e62ce  
    2626#include "cfSubResGcd.h"
    2727#include "cfModGcd.h"
     28#include "FLINTconvert.h"
    2829#include "facAlgFuncUtil.h"
    2930
     
    100101  if ( getCharacteristic() != 0 )
    101102  {
     103    #if defined(HAVE_FLINT) && ( __FLINT_RELEASE >= 20503)
     104    if ( isOn( SW_USE_FL_GCD_P)
     105    && (CFFactory::gettype() != GaloisFieldDomain)
     106    && (getCharacteristic()>500)
     107    &&(!hasAlgVar(fc)) && (!hasAlgVar(gc)))
     108    {
     109      return gcdFlintMP_Zp(fc,gc);
     110    }
     111    #endif
    102112    #ifdef HAVE_NTL
    103113    if ((!fc_and_gc_Univariate) && (isOn( SW_USE_EZGCD_P )))
     
    119129    fc = subResGCD_p( fc, gc );
    120130  }
    121   else if (!fc_and_gc_Univariate)
     131  else if (!fc_and_gc_Univariate) /* && char==0*/
    122132  {
     133    #if defined(HAVE_FLINT) && ( __FLINT_RELEASE >= 20503)
     134    if (( isOn( SW_USE_FL_GCD_0) )
     135    &&(!hasAlgVar(fc)) && (!hasAlgVar(gc)))
     136    {
     137      return gcdFlintMP_QQ(fc,gc);
     138    }
     139    else
     140    #endif
    123141    if ( isOn( SW_USE_EZGCD ) )
    124142      fc= ezgcd (fc, gc);
    125 #ifdef HAVE_NTL
     143    #ifdef HAVE_NTL
    126144    else if (isOn(SW_USE_CHINREM_GCD))
    127145      fc = modGCDZ( fc, gc);
    128 #endif
     146    #endif
    129147    else
    130148    {
Note: See TracChangeset for help on using the changeset viewer.