Skip to content

Commit 065f079

Browse files
committed
update docs
1 parent 84ae3f4 commit 065f079

27 files changed

+448
-431
lines changed

docs/_rst/source/advanced_usage.rst

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Accessing Lower-Order Results
99

1010
Let's say you want to calculate the value, gradient, and Hessian of some function ``f`` at
1111
an input ``x``. You could execute ``f(x)``, ``ForwardDiff.gradient(f, x)`` and
12-
``ForwardDiff.hessian(f, x)``, but that would be a **horribly redundant way to accomplish
12+
``ForwardDiff.hessian(f, x)``, but that would be a **horribly redundant way to accomplish
1313
this task!**
1414

1515
In the course of calculating higher-order derivatives, ForwardDiff ends up calculating all
@@ -37,7 +37,7 @@ For example:
3737

3838
.. code-block:: julia
3939
40-
julia> import ForwardDiff
40+
julia> using ForwardDiff: GradientConfig, Chunk, gradient!
4141
4242
# let's use a Rosenbrock function as our target function
4343
julia> function rosenbrock(x)
@@ -58,25 +58,25 @@ For example:
5858
julia> out = similar(x);
5959
6060
# construct GradientConfig with chunk size of 1
61-
julia> cfg1 = ForwardDiff.GradientConfig{1}(x);
61+
julia> cfg1 = GradientConfig(rosenbrock, x, Chunk{1}());
6262
6363
# construct GradientConfig with chunk size of 4
64-
julia> cfg4 = ForwardDiff.GradientConfig{4}(x);
64+
julia> cfg4 = GradientConfig(rosenbrock, x, Chunk{4}());
6565
6666
# construct GradientConfig with chunk size of 10
67-
julia> cfg10 = ForwardDiff.GradientConfig{10}(x);
67+
julia> cfg10 = GradientConfig(rosenbrock, x, Chunk{10}());
6868
6969
# (input length of 10000) / (chunk size of 1) = (10000 1-element chunks)
70-
julia> @time ForwardDiff.gradient!(out, rosenbrock, x, cfg1);
71-
0.408305 seconds (4 allocations: 160 bytes)
70+
julia> @time gradient!(out, rosenbrock, x, cfg1);
71+
0.775139 seconds (4 allocations: 160 bytes)
7272
7373
# (input length of 10000) / (chunk size of 4) = (2500 4-element chunks)
74-
julia> @time ForwardDiff.gradient!(out, rosenbrock, x, cfg4);
75-
0.295764 seconds (4 allocations: 160 bytes)
74+
julia> @time gradient!(out, rosenbrock, x, cfg4);
75+
0.386459 seconds (4 allocations: 160 bytes)
7676
7777
# (input length of 10000) / (chunk size of 10) = (1000 10-element chunks)
78-
julia> @time ForwardDiff.gradient!(out, rosenbrock, x, cfg10);
79-
0.267396 seconds (4 allocations: 160 bytes)
78+
julia> @time gradient!(out, rosenbrock, x, cfg10);
79+
0.282529 seconds (4 allocations: 160 bytes)
8080
8181
If you do not explicity provide a chunk size, ForwardDiff will try to guess one for you
8282
based on your input vector:
@@ -85,10 +85,10 @@ based on your input vector:
8585
8686
# The GradientConfig constructor will automatically select a
8787
# chunk size in one is not explicitly provided
88-
julia> cfg = ForwardDiff.GradientConfig(x);
88+
julia> cfg = ForwardDiff.GradientConfig(rosenbrock, x);
8989
9090
julia> @time ForwardDiff.gradient!(out, rosenbrock, x, cfg);
91-
0.266920 seconds (4 allocations: 160 bytes)
91+
0.281853 seconds (4 allocations: 160 bytes)
9292
9393
If your input dimension is a constant, you should explicitly select a chunk size rather than
9494
relying on ForwardDiff's heuristic. There are two reasons for this. The first is that
@@ -130,8 +130,8 @@ aren't sensitive to the input and thus cause ForwardDiff to incorrectly return `
130130
131131
# the dual number's perturbation component is zero, so this
132132
# variable should not propagate derivative information
133-
julia> log(ForwardDiff.Dual(0.0, 0.0))
134-
Dual(-Inf,NaN) # oops, this NaN should be 0.0
133+
julia> log(ForwardDiff.Dual{:tag}(0.0, 0.0))
134+
Dual{:tag}(-Inf,NaN) # oops, this NaN should be 0.0
135135
136136
Here, ForwardDiff computes the derivative of ``log(0.0)`` as ``NaN`` and then propagates
137137
this derivative by multiplying it by the perturbation component. Usually, ForwardDiff can
@@ -153,7 +153,6 @@ In the future, we plan on allowing users and downstream library authors to dynam
153153
enable ``NaN``-safe mode via the ``AbstractConfig`` API (see `the relevant issue
154154
<https://github.com/JuliaDiff/ForwardDiff.jl/issues/181>`_).
155155

