-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize map_coefficients, change_base_ring for some inputs #1994
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -657,6 +657,11 @@ | |||||
# | ||||||
############################################################################### | ||||||
|
||||||
_content_ptr(c::QQMPolyRingElem) = Ptr{QQFieldElem}(pointer_from_objref(c)) | ||||||
_content_ptr(c::Ptr{QQMPolyRingElem}) = Ptr{QQFieldElem}(c) | ||||||
_content_ptr(c::Ref{QQMPolyRingElem}) = _content_ptr(c[]) | ||||||
_zpoly_ptr(c::QQMPolyRingElemOrPtr) = Ptr{ZZMPolyRingElem}(_content_ptr(c) + sizeof(QQFieldElem)) | ||||||
|
||||||
function zero!(a::QQMPolyRingElem) | ||||||
@ccall libflint.fmpq_mpoly_zero(a::Ref{QQMPolyRingElem}, a.parent::Ref{QQMPolyRing})::Nothing | ||||||
return a | ||||||
|
@@ -760,6 +765,20 @@ | |||||
mul!(a::QQMPolyRingElem, b::QQMPolyRingElem, c::RationalUnion) = mul!(a, b, flintify(c)) | ||||||
mul!(a::QQMPolyRingElem, b::RationalUnion, c::QQMPolyRingElem) = mul!(a, c, b) | ||||||
|
||||||
# special: multiply a QQMPolyRingElem by an integer and store the result as a ZZMPolyRingElem. | ||||||
# obviously this only works if the integers is a multiple of the denominator of the polynomial | ||||||
function mul!(a::ZZMPolyRingElem, b::QQMPolyRingElem, c::IntegerUnion) | ||||||
x = QQFieldElem() | ||||||
GC.@preserve a b x begin | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
x = mul!(x, _content_ptr(b), c) | ||||||
bp = _zpoly_ptr(b) | ||||||
lgoettgens marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
xp = _num_ptr(x) | ||||||
@ccall libflint.fmpz_mpoly_scalar_mul_fmpz(a::Ref{ZZMPolyRingElem}, bp::Ref{ZZMPolyRingElem}, xp::Ref{ZZRingElem}, parent(a)::Ref{ZZMPolyRing})::Nothing | ||||||
end | ||||||
return a | ||||||
end | ||||||
|
||||||
|
||||||
divexact!(a::QQMPolyRingElem, b::QQMPolyRingElem, c::RationalUnion) = divexact!(a, b, flintify(c)) | ||||||
|
||||||
# Set the n-th coefficient of a to c. If zero coefficients are inserted, they | ||||||
|
@@ -1059,3 +1078,47 @@ | |||||
|
||||||
return R(newaa, newbb) | ||||||
end | ||||||
|
||||||
############################################################################### | ||||||
# | ||||||
# Changing base ring, mapping coefficients | ||||||
# | ||||||
############################################################################### | ||||||
|
||||||
function map_coefficients(R::ZZRing, f::QQMPolyRingElem; | ||||||
cached::Bool = true, | ||||||
parent::ZZMPolyRing = AbstractAlgebra._change_mpoly_ring(R, parent(f), cached)) | ||||||
@req isinteger(_content_ptr(f)) "input polynomial must have integral coefficients" | ||||||
@req ngens(parent) == ngens(Nemo.parent(f)) "parents must have matching numbers of generators" | ||||||
@req internal_ordering(parent) == internal_ordering(Nemo.parent(f)) "parents must have matching internal ordering" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this too strict? Maybe instead of erroring out when the orderings don't match we should fall back to the generic code ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do other methods of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahh apparently I can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (A test case should also be added to verify this works as desired) |
||||||
return mul!(zero(parent), f, 1) | ||||||
end | ||||||
|
||||||
function map_coefficients(F::fpField, f::QQMPolyRingElem; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apparently this function is untested so a test should be added (TODO) |
||||||
cached::Bool = true, | ||||||
parent::MPolyRing = AbstractAlgebra._change_mpoly_ring(F, parent(f), cached)) | ||||||
dF = denominator(f) | ||||||
d = F(dF) | ||||||
if iszero(d) | ||||||
error("Denominator divisible by p!") | ||||||
end | ||||||
m = inv(d) | ||||||
ctx = MPolyBuildCtx(parent) | ||||||
for x in zip(coefficients(f), exponent_vectors(f)) | ||||||
el = numerator(x[1] * dF) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could optimize this further by using |
||||||
push_term!(ctx, F(el) * m, x[2]) | ||||||
end | ||||||
return finish(ctx) | ||||||
end | ||||||
|
||||||
function change_base_ring(R::ZZRing, f::QQMPolyRingElem; | ||||||
cached::Bool = true, | ||||||
parent::ZZMPolyRing = AbstractAlgebra._change_mpoly_ring(R, parent(f), cached)) | ||||||
return map_coefficients(R, f; cached, parent) | ||||||
end | ||||||
|
||||||
function change_base_ring(F::fpField, f::QQMPolyRingElem; | ||||||
cached::Bool = true, | ||||||
parent::fpMPolyRing = AbstractAlgebra._change_mpoly_ring(F, parent(f), cached)) | ||||||
return map_coefficients(R, f; cached, parent) | ||||||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the
parent
computation here was wrong as it ignored the internal ordering