Skip to content

Commit c2bc2b1

Browse files
updated and documented
1 parent 86f03db commit c2bc2b1

File tree

3 files changed

+168
-6
lines changed

3 files changed

+168
-6
lines changed

README.md

+164-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,168 @@
88
[![codecov.io](http://codecov.io/github/ChrisRackauckas/DiffEqDiffTools.jl/coverage.svg?branch=master)](http://codecov.io/github/ChrisRackauckas/DiffEqDiffTools.jl?branch=master)
99
[![DiffEqDiffTools](http://pkg.julialang.org/badges/DiffEqDiffTools_0.6.svg)](http://pkg.julialang.org/?pkg=DiffEqDiffTools)
1010

11-
DiffEqDiffTools.jl is a component package in the DifferentialEquations ecosystem. It holds the common tools for taking derivatives, Jacobians, etc. and utilizing the traits from the ParameterizedFunctions when possible for increasing the speed of calculations. Users interested in using this functionality should check out [DifferentialEquations.jl](https://github.com/JuliaDiffEq/DifferentialEquations.jl/blob/master/src/DifferentialEquations.jl).
11+
DiffEqDiffTools.jl is a component package in the DifferentialEquations ecosystem.
12+
It holds the common tools for taking derivatives, Jacobians, etc. and utilizing
13+
the traits from the ParameterizedFunctions when possible for increasing the
14+
speed of calculations. Users interested in using this functionality should check
15+
out [DifferentialEquations.jl](https://github.com/JuliaDiffEq/DifferentialEquations.jl/blob/master/src/DifferentialEquations.jl).
1216

13-
Note: This is currently a work in progress. Anyways, it will be behind the scenes. If you're interesting in helping develop it, please contact Chris Rackauckas.
17+
## General Structure
18+
19+
The general structure of the library is as follows. You can call the differencing
20+
functions directly and this will allocate a temporary cache to solve the problem
21+
with. To make this non-allocating for repeat calls, you can call the cache
22+
construction functions. Each cache construction function has two possibilities:
23+
one version where you give it prototype arrays and it generates the cache
24+
variables, and one fully non-allocating version where you give it the cache
25+
variables. This is summarized as:
26+
27+
- Just want a quick derivative? Calculating once? Call the differencing function.
28+
- Going to calculate the derivative multiple times but don't have cache arrays
29+
around? Use the allocating cache and then pass this into the differencing
30+
function (this will allocate only in the one cache construction).
31+
- Have cache variables around from your own algorithm and want to re-use them
32+
in the differencing functions? Use the non-allocating cache construction
33+
and pass the cache to the differencing function.
34+
35+
## Scalar Derivatives
36+
37+
```julia
38+
finite_difference_derivative(f, x::T, fdtype::Type{T1}=Val{:central},
39+
returntype::Type{T2}=eltype(x), f_x::Union{Void,T}=nothing)
40+
```
41+
42+
## Multi-Point Derivatives
43+
44+
### Differencing Calls
45+
46+
```julia
47+
# Cache-less but non-allocating if `fx` and `epsilon` are supplied
48+
# fx must be f(x)
49+
finite_difference_derivative(
50+
f,
51+
x :: AbstractArray{<:Number},
52+
fdtype :: Type{T1} = Val{:central},
53+
returntype :: Type{T2} = eltype(x), # return type of f
54+
fx :: Union{Void,AbstractArray{<:Number}} = nothing,
55+
epsilon :: Union{Void,AbstractArray{<:Real}} = nothing)
56+
57+
finite_difference_derivative!(
58+
df :: AbstractArray{<:Number},
59+
f,
60+
x :: AbstractArray{<:Number},
61+
fdtype :: Type{T1} = Val{:central},
62+
returntype :: Type{T2} = eltype(x),
63+
fx :: Union{Void,AbstractArray{<:Number}} = nothing,
64+
epsilon :: Union{Void,AbstractArray{<:Real}} = nothing)
65+
66+
# Cached
67+
finite_difference_derivative!(df::AbstractArray{<:Number}, f,
68+
x::AbstractArray{<:Number},
69+
cache::DerivativeCache{T1,T2,fdtype,returntype})
70+
```
71+
72+
### Allocating and Non-Allocating Constructor
73+
74+
```julia
75+
DerivativeCache(
76+
x :: AbstractArray{<:Number},
77+
fx :: Union{Void,AbstractArray{<:Number}} = nothing,
78+
epsilon :: Union{Void,AbstractArray{<:Real}} = nothing,
79+
fdtype :: Type{T1} = Val{:central},
80+
returntype :: Type{T2} = eltype(x))
81+
```
82+
83+
This allocates either `fx` or `epsilon` if these are nothing and they are needed.
84+
`fx` is the current call of `f(x)` and is required for forward-differencing
85+
(otherwise is not necessary).
86+
87+
## Gradients
88+
89+
### Differencing Calls
90+
91+
```julia
92+
# Cache-less
93+
finite_difference_gradient(f, x, fdtype::Type{T1}=Val{:central},
94+
returntype::Type{T2}=eltype(x),
95+
inplace::Type{Val{T3}}=Val{true})
96+
finite_difference_gradient!(df, f, x, fdtype::Type{T1}=Val{:central},
97+
returntype::Type{T2}=eltype(df),
98+
inplace::Type{Val{T3}}=Val{true})
99+
100+
# Cached
101+
finite_difference_gradient!(df::AbstractArray{<:Number}, f,
102+
x::AbstractArray{<:Number},
103+
cache::GradientCache)
104+
```
105+
106+
### Allocating Cache Constructor
107+
108+
```julia
109+
GradientCache(
110+
df :: Union{<:Number,AbstractArray{<:Number}},
111+
x :: Union{<:Number, AbstractArray{<:Number}},
112+
fdtype :: Type{T1} = Val{:central},
113+
returntype :: Type{T2} = eltype(df),
114+
inplace :: Type{Val{T3}} = Val{true})
115+
```
116+
117+
### Non-Allocating Cache Constructor
118+
119+
```julia
120+
GradientCache(
121+
c1 :: Union{Void,AbstractArray{<:Number}},
122+
c2 :: Union{Void,AbstractArray{<:Number}},
123+
fx :: Union{Void,<:Number,AbstractArray{<:Number}} = nothing,
124+
fdtype :: Type{T1} = Val{:central},
125+
returntype :: Type{T2} = eltype(df),
126+
inplace :: Type{Val{T3}} = Val{true})
127+
```
128+
129+
Note that here `fx` is a cached function call of `f`. If you provide `fx`, then
130+
`fx` will be used in the forward differencing method to skip a function call.
131+
It is on you to make sure that you update `cache.fx` every time before
132+
calling `finite_difference_gradient!`. A good use of this is if you have a
133+
cache array for the output of `fx` already being used, you can make it alias
134+
into the differencing algorithm here.
135+
136+
## Jacobians
137+
138+
### Differencing Calls
139+
140+
```julia
141+
# Cache-less
142+
finite_difference_jacobian(f, x::AbstractArray{<:Number},
143+
fdtype :: Type{T1}=Val{:central},
144+
returntype :: Type{T2}=eltype(x),
145+
inplace :: Type{Val{T3}}=Val{true})
146+
147+
# Cached
148+
finite_difference_jacobian(f,x,cache::JacobianCache)
149+
finite_difference_jacobian!(J::AbstractMatrix{<:Number},f,
150+
x::AbstractArray{<:Number},cache::JacobianCache)
151+
```
152+
153+
### Allocating Cache Constructor
154+
155+
```julia
156+
JacobianCache(
157+
x,
158+
fdtype :: Type{T1} = Val{:central},
159+
returntype :: Type{T2} = eltype(x),
160+
inplace :: Type{Val{T3}} = Val{true})
161+
```
162+
163+
This assumes the Jacobian is square.
164+
165+
### Non-Allocating Cache Constructor
166+
167+
```julia
168+
JacobianCache(
169+
x1 ,
170+
fx ,
171+
fx1,
172+
fdtype :: Type{T1} = Val{:central},
173+
returntype :: Type{T2} = eltype(fx),
174+
inplace :: Type{Val{T3}} = Val{true})
175+
```

src/gradients.jl

+2-3
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ function GradientCache(
5050
end
5151

5252
function GradientCache(
53+
c1 :: Union{Void,AbstractArray{<:Number}},
54+
c2 :: Union{Void,AbstractArray{<:Number}},
5355
fx :: Union{Void,<:Number,AbstractArray{<:Number}} = nothing,
54-
c1 :: Union{Void,AbstractArray{<:Number}} = nothing,
55-
c2 :: Union{Void,AbstractArray{<:Number}} = nothing,
5656
fdtype :: Type{T1} = Val{:central},
5757
returntype :: Type{T2} = eltype(df),
5858
inplace :: Type{Val{T3}} = Val{true}) where {T1,T2,T3}
@@ -249,7 +249,6 @@ function finite_difference_gradient!(df::StridedVector{<:Number}, f, x::StridedV
249249
fx0 = f(x)
250250
x[i] += epsilon
251251
dfi = (f(x) - fx0) / epsilon
252-
@show dfi
253252
x[i] = x_old
254253
end
255254

src/jacobians.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ function finite_difference_jacobian(f,x,cache::JacobianCache)
9999
J
100100
end
101101

102-
function finite_difference_jacobian!(J::AbstractMatrix{<:Number}, f,x::AbstractArray{<:Number},
102+
function finite_difference_jacobian!(J::AbstractMatrix{<:Number},
103+
f,x::AbstractArray{<:Number},
103104
cache::JacobianCache{T1,T2,T3,fdtype,returntype,inplace}) where {T1,T2,T3,fdtype,returntype,inplace}
104105

105106
m, n = size(J)

0 commit comments

Comments
 (0)