Skip to content

Commit 6b65f47

Browse files
committed
Merge pull request #16 from MikaelSlevinsky/master
Basic support for Pade approximants
2 parents 3a01738 + 051d82a commit 6b65f47

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

src/Polynomials.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Polynomials
44
#todo: sparse polynomials?
55

66
export Poly, polyval, polyint, polyder, poly, roots
7+
export Pade, padeval
78

89
import Base: length, endof, getindex, setindex!, copy, zero, one, convert
910
import Base: show, print, *, /, //, -, +, ==, divrem, rem, eltype
@@ -341,7 +342,7 @@ function roots{T}(p::Poly{T})
341342
return r
342343
end
343344

344-
function gcd{T<:FloatingPoint, S<:FloatingPoint}(a::Poly{T}, b::Poly{S})
345+
function gcd{T, S}(a::Poly{T}, b::Poly{S})
345346
#Finds the Greatest Common Denominator of two polynomials recursively using
346347
#Euclid's algorithm: http://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclid.27s_algorithm
347348
if all(abs(b.a).<=2*eps(S))
@@ -351,4 +352,7 @@ function gcd{T<:FloatingPoint, S<:FloatingPoint}(a::Poly{T}, b::Poly{S})
351352
return gcd(b, r)
352353
end
353354
end
355+
356+
include("pade.jl")
357+
354358
end # module Poly

src/pade.jl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
immutable Pade{T<:Number,S<:Number}
2+
p::Poly{T}
3+
q::Poly{S}
4+
var::Symbol
5+
function Pade(p::Poly{T},q::Poly{S})
6+
if p.var != q.var
7+
error("Polynomials must have same variable")
8+
end
9+
new(p, q, p.var)
10+
end
11+
end
12+
Pade{T<:Number,S<:Number}(p::Poly{T}, q::Poly{S}) = Pade{T,S}(p,q)
13+
14+
function Pade{T}(c::Poly{T},m::Int,n::Int)
15+
@assert m+n < length(c)
16+
rold,rnew = Poly([zeros(T,m+n+1),one(T)],c.var),Poly(c.a[1:m+n+1],c.var)
17+
uold,vold = Poly([one(T)],c.var),Poly([zero(T)],c.var)
18+
unew,vnew = vold,uold
19+
for i=1:n
20+
temp0,temp1,temp2 = rnew,unew,vnew
21+
q,rnew = divrem(rold,rnew)
22+
unew,vnew = uold-q*unew,vold-q*vnew
23+
rold,uold,vold = temp0,temp1,temp2
24+
25+
end
26+
if vnew[0] == 0
27+
d = gcd(rnew,vnew)
28+
rnew /= d
29+
vnew /= d
30+
end
31+
Pade(rnew/vnew[0],vnew/vnew[0])
32+
end
33+
padeval{T}(PQ::Pade{T},x) = polyval(PQ.p,x)./polyval(PQ.q,x)

test/tests.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,30 @@ pS3 = Poly([1, 2, 3, 4, 5], :s)
8686
@test_throws ErrorException pS1 * pX
8787
@test_throws ErrorException pS1 / pX
8888
@test_throws ErrorException pS1 % pX
89+
90+
#Tests for Pade approximants
91+
92+
println("Test for the exponential function.")
93+
a = Poly(1.//convert(Vector{Int},gamma(1:17)),"x")
94+
PQexp = Pade(a,8,8)
95+
@test padeval(PQexp,1.0) == exp(1.0)
96+
@test padeval(PQexp,-1.0) == exp(-1.0)
97+
98+
println("Test for the sine function.")
99+
b = Poly(convert(Vector{BigInt},sinpi((0:16)/2)).//convert(Vector{BigInt},gamma(BigFloat("1.0"):BigFloat("17.0"))),"x")
100+
PQsin = Pade(b,8,7)
101+
@test isapprox(padeval(PQsin,1.0),sin(1.0))
102+
@test isapprox(padeval(PQsin,-1.0),sin(-1.0))
103+
104+
println("Test for the cosine function.")
105+
c = Poly(convert(Vector{BigInt},sinpi((1:17)/2)).//convert(Vector{BigInt},gamma(BigFloat("1.0"):BigFloat("17.0"))),"x")
106+
PQcos = Pade(c,8,8)
107+
@test isapprox(padeval(PQcos,1.0),cos(1.0))
108+
@test isapprox(padeval(PQcos,-1.0),cos(-1.0))
109+
110+
println("Test for the summation of a factorially divergent series.")
111+
d = Poly(convert(Vector{BigInt},(-1).^(0:60).*gamma(BigFloat("1.0"):BigFloat("61.0"))).//1,"x")
112+
PQexpint = Pade(d,30,30)
113+
println("The approximate sum of the divergent series is: ",float64(padeval(PQexpint,1.0)))
114+
println("The approximate sum of the convergent series is: ",exp(1)*(-γ-sum([(-1).^k/k./gamma(k+1) for k=1:20])))
115+
@test isapprox(padeval(PQexpint,1.0) , exp(1)*(-γ-sum([(-1).^k/k./gamma(k+1) for k=1:20])))

0 commit comments

Comments
 (0)