Skip to content

Commit

Permalink
add unexported critical points (#458)
Browse files Browse the repository at this point in the history
* add unexported critical points

* consolidate

* clean up

* add precompiles
  • Loading branch information
jverzani authored Feb 4, 2023
1 parent cb23e64 commit 8be6bc9
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name = "Polynomials"
uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
license = "MIT"
author = "JuliaMath"
version = "3.2.3"
version = "3.2.4"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
2 changes: 2 additions & 0 deletions src/Polynomials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ include("rational-functions/plot-recipes.jl")
# compat; opt-in with `using Polynomials.PolyCompat`
include("polynomials/Poly.jl")

include("precompiles.jl")

end # module
49 changes: 49 additions & 0 deletions src/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,55 @@ Calculate the pseudo-Vandermonde matrix of the given polynomial type with the gi
"""
vander(::Type{<:AbstractPolynomial}, x::AbstractVector, deg::Integer)


"""
critical_points(p::AbstractPolynomial{<:Real}, I=domain(p); endpoints::Bool=true)
Return the critical points of `p` (real zeros of the derivative) within `I` in sorted order.
* `p`: a polynomial
* `I`: a specification of a closed or infinite domain, defaulting to `Polynomials.domain(p)`. When specified, the values of `extrema(I)` are used with closed endpoints when finite.
* `endpoints::Bool`: if `true`, return the endpoints of `I` along with the critical points
Can be used in conjuction with `findmax`, `findmin`, `argmax`, `argmin`, `extrema`, etc.
## Example
```
x = variable()
p = x^2 - 2
cps = Polynomials.critical_points(p)
findmin(p, cps) # (-2.0, 2.0)
argmin(p, cps) # 0.0
extrema(p, cps) # (-2.0, Inf)
cps = Polynomials.critical_points(p, (0, 2))
extrema(p, cps) # (-2.0, 2.0)
```
"""
function critical_points(p::AbstractPolynomial{T}, I = domain(p);
endpoints::Bool=true) where {T <: Real}

I′ = Interval(I)
l, r = extrema(I′)

q = Polynomials.ngcd(derivative(p), derivative(p,2)).v
pts = sort(real.(filter(isreal, roots(q))))
pts = filter(in(I′), pts)

!endpoints && return pts

l !== first(pts) && pushfirst!(pts, l)
r != last(pts) && push!(pts, r)
pts
end






"""
integrate(p::AbstractPolynomial)
Expand Down
2 changes: 2 additions & 0 deletions src/contrib.jl
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ struct Interval{T, L <: Bound, R <: Bound}
end
Interval(f, l) = Interval{Closed, Closed}(f, l)
end
Interval(I::Interval) = I
Interval(I) = Interval(extrema(I)...)

bounds_types(x::Interval{T,L,R}) where {T,L,R} = (L, R)

Expand Down
6 changes: 6 additions & 0 deletions src/precompiles.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# precompiles

p = fromroots(Polynomial, [1,1,2])
Multroot.multroot(p)
gcd(p, derivative(p); method=:numerical)
uvw(p, derivative(p); method=:numerical)
18 changes: 18 additions & 0 deletions test/StandardBasis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,24 @@ end
end
end

@testset "critical points" begin
for P in (Polynomial, ImmutablePolynomial)
p = fromroots(P, [-1,-1, 2]) |> integrate
cps = Polynomials.critical_points(p, (-5,5); endpoints=false)
@test all(cps .≈ [-1, 2])
cps = Polynomials.critical_points(p, (0,5); endpoints=false)
@test all(cps .≈ [2])

cps = Polynomials.critical_points(p)
m, i = findmin(p, cps)
@test m -6.0
x = argmin(p, cps)
@test x 2.0
mn, mx = extrema(p, cps)
@test mn -6.0 && isinf(mx)
end
end

@testset "Integrals and Derivatives" begin
# Integrals derivatives
@testset for P in Ps
Expand Down

2 comments on commit 8be6bc9

@jverzani
Copy link
Member Author

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/77008

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 v3.2.4 -m "<description of version>" 8be6bc9719bcd96baf217d0e8fb116b543c10460
git push origin v3.2.4

Please sign in to comment.