Skip to content

Commit d17ec51

Browse files
authored
Merge pull request #259 from singularitti/master
Add `is_`, `as_`, `isreal`, `real`, `isintegerpoly` & `asintegerpoly`
2 parents 930b116 + 3195ea9 commit d17ec51

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

docs/src/reference.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ chop
2525
chop!
2626
truncate
2727
truncate!
28+
isreal
29+
real
30+
isintegral
31+
ismonic
2832
```
2933

3034
## Arithmetic

src/common.jl

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ export fromroots,
1515
fit,
1616
integrate,
1717
derivative,
18-
variable
18+
variable,
19+
isintegral,
20+
ismonic
1921

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

303+
# See discussions in https://github.com/JuliaMath/Polynomials.jl/issues/258
304+
"""
305+
all(pred, poly::AbstractPolynomial)
306+
307+
Test whether all coefficients of an `AbstractPolynomial` satisfy predicate `pred`.
308+
309+
You can implement `isreal`, etc., to a `Polynomial` by using `all`.
310+
"""
311+
Base.all(pred, poly::AbstractPolynomial) = all(pred, poly[:])
312+
"""
313+
any(pred, poly::AbstractPolynomial)
314+
315+
Test whether any coefficient of an `AbstractPolynomial` satisfies predicate `pred`.
316+
"""
317+
Base.any(pred, poly::AbstractPolynomial) = any(pred, poly[:])
318+
"""
319+
map(fn, p::AbstractPolynomial)
320+
321+
Transform coefficients of `p` by applying a function (or other callables) `fn` to each of them.
322+
323+
You can implement `real`, etc., to a `Polynomial` by using `map`.
324+
"""
325+
Base.map(fn, p::P) where {P<:AbstractPolynomial} = (P)(map(fn, coeffs(p)), p.var)
326+
327+
"""
328+
isreal(p::AbstractPolynomial)
329+
330+
Determine whether a polynomial is a real polynomial, i.e., having only real numbers as coefficients.
331+
332+
See also: [`real`](@ref)
333+
"""
334+
Base.isreal(p::AbstractPolynomial) = all(isreal, p)
335+
"""
336+
real(p::AbstractPolynomial)
337+
338+
Construct a real polynomial from the real parts of the coefficients of `p`.
339+
340+
See also: [`isreal`](@ref)
341+
342+
!!! note
343+
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`.
344+
"""
345+
Base.real(p::AbstractPolynomial) = map(real, p)
346+
347+
"""
348+
isintegral(p::AbstractPolynomial)
349+
350+
Determine whether a polynomial is an integer polynomial, i.e., having only integers as coefficients.
351+
"""
352+
isintegral(p::AbstractPolynomial) = all(isinteger, p)
353+
354+
"""
355+
ismonic(p::AbstractPolynomial)
356+
357+
Determine whether a polynomial is a monic polynomial, i.e., its leading coefficient is one.
358+
"""
359+
ismonic(p::AbstractPolynomial) = isone(p[end])
360+
301361
"""
302362
coeffs(::AbstractPolynomial)
303363

test/Poly.jl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,50 @@ fit(Poly, xx,yy,2)
421421
## Issue with overflow and polyder Issue #159
422422
@test !iszero(polyder(Poly(BigInt[0, 1])^100, 100))
423423

424+
@testset "`all` and `any`" begin
425+
@test all(x -> x > 1, Polynomial([2 // 1, 3, Int8(4), 5.0]))
426+
@test any(x -> x > 1, Polynomial([2 // 1, 3, Int8(4), 5.0]))
427+
@test any(isnan, Polynomial([2 // 1, NaN, Int8(4), 5.0]))
428+
@test any(!isfinite, Polynomial([2 // 1, NaN, Int8(4), 5.0]))
429+
@test any(isinf, Polynomial([2 // 1, Inf64, Int8(4), 5.0]))
430+
@test any(iszero, Polynomial([1, 0, 2.0, 3 // 1]))
431+
end
432+
433+
@testset "`map`" begin
434+
@test map(sqrt, Polynomial([1, 2, 3, 4.0])) == Polynomial([1, 2, 3, 4])
435+
@test map(x -> x + 1, Polynomial([1, 2, 3, 4.0])) == Polynomial([2, 3, 4.0, 5 // 1])
436+
@test map(zero, Polynomial([1, 2, 3, 4.0])) == Polynomial(0)
437+
@test map(one, Polynomial([1, 2, 3, 4.0])) == Polynomial([1, 1, 1, 1])
438+
@test map(float, Polynomial([1, 2, 3, 4])) == Polynomial([1.0, 2.0, 3.0, 4.0])
439+
end
424440

441+
@testset "`isreal` and `real`" begin
442+
x = Polynomial([1 // 2, 2 + 0im, 3.0, 4.0 + 0.0im])
443+
y = Polynomial([1 // 2, 2 + 0im, 3.0, 4.0 + 0.1im])
444+
@test isreal(x) === true
445+
@test isequal(x, real(x)) === true
446+
@test eltype(real(x)) === Float64
447+
@test real(x) == Polynomial([1 // 2, 2, 3, 4.0])
448+
@test isreal(y) === false
449+
@test real(y) == real(x)
450+
end
425451

452+
@testset "`isintegral`" begin
453+
x = Polynomial([1 // 1, Int8(2) + 0im, 3.0, Int16(4) + 0im])
454+
y = Polynomial([1 // 2, Int8(2) + 0im, 3.0, Int16(4) + 0im])
455+
@test isintegral(x) === true
456+
@test isintegral(y) === false
457+
@test convert(Polynomial{Int}, x) == Polynomial([1, 2, 3, 4])
458+
@test_throws InexactError convert(Polynomial{Int}, y)
459+
end
460+
461+
@testset "`ismonic`" begin
462+
@test !ismonic(Polynomial([1, 2, 3, 4]))
463+
@test ismonic(Polynomial([2, 3, 4, 1 // 1]))
464+
@test ismonic(Polynomial([2, 3, 4, 1.0]))
465+
@test !ismonic(zero(Polynomial))
466+
@test ismonic(one(Polynomial))
467+
end
426468

427469

428470
@testset "Pade" begin

0 commit comments

Comments
 (0)