@@ -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
9092end
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
91102function finite_difference {T <: Number} (f:: Function , x:: Vector{T} )
92103 finite_difference (f, x, :central )
93104end
98109# #
99110# #############################################################################
100111
112+ # TODO : Add mutating version
101113function 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+
155169function finite_difference_hessian {T <: Number} (f:: Function , x:: Vector{T} )
156170 # What is the dimension of x?
157171 n = length (x)
0 commit comments