-
Notifications
You must be signed in to change notification settings - Fork 39
/
finitediff.jl
39 lines (34 loc) · 1.26 KB
/
finitediff.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
#=
Very heavily inspired by Calculus.jl, but with an emphasis on performance and DiffEq API convenience.
=#
#=
Compute the finite difference interval epsilon.
Reference: Numerical Recipes, chapter 5.7.
=#
@inline function compute_epsilon(::Type{Val{:forward}}, x::T, eps_sqrt=sqrt(eps(real(T)))) where T<:Number
eps_sqrt * max(one(real(T)), abs(x))
end
@inline function compute_epsilon(::Type{Val{:central}}, x::T, eps_cbrt=cbrt(eps(real(T)))) where T<:Number
eps_cbrt * max(one(real(T)), abs(x))
end
@inline function compute_epsilon(::Type{Val{:complex}}, x::T, ::Union{Void,T}=nothing) where T<:Real
eps(T)
end
@inline function compute_epsilon_factor(fdtype::DataType, ::Type{T}) where T<:Number
if fdtype==Val{:forward}
return sqrt(eps(real(T)))
elseif fdtype==Val{:central}
return cbrt(eps(real(T)))
else
return one(real(T))
end
end
function fdtype_error(funtype::Type{T}=Float64) where T
if funtype<:Real
error("Unrecognized fdtype: valid values are Val{:forward}, Val{:central} and Val{:complex}.")
elseif funtype<:Complex
error("Unrecognized fdtype: valid values are Val{:forward} or Val{:central}.")
else
error("Unrecognized returntype: should be a subtype of Real or Complex.")
end
end