Skip to content

Commit c8d8cc3

Browse files
committed
Fixed the discrepancy between length and degree
1 parent 449a06c commit c8d8cc3

File tree

3 files changed

+53
-41
lines changed

3 files changed

+53
-41
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ Poly(0.5 - 0.5x^2)
5353

5454
Note that operations involving polynomials with different variables will error.
5555

56+
To get the degree of the polynomial use `degree` method
57+
```
58+
julia> degree(p)
59+
1
60+
61+
julia> degree(p^2)
62+
2
63+
64+
julia> degree(p-p)
65+
0
66+
```
67+
5668
```julia
5769
julia> p = Poly([1, 2, 3], :x)
5870
julia> q = Poly([1, 2, 3], :s)

src/Polynomials.jl

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Polynomials
66
using Compat
77

88
export Poly, polyval, polyint, polyder, poly, roots
9-
export Pade, padeval
9+
export Pade, padeval, degree
1010

1111
import Base: length, endof, getindex, setindex!, copy, zero, one, convert
1212
import Base: show, print, *, /, //, -, +, ==, divrem, rem, eltype
@@ -20,7 +20,14 @@ immutable Poly{T<:Number}
2020
a::Vector{T}
2121
var::Symbol
2222
function Poly(a::Vector{T}, var)
23-
new(a, symbol(var))
23+
# if a == [] we replace it with a = [0]
24+
if length(a) == 0
25+
return new(zeros(T,1), symbol(var))
26+
else
27+
# determine the last nonzero element and truncate a accordingly
28+
a_last = max(1,findlast( p->(abs(p) > 2*eps(T)), a))
29+
new(a[1:a_last], symbol(var))
30+
end
2431
end
2532
end
2633

@@ -33,6 +40,7 @@ promote_rule{T, S}(::Type{Poly{T}}, ::Type{Poly{S}}) = Poly{promote_type(T, S)}
3340
eltype{T}(::Poly{T}) = T
3441

3542
length(p::Poly) = length(p.a)
43+
degree(p::Poly) = length(p)-1
3644
endof(p::Poly) = length(p) - 1
3745

3846
getindex{T}(p::Poly{T}, i) = (i+1 > length(p.a) ? zero(T) : p.a[i+1])
@@ -180,53 +188,48 @@ function *{T,S}(p1::Poly{T}, p2::Poly{S})
180188
error("Polynomials must have same variable")
181189
end
182190
R = promote_type(T,S)
183-
n = degree(p1)
184-
m = degree(p2)
185-
a = Poly(zeros(R,m+n+1), p1.var)
191+
n = length(p1)-1
192+
m = length(p2)-1
193+
a = zeros(R,m+n+1)
194+
186195
for i = 0:n
187196
for j = 0:m
188-
a[i+j] += p1[i] * p2[j]
189-
end
190-
end
191-
a
192-
end
193-
194-
function degree{T}(p::Poly{T})
195-
for i = length(p):-1:0
196-
if abs(p[i]) > 2*eps(T)
197-
return i
197+
a[i+j+1] += p1[i] * p2[j]
198198
end
199199
end
200-
return 0
200+
Poly(a,p1.var)
201201
end
202202

203203
function divrem{T, S}(num::Poly{T}, den::Poly{S})
204204
if num.var != den.var
205205
error("Polynomials must have same variable")
206206
end
207-
m = degree(den)
207+
m = length(den)-1
208208
if m == 0 && den[0] == 0
209209
throw(DivideError())
210210
end
211211
R = typeof(one(T)/one(S))
212-
n = degree(num)
212+
n = length(num)-1
213213
deg = n-m+1
214214
if deg <= 0
215215
return convert(Poly{R}, zero(num)), convert(Poly{R}, num)
216216
end
217-
# We will still modify q,r, but already wrap it in a
218-
# polynomial, so the indexing below is more natural
219-
pQ = Poly(zeros(R, deg), num.var)
220-
pR = Poly(zeros(R, n+1), num.var)
221-
pR.a[:] = num.a[1:(n+1)]
217+
218+
aQ = zeros(R, deg)
219+
# aR = deepcopy(num.a)
220+
@show num.a
221+
aR = R[ num.a[i] for i = 1:n+1 ]
222222
for i = n:-1:m
223-
quot = pR[i] / den[m]
224-
pQ[i-m] = quot
223+
quot = aR[i+1] / den[m]
224+
aQ[i-m+1] = quot
225225
for j = 0:m
226226
elem = den[j]*quot
227-
pR[i-(m-j)] -= elem
227+
aR[i-(m-j)+1] -= elem
228228
end
229229
end
230+
pQ = Poly(aQ, num.var)
231+
pR = Poly(aR, num.var)
232+
230233
return pQ, pR
231234
end
232235
/(num::Poly, den::Poly) = divrem(num, den)[1]
@@ -236,12 +239,7 @@ function ==(p1::Poly, p2::Poly)
236239
if p1.var != p2.var
237240
return false
238241
else
239-
for i = 1:max(length(p1),length(p2))
240-
if p1[i] != p2[i]
241-
return false
242-
end
243-
end
244-
return true
242+
return p1.a == p2.a
245243
end
246244
end
247245

@@ -266,11 +264,10 @@ function polyint{T}(p::Poly{T}, k::Number=0)
266264
R = typeof(one(T)/1)
267265
a2 = Array(R, n+1)
268266
a2[1] = k
269-
p2 = Poly(a2, p.var)
270267
for i = 1:n
271-
p2[i] = p[i-1] / i
268+
a2[i+1] = p[i-1] / i
272269
end
273-
p2
270+
return Poly(a2, p.var)
274271
end
275272

276273
function polyder{T}(p::Poly{T}, order::Int=1)
@@ -282,11 +279,11 @@ function polyder{T}(p::Poly{T}, order::Int=1)
282279
elseif order == 0
283280
return p
284281
else
285-
p2 = Poly(Array(T, n-order), p.var)
282+
a2 = Array(T, n-order)
286283
for i = order:n-1
287-
p2[i-order] = p[i] * prod((i-order+1):i)
284+
a2[i-order+1] = p[i] * prod((i-order+1):i)
288285
end
289-
return p2
286+
return Poly(a2, p.var)
290287
end
291288
end
292289

test/runtests.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ pN = Poly([276,3,87,15,24,0])
1414
pR = Poly([3//4, -2//1, 1//1])
1515
p1000 = Poly(randn(1000))
1616

17-
@test length(pNULL) == 0
17+
@test length(pNULL) == 1
18+
@test length(p1000-p1000) == 1
19+
@test length(p1000^0) == 1
20+
@test length(0*p1000) == 1
1821
@test length(p1000) == 1000
1922
sprint(show, p1000)
2023
sprint(show, pNULL)
@@ -33,7 +36,7 @@ sprint(show, pNULL)
3336
@test pNULL^3 == pNULL
3437
@test pNULL*pNULL == pNULL
3538

36-
@test map(Polynomials.degree, [pNULL,p0,p1,p2,p3,p4,p5,pN,pR,p1000]) == [0,0,0,1,2,3,4,4,2,999]
39+
@test map(degree, [pNULL,p0,p1,p2,p3,p4,p5,pN,pR,p1000]) == [0,0,0,1,2,3,4,4,2,999]
3740

3841
@test polyval(pN, -.125) == 276.9609375
3942
@test polyval(pNULL, 10) == 0
@@ -47,7 +50,7 @@ sprint(show, pNULL)
4750
@test polyder(p1) == polyder(p0) == polyder(pNULL) == pNULL
4851

4952
@test poly([-1,-1]) == p3
50-
@test roots(p0)==roots(p1)==roots(pNULL)==[]
53+
@test roots(p0)==roots(p1)==roots(pNULL)==[]
5154
@test roots(p2) == [-1]
5255
a_roots = copy(pN.a)
5356
@test all(abs(sort(roots(poly(a_roots))) - sort(a_roots)) .< 1e6)

0 commit comments

Comments
 (0)