156-
157156
Hessian of a vector-valued function
158157
-----------------------------------
159158

@@ -163,17 +162,17 @@ For example:
163162

164163
.. code-block:: julia
165164
166-
julia> ForwardDiff.jacobian(x -> ForwardDiff.jacobian(sin, x), [1,2,3])
167-
9×3 Array{Float64,2}:
168-
-0.841471 0.0 0.0
169-
-0.0 -0.0 -0.0
170-
-0.0 -0.0 -0.0
171-
0.0 0.0 0.0
172-
-0.0 -0.909297 -0.0
173-
-0.0 -0.0 -0.0
174-
0.0 0.0 0.0
175-
-0.0 -0.0 -0.0
176-
-0.0 -0.0 -0.14112
165+
julia> ForwardDiff.jacobian(x -> ForwardDiff.jacobian(cumprod, x), [1,2,3])
166+
9×3 Array{Int64,2}:
167+
0 0 0
168+
0 1 0
169+
0 3 2
170+
0 0 0
171+
1 0 0
172+
3 0 1
173+
0 0 0
174+
0 0 0
175+
2 1 0
177176
178177
Since this functionality is composed from ForwardDiff's existing API rather than built into
179178
it, you're free to construct a ``vector_hessian`` function which suits your needs. For
@@ -190,22 +189,22 @@ expensive operation):
190189
end
191190
vector_hessian (generic function with 1 method)
192191
193-
julia> vector_hessian(sin, [1, 2, 3])
194-
3×3×3 Array{Float64,3}:
192+
julia> vector_hessian(cumprod, [1, 2, 3])
193+
3×3×3 Array{Int64,3}:
195194
[:, :, 1] =
196-
-0.841471 0.0 0.0
197-
-0.0 -0.0 -0.0
198-
-0.0 -0.0 -0.0
195+
0 0 0
196+
0 1 0
197+
0 3 2
199198
200199
[:, :, 2] =
201-
0.0 0.0 0.0
202-
-0.0 -0.909297 -0.0
203-
-0.0 -0.0 -0.0
200+
0 0 0
201+
1 0 0
202+
3 0 1
204203
205204
[:, :, 3] =
206-
0.0 0.0 0.0
207-
-0.0 -0.0 -0.0
208-
-0.0 -0.0 -0.14112
205+
0 0 0
206+
0 0 0
207+
2 1 0
209208
210209
Likewise, you could write a version of ``vector_hessian`` which supports functions of the
211210
form ``f!(y, x)``, or perhaps an in-place Jacobian with ``ForwardDiff.jacobian!``.
@@ -232,10 +231,10 @@ SIMD instructions (i.e. not starting Julia with ``-O3``):
232231
julia> using ForwardDiff: Dual
233232
234233
julia> a = Dual(1., 2., 3., 4.)
235-
Dual(1.0,2.0,3.0,4.0)
234+
Dual{Void}(1.0,2.0,3.0,4.0)
236235
237236
julia> b = Dual(5., 6., 7., 8.)
238-
Dual(5.0,6.0,7.0,8.0)
237+
Dual{Void}(5.0,6.0,7.0,8.0)
239238
240239
julia> @code_llvm a + b
241240

docs/_rst/source/basic_api.rst

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,26 @@ Basic ForwardDiff API
44
Derivatives of :math:`f(x) : \mathbb{R} \to \mathbb{R}^{n_1} \times \dots \times \mathbb{R}^{n_k}`
55
--------------------------------------------------------------------------------------------------
66

7-
Use ``ForwardDiff.derivative`` to differentiate functions of the form ``f(::Real)::Real`` and ``f(::Real)::AbstractArray``.
7+
Use ``ForwardDiff.derivative`` to differentiate functions of the form ``f(::Real...)::Real`` and ``f(::Real...)::AbstractArray``.
88

