From 40dda1f610f41552e13f006175cb6b5340f96e32 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 25 Jul 2018 14:19:34 +0200 Subject: [PATCH] support converting Nemo polynomials to GAP - added new GAP functions `GAPCoefficientsOfNemo_Polynomial`, `ElementOfNemoNumberField`, and corresponding Julia functions - increase the rank of generic methods for `IsNemoObject` arguments, otherwise the GAP library methods for polynomials are preferred - simplified syntax: now `Julia.Singular.Matrix` and `Julia.Core._apply` are available --- JuliaExperimental/gap/numfield.g | 221 +++++++++++++++--- JuliaExperimental/gap/record.g | 2 +- .../ipynb/GAPJulia_Singular_blog.ipynb | 3 +- JuliaExperimental/julia/hnf.jl | 2 +- JuliaExperimental/julia/numfield.jl | 83 ++++--- JuliaExperimental/julia/utils.jl | 71 +++++- JuliaExperimental/julia/zlattice.jl | 5 +- JuliaExperimental/tst/numfield.tst | 26 +++ 8 files changed, 345 insertions(+), 68 deletions(-) diff --git a/JuliaExperimental/gap/numfield.g b/JuliaExperimental/gap/numfield.g index d139a8963..b22308755 100644 --- a/JuliaExperimental/gap/numfield.g +++ b/JuliaExperimental/gap/numfield.g @@ -202,7 +202,56 @@ BindGlobal( "Nemo_Polynomial", function( R, descr ) return ObjectifyWithAttributes( rec(), ElementsFamily( FamilyObj( R ) )!.defaultPolynomialType, - JuliaPointer, pol ); + JuliaPointer, pol, + ParentAttr, R ); +end ); + + +############################################################################# +## +#F GAPCoefficientsOfNemo_Polynomial( ) +## +BindGlobal( "GAPCoefficientsOfNemo_Polynomial", function( pol ) + local R, info, num, den, monomials; + + R:= Parent( pol ); + if HasJuliaPointer( pol ) then + pol:= JuliaPointer( pol ); + fi; + + if R!.isUnivariatePolynomialRing = true then + info:= Julia.GAPUtilsExperimental.CoefficientsOfUnivarateNemoPolynomialFmpq( + pol ); + info:= Julia.GAPUtilsExperimental.CoefficientsNumDenOfFmpqArray( info ); + num:= StructuralConvertedFromJulia( info[2] ); + den:= StructuralConvertedFromJulia( info[3] ); + if ConvertedFromJulia( info[1] ) = "int" then + # Just convert the integers to GAP. + return List( [ 1 .. Length( num ) ], i -> num[i] / den[i] ); + else + # The entries are hex strings encoding integers. + return List( [ 1 .. Length( num ) ], + i -> IntHexString( num[i] ) / IntHexString( den[i] ) ); + fi; + else + info:= JuliaGetFieldOfObject( pol, "coeffs" ); + info:= Julia.GAPUtilsExperimental.CoefficientsNumDenOfFmpqArray( info ); + num:= StructuralConvertedFromJulia( info[2] ); + den:= StructuralConvertedFromJulia( info[3] ); + if ConvertedFromJulia( info[1] ) = "int" then + # Just convert the integers to GAP. + info:= List( [ 1 .. Length( num ) ], i -> num[i] / den[i] ); + else + # The entries are hex strings encoding integers. + info:= List( [ 1 .. Length( num ) ], + i -> IntHexString( num[i] ) / IntHexString( den[i] ) ); + fi; + monomials:= Julia.GAPUtilsExperimental.NestedArrayFromMatrix( + JuliaGetFieldOfObject( pol, "exps" ) ); + + return [ info, + StructuralConvertedFromJulia( monomials ) ]; + fi; end ); @@ -289,11 +338,132 @@ BindGlobal( "Nemo_Field", function( F, descr... ) end ); +############################################################################# +## +InstallMethod( \in, + IsElmsColls, + [ "IsNemoFieldElement", "IsNemoField" ], + ReturnTrue ); + + +############################################################################# +## +BindGlobal( "ElementOfNemoNumberField", function( nemoF, coeffs ) + local d, res; + + # Compute the common denominator. + coeffs:= ExtRepOfObj( coeffs ); + d:= Lcm( List( coeffs, DenominatorRat ) ); + coeffs:= coeffs * d; + + # Convert the list of integral coefficient vectors + # to a suitable matrix in Julia (Nemo.fmpz_mat). + res:= Julia.GAPUtilsExperimental.MatrixFromNestedArray( [ coeffs ] ); + res:= Julia.Nemo.matrix( Julia.Nemo.ZZ, res ); + + # Call the Julia function. + res:= Julia.GAPNumberFields.NemoElementOfNumberField( + JuliaPointer( nemoF ), res, d ); + + return ObjectifyWithAttributes( rec(), + ElementsFamily( FamilyObj( nemoF ) )!.defaultType, + JuliaPointer, res ); +end ); + + #T Random for this field: #T method for alg. ext.; method for v. sp. -> then need basis ... #T -> and need arithm. between GAP coeffs. and NEMO field elements +############################################################################# +## +#R IsIsomorphismToNemoFieldRep( ) +## +DeclareRepresentation( "IsIsomorphismToNemoFieldRep", + IsAttributeStoringRep, [] ); + + +############################################################################# +## +#P IsIsomorphismToNemoField( ) +## +DeclareSynonym( "IsIsomorphismToNemoField", + IsIsomorphismToNemoFieldRep + and IsFieldHomomorphism + and IsMapping + and IsBijective ); + + +############################################################################## +## +#F IsomorphismToNemoField( ) +## +## For a field that consists of 'IsAlgebraicElement' elements, +## this function returns a field isomorphism +## to a field consisting of elements in '...'. +## +IsomorphismToNemoField:= function( F ) + local NemoF; + + # Check the argument. + if not ( IsAlgebraicElementCollection( F ) and IsField( F ) ) then + Error( " must be an algebraic extension" ); + fi; + + NemoF:= Nemo_Field( F ); + + return Objectify( TypeOfDefaultGeneralMapping( F, NemoF, + IsSPGeneralMapping + and IsIsomorphismToNemoField ), + rec() ); +end; + + +############################################################################# +## +#M ImageElm( , ) +## +InstallMethod( ImageElm, + FamSourceEqFamElm, + [ "IsIsomorphismToNemoField", "IsAlgebraicElement" ], + function( iso, algelm ) + return ElementOfNemoNumberField( Range( iso ), algelm ); + end ); + + +############################################################################# +## +#M PreImageElm( , ) +## +InstallMethod( PreImageElm, + FamRangeEqFamElm, + [ "IsIsomorphismToNemoField", "IsNemoFieldElement" ], + function( iso, elm ) + local numden, getindex, convert, num, den, coeffs, i; + + numden:= Julia.GAPNumberFields.CoefficientVectorsNumDenOfNumberFieldElement( JuliaPointer( elm ), Dimension( Source( iso ) ) ); + + getindex:= Julia.Base.getindex; + convert:= Julia.Base.convert; + num:= StructuralConvertedFromJulia( + convert( JuliaEvalString( "Array{Int,1}" ), + getindex( numden, 1 ) ) ); + den:= StructuralConvertedFromJulia( + convert( JuliaEvalString( "Array{Int,1}" ), + getindex( numden, 2 ) ) ); + coeffs:= []; + for i in [ 1 .. Length( num ) ] do + coeffs[i]:= num[i] / den[i]; + od; + + return AlgExtElm( ElementsFamily( FamilyObj( Source( iso ) ) ), coeffs ); + end ); + + +#T hier! + + ############################################################################# ## #F NemoElement(