Skip to content

Commit 8e213b8

Browse files
Add mutating finite differencer
1 parent a577dc5 commit 8e213b8

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

src/finite_difference.jl

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,35 +51,37 @@ finite_difference(f::Function, x::Number) = finite_difference(f, x, :central)
5151
##
5252
##############################################################################
5353

54-
function finite_difference{T <: Number}(f::Function,
55-
x::Vector{T},
56-
dtype::Symbol)
54+
function finite_difference!{S <: Number, T <: Number}(f::Function,
55+
x::Vector{S},
56+
differential::Vector{T},
57+
dtype::Symbol)
5758
# What is the dimension of x?
5859
n = length(x)
5960

60-
# Storage for forward differences
61-
differential = Array(Float64, n)
62-
6361
# Iterate over each dimension of the gradient separately.
6462
# Use xplusdx to store x + dx instead of creating a new vector on each pass.
6563
# Use xminusdx to store x - dx instead of creating a new vector on each pass.
6664
if dtype == :forward
6765
# Establish a baseline value of f(x).
6866
f_x = f(x)
69-
xplusdx = copy(x)
7067
for i = 1:n
7168
epsilon = sqrt(eps(max(one(T), abs(x[i]))))
72-
xplusdx[i] = x[i] + epsilon
73-
differential[i] = (f(xplusdx) - f_x) / (xplusdx[i] - x[i])
74-
xplusdx[i] = x[i]
69+
oldx = x[i]
70+
x[i] = oldx + epsilon
71+
f_xplusdx = f(x)
72+
x[i] = oldx
73+
differential[i] = (f_xplusdx - f_x) / epsilon
7574
end
7675
elseif dtype == :central
77-
xplusdx, xminusdx = copy(x), copy(x)
7876
for i = 1:n
7977
epsilon = cbrt(eps(max(one(T), abs(x[i]))))
80-
xplusdx[i], xminusdx[i] = x[i] + epsilon, x[i] - epsilon
81-
differential[i] = (f(xplusdx) - f(xminusdx)) / (xplusdx[i] - xminusdx[i])
82-
xplusdx[i], xminusdx[i] = x[i], x[i]
78+
oldx = x[i]
79+
x[i] = oldx + epsilon
80+
f_xplusdx = f(x)
81+
x[i] = oldx - epsilon
82+
f_xminusdx = f(x)
83+
x[i] = oldx
84+
differential[i] = (f_xplusdx - f_xminusdx) / (2 * epsilon)
8385
end
8486
else
8587
error("dtype must be :forward or :central")
@@ -88,6 +90,15 @@ function finite_difference{T <: Number}(f::Function,
8890
# Return the estimated gradient.
8991
return differential
9092
end
93+
function finite_difference{T <: Number}(f::Function,
94+
x::Vector{T},
95+
dtype::Symbol)
96+
# What is the dimension of x?
97+
n = length(x)
98+
differential = Array(Float64, n)
99+
finite_difference!(f, x, differential, dtype)
100+
return differential
101+
end
91102
function finite_difference{T <: Number}(f::Function, x::Vector{T})
92103
finite_difference(f, x, :central)
93104
end
@@ -98,6 +109,7 @@ end
98109
##
99110
##############################################################################
100111

112+
# TODO: Add mutating version
101113
function finite_difference_jacobian{T <: Number}(f::Function, x::Vector{T}, dtype::Symbol)
102114
# What is the dimension of x?
103115
n = length(x)
@@ -152,6 +164,8 @@ finite_difference_hessian(f::Function, g::Function, x::Number) = finite_differen
152164
##
153165
##############################################################################
154166

167+
# TODO: Add mutating version
168+
155169
function finite_difference_hessian{T <: Number}(f::Function, x::Vector{T})
156170
# What is the dimension of x?
157171
n = length(x)

0 commit comments

Comments
 (0)