Skip to content

Commit eef6fac

Browse files
committed
Merge pull request #29 from pwl/master
Fixed the discrepancy between length and degree
2 parents 0c2c054 + c8d8cc3 commit eef6fac

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
@@ -23,7 +23,14 @@ immutable Poly{T<:Number}
2323
a::Vector{T}
2424
var::Symbol
2525
function Poly(a::Vector{T}, var)
26-
new(a, symbol(var))
26+
# if a == [] we replace it with a = [0]
27+
if length(a) == 0
28+
return new(zeros(T,1), symbol(var))
29+
else
30+
# determine the last nonzero element and truncate a accordingly
31+
a_last = max(1,findlast( p->(abs(p) > 2*eps(T)), a))
32+
new(a[1:a_last], symbol(var))
33+
end
2734
end
2835
end
2936

@@ -36,6 +43,7 @@ promote_rule{T, S}(::Type{Poly{T}}, ::Type{Poly{S}}) = Poly{promote_type(T, S)}
3643
eltype{T}(::Poly{T}) = T
3744

3845
length(p::Poly) = length(p.a)
46+
degree(p::Poly) = length(p)-1
3947
endof(p::Poly) = length(p) - 1
4048

4149
getindex{T}(p::Poly{T}, i) = (i+1 > length(p.a) ? zero(T) : p.a[i+1])
@@ -183,53 +191,48 @@ function *{T,S}(p1::Poly{T}, p2::Poly{S})
183191
error("Polynomials must have same variable")
184192
end
185193
R = promote_type(T,S)
186-
n = degree(p1)
187-
m = degree(p2)
188-
a = Poly(zeros(R,m+n+1), p1.var)
194+
n = length(p1)-1
195+
m = length(p2)-1
196+
a = zeros(R,m+n+1)
197+
189198
for i = 0:n
190199
for j = 0:m
191-
a[i+j] += p1[i] * p2[j]
192-
end
193-
end
194-
a
195-
end
196-
197-
function degree{T}(p::Poly{T})
198-
for i = length(p):-1:0
199-
if abs(p[i]) > 2*eps(T)
200-
return i
200+
a[i+j+1] += p1[i] * p2[j]
201201
end
202202
end
203-
return 0
203+
Poly(a,p1.var)
204204
end
205205

206206
function divrem{T, S}(num::Poly{T}, den::Poly{S})
207207
if num.var != den.var
208208
error("Polynomials must have same variable")
209209
end
210-
m = degree(den)
210+
m = length(den)-1
211211
if m == 0 && den[0] == 0
212212
throw(DivideError())
213213
end
214214
R = typeof(one(T)/one(S))
215-
n = degree(num)
215+
n = length(num)-1
216216
deg = n-m+1
217217
if deg <= 0
218218
return convert(Poly{R}, zero(num)), convert(Poly{R}, num)
219219
end
220-
# We will still modify q,r, but already wrap it in a
221-
# polynomial, so the indexing below is more natural
222-
pQ = Poly(zeros(R, deg), num.var)
223-
pR = Poly(zeros(R, n+1), num.var)
224-
pR.a[:] = num.a[1:(n+1)]
220+
221+
aQ = zeros(R, deg)
222+
# aR = deepcopy(num.a)
223+
@show num.a
224+
aR = R[ num.a[i] for i = 1:n+1 ]
225225
for i = n:-1:m
226-
quot = pR[i] / den[m]
227-
pQ[i-m] = quot
226+
quot = aR[i+1] / den[m]
227+
aQ[i-m+1] = quot
228228
for j = 0:m
229229
elem = den[j]*quot
230-
pR[i-(m-j)] -= elem
230+
aR[i-(m-j)+1] -= elem
231231
end
232232
end
233+
pQ = Poly(aQ, num.var)
234+
pR = Poly(aR, num.var)
235+
233236
return pQ, pR
234237
end
235238
/(num::Poly, den::Poly) = divrem(num, den)[1]
@@ -239,12 +242,7 @@ function ==(p1::Poly, p2::Poly)
239242
if p1.var != p2.var
240243
return false
241244
else
242-
for i = 1:max(length(p1),length(p2))
243-
if p1[i] != p2[i]
244-
return false
245-
end
246-
end
247-
return true
245+
return p1.a == p2.a
248246
end
249247
end
250248

@@ -273,11 +271,10 @@ function polyint{T}(p::Poly{T}, k::Number=0)
273271
R = typeof(one(T)/1)
274272
a2 = Array(R, n+1)
275273
a2[1] = k
276-
p2 = Poly(a2, p.var)
277274
for i = 1:n
278-
p2[i] = p[i-1] / i
275+
a2[i+1] = p[i-1] / i
279276
end
280-
p2
277+
return Poly(a2, p.var)
281278
end
282279

283280
function polyder{T}(p::Poly{T}, order::Int=1)
@@ -289,11 +286,11 @@ function polyder{T}(p::Poly{T}, order::Int=1)
289286
elseif order == 0
290287
return p
291288
else
292-
p2 = Poly(Array(T, n-order), p.var)
289+
a2 = Array(T, n-order)
293290
for i = order:n-1
294-
p2[i-order] = p[i] * prod((i-order+1):i)
291+
a2[i-order+1] = p[i] * prod((i-order+1):i)
295292
end
296-
return p2
293+
return Poly(a2, p.var)
297294
end
298295
end
299296

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
@@ -52,7 +55,7 @@ if VERSION >= v"0.4"
5255
end
5356

5457
@test poly([-1,-1]) == p3
55-
@test roots(p0)==roots(p1)==roots(pNULL)==[]
58+
@test roots(p0)==roots(p1)==roots(pNULL)==[]
5659
@test roots(p2) == [-1]
5760
a_roots = copy(pN.a)
5861
@test all(abs(sort(roots(poly(a_roots))) - sort(a_roots)) .< 1e6)

0 commit comments

Comments
 (0)