99
.. function:: ForwardDiff.derivative!(out, f, x)
1010

11-
Compute :math:`f'(x)`, storing the output in ``out``.
11+
Compute :math:`f'(x)`, storing the output in ``out``. If ``x`` is a ``Tuple``,
12+
then ``f`` will be called as ``f(x...)`` and the derivatives with respect to
13+
each element in `x` will be stored in the respective element of ``out`` (which
14+
should also be a ``Tuple``).
1215

1316
.. function:: ForwardDiff.derivative(f, x)
1417

15-
Compute and return :math:`f'(x)`.
18+
Compute and return :math:`f'(x)`. If ``x`` is a ``Tuple``, ``f`` will be
19+
called as ``f(x...)``, and a ``Tuple`` of derivatives will be returned.
1620

1721
Gradients of :math:`f(x) : \mathbb{R}^{n_1} \times \dots \times \mathbb{R}^{n_k} \to \mathbb{R}`
1822
------------------------------------------------------------------------------------------------
1923

2024
Use ``ForwardDiff.gradient`` to differentiate functions of the form ``f(::AbstractArray)::Real``.
2125

22-
.. function:: ForwardDiff.gradient!(out, f, x, cfg = ForwardDiff.GradientConfig(x))
26+
.. function:: ForwardDiff.gradient!(out, f, x, cfg = ForwardDiff.GradientConfig(f, x))
2327

