Skip to content

Commit 0656459

Browse files
committed
Use buffer
1 parent c9cbca9 commit 0656459

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

src/gcd.jl

+35-12
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ _polynomial(ts, state, ::MA.IsNotMutable) = polynomial(ts, state)
397397
_polynomial(ts, state, ::MA.IsMutable) = polynomial!(ts, state)
398398

399399
"""
400-
primitive_univariate_gcd!(p::APL, q::APL, algo::AbstractUnivariateGCDAlgorithm)
400+
primitive_univariate_gcd!(p::APL, q::APL, algo::AbstractUnivariateGCDAlgorithm, buffer=nothing)
401401
402402
Returns the `gcd` of primitive polynomials `p` and `q` using algorithm `algo`
403403
which is a subtype of [`AbstractUnivariateGCDAlgorithm`](@ref).
@@ -419,11 +419,19 @@ end
419419

420420
# If `p` and `q` do not have the same type then the local variables `p` and `q`
421421
# won't be type stable so we create `u` and `v`.
422-
function primitive_univariate_gcd!(p::APL, q::APL, algo::GeneralizedEuclideanAlgorithm)
422+
function primitive_univariate_gcd!(
423+
p::APL,
424+
q::APL,
425+
algo::GeneralizedEuclideanAlgorithm,
426+
buffer=nothing,
427+
)
423428
if maxdegree(p) < maxdegree(q)
424-
return primitive_univariate_gcd!(q, p, algo)
429+
return primitive_univariate_gcd!(q, p, algo, buffer)
425430
end
426431
R = MA.promote_operation(gcd, typeof(p), typeof(q))
432+
if isnothing(buffer)
433+
buffer = MA.buffer_for(rem_or_pseudo_rem, R, R, typeof(algo))
434+
end
427435
u = convert(R, p)
428436
v = convert(R, q)
429437
while true
@@ -436,7 +444,7 @@ function primitive_univariate_gcd!(p::APL, q::APL, algo::GeneralizedEuclideanAlg
436444
end
437445

438446
d_before = degree(leadingmonomial(u))
439-
r = MA.operate!!(rem_or_pseudo_rem, u, v, algo)
447+
r = MA.buffered_operate!!(buffer, rem_or_pseudo_rem, u, v, algo)
440448
d_after = degree(leadingmonomial(r))
441449
if d_after == d_before
442450
not_divided_error(u, v)
@@ -485,7 +493,7 @@ function primitive_univariate_gcdx(u0::APL, v0::APL, algo::GeneralizedEuclideanA
485493
end
486494

487495

488-
function primitive_univariate_gcd!(p::APL, q::APL, ::SubresultantAlgorithm)
496+
function primitive_univariate_gcd!(p::APL, q::APL, ::SubresultantAlgorithm, buffer=nothing)
489497
error("Not implemented yet")
490498
end
491499

@@ -512,13 +520,28 @@ If the coefficients are not `AbstractFloat`, this
512520
*Art of computer programming, volume 2: Seminumerical algorithms.*
513521
Addison-Wesley Professional. Third edition.
514522
"""
515-
function univariate_gcd(p1::APL{S}, p2::APL{T}, algo::AbstractUnivariateGCDAlgorithm, m1::MA.MutableTrait, m2::MA.MutableTrait) where {S,T}
516-
return univariate_gcd(_field_absorb(algebraic_structure(S), algebraic_structure(T)), p1, p2, algo, m1, m2)
517-
end
518-
function univariate_gcd(::UFD, p1::APL, p2::APL, algo::AbstractUnivariateGCDAlgorithm, m1::MA.MutableTrait, m2::MA.MutableTrait)
523+
function univariate_gcd(
524+
p1::APL{S},
525+
p2::APL{T},
526+
algo::AbstractUnivariateGCDAlgorithm,
527+
m1::MA.MutableTrait,
528+
m2::MA.MutableTrait,
529+
buffer=nothing
530+
) where {S,T}
531+
return univariate_gcd(_field_absorb(algebraic_structure(S), algebraic_structure(T)), p1, p2, algo, m1, m2, buffer)
532+
end
533+
function univariate_gcd(
534+
::UFD,
535+
p1::APL,
536+
p2::APL,
537+
algo::AbstractUnivariateGCDAlgorithm,
538+
m1::MA.MutableTrait,
539+
m2::MA.MutableTrait,
540+
buffer=nothing,
541+
)
519542
f1, g1 = primitive_part_content(p1, algo, m1)
520543
f2, g2 = primitive_part_content(p2, algo, m2)
521-
pp = primitive_univariate_gcd!(f1, f2, algo)
544+
pp = primitive_univariate_gcd!(f1, f2, algo, buffer)
522545
gg = _gcd(g1, g2, algo, MA.IsMutable(), MA.IsMutable())#::MA.promote_operation(gcd, typeof(g1), typeof(g2))
523546
# Multiply each coefficient by the gcd of the contents.
524547
if !isone(gg)
@@ -527,8 +550,8 @@ function univariate_gcd(::UFD, p1::APL, p2::APL, algo::AbstractUnivariateGCDAlgo
527550
return pp
528551
end
529552

530-
function univariate_gcd(::Field, p1::APL, p2::APL, algo::AbstractUnivariateGCDAlgorithm, m1::MA.MutableTrait, m2::MA.MutableTrait)
531-
return primitive_univariate_gcd!(_copy(p1, m1), _copy(p2, m2), algo)
553+
function univariate_gcd(::Field, p1::APL, p2::APL, algo::AbstractUnivariateGCDAlgorithm, m1::MA.MutableTrait, m2::MA.MutableTrait, buffer=nothing)
554+
return primitive_univariate_gcd!(_copy(p1, m1), _copy(p2, m2), algo, buffer)
532555
end
533556

534557
function univariate_gcdx(p1::APL{S}, p2::APL{T}, algo::AbstractUnivariateGCDAlgorithm) where {S,T}

test/allocations.jl

+10-3
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,22 @@ function _test_univ_gcd(T, algo)
151151
@polyvar x
152152
p1 = o * x^2 + 2o * x + o
153153
p2 = o * x + o
154+
buffer = buffer_for(MP.rem_or_pseudo_rem, typeof(p1), typeof(p2), typeof(algo))
154155
mutable_alloc_test(mutable_copy(p1), 0) do p1
155-
MP.univariate_gcd(p1, p2, algo, IsMutable(), IsMutable())
156+
MP.primitive_univariate_gcd!(p1, p2, algo, buffer)
157+
end
158+
if T === Int
159+
mutable_alloc_test(mutable_copy(p1), 0) do p1
160+
MP.gcd(p1, p2, algo, IsMutable(), IsMutable())
161+
end
156162
end
157163
end
158164

159165
function test_univ_gcd()
160166
algo = GeneralizedEuclideanAlgorithm()
161-
_test_univ_gcd(Int, algo)
162-
#_test_univ_gcd(BigInt, algo) # TODO
167+
@testset "$T" for T in [Int, BigInt]
168+
_test_univ_gcd(T, algo)
169+
end
163170
end
164171

165172
end

0 commit comments

Comments
 (0)