Skip to content

Commit

Permalink
Doc updates again and linting checks
Browse files Browse the repository at this point in the history
  • Loading branch information
peekxc committed Dec 4, 2024
1 parent 3cd83a3 commit 1a4d182
Show file tree
Hide file tree
Showing 116 changed files with 2,518 additions and 6,663 deletions.
1,176 changes: 0 additions & 1,176 deletions docs/_site/basic/imate_compare.html

This file was deleted.

1,422 changes: 0 additions & 1,422 deletions docs/_site/basic/quickstart.html

This file was deleted.

1,430 changes: 0 additions & 1,430 deletions docs/_site/guides/intro.html

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ <h2 class="anchored" data-anchor-id="c-usage">C++ usage</h2>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">void</span> shape<span class="op">()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="bu">std::</span>make_pair<span class="op">(</span>nrow<span class="op">,</span> ncol<span class="op">);</span> <span class="op">}</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<p>It’s up to you to ensure <code>shape()</code> yields the correct size; <code>primate</code> will supply vectors to <code>input</code> of size <code>.shape().second</code> (number of columns) and guarantees the pointer to the <code>output</code> will be at least <code>shape().first</code> (number of rows), no more.</p>
<p>To read more about how semantics extend to the C++ side via <em>C++20 concepts</em>, see the <a href="../advanced/cpp_integration.qmd">C++ integration guide</a>. If youre using pybind11 and you want to extend <code>primate</code>s Python API to work natively with linear operator implemented in C++, see the <a href="../advanced/pybind11_integration.qmd">pybind11 integration guide</a>.</p>
<!-- To read more about how semantics extend to the C++ side via _C++20 concepts_, see the [C++ integration guide](../advanced/cpp_integration.qmd). If you're using pybind11 and you want to extend `primate`'s Python API to work natively with linear operator implemented in C++, see the [pybind11 integration guide](../advanced/pybind11_integration.qmd). -->


</section>
Expand Down
175 changes: 91 additions & 84 deletions docs/_site/quickstart.html → docs/basic/quickstart.html

Large diffs are not rendered by default.

42 changes: 21 additions & 21 deletions docs/_site/guides/intro_trace.html → docs/guides/intro_trace.html

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ <h1 class="title">Matrix function estimation with <code>primate</code></h1>
</header>


