-
Notifications
You must be signed in to change notification settings - Fork 4
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
Don't recompute congruence substitutions #240
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 |
---|---|---|
|
@@ -365,13 +365,6 @@ function (R::GenericCycloRing)(f::Dict{UPolyFrac,UPoly}; simplify::Bool=true) # | |
return GenericCyclo(f, R) | ||
end | ||
|
||
# congruence preparation | ||
if R.congruence !== nothing | ||
q = gen(base_ring(R), 1) | ||
substitute = R.congruence[2] * q + R.congruence[1] | ||
substitute_inv = (q - R.congruence[1]) * 1//R.congruence[2] | ||
end | ||
|
||
# reduce numerators modulo denominators | ||
L = NTuple{4,UPoly}[] | ||
for (g, c) in f | ||
|
@@ -381,8 +374,8 @@ function (R::GenericCycloRing)(f::Dict{UPolyFrac,UPoly}; simplify::Bool=true) # | |
else | ||
gp = | ||
evaluate( | ||
numerator(g), [1], [substitute] | ||
)//evaluate(denominator(g), [1], [substitute]) | ||
numerator(g), [1], [R.substitute] | ||
)//evaluate(denominator(g), [1], [R.substitute]) | ||
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. If the fraction was reduced (i.e. numerator and denomiator are coprime) before the substitution, then it still is after, correct? But the In any case, you next need numerator and denominator anyway. So perhaps something like this could be used in this loop instead: den_g = denominator(g)
num_g = numerator(g)
if R.congruence === nothing
den_g = evaluate(den_g, [1], [substitute])
num_g = evaluate(num_g, [1], [substitute])
end
a, r = divrem(num_g, den_g)
push!(L, (c, den_g, r, a)) This would arguably also make the code a little bit nicer? 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.
No, not necessarily. This is kind of the whole point of this substitution. Take for example the fraction 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. ah of course, gotcha. So please add a comment explaining just that? :-) |
||
end | ||
a, r = divrem(numerator(gp), denominator(gp)) | ||
push!(L, (c, denominator(gp), r, a)) | ||
|
@@ -430,8 +423,8 @@ function (R::GenericCycloRing)(f::Dict{UPolyFrac,UPoly}; simplify::Bool=true) # | |
else | ||
gp = | ||
evaluate( | ||
numerator(g), [1], [substitute_inv] | ||
)//evaluate(denominator(g), [1], [substitute_inv]) | ||
numerator(g), [1], [R.substitute_inv] | ||
)//evaluate(denominator(g), [1], [R.substitute_inv]) | ||
end | ||
if haskey(fp, gp) | ||
fp[gp] += cp * c | ||
|
@@ -460,13 +453,11 @@ end | |
|
||
# Parent constructor | ||
|
||
# TODO Maybe don't require at least one variable? | ||
function generic_cyclotomic_ring( | ||
R::UPolyRing; | ||
congruence::Union{Tuple{ZZRingElem,ZZRingElem},Nothing}=nothing, | ||
cached::Bool=true, | ||
) | ||
length(gens(R)) < 1 && error("At least one free variable is needed") | ||
return GenericCycloRing(R, congruence) | ||
end | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -30,6 +30,23 @@ Generic cyclotomic ring | |||||
struct GenericCycloRing <: Ring | ||||||
base_ring::UPolyRing | ||||||
congruence::Union{Tuple{ZZRingElem,ZZRingElem},Nothing} | ||||||
substitute::UPoly | ||||||
substitute_inv::UPoly | ||||||
function GenericCycloRing( | ||||||
R::UPolyRing, | ||||||
congruence::Union{Tuple{ZZRingElem,ZZRingElem},Nothing}, | ||||||
) | ||||||
# TODO Maybe don't require at least one variable? | ||||||
length(gens(R)) < 1 && error("At least one free variable is needed") | ||||||
if congruence == nothing | ||||||
return new(R, congruence) | ||||||
else | ||||||
q = gen(R, 1) | ||||||
substitute = congruence[2] * q + congruence[1] | ||||||
substitute_inv = (q - congruence[1]) * 1//congruence[2] | ||||||
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. As discussed orally, computing this here in advance may be too costly. I would recommend changing the ring to a Then add an accessor function (or two, depending on taste) to get their content, with suitable 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. Also, why isn't this
Suggested change
|
||||||
return new(R, congruence, substitute, substitute_inv) | ||||||
end | ||||||
end | ||||||
end | ||||||
|
||||||
@doc raw""" | ||||||
|
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.
Style / taste question, but: I like to avoid nested control flow, esp. multi-level, to improve code clarity. So here I'd do
and then drop the
if !iszero(c)
and thereby reduce the indention level inside the loop