2428
Compute :math:`\nabla f(\vec{x})`, storing the output in ``out``. It is highly advised
2529
to preallocate ``cfg`` yourself (see the `AbstractConfig
@@ -34,23 +38,23 @@ Jacobians of :math:`f(x) : \mathbb{R}^{n_1} \times \dots \times \mathbb{R}^{n_k}
3438

3539
Use ``ForwardDiff.jacobian`` to differentiate functions of the form ``f(::AbstractArray)::AbstractArray``.
3640

37-
.. function:: ForwardDiff.jacobian!(out, f, x, cfg = ForwardDiff.JacobianConfig(x))
41+
.. function:: ForwardDiff.jacobian!(out, f, x, cfg = ForwardDiff.JacobianConfig(f, x))
3842

3943
Compute :math:`\mathbf{J}(f)(\vec{x})`, storing the output in ``out``. It is highly
4044
advised to preallocate ``cfg`` yourself (see the `AbstractConfig
4145
<basic_api.html#the-abstractconfig-types>`_ section below).
4246

43-
.. function:: ForwardDiff.jacobian!(out, f!, y, x, cfg = ForwardDiff.JacobianConfig(y, x))
47+
.. function:: ForwardDiff.jacobian!(out, f!, y, x, cfg = ForwardDiff.JacobianConfig(f!, y, x))
4448

4549
Compute :math:`\mathbf{J}(f)(\vec{x})`, where :math:`f(\vec{x})` can be called as
4650
``f!(y, x)`` such that the output of :math:`f(\vec{x})` is stored in ``y``. The output
4751
matrix is stored in ``out``.
4852

49-
.. function:: ForwardDiff.jacobian(f, x, cfg = ForwardDiff.JacobianConfig(x))
53+
.. function:: ForwardDiff.jacobian(f, x, cfg = ForwardDiff.JacobianConfig(f, x))
5054

5155
Compute and return :math:`\mathbf{J}(f)(\vec{x})`.
5256

53-
.. function:: ForwardDiff.jacobian(f!, y, x, cfg = ForwardDiff.JacobianConfig(y, x))
57+
.. function:: ForwardDiff.jacobian(f!, y, x, cfg = ForwardDiff.JacobianConfig(f!, y, x))
5458

5559
Compute and return :math:`\mathbf{J}(f)(\vec{x})`, where :math:`f(\vec{x})` can be
5660
called as ``f!(y, x)`` such that the output of :math:`f(\vec{x})` is stored in ``y``.
@@ -60,13 +64,13 @@ Hessians of :math:`f(x) : \mathbb{R}^{n_1} \times \dots \times \mathbb{R}^{n_k}
6064

6165
Use ``ForwardDiff.hessian`` to perform second-order differentiation on functions of the form ``f(::AbstractArray)::Real``.
6266

63-
.. function:: ForwardDiff.hessian!(out, f, x, cfg = ForwardDiff.HessianConfig(x))
67+
.. function:: ForwardDiff.hessian!(out, f, x, cfg = ForwardDiff.HessianConfig(f, x))
6468

6569
Compute :math:`\mathbf{H}(f)(\vec{x})`, storing the output in ``out``. It is highly
6670
advised to preallocate ``cfg`` yourself (see the `AbstractConfig
6771
<basic_api.html#the-abstractconfig-types>`_ section below).
6872

69-
.. function:: ForwardDiff.hessian(f, x, cfg = ForwardDiff.HessianConfig(x))
73+
.. function:: ForwardDiff.hessian(f, x, cfg = ForwardDiff.HessianConfig(f, x))
7074

7175
Compute and return :math:`\mathbf{H}(f)(\vec{x})`.
7276

@@ -77,66 +81,63 @@ For the sake of convenience and performance, all "extra" information used by For
7781
API methods is bundled up in the ``ForwardDiff.AbstractConfig`` family of types. Theses
7882
types allow the user to easily feed several different parameters to ForwardDiff's API
7983
methods, such as `chunk size <advanced_usage.html#configuring-chunk-size>`_, work buffers,
80-
multithreading configurations, and perturbation seed configurations.
84+
and perturbation seed configurations.
8185

8286
ForwardDiff's basic API methods will allocate these types automatically by default,
8387
but you can drastically reduce memory usage if you preallocate them yourself.
8488

85-
Note that for all constructors below, the chunk size ``N`` may be explictly provided as a
86-
type parameter, or omitted, in which case ForwardDiff will automatically select a chunk size
87-
for you. However, it is highly recomended to `specify the chunk size manually when possible
89+
Note that for all constructors below, the chunk size ``N`` may be explictly provided,
90+
or omitted, in which case ForwardDiff will automatically select a chunk size for you.
91+
However, it is highly recomended to `specify the chunk size manually when possible
8892
<advanced_usage.html#configuring-chunk-size>`_.
8993

90-
.. function:: ForwardDiff.GradientConfig{N}(x)
94+
Note also that configurations constructed for a specific function ``f`` cannot
95+
be reused to differentiate other functions (though can be reused to differentiate
96+
``f`` at different values). To construct a configuration which can be reused to
97+
differentiate any function, you can pass ``nothing`` as the function argument.
98+
While this is more flexible, this decreases ForwardDiff's ability to catch
99+
and prevent `perturbation confusion`_.
91100

92-
Construct a ``GradientConfig`` instance based on the type and shape of the input vector
93-
``x``. The returned ``GradientConfig`` instance contains all the work buffers required
94-
by ForwardDiff's gradient/Jacobian methods. If taking the Jacobian of a target function
95-
with the form ``f!(y, x)``, use the constructor ``ForwardDiff.GradientConfig{N}(y, x)``
96-
instead.
101+
.. function:: ForwardDiff.GradientConfig(f, x, chunk::ForwardDiff.Chunk{N} = Chunk(x))
102+
103+
Construct a ``GradientConfig`` instance based on the type of ``f`` and
104+
type/shape of the input vector ``x``. The returned ``GradientConfig``
105+
instance contains all the work buffers required by ForwardDiff's gradient
106+
methods.
97107

98108
This constructor does not store/modify ``x``.
99109

100-
.. function:: ForwardDiff.JacobianConfig{N}(x)
110+
.. function:: ForwardDiff.JacobianConfig(f, x, chunk::ForwardDiff.Chunk{N} = Chunk(x))
101111

102-
Exactly like ``ForwardDiff.GradientConfig{N}(x)``, but returns a `JacobianConfig`
103-
instead.
112+
Exactly like the ``GradientConfig`` constructor, but returns a ``JacobianConfig`` instead.
104113

105-
.. function:: ForwardDiff.JacobianConfig{N}(y, x)
114+
.. function:: ForwardDiff.JacobianConfig(f!, y, x, chunk::ForwardDiff.Chunk{N} = Chunk(x))
106115

107-
Construct a ``JacobianConfig`` instance based on the type and shape of the output vector
108-
``y`` and the input vector ``x``. The returned ``JacobianConfig`` instance contains all
109-
the work buffers required by ``ForwardDiff.jacobian``/``ForwardDiff.jacobian!`` with a
110-
target function of the form ``f!(y, x)``.
116+
Construct a ``JacobianConfig`` instance based on the type of ``f!``, and the
117+
types/shapes of the output vector ``y`` and the input vector ``x``. The
118+
returned ``JacobianConfig`` instance contains all the work buffers required
119+
by ``ForwardDiff.jacobian``/``ForwardDiff.jacobian!`` when the target
120+
function takes the form ``f!(y, x)``.
111121

112122
This constructor does not store/modify ``y`` or ``x``.
113123

114-
.. function:: ForwardDiff.HessianConfig{N}(x)
124+
.. function:: ForwardDiff.HessianConfig(f, x, chunk::ForwardDiff.Chunk{N} = Chunk(x))
115125

116-
Construct a ``HessianConfig`` instance based on the type and shape of the input vector
117-
``x``. The returned ``HessianConfig`` instance contains all the work buffers required
118-
by ForwardDiff's Hessian methods. If using
119-
``ForwardDiff.hessian!(out::DiffBase.DiffResult, args...)``, use the constructor
120-
``ForwardDiff.HessianConfig{N}(out, x)`` instead.
126+
Construct a ``HessianConfig`` instance based on the type of ``f`` and
127+
type/shape of the input vector ``x``. The returned ``HessianConfig`` instance contains
128+
all the work buffers required by ForwardDiff's Hessian methods. If using
129+
``ForwardDiff.hessian!(out::DiffBase.DiffResult, f, x)``, use the constructor
130+
``ForwardDiff.HessianConfig(f, out, x, chunk)`` instead.
121131

122132
This constructor does not store/modify ``x``.
123133

124-
.. function:: ForwardDiff.HessianConfig{N}(out::DiffBase.DiffResult, x)
134+
.. function:: ForwardDiff.HessianConfig(f, out::DiffBase.DiffResult, x, chunk::ForwardDiff.Chunk{N} = Chunk(x))
125135

126-
Construct an ``HessianConfig`` instance based on the type and shape of the storage in
127-
``out`` and the input vector ``x``. The returned ``HessianConfig`` instance contains
128-
all the work buffers required by ``ForwardDiff.hessian!(out::DiffBase.DiffResult,
129-
args...)``.
136+
Construct an ``HessianConfig`` instance based on the type of ``f``, types/storage
137+
in ``out``, and type/shape of the input vector ``x``. The returned ``HessianConfig``
138+
instance contains all the work buffers required by
139+
``ForwardDiff.hessian!(out::DiffBase.DiffResult, args...)``.
130140

131141
This constructor does not store/modify ``out`` or ``x``.
132142

133-
.. function:: ForwardDiff.MultithreadConfig(cfg::AbstractConfig)
134-
135-
Wrap the given ``cfg`` in a ``MultithreadConfig`` instance, which can then be passed to
136-
gradient or Hessian methods in order to enable experimental multithreading. Jacobian
137-
methods do not yet support multithreading.
138-
139-
Note that multithreaded ForwardDiff API methods will attempt to use all available
140-
threads. In the future, once Julia exposes more fine-grained threading primitives,
141-
a ``MultithreadConfig`` constructor may be added which takes in a user-provided subset
142-
of thread IDs instead of using all available threads.
143+
.. _`perturbation confusion`: https://github.com/JuliaDiff/ForwardDiff.jl/issues/83

docs/_rst/source/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@
5757
# built documents.
5858
#
5959
# The short X.Y version.
60-
version = '0.2'
60+
version = '0.5'
6161
# The full version, including alpha/beta/rc tags.
62-
release = '0.2.3'
62+
release = '0.5.0'
6363

6464
# The language for content autogenerated by Sphinx. Refer to documentation
6565
# for a list of supported languages.

docs/_rst/source/contributing.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ To see a list of functions to pick from, look at ``ForwardDiff.AUTO_DEFINED_UNAR
4040
4141
4242
Some of these functions may have already been manually optimized. To see what functions have
43-
already been done, go to ``src/dual.jl``, scroll down to the ``Special Cases`` section, and
44-
look at the functions under ``Manually Optimized`` (further optimizations to these functions
45-
are always welcome, if you can come up with something clever).
43+
already been done, go to ``src/dual.jl`` and scroll down to the ``Special Cases`` section.
4644

4745
The functions in ``ForwardDiff.AUTO_DEFINED_UNARY_FUNCS`` are automatically tested as part
4846
of ForwardDiff's test suite, so you don't need to write tests yourself. You can test your

0 commit comments

Comments
 (0)