Skip to content

Commit

Permalink
build based on f41651f
Browse files Browse the repository at this point in the history
  • Loading branch information
Documenter.jl committed Apr 18, 2024
1 parent 7e8f1ce commit c575cd9
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 22 deletions.
2 changes: 1 addition & 1 deletion dev/.documenter-siteinfo.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-04-17T11:26:12","documenter_version":"1.4.0"}}
{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-04-18T08:46:54","documenter_version":"1.4.0"}}
19 changes: 12 additions & 7 deletions dev/api/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dev/examples/0_intro/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
end</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ErrorException(&quot;Mutating arrays is not supported -- called setindex!(Vector{Float64}, ...)\nThis error occurs when you ask Zygote to differentiate operations that change\nthe elements of arrays in place (e.g. setting values with x .= ...)\n\nPossible fixes:\n- avoid mutating operations (preferred)\n- or read the documentation and solutions for this error\n https://fluxml.ai/Zygote.jl/latest/limitations\n&quot;)</code></pre><p>Zygote.jl also throws an error because it cannot handle mutation.</p><h2 id="Implicit-function"><a class="docs-heading-anchor" href="#Implicit-function">Implicit function</a><a id="Implicit-function-1"></a><a class="docs-heading-anchor-permalink" href="#Implicit-function" title="Permalink"></a></h2><p>The first possible use of ImplicitDifferentiation.jl is to overcome the limitations of automatic differentiation packages by defining functions (and computing their derivatives) implicitly. An implicit function is a mapping</p><p class="math-container">\[x \in \mathbb{R}^n \longmapsto y(x) \in \mathbb{R}^m\]</p><p>whose output is defined by conditions</p><p class="math-container">\[c(x,y(x)) = 0 \in \mathbb{R}^m\]</p><p>We represent it using a type called <a href="../../api/#ImplicitDifferentiation.ImplicitFunction"><code>ImplicitFunction</code></a>, which you will see in action shortly.</p><p>First we define a forward mapping corresponding to the function we consider. It returns the actual output <span>$y(x)$</span> of the function, and can be thought of as a black box solver. Importantly, this Julia callable <em>doesn&#39;t need to be differentiable by automatic differentiation packages but the underlying function still needs to be mathematically differentiable</em>.</p><pre><code class="language-julia hljs">forward(x) = badsqrt(x);</code></pre><p>Then we define <code>conditions</code> <span>$c(x, y) = 0$</span> that the output <span>$y(x)$</span> is supposed to satisfy. These conditions must be array-valued, with the same size as <span>$y$</span>. Unlike the forward mapping, <em>the conditions need to be differentiable by automatic differentiation packages</em> with respect to both <span>$x$</span> and <span>$y$</span>. Here the conditions are very obvious: the square of the square root should be equal to the original value.</p><pre><code class="language-julia hljs">function conditions(x, y)
c = y .^ 2 .- x
return c
end;</code></pre><p>Finally, we construct a wrapper <code>implicit</code> around the previous objects. By default, <code>forward</code> is assumed to return a single output and <code>conditions</code> is assumed to accept 2 arguments.</p><pre><code class="language-julia hljs">implicit = ImplicitFunction(forward, conditions)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ImplicitFunction{lazy}(forward, conditions, ImplicitDifferentiation.DefaultLinearSolver(), nothing, nothing)</code></pre><p>What does this wrapper do? When we call it as a function, it just falls back on <code>implicit.forward</code>, so unsurprisingly we get the output <span>$y(x)$</span>.</p><pre><code class="language-julia hljs">implicit(x)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2-element Vector{Float64}:
end;</code></pre><p>Finally, we construct a wrapper <code>implicit</code> around the previous objects. By default, <code>forward</code> is assumed to return a single output and <code>conditions</code> is assumed to accept 2 arguments.</p><pre><code class="language-julia hljs">implicit = ImplicitFunction(forward, conditions)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ImplicitFunction{lazy}(forward, conditions, ImplicitDifferentiation.KrylovLinearSolver(), nothing, nothing)</code></pre><p>What does this wrapper do? When we call it as a function, it just falls back on <code>implicit.forward</code>, so unsurprisingly we get the output <span>$y(x)$</span>.</p><pre><code class="language-julia hljs">implicit(x)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2-element Vector{Float64}:
2.0
3.0</code></pre><p>And when we try to compute its Jacobian, the <a href="https://en.wikipedia.org/wiki/Implicit_function_theorem">implicit function theorem</a> is applied in the background to circumvent the lack of differentiability of the forward mapping.</p><h2 id="Forward-and-reverse-mode-autodiff"><a class="docs-heading-anchor" href="#Forward-and-reverse-mode-autodiff">Forward and reverse mode autodiff</a><a id="Forward-and-reverse-mode-autodiff-1"></a><a class="docs-heading-anchor-permalink" href="#Forward-and-reverse-mode-autodiff" title="Permalink"></a></h2><p>Now ForwardDiff.jl works seamlessly.</p><pre><code class="language-julia hljs">ForwardDiff.jacobian(implicit, x) ≈ J</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">true</code></pre><p>And so does Zygote.jl. Hurray!</p><pre><code class="language-julia hljs">Zygote.jacobian(implicit, x)[1] ≈ J</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">true</code></pre><hr/><p><em>This page was generated using <a href="https://github.com/fredrikekre/Literate.jl">Literate.jl</a>.</em></p></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../../">« Home</a><a class="docs-footer-nextpage" href="../1_basic/">Basic use cases »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.4.0 on <span class="colophon-date" title="Wednesday 17 April 2024 11:26">Wednesday 17 April 2024</span>. Using Julia version 1.10.2.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
3.0</code></pre><p>And when we try to compute its Jacobian, the <a href="https://en.wikipedia.org/wiki/Implicit_function_theorem">implicit function theorem</a> is applied in the background to circumvent the lack of differentiability of the forward mapping.</p><h2 id="Forward-and-reverse-mode-autodiff"><a class="docs-heading-anchor" href="#Forward-and-reverse-mode-autodiff">Forward and reverse mode autodiff</a><a id="Forward-and-reverse-mode-autodiff-1"></a><a class="docs-heading-anchor-permalink" href="#Forward-and-reverse-mode-autodiff" title="Permalink"></a></h2><p>Now ForwardDiff.jl works seamlessly.</p><pre><code class="language-julia hljs">ForwardDiff.jacobian(implicit, x) ≈ J</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">true</code></pre><p>And so does Zygote.jl. Hurray!</p><pre><code class="language-julia hljs">Zygote.jacobian(implicit, x)[1] ≈ J</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">true</code></pre><hr/><p><em>This page was generated using <a href="https://github.com/fredrikekre/Literate.jl">Literate.jl</a>.</em></p></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../../">« Home</a><a class="docs-footer-nextpage" href="../1_basic/">Basic use cases »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.4.0 on <span class="colophon-date" title="Thursday 18 April 2024 08:46">Thursday 18 April 2024</span>. Using Julia version 1.10.2.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
8 changes: 4 additions & 4 deletions dev/examples/1_basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
end;</code></pre><p>Even though they are defined as a gradient, it is better to provide optimality conditions explicitly: that way we avoid nesting autodiff calls. By default, the conditions should accept two arguments as input. The forward mapping and the conditions should accept the same set of keyword arguments.</p><pre><code class="language-julia hljs">function conditions_optim(x, y; method)
∇₂f = @. 4 * (y^2 - x) * y
return ∇₂f
end;</code></pre><p>We now have all the ingredients to construct our implicit function.</p><pre><code class="language-julia hljs">implicit_optim = ImplicitFunction(forward_optim, conditions_optim)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ImplicitFunction{lazy}(forward_optim, conditions_optim, ImplicitDifferentiation.DefaultLinearSolver(), nothing, nothing)</code></pre><p>And indeed, it behaves as it should when we call it:</p><pre><code class="language-julia hljs">implicit_optim(x; method=LBFGS()) .^ 2</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2-element Vector{Float64}:
end;</code></pre><p>We now have all the ingredients to construct our implicit function.</p><pre><code class="language-julia hljs">implicit_optim = ImplicitFunction(forward_optim, conditions_optim)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ImplicitFunction{lazy}(forward_optim, conditions_optim, ImplicitDifferentiation.KrylovLinearSolver(), nothing, nothing)</code></pre><p>And indeed, it behaves as it should when we call it:</p><pre><code class="language-julia hljs">implicit_optim(x; method=LBFGS()) .^ 2</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2-element Vector{Float64}:
3.9999999998710107
8.999999999664347</code></pre><p>Forward mode autodiff</p><pre><code class="language-julia hljs">ForwardDiff.jacobian(_x -&gt; implicit_optim(_x; method=LBFGS()), x)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2×2 Matrix{Float64}:
0.25 0.0
Expand All @@ -35,7 +35,7 @@
end;</code></pre><pre><code class="language-julia hljs">function conditions_nlsolve(x, y; method)
c = y .^ 2 .- x
return c
end;</code></pre><pre><code class="language-julia hljs">implicit_nlsolve = ImplicitFunction(forward_nlsolve, conditions_nlsolve)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ImplicitFunction{lazy}(forward_nlsolve, conditions_nlsolve, ImplicitDifferentiation.DefaultLinearSolver(), nothing, nothing)</code></pre><pre><code class="language-julia hljs">implicit_nlsolve(x; method=:newton) .^ 2</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2-element Vector{Float64}:
end;</code></pre><pre><code class="language-julia hljs">implicit_nlsolve = ImplicitFunction(forward_nlsolve, conditions_nlsolve)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ImplicitFunction{lazy}(forward_nlsolve, conditions_nlsolve, ImplicitDifferentiation.KrylovLinearSolver(), nothing, nothing)</code></pre><pre><code class="language-julia hljs">implicit_nlsolve(x; method=:newton) .^ 2</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2-element Vector{Float64}:
4.000000000000009
9.000000008381901</code></pre><p>Forward mode autodiff</p><pre><code class="language-julia hljs">ForwardDiff.jacobian(_x -&gt; implicit_nlsolve(_x; method=:newton), x)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2×2 Matrix{Float64}:
0.25 0.0
Expand All @@ -56,7 +56,7 @@
end;</code></pre><pre><code class="language-julia hljs">function conditions_fixedpoint(x, y; iterations)
g = (y .+ x ./ y) ./ 2
return g .- y
end;</code></pre><pre><code class="language-julia hljs">implicit_fixedpoint = ImplicitFunction(forward_fixedpoint, conditions_fixedpoint)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ImplicitFunction{lazy}(forward_fixedpoint, conditions_fixedpoint, ImplicitDifferentiation.DefaultLinearSolver(), nothing, nothing)</code></pre><pre><code class="language-julia hljs">implicit_fixedpoint(x; iterations=10) .^ 2</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2-element Vector{Float64}:
end;</code></pre><pre><code class="language-julia hljs">implicit_fixedpoint = ImplicitFunction(forward_fixedpoint, conditions_fixedpoint)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ImplicitFunction{lazy}(forward_fixedpoint, conditions_fixedpoint, ImplicitDifferentiation.KrylovLinearSolver(), nothing, nothing)</code></pre><pre><code class="language-julia hljs">implicit_fixedpoint(x; iterations=10) .^ 2</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2-element Vector{Float64}:
4.0
9.0</code></pre><p>Forward mode autodiff</p><pre><code class="language-julia hljs">ForwardDiff.jacobian(_x -&gt; implicit_fixedpoint(_x; iterations=10), x)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">2×2 Matrix{Float64}:
0.25 0.0
Expand All @@ -68,4 +68,4 @@
Zygote.jacobian(_x -&gt; forward_fixedpoint(_x; iterations=10), x)[1]
catch e
e
end</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ErrorException(&quot;Mutating arrays is not supported -- called copyto!(Vector{Float64}, ...)\nThis error occurs when you ask Zygote to differentiate operations that change\nthe elements of arrays in place (e.g. setting values with x .= ...)\n\nPossible fixes:\n- avoid mutating operations (preferred)\n- or read the documentation and solutions for this error\n https://fluxml.ai/Zygote.jl/latest/limitations\n&quot;)</code></pre><hr/><p><em>This page was generated using <a href="https://github.com/fredrikekre/Literate.jl">Literate.jl</a>.</em></p></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../0_intro/">« Introduction</a><a class="docs-footer-nextpage" href="../2_advanced/">Advanced use cases »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.4.0 on <span class="colophon-date" title="Wednesday 17 April 2024 11:26">Wednesday 17 April 2024</span>. Using Julia version 1.10.2.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
end</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">ErrorException(&quot;Mutating arrays is not supported -- called copyto!(Vector{Float64}, ...)\nThis error occurs when you ask Zygote to differentiate operations that change\nthe elements of arrays in place (e.g. setting values with x .= ...)\n\nPossible fixes:\n- avoid mutating operations (preferred)\n- or read the documentation and solutions for this error\n https://fluxml.ai/Zygote.jl/latest/limitations\n&quot;)</code></pre><hr/><p><em>This page was generated using <a href="https://github.com/fredrikekre/Literate.jl">Literate.jl</a>.</em></p></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../0_intro/">« Introduction</a><a class="docs-footer-nextpage" href="../2_advanced/">Advanced use cases »</a><div class="flexbox-break"></div><p class="footer-message">Powered by <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> and the <a href="https://julialang.org/">Julia Programming Language</a>.</p></nav></div><div class="modal" id="documenter-settings"><div class="modal-background"></div><div class="modal-card"><header class="modal-card-head"><p class="modal-card-title">Settings</p><button class="delete"></button></header><section class="modal-card-body"><p><label class="label">Theme</label><div class="select"><select id="documenter-themepicker"><option value="auto">Automatic (OS)</option><option value="documenter-light">documenter-light</option><option value="documenter-dark">documenter-dark</option></select></div></p><hr/><p>This document was generated with <a href="https://github.com/JuliaDocs/Documenter.jl">Documenter.jl</a> version 1.4.0 on <span class="colophon-date" title="Thursday 18 April 2024 08:46">Thursday 18 April 2024</span>. Using Julia version 1.10.2.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
Loading

0 comments on commit c575cd9

Please sign in to comment.