-
Notifications
You must be signed in to change notification settings - Fork 77
/
derivative.jl
97 lines (91 loc) · 3.9 KB
/
derivative.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
function derivative(f, ftype::Symbol, dtype::Symbol)
if ftype == :scalar
return x::Number -> finite_difference(f, float(x), dtype)
elseif ftype == :vector
return x::Vector -> finite_difference(f, float(x), dtype)
else
error("ftype must :scalar or :vector")
end
end
derivative(f, x::Union{T, Vector{T}}, dtype::Symbol = :central) where {T <: Number} = finite_difference(f, float(x), dtype)
derivative(f, dtype::Symbol = :central) = derivative(f, :scalar, dtype)
gradient(f, x::Union{T, Vector{T}}, dtype::Symbol = :central) where {T <: Number} = finite_difference(f, float(x), dtype)
gradient(f, dtype::Symbol = :central) = derivative(f, :vector, dtype)
@static if isdefined(Compat.LinearAlgebra, :gradient)
function Compat.LinearAlgebra.gradient(f, x::Union{T, Vector{T}}, dtype::Symbol = :central) where T <: Number
Base.depwarn("The finite difference methods from Calculus.jl no longer extend " *
"Base.gradient and should be called as Calculus.gradient instead. " *
"This usage is deprecated.", :gradient)
Calculus.gradient(f,x,dtype)
end
function Compat.LinearAlgebra.gradient(f, dtype::Symbol = :central)
Base.depwarn("The finite difference methods from Calculus.jl no longer extend " *
"Base.gradient and should be called as Calculus.gradient instead. " *
"This usage is deprecated.", :gradient)
Calculus.gradient(f,dtype)
end
end
if isdefined(Base, :adjoint)
Base.adjoint(f::Function) = derivative(f)
else
Base.ctranspose(f::Function) = derivative(f)
end
function jacobian(f, x::Vector{T}, dtype::Symbol) where T <: Number
finite_difference_jacobian(f, x, dtype)
end
function jacobian(f, dtype::Symbol)
g(x::Vector) = finite_difference_jacobian(f, x, dtype)
return g
end
jacobian(f) = jacobian(f, :central)
function second_derivative(f, g, ftype::Symbol, dtype::Symbol)
if ftype == :scalar
return x::Number -> finite_difference_hessian(f, g, x, dtype)
elseif ftype == :vector
return x::Vector -> finite_difference_hessian(f, g, x, dtype)
else
error("ftype must :scalar or :vector")
end
end
function second_derivative(f, g, x::Union{T, Vector{T}}, dtype::Symbol) where T <: Number
finite_difference_hessian(f, g, x, dtype)
end
function hessian(f, g, x::Union{T, Vector{T}}, dtype::Symbol) where T <: Number
finite_difference_hessian(f, g, x, dtype)
end
function second_derivative(f, g, x::Union{T, Vector{T}}) where T <: Number
finite_difference_hessian(f, g, x, :central)
end
function hessian(f, g, x::Union{T, Vector{T}}) where T <: Number
finite_difference_hessian(f, g, x, :central)
end
function second_derivative(f, x::Number, dtype::Symbol)
finite_difference_hessian(f, derivative(f), x, dtype)
end
function hessian(f, x::Number, dtype::Symbol)
finite_difference_hessian(f, derivative(f), x, dtype)
end
function second_derivative(f, x::Vector{T}, dtype::Symbol) where T <: Number
finite_difference_hessian(f, gradient(f), x, dtype)
end
function hessian(f, x::Vector{T}, dtype::Symbol) where T <: Number
finite_difference_hessian(f, gradient(f), x, dtype)
end
function second_derivative(f, x::Number)
finite_difference_hessian(f, derivative(f), x, :central)
end
function hessian(f, x::Number)
finite_difference_hessian(f, derivative(f), x, :central)
end
function second_derivative(f, x::Vector{T}) where T <: Number
finite_difference_hessian(f, gradient(f), x, :central)
end
function hessian(f, x::Vector{T}) where T <: Number
finite_difference_hessian(f, gradient(f), x, :central)
end
second_derivative(f, g, dtype::Symbol) = second_derivative(f, g, :scalar, dtype)
second_derivative(f, g) = second_derivative(f, g, :scalar, :central)
second_derivative(f) = second_derivative(f, derivative(f), :scalar, :central)
hessian(f, g, dtype::Symbol) = second_derivative(f, g, :vector, dtype)
hessian(f, g) = second_derivative(f, g, :vector, :central)
hessian(f) = second_derivative(f, gradient(f), :vector, :central)