Skip to content

Commit

Permalink
Add lift(::FqPolyRing, ::FqFieldElem) (#1490)
Browse files Browse the repository at this point in the history
* Add lift(::FqPolyRing, ::FqFieldElem)
  • Loading branch information
thofma authored Jun 8, 2023
1 parent 5300744 commit 2cd74cb
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "Nemo"
uuid = "2edaba10-b0f1-5616-af89-8c11ac63239a"
version = "0.34.4"
version = "0.34.5"

[deps]
AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d"
Expand Down
1 change: 1 addition & 0 deletions docs/src/finitefield.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,5 @@ tr(::FqFieldElem)
absolute_tr(::FqFieldElem)
norm(::FqFieldElem)
absolute_norm(::FqFieldElem)
lift(::FqPolyRing, ::FqFieldElem)
```
56 changes: 50 additions & 6 deletions src/flint/fq_default_extended.jl
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,8 @@ function _fq_field_from_fmpz_mod_poly_in_disguise(f::FqPolyRingElem, s)
@assert parent(y) === z
return y
end
z.backwardmap = g -> begin
y = parent(f)()
z.backwardmap = function(g, R = parent(f))
y = R()
ccall((:fq_default_get_fmpz_mod_poly, libflint), Nothing,
(Ref{FqPolyRingElem}, Ref{FqFieldElem}, Ref{FqField}), y, g, z)
return y
Expand Down Expand Up @@ -534,8 +534,8 @@ function _fq_field_from_nmod_poly_in_disguise(f::FqPolyRingElem, s)
(Ref{FqFieldElem}, Ref{FqPolyRingElem}, Ref{FqField}), y, g, z)
return y
end
z.backwardmap = g -> begin
y = parent(f)()
z.backwardmap = function(g, R = parent(f))
y = R()
ccall((:fq_default_get_nmod_poly, libflint), Nothing,
(Ref{FqPolyRingElem}, Ref{FqFieldElem}, Ref{FqField}), y, g, z)
return y
Expand Down Expand Up @@ -597,10 +597,10 @@ function FqField(f::FqPolyRingElem, s::Symbol, cached::Bool = false, absolute::B
end
end
forwardmatinv = inv(forwardmat)
backwardmap = y -> begin
backwardmap = function(y, R = parent(f))
w = matrix(Fp, 1, d, [_coeff(y, j - 1) for j in 1:d])
ww = [Fp(_coeff(y, j - 1)) for j in 1:d]
_abs_gen_rel = zero(parent(f))
_abs_gen_rel = zero(R)
fl, vv = can_solve_with_solution(forwardmat, w, side = :left)
vvv = ww * forwardmatinv
@assert fl
Expand Down Expand Up @@ -782,3 +782,47 @@ function (F::FqField)(p::FqPolyRingElem)
end
end
end

################################################################################
#
# Lift
#
################################################################################

function _lift_standard(R::FqPolyRing, a::FqFieldElem)
K = parent(a)
F = base_ring(R)
p = R()
@assert F === base_field(parent(a))
if _fq_default_ctx_type(F) == _FQ_DEFAULT_NMOD
ccall((:fq_default_get_nmod_poly, libflint), Nothing,
(Ref{FqPolyRingElem}, Ref{FqFieldElem}, Ref{FqField}),
p, a, K)
return p
else
@assert _fq_default_ctx_type(F) == _FQ_DEFAULT_FMPZ_NMOD
ccall((:fq_default_get_fmpz_mod_poly, libflint), Nothing,
(Ref{FqPolyRingElem}, Ref{FqFieldElem}, Ref{FqField}),
p, a, K)
return p
end
end

@doc raw"""
lift(R::FqPolyRing, a::FqFieldElem) -> FqPolyRingElem
Given a polynomial ring over the base field of the parent of `a`, return a lift
such that `parent(a)(lift(R, a)) == a` is `true`.
"""
function lift(R::FqPolyRing, a::FqFieldElem)
base_ring(R) !== base_field(parent(a)) &&
error("Polynomial ring has wrong coefficient ring")
K = parent(a)
if isdefined(K, :backwardmap)
return K.backwardmap(a)
else
@assert is_absolute(K)
@assert K.isstandard
return _lift_standard(R, a)
end
end
4 changes: 4 additions & 0 deletions test/flint/fq_default-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ end
f = 3a^4 + 2a^3 + a + 5
S, y = Nemo._GF(7)["y"]
@test f == U(3y^4 + 2y^3 + y + 5)
S, y = base_field(U)["y"]
@test lift(S, f) == 3y^4 + 2y^3 + y + 5

S, y = Nemo._GF(5)["y"]
@test_throws ErrorException U(y)
Expand All @@ -129,6 +131,8 @@ end
f = 3a^4 + 2a^3 + a + 5
S, y = Nemo._GF(ZZ(1180591620717411303449))["y"]
@test f == U(3y^4 + 2y^3 + y + 5)
S, y = base_field(U)["y"]
@test lift(S, f) == 3y^4 + 2y^3 + y + 5

S, y = Nemo._GF(5)["y"]
@test_throws ErrorException U(y)
Expand Down
11 changes: 11 additions & 0 deletions test/flint/fq_default_extended-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@
F, b = NGFiniteField(f, "b", cached = false)
@test_throws ErrorException lift(ZZ["x"][1], b)
@test F(ZZ["x"][2] + 1) == b + 1
c = 2b^2 + 2b + 1
@test lift(Rx, c) == 2x^2 + 2x + 1

R, a = NGFiniteField(ZZ(1180591620717411303449), 2, "a")
Rx, x = R["x"]
f = x^3 + 8*x^2 + 3*x + 5
F, b = NGFiniteField(f, "b", cached = false)
@test_throws ErrorException lift(ZZ["x"][1], b)
@test F(ZZ["x"][2] + 1) == b + 1
c = 2b^2 + 2b + 1
@test lift(Rx, c) == 2x^2 + 2x + 1
end

@testset "FqFieldElem.printing" begin
Expand Down

2 comments on commit 2cd74cb

@thofma
Copy link
Member Author

@thofma thofma commented on 2cd74cb Jun 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/85115

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.34.5 -m "<description of version>" 2cd74cbdbe088df35f07c73df66a66edefe77110
git push origin v0.34.5

Please sign in to comment.