Skip to content

Commit

Permalink
Merge pull request #259 from singularitti/master
Browse files Browse the repository at this point in the history
Add `is_`, `as_`, `isreal`, `real`, `isintegerpoly` & `asintegerpoly`
  • Loading branch information
jverzani authored Sep 10, 2020
2 parents 930b116 + 3195ea9 commit d17ec51
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
4 changes: 4 additions & 0 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ chop
chop!
truncate
truncate!
isreal
real
isintegral
ismonic
```

## Arithmetic
Expand Down
62 changes: 61 additions & 1 deletion src/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export fromroots,
fit,
integrate,
derivative,
variable
variable,
isintegral,
ismonic

"""
fromroots(::AbstractVector{<:Number}; var=:x)
Expand Down Expand Up @@ -298,6 +300,64 @@ function Base.iszero(p::AbstractPolynomial)
return all(iszero.(coeffs(p))) && p[0] == 0
end

# See discussions in https://github.com/JuliaMath/Polynomials.jl/issues/258
"""
all(pred, poly::AbstractPolynomial)
Test whether all coefficients of an `AbstractPolynomial` satisfy predicate `pred`.
You can implement `isreal`, etc., to a `Polynomial` by using `all`.
"""
Base.all(pred, poly::AbstractPolynomial) = all(pred, poly[:])
"""
any(pred, poly::AbstractPolynomial)
Test whether any coefficient of an `AbstractPolynomial` satisfies predicate `pred`.
"""
Base.any(pred, poly::AbstractPolynomial) = any(pred, poly[:])
"""
map(fn, p::AbstractPolynomial)
Transform coefficients of `p` by applying a function (or other callables) `fn` to each of them.
You can implement `real`, etc., to a `Polynomial` by using `map`.
"""
Base.map(fn, p::P) where {P<:AbstractPolynomial} = (P)(map(fn, coeffs(p)), p.var)

"""
isreal(p::AbstractPolynomial)
Determine whether a polynomial is a real polynomial, i.e., having only real numbers as coefficients.
See also: [`real`](@ref)
"""
Base.isreal(p::AbstractPolynomial) = all(isreal, p)
"""
real(p::AbstractPolynomial)
Construct a real polynomial from the real parts of the coefficients of `p`.
See also: [`isreal`](@ref)
!!! note
This could cause losing terms in `p`. This method is usually called on polynomials like `p = Polynomial([1, 2 + 0im, 3.0, 4.0 + 0.0im])` where you want to chop the imaginary parts of the coefficients of `p`.
"""
Base.real(p::AbstractPolynomial) = map(real, p)

"""
isintegral(p::AbstractPolynomial)
Determine whether a polynomial is an integer polynomial, i.e., having only integers as coefficients.
"""
isintegral(p::AbstractPolynomial) = all(isinteger, p)

"""
ismonic(p::AbstractPolynomial)
Determine whether a polynomial is a monic polynomial, i.e., its leading coefficient is one.
"""
ismonic(p::AbstractPolynomial) = isone(p[end])

"""
coeffs(::AbstractPolynomial)
Expand Down
42 changes: 42 additions & 0 deletions test/Poly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,50 @@ fit(Poly, xx,yy,2)
## Issue with overflow and polyder Issue #159
@test !iszero(polyder(Poly(BigInt[0, 1])^100, 100))

@testset "`all` and `any`" begin
@test all(x -> x > 1, Polynomial([2 // 1, 3, Int8(4), 5.0]))
@test any(x -> x > 1, Polynomial([2 // 1, 3, Int8(4), 5.0]))
@test any(isnan, Polynomial([2 // 1, NaN, Int8(4), 5.0]))
@test any(!isfinite, Polynomial([2 // 1, NaN, Int8(4), 5.0]))
@test any(isinf, Polynomial([2 // 1, Inf64, Int8(4), 5.0]))
@test any(iszero, Polynomial([1, 0, 2.0, 3 // 1]))
end

@testset "`map`" begin
@test map(sqrt, Polynomial([1, 2, 3, 4.0])) == Polynomial([1, 2, 3, 4])
@test map(x -> x + 1, Polynomial([1, 2, 3, 4.0])) == Polynomial([2, 3, 4.0, 5 // 1])
@test map(zero, Polynomial([1, 2, 3, 4.0])) == Polynomial(0)
@test map(one, Polynomial([1, 2, 3, 4.0])) == Polynomial([1, 1, 1, 1])
@test map(float, Polynomial([1, 2, 3, 4])) == Polynomial([1.0, 2.0, 3.0, 4.0])
end

@testset "`isreal` and `real`" begin
x = Polynomial([1 // 2, 2 + 0im, 3.0, 4.0 + 0.0im])
y = Polynomial([1 // 2, 2 + 0im, 3.0, 4.0 + 0.1im])
@test isreal(x) === true
@test isequal(x, real(x)) === true
@test eltype(real(x)) === Float64
@test real(x) == Polynomial([1 // 2, 2, 3, 4.0])
@test isreal(y) === false
@test real(y) == real(x)
end

@testset "`isintegral`" begin
x = Polynomial([1 // 1, Int8(2) + 0im, 3.0, Int16(4) + 0im])
y = Polynomial([1 // 2, Int8(2) + 0im, 3.0, Int16(4) + 0im])
@test isintegral(x) === true
@test isintegral(y) === false
@test convert(Polynomial{Int}, x) == Polynomial([1, 2, 3, 4])
@test_throws InexactError convert(Polynomial{Int}, y)
end

@testset "`ismonic`" begin
@test !ismonic(Polynomial([1, 2, 3, 4]))
@test ismonic(Polynomial([2, 3, 4, 1 // 1]))
@test ismonic(Polynomial([2, 3, 4, 1.0]))
@test !ismonic(zero(Polynomial))
@test ismonic(one(Polynomial))
end


@testset "Pade" begin
Expand Down

0 comments on commit d17ec51

Please sign in to comment.