/* $Id: NTLconvert.cc,v 1.24 2008-06-30 09:31:21 Singular Exp $ */ #include #ifdef HAVE_SINGULAR #ifndef OM_NDEBUG #define OM_NDEBUG #endif #endif #include "cf_gmp.h" #include "assert.h" #include "cf_defs.h" #include "canonicalform.h" #include "cf_iter.h" #include "fac_berlekamp.h" #include "fac_cantzass.h" #include "fac_univar.h" #include "fac_multivar.h" #include "fac_sqrfree.h" #include "cf_algorithm.h" #ifdef HAVE_NTL #include #include #include #include #include #include #include #include #include #include #include "int_int.h" #include #include "NTLconvert.h" #ifdef HAVE_OMALLOC #define Alloc(L) omAlloc(L) #define Free(A,L) omFreeSize(A,L) #elif defined(USE_MEMUTIL) #include "memutil.h" #define Alloc(L) getBlock(L) #define Free(A,L) freeBlock(A,L) #else #define Alloc(L) malloc(L) #define Free(A,L) free(A) #endif void out_cf(char *s1,const CanonicalForm &f,char *s2); int fac_NTL_char=-1; // the current characterstic for NTL calls // -1: undefined #ifdef NTL_CLIENT // in : using of name space NTL NTL_CLIENT #endif //////////////////////////////////////////////////////////////////////////////// // NAME: convertFacCF2NTLZZpX // // // // DESCRIPTION: // // Conversion routine for Factory-type canonicalform into ZZpX of NTL, // // i.e. polynomials over F_p. As a precondition for correct execution, // // the characteristic has to a a prime number. // // // // INPUT: A canonicalform f // // OUTPUT: The converted NTL-polynomial over F_p of type ZZpX // //////////////////////////////////////////////////////////////////////////////// #if 0 void out_cf(char *s1,const CanonicalForm &f,char *s2) { printf("%s",s1); if (f.isZero()) printf("+0"); else if (! f.inCoeffDomain() ) { int l = f.level(); for ( CFIterator i = f; i.hasTerms(); i++ ) { int e=i.exp(); printf("+(");out_cf("+(",i.coeff(),")*v(");printf("%d)^%d",l,e); } } else { if ( f.isImm() ) { printf("+%d(",f.intval()); } else printf("+...("); if (f.inZ()) printf("Z)"); else if (f.inQ()) printf("Q)"); else if (f.inFF()) printf("FF)"); else if (f.inPP()) printf("PP)"); else if (f.inGF()) printf("PP)"); else if (f.inExtension()) printf("E(%d))",f.level()); } printf("%s",s2); } #endif ZZ_pX convertFacCF2NTLZZpX(CanonicalForm f) { ZZ_pX ntl_poly; CFIterator i; i=f; int j=0; int NTLcurrentExp=i.exp(); int largestExp=i.exp(); int k; // we now build up the NTL-polynomial ntl_poly.SetMaxLength(largestExp+1); for (;i.hasTerms();i++) { for (k=NTLcurrentExp;k>i.exp();k--) { SetCoeff(ntl_poly,k,0); } NTLcurrentExp=i.exp(); CanonicalForm c=i.coeff(); if (!c.isImm()) c=c.mapinto(); //c%= getCharacteristic(); if (!c.isImm()) { //This case will never happen if the characteristic is in fact a prime // number, since all coefficients are represented as immediates #ifndef NOSTREAMIO cout<<"convertFacCF2NTLZZ_pX: coefficient not immediate! : "<=0;k--) { SetCoeff(ntl_poly,k,0); } //normalize the polynomial and return it ntl_poly.normalize(); return ntl_poly; } zz_pX convertFacCF2NTLzzpX(CanonicalForm f) { zz_pX ntl_poly; CFIterator i; i=f; int j=0; int NTLcurrentExp=i.exp(); int largestExp=i.exp(); int k; // we now build up the NTL-polynomial ntl_poly.SetMaxLength(largestExp+1); for (;i.hasTerms();i++) { for (k=NTLcurrentExp;k>i.exp();k--) { SetCoeff(ntl_poly,k,0); } NTLcurrentExp=i.exp(); CanonicalForm c=i.coeff(); if (!c.isImm()) c.mapinto(); //c%= getCharacteristic(); if (!c.isImm()) { //This case will never happen if the characteristic is in fact a prime // number, since all coefficients are represented as immediates #ifndef NOSTREAMIO cout<<"convertFacCF2NTLzz_pX: coefficient not immediate! : "<=0;k--) { SetCoeff(ntl_poly,k,0); } //normalize the polynomial and return it ntl_poly.normalize(); return ntl_poly; } //////////////////////////////////////////////////////////////////////////////// // NAME: convertFacCF2NTLGF2X // // // // DESCRIPTION: // // Conversion routine for Factory-type canonicalform into GF2X of NTL, // // i.e. polynomials over F_2. As precondition for correct execution, // // the characteristic must equal two. // // This is a special case of the more general conversion routine for // // canonicalform to ZZpX. It is included because NTL provides additional // // support and faster algorithms over F_2, moreover the conversion code // // can be optimized, because certain steps are either completely obsolent // // (like normalizing the polynomial) or they can be made significantly // // faster (like building up the NTL-polynomial). // // // // INPUT: A canonicalform f // // OUTPUT: The converted NTL-polynomial over F_2 of type GF2X // //////////////////////////////////////////////////////////////////////////////// GF2X convertFacCF2NTLGF2X(CanonicalForm f) { //printf("convertFacCF2NTLGF2X\n"); GF2X ntl_poly; CFIterator i; i=f; int j=0; int NTLcurrentExp=i.exp(); int largestExp=i.exp(); int k; //building the NTL-polynomial ntl_poly.SetMaxLength(largestExp+1); for (;i.hasTerms();i++) { for (k=NTLcurrentExp;k>i.exp();k--) { SetCoeff(ntl_poly,k,0); } NTLcurrentExp=i.exp(); if (!i.coeff().isImm()) i.coeff()=i.coeff().mapinto(); if (!i.coeff().isImm()) { #ifndef NOSTREAMIO cout<<"convertFacCF2NTLGF2X: coefficient not immidiate! : " << f << "\n"; #else //NTL_SNS printf("convertFacCF2NTLGF2X: coefficient not immidiate!"); #endif NTL_SNS exit(1); } else { SetCoeff(ntl_poly,NTLcurrentExp,i.coeff().intval()); } NTLcurrentExp--; } for (k=NTLcurrentExp;k>=0;k--) { SetCoeff(ntl_poly,k,0); } //normalization is not necessary of F_2 return ntl_poly; } //////////////////////////////////////////////////////////////////////////////// // NAME: convertNTLZZpX2CF // // // // DESCRIPTION: // // Conversion routine for NTL-Type ZZpX to Factory-Type canonicalform. // // Additionally a variable x is needed as a parameter indicating the // // main variable of the computed canonicalform. To guarantee the correct // // execution of the algorithm, the characteristic has a be an arbitrary // // prime number. // // // // INPUT: A canonicalform f, a variable x // // OUTPUT: The converted Factory-polynomial of type canonicalform, // // built by the main variable x // //////////////////////////////////////////////////////////////////////////////// CanonicalForm convertNTLZZpX2CF(ZZ_pX poly,Variable x) { //printf("convertNTLZZpX2CF\n"); CanonicalForm bigone; if (deg(poly)>0) { // poly is non-constant bigone=0; bigone.mapinto(); // Compute the canonicalform coefficient by coefficient, // bigone summarizes the result. for (int j=0;j0) { // poly is non-constant bigone=0; bigone.mapinto(); // Compute the canonicalform coefficient by coefficient, // bigone summarizes the result. for (int j=0;j0) { // poly is non-constant bigone=0; bigone.mapinto(); // Compute the canonicalform coefficient by coefficient, // bigone summarizes the result. // In constrast to the more general conversion to ZZpX // the only possible coefficients are zero // and one yielding the following simplified loop for (int j=0;j=0;i--) { rueckgabe.append(CFFactor(convertNTLZZpX2CF(e[i].a,x),e[i].b)); } // the multiplicity at pos 1 if (!IsOne(multi)) rueckgabe.insert(CFFactor(CanonicalForm(to_long(rep(multi))),1)); return rueckgabe; } CFFList convertNTLvec_pair_zzpX_long2FacCFFList (vec_pair_zz_pX_long e,zz_p multi,Variable x) { //printf("convertNTLvec_pair_zzpX_long2FacCFFList\n"); CFFList rueckgabe; zz_pX polynom; long exponent; CanonicalForm bigone; // Maybe, e may additionally be sorted with respect to increasing degree of x // but this is not //important for the factorization, but nevertheless would take computing time, // so it is omitted // Go through the vector e and compute the CFFList // again bigone summarizes the result for (int i=e.length()-1;i>=0;i--) { rueckgabe.append(CFFactor(convertNTLzzpX2CF(e[i].a,x),e[i].b)); } // the multiplicity at pos 1 if (!IsOne(multi)) rueckgabe.insert(CFFactor(CanonicalForm(to_long(rep(multi))),1)); return rueckgabe; } //////////////////////////////////////////////////////////////////////////////// // NAME: convertNTLvec_pair_GF2X_long2FacCFFList // // // // DESCRIPTION: // // Routine for converting a vector of polynomials of type GF2X from // // NTL to a list CFFList of Factory. This routine will be used after a // // successful factorization of NTL to convert the result back to Factory. // // As usual this is simply a special case of the more general conversion // // routine but again speeded up by leaving out unnecessary steps. // // Additionally a variable x and the computed multiplicity, as type // // GF2 of NTL, are needed as parameters indicating the main variable of the // // computed canonicalform and the multiplicity of the original polynomial. // // To guarantee the correct execution of the algorithm the characteristic // // has a be an arbitrary prime number. // // // // INPUT: A vector of polynomials over GF2 of type vec_pair_GF2X_long and // // a variable x and a multiplicity of type GF2 // // OUTPUT: The converted list of polynomials of type CFFList, all // // polynomials have x as their main variable // //////////////////////////////////////////////////////////////////////////////// CFFList convertNTLvec_pair_GF2X_long2FacCFFList (vec_pair_GF2X_long e,GF2 multi,Variable x) { //printf("convertNTLvec_pair_GF2X_long2FacCFFList\n"); CFFList rueckgabe; GF2X polynom; long exponent; CanonicalForm bigone; // Maybe, e may additionally be sorted with respect to increasing degree of x // but this is not //important for the factorization, but nevertheless would take computing time // so it is omitted. //We do not have to worry about the multiplicity in GF2 since it equals one. // Go through the vector e and compute the CFFList // bigone summarizes the result again for (int i=e.length()-1;i>=0;i--) { bigone=0; polynom=e[i].a; exponent=e[i].b; for (int j=0;j((long)MINIMMEDIATE)) && (coeff_long<((long)MAXIMMEDIATE))) { // coefficient is immediate --> return the coefficient as canonicalform return CanonicalForm(coeff_long); } else { // coefficient is not immediate (gmp-number) if (cf_stringtemp_l==0) { cf_stringtemp=(char *)Alloc(1023); cf_stringtemp2=(char *)Alloc(1023); cf_stringtemp[0]='\0'; cf_stringtemp2[0]='\0'; cf_stringtemp_l=1023; } // convert coefficient to char* (input for gmp) dummy[1]='\0'; if (coefficient<0) { // negate coefficient, but store the sign in minusremainder minusremainder=1; coefficient=-coefficient; } int l=0; while (coefficient>15) { ZZ quotient,remaind; ZZ ten;ten=16; DivRem(quotient,remaind,coefficient,ten); dummy[0]=numbers[to_long(remaind)]; //tmp*=10; tmp+=to_long(remaind); l++; if (l>=cf_stringtemp_l-2) { Free(cf_stringtemp2,cf_stringtemp_l); char *p=(char *)Alloc(cf_stringtemp_l*2); //NTL_SNS memcpy(p,cf_stringtemp,cf_stringtemp_l); Free(cf_stringtemp,cf_stringtemp_l); cf_stringtemp_l*=2; cf_stringtemp=p; cf_stringtemp2=(char *)Alloc(cf_stringtemp_l); } cf_stringtemp[l-1]=dummy[0]; cf_stringtemp[l]='\0'; //strcat(stringtemp,dummy); coefficient=quotient; } //built up the string in dummy[0] dummy[0]=numbers[to_long(coefficient)]; //NTL_SNS strcat(cf_stringtemp,dummy); //tmp*=10; tmp+=to_long(coefficient); if (minusremainder==1) { //Check whether coefficient has been negative at the start of the procedure cf_stringtemp2[0]='-'; //tmp*=(-1); } //reverse the list to obtain the correct string int len= //NTL_SNS strlen(cf_stringtemp); for (int i=len-1;i>=0;i--) { cf_stringtemp2[len-i-1+minusremainder]=cf_stringtemp[i]; } cf_stringtemp2[len+minusremainder]='\0'; } //convert the string to canonicalform using the char*-Constructor return CanonicalForm(cf_stringtemp2,16); //return tmp; } //////////////////////////////////////////////////////////////////////////////// // NAME: convertFacCF2NTLZZX // // // // DESCRIPTION: // // Routine for conversion of canonicalforms in Factory to polynomials // // of type ZZX of NTL. To guarantee the correct execution of the // // algorithm the characteristic has to equal zero. // // // // INPUT: The canonicalform that has to be converted // // OUTPUT: The converted NTL-polynom of type ZZX // //////////////////////////////////////////////////////////////////////////////// ZZX convertFacCF2NTLZZX(CanonicalForm f) { ZZX ntl_poly; CFIterator i; i=f; int j=0; int NTLcurrentExp=i.exp(); int largestExp=i.exp(); int k; //set the length of the NTL-polynomial ntl_poly.SetMaxLength(largestExp+1); //Go through the coefficients of the canonicalform and build up the NTL-polynomial for (;i.hasTerms();i++) { for (k=NTLcurrentExp;k>i.exp();k--) { SetCoeff(ntl_poly,k,0); } NTLcurrentExp=i.exp(); if (!i.coeff().isImm()) { //Coefficient is a gmp-number mpz_t gmp_val; ZZ temp; char* stringtemp; gmp_val[0]=getmpi(i.coeff().getval()); int l=mpz_sizeinbase(gmp_val,10)+2; stringtemp=(char*)Alloc(l); stringtemp=mpz_get_str(stringtemp,10,gmp_val); mpz_clear(gmp_val); conv(temp,stringtemp); Free(stringtemp,l); //set the computed coefficient SetCoeff(ntl_poly,NTLcurrentExp,temp); } else { //Coefficient is immediate --> use its value SetCoeff(ntl_poly,NTLcurrentExp,i.coeff().intval()); } NTLcurrentExp--; } for (k=NTLcurrentExp;k>=0;k--) { SetCoeff(ntl_poly,k,0); } //normalize the polynomial ntl_poly.normalize(); return ntl_poly; } //////////////////////////////////////////////////////////////////////////////// // NAME: convertNTLvec_pair_ZZX_long2FacCFFList // // // // DESCRIPTION: // // Routine for converting a vector of polynomials from ZZ to a list // // CFFList of Factory. This routine will be used after a successful // // factorization of NTL to convert the result back to Factory. // // Additionally a variable x and the computed multiplicity, as a type // // ZZ of NTL, is needed as parameters indicating the main variable of the // // computed canonicalform and the multiplicity of the original polynomial. // // To guarantee the correct execution of the algorithm the characteristic // // has to equal zero. // // // // INPUT: A vector of polynomials over ZZ of type vec_pair_ZZX_long and // // a variable x and a multiplicity of type ZZ // // OUTPUT: The converted list of polynomials of type CFFList, all // // have x as their main variable // //////////////////////////////////////////////////////////////////////////////// CFFList convertNTLvec_pair_ZZX_long2FacCFFList(vec_pair_ZZX_long e,ZZ multi,Variable x) { CFFList rueckgabe; ZZX polynom; long exponent; CanonicalForm bigone; // Go through the vector e and build up the CFFList // As usual bigone summarizes the result for (int i=e.length()-1;i>=0;i--) { ZZ coefficient; polynom=e[i].a; exponent=e[i].b; bigone=convertNTLZZX2CF(polynom,x); //append the converted polynomial to the list rueckgabe.append(CFFactor(bigone,exponent)); } // the multiplicity at pos 1 //if (!IsOne(multi)) rueckgabe.insert(CFFactor(convertZZ2CF(multi),1)); //return the converted list return rueckgabe; } //////////////////////////////////////////////////////////////////////////////// // NAME: convertNTLZZpX2CF // // // // DESCRIPTION: // // Routine for conversion of elements of arbitrary extensions of ZZp, // // having type ZZpE, of NTL to their corresponding values of type // // canonicalform in Factory. // // To guarantee the correct execution of the algorithm the characteristic // // has to be an arbitrary prime number and Factory has to compute in an // // extension of F_p. // // // // INPUT: The coefficient of type ZZpE and the variable x indicating the main// // variable of the computed canonicalform // // OUTPUT: The converted value of coefficient as type canonicalform // //////////////////////////////////////////////////////////////////////////////// CanonicalForm convertNTLZZpE2CF(ZZ_pE coefficient,Variable x) { return convertNTLZZpX2CF(rep(coefficient),x); } CanonicalForm convertNTLzzpE2CF(zz_pE coefficient,Variable x) { return convertNTLzzpX2CF(rep(coefficient),x); } //////////////////////////////////////////////////////////////////////////////// // NAME: convertNTLvec_pair_ZZpEX_long2FacCFFList // // // // DESCRIPTION: // // Routine for converting a vector of polynomials from ZZpEX to a CFFList // // of Factory. This routine will be used after a successful factorization // // of NTL to convert the result back to Factory. // // Additionally a variable x and the computed multiplicity, as a type // // ZZpE of NTL, is needed as parameters indicating the main variable of the // // computed canonicalform and the multiplicity of the original polynomial. // // To guarantee the correct execution of the algorithm the characteristic // // has a be an arbitrary prime number p and computations have to be done // // in an extention of F_p. // // // // INPUT: A vector of polynomials over ZZpE of type vec_pair_ZZ_pEX_long and // // a variable x and a multiplicity of type ZZpE // // OUTPUT: The converted list of polynomials of type CFFList, all polynomials // // have x as their main variable // //////////////////////////////////////////////////////////////////////////////// CFFList convertNTLvec_pair_ZZpEX_long2FacCFFList(vec_pair_ZZ_pEX_long e,ZZ_pE multi,Variable x,Variable alpha) { CFFList rueckgabe; ZZ_pEX polynom; long exponent; CanonicalForm bigone; // Maybe, e may additionally be sorted with respect to increasing degree of x, but this is not //important for the factorization, but nevertheless would take computing time, so it is omitted // Go through the vector e and build up the CFFList // As usual bigone summarizes the result during every loop for (int i=e.length()-1;i>=0;i--) { bigone=0; polynom=e[i].a; exponent=e[i].b; for (int j=0;j=0;i--) { bigone=0; polynom=e[i].a; exponent=e[i].b; for (int j=0;j=0;i--) { bigone=0; polynom=e[i].a; exponent=e[i].b; for (int j=0;ji.exp();k--) SetCoeff(result,k,0); NTLcurrentExp=i.exp(); CanonicalForm c=i.coeff(); GF2X cc=convertFacCF2NTLGF2X(c); //ZZ_pE ccc; //conv(ccc,cc); SetCoeff(result,NTLcurrentExp,to_GF2E(cc)); NTLcurrentExp--; } for(k=NTLcurrentExp;k>=0;k--) SetCoeff(result,k,0); result.normalize(); return result; } //////////////////////////////////////////////////// // CanonicalForm in Z_p(a)[X] to NTL ZZ_pEX // //////////////////////////////////////////////////// ZZ_pEX convertFacCF2NTLZZ_pEX(CanonicalForm f, ZZ_pX mipo) { ZZ_pE::init(mipo); ZZ_pEX result; CFIterator i; i=f; int j=0; int NTLcurrentExp=i.exp(); int largestExp=i.exp(); int k; result.SetMaxLength(largestExp+1); for(;i.hasTerms();i++) { for(k=NTLcurrentExp;k>i.exp();k--) SetCoeff(result,k,0); NTLcurrentExp=i.exp(); CanonicalForm c=i.coeff(); ZZ_pX cc=convertFacCF2NTLZZpX(c); //ZZ_pE ccc; //conv(ccc,cc); SetCoeff(result,NTLcurrentExp,to_ZZ_pE(cc)); NTLcurrentExp--; } for(k=NTLcurrentExp;k>=0;k--) SetCoeff(result,k,0); result.normalize(); return result; } zz_pEX convertFacCF2NTLzz_pEX(CanonicalForm f, zz_pX mipo) { zz_pE::init(mipo); zz_pEX result; CFIterator i; i=f; int j=0; int NTLcurrentExp=i.exp(); int largestExp=i.exp(); int k; result.SetMaxLength(largestExp+1); for(;i.hasTerms();i++) { for(k=NTLcurrentExp;k>i.exp();k--) SetCoeff(result,k,0); NTLcurrentExp=i.exp(); CanonicalForm c=i.coeff(); zz_pX cc=convertFacCF2NTLzzpX(c); //ZZ_pE ccc; //conv(ccc,cc); SetCoeff(result,NTLcurrentExp,to_zz_pE(cc)); NTLcurrentExp--; } for(k=NTLcurrentExp;k>=0;k--) SetCoeff(result,k,0); result.normalize(); return result; } #endif