Skip to content

Commit d656bb9

Browse files
committed
tweak defaults with ngcd with one euclidean step
1 parent e98da23 commit d656bb9

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

src/polynomials/ngcd.jl

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,37 @@ function ngcd(p::P, q::Q, args...;kwargs...) where {T, S, P<:StandardBasisPolyno
1414

1515
p′,q′ = promote(p,q)
1616
u,v,w,Θ,κ = NGCD.ngcd(coeffs(p′), coeffs(q′), args...; kwargs...)
17+
1718
PP = (typeof(p′))
1819
(u=PP(u, p.var), v=PP(v, p.var), w = PP(w, p.var), Θ=Θ, κ=κ)
20+
1921
end
2022

2123
"""
2224
ngcd′(p,q)
2325
2426
When degree(p) ≫ degree(q), this uses a early call to `divrem`.
2527
"""
26-
function ngcd′(p::P, q::P; kwargs...) where {P <: StandardBasisPolynomial}
28+
function ngcd′(p::P, q::P;
29+
atol = eps(real(float(T))),
30+
# rtol=eps(real(float(T))),
31+
rtol = Base.rtoldefault(real(float(T))), # relax this
32+
satol= atol,
33+
srtol= rtol,
34+
kwargs...
35+
) where {T, P <: StandardBasisPolynomial{T}}
36+
37+
2738
a, b = divrem(p,q)
28-
u,v,w,Θ, κ = ngcd(q, b; kwargs...)
29-
ngcd(p, q, degree(u))
39+
40+
# check if a=u (p,q) ≈ (aq,q)
41+
if isapprox(p, a*q, atol=atol, rtol=rtol)
42+
return a
43+
else
44+
u,v,w,Θ, κ = ngcd(q, b; atol=100atol, rtol=100rtol, kwargs...)
45+
u
46+
#ngcd(p, q, degree(u))
47+
end
3048
end
3149

3250

@@ -111,10 +129,10 @@ Note: Based on work by Andreas Varga
111129
function ngcd(ps::Vector{T},
112130
qs::Vector{T};
113131
scale::Bool=true,
114-
atol=(length(ps)+length(qs))*eps(real(T)),
115-
rtol=eps(real(T)), #Base.rtoldefault(real(T)),
116-
satol=atol,
117-
srtol=eps(real(T)),
132+
atol = eps(real(T)),
133+
rtol = eps(real(T)),
134+
satol = atol,
135+
srtol = rtol,
118136
verbose=false
119137
) where {T <: AbstractFloat}
120138

test/StandardBasis.jl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ end
714714
r1, r2 = 1/2, 3/2
715715
U(n) = prod( (x-r1*alpha(j,n))^2 + r1^2*beta(j,n)^2 for j in 1:n)
716716
V(n) = prod( (x-r2*alpha(j,n))^2 + r2^2*beta(j,n)^2 for j in 1:n)
717-
W(n) = prod( (x-r1*alpha(j,n))^2 + r1^2*beta(j,n)^2 for j in (n+1):2n)
717+
W(n) = prod( (x-r1*alpha(j,n))^2 + r1^2*beta(j,n)^2 for j in (n+1):2n)
718718
for n in 2:2:20
719719
p = U(n) * V(n); q = U(n) * W(n)
720720
@test degree(gcd(p,q, method=:numerical)) == degree(U(n))
@@ -729,7 +729,16 @@ W(n) = prod( (x-r1*alpha(j,n))^2 + r1^2*beta(j,n)^2 for j in (n+1):2n)
729729
@test degree(gcd(p,dp, method=:numerical)) == sum(max.(ms .- 1, 0))
730730
end
731731

732-
732+
#
733+
x = variable(P{Float64})
734+
for n in (10,20,50, 100)
735+
p = (x-1)^n * (x-2)^n * (x-3)
736+
q = (x-1) * (x-2) * (x-4)
737+
@test degree(gcd(p,q, method=:numerical)) != 2
738+
@test degree(Polynomials.ngcd′(p,q)) == 2
739+
end
740+
741+
733742

734743
end
735744

0 commit comments

Comments
 (0)