Skip to content

Commit 9b1de1e

Browse files
authored
close #213; update tests; fix bug in isconstant for SparsePolynomials (#214)
2 parents 6fdb7ba + 58cb31c commit 9b1de1e

File tree

5 files changed

+59
-25
lines changed

5 files changed

+59
-25
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "Polynomials"
22
uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
33
license = "MIT"
44
author = "JuliaMath"
5-
version = "1.0.2"
5+
version = "1.0.3"
66

77
[deps]
88
Intervals = "d8418881-c3e1-53bb-8760-2df7ec849ed5"

docs/src/index.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ ERROR: Polynomials must have same variable
101101
[...]
102102
```
103103

104+
Except for operations involving constant polynomials.
105+
106+
```jldoctest
107+
julia> p = Polynomial([1, 2, 3], :x)
108+
Polynomial(1 + 2*x + 3*x^2)
109+
110+
julia> q = Polynomial(1, :y)
111+
Polynomial(1)
112+
113+
julia> p+q
114+
Polynomial(2 + 2*x + 3*x^2)
115+
```
116+
104117
### Integrals and Derivatives
105118

106119
Integrate the polynomial `p` term by term, optionally adding constant

src/polynomials/Polynomial.jl

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ If ``p = a_n x^n + \\ldots + a_2 x^2 + a_1 x + a_0``, we construct this through
1111
1212
The usual arithmetic operators are overloaded to work with polynomials as well as
1313
with combinations of polynomials and scalars. However, operations involving two
14-
polynomials of different variables causes an error.
14+
polynomials of different variables causes an error except those involving a constant polynomial.
1515
1616
# Examples
1717
```@meta
@@ -82,27 +82,48 @@ julia> p.(0:3)
8282

8383

8484
function Base.:+(p1::Polynomial{T}, p2::Polynomial{S}) where {T, S}
85-
86-
#isconstant(p1) && return p2 + p1[0] # factor of 2 slower with this check
87-
#isconstant(p2) && return p1 + p2[0]
88-
p1.var != p2.var && error("Polynomials must have same variable")
89-
9085
n1, n2 = length(p1), length(p2)
91-
c = [p1[i] + p2[i] for i = 0:max(n1, n2)]
92-
return Polynomial(c, p1.var)
86+
if n1 > 1 && n2 > 1
87+
p1.var != p2.var && error("Polynomials must have same variable")
88+
if n1 >= n2
89+
c = copy(p1.coeffs)
90+
for i = 1:n2
91+
c[i] += p2.coeffs[i]
92+
end
93+
else
94+
c = copy(p2.coeffs)
95+
for i = 1:n1
96+
c[i] += p1.coeffs[i]
97+
end
98+
end
99+
return Polynomial(c, p1.var)
100+
elseif n1 <= 1
101+
c = copy(p2.coeffs)
102+
c[1] += p1[0]
103+
return Polynomial(c, p2.var)
104+
else
105+
c = copy(p1.coeffs)
106+
c[1] += p2[0]
107+
return Polynomial(c, p1.var)
108+
end
93109
end
94110

95111

96112
function Base.:*(p1::Polynomial{T}, p2::Polynomial{S}) where {T,S}
97113

98-
#isconstant(p1) && return p2 * p1[0] # no real effect
99-
#isconstant(p2) && return p1 * p2[0]
100-
p1.var != p2.var && error("Polynomials must have same variable")
101-
n,m = length(p1)-1, length(p2)-1 # not degree, so pNULL works
102-
R = promote_type(T, S)
103-
c = zeros(R, m + n + 1)
104-
for i in 0:n, j in 0:m
105-
@inbounds c[i + j + 1] += p1[i] * p2[j]
114+
n, m = length(p1)-1, length(p2)-1 # not degree, so pNULL works
115+
if n > 0 && m > 0
116+
p1.var != p2.var && error("Polynomials must have same variable")
117+
R = promote_type(T, S)
118+
c = zeros(R, m + n + 1)
119+
for i in 0:n, j in 0:m
120+
@inbounds c[i + j + 1] += p1[i] * p2[j]
121+
end
122+
return Polynomial(c, p1.var)
123+
elseif n <= 0
124+
return Polynomial(copy(p2.coeffs) * p1[0], p2.var)
125+
else
126+
return Polynomial(copy(p1.coeffs) * p2[0], p1.var)
106127
end
107-
return Polynomial(c, p1.var)
128+
108129
end

src/polynomials/SparsePolynomial.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ end
9292
degree(p::SparsePolynomial) = isempty(p.coeffs) ? -1 : maximum(keys(p.coeffs))
9393
function isconstant(p::SparsePolynomial)
9494
n = length(keys(p.coeffs))
95-
(n > 1 || iszero(p[0])) && return false
95+
(n > 1 || (n==1 && iszero(p[0]))) && return false
9696
return true
9797
end
9898

@@ -188,7 +188,7 @@ function Base.:+(p1::SparsePolynomial{T}, p2::SparsePolynomial{S}) where {T, S}
188188

189189
isconstant(p1) && return p2 + p1[0]
190190
isconstant(p2) && return p1 + p2[0]
191-
191+
192192
p1.var != p2.var && error("SparsePolynomials must have same variable")
193193

194194
R = promote_type(T,S)

test/StandardBasis.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ end
5555
end
5656

5757
@testset "Other Construction" begin
58-
for P in (ImmutablePolynomial{10}, Polynomial)
58+
for P in (ImmutablePolynomial{10}, Polynomial, SparsePolynomial, LaurentPolynomial)
5959

6060
# Leading 0s
6161
p = P([1, 2, 0, 0])
@@ -77,11 +77,11 @@ end
7777

7878
pNULL = P(Int[])
7979
@test iszero(pNULL)
80-
@test degree(pNULL) == -1
80+
P != LaurentPolynomial && @test degree(pNULL) == -1
8181

8282
p0 = P([0])
8383
@test iszero(p0)
84-
@test degree(p0) == -1
84+
P != LaurentPolynomial && @test degree(p0) == -1
8585

8686
# variable(), P() to generate `x` in given basis
8787
@test degree(variable(P)) == 1
@@ -91,7 +91,7 @@ end
9191
@test variable(P, :y) == P(:y)
9292

9393
# test degree, isconstant
94-
@test degree(zero(P)) == -1
94+
P != LaurentPolynomial && @test degree(zero(P)) == -1
9595
@test degree(one(P)) == 0
9696
@test degree(P(1)) == 0
9797
@test degree(P([1])) == 0
@@ -506,7 +506,7 @@ end
506506
end
507507

508508
# issue 206 with mixed variable types and promotion
509-
for P in (ImmutablePolynomial,)
509+
for P in Ps
510510
λ = P([0,1],)
511511
A = [1 λ; λ^2 λ^3]
512512
@test A == diagm(0 => [1, λ^3], 1=>[λ], -1=>^2])

0 commit comments

Comments
 (0)