From 7a3bb781b2f63cbcc8612889b41d1759b05689dc Mon Sep 17 00:00:00 2001 From: Jean-Guillaume Dumas Date: Sun, 17 Jul 2016 17:47:26 +0200 Subject: [PATCH] Applying pull-request by d-torrance: --- Macaulay2 uses givaro as a dependency. However, it builds its own patched givaro, adding an additional version of the function GFqDom [1]. It would great if this function existed natively so that Macaulay2 could be built using a pre-existing givaro on the user's system. --- --- examples/Polynomial/Makefile.am | 3 +- examples/Polynomial/isgenerator.C | 53 +++++++++++++++++++++++ src/kernel/field/gfq.h | 10 ++++- src/kernel/field/gfq.inl | 71 +++++++++++++++++++++++++++++++ tests/test-ffarith.C | 15 +++++-- 5 files changed, 146 insertions(+), 6 deletions(-) create mode 100755 examples/Polynomial/isgenerator.C diff --git a/examples/Polynomial/Makefile.am b/examples/Polynomial/Makefile.am index 06ab40da..3bfc986c 100755 --- a/examples/Polynomial/Makefile.am +++ b/examples/Polynomial/Makefile.am @@ -30,12 +30,13 @@ LDADD = -L${top_srcdir}/src -L${top_srcdir}/src/.libs -lgivaro $(GMP_LIBS) $(LDF AM_LDFLAGS=-static -EXTRA_PROGRAMS=isirred isprimitive trunc_arith pol_arith pol_eval pol_factor interpolate PolynomialCRT highorder bivariate +EXTRA_PROGRAMS=isirred isprimitive trunc_arith pol_arith pol_eval pol_factor interpolate PolynomialCRT highorder bivariate isgenerator CLEANFILES=$(EXTRA_PROGRAMS) interpolate_SOURCES = interpolate.C isirred_SOURCES = isirred.C +isgenerator_SOURCES = isgenerator.C isprimitive_SOURCES = isprimitive.C pol_arith_SOURCES = pol_arith.C trunc_arith_SOURCES = trunc_arith.C diff --git a/examples/Polynomial/isgenerator.C b/examples/Polynomial/isgenerator.C new file mode 100755 index 00000000..43763496 --- /dev/null +++ b/examples/Polynomial/isgenerator.C @@ -0,0 +1,53 @@ +// Copyright(c)'1994-2009 by The Givaro group +// This file is part of Givaro. +// Givaro is governed by the CeCILL-B license under French law +// and abiding by the rules of distribution of free software. +// see the COPYRIGHT file for more details. +/*! @file examples/Polynomial/isprimitive.C + * @ingroup examples + * @ingroup polynomials + * @example examples/Polynomial/isprimitive.C + * @brief NO DOC + */ + +#include +#include +#include +#include +#include + +// using namespace std; + +using namespace Givaro; + + +int main(int argc, char** argv) +{ + typedef GFqDom::Residu_t UT; + UT MOD; + if (argc > 1) + MOD = (UT)atoi(argv[1]); + else + std::cin >> MOD; + uint64_t expo = 1; + if (argc > 2) expo = (uint64_t)atoi(argv[2]); + + GFqDom F(MOD, expo); + + Poly1FactorDom, Dense> FD(F,Indeter("X")); + Poly1FactorDom, Dense>::Element P, G; + FD.read( std::cin, P ); + FD.read( std::cin, G ); + + Timer tim; tim.clear(); tim.start(); + bool f = FD.is_prim_root(G, P ); + tim.stop(); + + FD.write(F.write( FD.write( std::cout, G ) << " is " << (f?"":"not ") << " a generator in " ) << " defined with ", P) << std::endl; + + // std::cout << f << std::endl; + std::cerr << tim << std::endl; + + return 0; +} + diff --git a/src/kernel/field/gfq.h b/src/kernel/field/gfq.h index baa2d09e..04ff2cad 100755 --- a/src/kernel/field/gfq.h +++ b/src/kernel/field/gfq.h @@ -5,7 +5,7 @@ // and abiding by the rules of distribution of free software. // see the COPYRIGHT file for more details. // file: gfq.h -// Time-stamp: <28 Oct 15 20:48:41 Jean-Guillaume.Dumas@imag.fr> +// Time-stamp: <17 Jul 16 16:12:52 Jean-Guillaume.Dumas@imag.fr> // date: 1999 // version: // author: Jean-Guillaume.Dumas @@ -98,6 +98,14 @@ template class GFqDom { template GFqDom(const UTT P, const UTT e, const Vector& modPoly); + // Construction with prescribed irreducible polynomial + // and with prescribed generator polynomial + // coefficients of the vector should be integers-like + // there will be a call to this->init to build the + // representation of both polynomials + template + GFqDom( const UTT P, const UTT e, const Vector& modPoly, const Vector& genPoly); + GFqDom( const GFqDom& F) : zero(F.zero), one(F.one), diff --git a/src/kernel/field/gfq.inl b/src/kernel/field/gfq.inl index 1b462a79..0e6dcddd 100755 --- a/src/kernel/field/gfq.inl +++ b/src/kernel/field/gfq.inl @@ -1115,6 +1115,77 @@ namespace Givaro { _plus1[size_t(mOne)] = 0; } + // Construction with prescribed irreducible polynomial + // and with prescribed generator polynomial + // coefficients of the vector should be integers-like + // there will be a call to this->init to build the + // representation of both polynomials + template + template + inline GFqDom::GFqDom(const UTT P, const UTT e, + const Vector& modPoly, const Vector& genPoly): + zero(0) + , one ((TT) power(P,e) - 1 ) + , mOne( (P==2)? (one) : ( one >> 1) ) // 1 == -1 in GF(2^k) + , _characteristic(P) + , _exponent(e) + , _q( (UTT) one + 1 ) + , _qm1 ( (UTT)one ) + , _log2pol( (UT)_q ) + , _pol2log( (UT)_q ) + , _plus1( (UT)_q ) + , _dcharacteristic( (double)P ) + { + + // 1 is represented by q-1, zero by 0 + _log2pol[0] = (UTT)zero; + + GFqDom Zp(P,1); + typedef Poly1FactorDom< GFqDom, Dense > PolDom; + PolDom Pdom( Zp ); + typename PolDom::Element Ft, F(e+1), G(genPoly.size()), H; + + for( size_t i = 0; i < F.size(); ++i ) + Zp.init( F[i], modPoly[i]); + + for( size_t i = 0; i < G.size(); ++i ) + Zp.init( G[i], genPoly[i]); + + Pdom.assign(H,G); + + typedef Poly1PadicDom< GFqDom, Dense > PadicDom; + PadicDom PAD(Pdom); + + PAD.eval(_log2pol[1],H); + PAD.eval(_irred, F); + + for (UTT i = 2; i < _qm1; ++i) { + Pdom.mulin(H, G); + Pdom.modin(H, F); + PAD.eval(_log2pol[i], H); + } + _log2pol[_qm1] = 1; + + _log2pol[0] = 0; + + for (UTT i = 0; i < _q; ++i) + _pol2log[ _log2pol[i] ] = i; + + _plus1[0] = 0; + + UTT a,b,r; + for (UTT i = 1; i < _q; ++i) { + a = _log2pol[i]; + r = a % P; + if (r == (P - 1)) + b = a - r; + else + b = a + 1; + _plus1[i] = (TT)_pol2log[b] - (TT)_qm1; + } + + _plus1[size_t(mOne)] = 0; + } template inline void GFqDom::Init() {} diff --git a/tests/test-ffarith.C b/tests/test-ffarith.C index 522813a0..84049c0d 100755 --- a/tests/test-ffarith.C +++ b/tests/test-ffarith.C @@ -371,12 +371,19 @@ int main(int argc, char ** argv) // Zech log finite field with 256 elements // and prescribed 1 + x +x^3 +x^4 +x^8 irreducible polynomial - std::vector< GFqDom::Residu_t > Irred(9); - Irred[0] = 1; Irred[1] = 1; Irred[2] = 0; Irred[3] = 1; - Irred[4] = 1; Irred[5] = 0; Irred[6] = 0; Irred[7] = 0; - Irred[8] = 1; +// std::vector< GFqDom::Residu_t > Irred(9); +// Irred[0] = 1; Irred[1] = 1; Irred[2] = 0; Irred[3] = 1; +// Irred[4] = 1; Irred[5] = 0; Irred[6] = 0; Irred[7] = 0; +// Irred[8] = 1; + std::vector< int64_t > Irred {1,1,0,1,1,0,0,0,1}; TEST_SPECIFIC(GFqDom, GF256, 2, 8, Irred); + // Zech log finite field with 343 elements + // and prescribed 3 +x^3 irreducible polynomial + // and prescribed 5 +3x +4x^2 generator polynomial + std::vector< int64_t > Irred3 {3,0,0,1}, Gene3 {5,3,4}; + TEST_SPECIFIC(GFqDom, GF343, 7, 3, Irred3, Gene3); + TEST_SPECIFIC(GFqDom, GF625, 5, 4); TEST_SPECIFIC(GFqExt, GF81, 3, 4);