Skip to content

Commit 306f9c3

Browse files
Merge pull request #15 from johnmyleswhite/cleanup
Change Taylor finite difference arguments
2 parents 425374a + c5f10e1 commit 306f9c3

File tree

2 files changed

+26
-40
lines changed

2 files changed

+26
-40
lines changed

src/finite_difference.jl

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
##############################################################################
2-
##
3-
## TODO: dtype == :complex
4-
## See minFunc code for examples of how this could be done
5-
##
6-
##############################################################################
7-
81
##############################################################################
92
##
103
## Graveyard of Alternative Functions
@@ -24,13 +17,13 @@
2417

2518
##############################################################################
2619
##
27-
## Derivative of f: R -> R
20+
## Derivative of f: C -> R
2821
##
2922
##############################################################################
3023

3124
function finite_difference{T <: Number}(f::Function,
3225
x::T,
33-
dtype::Symbol)
26+
dtype::Symbol = :central)
3427
if dtype == :forward
3528
epsilon = sqrt(eps(max(one(T), abs(x))))
3629
xplusdx = x + epsilon
@@ -41,13 +34,14 @@ function finite_difference{T <: Number}(f::Function,
4134
xplusdx, xminusdx = x + epsilon, x - epsilon
4235
# Is it better to do 2 * epsilon or xplusdx - xminusdx?
4336
return (f(xplusdx) - f(xminusdx)) / (2 * epsilon)
37+
elseif dtype == :complex
38+
epsilon = eps(x)
39+
xplusdx = x + epsilon * im
40+
return imag(f(xplusdx)) / epsilon
4441
else
45-
error("dtype must be :forward or :central")
42+
error("dtype must be :forward, :central or :complex")
4643
end
4744
end
48-
function finite_difference(f::Function, x::Number)
49-
finite_difference(f, x, :central)
50-
end
5145

5246
##############################################################################
5347
##
@@ -95,7 +89,7 @@ function finite_difference!{S <: Number, T <: Number}(f::Function,
9589
end
9690
function finite_difference{T <: Number}(f::Function,
9791
x::Vector{T},
98-
dtype::Symbol)
92+
dtype::Symbol = :central)
9993
# Allocate memory for gradient
10094
g = Array(Float64, length(x))
10195

@@ -105,9 +99,6 @@ function finite_difference{T <: Number}(f::Function,
10599
# Return mutated gradient
106100
return g
107101
end
108-
function finite_difference{T <: Number}(f::Function, x::Vector{T})
109-
finite_difference(f, x, :central)
110-
end
111102

112103
##############################################################################
113104
##
@@ -121,7 +112,7 @@ function finite_difference_jacobian!{R <: Number,
121112
x::Vector{R},
122113
f_x::Vector{S},
123114
J::Array{T},
124-
dtype::Symbol)
115+
dtype::Symbol = :central)
125116
# What is the dimension of x?
126117
m, n = size(J)
127118

@@ -154,7 +145,7 @@ function finite_difference_jacobian!{R <: Number,
154145
end
155146
function finite_difference_jacobian{T <: Number}(f::Function,
156147
x::Vector{T},
157-
dtype::Symbol)
148+
dtype::Symbol = :central)
158149
# Establish a baseline for f_x
159150
f_x = f(x)
160151

@@ -181,14 +172,9 @@ end
181172
function finite_difference_hessian(f::Function,
182173
g::Function,
183174
x::Number,
184-
dtype::Symbol)
175+
dtype::Symbol = :central)
185176
finite_difference(g, x, dtype)
186177
end
187-
function finite_difference_hessian(f::Function,
188-
g::Function,
189-
x::Number)
190-
finite_difference(g, x, :central)
191-
end
192178

193179
##############################################################################
194180
##
@@ -242,8 +228,12 @@ function finite_difference_hessian{T <: Number}(f::Function,
242228
# Return the Hessian
243229
return H
244230
end
245-
finite_difference_hessian{T}(f::Function, g::Function, x::Vector{T}, dtype::Symbol) = finite_difference_jacobian(g, x, dtype)
246-
finite_difference_hessian{T}(f::Function, g::Function, x::Vector{T}) = finite_difference_jacobian(g, x, :central)
231+
function finite_difference_hessian{T}(f::Function,
232+
g::Function,
233+
x::Vector{T},
234+
dtype::Symbol = :central)
235+
finite_difference_jacobian(g, x, dtype)
236+
end
247237

248238
##############################################################################
249239
##
@@ -255,7 +245,10 @@ finite_difference_hessian{T}(f::Function, g::Function, x::Vector{T}) = finite_di
255245

256246
# Higher precise finite difference method based on Taylor series approximation.
257247
# h is the stepsize
258-
function taylor_finite_difference(f::Function, x::Float64, h::Float64, dtype::Symbol)
248+
function taylor_finite_difference(f::Function,
249+
x::Real,
250+
dtype::Symbol = :central,
251+
h::Real = 10e-4)
259252
if dtype == :forward
260253
f_x = f(x)
261254
d = 2^3 * (2^2 * (f(x + h) - f_x) - (f(x + 2 * h) - f_x))
@@ -270,17 +263,10 @@ function taylor_finite_difference(f::Function, x::Float64, h::Float64, dtype::Sy
270263
end
271264
return d
272265
end
273-
function taylor_finite_difference(f::Function, x::Float64, h::Float64)
274-
taylor_finite_difference(f, x, h, :central)
275-
end
276-
function taylor_finite_difference(f::Function, x::Float64, dtype::Symbol)
277-
taylor_finite_difference(f, x, 10e-4, dtype)
278-
end
279-
function taylor_finite_difference(f::Function, x::Float64)
280-
taylor_finite_difference(f, x, 10e-4)
281-
end
282266

283-
function taylor_finite_difference_hessian(f::Function, x::Float64, h::Float64)
267+
function taylor_finite_difference_hessian(f::Function,
268+
x::Real,
269+
h::Real)
284270
f_x = f(x)
285271
d = 4^6 * (2^4 * (f(x + h) + f(x - h) - 2 * f_x) - (f(x + 2 * h) + f(x - 2 * h) - 2 * f_x))
286272
d += - (2^4 * (f(x + 4 * h) + f(x - 4 * h) - 2 * f_x) - (f(x + 8 * h) + f(x - 8 * h) - 2 * f_x))

test/finite_difference.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,5 @@ gx = gradient(fx)
7272
@elapsed Calculus.finite_difference(x -> x^2, 1.0, :forward)
7373
@elapsed Calculus.finite_difference(x -> x^2, 1.0, :central)
7474
@elapsed Calculus.finite_difference(x -> x^2, 1.0)
75-
@elapsed Calculus.taylor_finite_difference(x -> x^2, 1.0, 10e-4, :forward)
76-
@elapsed Calculus.taylor_finite_difference(x -> x^2, 1.0, 10e-4, :central)
75+
@elapsed Calculus.taylor_finite_difference(x -> x^2, 1.0, :forward, 10e-4)
76+
@elapsed Calculus.taylor_finite_difference(x -> x^2, 1.0, :central, 10e-4)

0 commit comments

Comments
 (0)