Skip to content

Commit

Permalink
build based on 44de626
Browse files Browse the repository at this point in the history
  • Loading branch information
Documenter.jl committed Dec 7, 2023
1 parent a7f30e4 commit 17f4487
Show file tree
Hide file tree
Showing 29 changed files with 1,178 additions and 2 deletions.
2 changes: 1 addition & 1 deletion stable
94 changes: 94 additions & 0 deletions v0.0.12/API/Continuous Time/convergence/index.html

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions v0.0.12/API/Continuous Time/empirical_generator/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><title>Empirical Generator · Markov Chain Hammer</title><script data-outdated-warner src="../../../assets/warner.js"></script><link href="https://cdnjs.cloudflare.com/ajax/libs/lato-font/3.0.0/css/lato-font.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/juliamono/0.045/juliamono.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/fontawesome.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/solid.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/brands.min.css" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.24/katex.min.css" rel="stylesheet" type="text/css"/><script>documenterBaseURL="../../.."</script><script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js" data-main="../../../assets/documenter.js"></script><script src="../../../siteinfo.js"></script><script src="../../../../versions.js"></script><link class="docs-theme-link" rel="stylesheet" type="text/css" href="../../../assets/themes/documenter-dark.css" data-theme-name="documenter-dark" data-theme-primary-dark/><link class="docs-theme-link" rel="stylesheet" type="text/css" href="../../../assets/themes/documenter-light.css" data-theme-name="documenter-light" data-theme-primary/><script src="../../../assets/themeswap.js"></script></head><body><div id="documenter"><nav class="docs-sidebar"><div class="docs-package-name"><span class="docs-autofit"><a href="../../../">Markov Chain Hammer</a></span></div><form class="docs-search" action="../../../search/"><input class="docs-search-query" id="documenter-search-query" name="q" type="text" placeholder="Search docs"/></form><ul class="docs-menu"><li><a class="tocitem" href="../../../">Home</a></li><li><input class="collapse-toggle" id="menuitem-2" type="checkbox" checked/><label class="tocitem" for="menuitem-2"><span class="docs-label">API</span><i class="docs-chevron"></i></label><ul class="collapsed"><li><a class="tocitem" href="../../overview/">Overview</a></li><li><input class="collapse-toggle" id="menuitem-2-2" type="checkbox"/><label class="tocitem" for="menuitem-2-2"><span class="docs-label">Discrete Time</span><i class="docs-chevron"></i></label><ul class="collapsed"><li><a class="tocitem" href="../../Discrete Time/transfer_operators/">Transfer Operators and Markov Chains</a></li><li><a class="tocitem" href="../../Discrete Time/empirical_transfer_operators/">Data-driven Transfer Operators</a></li><li><a class="tocitem" href="../../Discrete Time/convergence/">Convergence of Transfer Operators</a></li></ul></li><li><input class="collapse-toggle" id="menuitem-2-3" type="checkbox" checked/><label class="tocitem" for="menuitem-2-3"><span class="docs-label">Continuous Time</span><i class="docs-chevron"></i></label><ul class="collapsed"><li><a class="tocitem" href="../generators/">Generators</a></li><li class="is-active"><a class="tocitem" href>Empirical Generator</a></li><li><a class="tocitem" href="../convergence/">Convergence of Generators</a></li></ul></li><li><input class="collapse-toggle" id="menuitem-2-4" type="checkbox"/><label class="tocitem" for="menuitem-2-4"><span class="docs-label">Uncertainty Quantification</span><i class="docs-chevron"></i></label><ul class="collapsed"><li><a class="tocitem" href="../../Uncertainty Quantification/bayesian_empirical_generator/">Bayesian Empirical Generator</a></li><li><a class="tocitem" href="../../Uncertainty Quantification/constructing_prior/">Constructing Prior Distributions</a></li><li><a class="tocitem" href="../../Uncertainty Quantification/sampling/">Sampling from the Bayesian Generator</a></li></ul></li></ul></li><li><input class="collapse-toggle" id="menuitem-3" type="checkbox"/><label class="tocitem" for="menuitem-3"><span class="docs-label">Modules</span><i class="docs-chevron"></i></label><ul class="collapsed"><li><a class="tocitem" href="../../../Modules/module_overview/">Overview</a></li><li><a class="tocitem" href="../../../Modules/transition_matrix/">TransitionMatrix</a></li><li><a class="tocitem" href="../../../Modules/bayesian_matrix/">BayesianMatrix</a></li><li><a class="tocitem" href="../../../Modules/trajectory/">Trajectory</a></li><li><a class="tocitem" href="../../../Modules/clustering/">Clustering</a></li><li><a class="tocitem" href="../../../Modules/utils/">Utils</a></li></ul></li><li><a class="tocitem" href="../../../function_index/">Function Index</a></li></ul><div class="docs-version-selector field has-addons"><div class="control"><span class="docs-label button is-static is-size-7">Version</span></div><div class="docs-selector control is-expanded"><div class="select is-fullwidth is-size-7"><select id="documenter-version-selector"></select></div></div></div></nav><div class="docs-main"><header class="docs-navbar"><nav class="breadcrumb"><ul class="is-hidden-mobile"><li><a class="is-disabled">API</a></li><li><a class="is-disabled">Continuous Time</a></li><li class="is-active"><a href>Empirical Generator</a></li></ul><ul class="is-hidden-tablet"><li class="is-active"><a href>Empirical Generator</a></li></ul></nav><div class="docs-right"><a class="docs-edit-link" href="https://github.com/sandreza/MarkovChainHammer.jl/blob/main/docs/src/API/Continuous Time/empirical_generator.md" title="Edit on GitHub"><span class="docs-icon fab"></span><span class="docs-label is-hidden-touch">Edit on GitHub</span></a><a class="docs-settings-button fas fa-cog" id="documenter-settings-button" href="#" title="Settings"></a><a class="docs-sidebar-button fa fa-bars is-hidden-desktop" id="documenter-sidebar-button" href="#"></a></div></header><article class="content" id="documenter-page"><h1 id="sec:empirical_generator"><a class="docs-heading-anchor" href="#sec:empirical_generator">Empirical Generator</a><a id="sec:empirical_generator-1"></a><a class="docs-heading-anchor-permalink" href="#sec:empirical_generator" title="Permalink"></a></h1><p>In this section, we will see how to construct a generator from data. This is useful when we don&#39;t know the underlying generator. There is an inherent limitation in constructing generators that wasn&#39;t present when constructing the transfer operator: The data comes at a fixed timescale, thus the generator will only be known up to the timescales present in the timeseries. Nonetheless it is possible to construct a generator from the timeseries under a few assumptions. </p><p>For example, suppose that we have the Markov chain with three states</p><pre><code class="language-julia hljs">markov_chain = [1 1 2 2 2 1 3 1 1 2 2]</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">1×11 Matrix{Int64}:
1 1 2 2 2 1 3 1 1 2 2</code></pre><p>and we want to estimate the transfer operator from this data. We can do this by using the function <code>generator</code> which is imported from the <code>MarkovChainHammer.TransitionMatrix</code> module. This function takes a Markov chain as input and returns the empirical transition matrix of the Markov chain. We assume that the time intervals are uniform in time with timestep <span>$dt = 1$</span></p><pre><code class="language-julia hljs">using MarkovChainHammer.TransitionMatrix: generator
dt = 1.0
Q = generator(markov_chain; dt = dt)
Q</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">3×3 Matrix{Float64}:
-0.6 0.4 1.0
0.4 -0.4 0.0
0.2 0.0 -1.0</code></pre><p>This matrix is constructed by counting the amount of time spent in a state to construct the diagonal entries of the matrix, i.e., the holding times. We can manually import the holding times to understand the construction of the <span>$Q$</span> matrix, from the <code>MarkovChainHammer.TransitionMatrix</code> function <code>holding_times</code></p><pre><code class="language-julia hljs">using MarkovChainHammer.TransitionMatrix: holding_times
state_holding_times = holding_times(markov_chain, 3; dt = dt)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">3-element Vector{Vector{Float64}}:
[2.0, 1.0, 2.0]
[3.0, 2.0]
[1.0]</code></pre><p>The first argument to the function is the markov<em>chain, the second argument is the total number of states, and the keyword argument is the time step size associated with the entries of the markov</em>chain.</p><p>We see, from the markov chain, that state 1 spends 2 time units in state 1, followed by 1 time unit, then follow by 2 time units. State 2 spends 3 time units repeating itself, then two time units. And lastly, state 3 is only observed once for one time unit.</p><p>The diagonals of the <span>$Q$</span> matrix are given by taking the average of the holding times, then taking the reciprocal. We can verify this manually by importing the <code>mean</code> function from the <code>Statistics</code> package.</p><pre><code class="language-julia hljs">using Statistics
1 ./ mean.(state_holding_times)</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">3-element Vector{Float64}:
0.6
0.4
1.0</code></pre><p>We can verify the off diagonal terms as well. We just need to track the number of times that a given state was exited. For example, when leaving state 1 we observe <span>$1 \rightarrow 2$</span>, read as 1 transitions to 2, <span>$1 \rightarrow 3$</span>, and <span>$1 \rightarrow 2$</span>. Thus going from state state 1 to state 2 is twice as likely as going from state 1 to state 3 and the associated probabilities are <span>$2/3$</span> for transitioning from 1 to 2 and <span>$1/3$</span> for transitioning from 2 to 3. These two probabilities then get multiplied by the reciprocal empircal holding time for being in state 1, which in this case is <span>$0.6$</span> to yield the first column of the <span>$Q$</span> matrix </p><pre><code class="language-julia hljs">Q[:, 1]</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">3-element Vector{Float64}:
-0.6
0.39999999999999997
0.19999999999999998</code></pre><p>For the other two states we observe that we only see state 2 transitioning to state 1 and state 3 only ever transitions to state 1, thus the matrix entries are <span>$Q_{32} = Q_{23} = 0$</span>. The requirement that the columns must sum to zero then determines the other entries (or noticing that the probability of going to state 1 after having left state 2 is 1 and similarly for state 3).</p><p>This brings us to our first warning about constructing the empirical generator. It is most meaningful when there is enough timeseries data to stay within a given state for more than one &quot;timestep&quot;. </p><p>Our last comment is that changing <span>$dt$</span> amounts to rescaling the generator. That is to say, </p><pre><code class="language-julia hljs">Q1 = generator(markov_chain; dt = 1.0)
Q2 = generator(markov_chain; dt = 2.0)
Q1 - 2.0 * Q2</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">3×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0</code></pre><p>As a last comment we mention that one can also construct the transfer operator, then take the matrix logarithm, and then divide by <span>$dt$</span> to get another estimate of the generator; however, the resulting matrix no longer has an &quot;infinitesimal&quot; probabilistic interpretation, as the following example shows</p><pre><code class="language-julia hljs">using MarkovChainHammer.TransitionMatrix: perron_frobenius
dt = 1.0
ℳ = perron_frobenius(markov_chain)
log(ℳ) / dt</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">3×3 Matrix{ComplexF64}:
-0.612402+1.03113im 0.299568-0.241032im 0.665466-3.22739im
0.479309-0.385651im -0.335089+0.0901481im 0.284164+1.20707im
0.133093-0.645477im 0.0355205+0.150884im -0.949629+2.02032im</code></pre><p>The columns still sum to zero, but the entries of the matrix no longer have an interpretation as holding times or probabilities. This example also shows why generators have a much more limited and special structure as compared to the transfer operator. The requirement that one generates probabilities over infinitesimal steps imposes severe restrictions. We may lift these restrictions if we are willing to give up computing an infinitesimal generator and live with generators that are applicable only over a finite timescale. This fact reflects a well-known theorem in numerical analysis that positivity preserving linear operators are inherently lower-order. </p><p>An alternative way to construct the generator from the perron-frobenius operator is to take the difference between the identity matrix and the perron-frobenius operator and then divide by dt</p><pre><code class="language-julia hljs">using LinearAlgebra
dt = 1.0
Q = (ℳ - I) / dt</code></pre><pre class="documenter-example-output"><code class="nohighlight hljs ansi">3×3 Matrix{Float64}:
-0.6 0.25 1.0
0.4 -0.25 0.0
0.2 0.0 -1.0</code></pre><p>where we had to use the <code>LinearAlgebra</code> package to import the identity matrix. This calculation makes use of the relation that the generator is the infinitesimal generator of the perron-frobenius operator</p><p class="math-container">\[\mathcal{M} = e^{dt Q} \approx \mathbb{I} + dt Q \]</p><p>This is only good if the timesteps are sufficiently small.</p></article><nav class="docs-footer"><a class="docs-footer-prevpage" href="../generators/">« Generators</a><a class="docs-footer-nextpage" href="../convergence/">Convergence of Generators »</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="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 0.27.25 on <span class="colophon-date" title="Thursday 7 December 2023 17:22">Thursday 7 December 2023</span>. Using Julia version 1.8.5.</p></section><footer class="modal-card-foot"></footer></div></div></div></body></html>
Loading

0 comments on commit 17f4487

Please sign in to comment.