<div id="958fa68c" class="cell" data-execution_count="1">
<div id="7d60763e" class="cell" data-execution_count="1">
<div class="cell-output cell-output-display">
<script type="application/javascript">
'use strict';
Expand Down Expand Up @@ -915,9 +915,9 @@ <h1 class="title">Matrix function estimation with <code>primate</code></h1>
</script>
</div>
</div>
<p>In the <a href="intro.qmd">introduction</a>, the basics of implicit trace estimation were introduced, wherein it shown both in theory and with code using <code>primate</code> how to estimate the trace of <em>matrix functions</em>:</p>
<p>In the <a href="../guides/intro_trace.html">introduction</a>, the basics of implicit trace estimation were introduced, wherein it shown both in theory and with code using <code>primate</code> how to estimate the trace of <em>matrix functions</em>:</p>
<p><span class="math display"> f(A) = U f(\Lambda) U^T, \quad f: [a,b] \to \mathbb{R} </span></p>
<p>In particular, the introduction briefly covered how the <a href="lanczos.qmd">Lanczos method</a> is intimately connected to <em>Gaussian Quadrature</em>, and how this connection enables fast randomized trace estimation of <span class="math inline">f(A)</span>.</p>
<p>In particular, the introduction briefly covered how the Lanczos method is intimately connected to <em>Gaussian Quadrature</em>, and how this connection enables fast randomized trace estimation of <span class="math inline">f(A)</span>.</p>
<p>In this post, I’ll cover how to approximate the action <span class="math inline">v \mapsto f(A)v</span> for any function <span class="math inline">f</span> with <code>primate</code> with its <code>matrix_function</code> API, and how to compose this functionality with other trace estimators.</p>
<section id="matrix-function-approximation" class="level2">
<h2 class="anchored" data-anchor-id="matrix-function-approximation">Matrix function approximation</h2>
Expand All @@ -944,7 +944,7 @@ <h2 class="anchored" data-anchor-id="modifying-operators">Modifying operators</h
<li>Multiply <span class="math inline">v</span> by <span class="math inline">f(A)</span> induced by <span class="math inline">f(\lambda) = \lambda + \epsilon</span></li>
</ol>
<p>Lets see what the code to accomplish this using (3) looks like:</p>
<div id="54ce6310" class="cell" data-execution_count="2">
<div id="7748801a" class="cell" data-execution_count="2">
<div class="sourceCode cell-code" id="cb1"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> primate.random <span class="im">import</span> symmetric</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> primate.operators <span class="im">import</span> matrix_function</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
Expand Down Expand Up @@ -974,7 +974,7 @@ <h2 class="anchored" data-anchor-id="modifying-operators">Modifying operators</h
</div>
</div>
<p>Observe <span class="math inline">M</span> matches the ground truth <span class="math inline">v \mapsto (A + \epsilon I)v</span>. In this way, one benefit of using <code>matrix_function</code> is that it allows one to approximate <span class="math inline">f(A)</span> by thinking only about what is happening at the spectral level (as opposed to the matrix level). We can check the result is identical to approach (1) and (2) above:</p>
<div id="ed60c691" class="cell" data-execution_count="3">
<div id="28d2f7ce" class="cell" data-execution_count="3">
<div class="sourceCode cell-code" id="cb3"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>np.allclose(A <span class="op">@</span> v <span class="op">+</span> <span class="fl">0.10</span> <span class="op">*</span> v, v_truth)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-display" data-execution_count="3">
<pre><code>True</code></pre>
Expand All @@ -989,7 +989,7 @@ <h2 class="anchored" data-anchor-id="when-v-mapsto-fav-is-not-known">When <span
<p>Such expressions pop up in a variety of settings, such as in <a href="https://en.wikipedia.org/wiki/Ridge_regression">Tikhonov regularization</a>, in Schatten-norm estimation <span class="citation" data-cites="ubaru2017fast">(<a href="#ref-ubaru2017fast" role="doc-biblioref">Ubaru, Saad, and Seghouane 2017</a>)</span>, in the <a href="https://scikit-sparse.readthedocs.io/en/latest/cholmod.html#sksparse.cholmod.Factor.cholesky_AAt_inplace">Cholesky factorization of PSD matrices</a>, and so on.</p>
<p>Note that unlike the previous setting, we cannot readily access <span class="math inline">v \mapsto f(A)v</span> unless we explicitly compute the full spectral decomposition of <span class="math inline">A</span> or the inverse of <span class="math inline">A</span>, both of which are expensive to obtain. Alternatively, observe that for <span class="math inline">A \succeq 0</span>, we have: <span class="math display"> \lambda \in \Lambda(\, A \, ) \; \Leftrightarrow \; (\lambda+\epsilon)^{-1} \in \Lambda(\, (A + \epsilon I)^{-1} \,)</span></p>
<p>Thus, obtaining an operator approximating <span class="math inline">v \mapsto (A + \epsilon I)^{-1}v</span> requires just a trivial modification of the code above:</p>
<div id="768ff03c" class="cell" data-execution_count="4">
<div id="e6ecb69c" class="cell" data-execution_count="4">
<div class="sourceCode cell-code" id="cb5"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="co">## Alternative: v_truth = np.linalg.inv((A + 0.10 * np.eye(A.shape[0]))) @ v</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>v_truth <span class="op">=</span> (U <span class="op">@</span> np.diag(np.reciprocal(Lambda <span class="op">+</span> <span class="fl">0.10</span>)) <span class="op">@</span> U.T) <span class="op">@</span> v</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a></span>
Expand All @@ -1014,16 +1014,16 @@ <h2 class="anchored" data-anchor-id="when-v-mapsto-fav-is-not-known">When <span
<section id="back-to-trace-estimation" class="level2">
<h2 class="anchored" data-anchor-id="back-to-trace-estimation">Back to trace estimation</h2>
<p>There are several use-cases wherein one might be interested in the output <span class="math inline">f(A)v</span> itself, e.g.&nbsp;principal component regression or spectral clustering. Another use case is implicit <em>matrix function</em> trace estimation.</p>
<div id="e1094e07" class="cell" data-execution_count="5">
<div id="9b045177" class="cell" data-execution_count="5">
<div class="sourceCode cell-code" id="cb7"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> primate.trace <span class="im">import</span> hutch, xtrace</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>M <span class="op">=</span> matrix_function(A, fun<span class="op">=</span><span class="st">"log"</span>)</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(<span class="ss">f"Logdet exact : </span><span class="sc">{</span>np<span class="sc">.</span><span class="bu">sum</span>(np.log(np.linalg.eigvalsh(A)))<span class="sc">:6e}</span><span class="ss">"</span>)</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(<span class="ss">f"Logdet Hutch : </span><span class="sc">{</span>hutch(M)<span class="sc">:6e}</span><span class="ss">"</span>)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(<span class="ss">f"Logdet XTrace : </span><span class="sc">{</span>xtrace(M)<span class="sc">:6e}</span><span class="ss">"</span>)</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>Logdet exact : -1.515298e+02
Logdet Hutch : -1.541574e+02
Logdet XTrace : -1.515291e+02</code></pre>
Logdet Hutch : -1.551535e+02
Logdet XTrace : -1.515277e+02</code></pre>
</div>
</div>
<p>As with the hutch estimators applied to matrix functions, note that the action <span class="math inline">v \mapsto f(A)v</span> is subject to the approximation errors mentioned above, making such extensions limited to functions that are well-approximated by the Lanczos method.</p>
Expand Down
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 1a4d182

Please sign in to comment.