diff --git a/mlss/Bayesian Machine Learning.jl b/mlss/Bayesian Machine Learning.jl new file mode 100644 index 00000000..9ed7281f --- /dev/null +++ b/mlss/Bayesian Machine Learning.jl @@ -0,0 +1,3311 @@ +### A Pluto.jl notebook ### +# v0.20.19 + +#> [frontmatter] +#> image = "https://github.com/bmlip/course/blob/v2/assets/figures/scientific-inquiry-loop-w-BML-eqs.png?raw=true" +#> description = "Introduction to Bayesian modeling, parameter estimation, and model evaluation." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ b32d2d36-f3a5-406f-adf6-c7b8ebe6cc77 +using MarkdownLiteral: @mdx + +# ╔═╡ 17182feb-2c58-4485-aadc-114003376607 +using Random + +# ╔═╡ df312e6a-503f-486f-b7ec-15404070960c +using Distributions, StatsPlots, SpecialFunctions + +# ╔═╡ caba8eee-dfea-45bc-a8a7-1dd20a1fa994 +using BmlipTeachingTools + +# ╔═╡ 3987d441-b9c8-4bb1-8b2d-0cc78d78819e +using Plots, LaTeXStrings, Plots.PlotMeasures + +# ╔═╡ 6a23b828-d294-11ef-371a-05d061144a43 +title("Bayesian Machine Learning") + +# ╔═╡ 6be2e966-4048-44d0-a37e-95060e3fe30b +PlutoUI.TableOfContents() + +# ╔═╡ 6a23df9e-d294-11ef-3ddf-a51d4cea00fc +md""" +## Preliminaries + +##### Goals + + * Introduction to Bayesian (i.e., probabilistic) modeling + +##### Materials + + * Mandatory + + * These lecture notes + + * Optional + + * Bishop pp. 68-74 (on the coin toss example) + * [Ariel Caticha - 2012 - Entropic Inference and the Foundations of Physics](https://github.com/bmlip/course/blob/main/assets/files/Caticha-2012-Entropic-Inference-and-the-Foundations-of-Physics.pdf), pp.35-44 (section 2.9, on deriving Bayes rule for updating probabilities) + + + +""" + +# ╔═╡ eca027f8-40c9-4e53-85b5-d08b8fe9dd97 +challenge_statement("Predicting a Coin Toss",header_level=1) + +# ╔═╡ 4f6a2d4f-bd89-4b0c-b544-397de2e34e72 +md""" + +##### Problem +We observe the following sequence of heads (outcome ``=1``) and tails (outcome ``=0``) when tossing the same coin repeatedly. + +Number of tosses: $(@bind intro_N Slider(1:20; default=7, show_value=true)) +""" + +# ╔═╡ daa1df0e-4ec5-4fb1-a355-a42c35bd35b9 +md""" +What is the probability that heads comes up next? + +##### Solution + +Later in this lecture. +""" + +# ╔═╡ 6a24b9e4-d294-11ef-3ead-9d272fbf89be +md""" +# The Bayesian Modeling Approach + +""" + +# ╔═╡ 6a24c3e6-d294-11ef-3581-2755a9ba15ba +md""" + +Suppose that your application is to predict a future observation ``x``, based on ``N`` past observations ``D=\{x_1,\dotsc,x_N\}``. + +The **Bayesian modeling** approach to solving this task involves four stages: + +""" + +# ╔═╡ e2de9415-7bd8-4e95-abeb-53fc068ee950 +md""" + REPEAT + 1. Model Specification + 2. Parameter Estimation + 3. Model Evaluation + UNTIL model performance is satisfactory + 4. Apply Model +""" + +# ╔═╡ 6a24c9f4-d294-11ef-20cc-172ea50da901 +md""" +In principle, based on the model evaluation results, you may want to re-specify your model and *repeat* the design process (a few times), until model performance is acceptable. + +""" + +# ╔═╡ 6a24cee0-d294-11ef-35cb-71ab9ef935e5 +md""" +Next, we discuss these four stages in a bit more detail. + +""" + +# ╔═╡ 6a24d478-d294-11ef-2a75-9d03a5ba7ff8 +md""" +## 1. Model Specification + +Your first task is to propose a probabilistic model for generating the observations ``x``. + +""" + +# ╔═╡ 6a24fde8-d294-11ef-29bf-ad3e20a53c29 +md""" +A probabilistic model ``m`` consists of a joint distribution ``p(x,\theta|m)`` that relates observations ``x`` to model parameters ``\theta``. Usually, the model is proposed in the form of a data-generating distribution ``p(x|\theta,m)`` and a prior ``p(\theta|m)``, + +""" + +# ╔═╡ a75c75ed-c67b-4be2-adbf-8984f27fc05d +md""" + + +```math +\underbrace{p(x,\theta|m)}_{\text{model}} = \underbrace{p(x|\theta,m)}_{\substack{ \text{data}\\ \text{generation}}} \,\underbrace{p(\theta|m)}_{\text{prior}} \,. +``` + +""" + +# ╔═╡ 6a251a08-d294-11ef-171a-27b9d0f818bc +md""" +*You* are responsible to choose the data generating distribution ``p(x|\theta)`` based on your physical understanding of the data generating process. (For brevity, if we are working on one given model ``m`` with no alternative models, we usually drop the given dependency on ``m`` from the notation). + +""" + +# ╔═╡ 6a252250-d294-11ef-33cd-89b18066817d +md""" +*You* must also choose the prior ``p(\theta)`` to reflect what you know about the parameter values before you see the data ``D``. + +""" + +# ╔═╡ 6a25307e-d294-11ef-0662-3db678b32e99 +md""" +## 2. Parameter Estimation + +You must now specify a likelihood function for the parameters from the data-generating distribution. Note that, for a given (i.e., *observed*) data set ``D=\{x_1,x_2,\dots,x_N\}`` with *independent* observations ``x_n``, the likelihood factorizes as + +```math + p(D|\theta) = \prod_{n=1}^N p(x_n|\theta)\,. +``` + +So, usually you select the data-generating distribution for one observation ``x_n`` and then use (in-)dependence assumptions to combine these models into a likelihood function for the model parameters. + +""" + +# ╔═╡ 6a25379a-d294-11ef-3e07-87819f6d75cb +md""" +The likelihood and prior both contain information about the model parameters. Next, you use Bayes rule to fuse these two information sources into a posterior distribution for the parameters: + +```math +\begin{align*} +\underbrace{p(\theta|D) }_{\text{posterior}} =\frac{\overbrace{p(D|\theta)}^{\text{likelihood}} \,\overbrace{p(\theta)}^{\text{prior}}}{\underbrace{\int p(D|\theta) p(\theta) \mathrm{d}\theta}_{p(D)\text{ (evidence)}}} +\end{align*} +``` + +""" + +# ╔═╡ 6a254460-d294-11ef-1890-230b75b6b9ee +md""" +Note that there's **no need for you to design some clever parameter estimation algorithm**. Bayes rule *is* the parameter estimation algorithm, which can be entirely expressed in terms of the likelihood and prior. The only complexity lies in the computational issues (in particular, the computational load of computing the evidence)! + +""" + +# ╔═╡ 6a2552ac-d294-11ef-08d6-179e068bc297 +md""" +This parameter estimation "recipe" works if the right-hand side (RHS) factors can be evaluated; the computational details can be quite challenging and this is what machine learning is about. + + +""" + +# ╔═╡ ce75e785-868f-4361-93f8-c582ac1b891b +keyconcept(" ", + md""" + + Bayesian Machine learning is EASY, apart from computational details :) + + """ +) + +# ╔═╡ 6a2561c0-d294-11ef-124d-373846e3120c +md""" +## 3. Model Evaluation + +In the framework above, parameter estimation was executed by "perfect" Bayesian reasoning. So is everything settled now? + +""" + +# ╔═╡ 6a257020-d294-11ef-0490-e151934b2f42 +md""" +No, there appears to be one remaining problem: how good really were our assumptions ``p(D|\theta)`` and ``p(\theta)`` in the model specification phase? We want to "score" the model performance. + +""" + +# ╔═╡ 6a257f34-d294-11ef-2928-fbb800e81124 +md""" +Note that this question is only interesting in practice if we have alternative models to choose from. After all, if you don't have an alternative model, any value for the model evidence would still not lead you to switch to another model. + +""" + +# ╔═╡ 6a25a11e-d294-11ef-1c51-09482dad86f2 +md""" +Let's assume that we have more candidate models, say ``\mathcal{M} = \{m_1,\ldots,m_K\}`` where each model relates to a specific prior ``p(\theta|m_k)`` and likelihood ``p(D|\theta,m_k)``? Can we evaluate the relative performance of a model against another model from the set? + +""" + +# ╔═╡ 6a25edfc-d294-11ef-3411-6f74c376461e +md""" +Start again with **model specification**. *You* must now specify a *model* prior ``p(m_k)`` (next to the likelihood ``p(D|\theta,m_k)`` and *parameter* prior ``p(\theta|m_k)``) for each of the models to get a new model specification that includes the model ``m_k`` as a parameter: +""" + +# ╔═╡ 53de7edd-6c28-49a7-9f54-cf7b8ca42aeb +md""" +```math +p(D,\theta,m_k) = p(D|\theta,m_k) p(\theta|m_k) p(m_k) +``` +""" + +# ╔═╡ 288fbee6-0783-4447-b5d0-f5c2b29b39c7 +md""" + +Then, solve the desired inference problem for the posterior over the model ``m_k``: + +```math +\begin{align} +\underbrace{p(m_k|D)}_{\substack{\text{model}\\\text{posterior}}} + \propto \underbrace{p(m_k)}_{\substack{\text{model}\\\text{prior}}}\, \underbrace{\int_\theta \underbrace{p(D|\theta,m_k)}_{\text{likelihood}} \,\underbrace{p(\theta|m_k)}_{\substack{\text{parameter} \\ \text{prior}}}\, \mathrm{d}\theta }_{\substack{\text{evidence }p(D|m_k)\\\text{= model likelihood}}}\\ +\end{align} +``` + +""" + +# ╔═╡ 74fa1925-0d9f-47f6-a6bd-b822948a4fbc +details("Prove this yourself, and click for solution", +md""" +```math +\begin{align} +p(m_k|D)&= \frac{p(m_k,D) }{p(D)} \\ + &\propto p(m_k,D)\\ + &= \int_\theta p(D,\theta,m_k) \,\mathrm{d}\theta\\ + &= p(m_k)\int_\theta p(D|\theta,m_k)\,p(\theta|m_k)\, \mathrm{d}\theta +\end{align} +``` +""") + +# ╔═╡ 6a261278-d294-11ef-25a0-5572de58ad06 +md""" +You *can* evaluate the RHS of this equation since *you* selected the model priors ``p(m_k)``, the parameter priors ``p(\theta|m_k)``, and the likelihoods ``p(D|\theta,m_k)``. + +""" + +# ╔═╡ 6a26549a-d294-11ef-1f10-15c4d14ae41f +md""" +Note that, to evaluate the model posterior, you must calculate the **model evidence** ``p(D|m_k)``, which can be interpreted as a likelihood function for model ``m_k``. + +""" + +# ╔═╡ 6a262182-d294-11ef-23e9-ed45e1da9f46 +md""" +You can now compare posterior distributions ``p(m_k|D)`` for a set of models ``\{m_k\}`` and decide on the merits of each model relative to alternative models. This procedure is called **Bayesian model comparison**. + +""" + +# ╔═╡ 6a2672d6-d294-11ef-1886-3195c9c7cfa9 +md""" +Again, **no need to invent a special algorithm for estimating the performance of your model**. Straightforward application of probability theory takes care of all that. + +""" + +# ╔═╡ 6aa2399d-a949-40f9-8ee6-b0c2be1dc478 +keyconcept(" ", + md""" + + In a Bayesian modeling framework, **model evaluation** follows the same recipe as parameter estimation; it just works at one higher hierarchical level. + + """ +) + + +# ╔═╡ 6a2664c6-d294-11ef-0a49-5192e17fb9ea +md""" + +Compare the calculations between parameter estimation and model evaluation +```math +\begin{align*} +p(\theta|D) &\propto p(D|\theta) p(\theta) \; &&\text{(parameter estimation)} \\ +p(m_k|D) &\propto p(D|m_k) p(m_k) \; &&\text{(model evaluation)} +\end{align*} +``` + +""" + +# ╔═╡ 6a26a31e-d294-11ef-2c2f-b349d0859a27 +md""" +With the (relative) performance evaluation scores of your model in hand, you could now re-specify your model (hopefully an improved model) and *repeat* the design process until the model performance score is acceptable (see the 4-step [Bayesian modeling process](#Bayesian-modeling-recipe) above). + +""" + +# ╔═╡ 6a269568-d294-11ef-02e3-13402d296391 +md""" +In principle, you could proceed with asking how good your choice for the candidate model set ``\mathcal{M}`` was. You would have to provide a set of alternative model sets ``\{\mathcal{M}_1,\mathcal{M}_2,\ldots,\mathcal{M}_M\}`` with priors ``p(\mathcal{M}_m)`` for each set and compute posteriors ``p(\mathcal{M}_m|D)``. And so forth ... + +""" + +# ╔═╡ 6a26b7bc-d294-11ef-03e7-2715b6f8dcc7 +md""" +### Bayes Factors + +""" + +# ╔═╡ 6a26f244-d294-11ef-0488-c1e4ec6e739d +md""" +As an aside, in the (statistics and machine learning) literature, performance comparison between two models is often reported by the [Bayes Factor](https://en.wikipedia.org/wiki/Bayes_factor), which is defined as the ratio of model evidences: + +```math +\begin{align*} +\mathrm{BF_{12}} \triangleq \frac{p(D|m_1)}{p(D|m_2)} += \underbrace{\frac{p(m_1|D)}{p(m_2|D)}}_{\substack{\text{posterior} \\ \text{ratio}}} \cdot \underbrace{\frac{p(m_2)}{p(m_1)}}_{\substack{\text{prior} \\ \text{ratio}}} +\end{align*} +``` +""" + +# ╔═╡ 99db44c9-185c-4f39-ae5e-1a4cd751d980 +details("Prove this yourself, and click for solution", +md""" +```math +\begin{align*} +\mathrm{BF_{12}} &= \frac{p(D|m_1)}{p(D|m_2)} \\ +&= \frac{p(D,m_1)}{p(m_1)} \bigg/ \frac{p(D,m_2)}{p(m_2)} \\ +&= \frac{p(m_1|D) p(D)}{p(m_1)} \cdot \frac{p(m_2)}{p(m_2|D) p(D)} \\ +&= \frac{p(m_1|D)}{p(m_2|D)} \cdot \frac{p(m_2)}{p(m_1)} +\end{align*} +``` +""") + +# ╔═╡ d22f58ac-9f68-41cb-8e61-cf74d3692c44 +md""" +Hence, for equal model priors (``p(m_1)=p(m_2)=0.5``), the Bayes Factor reports the posterior probability ratio for the two models. + +In principle, any hard decision on which is the better model has to accept some *ad hoc* arguments. [Jeffreys (1961)](https://www.amazon.com/Theory-Probability-Classic-Physical-Sciences/dp/0198503687/ref=sr_1_1?qid=1663516628&refinements=p_27%3Athe+late+Harold+Jeffreys&s=books&sr=1-1&text=the+late+Harold+Jeffreys) advises to use the **log-Bayes factor**, + +```math +\mathrm{logBF}_{12} := ^{10}\log\frac{p(D|m_1)}{p(D|m_2)} \,, +``` + +to quantify evidence for preferring model ``m_1`` over ``m_2`` by the following interpretation: + +| ``\mathrm{logBF}_{12}`` | Evidence for ``m_1`` | +|:---------------------|:----------------------------| +| 0 to 0.5 | not worth mentioning | +| 0.5 to 1 | substantial | +| 1 to 2 | strong | +| >2 | decisive | + +""" + +# ╔═╡ 6a2707e6-d294-11ef-02ad-31bf84662c70 +md""" +## 4. Apply Model (Prediction) + +Once we are satisfied with the evidence for a (trained) model, we can apply the model to our prediction/classification/etc task. + +""" + +# ╔═╡ 6a271a56-d294-11ef-0046-add807cc0b4f +md""" +Given the data ``D``, our knowledge about a yet unobserved datum ``x`` is captured by the following inference problem (where everything is conditioned on the selected model): + +```math +p(x|D) = \int \underbrace{p(x|\theta)}_{\substack{\text{data } \\ \text{generating}}} \, \underbrace{p(\theta|D)}_{\text{posterior}} \,\mathrm{d}\theta +``` + +""" + +# ╔═╡ f6ee5570-9b92-42b6-baf3-3eed5352a060 +details("Prove this yourself, and click for solution", +md""" +```math +\begin{align*} +p(x|D) &\stackrel{s}{=} \int p(x,\theta|D) \,\mathrm{d}\theta\\ + &\stackrel{p}{=} \int p(x|\theta,D) p(\theta|D) \,\mathrm{d}\theta\\ + &\stackrel{m}{=} \int p(x|\theta) \, p(\theta|D) \,\mathrm{d}\theta +\end{align*} +``` + +In the last equation, the simplification ``p(x|\theta,D) = p(x|\theta)`` follows from our model specification. In particular, we assumed a *parametric* data generating distribution ``p(x|\theta)`` with no explicit dependency on the data set ``D``. Technically, in our model specification, we assumed that ``x`` is conditionally independent from ``D``, given the parameters ``\theta``, i.e., we assumed ``p(x|\theta, D) = p(x|\theta)``. The information from the data set ``D`` has been absorbed in the posterior ``p(\theta|D)``, so all information from ``D`` is passed to a new observation ``x`` through the (posterior distribution over the) parameters ``\theta``. + +""") + +# ╔═╡ 6a273ae0-d294-11ef-2c00-9b3eaed93f6d +md""" +Again, **no need to invent a special prediction algorithm**. Probability theory takes care of all that. The complexity of prediction is just computational, namely, how to carry out the marginalization over ``\theta``. + +""" + +# ╔═╡ 6a274948-d294-11ef-0563-1796b8883306 +md""" +Note that the application of the learned posterior ``p(\theta|D)`` not necessarily has to be a prediction task. We use it here as an example, but other applications (e.g., classification, regression etc.) are of course also possible. + +""" + +# ╔═╡ 6a275a52-d294-11ef-1323-9d83972f611a +md""" +### Prediction with multiple models + +When you have a posterior ``p(m_k|D)`` for the models, you don't *need* to choose one model for the prediction task. You can do prediction by **Bayesian model averaging**, which combines the predictive power from all models: + +```math +\begin{align*} +p(x|D) &= \sum_k \int p(x,\theta,m_k|D)\,\mathrm{d}\theta \\ + &= \sum_k \int p(x|\theta,m_k) \,p(\theta|m_k,D)\, p(m_k|D) \,\mathrm{d}\theta \\ + &= \sum_k \underbrace{p(m_k|D)}_{\substack{\text{model}\\\text{posterior}}} \cdot \int \underbrace{p(\theta|m_k,D)}_{\substack{\text{parameter}\\\text{posterior}}} \, \underbrace{p(x|\theta,m_k)}_{\substack{\text{data generating}\\\text{distribution}}} \,\mathrm{d}\theta +\end{align*} +``` + +""" + +# ╔═╡ 6a27684e-d294-11ef-040e-c302cdad714a +md""" +Alternatively, if you do need to work with one model (e.g. due to computational resource constraints), you can for instance select the model with largest posterior ``p(m_k|D)`` and use that model for prediction. This is called **Bayesian model selection**. + +""" + +# ╔═╡ 6a2777d0-d294-11ef-1ac3-add102c097d6 +md""" +Bayesian model averaging is the principal way to apply PT to machine learning. You don't throw away information by discarding lesser performant models, but rather use PT (marginalization of models) to compute + +```math +p(\text{what-I-am-interested-in} \,|\, \text{all available information})\,. +``` + +""" + +# ╔═╡ 6a278784-d294-11ef-11ae-65bd398910d5 +md""" +## We're Done! + +In principle, you now have the recipe in your hands to solve all your prediction/classification/regression (etc.) problems by the same Bayesian modeling method: + +""" + +# ╔═╡ c03229ef-3e0f-4612-909b-97f488a1e4c9 +md""" + REPEAT + 1. Model Specification + 2. Parameter Estimation + 3. Model Evaluation + UNTIL model performance is satisfactory + 4. Apply Model +""" + +# ╔═╡ 6a27951c-d294-11ef-2e1a-b5a4ce84aceb +md""" +Crucially, there is no need to invent clever machine learning algorithms, and there is no need to invent a clever prediction algorithm nor a need to invent a model performance criterion. Instead, you propose a model and, from there on, you let PT reason about everything that you care about. + +""" + +# ╔═╡ 6a27a28a-d294-11ef-1f33-41b444761429 +md""" +Your problems are only of computational nature. Perhaps the integral to compute the evidence may not be analytically tractable, etc. + +""" + +# ╔═╡ 55dec435-aa78-41ba-aad5-9d79ce292f42 +keyconcept("", "Bayesian machine learning is a subfield of machine learning that commits entirely to probability theory as the framework for all information-processing tasks. This is well justified, because probability theory is the optimal calculus for representing and manipulating states of knowledge.") + +# ╔═╡ 6a27b114-d294-11ef-099d-1d55968934a6 +md""" +## Bayesian Evidence as a Model Performance Criterion + +I'd like to convince you that $(HTML("Bayesian model evidence")) ``p(D|m)`` is an excellent criterion for assessing your model's performance. To do so, let us consider a decomposition that relates model evidence to other highly-valued criteria such as **accuracy** and **model complexity**. + +""" + +# ╔═╡ 6a27beca-d294-11ef-1895-d57b11b827c1 +md""" +Consider a model ``p(x,\theta|m)`` and a data set ``D = \{x_1,x_2, \ldots,x_N\}``. + +""" + +# ╔═╡ cc8af69e-6d00-4327-aaa2-0b1023052b8a +md""" +Given the data set ``D``, the log-evidence for model ``m`` decomposes as +""" + +# ╔═╡ c454be00-05e7-42f6-a243-bf559ed6eff7 +md""" +```math +\begin{flalign} +\underbrace{\log p(D|m)}_{\text{log-evidence}} = \underbrace{\int p(\theta|D,m) \log p(D|\theta,m) \mathrm{d}\theta}_{\text{accuracy (a.k.a. data fit)}} - \underbrace{\int p(\theta|D,m) \log \frac{p(\theta|D,m)}{p(\theta|m)} \mathrm{d}\theta}_{\text{complexity}} \,. +\end{flalign} +``` + +""" + +# ╔═╡ 6a9ad1c4-dfb2-4987-9ddc-da6131605083 +hide_proof( +md""" +```math +\begin{flalign} +\log p(D|m)&= \log p(D|m) \cdot \underbrace{\int p(\theta|D,m)\mathrm{d}\theta}_{\text{evaluates to }1} \\ + &= \int p(\theta|D,m) \log p(D|m) \mathrm{d}\theta \qquad \text{(move $\log p(D|m)$ into the integral)} \\ + &= \int p(\theta|D,m) \log \underbrace{\frac{p(D|\theta,m) p(\theta|m)}{p(\theta|D,m)}}_{\text{by Bayes rule}} \mathrm{d}\theta \\ + &= \underbrace{\int p(\theta|D,m) \log p(D|\theta,m) \mathrm{d}\theta}_{\text{accuracy (a.k.a. data fit)}} - \underbrace{\int p(\theta|D,m) \log \frac{p(\theta|D,m)}{p(\theta|m)} \mathrm{d}\theta}_{\text{complexity}} +\end{flalign} +``` +""") + +# ╔═╡ 6a27efc6-d294-11ef-2dc2-3b2ef95e72f5 +md""" +The "accuracy" term (also known as data fit) measures how well the model predicts the data set ``D``. We want this term to be high because good models should predict the data ``D`` well. Indeed, higher accuracy leads to higher model evidence. To achieve high accuracy, applying Bayes' rule will shift the posterior ``p(\theta|D)`` away from the prior towards the likelihood function ``p(D|\theta)``. + +""" + +# ╔═╡ 6a280132-d294-11ef-10ac-f3890cb3f78b +md""" +The second term ("complexity", also known as "information gain") is technically a [Kullback-Leibler divergence](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence) (KLD) between the posterior and prior distributions, see [OPTIONAL SLIDE](#KLD) below. The KLD is an information-theoretic quantity that can be interpreted as a "distance" measure between two distributions. In other words, the complexity term measures how much the beliefs about ``\theta`` changed, due to learning from the data ``D``. Generally, we like the complexity term to be low, because moving away means forgetting previously acquired information represented by the prior. Indeed, lower complexity leads to higher model evidence. + +""" + +# ╔═╡ 6a2814b0-d294-11ef-3a76-9b93c1fcd4d5 +md""" +Models with high evidence ``p(D|m)`` prefer both high accuracy and low complexity. Therefore, models with high evidence tend to predict the training data ``D`` well (high accuracy), yet also try to preserve the information encoded by the prior (low complexity). These types of models are said to *generalize* well, since they can be applied to different data sets without specific adaptations for each data set. + +""" + +# ╔═╡ 6a282892-d294-11ef-2c12-4b1c7374617c +md""" +Focussing only on accuracy maximization could lead to *overfitting* of the data set ``D``. Focussing only on complexity minimization could lead to *underfitting* of the data. Bayesian ML attends to both terms and avoids both underfitting and overfitting. + +""" + +# ╔═╡ 6a286b04-d294-11ef-1b34-8b7a85c0048c +keyconcept(" ", + md""" + + Bayesian learning automatically leads to models that generalize well. There is **no need for early stopping or validation data sets**. There is also **no need for tuning parameters** in the learning process. Just learn on the full data set and all behaves well. + """ +) + +# ╔═╡ 6a2879e6-d294-11ef-37db-df7babe24d25 +md""" +Put provocatively, this highlights that the common machine learning practice of splitting a dataset into training, validation, and test sets is, in essence, an ad hoc workaround, a substitute for formulating the learning task properly as a Bayesian inference problem. + +""" + +# ╔═╡ 6a2889ae-d294-11ef-2439-e1a541a5ccd7 +md""" +## Bayesian Modeling and the Scientific Method Revisited + +The Bayesian modeling approach provides a unified framework for the Scientific Inquiry method. We can now add equations to the design loop. (Trial design to be discussed in [Intelligent Agent lesson](https://bmlip.github.io/course/lectures/Intelligent%20Agents%20and%20Active%20Inference.html).) + +![](https://github.com/bmlip/course/blob/v2/assets/figures/scientific-inquiry-loop-w-BML-eqs.png?raw=true) + +""" + +# ╔═╡ c050f468-7eec-403f-9304-552bd0d9b222 +html""" + +""" + +# ╔═╡ 1dbc69a3-b3ec-44de-af7c-944ebc01f523 +challenge_solution("Predicting a Coin Toss",header_level=1) + +# ╔═╡ 6a2898ea-d294-11ef-39ec-31e4bac1e048 +md""" + +At the beginning of this lesson, we posed the following challenge: + +We observe a the following sequence of heads (outcome = ``1``) and tails (outcome = ``0``) when tossing the same coin repeatedly + +```math +D=\{1011001\}\,. +``` + +What is the probability that heads comes up next? We solve this in the next slides ... + +""" + +# ╔═╡ 6a28a704-d294-11ef-1bf2-efbdb0cb4cbc +md""" +## 1. Model Specification for Coin Toss + +We observe a sequence of ``N`` coin tosses ``D=\{x_1,\ldots,x_N\}`` with ``n`` heads. + +""" + +# ╔═╡ 6a28b44c-d294-11ef-15da-81be8753d311 +md""" +Let us denote outcomes by + +```math +x_k = \begin{cases} 1 & \text{if heads comes up} \\ + 0 & \text{otherwise (tails)} \end{cases} + +``` + +""" + +# ╔═╡ 6a28c9b4-d294-11ef-222b-97bf0912efe7 +md""" +### Likelihood + +Assume a [**Bernoulli** distributed](https://en.wikipedia.org/wiki/Bernoulli_distribution) variable ``p(x_k=1|\mu)=\mu`` for a single coin toss, leading to + +```math +p(x_k|\mu)=\mu^{x_k} (1-\mu)^{1-x_k} \,. +``` + +Assume ``n`` times heads were thrown out of a total of ``N`` throws. The likelihood function then follows a [**binomial** distribution](https://en.wikipedia.org/wiki/Binomial_distribution) : + +```math + +p(D|\mu) = \prod_{k=1}^N p(x_k|\mu) = \mu^n (1-\mu)^{N-n} +``` + +""" + +# ╔═╡ 6a28d81e-d294-11ef-2a9f-d32daa5556ae +md""" +### $(HTML("Prior")) + +Assume the prior beliefs for ``\mu`` are governed by a [**beta distribution**](https://en.wikipedia.org/wiki/Beta_distribution) + +```math +p(\mu) = \mathrm{Beta}(\mu|\alpha,\beta) = \frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)} \mu^{\alpha-1}(1-\mu)^{\beta-1} +``` + +where the [Gamma function](https://en.wikipedia.org/wiki/Gamma_function) is sort-of a generalized factorial function. In particular, if ``\alpha,\beta`` are integers, then + +```math +\frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)} = \frac{(\alpha+\beta-1)!}{(\alpha-1)!\,(\beta-1)!} +``` + +""" + +# ╔═╡ 6a28e674-d294-11ef-391b-0d33fd609fb8 +md""" +A *what* distribution? Yes, the **beta distribution** is a [**conjugate prior**](https://en.wikipedia.org/wiki/Conjugate_prior) for the binomial distribution, which means that + +```math +\underbrace{\text{beta}}_{\text{posterior}} \propto \underbrace{\text{binomial}}_{\text{likelihood}} \times \underbrace{\text{beta}}_{\text{prior}} +``` + +so we get a closed-form posterior. + +""" + +# ╔═╡ 6a28f466-d294-11ef-3af9-e34de9736c71 +md""" + +``\alpha`` and ``\beta`` are called **hyperparameters**, since they parameterize the distribution for another parameter (``\mu``). E.g., ``\alpha=\beta=1`` leads to a uniform prior for ``\mu``. We use Julia below to visualize some priors ``\mathrm{Beta}(\mu|\alpha,\beta)`` for different values of ``\alpha, \beta``. + +""" + +# ╔═╡ 51bed1cc-c960-46fe-bc09-2b684df3b0cc +# maintain a vector of log evidences to plot later +params = [ + (α=0.1, β=0.1) + (α=1.0, β=1.0) + (α=2.0, β=3.0) + (α=8.0, β=4.0) +]; + +# ╔═╡ 513414c7-0a54-4767-a583-7d779f8fbc55 +let + x = 0:0.01:1 + + plots = map(enumerate(params)) do (i, (α, β)) + y = pdf.(Beta(α, β), x) + plot(x, y; + label="α=$α, β=$β", + xlabel=i in [3, 4] ? "μ" : nothing, + ylabel=i in [1, 3] ? "Density" : nothing, + ) + end + + plot(plots...; + layout=(2, 2), + suptitle="PDFs of some Beta distributions", + legend=:topleft, + link=:both, + padding=10, + ) +end + +# ╔═╡ ee3da94c-5e87-4a0b-8373-c01e339d28aa +md""" +##### Pick Your Own Parameters + + +α = $(@bind beta_pdf_a NumberField(.1:.1:1000; default=6.0)), +β = $(@bind beta_pdf_b NumberField(.1:.1:1000; default=2.0)) +""" + +# ╔═╡ 261620b0-9580-4d9e-b7de-d7972ea549cd +let + α = isnan(beta_pdf_a) ? 0.1 : beta_pdf_a + β = isnan(beta_pdf_b) ? 0.1 : beta_pdf_b + x = 0:0.01:1 + + y = pdf.(Beta(α, β), x) + plot(x, y; + # label="α=$α, β=$β", + ylim=(0, clamp(maximum(y)*1.05, 4, 4)), + label=nothing, + xlabel="μ", + ylabel="Density", + size=(600,250) + ) + +end + +# ╔═╡ 6a294790-d294-11ef-270b-5b2152431426 +md""" +#### Choosing a Prior + +Before observing any data, you can express your state-of-knowledge about the coin by choosing values for ``\alpha`` and ``\beta`` that reflect your beliefs. Stronger yet, you *must* choose values for ``\alpha`` and ``\beta``, because the Bayesian framework does not allow you to walk away from your responsibility to explicitly state your beliefs before the experiment. + +""" + +# ╔═╡ b872cd69-d534-4b04-bb76-d85bb7ef0ea9 +md""" +## 2. Parameter Estimation for Coin Toss + +Next, infer the posterior PDF over ``\mu`` (and evidence) through Bayes rule, +""" + +# ╔═╡ 1ba1939d-9986-4b97-9273-4f2434f1d385 +md""" +```math +\begin{flalign*} +p&(D|\mu)\cdot p(\mu) \\ + &= \underbrace{\biggl(\frac{B(n+\alpha,N-n+\beta)}{B(\alpha,\beta)}\biggr)}_{\text{evidence }p(D)} \cdot \underbrace{\biggl( \frac{1}{B(n+\alpha,N-n+\beta)} \mu^{n+\alpha-1} (1-\mu)^{N-n+\beta-1}\biggr)}_{\text{posterior }p(\mu|D)=\mathrm{Beta}(\mu|n+\alpha, N-n+\beta)} +\end{flalign*} +``` +where ``B(\alpha,\beta) \triangleq \frac{\Gamma(\alpha) \Gamma(\beta)}{\Gamma(\alpha + \beta)}``. +""" + +# ╔═╡ b426df32-5629-4773-b862-101cfbd82d42 +details("Prove this, and click for solution", +md""" +```math +\begin{flalign*} +p&(D|\mu)\cdot p(\mu) \\ + &= \underbrace{\biggl( \mu^n (1-\mu)^{N-n}\biggr)}_{\text{likelihood}} \cdot \underbrace{\biggl( \frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)} \mu^{\alpha-1}(1-\mu)^{\beta-1} \biggr)}_{\text{prior}} \\ + &= \frac{\Gamma(\alpha+\beta)}{\Gamma(\alpha)\Gamma(\beta)} \mu^{n+\alpha-1} (1-\mu)^{N-n+\beta-1} \\ + &= \frac{1}{B(\alpha,\beta)} \mu^{n+\alpha-1} (1-\mu)^{N-n+\beta-1} \\ + &= \underbrace{\biggl(\frac{B(n+\alpha,N-n+\beta)}{B(\alpha,\beta)}\biggr)}_{\text{evidence }p(D)} \cdot \underbrace{\biggl( \frac{1}{B(n+\alpha,N-n+\beta)} \mu^{n+\alpha-1} (1-\mu)^{N-n+\beta-1}\biggr)}_{\text{posterior }p(\mu|D)=\mathrm{Beta}(\mu|n+\alpha, N-n+\beta)} +\end{flalign*} +``` +In the final equation, we included the term ``\frac{1}{B(n+\alpha,\,N-n+\beta)}`` to normalize the posterior ``p(\mu | D)``, and we compensated for this normalization in the evidence factor. + """) + +# ╔═╡ 181ade96-8e1e-4186-9227-c1561352529d +md""" +Hence, the posterior is also beta-distributed as + +```math +p(\mu|D) = \mathrm{Beta}(\mu|\,n+\alpha, N-n+\beta) +``` + +""" + +# ╔═╡ 6a29d548-d294-11ef-1361-ad2230cad02b +md""" +## 3. Model Evaluation for Coin Toss + +It follow from the above calculation that the evidence for model ``m`` can be analytically expressed as + +```math +\begin{align} +p(D|m) &= \frac{B(n+\alpha,N-n+\beta)}{B(\alpha,\beta)} \\ +\Big( &= \frac{\Gamma(n+\alpha) \Gamma(N-n+\beta)}{\Gamma(N+\alpha+\beta)} \Bigg/ \frac{\Gamma(\alpha)\Gamma(\beta)}{\Gamma(\alpha+\beta)}\,. \Big) +\end{align} +``` + +The model evidence is a scalar. In the absence of an alternative model, the value of the model evidence is not very useful. However, you may want to compare the model evidence of this model to the evidence for another model on the same data set. + +""" + +# ╔═╡ 6a29e25e-d294-11ef-15ce-5bf3d8cdb64c +md""" +## 4. Prediction (Application) for Coin Toss + +Once we have accepted a model, let's apply it to the application, in this case, predicting future observations. + +""" + +# ╔═╡ 6a29f1c2-d294-11ef-147f-877f99e5b57c +md""" +Marginalize over the parameter posterior to get the predictive PDF for a new coin toss ``x_\bullet``, given the data ``D``, + +```math +\begin{align*} +p(x_\bullet=1|D) &= \int_0^1 p(x_\bullet=1|\mu)\,p(\mu|D) \,\mathrm{d}\mu \\ + &= \int_0^1 \mu \times \mathrm{Beta}(\mu|\,n+\alpha, N-n+\beta) \,\mathrm{d}\mu \\ + &= \frac{n+\alpha}{N+\alpha+\beta} +\end{align*} +``` + +This result is known as [**Laplace's rule of succession**](https://en.wikipedia.org/wiki/Rule_of_succession). + +""" + +# ╔═╡ 6a2a000e-d294-11ef-17d6-bdcddeedc65d +md""" +The above integral computes the mean of a beta distribution, which is given by ``\mathbb{E}[x] = \frac{a}{a+b}`` for ``x \sim \mathrm{Beta}(a,b)``, see [wikipedia](https://en.wikipedia.org/wiki/Beta_distribution). + +""" + +# ╔═╡ 6a2a0f18-d294-11ef-02c2-ef117377ca66 +md""" +Finally, we're ready to solve our challenge: for ``D=\{1011001\}`` and uniform prior (``\alpha=\beta=1``), we get + +```math + p(x_\bullet=1|D)=\frac{n+1}{N+2} = \frac{4+1}{7+2} = \frac{5}{9} +``` + +In other words, given the model assumptions (the Bernoulli data-generating distribution and Beta prior as specified above), and the observations ``D=\{1011001\}``, the probability for observing heads (outcome=``1``) on the next toss is ``\frac{5}{9}``. + +""" + +# ╔═╡ 6a2a1daa-d294-11ef-2a67-9f2ac60a14c5 +md""" +Be aware that there is no such thing as an "objective" or "correct" prediction. Every prediction is conditional on the selected model and the used data set. + +""" + +# ╔═╡ 6a2a2af2-d294-11ef-0072-bdc3c6f95bb3 +md""" +## What did we learn from the data? + +What did we learn from the data? Before seeing any data, we think that the probability for throwing heads is + +```math +\left. p(x_\bullet=1|D) \right|_{n=N=0} = \left.\frac{n+\alpha}{N+\alpha+\beta}\right|_{n=N=0} = \frac{\alpha}{\alpha + \beta}\,. +``` + +""" + +# ╔═╡ 6a2a389e-d294-11ef-1b8c-b55de794b65c +md""" +Hence, ``\alpha`` and ``\beta`` can be interpreted as prior pseudo-counts for heads and tails, respectively. + +""" + +# ╔═╡ 6a2a465e-d294-11ef-2aa0-43c954a6439e +md""" +If we were to assume zero pseudo-counts, i.e. ``\alpha=\beta \rightarrow 0``, then our prediction for throwing heads after ``N`` coin tosses is completely based on the data, given by + +```math +\left. p(x_\bullet=1|D) \right|_{\alpha=\beta \rightarrow 0} = \left.\frac{n+\alpha}{N+\alpha+\beta}\right|_{\alpha=\beta \rightarrow 0} = \frac{n}{N}\,. +``` + +""" + +# ╔═╡ 48fd2dff-796d-48bc-b5a8-bee270d119fd +md""" +Note the following decomposition +""" + +# ╔═╡ e3f9e571-2248-403c-8ab8-f6b99597f595 +md""" +```math +\begin{flalign*} + p(x_\bullet=1|\,D) &= \frac{n+\alpha}{N+\alpha+\beta} \\ + &= \underbrace{\frac{\alpha}{\alpha+\beta}}_{\substack{\text{prior}\\\text{prediction}}} + \underbrace{\underbrace{\frac{N}{N+\alpha+\beta}}_{\text{gain}}\cdot \underbrace{\biggl( \underbrace{\frac{n}{N}}_{\substack{\text{data-based}\\\text{prediction}}} - \underbrace{\frac{\alpha}{\alpha+\beta}}_{\substack{\text{prior}\\\text{prediction}}} \biggr)}_{\text{prediction error}}}_{\text{correction}} +\end{flalign*} +``` + +""" + +# ╔═╡ 90f691ad-046c-4595-99b0-19a1d6cb599e +details("Prove this yourself, and click for solution", +md""" +```math +\begin{align*} + p(x_\bullet=1|\,D) &= \frac{n+\alpha}{N+\alpha+\beta} \\ + &= \frac{\alpha}{N+\alpha+\beta} + \frac{n}{N+\alpha+\beta} \\ + &= \frac{\alpha}{N+\alpha+\beta}\cdot \frac{\alpha+\beta}{\alpha+\beta} + \frac{n}{N+\alpha+\beta}\cdot \frac{N}{N} \\ + &= \frac{\alpha}{\alpha+\beta}\cdot \frac{\alpha+\beta}{N+\alpha+\beta} + \frac{N}{N+\alpha+\beta}\cdot \frac{n}{N} \\ + &= \frac{\alpha}{\alpha+\beta}\cdot \biggl(1-\frac{N}{N+\alpha+\beta} \biggr) + \frac{N}{N+\alpha+\beta}\cdot \frac{n}{N} \\ + &= \underbrace{\frac{\alpha}{\alpha+\beta}}_{\substack{\text{prior}\\\text{prediction}}} + \underbrace{\underbrace{\frac{N}{N+\alpha+\beta}}_{\text{gain}}\cdot \underbrace{\biggl( \underbrace{\frac{n}{N}}_{\substack{\text{data-based}\\\text{prediction}}} - \underbrace{\frac{\alpha}{\alpha+\beta}}_{\substack{\text{prior}\\\text{prediction}}} \biggr)}_{\text{prediction error}}}_{\text{correction}} +\end{align*} +``` + """) + +# ╔═╡ 6a2a9faa-d294-11ef-1284-cfccb1da444e +md""" +Let's interpret this decomposition of the posterior prediction. Before the data ``D`` was observed, our model generated a *prior prediction* ``p(x_\bullet=1) = \frac{\alpha}{\alpha+\beta}``. Next, the degree to which the actually observed data matches this prediction is represented by the *prediction error* ``\frac{n}{N} - \frac{\alpha}{\alpha-\beta}``. The prior prediction is then updated to a *posterior prediction* ``p(x_\bullet=1|D)`` by adding a fraction of the prediction error to the prior prediction. Hence, the data plays the role of "correcting" the prior prediction. + +Note that, since ``0\leq \underbrace{\frac{N}{N+\alpha+\beta}}_{\text{gain}} \lt 1``, the Bayesian prediction lies between (fuses) the prior and data-based predictions. + +""" + +# ╔═╡ 6a2aad42-d294-11ef-3129-3be5be8c82d6 +md""" +For large ``N``, the gain goes to ``1`` and ``\left. p(x_\bullet=1|D)\right|_{N\rightarrow \infty} \rightarrow \frac{n}{N}`` goes to the data-based prediction (the observed relative frequency). + +""" + +# ╔═╡ 6a2abb16-d294-11ef-0243-d376e8a39bb0 +code_example("Bayesian Evolution for the Coin Toss"; big=true) + +# ╔═╡ 54cb380d-8864-4158-ba68-55027ae68971 +md""" +Let's code an example for a sequence of coin tosses, where we assume that the true coin generates data ``x_n \in \{0,1\}`` by a Bernoulli distribution: + +```math +p(x_n|\mu=0.4)=0.4^{x_n} \cdot 0.6^{1-x_n} +``` + +So, this coin is biased! + +""" + +# ╔═╡ 9da43d0f-e605-41b7-9bc6-db5be95bc87f +secret_distribution = Bernoulli(0.4); + +# ╔═╡ b791e819-f5a0-4c44-983b-07d8497516fb +@mdx """ + +```math +D=\\{$(Int.(rand(MersenneTwister(234), secret_distribution, intro_N)))\\}\\,. +``` + +""" + +# ╔═╡ 280e0819-674e-4a58-854d-5a66e0777074 +md""" +### Two Models +To predict the outcomes of future coin tosses, we'll compare **two models**: ``m_1`` and ``m_2``. Both models have the same data-generating distribution (also Bernoulli): + +```math +p(x_n|\mu,m_k) = \mu^{x_n} (1-\mu)^{1-x_n} \quad \text{for }k=1,2 \,, +``` + + +but they have different priors: + +```math +\begin{aligned} +p(\mu|m_1) &= \mathrm{Beta}(\mu|\alpha=100,\beta=500) \\ +p(\mu|m_2) &= \mathrm{Beta}(\mu|\alpha=8,\beta=13). \\ +\end{aligned} +``` + +""" + +# ╔═╡ e47b6eb6-2bb3-4c2d-bda6-f1535f2f94c4 +priors = [ + Beta(100., 500.), + Beta(8., 13.) +]; + +# ╔═╡ e55126ef-e956-464d-8ae0-32b077649f21 +md""" +> #### We can already guess which one is better! +> +> You can verify that model ``m_2`` has the best prior, since +> +> ```math +> \begin{align*} +> p(x_n=1|m_1) &= \left.\frac{\alpha}{\alpha+\beta}\right|_{m_1} = 100/600 \approx 0.17 \\ +> p(x_n=1|m_2) &= \left.\frac{\alpha}{\alpha+\beta}\right|_{m_2} = 8/21 \approx 0.38 \,, +> \end{align*} +> ``` +> +> (but you are not supposed to know that the real coin has a probability ``0.4`` for heads.) +> + +""" + +# ╔═╡ f67136ff-f33c-436e-823b-9c530d257ab0 +md""" +### Simulation + +Let's run ``500`` tosses: +""" + +# ╔═╡ d1d2bb84-7083-435a-9c19-4c02074143e3 +n_tosses = 500; + +# ╔═╡ 9c751f8e-f7ed-464f-b63c-41e318bbff2d +samples = rand(secret_distribution, n_tosses) + +# ╔═╡ 6922b899-499e-4f73-a6be-ca427fdc14ea +md""" +### Bayesian Machine Learning + +Now, let's update our posteriors iteratively. For every toss, we do a **Bayesian update step** to compute the new posterior for the distribution of ``\mu``. This posterior then becomes the **prior** for the next step. +""" + +# ╔═╡ 6a2af90a-d294-11ef-07bd-018326577791 +md""" + +For each model, we plot the parameter **posteriors** ``p(\mu|D_n,m_\bullet)`` computed after ``n`` iterations. +""" + +# ╔═╡ d484c41d-9834-4528-bf47-93ab4e35ebaa +md""" +Select iteration: $(@bind toss_index_1 Slider(0:n_tosses; show_value=true)) +""" + +# ╔═╡ 5ea6cefa-621a-4afc-bf9e-02d42b1d53f8 + + +# ╔═╡ 6a2b2d44-d294-11ef-33ba-15db357708b1 +md""" + +#### What happens with model 1? + +Note that both posteriors move toward the "correct" value (``\mu=0.4``). However, the posterior for ``m_1`` (blue) moves much slower because we assumed far more pseudo-observations for ``m_1`` than for ``m_2``. + + +""" + +# ╔═╡ e9b32823-efd2-4a27-b529-4f49752c00bb +keyconcept( + "", + "As additional observations are acquired, the influence of the prior progressively diminishes, while the likelihood increasingly dominates the posterior." +) + +# ╔═╡ 56b9aba3-6ead-498c-8670-ad93a1953b2a + + +# ╔═╡ c28b7130-f7fb-41ee-852e-9964b091d7fb +md""" +### Implementation: Iterative Bayesian Updating + +""" + +# ╔═╡ e99e7650-bb72-4576-8f2a-c3994533b644 +function handle_coin_toss(prior::Beta, observation::Bool) + posterior = Beta(prior.α + observation, prior.β + (1 - observation)) + return posterior +end; + +# ╔═╡ 51829800-1781-49ae-8ee7-ac15c0bfcb88 +# computes log10 of Gamma function +function log10gamma(num::Real)::Real + num = convert(BigInt, num) + return log10(gamma(num)) +end + +# ╔═╡ 7a624d2f-812a-47a0-a609-9fe299de94f5 +function log_evidence_prior(prior::Beta, N::Int64, n::Int64)::Real + log10gamma(prior.α + prior.β) - + log10gamma(prior.α) - + log10gamma(prior.β) + + log10gamma(n+prior.α) + + log10gamma((N-n)+prior.β) - + log10gamma(N+prior.α+prior.β) +end + +# ╔═╡ 3a903a4d-1fb0-4566-8151-9c86dfc40ceb +begin + # save a sequence of posterior distributions for every prior, starting with the prior itself + prior_distributions = [d for d in priors] + posterior_distributions = [[d] for d in priors] + log_evidences = [[] for _ in priors] + + + # for every sample we want to update our posterior + for (N, sample) in enumerate(samples) + # at every sample we want to update all distributions + for (i, prior) in enumerate(prior_distributions) + + # do bayesian updating + posterior = handle_coin_toss(prior, sample) + + # add posterior to vector of posterior distributions + push!(posterior_distributions[i], posterior) + + # compute log evidence and add to vector + log_evidence = log_evidence_prior(posterior_distributions[i][N], N, sum(samples[1:N])) + push!(log_evidences[i], log_evidence) + + # the prior for the next sample is the posterior from the current sample + prior_distributions[i] = posterior + end + end +end; + +# ╔═╡ 6a2b1106-d294-11ef-0d64-dbc26ba3eb44 +# Animate posterior distributions over time in a gif + +let i = toss_index_1 + p = plot(title="n = $i$(i == 0 ? " (priors)" : "")") + for (j,post) in enumerate(posterior_distributions) + plot!(post[i+1], xlims = (0, 1), fill=(0, .2,), label="Posterior model $j", linewidth=2, ylims=(0,28), xlabel="μ", legend=:topright) + end + vline!([mean(secret_distribution)]; style=:dash, color="purple", label="True parameter") +end + +# ╔═╡ f956e217-3dce-446a-8660-25f2c9cb05e2 +md""" +We now have a sequence of **posterior distributions** and **log evidences** for each model. Notice that the first "posterior" in each sequence is the prior, and the last posterior is the posterior that takes all data into account. This is our updated model, using Bayesian reasoning. + +_Click on the vectors below to see their values._ +""" + +# ╔═╡ 2c90eee1-b5d9-434d-bccc-64de8b458a48 +posterior_distributions + +# ╔═╡ 9d82af33-8e91-48e9-8c34-fa6ea31492c2 +log_evidences + +# ╔═╡ 69eaf045-e766-4b7f-a9e8-8eac674ca2ae + + +# ╔═╡ 6a2b3ba4-d294-11ef-3c28-176be260cb15 +md""" + +### Evidence Visualised + +We have an intuition that ``m_2`` is superior over ``m_1``. Let's check this by plotting over time the relative Bayesian evidences for each model: + +```math +\frac{p(D_n|m_i)}{\sum_{i=1}^2 p(D_n|m_i)} +``` + +""" + +# ╔═╡ ebcfcd1b-7fc8-42b7-a35e-4530f798cfdf +md""" +Select iteration: $(@bind toss_index_2 Slider(1:n_tosses; show_value=true)) +""" + +# ╔═╡ 188b5bea-6765-4dcf-9369-3b1fdbe94494 +let i = toss_index_2 + evidences = map(model -> exp.(model), log_evidences) + + plot(title=string(L"\frac{p_i(\mathbf{x}_{1:n})}{\sum_i p_i(\mathbf{x}_{1:n})}"," n = ", i), ylims=(0, 1), legend=:topleft) + total = sum(e[i] for e in evidences) + bar!([(e[i] / total) for e in evidences], group=["Model $i" for i in eachindex(priors)]) +end + +# ╔═╡ ee4006aa-e54b-4501-93ee-60b34bdf5c7b +exercise_statement("Convergence to 0"; header_level=4) + +# ╔═╡ 6a2b9676-d294-11ef-241a-89ff7aa676f9 +md""" +Over time, the relative evidence of model ``m_1`` converges to ``0``. Can you explain this behavior? + +""" + +# ╔═╡ 9c5d7c89-f65c-4f52-9e49-14692bed2452 +md""" +# Maximum Likelihood Estimation +""" + +# ╔═╡ 6a2bb18a-d294-11ef-23bb-99082caf6e01 +md""" +## From Posterior to Point-Estimate + +In the example above, Bayesian parameter estimation and prediction were tractable in closed form. This is often not the case. In that case, we will need to approximate some of the computations. + +""" + +# ╔═╡ 6a2bd3ac-d294-11ef-0543-6fe202ca35b6 +md""" +Recall Bayesian prediction + +```math +p(x|D) = \int p(x|\theta)p(\theta|D)\,\mathrm{d}{\theta} +``` + +""" + +# ╔═╡ 6a2bf332-d294-11ef-1ff1-cdbfb7732cf1 +md""" +If we approximate the posterior by a delta function, i.e., ``p(\theta|D) = \delta(\theta-\hat\theta)`` for one "best" value ``\hat\theta``, then the predictive distribution collapses to + +```math +p(x|D)= \int p(x|\theta)\,\delta(\theta-\hat\theta)\,\mathrm{d}{\theta} = p(x|\hat\theta) +``` + +""" + +# ╔═╡ 6a2c008e-d294-11ef-2f07-11cdfb2bddca +md""" +This is just the data-generating distribution ``p(x|\theta)`` evaluated at ``\theta=\hat\theta``, which is easy to evaluate. + +""" + +# ╔═╡ 6a2c11e6-d294-11ef-173b-23fc6dbfefca +md""" +The next question is how to get the parameter estimate ``\hat{\theta}``? (See next slide). + +""" + +# ╔═╡ 6a2c229e-d294-11ef-2f24-ebe43cbfbfa4 +md""" +## Some Well-known Point-Estimates + +- **Bayes estimate** (the mean of the posterior) + +```math +\hat \theta_{\text{Bayes}} = \int \theta \, p\left( \theta |D \right) +\,\mathrm{d}{\theta} +``` + +""" + +# ╔═╡ 6a2c3036-d294-11ef-23cb-c3b36c475e8f +md""" +- **Maximum A Posteriori** (MAP) estimate + +```math +\hat \theta_{\text{map}}= \arg\max _{\theta} p\left( \theta |D \right) = +\arg \max_{\theta} p\left(D |\theta \right) \, p\left(\theta \right) +``` + +""" + +# ╔═╡ 6a2c4058-d294-11ef-2312-d9c672d49701 +md""" +- **Maximum Likelihood** (ML) estimate + +```math +\hat \theta_{ml} = \arg \max_{\theta} p\left(D |\theta\right) +``` + +Note that Maximum Likelihood (ML) is MAP with a uniform prior. MAP is sometimes called a 'penalized' ML procedure: + +```math +\hat \theta_{map} = \arg \max _\theta \{ \underbrace{\log +p\left( D|\theta \right)}_{\text{log-likelihood}} + \underbrace{\log +p\left( \theta \right)}_{\text{penalty}} \} +``` + +ML is the most common approximation to the full Bayesian posterior. + +""" + +# ╔═╡ 6a2c505c-d294-11ef-1c92-c1b0e9d50da5 +md""" +## Bayesian vs Maximum Likelihood Learning + +Consider the task: predict a future observation ``x`` from an observed data set ``D``. Let us compare full Bayesian modeling with the maximum likelihood approach. + +""" + +# ╔═╡ 7c8b1add-085a-41ba-9d6c-b26d3eef22e4 +md""" + +| | **Bayesian** | **Maximum Likelihood** | +|:----|:---------|:-----| +| 1. **Model Specification** | Choose a model ``m`` with data-generating distribution ``p(x\|\theta, m)`` and parameter prior ``p(\theta\|m)``. | Choose a model ``m`` with same data generating distribution ``p(x\|\theta, m)``. No need for priors. | +| 2. **Learning** | Use Bayes rule to find the parameter posterior: $(HTML("
"))``p(\theta\|D) \propto p(D\|\theta) p(\theta)`` | By Maximum Likelihood (ML) optimization: $(HTML("
")) ``\hat \theta = \arg \max_{\theta} p(D\|\theta)`` | +| 3. **Prediction** | ``p(x\|D) = \int p(x\|\theta) p(\theta\|D) \,\mathrm{d}\theta`` | ``p(x\|D) = p(x\|\hat\theta)`` | + + +""" + +# ╔═╡ 6a2c5e08-d294-11ef-213d-97bcfa16eb5a +md""" +## Report Card on Maximum Likelihood Estimation + + + +""" + +# ╔═╡ 6a2c7230-d294-11ef-05a2-3ff2f65d10e0 +md""" +(good!). ML works rather well if we have a lot of data because the influence of the prior diminishes with more data. + +""" + +# ╔═╡ 6a2c7f5a-d294-11ef-2e17-9108a39df280 +md""" +(good!). Computationally often do-able. Useful fact that makes the optimization easier (since ``\log`` is monotonously increasing): + +```math +\arg\max_\theta \log p(D|\theta) = \arg\max_\theta p(D|\theta) +``` + +""" + +# ╔═╡ 6a2c8f4a-d294-11ef-213c-dfa929a403bc +md""" +(bad). ML cannot be used for model comparison! In ML estimation, the Bayesian model evidence is undefined because no prior distribution is specified. Even if we attempt to simulate ML as a special case of Bayesian inference by using a uniform prior, the evidence still collapses: a uniform prior over the entire real line is not a proper probability distribution, since its integral does not evaluate to 1. Consequently, when performing ML estimation, Bayesian model evidence cannot be used to evaluate model performance: + +```math +\begin{align*} +\underbrace{p(D|m)}_{\substack{\text{Bayesian}\\ \text{evidence}}} &= \int p(D|\theta) \cdot p(\theta|m)\,\mathrm{d}\theta \\ + &= \lim_{(b-a)\rightarrow \infty} \int p(D|\theta)\cdot \underbrace{\text{Uniform}(\theta|a,b)}_{\text{"ML prior"}}\,\mathrm{d}\theta \\ + &= \lim_{(b-a)\rightarrow \infty} \frac{1}{b-a}\underbrace{\int_a^b p(D|\theta)\,\mathrm{d}\theta}_{<\infty} \\ + &= 0 +\end{align*} +``` + +In fact, this is a serious disadvantage because Bayesian evidence is a principled performance assessment criterion that follows from straightforward PT. In practice, when estimating parameters by maximum likelihood, we often evaluate model performance by an *ad hoc* performance measure such as mean-squared-error on a testing data set. + +""" + +# ╔═╡ 6a2ca496-d294-11ef-0043-1f350b36773e +keyconcept(" ", + md""" + Maximum likelihood estimation is, at best, an approximation to Bayesian learning. Still, it is a very popular method, and with good reason: when plenty of data are available, it often provides a practical and effective solution. + """ +) + + +# ╔═╡ 47842de0-d17e-460e-b3b7-b2e642569e25 +md""" +# Summary +""" + +# ╔═╡ b273c8bc-3819-4f63-801a-acf0ee78ef1d +keyconceptsummary() + +# ╔═╡ 4bfd141f-fe2f-46a0-aa35-872cab45ea00 +exercises(header_level=1) + +# ╔═╡ f2969d91-4a5b-4665-9fa5-521db750302f +md""" + +##### Bayes estimate (**) + +(##) The Bayes estimate is a summary of a posterior distribution by a delta distribution on its mean, i.e., + +```math +\hat \theta_{bayes} = \int \theta \, p\left( \theta |D \right) +\,\mathrm{d}{\theta} +``` + +Prove that the Bayes estimate minimizes the mean-squared error, i.e., Prove that + +```math +\hat \theta_{bayes} = \arg\min_{\hat \theta} \int_\theta (\hat \theta -\theta)^2 p \left( \theta |D \right) \,\mathrm{d}{\theta} +``` +""" + +# ╔═╡ 7dd9a456-9dca-47c8-98c5-51f87f28e6a4 +hide_solution( +md""" +To minimize the expected mean-squared error we will look for ``\hat{\theta}`` that makes the gradient of the integral with respect to ``\hat{\theta}`` vanish. + +```math +\begin{align*} + \nabla_{\hat{\theta}} \int_\theta (\hat \theta -\theta)^2 p \left( \theta |D \right) \,\mathrm{d}{\theta} &= 0 \\ + \int_\theta \nabla_{\hat{\theta}} (\hat \theta -\theta)^2 p \left( \theta |D \right) \,\mathrm{d}{\theta} &= 0 \\ + \int_\theta 2(\hat \theta -\theta) p \left( \theta |D \right) \,\mathrm{d}{\theta} &= 0 \\ + \int_\theta \hat \theta p \left( \theta |D \right) \,\mathrm{d}{\theta} &= \int_\theta \theta p \left( \theta |D \right) \,\mathrm{d}{\theta} \\ + \hat \theta \underbrace{\int_\theta p \left( \theta |D \right) \,\mathrm{d}{\theta}}_{1} &= \int_\theta \theta p \left( \theta |D \right) \,\mathrm{d}{\theta} \\ + \Rightarrow \hat \theta &= \int_\theta \theta p \left( \theta |D \right) \,\mathrm{d}{\theta} +\end{align*} +``` +""" +) + +# ╔═╡ b2820dfd-b3ca-477b-8cb7-c430e0fe18dd +md""" + +##### Coin Toss MAP and ML (**) + +Consider the coin toss example with model +```math +\begin{align} +p(x_k|\mu) &= \mu^{x_k} (1-\mu)^{1-x_k} \\ +p(\mu) &= \mathrm{Beta}(\mu|\alpha,\beta) \,. +\end{align} +``` +and a given data set ``D=\{x_1, x_2,\ldots,x_N\}``. + +- (a) Derive the Maximum Likelihood estimate for ``\mu``. +- (b) Derive the MAP estimate for ``\mu``. +- (c) Do these two estimates ever coincide (if so, under what circumstances)? + + +""" + +# ╔═╡ 664d4183-edb6-4818-a44b-bf4c0a22a33c +hide_solution( +md""" +- (a) The likelihood is given by ``p(D|\mu) = \mu^n\cdot (1-\mu)^{(N-n)}``. It follows that + + +```math +\begin{align*} + \nabla \log p(D|\mu) &= 0 \\ + \nabla \left( n\log \mu + (N-n)\log(1-\mu)\right) &= 0\\ + \frac{n}{\mu} - \frac{N-n}{1-\mu} &= 0 \\ + \rightarrow \hat{\mu}_{\text{ML}} &= \frac{n}{N} + \end{align*} +``` + +- (b) We can write the posterior as as + + +```math +\begin{align*} + p(\mu|D) &\propto p(D|\mu)p(\mu) \\ + &\propto \mu^n (1-\mu)^{N-n} \mu^{\alpha-1} (1-\mu)^{\beta-1} \\ + &\propto \mathcal{B}(\mu|n+\alpha,N-n+\beta) + \end{align*} +``` + +The MAP estimate for a beta distribution ``\mathcal{B}(a,b)`` is located at ``\frac{a - 1}{a+b-2}``, see [wikipedia](https://en.wikipedia.org/wiki/Beta_distribution). Hence, + + +```math +\begin{align*} +\hat{\mu}_{\text{MAP}} &= \frac{(n+\alpha)-1}{(n+\alpha) + (N-n+\beta) -2} \\ + &= \frac{n+\alpha-1}{N + \alpha +\beta -2} +\end{align*} +``` + +- (c) As ``N`` gets larger, the MAP estimate approaches the ML estimate. In the limit the MAP solution converges to the ML solution. + + +""" +) + +# ╔═╡ ecb036da-a0a2-4919-b1aa-bc33b6ba7e73 +md""" + +##### Model Comparison (**) + +A model ``m_1`` is described by a single parameter ``\theta``, with ``0 \leq \theta \leq 1``. The system can produce data ``x \in \{0,1\}``. The sampling distribution and prior are given by + +```math +\begin{align*} +p(x|\theta,m_1) &= \theta^x (1-\theta)^{(1-x)} \\ +p(\theta|m_1) &= 6\theta(1-\theta) +\end{align*} +``` + +- (a) Work out the probability ``p(x=1|m_1)``. + +- (b) Determine the posterior ``p(\theta|x=1,m_1)``. + +Now consider a second model ``m_2`` with the following sampling distribution and prior on ``0 \leq \theta \leq 1``: + +```math +\begin{align*} +p(x|\theta,m_2) &= (1-\theta)^x \theta^{(1-x)} \\ +p(\theta|m_2) &= 2\theta +\end{align*} +``` + +- (c) Determine the probability ``p(x=1|m_2)``. + +Now assume that the model priors are given by + +```math +\begin{align*} + p(m_1) &= 1/3 \\ + p(m_2) &= 2/3 + \end{align*} +``` + +- (d) Compute the probability ``p(x=1)`` by "Bayesian model averaging", i.e., by weighing the predictions of both models appropriately. + + +- (e) Compute the fraction of posterior model probabilities ``\frac{p(m_1|x=1)}{p(m_2|x=1)}``. + + +- (f) Which model do you prefer after observation ``x=1``? + + +""" + +# ╔═╡ de08c2a1-c5e3-4add-8b22-2c633247da48 +hide_solution( +md""" +- (a) Work out the probability ``p(x=1|m_1)``. + +```math +\begin{align*} + p(x=1|m_1) &= \int_0^1 p(x=1|\theta,m_1) p(\theta|m_1) \mathrm{d}\theta \\ + &= \int \theta \cdot 6\theta (1-\theta) \mathrm{d}\theta \\ + &= 6 \cdot \left(\frac{1}{3}\theta^3 - \frac{1}{4}\theta^4\right) \bigg|_0^1 \\ + &= 6 \cdot (\frac{1}{3} - \frac{1}{4}) = \frac{1}{2} +\end{align*} +``` + +- (b) Determine the posterior ``p(\theta|x=1,m_1)``. + +```math +\begin{align*} + p(\theta|x=1,m_1) &= \frac{p(x=1|\theta) p(\theta|m_1)}{p(x=1|m_1)} \\ + &= 2\cdot \theta \cdot 6\theta (1-\theta) \\ + &= \begin{cases} 12 \theta^2 (1-\theta) & \text{if }0 \leq \theta \leq 1 \\ + 0 & \text{otherwise} \end{cases} + \end{align*} +``` + +Now consider a second model ``m_2`` with the following sampling distribution and prior on ``0 \leq \theta \leq 1``: + +```math +\begin{align*} +p(x|\theta,m_2) &= (1-\theta)^x \theta^{(1-x)} \\ +p(\theta|m_2) &= 2\theta +\end{align*} +``` + +- (c) Determine the probability ``p(x=1|m_2)``. + +```math +\begin{align*} + p(x=1|m_2) &= \int_0^1 p(x=1|\theta,m_2) p(\theta|m_2) \mathrm{d}\theta \\ + &= \int (1-\theta) \cdot 2\theta \mathrm{d}\theta \\ + &= 2 \cdot \left( \frac{1}{2}\theta^2 - \frac{1}{3}\theta^3 \right) \bigg|_0^1 \\ + &= 2 \cdot (\frac{1}{2} - \frac{1}{3}) = \frac{1}{3} + \end{align*} +``` + +Now assume that the model priors are given by + +```math +\begin{align*} + p(m_1) &= 1/3 \\ + p(m_2) &= 2/3 + \end{align*} +``` + +- (d) Compute the probability ``p(x=1)`` by "Bayesian model averaging", i.e., by weighing the predictions of both models appropriately. + +```math +\begin{align*} + p(x=1) &= \sum_{k=1}^2 p(x=1|m_k) p(m_k) \\ + &= \frac{1}{2} \cdot \frac{1}{3} + \frac{1}{3} \cdot \frac{2}{3} = \frac{7}{18} + \end{align*} +``` + +- (e) Compute the fraction of posterior model probabilities ``\frac{p(m_1|x=1)}{p(m_2|x=1)}``. + +```math +\frac{p(m_1|x=1)}{p(m_2|x=1)} = \frac{p(x=1|m_1) p(m_1)}{p(x=1|m_2) p(m_2)} = \frac{\frac{1}{2} \cdot \frac{1}{3}}{\frac{1}{3} \cdot \frac{2}{3}} =\frac{3}{4} +``` + +- (f) Which model do you prefer after observation ``x=1``? + +In principle, the observation ``x=1`` favors model ``m_2``, since ``p(m_2|x=1) = \frac{4}{3} \times p(m_1|x=1)``. However, note that ``\log_{10} \frac{3}{4} \approx -0.125``, so the extra evidence for ``m_2`` relative to ``m_1`` is very low. At this point, after 1 observation, we have no preference for a model yet. + +""") + +# ╔═╡ 6a2cb25e-d294-11ef-1d88-1fc784b33df0 +md""" +# Optional Slides + +""" + +# ╔═╡ 1edae118-dcc7-4169-95cf-f36025f2c336 +md""" +## Working with Distributions in code + +Take a look at this mini lecture to see some simple examples of using distributions in Julia: +""" + +# ╔═╡ 275a9a69-3135-4cbd-8a35-b1abee4af83f +NotebookCard("https://bmlip.github.io/course/minis/Distributions%20in%20Julia.html") + +# ╔═╡ 6a2ccd16-d294-11ef-22ee-a5cff62ccd9c +md""" +## The Kullback-Leibler Divergence$(HTML("")) + +""" + +# ╔═╡ f5d8d021-3157-464f-93a2-b3054779e55f +NotebookCard("https://bmlip.github.io/course/minis/KL%20Divergence.html") + +# ╔═╡ 1f92c406-6792-4af6-9132-35efd8223bc5 +md""" +# Code +""" + +# ╔═╡ 7a764a14-a5df-4f76-8836-f0a571fc3519 +wideq(x) = PlutoUI.ExperimentalLayout.Div([x]; style="min-width: max-content;") |> WideCell + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +MarkdownLiteral = "736d6165-7244-6769-4267-6b50796e6954" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" +StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd" + +[compat] +BmlipTeachingTools = "~1.3.1" +Distributions = "~0.25.122" +LaTeXStrings = "~1.4.0" +MarkdownLiteral = "~0.1.2" +Plots = "~1.40.17" +SpecialFunctions = "~2.6.1" +StatsPlots = "~0.15.8" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "cbe308c57a080037e364873ac63012af4000489b" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.4.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Arpack]] +deps = ["Arpack_jll", "Libdl", "LinearAlgebra", "Logging"] +git-tree-sha1 = "9b9b347613394885fd1c8c7729bfc60528faa436" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.5.4" + +[[deps.Arpack_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "OpenBLAS_jll", "Pkg"] +git-tree-sha1 = "5ba6c757e8feccf03a1554dfaf3e26b3cfc7fd5e" +uuid = "68821587-b530-5797-8361-c406ea357684" +version = "3.5.1+1" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "e4c6a16e77171a5f5e25e9646617ab1c276c5607" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.26.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.Clustering]] +deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "Random", "SparseArrays", "Statistics", "StatsBase"] +git-tree-sha1 = "3e22db924e2945282e70c33b75d4dde8bfa44c94" +uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5" +version = "0.15.8" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.CommonMark]] +deps = ["PrecompileTools"] +git-tree-sha1 = "351d6f4eaf273b753001b2de4dffb8279b100769" +uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" +version = "0.9.1" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.12" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "97f08406df914023af55ade2f843c39e99c5d969" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.10.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.11+0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2025.2.0+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "65d505fa4c0d7072990d659ef3fc086eb6da8208" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.16.2" + + [deps.Interpolations.extensions] + InterpolationsForwardDiffExt = "ForwardDiff" + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "ba51324b894edaf1df3ab16e2cc6bc3280a2f1a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.10" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +version = "1.11.0" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "282cadc186e7b2ae0eeadbd7a4dffed4196ae2aa" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2025.2.0+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MarkdownLiteral]] +deps = ["CommonMark", "HypertextLiteral"] +git-tree-sha1 = "f7d73634acd573bf3489df1ee0d270a5d6d3a7a3" +uuid = "736d6165-7244-6769-4267-6b50796e6954" +version = "0.1.2" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.MultivariateStats]] +deps = ["Arpack", "Distributions", "LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI", "StatsBase"] +git-tree-sha1 = "816620e3aac93e5b5359e4fdaf23ca4525b00ddf" +uuid = "6f286f6a-111f-5878-ab1e-185364afe411" +version = "0.10.3" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "ca7e18198a166a1f3eb92a3650d53d94ed8ca8a1" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.22" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.OffsetArrays]] +git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.17.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.8" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.15" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StatsPlots]] +deps = ["AbstractFFTs", "Clustering", "DataStructures", "Distributions", "Interpolations", "KernelDensity", "LinearAlgebra", "MultivariateStats", "NaNMath", "Observables", "Plots", "RecipesBase", "RecipesPipeline", "Reexport", "StatsBase", "TableOperations", "Tables", "Widgets"] +git-tree-sha1 = "88cf3587711d9ad0a55722d339a013c4c56c5bbc" +uuid = "f3b207a7-027a-5e70-b257-86293d7955fd" +version = "0.15.8" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableOperations]] +deps = ["SentinelArrays", "Tables", "Test"] +git-tree-sha1 = "e383c87cf2a1dc41fa30c093b2a19877c83e1bc1" +uuid = "ab02a1b2-a7df-11e8-156e-fb1833f50b87" +version = "1.2.0" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.12.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.Widgets]] +deps = ["Colors", "Dates", "Observables", "OrderedCollections"] +git-tree-sha1 = "e9aeb174f95385de31e70bd15fa066a505ea82b9" +uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" +version = "0.6.7" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─6a23b828-d294-11ef-371a-05d061144a43 +# ╟─6be2e966-4048-44d0-a37e-95060e3fe30b +# ╟─6a23df9e-d294-11ef-3ddf-a51d4cea00fc +# ╟─eca027f8-40c9-4e53-85b5-d08b8fe9dd97 +# ╟─4f6a2d4f-bd89-4b0c-b544-397de2e34e72 +# ╟─b791e819-f5a0-4c44-983b-07d8497516fb +# ╟─daa1df0e-4ec5-4fb1-a355-a42c35bd35b9 +# ╟─6a24b9e4-d294-11ef-3ead-9d272fbf89be +# ╟─6a24c3e6-d294-11ef-3581-2755a9ba15ba +# ╟─e2de9415-7bd8-4e95-abeb-53fc068ee950 +# ╟─6a24c9f4-d294-11ef-20cc-172ea50da901 +# ╟─6a24cee0-d294-11ef-35cb-71ab9ef935e5 +# ╟─6a24d478-d294-11ef-2a75-9d03a5ba7ff8 +# ╟─6a24fde8-d294-11ef-29bf-ad3e20a53c29 +# ╟─a75c75ed-c67b-4be2-adbf-8984f27fc05d +# ╟─6a251a08-d294-11ef-171a-27b9d0f818bc +# ╟─6a252250-d294-11ef-33cd-89b18066817d +# ╟─6a25307e-d294-11ef-0662-3db678b32e99 +# ╟─6a25379a-d294-11ef-3e07-87819f6d75cb +# ╟─6a254460-d294-11ef-1890-230b75b6b9ee +# ╟─6a2552ac-d294-11ef-08d6-179e068bc297 +# ╟─ce75e785-868f-4361-93f8-c582ac1b891b +# ╟─6a2561c0-d294-11ef-124d-373846e3120c +# ╟─6a257020-d294-11ef-0490-e151934b2f42 +# ╟─6a257f34-d294-11ef-2928-fbb800e81124 +# ╟─6a25a11e-d294-11ef-1c51-09482dad86f2 +# ╟─6a25edfc-d294-11ef-3411-6f74c376461e +# ╟─53de7edd-6c28-49a7-9f54-cf7b8ca42aeb +# ╟─288fbee6-0783-4447-b5d0-f5c2b29b39c7 +# ╟─74fa1925-0d9f-47f6-a6bd-b822948a4fbc +# ╟─6a261278-d294-11ef-25a0-5572de58ad06 +# ╟─6a26549a-d294-11ef-1f10-15c4d14ae41f +# ╟─6a262182-d294-11ef-23e9-ed45e1da9f46 +# ╟─6a2672d6-d294-11ef-1886-3195c9c7cfa9 +# ╟─6aa2399d-a949-40f9-8ee6-b0c2be1dc478 +# ╟─6a2664c6-d294-11ef-0a49-5192e17fb9ea +# ╟─6a26a31e-d294-11ef-2c2f-b349d0859a27 +# ╟─6a269568-d294-11ef-02e3-13402d296391 +# ╟─6a26b7bc-d294-11ef-03e7-2715b6f8dcc7 +# ╟─6a26f244-d294-11ef-0488-c1e4ec6e739d +# ╟─99db44c9-185c-4f39-ae5e-1a4cd751d980 +# ╟─d22f58ac-9f68-41cb-8e61-cf74d3692c44 +# ╟─6a2707e6-d294-11ef-02ad-31bf84662c70 +# ╟─6a271a56-d294-11ef-0046-add807cc0b4f +# ╟─f6ee5570-9b92-42b6-baf3-3eed5352a060 +# ╟─6a273ae0-d294-11ef-2c00-9b3eaed93f6d +# ╟─6a274948-d294-11ef-0563-1796b8883306 +# ╟─6a275a52-d294-11ef-1323-9d83972f611a +# ╟─6a27684e-d294-11ef-040e-c302cdad714a +# ╟─6a2777d0-d294-11ef-1ac3-add102c097d6 +# ╟─6a278784-d294-11ef-11ae-65bd398910d5 +# ╟─c03229ef-3e0f-4612-909b-97f488a1e4c9 +# ╟─6a27951c-d294-11ef-2e1a-b5a4ce84aceb +# ╟─6a27a28a-d294-11ef-1f33-41b444761429 +# ╟─55dec435-aa78-41ba-aad5-9d79ce292f42 +# ╟─6a27b114-d294-11ef-099d-1d55968934a6 +# ╟─6a27beca-d294-11ef-1895-d57b11b827c1 +# ╟─cc8af69e-6d00-4327-aaa2-0b1023052b8a +# ╟─c454be00-05e7-42f6-a243-bf559ed6eff7 +# ╟─6a9ad1c4-dfb2-4987-9ddc-da6131605083 +# ╟─6a27efc6-d294-11ef-2dc2-3b2ef95e72f5 +# ╟─6a280132-d294-11ef-10ac-f3890cb3f78b +# ╟─6a2814b0-d294-11ef-3a76-9b93c1fcd4d5 +# ╟─6a282892-d294-11ef-2c12-4b1c7374617c +# ╟─6a286b04-d294-11ef-1b34-8b7a85c0048c +# ╟─6a2879e6-d294-11ef-37db-df7babe24d25 +# ╟─6a2889ae-d294-11ef-2439-e1a541a5ccd7 +# ╟─c050f468-7eec-403f-9304-552bd0d9b222 +# ╟─1dbc69a3-b3ec-44de-af7c-944ebc01f523 +# ╟─6a2898ea-d294-11ef-39ec-31e4bac1e048 +# ╟─6a28a704-d294-11ef-1bf2-efbdb0cb4cbc +# ╟─6a28b44c-d294-11ef-15da-81be8753d311 +# ╟─6a28c9b4-d294-11ef-222b-97bf0912efe7 +# ╟─6a28d81e-d294-11ef-2a9f-d32daa5556ae +# ╟─6a28e674-d294-11ef-391b-0d33fd609fb8 +# ╟─6a28f466-d294-11ef-3af9-e34de9736c71 +# ╟─51bed1cc-c960-46fe-bc09-2b684df3b0cc +# ╟─513414c7-0a54-4767-a583-7d779f8fbc55 +# ╟─ee3da94c-5e87-4a0b-8373-c01e339d28aa +# ╟─261620b0-9580-4d9e-b7de-d7972ea549cd +# ╟─6a294790-d294-11ef-270b-5b2152431426 +# ╟─b872cd69-d534-4b04-bb76-d85bb7ef0ea9 +# ╟─1ba1939d-9986-4b97-9273-4f2434f1d385 +# ╟─b426df32-5629-4773-b862-101cfbd82d42 +# ╟─181ade96-8e1e-4186-9227-c1561352529d +# ╟─6a29d548-d294-11ef-1361-ad2230cad02b +# ╟─6a29e25e-d294-11ef-15ce-5bf3d8cdb64c +# ╟─6a29f1c2-d294-11ef-147f-877f99e5b57c +# ╟─6a2a000e-d294-11ef-17d6-bdcddeedc65d +# ╟─6a2a0f18-d294-11ef-02c2-ef117377ca66 +# ╟─6a2a1daa-d294-11ef-2a67-9f2ac60a14c5 +# ╟─6a2a2af2-d294-11ef-0072-bdc3c6f95bb3 +# ╟─6a2a389e-d294-11ef-1b8c-b55de794b65c +# ╟─6a2a465e-d294-11ef-2aa0-43c954a6439e +# ╟─48fd2dff-796d-48bc-b5a8-bee270d119fd +# ╟─e3f9e571-2248-403c-8ab8-f6b99597f595 +# ╟─90f691ad-046c-4595-99b0-19a1d6cb599e +# ╟─6a2a9faa-d294-11ef-1284-cfccb1da444e +# ╟─6a2aad42-d294-11ef-3129-3be5be8c82d6 +# ╟─6a2abb16-d294-11ef-0243-d376e8a39bb0 +# ╟─54cb380d-8864-4158-ba68-55027ae68971 +# ╠═9da43d0f-e605-41b7-9bc6-db5be95bc87f +# ╟─280e0819-674e-4a58-854d-5a66e0777074 +# ╠═e47b6eb6-2bb3-4c2d-bda6-f1535f2f94c4 +# ╟─e55126ef-e956-464d-8ae0-32b077649f21 +# ╟─f67136ff-f33c-436e-823b-9c530d257ab0 +# ╠═9c751f8e-f7ed-464f-b63c-41e318bbff2d +# ╟─d1d2bb84-7083-435a-9c19-4c02074143e3 +# ╟─6922b899-499e-4f73-a6be-ca427fdc14ea +# ╟─6a2af90a-d294-11ef-07bd-018326577791 +# ╟─6a2b1106-d294-11ef-0d64-dbc26ba3eb44 +# ╟─d484c41d-9834-4528-bf47-93ab4e35ebaa +# ╟─5ea6cefa-621a-4afc-bf9e-02d42b1d53f8 +# ╟─6a2b2d44-d294-11ef-33ba-15db357708b1 +# ╟─e9b32823-efd2-4a27-b529-4f49752c00bb +# ╟─56b9aba3-6ead-498c-8670-ad93a1953b2a +# ╟─c28b7130-f7fb-41ee-852e-9964b091d7fb +# ╠═3a903a4d-1fb0-4566-8151-9c86dfc40ceb +# ╠═e99e7650-bb72-4576-8f2a-c3994533b644 +# ╟─7a624d2f-812a-47a0-a609-9fe299de94f5 +# ╟─51829800-1781-49ae-8ee7-ac15c0bfcb88 +# ╟─f956e217-3dce-446a-8660-25f2c9cb05e2 +# ╠═2c90eee1-b5d9-434d-bccc-64de8b458a48 +# ╠═9d82af33-8e91-48e9-8c34-fa6ea31492c2 +# ╟─69eaf045-e766-4b7f-a9e8-8eac674ca2ae +# ╟─6a2b3ba4-d294-11ef-3c28-176be260cb15 +# ╟─188b5bea-6765-4dcf-9369-3b1fdbe94494 +# ╟─ebcfcd1b-7fc8-42b7-a35e-4530f798cfdf +# ╟─ee4006aa-e54b-4501-93ee-60b34bdf5c7b +# ╟─6a2b9676-d294-11ef-241a-89ff7aa676f9 +# ╟─9c5d7c89-f65c-4f52-9e49-14692bed2452 +# ╟─6a2bb18a-d294-11ef-23bb-99082caf6e01 +# ╟─6a2bd3ac-d294-11ef-0543-6fe202ca35b6 +# ╟─6a2bf332-d294-11ef-1ff1-cdbfb7732cf1 +# ╟─6a2c008e-d294-11ef-2f07-11cdfb2bddca +# ╟─6a2c11e6-d294-11ef-173b-23fc6dbfefca +# ╟─6a2c229e-d294-11ef-2f24-ebe43cbfbfa4 +# ╟─6a2c3036-d294-11ef-23cb-c3b36c475e8f +# ╟─6a2c4058-d294-11ef-2312-d9c672d49701 +# ╟─6a2c505c-d294-11ef-1c92-c1b0e9d50da5 +# ╟─7c8b1add-085a-41ba-9d6c-b26d3eef22e4 +# ╟─6a2c5e08-d294-11ef-213d-97bcfa16eb5a +# ╟─6a2c7230-d294-11ef-05a2-3ff2f65d10e0 +# ╟─6a2c7f5a-d294-11ef-2e17-9108a39df280 +# ╟─6a2c8f4a-d294-11ef-213c-dfa929a403bc +# ╟─6a2ca496-d294-11ef-0043-1f350b36773e +# ╟─47842de0-d17e-460e-b3b7-b2e642569e25 +# ╟─b273c8bc-3819-4f63-801a-acf0ee78ef1d +# ╟─4bfd141f-fe2f-46a0-aa35-872cab45ea00 +# ╟─f2969d91-4a5b-4665-9fa5-521db750302f +# ╟─7dd9a456-9dca-47c8-98c5-51f87f28e6a4 +# ╟─b2820dfd-b3ca-477b-8cb7-c430e0fe18dd +# ╟─664d4183-edb6-4818-a44b-bf4c0a22a33c +# ╟─ecb036da-a0a2-4919-b1aa-bc33b6ba7e73 +# ╟─de08c2a1-c5e3-4add-8b22-2c633247da48 +# ╟─6a2cb25e-d294-11ef-1d88-1fc784b33df0 +# ╟─1edae118-dcc7-4169-95cf-f36025f2c336 +# ╟─275a9a69-3135-4cbd-8a35-b1abee4af83f +# ╟─6a2ccd16-d294-11ef-22ee-a5cff62ccd9c +# ╟─f5d8d021-3157-464f-93a2-b3054779e55f +# ╟─1f92c406-6792-4af6-9132-35efd8223bc5 +# ╠═b32d2d36-f3a5-406f-adf6-c7b8ebe6cc77 +# ╠═17182feb-2c58-4485-aadc-114003376607 +# ╠═df312e6a-503f-486f-b7ec-15404070960c +# ╠═caba8eee-dfea-45bc-a8a7-1dd20a1fa994 +# ╠═3987d441-b9c8-4bb1-8b2d-0cc78d78819e +# ╟─7a764a14-a5df-4f76-8836-f0a571fc3519 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/Factor Graphs.jl b/mlss/Factor Graphs.jl new file mode 100644 index 00000000..f2eca43e --- /dev/null +++ b/mlss/Factor Graphs.jl @@ -0,0 +1,3273 @@ +### A Pluto.jl notebook ### +# v0.20.19 + +#> [frontmatter] +#> image = "https://github.com/bmlip/course/blob/v2/assets/figures/ffg-example-1.png?raw=true" +#> description = "Introduction to Forney-style factor graphs and message passing-based inference." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ 5a8dcadb-f0c2-4fb0-b8cd-db8cf49cc292 +using BmlipTeachingTools + +# ╔═╡ 965a08f4-d294-11ef-0604-1586ff37c0d4 +using Plots, LinearAlgebra, LaTeXStrings + +# ╔═╡ 2cb7d369-e7fd-4d66-8321-66a9197a26bd +using RxInfer, Random + +# ╔═╡ 387f55ba-0fa4-4171-a405-3b1fb4e6b586 +using StableRNGs + +# ╔═╡ 96547560-d294-11ef-0fa7-6b6489f7baba +title("Factor Graphs") + +# ╔═╡ af24aa27-b0a1-4c9b-aee0-0e5143d2f47e +PlutoUI.TableOfContents() + +# ╔═╡ 9654ea3e-d294-11ef-335c-657af1ceaf19 +md""" +## Preliminaries + +##### Goal + + * Introduction to Forney-style factor graphs and message passing-based inference + +##### Materials + + * Mandatory + + * These lecture notes + * Loeliger (2007), [The factor graph approach to model based signal processing](https://github.com/bmlip/course/blob/main/assets/files/Loeliger-2007-The-factor-graph-approach-to-model-based-signal-processing.pdf), pp. 1295-1302 (until section V) + * Optional + + * Frederico Wadehn (2015), [Probabilistic graphical models: Factor graphs and more](https://www.youtube.com/watch?v=Fv2YbVg9Frc&t=31) video lecture (**recommended**) + * References + + * Forney (2001), [Codes on graphs: normal realizations](https://github.com/bmlip/course/blob/main/assets/files/Forney-2001-Codes-on-graphs-normal-realizations.pdf) + +""" + +# ╔═╡ 96552348-d294-11ef-16d8-b53563054687 +md""" +## Why Factor Graphs? + + +A probabilistic inference task derives most of its computational complexity from the need to perform marginalization, i.e., integrating (or summing) over latent or nuisance variables. + +For example, for a model ``p(x_1,x_2,x_3,x_4,x_5)``, the inference task ``p(x_2|x_3)`` involves computing + +```math +p(x_2|x_3) = \frac{p(x_2,x_3)}{p(x_3)} = \frac{\int \cdots \int p(x_1,x_2,x_3,x_4,x_5) \, \mathrm{d}x_1 \mathrm{d}x_4 \mathrm{d}x_5}{\int \cdots \int p(x_1,x_2,x_3,x_4,x_5) \, \mathrm{d}x_1 \mathrm{d}x_2 \mathrm{d}x_4 \mathrm{d}x_5} +``` + +Because marginalization operations (sums or integrals) scale poorly with the number of variables, a phenomenon known as the [curse of dimensionality](https://en.wikipedia.org/wiki/Curse_of_dimensionality), we must often leverage the model’s conditional independence structure to reduce computational complexity and obtain feasible inference procedures. + +Factor graphs provide a computationally efficient approach to solving inference problems **if the probabilistic model can be factorized**. + +""" + + +# ╔═╡ 9655959e-d294-11ef-0ca6-5f20aa579e91 +md""" + $(HTML("Factorization helps.")) For instance, if ``p(x_1,x_2,x_3,x_4,x_5) = p(x_1)p(x_2,x_3)p(x_4)p(x_5|x_4)``, then + +```math +\begin{align} +p(x_2|x_3) &= \frac{\int \cdots \int p(x_1)p(x_2,x_3)p(x_4)p(x_5|x_4) \, \mathrm{d}x_1 \mathrm{d}x_4 \mathrm{d}x_5}{\int \cdots \int p(x_1)p(x_2,x_3)p(x_4)p(x_5|x_4) \, \mathrm{d}x_1 \mathrm{d}x_2 \mathrm{d}x_4 \mathrm{d}x_5} \\ + &= \frac{p(x_2,x_3)}{\int p(x_2,x_3) \mathrm{d}x_2} +\end{align} +``` + +which is computationally much cheaper than the general case above. + +In this lesson, we discuss how computationally efficient inference in *factorized* probability distributions can be automated by message passing-based inference in factor graphs. + +""" + +# ╔═╡ 05db1eab-5b63-4ab9-8b4a-ab2cde554295 +md""" +# Forney-style Factor Graphs +""" + +# ╔═╡ 9655b2c2-d294-11ef-057f-9b3984064411 +md""" +## Factor Graph Construction Rules + +""" + +# ╔═╡ 403845d6-0229-4c93-bc23-3aecfd76e874 +TwoColumn( +md""" +Consider a function +```math + \begin{align} +f(x_1,&x_2,x_3,x_4,x_5) \\ + &= f_a(x_1,x_2,x_3) \cdot f_b(x_3,x_4,x_5) \cdot f_c(x_4)\,. + \end{align} +``` +The factorization of this function can be graphically represented by a **Forney-style Factor Graph** (FFG), see image on the right. +""", + +md""" +![](https://github.com/bmlip/course/blob/v2/assets/figures/ffg-example-1.png?raw=true) +""") + +# ╔═╡ 9655d360-d294-11ef-0f06-ab58e2ad0e5f +md""" +An FFG is an **undirected** graph subject to the following construction rules ([Forney, 2001](https://github.com/bmlip/course/blob/main/assets/files/Forney-2001-Codes-on-graphs-normal-realizations.pdf)) + +1. A **node** for every factor; +2. An **edge** (or **half-edge**) for every variable; +3. Node ``f_\bullet`` is connected to edge ``x`` **iff** variable ``x`` appears in factor ``f_\bullet``. + +""" + +# ╔═╡ 9655e06c-d294-11ef-0393-9355d6e20afb +md""" +A **configuration** is an assignment of values to all variables. A configuration ``\omega=(x_1,x_2,x_3,x_4,x_5)`` is said to be **valid** iff ``f(\omega) \neq 0`` + +""" + +# ╔═╡ 9655ed6e-d294-11ef-370f-937b590036f3 +md""" +## Equality Nodes for Branching Points + +Note that a variable can appear in maximally two factors in an FFG (since an edge has only two end points). + +""" + +# ╔═╡ 9655fb88-d294-11ef-1ceb-91585012d142 +md""" +Consider the factorization (where ``x_2`` appears in three factors) + +```math + f(x_1,x_2,x_3,x_4) = f_a(x_1,x_2)\cdot f_b(x_2,x_3) \cdot f_c(x_2,x_4) +``` + +""" + +# ╔═╡ 965606f2-d294-11ef-305b-870427879e50 +md""" +For the factor graph representation, we will instead consider the function ``g``, defined as + +```math +\begin{align*} + g(x_1,x_2&,x_2^\prime,x_2^{\prime\prime},x_3,x_4) + = f_a(x_1,x_2)\cdot f_b(x_2^\prime,x_3) \cdot f_c(x_2^{\prime\prime},x_4) \cdot f_=(x_2,x_2^\prime,x_2^{\prime\prime})\,, +\end{align*} +``` + + +""" + +# ╔═╡ 2d5cd42e-26ea-4ee4-979f-3a4e2c6271b6 +TwoColumn( +md""" +where +```math +f_=(x_2,x_2^\prime,x_2^{\prime\prime}) \triangleq \delta(x_2-x_2^\prime)\, \delta(x_2-x_2^{\prime\prime}) +``` +is a so-called **equality** (or branching) node. +""", +md""" +![](https://github.com/bmlip/course/blob/v2/assets/figures/ffg-wEquality-node.png?raw=true) +""") + +# ╔═╡ 96561594-d294-11ef-1590-198382927808 +md""" +Note that through introduction of auxiliary variables ``x_2^{\prime}`` and ``x_2^{\prime\prime}`` and a factor ``f_=(x_2,x_2^\prime,x_2^{\prime\prime})``, each variable in ``g`` appears in maximally two factors. + +The constraint ``f_=(x,x^\prime,x^{\prime\prime})`` enforces that ``x=x^\prime=x^{\prime\prime}`` **for every valid configuration**. + +Since ``f`` is a marginal of ``g``, i.e., + +```math +f(x_1,x_2,x_3,x_4) = \iint g(x_1,x_2,x_2^\prime,x_2^{\prime\prime},x_3,x_4)\, \mathrm{d}x_2^\prime \mathrm{d}x_2^{\prime\prime} +``` + +it follows that any inference problem on ``f`` can be executed by a corresponding inference problem on ``g``, e.g., + +```math +\begin{align*} +f(x_1 \mid x_2) &\triangleq \frac{\iint f(x_1,x_2,x_3,x_4) \,\mathrm{d}x_3 \mathrm{d}x_4 }{ \int\cdots\int f(x_1,x_2,x_3,x_4) \,\mathrm{d}x_1 \mathrm{d}x_3 \mathrm{d}x_4} \\ + &= \frac{\int\cdots\int g(x_1,x_2,x_2^\prime,x_2^{\prime\prime},x_3,x_4) \,\mathrm{d}x_2^\prime \mathrm{d}x_2^{\prime\prime} \mathrm{d}x_3 \mathrm{d}x_4 }{ \int\cdots\int g(x_1,x_2,x_2^\prime,x_2^{\prime\prime},x_3,x_4) \,\mathrm{d}x_1 \mathrm{d}x_2^\prime \mathrm{d}x_2^{\prime\prime} \mathrm{d}x_3 \mathrm{d}x_4} \\ + &= g(x_1 \mid x_2) +\end{align*} +``` +""" + +# ╔═╡ 9656cf72-d294-11ef-03aa-b715dd686c09 +md""" +## Probabilistic Models as Factor Graphs + +FFGs can be used to express conditional independence (factorization) in probabilistic models. + + +For example, the (previously shown) graph for + +```math +f_a(x_1,x_2,x_3) \cdot f_b(x_3,x_4,x_5) \cdot f_c(x_4) +``` + +could represent the probabilistic model + +```math +p(x_1,x_2,x_3,x_4,x_5) = p(x_1,x_2|x_3) \cdot p(x_3,x_5|x_4) \cdot p(x_4) +``` + +""" + +# ╔═╡ 27b9e811-4542-4fe8-86a5-f8ba09074761 +TwoColumn( +md""" +where we identify +```math +\begin{align*} +f_a(x_1,x_2,x_3) &= p(x_1,x_2|x_3) \\ +f_b(x_3,x_4,x_5) &= p(x_3,x_5|x_4) \\ +f_c(x_4) &= p(x_4) +\end{align*} +``` +""", +@htl """ + + + +""") + +# ╔═╡ 9656d850-d294-11ef-21a1-474b07ea7729 +md""" +This factorized probability distribution is represented by the above FFG. + +""" + +# ╔═╡ 9658329c-d294-11ef-0d03-45e6872c4985 +md""" +## Terminating an FFG + +Consider a model + +```math +f(x_1,x_2,y) = f_a(x_1) f_b(x_1,x_2,y) \,. +``` + +In this model, the variables ``x_2`` and ``y`` appear in only one factor. In the corresponding FFG, edges that only connect to one factor are called a **half-edges**. Half-edges typically represent inputs or outputs of the graph, such as observed variables and external control signals. + +In general, any half-edge can be terminated by a node ``f(\cdot) = 1``, since the model + +```math +f_a(x_1) f_b(x_1,x_2,y) \underbrace{f_c(y)}_{=1} \underbrace{f_d(x_2)}_{=1}\,, +``` +is the same model as ``f_a(x_1) f_b(x_1,x_2,y)``. + + +![](https://github.com/bmlip/course/blob/v2/assets/figures/ffg-terminal-node.png?raw=true) + +An FFG without half-edges is called a Terminated FFG (TFFG). + +""" + +# ╔═╡ f0181b53-a604-489f-a89e-db6fc58571dd +md""" +## Representing Observations + +An observation, say ``y=3``, can be represented by a **delta node** ``f(y)=\delta(y−3)`` to terminate the half-edge for variable ``y``. + +In an FFG, we visualize a delta node by a small black box, + +""" + +# ╔═╡ 9862f675-87e6-4bba-a07d-9e51839819c7 +Resource("https://github.com/bmlip/course/blob/v2/assets/figures/ffg-observation-y-3.png?raw=true", :width => 500, :style => "background: white; padding: 1em; border-radius: 1em;") + +# ╔═╡ ea4a720f-a644-46a0-ad35-b215780e0928 +keyconcept("",md"Any factorized probabilistic model, including a set of observations for that model, can be represented by a Terminated Forney-style factor graph.") + +# ╔═╡ 00c69a22-feb5-4d1e-9ab5-a136435d7d22 +md""" +# Message Passing-based Inference +""" + +# ╔═╡ 9656e606-d294-11ef-1daa-312623552a5b +md""" +## Inference in Factorized Models + +Factorizations offer opportunities to reduce the computational cost of inference by exploiting the conditional independence structure of the model. + +""" + +# ╔═╡ 9656ee62-d294-11ef-38f4-7bc8031df7ee +md""" +Assume we wish to compute the marginal + +```math +\bar{f}(x_3) \triangleq \sum\limits_{x_1,x_2,x_4,x_5,x_6,x_7}f(x_1,x_2,\ldots,x_7) +``` + +for a model ``f`` with given factorization + +```math +f(x_1,x_2,\ldots,x_7) = f_a(x_1) f_b(x_2) f_c(x_1,x_2,x_3) f_d(x_4) f_e(x_3,x_4,x_5) f_f(x_5,x_6,x_7) f_g(x_7) +``` + +""" + +# ╔═╡ 9656fae2-d294-11ef-10d8-ff921d5956bd +md""" +Note that, if each variable ``x_i`` can take on ``10`` values, then computing the marginal ``\bar{f}(x_3)`` takes about ``10^6`` (=``1`` million) additions. + +""" + +# ╔═╡ b33b2aef-e672-490c-bdf4-a5f655fa4695 +md""" +We draw here the FFG for the factorized distribution: + +""" + +# ╔═╡ f46473f8-e749-431d-8350-751115f0aaf0 +Resource("https://github.com/bmlip/course/blob/v4/assets/figures/ffg-message-passing.png?raw=true", :style => "background: #eee; padding: 1em; border-radius: 1em;") + +# ╔═╡ cb3df230-6c7e-41b9-ba13-3c5f8a7fbb62 +md""" +Note that we drew *directed edges* to distinguish between intermediate results ("messages") ``\overrightarrow{\mu}_\bullet(\cdot)`` that flow in the same direction as the arrow of the edge (later to be called: forward messages) from intermediate results ``\overleftarrow{\mu}_\bullet(\cdot)`` that flow in opposite direction (later to be called: backward messages). This is just a notational convenience since an FFG is computationally an undirected graph. For now, only consider the nodes and edges. The messages ``\overrightarrow{\mu}_\bullet(\cdot)`` will be discussed later. + +""" + +# ╔═╡ 96570d3e-d294-11ef-0178-c34dda717495 +md""" +Due to the factorization of ``f(x_1,x_2,\ldots,x_7)`` and the [Generalized Distributive Law](https://en.wikipedia.org/wiki/Generalized_distributive_law), we can decompose the marginalization operation to the following product-of-sums: + +```math +\begin{align*} +\bar{f}(x_3) = + &\underbrace{ \Bigg( \sum_{x_1,x_2} \underbrace{f_a(x_1)}_{\overrightarrow{\mu}_{X_1}(x_1)}\, \underbrace{f_b(x_2)}_{\overrightarrow{\mu}_{X_2}(x_2)}\,f_c(x_1,x_2,x_3)\Bigg) }_{\overrightarrow{\mu}_{X_3}(x_3)} \\ + &\quad\underbrace{ \cdot\Bigg( \sum_{x_4,x_5} \underbrace{f_d(x_4)}_{\overrightarrow{\mu}_{X_4}(x_4)}\,f_e(x_3,x_4,x_5) \cdot \underbrace{ \big( \sum_{x_6,x_7} f_f(x_5,x_6,x_7)\,\underbrace{f_g(x_7)}_{\overleftarrow{\mu}_{X_7}(x_7)}\big) }_{\overleftarrow{\mu}_{X_5}(x_5)} \Bigg) }_{\overleftarrow{\mu}_{X_3}(x_3)} +\end{align*} +``` + +which, in case ``x_i`` has ``10`` values, requires a few hundred additions and is therefore computationally (much!) lighter than executing the whole sum ``\sum_{x_1,\ldots,x_7}f(x_1,x_2,\ldots,x_7)`` + + +""" + +# ╔═╡ 9657b088-d294-11ef-3017-e95c4c69b62b +md""" +As an afterthought, note that applying the distributive law in an FFG for inference is analogous to replacing the sum-of-products + +```math +ac + ad + bc + bd +``` + +by the following product-of-sums: + +```math +(a + b)(c + d) \,. +``` + +Which of these two computations is cheaper to execute? + +""" + +# ╔═╡ 0afe3cdc-15ed-4d9a-848a-d1977d051866 +md""" +## Closing-the-Box and Message Passing Interpretations +""" + +# ╔═╡ 96571c34-d294-11ef-11ef-29beeb1f96c2 +md""" +Note that the intermediate result ``\overrightarrow{\mu}_{X_3}(x_3)`` is obtained by multiplying all enclosed factors (``f_a``, ``f_b, f_c``) by the red dashed box, followed by marginalization (summing) over all enclosed variables (``x_1``, ``x_2``), + +```math +\overrightarrow{\mu}_{X_3}(x_3) = \underbrace{\sum_{x_1}\sum_{x_2}}_{\text{enclosed variables}}\underbrace{f_a(x_1)f_b(x_2) f_c(x_1,x_2,x_3) }_{\text{enclosed factors}} +``` + +This operation is known as **Closing-the-Box**. The result is a new **composite node** that holds the factor ``\overrightarrow{\mu}_{X_3}(x_3)``, and is visually represented by the red dashed box in the factor graph. The composite node ``\overrightarrow{\mu}_{X_3}(x_3)`` depends only on the variable(s) that cross the boundary of the box (in this case ``x_3``) and effectively replaces the internal subgraph contained within the red box. +""" + +# ╔═╡ 253d4703-03d6-4961-8c3b-b70d2cbc0710 +md""" +When closing the box around a terminal node, the result is simply the factor associated with that node, since there are no internal variables to marginalize. +""" + +# ╔═╡ a7b1f559-3c34-491e-83e7-ba95c8c22c80 +md""" + +The Closing-the-box operation can alternatively be interpreted as **passing a message** from the newly created composite node to the rest of the graph. For instance, ``\overrightarrow{\mu}_{X_3}(x_3)`` can be understood in two equivalent ways: + * as a factor associated with the composite node that encloses the subgraph inside the red box. + * as a message sent from this composite node to the variable ``x_3``. + +In both interpretations, the internal details of the subgraph are abstracted away, and the composite node effectively summarizes its contribution to the overall inference process. + + +""" + +# ╔═╡ 70736e62-2b6c-4b3a-ab59-7e51522d620b +md""" + +The complete inference process for computing ``\bar{f}(x_3)`` can be interpreted as a **message passing process**. It begins by sending messages from the terminal nodes and then propagates them through the internal nodes of the factor graph. This continues until both the forward and backward messages for ``x_3`` have been computed. The final result, ``\bar{f}(x_3)``, is obtained by multiplying the forward and backward messages, + +```math +\bar{f}(x_3) = \overrightarrow{\mu}_{X_3}(x_3) \cdot \overleftarrow{\mu}_{X_3}(x_3) +``` + +This message-based interpretation enables modular, local inference that scales efficiently with the structure of the factor graph. + + +""" + + +# ╔═╡ 96575dd4-d294-11ef-31d6-b39b4c4bdea1 +md""" +## Sum-Product Messages + +Let's continue with the message passing interpretation of inference in an FFG. Closing the red box around ``f_a``, ``f_b`` and ``f_c`` leads to an outgoing message ``\overrightarrow{\mu}_{X_3}(x_3)`` for node ``f_c``, given by + +```math +\begin{align} +\underbrace{\overrightarrow{\mu}_{X_3}(x_3)}_{\substack{ \text{outgoing} \\ \text{message} }} +&= \sum_{x_1}\sum_{x_2} \underbrace{\overrightarrow{\mu}_{X_1}(x_1) \overrightarrow{\mu}_{X_2}(x_2)}_{\substack{\text{incoming} \\ \text{messages}}} \underbrace{f_c(x_1,x_2,x_3)}_{\text{factor}} +\end{align} +``` + +This recipe holds generally. For a node ``f(y,x_1,\ldots,x_n)`` with incoming messages ``\overrightarrow{\mu}_{X_1}(x_1)``, ``\overrightarrow{\mu}_{X_2}(x_2)``, ``\ldots``,``\overrightarrow{\mu}_{X_n}(x_n)``, the outgoing message is given by ([Loeliger (2007), pg.1299](https://github.com/bmlip/course/blob/main/assets/files/Loeliger-2007-The-factor-graph-approach-to-model-based-signal-processing.pdf)): + +```math +\underbrace{\overrightarrow{\mu}_{Y}(y)}_{\substack{ \text{outgoing}\\ \text{message}}} = \sum_{x_1,\ldots,x_n} \underbrace{\overrightarrow{\mu}_{X_1}(x_1)\cdots \overrightarrow{\mu}_{X_n}(x_n)}_{\substack{\text{incoming} \\ \text{messages}}} \cdot \underbrace{f(y,x_1,\ldots,x_n)}_{\substack{\text{node}\\ \text{function}}} \tag{SP} +``` + +""" + +# ╔═╡ 5cc2016e-0383-448c-bd33-5b3a687b7436 +TwoColumn( +md""" +Equation (SP) is called a **Sum-Product** message, so named because the computation involves evaluating a sum-of-products. Note that all SP messages in an FFG can be computed from information that is **locally available** at each node. +""", +@htl """ + + + +""") + +# ╔═╡ f65f5d0e-2583-4b88-b9f2-5fee15257c05 +md""" + + +If the factor graph for the whole model has no cycles, i.e., the FFG is a tree, then passing SP messages from the terminal nodes to the internal (latent) variables yields exact Bayesian marginals for all hidden variables. This inference method is known as the **Sum-Product** (SP) algorithm. + +However, if the graph contains cycles, one can view it conceptually as an infinite tree by “unrolling” the cycles. In this loopy setting, SP-based inference is not guaranteed to yield exact marginals. Nevertheless, in practice, if we run the SP algorithm for a limited number of iterations (i.e., a finite unrolling), we often obtain high-quality approximate marginals that are sufficient for many inference tasks. +""" + +# ╔═╡ 7009cdc8-892c-499e-b932-b828fa300b6c +keyconcept("", +md""" +For a node ``f(y,x_1,\ldots,x_n)`` with incoming messages ``\overrightarrow{\mu}_{X_1}(x_1)``, ``\overrightarrow{\mu}_{X_2}(x_2)``, ``\ldots``,``\overrightarrow{\mu}_{X_n}(x_n)``, the outgoing message is given by the **sum-product rule**: + +```math +\overrightarrow{\mu}_{Y}(y)= \sum_{x_1,\ldots,x_n} \overrightarrow{\mu}_{X_1}(x_1)\cdots \overrightarrow{\mu}_{X_n}(x_n) \cdot f(y,x_1,\ldots,x_n) +``` +""") + +# ╔═╡ 91f81188-727c-4754-9a07-e754eef8bbe0 +md""" +## Example: Sum-Product Messages for the Equality Node +""" + +# ╔═╡ 0633afea-5e92-4bad-8402-d159c534af81 +TwoColumn( +md""" +As an example, let´s evaluate the SP messages for the **equality node** + +```math +f_=(x,y,z) = \delta(z-x)\delta(z-y) \,. +``` +""", +@htl """ + + + +""") + +# ╔═╡ f11564db-aafc-4df9-b494-4e5ced9bfcfe +md""" + +Given incoming messages ``\overrightarrow{\mu}_{X}(x)`` and ``\overrightarrow{\mu}_{Y}(y)``, the outgoing SP message ``\overrightarrow{\mu}_{Z}(z)`` to edge ``z`` is given by +```math +\begin{align*} +\overrightarrow{\mu}_{Z}(z) &= \iint \overrightarrow{\mu}_{X}(x) \overrightarrow{\mu}_{Y}(y) \,\delta(z-x)\delta(z-y) \,\mathrm{d}x \mathrm{d}y \\ + &= \overrightarrow{\mu}_{X}(z) \int \overrightarrow{\mu}_{Y}(y) \,\delta(z-y) \,\mathrm{d}y \\ + &= \overrightarrow{\mu}_{X}(z) \overrightarrow{\mu}_{Y}(z) +\end{align*} +``` + +By symmetry, this also implies (for the same equality node) that + +```math +\begin{align*} +\overleftarrow{\mu}_{X}(x) &= \overrightarrow{\mu}_{Y}(x) \overleftarrow{\mu}_{Z}(x) \\ +\overleftarrow{\mu}_{Y}(y) &= \overrightarrow{\mu}_{X}(y) \overleftarrow{\mu}_{Z}(y)\,. +\end{align*} +``` + +It follows that message passing through an equality node is analogous to applying Bayes’ rule: two information sources are fused by multiplying their corresponding probability distributions. + +""" + +# ╔═╡ 9651f976-b834-4b81-8810-649f0290969d +md""" +# RxInfer: A Toolbox for Automated Bayesian inference +""" + +# ╔═╡ 96587a66-d294-11ef-2c7a-9fd7bea76582 +md""" +## Automating Bayesian Inference by Message Passing + +The foregoing message update rules can be worked out in closed form and put into tables (e.g., see Tables 1 through 6 in [Loeliger (2007)](https://github.com/bmlip/course/blob/main/assets/files/Loeliger-2007-The-factor-graph-approach-to-model-based-signal-processing.pdf) for many standard factors such as essential probability distributions and operations such as additions, fixed-gain multiplications, and branching (equality nodes). + +In the optional slides below, we have worked out a few more update rules for the [addition node](#sp-for-addition-node) and the [multiplication node](#sp-for-multiplication-node). + +If the update rules for all node types in a graph have been tabulated, then inference by message passing comes down to executing a set of table-lookup operations, thus creating a completely **automatable Bayesian inference framework**. + +In our research lab [BIASlab](http://biaslab.org) (FLUX 7.060), we are developing [RxInfer](http://rxinfer.com), which is a (Julia) toolbox for automating Bayesian inference by message passing in a factor graph. + +In general, a code package that automates Bayesian inference is called a [Probabilistic Programming](https://en.wikipedia.org/wiki/Probabilistic_programming) Language (PPL). RxInfer is a PPL that automates inference through message passing-based inference in a factor graph. + +""" + +# ╔═╡ 89e2757e-a09f-40c6-8dd7-9b4b4d232e17 +md""" +![](https://github.com/bmlip/course/blob/main/assets/figures/RxInfer-gif.gif?raw=true) +""" + +# ╔═╡ c4b5b124-e52a-41fc-b27e-a58181622e5c +md""" +The figure above (a screen recording from the [RxInfer webpage](http://rxinfer.com)) is an animated GIF illustrating how RxInfer operates. The model is represented as a graph in which each node passes messages to its neighbors. When messages meet on an edge, the belief about the variable associated with that edge is updated. +""" + +# ╔═╡ a1c957c1-69b7-4178-ab59-c0b2439bb01a +code_example("Bayesian Linear Regression by Message Passing"; big=true) + +# ╔═╡ 9658c106-d294-11ef-01db-cfcff611ed81 +md""" +Assume we want to estimate some function ``f: \mathbb{R}^D \rightarrow \mathbb{R}`` from a given data set ``D = \{(x_1,y_1), \ldots, (x_N,y_N)\}``, with ``x_i \in \mathbb{R}^D``, ``y_i \in \mathbb{R}``. + +""" + +# ╔═╡ 96594d44-d294-11ef-22b8-95165fb08ce4 +md""" +### Model Specification + +We will assume a linear model with white Gaussian noise and a Gaussian prior on the coefficients ``w``: + +```math +\begin{align*} + y_i &= w^T x_i + \epsilon_i \\ + \epsilon_i &\sim \mathcal{N}(0, \sigma^2) \\ + w &\sim \mathcal{N}(0,\Sigma) +\end{align*} +``` + +or equivalently + +```math +\begin{align*} +p(w,\epsilon,D) &= \overbrace{p(w)}^{\text{weight prior}} \prod_{i=1}^N \overbrace{p(y_i\,|\,x_i,w,\epsilon_i)}^{\text{data-generating}} \overbrace{p(\epsilon_i)}^{\text{noise prior}} \\ + &= \mathcal{N}(w\,|\,0,\Sigma) \prod_{i=1}^N \delta(y_i - w^T x_i - \epsilon_i) \mathcal{N}(\epsilon_i\,|\,0,\sigma^2) +\end{align*} +``` + +""" + +# ╔═╡ 96597ce0-d294-11ef-3478-25c6bbef601e +md""" +### Inference (parameter estimation) + +We are interested in inferring the posterior ``p(w|D)``. We will execute inference by message passing on the FFG for the model. + +""" + +# ╔═╡ 965998a8-d294-11ef-1d18-85876e3656c5 +md""" +The left figure shows the factor graph for this model for one observation ``(x,y)``. The figure on the right shows the message passing scheme. + +""" + +# ╔═╡ 284a9dd5-1e26-4fd3-bb58-6e7ac0a0872f +Resource("https://github.com/bmlip/course/blob/v2/assets/figures/ffg-bayesian-linear-regression.png?raw=true", :width=>500, :style => "background: white; padding: 1em; border-radius: 1em;") + +# ╔═╡ 42dd67e6-eb0f-4368-9947-47de229f7be1 +md""" +### Modeling a Polynomial +The section above is about a **linear model** for a function on ``\mathbb{R}^D \rightarrow \mathbb{R}``. + +In the example below, we will model a function ``f: \mathbb{R} \rightarrow \mathbb{R}`` with a **polynomial** of degree ``K``. + + +We can use a linear model for a polynomial! The trick is to turn each training data point ``(x,y) \in \mathbb{R} \times \mathbb{R}`` into a feature vector: + +```math +(\,[1, x, x^2, x^3, \cdots, x^K], \ y\,) \quad \in \, \mathbb{R}^{K+1} \times \mathbb{R} +``` + +And we have now transformed our polynomial model on ``\mathbb{R}`` to a linear model on ``\mathbb{R}^{K+1}``. + + +""" + +# ╔═╡ 480165f9-33d9-4db1-bf05-8d99f0d9fb3e +md""" +### Generate the Data Set +For details, see [the Appendix](#Code). + +""" + +# ╔═╡ 1c9c7994-672c-42a3-8ae7-8ce092ada9f0 +begin + N_bond = @bindname Nsamples Slider(1:30; default=20, show_value=true) +end + +# ╔═╡ 8a2019af-9500-42c5-8408-ff93104a2d79 +md""" +Now, we want to find the parameter ``w`` for our polynomial ``f_w`` to model this data. +""" + +# ╔═╡ 1a40ef8d-d677-4bf0-9186-18c5aa43a849 + + +# ╔═╡ 965a1df0-d294-11ef-323c-3da765f1104a +md""" +### Infer Solution with RxInfer + +Now build the factor graph in RxInfer, and perform sum-product message passing to generate a posterior for the weights. + +""" + +# ╔═╡ fd338a30-9622-405a-96fa-caca6bd4ccfb +@model function linear_regression(y,x, Nsamples, Σ, σ²) + + w ~ MvNormalMeanCovariance(zeros(3),Σ) + + for i in 1:Nsamples + y[i] ~ NormalMeanVariance(dot(w, x[i]), σ²) + end +end + +# ╔═╡ 1070063a-ef85-4527-ae82-1f01c1a506ff +prior_Σ = 1e5 * Diagonal(I,3); # prior for the weights + +# ╔═╡ 9431bc9a-bd83-4e4d-b64d-0571c1d01c87 +md""" +It worked! Now we have a **posterior distribution** for ``w``: +""" + +# ╔═╡ b3262127-69e0-4efb-875b-074d1d70437c + + +# ╔═╡ fb61c774-34a3-493a-b149-c870993b6d46 +md""" +#### Plot the Results + +Let's sample ``10`` typical values for the weights ``w`` from this posterior distribution, and plot the corresponding curves ``f_w: x \mapsto w^Tx`` in the scatter plot again. + + +""" + +# ╔═╡ 5bcefd5f-4cd2-4cfe-8c1f-1129e5020d9a +N_bond + +# ╔═╡ 1832bffd-2729-4d3f-86f4-0e2d9ab26ba3 +md""" +Notice how the samples of the functions ``f_w`` lie closer together as we get more observations! +""" + +# ╔═╡ 4a10044c-e044-43e1-bd44-847f56019061 +keyconcept( + "", + md""" + “In `RxInfer`, once the model is specified and the observations are provided, Bayesian inference is carried out automatically via the `infer()` function.” + """ +) + +# ╔═╡ 965a6c20-d294-11ef-1c91-4bd237afbd20 +md""" +## Final thoughts: Modularity and Abstraction + +The great Michael Jordan (no, not [this one](https://youtu.be/cuLprHh_BRg), but [this one](https://people.eecs.berkeley.edu/~jordan/)), wrote: + +> "I basically know of two principles for treating complicated systems in simple ways: the first is the principle of **modularity** and the second is the principle of **abstraction**. I am an apologist for computational probability in machine learning because I believe that probability theory implements these two principles in deep and intriguing ways — namely through factorization and through averaging. Exploiting these two mechanisms as fully as possible seems to me to be the way forward in machine learning." — Michael Jordan, 1997 (quoted in [Fre98](https://mitpress.mit.edu/9780262062022/)). + +Factor graphs capture these ideas elegantly—both visually and computationally. + +**Visually**, the graph structure displays the modularity of conditional independencies in the model. Each node encapsulates internal complexity, and by closing the box, we can hierarchically move to higher levels of abstraction. + +**Computationally**, message-passing inference exploits the distributive law to avoid unnecessary computations. + +Although RxInfer is still under active development, my prediction is that within 5–10 years, RxInfer—or a comparable toolbox—will be able to automate Bayesian inference for virtually any interesting probabilistic model you can conceive. In principle, you will then have all the tools needed to implement the four-step Bayesian ML recipe—model specification, parameter learning, model evaluation, and application—for any (Bayesian) information processing problem. + + +""" + +# ╔═╡ fa5bdb1c-4412-48cc-950c-9ed92b4c9f76 +md""" +# Summary +""" + +# ╔═╡ be670693-2036-46cb-8452-a2d0e1bf1172 +keyconceptsummary() + +# ╔═╡ 25492eea-e649-43f9-b71f-ac6d1a80d0ee +exercises(header_level=1) + +# ╔═╡ a5cd774f-57ad-4cb5-86c0-35987aa6e221 +md""" +##### Message Passing in a State Space Model (*) +""" + +# ╔═╡ b6de3f00-d3b8-44d8-b72a-48cd5628b607 +TwoColumn(md""" Consider the following state-space model: + +```math +\begin{align*} +z_k &= A z_{k-1} + w_k \\ +x_k &= C z_k + v_k +\end{align*} +``` + +where ``k=1,2,\ldots,n`` is the time step counter; ``z_k`` is an *unobserved* state sequence; ``x_k`` is an *observed* sequence; ``w_k \sim \mathcal{N}(0,\Sigma_w)`` and ``v_k \sim \mathcal{N}(0,\Sigma_v)`` are (unobserved) state and observation noise sequences respectively; ``z_0 \sim \mathcal{N}(0,\Sigma_0)`` is the initial state and ``A``, ``C``, ``\Sigma_v``,``\Sigma_w`` and ``\Sigma_0`` are known parameters. """, +@htl """ + +""") + + +# ╔═╡ 05375a01-4d1b-44cc-b1c4-a5eb4b6c5c5b +md""" +- (a) Rewrite the state-space equations as a set of conditional probability distributions. + +```math +\begin{align*} + p(z_k|z_{k-1},A,\Sigma_w) &= \ldots \\ + p(x_k|z_k,C,\Sigma_v) &= \ldots \\ + p(z_0|\Sigma_0) &= \ldots +\end{align*} +``` + +- (b) Define ``z^n \triangleq (z_0,z_1,\ldots,z_n)``, ``x^n \triangleq (x_1,\ldots,x_n)`` and ``\theta=\{A,C,\Sigma_w,\Sigma_v\}``. Now write out the generative model ``p(x^n,z^n|\theta)`` as a product of factors. + +- (c) We are interested in estimating ``z_k`` from a given estimate for ``z_{k-1}`` and the current observation ``x_k``, i.e., we are interested in computing ``p(z_k|z_{k-1},x_k,\theta)``. Can ``p(z_k|z_{k-1},x_k,\theta)`` be expressed as a Gaussian distribution? Explain why or why not in one sentence. + +- (d) Copy the graph onto your exam paper and draw the message passing schedule for computing ``p(z_k|z_{k-1},x_k,\theta)`` by drawing arrows in the factor graph. Indicate the order of the messages by assigning numbers to the arrows. + +- (e) Now assume that our belief about parameter ``\Sigma_v`` is instead given by a distribution ``p(\Sigma_v)`` (rather than a known value). Adapt the factor graph drawing of the previous answer to reflect our belief about ``\Sigma_v``. +""" + +# ╔═╡ 45251c19-6eae-41e7-b0ed-8bd70a67d4e0 +ex_d_sol = TwoColumn( + md""" + - (d) Copy the graph onto your exam paper and draw the message passing schedule for computing ``p(z_k|z_{k-1},x_k,\theta)`` by drawing arrows in the factor graph. Indicate the order of the messages by assigning numbers to the arrows. + + Some permutations of this order are also possible. The most important thing here is that you recognize the tree with ``Z_k`` as a root of the tree and pass messages from the terminals (e.g., ``Z_{k-1}``, ``X_k``, etc.) towards the root. + """, + @htl """ +  + """); + +# ╔═╡ 206c34b3-1873-460b-911e-f2cd4f8886af +hide_solution( +md""" + +- (a) Rewrite the state-space equations as a set of conditional probability distributions. + +```math +\begin{align*} + p(z_k|z_{k-1},A,\Sigma_w) &= \ldots \\ + p(x_k|z_k,C,\Sigma_v) &= \ldots \\ + p(z_0|\Sigma_0) &= \ldots +\end{align*} +``` + +This is a linear system with only Gaussian source signals (``w_k`` and ``v_k``), hence the distributions for ``z_k`` and ``x_k`` will also be Gaussian. As a result, we only need to compute the mean and covariance matrix. We begin with the mean for ``p(z_k|z_{k-1},A,\Sigma_w)``: + + +```math +\begin{align*} + E[z_k|z_{k-1},A,\Sigma_w] &= E[A z_{k-1} + w_k|z_{k-1},A,\Sigma_w] \\ + &= E[A z_{k-1}|z_{k-1},A] + E[w_k|\Sigma_w] \\ + &= A z_{k-1} + 0 + \end{align*} +``` + +And now the variance: + + +```math +\begin{align*} + V[z_k|z_{k-1},A,\Sigma_w] &= E[(z_k - E[z_k])(z_k-E[z_k])^T \,|\,z_{k-1},A,\Sigma_w ] \\ &= E[(\overbrace{A z_{k-1} + w_k}^{z_k} - \overbrace{A z_{k-1}}^{E[z_k]})(A z_{k-1} + w_k-A z_{k-1})^T|z_{k-1},A,\Sigma_w] \\ + &= E[w_k w_k^T|\Sigma_w] \\ + &= \Sigma_w + \end{align*} +``` + +You can execute similar computations for the other distributions, leading to + + +```math +\begin{align*} + p(z_k|z_{k-1},A,\Sigma_w) &= \mathcal{N}(z_k|A z_{k-1},\Sigma_w) \\ + p(x_k|z_k,C,\Sigma_v) &= \mathcal{N}(x_k|C z_k,\Sigma_v) \\ + p(z_0|\Sigma_0) &= \mathcal{N}(z_0|0,\Sigma_0) +\end{align*} +``` + +- (b) Define ``z^n \triangleq (z_0,z_1,\ldots,z_n)``, ``x^n \triangleq (x_1,\ldots,x_n)`` and ``\theta=\{A,C,\Sigma_w,\Sigma_v\}``. Now write out the generative model ``p(x^n,z^n|\theta)`` as a product of factors. + +```math +\begin{align*} +p(x^n,z^n|\theta) &= p(z_0|\Sigma_0) \prod_{k=1}^n p(x_k|z_k,C,\Sigma_v) \,p(z_k|z_{k-1},A,\Sigma_w) \\ + &= \mathcal{N}(z_0|0,\Sigma_0) \prod_{k=1}^n \mathcal{N}(x_k|C z_k,\Sigma_v) \,\mathcal{N}(z_k|A z_{k-1},\Sigma_w) +\end{align*} +``` + +- (c) We are interested in estimating ``z_k`` from a given estimate for ``z_{k-1}`` and the current observation ``x_k``, i.e., we are interested in computing ``p(z_k|z_{k-1},x_k,\theta)``. Can ``p(z_k|z_{k-1},x_k,\theta)`` be expressed as a Gaussian distribution? Explain why or why not in one sentence. + +Yes, since the generative model ``p(x^n,z^n|\theta)`` is (one big) Gaussian. + + $ex_d_sol + +- (e) Now assume that our belief about parameter ``\Sigma_v`` is instead given by a distribution ``p(\Sigma_v)`` (rather than a known value). Adapt the factor graph drawing of the previous answer to reflects our belief about ``\Sigma_v``. + +For answer, see drawing for answer (d). + +""") + +# ╔═╡ a6e155eb-7376-4e57-8e63-628934e14e78 +md""" +##### Messages for the Addition Node (*) + +""" + +# ╔═╡ 9dc870d7-a5f3-447c-96ee-ad23199bc253 +TwoColumn( +md""" +Consider an addition node + +```math +f_+(x,y,z) = \delta(z-x-y) +``` +- Derive an expression for the outgoing message ``\overrightarrow{\mu}_{Z}(z)`` in terms of the incoming messages ``\overrightarrow{\mu}_{X}(\cdot)`` and ``\overrightarrow{\mu}_{Y}(\cdot)``. + +""", + +@htl """ + + + +""") + +# ╔═╡ e8a35c28-6d6d-4066-8251-f091f28622a9 +hide_solution( +md""" + +We use the sum-product rule to compute + + +```math +\begin{align*} + \overrightarrow{\mu}_{Z}(z) &= \iint \overrightarrow{\mu}_{X}(x) \overrightarrow{\mu}_{Y}(y) \,\delta(z-x-y) \,\mathrm{d}x \mathrm{d}y \\ + &= \int \overrightarrow{\mu}_{X}(x) \overrightarrow{\mu}_{Y}(z-x) \,\mathrm{d}x \,, + \end{align*} +``` + +i.e., ``\overrightarrow{\mu}_{Z}`` is the convolution of the messages ``\overrightarrow{\mu}_{X}`` and ``\overrightarrow{\mu}_{Y}``. + + """) + +# ╔═╡ 965a8a1a-d294-11ef-1d2f-65abf76665e8 +md""" +# Optional Slides + +""" + +# ╔═╡ 965aa14c-d294-11ef-226f-65d587fefa64 +md""" +## $(HTML("Sum-Product Messages for Multiplication Nodes")) +""" + +# ╔═╡ 56e8a1bd-ef80-4265-b926-e5e9e085b72f +TwoColumn( +md""" +Next, let us consider a **multiplication** by a fixed (invertible matrix) gain ``f_A(x,y) = \delta(y-Ax)`` +""", +md""" +![](https://github.com/bmlip/course/blob/v2/assets/figures/ffg-gain-node.png?raw=true) +""" +) + +# ╔═╡ 965ab77c-d294-11ef-2510-95b1a998589f +md""" +```math +\begin{align*} +\overrightarrow{\mu}_{Y}(y) &= \int \overrightarrow{\mu}_{X}(x) \,\delta(y-Ax) \,\mathrm{d}x \\ +&= \int \overrightarrow{\mu}_{X}(x) \,|A|^{-1}\delta(x-A^{-1}y) \,\mathrm{d}x \\ +&= |A|^{-1}\overrightarrow{\mu}_{X}(A^{-1}y) \,. +\end{align*} +``` + +""" + +# ╔═╡ 965af708-d294-11ef-112c-f5470031dbbe +md""" +For a Gaussian message input message ``\overrightarrow{\mu}_{X}(x) = \mathcal{N}(x|\overrightarrow{m}_{X},\overrightarrow{V}_{X})``, the output message is also Gaussian with + +```math +\begin{align*} +\overrightarrow{m}_{Y} = A\overrightarrow{m}_{X} \,,\,\text{and}\,\, +\overrightarrow{V}_{Y} = A\overrightarrow{V}_{X}A^T +\end{align*} +``` + +since + +```math +\begin{align*} +\overrightarrow{\mu}_{Y}(y) &= |A|^{-1}\overrightarrow{\mu}_{X}(A^{-1}y) \\ + &\propto \exp \left( -\frac{1}{2} \left( A^{-1}y - \overrightarrow{m}_{X}\right)^T \overrightarrow{V}_{X}^{-1} \left( A^{-1}y - \overrightarrow{m}_{X}\right)\right) \\ + &= \exp \big( -\frac{1}{2} \left( y - A\overrightarrow{m}_{X}\right)^T \underbrace{A^{-T}\overrightarrow{V}_{X}^{-1} A^{-1}}_{(A \overrightarrow{V}_{X} A^T)^{-1}} \left( y - A\overrightarrow{m}_{X}\right)\big) \\ + &\propto \mathcal{N}(y| A\overrightarrow{m}_{X},A\overrightarrow{V}_{X}A^T) \,. +\end{align*} +``` + +""" + +# ╔═╡ 965b11a4-d294-11ef-1d04-dbdf39ce91a3 +md""" +**Exercise**: Prove that, for the same factor ``\delta(y-Ax)`` and Gaussian messages, the (backward) sum-product message ``\overleftarrow{\mu}_{X}`` is given by + +```math +\begin{align*} +\overleftarrow{\xi}_{X} &= A^T\overleftarrow{\xi}_{Y} \\ +\overleftarrow{W}_{X} &= A^T\overleftarrow{W}_{Y}A +\end{align*} +``` + +where ``\overleftarrow{\xi}_X \triangleq \overleftarrow{W}_X \overleftarrow{m}_X`` and ``\overleftarrow{W}_{X} \triangleq \overleftarrow{V}_{X}^{-1}`` (and similarly for ``Y``). + +""" + +# ╔═╡ 965b25ac-d294-11ef-0b9a-9d5a50a76069 +md""" +## $(HTML("Code example: Gaussian forward and backward messages for the Addition node")) + +""" + +# ╔═╡ 8dd6874c-12b7-47b6-b589-009849198024 +TwoColumn( +md""" +Let's calculate the Gaussian forward and backward messages for the addition node in RxInfer. +""", +md""" +![](https://github.com/bmlip/course/blob/v2/assets/figures/ffg-addition-node.png?raw=true) +""" +) + +# ╔═╡ bfbf3d09-23f5-4f54-96f6-bfe536cfc228 +md"Forward message on ``Z``:" + +# ╔═╡ e7e4b6d0-bdf0-4a93-9a73-7971e6e33065 +@call_rule typeof(+)(:out, Marginalisation) (m_in1 = NormalMeanVariance(1.0, 1.0), m_in2 = NormalMeanVariance(2.0, 1.0)) + +# ╔═╡ 2f5415e5-70b1-47ea-9790-7ac953bca538 +md"Backward message on ``X``:" + +# ╔═╡ 1b76ab6c-ffa2-40eb-a6c6-55d7097a5108 +@call_rule typeof(+)(:in1, Marginalisation) (m_out = NormalMeanVariance(3.0, 1.0), m_in2 = NormalMeanVariance(2.0, 1.0)) + +# ╔═╡ 965b886e-d294-11ef-1b10-0319896874cf +md""" +## Code Example: forward and backward messages for the Matrix Multiplication node + +""" + +# ╔═╡ a3e11d46-5a22-4eb6-ba91-7258ba3c667e +TwoColumn( +md""" +In the same way we can also investigate the forward and backward messages for the matrix multiplication ("gain") node +""", +md""" +![](https://github.com/bmlip/course/blob/v2/assets/figures/ffg-gain-node.png?raw=true) +""" +) + +# ╔═╡ 0efe10d8-1d0e-4a8f-8005-25ee261322b8 +md"Forward message on ``Y``:" + +# ╔═╡ 1be3121d-be18-46a1-9af9-f108a2257c22 +@call_rule typeof(*)(:out, Marginalisation) (m_A = PointMass(4.0), m_in = NormalMeanVariance(1.0, 1.0)) + +# ╔═╡ e5658c95-6cd0-426f-b819-31f9f2c7eaf4 +md"Backward message on ``X``:" + +# ╔═╡ 94ca674e-1a01-424c-8657-6510be7097c3 +@call_rule typeof(*)(:in, Marginalisation) (m_out = NormalMeanVariance(2.0, 1.0), m_A = PointMass(4.0)) + +# ╔═╡ 965c18f8-d294-11ef-2456-b945a46241f4 +md""" +## Example: Sum-Product Algorithm to infer a posterior + +""" + +# ╔═╡ e0add49a-94ac-4247-8554-5a50d4abbebb +TwoColumn( +md""" +Consider a generative model + +```math +p(x,y_1,y_2) = p(x)\,p(y_1|x)\,p(y_2|x) . +``` + +This model expresses the assumption that ``Y_1`` and ``Y_2`` are independent measurements of ``X``. + +""", +md""" +![](https://github.com/bmlip/course/blob/v2/assets/figures/ffg-observations.png?raw=true) +""" +) + +# ╔═╡ d05277c1-fb9e-4b2b-bcbc-d8be5e63cab5 +TwoColumn( +md""" +Assume that we are interested in the posterior for ``X`` after observing ``Y_1= \hat y_1`` and ``Y_2= \hat y_2``. The posterior for ``X`` can be inferred by applying the sum-product algorithm to the following graph: + +""", +md""" +![](https://github.com/bmlip/course/blob/v2/assets/figures/ffg-observations-2.png?raw=true) +""" +) + +# ╔═╡ 965c5f28-d294-11ef-324e-4df3e38b5045 +md""" +## Code for Sum-Product Algorithm to infer a posterior + +We'll use RxInfer to build the above graph, and perform sum-product message passing to infer the posterior ``p(x|y_1,y_2)``. We assume ``p(y_1|x)`` and ``p(y_2|x)`` to be Gaussian likelihoods with known variances: + +```math +\begin{align*} + p(y_1\,|\,x) &= \mathcal{N}(y_1\,|\,x, v_{y1}) \\ + p(y_2\,|\,x) &= \mathcal{N}(y_2\,|\,x, v_{y2}) +\end{align*} +``` + +Under this model, the posterior is given by: + +```math +\begin{align*} + p(x\,|\,y_1,y_2) &\propto \overbrace{p(y_1\,|\,x)\,p(y_2\,|\,x)}^{\text{likelihood}}\,\overbrace{p(x)}^{\text{prior}} \\ + &=\mathcal{N}(x\,|\,\hat{y}_1, v_{y1})\, \mathcal{N}(x\,|\,\hat{y}_2, v_{y2}) \, \mathcal{N}(x\,|\,m_x, v_x) +\end{align*} +``` + +so we can validate the answer by solving the Gaussian multiplication manually. + +""" + +# ╔═╡ d27f7af6-e094-44fa-8ba4-4ad2fa38f8bc +y1_hat = 1.0; y2_hat = 2.0; + +# ╔═╡ 90d62ba0-ca97-43f6-8f5a-0c1086a13f3d +md""" +Construct the factor graph + +""" + +# ╔═╡ 053e9dde-c088-4f15-9ca6-98b8185a8a11 +@model function my_model(y1,y2) + + # `x` is the hidden states + x ~ NormalMeanVariance(0.0, 4.0) + + # `y1` and `y2` are "clamped" observations + y1 ~ NormalMeanVariance(x, 1.0) + y2 ~ NormalMeanVariance(x, 2.0) + + return x +end + +# ╔═╡ 07b09ac1-7fa7-4b62-b130-97315adb6fa7 +result = infer(model=my_model(), data=(y1=y1_hat, y2 = y2_hat,)) + +# ╔═╡ defb2149-294b-47a8-99ed-1b3746b275f1 +Text("Sum-product message passing result: p(x|y1,y2) = \n\t𝒩($( + round(mean(result.posteriors[:x]); digits=3) +),$( + round(var(result.posteriors[:x]); digits=3) +))") + +# ╔═╡ b3656d6c-4717-4fcd-90c6-ae4f4aa5e1be + + +# ╔═╡ b15f28ce-c8c1-439b-aeca-74a58d2557e2 +md""" +We calculate mean and variance of `p(x|y1,y2)` manually by multiplying 3 Gaussians (see lesson 4 for details) +""" + +# ╔═╡ 86e67c05-068d-4de4-80f3-1a20cc8a43ea +v = 1 / (1/4 + 1/1 + 1/2) + +# ╔═╡ fffa27d5-eb68-4dd3-9995-4a53fba6c1e4 +m = v * (0/4 + y1_hat/1.0 + y2_hat/2.0) + +# ╔═╡ 578ec319-337d-4396-bb75-eaf99d95a38d +Text("Manual result: p(x|y1,y2) = \n\t𝒩($(m), $(v))") + +# ╔═╡ 89da2fc0-a7c8-4a9d-82d9-622a311d010d +md""" +# Code +""" + +# ╔═╡ 981b08cc-7fb4-4880-8e8a-0b60a5dd72a2 +stable_rand(args...; seed=nothing) = rand(StableRNG(543432 + hash(seed)), args...) + +# ╔═╡ 997235c1-08bd-4dbc-b1bc-cb10a3b83da4 +md""" +## Data generation details + +We first generate data by a "secret" function ``f`` that is parameterized by weights ``w^*``: + +""" + +# ╔═╡ aec4726a-954e-4e76-aae5-2dd6c979b12d +secret_true_w = [1.0; 2.0; 0.25]; + +# ╔═╡ 96ef3cfb-ca18-46d6-bcac-0122c2c85fba +f(x::Vector)::Real = secret_true_w' * x; + +# ╔═╡ 79a0d02b-368f-4371-854c-cf2cea9328e5 +f([3.0^0, 3.0^1, 3.0^2]) + +# ╔═╡ cb4427f9-0cb1-4393-b4de-14a4d64cc29c + + +# ╔═╡ aca1f927-bc3b-48f6-af5c-12ee2ea4a49b +N_bond + +# ╔═╡ 99265e22-e8dc-40fe-989f-0d2a6c72faac +z = stable_rand(Uniform(0, 10), Nsamples; seed=1234) + +# ╔═╡ f6fc4fad-70fb-432f-b77d-8e6ad42eef6c +md""" +Create the feature vector ``x = [1.0, z, z^2]``: +""" + +# ╔═╡ e20e9048-1271-41c7-97d3-635f320aa365 +x_train = [[1.0, z, z^2] for z in z] + +# ╔═╡ 2f86a4cf-2075-45b5-bf2d-2d4d6888461a +x_train + +# ╔═╡ 3a045b5c-9d87-46a6-a404-85c4bd77dd61 +md""" +Now we can generate the observed ``y`` coordinates in the data set: +""" + +# ╔═╡ ba7a2dbd-f068-4249-bc29-77f2d0804676 +data_noise_σ² = 2.0; + +# ╔═╡ 34ebbbe1-2a6b-422b-aeb1-cd2953acddca +# y[i] = w' * x[i] + ϵ +y_train = f.(x_train) + stable_rand(Normal(0, sqrt(data_noise_σ²)), Nsamples; seed=4566) + +# ╔═╡ 7764541a-c11e-4e12-bbac-f8906cbc5dc6 +scatter(z, y_train; + xlim=(-.2,10.2), + ylim=(-1,51), + label="data", + xlabel=L"z", + ylabel=L"f([1.0, z, z^2]) + \epsilon" +) + +# ╔═╡ 22f22f59-c320-4654-b472-b64cc3a001ff +y_train + +# ╔═╡ c03b1140-adce-467a-b953-50ad1bf3bc34 +results = infer( + model = linear_regression( + Nsamples=length(x_train), + Σ=prior_Σ, σ²=data_noise_σ² + ), + data = (y = y_train, x = x_train), + returnvars = (w = KeepLast(),), + iterations = 20, +) + +# ╔═╡ 83a70a4b-b114-4351-8fa2-dd565ebc9916 +convert(MvNormal, results.posteriors[:w]) + +# ╔═╡ 92f7bcfd-00a4-4cb7-a3eb-c1e101fdbcf6 +w_samples = rand(results.posteriors[:w], 10) |> eachcol .|> collect + +# ╔═╡ 965a37e8-d294-11ef-340f-0930b229dd32 +let + plt = scatter( + z, y_train; + xlim=(-.2,10.2), + ylim=(-1,51), + label="data", + xlabel=L"z", + ylabel=L"f([1.0, z, z^2]) + \epsilon" + ) + z_test = collect(0:0.2:12) + x_test = [[1.0; z; z^2] for z in z_test] + for w in w_samples + f_est(x) = w'*x + plot!(plt, z_test, map(f_est, x_test), alpha=0.5, label=nothing); + end + plt +end + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +RxInfer = "86711068-29c9-4ff7-b620-ae75d7495b3d" +StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" + +[compat] +BmlipTeachingTools = "~1.3.1" +LaTeXStrings = "~1.4.0" +Plots = "~1.40.17" +RxInfer = "~4.6.2" +StableRNGs = "~1.0.3" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "46a2a325723fda574bb6c8846f74c34db6ab166e" + +[[deps.ADTypes]] +git-tree-sha1 = "27cecae79e5cc9935255f90c53bb831cc3c870d7" +uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +version = "1.18.0" + + [deps.ADTypes.extensions] + ADTypesChainRulesCoreExt = "ChainRulesCore" + ADTypesConstructionBaseExt = "ConstructionBase" + ADTypesEnzymeCoreExt = "EnzymeCore" + + [deps.ADTypes.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.4.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.4.0" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "d2cd034553ee6ca084edaaf8ed6c9d50fd01555d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.21.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceMetalExt = "Metal" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.ArrayLayouts]] +deps = ["FillArrays", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "355ab2d61069927d4247cd69ad0e1f140b31e30d" +uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +version = "1.12.0" +weakdeps = ["SparseArrays"] + + [deps.ArrayLayouts.extensions] + ArrayLayoutsSparseArraysExt = "SparseArrays" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BayesBase]] +deps = ["Distributions", "DomainSets", "LinearAlgebra", "Random", "SpecialFunctions", "StaticArrays", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "TinyHugeNumbers"] +git-tree-sha1 = "5b723bf6b1081cab4d263e425be097224e0f434f" +uuid = "b4ee3484-f114-42fe-b91c-797d54a0c67e" +version = "1.5.8" +weakdeps = ["FastCholesky"] + + [deps.BayesBase.extensions] + FastCholeskyExt = "FastCholesky" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BitSetTuples]] +deps = ["TupleTools"] +git-tree-sha1 = "aa19428fb6ad21db22f8568f068de4f443d3bacc" +uuid = "0f2f92aa-23a3-4d05-b791-88071d064721" +version = "1.1.5" + +[[deps.BlockArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra"] +git-tree-sha1 = "79e651aa489a7879107d66e3d1948e9aa1b4055e" +uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" +version = "1.7.2" + + [deps.BlockArrays.extensions] + BlockArraysAdaptExt = "Adapt" + BlockArraysBandedMatricesExt = "BandedMatrices" + + [deps.BlockArrays.weakdeps] + Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.ChunkCodecCore]] +git-tree-sha1 = "51f4c10ee01bda57371e977931de39ee0f0cdb3e" +uuid = "0b6fb165-00bc-4d37-ab8b-79f91016dbe1" +version = "1.0.0" + +[[deps.ChunkCodecLibZlib]] +deps = ["ChunkCodecCore", "Zlib_jll"] +git-tree-sha1 = "cee8104904c53d39eb94fd06cbe60cb5acde7177" +uuid = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" +version = "1.0.0" + +[[deps.ChunkCodecLibZstd]] +deps = ["ChunkCodecCore", "Zstd_jll"] +git-tree-sha1 = "34d9873079e4cb3d0c62926a225136824677073f" +uuid = "55437552-ac27-4d47-9aa3-63184e8fd398" +version = "1.0.0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.Combinatorics]] +git-tree-sha1 = "8010b6bb3388abe68d95743dcbea77650bb2eddf" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.3" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.1" + +[[deps.CommonWorldInvalidations]] +git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" +uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" +version = "1.0.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.CompositeTypes]] +git-tree-sha1 = "bce26c3dab336582805503bed209faab1c279768" +uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657" +version = "0.1.4" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" +weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Dictionaries]] +deps = ["Indexing", "Random", "Serialization"] +git-tree-sha1 = "a86af9c4c4f33e16a2b2ff43c2113b2f390081fa" +uuid = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" +version = "0.4.5" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DifferentiationInterface]] +deps = ["ADTypes", "LinearAlgebra"] +git-tree-sha1 = "529bebbc74b36a4cfea09dd2aecb1288cd713a6d" +uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" +version = "0.7.9" + + [deps.DifferentiationInterface.extensions] + DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" + DifferentiationInterfaceDiffractorExt = "Diffractor" + DifferentiationInterfaceEnzymeExt = ["EnzymeCore", "Enzyme"] + DifferentiationInterfaceFastDifferentiationExt = "FastDifferentiation" + DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" + DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" + DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] + DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" + DifferentiationInterfaceGTPSAExt = "GTPSA" + DifferentiationInterfaceMooncakeExt = "Mooncake" + DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] + DifferentiationInterfaceReverseDiffExt = ["ReverseDiff", "DiffResults"] + DifferentiationInterfaceSparseArraysExt = "SparseArrays" + DifferentiationInterfaceSparseConnectivityTracerExt = "SparseConnectivityTracer" + DifferentiationInterfaceSparseMatrixColoringsExt = "SparseMatrixColorings" + DifferentiationInterfaceStaticArraysExt = "StaticArrays" + DifferentiationInterfaceSymbolicsExt = "Symbolics" + DifferentiationInterfaceTrackerExt = "Tracker" + DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] + + [deps.DifferentiationInterface.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" + Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + FastDifferentiation = "eb9bf01b-bf85-4b60-bf87-ee5de06c00be" + FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" + Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" + SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.DomainIntegrals]] +deps = ["CompositeTypes", "DomainSets", "FastGaussQuadrature", "GaussQuadrature", "HCubature", "IntervalSets", "LinearAlgebra", "QuadGK", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "934bf806ef2948114243f25e84a3ddf775d0f1a6" +uuid = "cc6bae93-f070-4015-88fd-838f9505a86c" +version = "0.5.2" + +[[deps.DomainSets]] +deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "c249d86e97a7e8398ce2068dce4c078a1c3464de" +uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" +version = "0.7.16" + + [deps.DomainSets.extensions] + DomainSetsMakieExt = "Makie" + DomainSetsRandomExt = "Random" + + [deps.DomainSets.weakdeps] + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EnumX]] +git-tree-sha1 = "bddad79635af6aec424f53ed8aad5d7555dc6f00" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.5" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.ExponentialFamily]] +deps = ["BayesBase", "BlockArrays", "Distributions", "DomainSets", "FastCholesky", "FillArrays", "ForwardDiff", "HCubature", "HypergeometricFunctions", "IntervalSets", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "PositiveFactorizations", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "StatsBase", "StatsFuns", "TinyHugeNumbers"] +git-tree-sha1 = "8351e116e111c97ad57718851da00ae5a5f92e0c" +uuid = "62312e5e-252a-4322-ace9-a5f4bf9b357b" +version = "2.1.1" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FastCholesky]] +deps = ["LinearAlgebra", "PositiveFactorizations"] +git-tree-sha1 = "1c0a81e006e40e9fcbd5f6f6cb42ac2700f86889" +uuid = "2d5283b6-8564-42b6-bb00-83ed8e915756" +version = "1.4.3" +weakdeps = ["StaticArraysCore"] + + [deps.FastCholesky.extensions] + StaticArraysCoreExt = "StaticArraysCore" + +[[deps.FastGaussQuadrature]] +deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "0044e9f5e49a57e88205e8f30ab73928b05fe5b6" +uuid = "442a2c76-b920-505d-bb47-c5924d526838" +version = "1.1.0" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "d60eb76f37d7e5a40cc2e7c36974d864b82dc802" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.17.1" +weakdeps = ["HTTP"] + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] +git-tree-sha1 = "9340ca07ca27093ff68418b7558ca37b05f8aeb1" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.29.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffSparseArraysExt = "SparseArrays" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedArguments]] +deps = ["TupleTools"] +git-tree-sha1 = "befa1ad59c77643dec6fc20d71fd6f5c3afcdadd" +uuid = "4130a065-6d82-41fe-881e-7a5c65156f7d" +version = "0.1.1" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "ba6ce081425d0afb2bedd00d9884464f764a9225" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.2.2" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" +version = "1.11.0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GaussQuadrature]] +deps = ["SpecialFunctions"] +git-tree-sha1 = "eb6f1f48aa994f3018cbd029a17863c6535a266d" +uuid = "d54b0c1a-921d-58e0-8e36-89d8069c0969" +version = "0.5.8" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.GraphPPL]] +deps = ["BitSetTuples", "DataStructures", "Dictionaries", "MacroTools", "MetaGraphsNext", "NamedTupleTools", "Static", "StaticArrays", "TupleTools", "Unrolled"] +git-tree-sha1 = "db4aece54ddddaa9e8d2880eb7cfc6f29bd1a650" +uuid = "b3f8163a-e979-4e85-b43e-1f63d8c8b42c" +version = "4.6.5" + + [deps.GraphPPL.extensions] + GraphPPLDistributionsExt = "Distributions" + GraphPPLGraphVizExt = "GraphViz" + GraphPPLPlottingExt = ["Cairo", "GraphPlot"] + + [deps.GraphPPL.weakdeps] + Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" + Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" + GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231" + GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Graphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "7a98c6502f4632dbe9fb1973a4244eaa3324e84d" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.13.1" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HCubature]] +deps = ["Combinatorics", "DataStructures", "LinearAlgebra", "QuadGK", "StaticArrays"] +git-tree-sha1 = "19ef9f0cb324eed957b7fe7257ac84e8ed8a48ec" +uuid = "19dc6840-f33b-545b-b366-655c7e3ffd49" +version = "1.7.0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HashArrayMappedTries]] +git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" +uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" +version = "0.2.0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.Indexing]] +git-tree-sha1 = "ce1566720fd6b19ff3411404d4b977acd4814f9f" +uuid = "313cdc1a-70c2-5d6a-ae34-0150d3930a38" +version = "1.1.1" + +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.IntervalSets]] +git-tree-sha1 = "5fbb102dcb8b1a858111ae81d56682376130517d" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.11" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.JLD2]] +deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] +git-tree-sha1 = "da2e9b4d1abbebdcca0aa68afa0aa272102baad7" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.6.2" +weakdeps = ["UnPack"] + + [deps.JLD2.extensions] + UnPackExt = "UnPack" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LazyArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "SparseArrays"] +git-tree-sha1 = "79ee64f6ba0a5a49930f51c86f60d7526b5e12c8" +uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" +version = "2.8.0" + + [deps.LazyArrays.extensions] + LazyArraysBandedMatricesExt = "BandedMatrices" + LazyArraysBlockArraysExt = "BlockArrays" + LazyArraysBlockBandedMatricesExt = "BlockBandedMatrices" + LazyArraysStaticArraysExt = "StaticArrays" + + [deps.LazyArrays.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.4.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MatrixCorrectionTools]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "73f93b21eae5714c282396bfae9d9f13d6ad04b6" +uuid = "41f81499-25de-46de-b591-c3cfc21e9eaf" +version = "1.2.0" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.MetaGraphsNext]] +deps = ["Graphs", "JLD2", "SimpleTraits"] +git-tree-sha1 = "c3f7e597f1cf5fe04e68e7907af47f055cad211c" +uuid = "fa8bd995-216d-47f1-8a91-f3b68fbeb377" +version = "0.7.4" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NLSolversBase]] +deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.10.0" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NamedTupleTools]] +git-tree-sha1 = "90914795fc59df44120fe3fff6742bb0d7adb1d0" +uuid = "d9ec5142-1e00-5aa0-9d6a-321866360f50" +version = "0.14.3" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Optim]] +deps = ["Compat", "EnumX", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "61942645c38dd2b5b78e2082c9b51ab315315d10" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.13.2" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PolyaGammaHybridSamplers]] +deps = ["Distributions", "Random", "SpecialFunctions", "StatsFuns"] +git-tree-sha1 = "9f6139650ff57f9d8528cd809ebc604c7e9738b1" +uuid = "c636ee4f-4591-4d8c-9fae-2dea21daa433" +version = "1.2.6" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "fbb92c6c56b34e1a2c4c36058f68f332bec840e7" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.ReactiveMP]] +deps = ["BayesBase", "DataStructures", "DiffResults", "Distributions", "DomainIntegrals", "DomainSets", "ExponentialFamily", "FastCholesky", "FastGaussQuadrature", "FixedArguments", "ForwardDiff", "HCubature", "LazyArrays", "LinearAlgebra", "MacroTools", "MatrixCorrectionTools", "Optim", "PolyaGammaHybridSamplers", "PositiveFactorizations", "Random", "Rocket", "SpecialFunctions", "StaticArrays", "StatsBase", "StatsFuns", "TinyHugeNumbers", "Tullio", "TupleTools", "Unrolled"] +git-tree-sha1 = "dcd2f85ba9f2f7be1b1b31708db889d078b161f6" +uuid = "a194aa59-28ba-4574-a09c-4a745416d6e3" +version = "5.6.2" + + [deps.ReactiveMP.extensions] + ReactiveMPOptimisersExt = "Optimisers" + ReactiveMPProjectionExt = "ExponentialFamilyProjection" + ReactiveMPRequiresExt = "Requires" + + [deps.ReactiveMP.weakdeps] + ExponentialFamilyProjection = "17f509fa-9a96-44ba-99b2-1c5f01f0931b" + Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.Rocket]] +deps = ["DataStructures", "Sockets", "Unrolled"] +git-tree-sha1 = "fe7373bf6b935c4431002fd91fa581d5eb835d09" +uuid = "df971d30-c9d6-4b37-b8ff-e965b2cb3a40" +version = "1.8.3" + +[[deps.RxInfer]] +deps = ["BayesBase", "DataStructures", "Dates", "Distributions", "DomainSets", "ExponentialFamily", "FastCholesky", "GraphPPL", "HTTP", "JSON", "LinearAlgebra", "Logging", "MacroTools", "Optim", "Preferences", "ProgressMeter", "Random", "ReactiveMP", "Reexport", "Rocket", "Static", "Statistics", "TupleTools", "UUIDs"] +git-tree-sha1 = "bcaf218d6b5329dc5e5be4299cbb5818c2c7bb19" +uuid = "86711068-29c9-4ff7-b620-ae75d7495b3d" +version = "4.6.2" + + [deps.RxInfer.extensions] + PrettyTablesExt = "PrettyTables" + ProjectionExt = "ExponentialFamilyProjection" + + [deps.RxInfer.weakdeps] + ExponentialFamilyProjection = "17f509fa-9a96-44ba-99b2-1c5f01f0931b" + PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SciMLPublic]] +git-tree-sha1 = "ed647f161e8b3f2973f24979ec074e8d084f1bee" +uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" +version = "1.0.0" + +[[deps.ScopedValues]] +deps = ["HashArrayMappedTries", "Logging"] +git-tree-sha1 = "c3b2323466378a2ba15bea4b2f73b081e022f473" +uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" +version = "1.5.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.2" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.5" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] +git-tree-sha1 = "49440414711eddc7227724ae6e570c7d5559a086" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.3.1" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.15" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TinyHugeNumbers]] +git-tree-sha1 = "83c6abf376718345a85c071b249ef6692a8936d4" +uuid = "783c9a47-75a3-44ac-a16b-f1ab7b3acf04" +version = "1.0.3" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.Tullio]] +deps = ["DiffRules", "LinearAlgebra", "Requires"] +git-tree-sha1 = "972698b132b9df8791ae74aa547268e977b55f68" +uuid = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc" +version = "0.3.8" + + [deps.Tullio.extensions] + TullioCUDAExt = "CUDA" + TullioChainRulesCoreExt = "ChainRulesCore" + TullioFillArraysExt = "FillArrays" + TullioTrackerExt = "Tracker" + + [deps.Tullio.weakdeps] + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.TupleTools]] +git-tree-sha1 = "41e43b9dc950775eac654b9f845c839cd2f1821e" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.6.0" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unrolled]] +deps = ["MacroTools"] +git-tree-sha1 = "6cc9d682755680e0f0be87c56392b7651efc2c7b" +uuid = "9602ed7d-8fef-5bc8-8597-8f21381861e8" +version = "0.1.5" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─96547560-d294-11ef-0fa7-6b6489f7baba +# ╟─af24aa27-b0a1-4c9b-aee0-0e5143d2f47e +# ╟─9654ea3e-d294-11ef-335c-657af1ceaf19 +# ╟─96552348-d294-11ef-16d8-b53563054687 +# ╟─9655959e-d294-11ef-0ca6-5f20aa579e91 +# ╟─05db1eab-5b63-4ab9-8b4a-ab2cde554295 +# ╟─9655b2c2-d294-11ef-057f-9b3984064411 +# ╟─403845d6-0229-4c93-bc23-3aecfd76e874 +# ╟─9655d360-d294-11ef-0f06-ab58e2ad0e5f +# ╟─9655e06c-d294-11ef-0393-9355d6e20afb +# ╟─9655ed6e-d294-11ef-370f-937b590036f3 +# ╟─9655fb88-d294-11ef-1ceb-91585012d142 +# ╟─965606f2-d294-11ef-305b-870427879e50 +# ╟─2d5cd42e-26ea-4ee4-979f-3a4e2c6271b6 +# ╟─96561594-d294-11ef-1590-198382927808 +# ╟─9656cf72-d294-11ef-03aa-b715dd686c09 +# ╟─27b9e811-4542-4fe8-86a5-f8ba09074761 +# ╟─9656d850-d294-11ef-21a1-474b07ea7729 +# ╟─9658329c-d294-11ef-0d03-45e6872c4985 +# ╟─f0181b53-a604-489f-a89e-db6fc58571dd +# ╟─9862f675-87e6-4bba-a07d-9e51839819c7 +# ╟─ea4a720f-a644-46a0-ad35-b215780e0928 +# ╟─00c69a22-feb5-4d1e-9ab5-a136435d7d22 +# ╟─9656e606-d294-11ef-1daa-312623552a5b +# ╟─9656ee62-d294-11ef-38f4-7bc8031df7ee +# ╟─9656fae2-d294-11ef-10d8-ff921d5956bd +# ╟─b33b2aef-e672-490c-bdf4-a5f655fa4695 +# ╟─f46473f8-e749-431d-8350-751115f0aaf0 +# ╟─cb3df230-6c7e-41b9-ba13-3c5f8a7fbb62 +# ╟─96570d3e-d294-11ef-0178-c34dda717495 +# ╟─9657b088-d294-11ef-3017-e95c4c69b62b +# ╟─0afe3cdc-15ed-4d9a-848a-d1977d051866 +# ╟─96571c34-d294-11ef-11ef-29beeb1f96c2 +# ╟─253d4703-03d6-4961-8c3b-b70d2cbc0710 +# ╟─a7b1f559-3c34-491e-83e7-ba95c8c22c80 +# ╟─70736e62-2b6c-4b3a-ab59-7e51522d620b +# ╟─96575dd4-d294-11ef-31d6-b39b4c4bdea1 +# ╟─5cc2016e-0383-448c-bd33-5b3a687b7436 +# ╟─f65f5d0e-2583-4b88-b9f2-5fee15257c05 +# ╟─7009cdc8-892c-499e-b932-b828fa300b6c +# ╟─91f81188-727c-4754-9a07-e754eef8bbe0 +# ╟─0633afea-5e92-4bad-8402-d159c534af81 +# ╟─f11564db-aafc-4df9-b494-4e5ced9bfcfe +# ╟─9651f976-b834-4b81-8810-649f0290969d +# ╟─96587a66-d294-11ef-2c7a-9fd7bea76582 +# ╟─89e2757e-a09f-40c6-8dd7-9b4b4d232e17 +# ╟─c4b5b124-e52a-41fc-b27e-a58181622e5c +# ╟─a1c957c1-69b7-4178-ab59-c0b2439bb01a +# ╟─9658c106-d294-11ef-01db-cfcff611ed81 +# ╟─96594d44-d294-11ef-22b8-95165fb08ce4 +# ╟─96597ce0-d294-11ef-3478-25c6bbef601e +# ╟─965998a8-d294-11ef-1d18-85876e3656c5 +# ╟─284a9dd5-1e26-4fd3-bb58-6e7ac0a0872f +# ╟─42dd67e6-eb0f-4368-9947-47de229f7be1 +# ╟─480165f9-33d9-4db1-bf05-8d99f0d9fb3e +# ╟─1c9c7994-672c-42a3-8ae7-8ce092ada9f0 +# ╟─7764541a-c11e-4e12-bbac-f8906cbc5dc6 +# ╟─8a2019af-9500-42c5-8408-ff93104a2d79 +# ╠═2f86a4cf-2075-45b5-bf2d-2d4d6888461a +# ╠═22f22f59-c320-4654-b472-b64cc3a001ff +# ╟─1a40ef8d-d677-4bf0-9186-18c5aa43a849 +# ╟─965a1df0-d294-11ef-323c-3da765f1104a +# ╠═fd338a30-9622-405a-96fa-caca6bd4ccfb +# ╠═1070063a-ef85-4527-ae82-1f01c1a506ff +# ╠═c03b1140-adce-467a-b953-50ad1bf3bc34 +# ╟─9431bc9a-bd83-4e4d-b64d-0571c1d01c87 +# ╠═83a70a4b-b114-4351-8fa2-dd565ebc9916 +# ╟─b3262127-69e0-4efb-875b-074d1d70437c +# ╟─fb61c774-34a3-493a-b149-c870993b6d46 +# ╟─5bcefd5f-4cd2-4cfe-8c1f-1129e5020d9a +# ╟─965a37e8-d294-11ef-340f-0930b229dd32 +# ╟─1832bffd-2729-4d3f-86f4-0e2d9ab26ba3 +# ╟─4a10044c-e044-43e1-bd44-847f56019061 +# ╠═92f7bcfd-00a4-4cb7-a3eb-c1e101fdbcf6 +# ╟─965a6c20-d294-11ef-1c91-4bd237afbd20 +# ╟─fa5bdb1c-4412-48cc-950c-9ed92b4c9f76 +# ╟─be670693-2036-46cb-8452-a2d0e1bf1172 +# ╟─25492eea-e649-43f9-b71f-ac6d1a80d0ee +# ╟─a5cd774f-57ad-4cb5-86c0-35987aa6e221 +# ╟─b6de3f00-d3b8-44d8-b72a-48cd5628b607 +# ╟─05375a01-4d1b-44cc-b1c4-a5eb4b6c5c5b +# ╟─206c34b3-1873-460b-911e-f2cd4f8886af +# ╟─45251c19-6eae-41e7-b0ed-8bd70a67d4e0 +# ╟─a6e155eb-7376-4e57-8e63-628934e14e78 +# ╟─9dc870d7-a5f3-447c-96ee-ad23199bc253 +# ╟─e8a35c28-6d6d-4066-8251-f091f28622a9 +# ╟─965a8a1a-d294-11ef-1d2f-65abf76665e8 +# ╟─965aa14c-d294-11ef-226f-65d587fefa64 +# ╟─56e8a1bd-ef80-4265-b926-e5e9e085b72f +# ╟─965ab77c-d294-11ef-2510-95b1a998589f +# ╟─965af708-d294-11ef-112c-f5470031dbbe +# ╟─965b11a4-d294-11ef-1d04-dbdf39ce91a3 +# ╟─965b25ac-d294-11ef-0b9a-9d5a50a76069 +# ╟─8dd6874c-12b7-47b6-b589-009849198024 +# ╟─bfbf3d09-23f5-4f54-96f6-bfe536cfc228 +# ╠═e7e4b6d0-bdf0-4a93-9a73-7971e6e33065 +# ╟─2f5415e5-70b1-47ea-9790-7ac953bca538 +# ╠═1b76ab6c-ffa2-40eb-a6c6-55d7097a5108 +# ╟─965b886e-d294-11ef-1b10-0319896874cf +# ╟─a3e11d46-5a22-4eb6-ba91-7258ba3c667e +# ╟─0efe10d8-1d0e-4a8f-8005-25ee261322b8 +# ╠═1be3121d-be18-46a1-9af9-f108a2257c22 +# ╟─e5658c95-6cd0-426f-b819-31f9f2c7eaf4 +# ╠═94ca674e-1a01-424c-8657-6510be7097c3 +# ╟─965c18f8-d294-11ef-2456-b945a46241f4 +# ╟─e0add49a-94ac-4247-8554-5a50d4abbebb +# ╟─d05277c1-fb9e-4b2b-bcbc-d8be5e63cab5 +# ╟─965c5f28-d294-11ef-324e-4df3e38b5045 +# ╠═d27f7af6-e094-44fa-8ba4-4ad2fa38f8bc +# ╟─90d62ba0-ca97-43f6-8f5a-0c1086a13f3d +# ╠═053e9dde-c088-4f15-9ca6-98b8185a8a11 +# ╠═07b09ac1-7fa7-4b62-b130-97315adb6fa7 +# ╟─defb2149-294b-47a8-99ed-1b3746b275f1 +# ╟─b3656d6c-4717-4fcd-90c6-ae4f4aa5e1be +# ╟─b15f28ce-c8c1-439b-aeca-74a58d2557e2 +# ╠═86e67c05-068d-4de4-80f3-1a20cc8a43ea +# ╠═fffa27d5-eb68-4dd3-9995-4a53fba6c1e4 +# ╟─578ec319-337d-4396-bb75-eaf99d95a38d +# ╟─89da2fc0-a7c8-4a9d-82d9-622a311d010d +# ╠═5a8dcadb-f0c2-4fb0-b8cd-db8cf49cc292 +# ╠═965a08f4-d294-11ef-0604-1586ff37c0d4 +# ╠═981b08cc-7fb4-4880-8e8a-0b60a5dd72a2 +# ╠═2cb7d369-e7fd-4d66-8321-66a9197a26bd +# ╠═387f55ba-0fa4-4171-a405-3b1fb4e6b586 +# ╟─997235c1-08bd-4dbc-b1bc-cb10a3b83da4 +# ╠═96ef3cfb-ca18-46d6-bcac-0122c2c85fba +# ╠═aec4726a-954e-4e76-aae5-2dd6c979b12d +# ╠═79a0d02b-368f-4371-854c-cf2cea9328e5 +# ╟─cb4427f9-0cb1-4393-b4de-14a4d64cc29c +# ╟─aca1f927-bc3b-48f6-af5c-12ee2ea4a49b +# ╠═99265e22-e8dc-40fe-989f-0d2a6c72faac +# ╟─f6fc4fad-70fb-432f-b77d-8e6ad42eef6c +# ╠═e20e9048-1271-41c7-97d3-635f320aa365 +# ╟─3a045b5c-9d87-46a6-a404-85c4bd77dd61 +# ╠═34ebbbe1-2a6b-422b-aeb1-cd2953acddca +# ╠═ba7a2dbd-f068-4249-bc29-77f2d0804676 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/Intelligent Agents and Active Inference.jl b/mlss/Intelligent Agents and Active Inference.jl new file mode 100644 index 00000000..c606e7f5 --- /dev/null +++ b/mlss/Intelligent Agents and Active Inference.jl @@ -0,0 +1,1964 @@ +### A Pluto.jl notebook ### +# v0.20.19 + +#> [frontmatter] +#> image = "https://imgur.com/FlRMz2f.png" +#> language = "en-US" +#> description = "Introduction to Active Inference and application to the design of synthetic intelligent agents" +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# ╔═╡ 0b5b816b-2dd2-4fe8-8f84-4eb2d58b5d59 +using RxInfer + +# ╔═╡ 97a0384a-0596-4714-a3fc-bf422aed4474 +using BmlipTeachingTools + +# ╔═╡ 278382c0-d294-11ef-022f-0d78e9e2d04c +title("Intelligent Agents and Active Inference") + +# ╔═╡ 9fbae8bf-2132-4a9a-ab0b-ef99e1b954a4 +PlutoUI.TableOfContents() + +# ╔═╡ 27839788-d294-11ef-30a2-8ff6357aa68b +md""" +## Preliminaries + +##### Goal + + * Introduction to Active Inference and application to the design of synthetic intelligent agents + +##### Materials + + * Mandatory + + * These lecture notes + + * Optional + + * Noumenal labs (2025), [WTF is the FEP? A short explainer on the free energy principle](https://www.noumenal.ai/post/wtf-is-the-fep-a-short-explainer-on-the-free-energy-principle) + * A concise, accessible introduction to the Free Energy Principle, aimed at demystifying it for a broader audience—matching the tone and intent suggested by the playful but clear title. + + * De Vries et al. (2025), [Expected Free Energy-based Planning as Variational Inference](https://arxiv.org/pdf/2504.14898) + * On minimizing expected free energy by variational free energy minimization. + + * Friston et al. (2023), [Path integrals, particular kinds, and strange things](https://doi.org/10.1016/j.plrev.2023.08.016) + * The most recent formal developments of the Free Energy Principle (FEP). This paper frames FEP as a principle of least action over trajectories. + + * Bert de Vries, Tim Scarfe and Keith Duggar (2023), Podcast on [Active Inference](https://youtu.be/2wnJ6E6rQsU?si=I4_k40j42_8E4igP). Machine Learning Street Talk podcast + * Quite extensive discussion on many aspect regarding the Free Energy Principle and Active Inference, in particular relating to its implementation. + + * Friston et al. (2022), [Designing Ecosystems of Intelligence from First Principles](https://arxiv.org/abs/2212.01354) + * Friston's vision on the future of AI. + + * Bert de Vries (2021), Presentation on [Beyond deep learning: natural AI systems](https://youtu.be/QYbcm6G_wsk?si=G9mkjmnDrQH9qk5k) (video) + * 30-minute introduction to active inference from an engineering point of view. + * Raviv (2018), [The Genius Neuroscientist Who Might Hold the Key to True AI](https://github.com/bmlip/course/blob/main/assets/files/WIRED-Friston.pdf). + * Interesting article on Karl Friston, who is a leading theoretical neuroscientist working on a theory that relates life and intelligent behavior to physics (and Free Energy minimization). (**highly recommended**) + * Karl Friston (2011), [What Is Optimal about Motor Control?](https://doi.org/10.1016/j.neuron.2011.10.018), Neuron 72-3, p488-498 + * This work critiques classical optimal control theory for being an insufficient model of biological motor control, and instead advocates active inference as a more suitable framework. + + + + + + +""" + +# ╔═╡ 2783a99e-d294-11ef-3163-bb455746bf52 +md""" +## Agents + +In the previous lessons, we assumed that a data set was given. + +In this lesson, we consider *agents*. An agent is a system that *interacts* with its environment through both sensors and actuators. + +Crucially, by acting on the environment, the agent is able to affect the data that it will sense in the future. + + * As an example, by changing the direction where I look, I can affect the (visual) data that will be sensed by my retina. + +With this definition of an agent, (biological) organisms are agents, and so are robots, self-driving cars, etc. + +In an engineering context, we are particularly interested in agents that behave with a *purpose*, that is, with a specific goal in mind, such as driving a car or trading in financial markets. + +In this lesson, we will describe how **goal-directed behavior** by biological (and synthetic) agents can also be interpreted as the minimization of a free energy functional. + +""" + +# ╔═╡ aed436fd-6773-4932-a5d8-d01cf99c10ec +challenge_statement("The Door-Key MiniGrid Problem", color="red",header_level=1) + +# ╔═╡ 983873d0-e1bc-4e1b-9b6c-3df0a17d83f6 +TwoColumn( + md"""##### Problem +In this example, we consider [the Door-Key MiniGrid problem](https://minigrid.farama.org/environments/minigrid/DoorKeyEnv/), which is part of the challenging MiniGrid environment family. In these environments, an agent is positioned in a gridworld and has to solve a particular task. The red triangle indicates the agent’s location and viewing direction, while the green square marks the target location. """, + md""" +![Minigrid environment](https://github.com/bmlip/course/blob/main/assets/ai_agent/minigrid_environment.png?raw=true) +""") + + +# ╔═╡ 2783b312-d294-11ef-2ebb-e5ede7a86583 +md""" +At each timestep, the agent observes the portion of the environment contained within the shaded rectangle in front of its viewing direction. The agent’s task is to find the key, use it to open the door (yellow square in the third column), and then navigate to the target square. + +We assume that the agent has complete knowledge of the environmental process dynamics (e.g., how to walk or which action corresponds to picking up a key). However, the locations of the key and door are randomized and therefore unknown. + +The challenge is to design an agent that autonomously navigates to the target square. The agent should be defined as a probabilistic model, with its control signals obtained by casting action selection as a Bayesian inference problem. + +""" + +# ╔═╡ 939e74b0-8ceb-4214-bbc0-407c8f0b2f26 +md""" +##### Solution +At the [end of this lesson](#Challenge-Revisited:-The-Door-Key-MiniGrid-Problem). +""" + +# ╔═╡ e3d5786b-49e0-40f7-9056-13e26e09a4cf +md""" +# The Free Energy Principle +""" + +# ╔═╡ 2f38a3c9-67d4-4c45-ad0b-e757f62d6a5e +md""" +## Motivation + +The human brain is the most complex control system we know. It processes inputs from about ``10`` million sensory neurons through roughly ``10^{11}`` (``=100`` billion) neurons, and drives action via about half a million motor neurons. None of these neurons “know” anything about Fourier transforms, dynamic programming, or backpropagation, they simply minimize variational free energy (VFE). + +Remarkably, this autonomous process is sufficient to create a control system that outperforms anything we have ever engineered with our hand-crafted theories of control and signal processing. As engineers, this motivates our work on active inference agents: if nature can produce such superior systems solely through autonomous VFE minimization, perhaps this is also the right path forward in engineering. To achieve truly high-performant adaptive control in volatile environments, it may be necessary to let go of hand-crafted algorithms and build systems that function solely by VFE minimization. + +This lecture explores that idea. +""" + +# ╔═╡ 4ed2ef1f-4d55-4f9b-b8f5-7f77b5fc62ca +@htl """ + + + +""" + +# ╔═╡ 2783c686-d294-11ef-3942-c75d2b559fb3 +md""" +## What Drives Intelligent Behavior? + +We begin with an example that requires "intelligent" decision-making. Assume that you are an owl and that you're hungry. What are you going to do? + +Have a look at [Prof. Karl Friston](https://www.wired.com/story/karl-friston-free-energy-principle-artificial-intelligence/)'s answer in this [video segment on the cost function for intelligent behavior](https://youtu.be/L0pVHbEg4Yw). (**Do watch the video!**) + +![image Friston presentation at CCN-2016](https://github.com/bmlip/course/blob/main/assets/figures/Friston-2016-presentation.png?raw=true) + +In his answer, Friston emphasizes that the first step is to search for food, for instance, a mouse. You cannot eat the mouse unless you know where it is, so the first imperative is to reduce your uncertainty about the location of the mouse. In other words, purposeful behavior begins with [epistemic](https://www.merriam-webster.com/dictionary/epistemic) behavior: searching to resolve uncertainty. + +This stands in contrast to more traditional approaches to intelligent behavior, such as [reinforcement learning](https://en.wikipedia.org/wiki/Reinforcement_learning), where the objective is to maximize a value function of future states, e.g., ``V(s)``, where ``s`` might encode how hungry the agent is. However, this paradigm falls short in scenarios where the optimal next action is to gather information, because uncertainty is not an attribute of states themselves, but of *beliefs* over states, which are expressed as probability distributions. + +Therefore, Friston argues that intelligent behavior requires us to optimize a functional ``F[q(s|u)]``, where ``q(s|u)`` is a probability distribution over (future) states ``s`` for a given action sequence ``u``, and ``F`` evaluates the quality of this belief. + +Later in his lectures and papers, Friston expands on this belief-based objective ``F`` and formalizes it as a variational free energy functional—laying the foundation for the **Free Energy Principle**. This principle offers a unifying framework that connects biological (or “intelligent”) decision-making and behavior directly to Bayesian inference. + +""" + +# ╔═╡ 126c3221-34b8-4a8f-b5b5-c14ff4c6a2a1 +keyconcept("","Friston’s key insight is that intelligent behavior necessarily involves uncertainty-reducing behavior, which should be framed as the optimization of a functional of beliefs (i.e., probabilities) over future states.") + +# ╔═╡ 29592915-cadf-4674-958b-5743a8f73a8b +md""" + +## The Free Energy Principle + +The Free Energy Principle (FEP) is neither a model nor a theory. Rather, it is a principle, that is, a **methodological framework** for describing the information-processing dynamics that *must* unfold in living systems to keep them within viable (i.e., livable) states over extended periods of time. + - Think of the processes continuously occurring in our bodies to maintain an internal temperature between approximately ``36^{\circ}\text{C}`` and ``37^{\circ}\text{C}``, regardless of the surrounding ambient temperature. + +The literature on the FEP is widely regarded as difficult to access. It was first formally derived as a specific case of the [Least Action Principle](#The-FEP-is-a-Least-Action-Principle-for-"Things") by Friston in his monograph [Friston (2019), A Free Energy Principle for a Particular Physics (2019)](https://arxiv.org/abs/1906.10184), and more recently presented in a more accessible form in [Friston et al. (2023), Path integrals, particular kinds, and strange things](https://doi.org/10.1016/j.plrev.2023.08.016). For a concise and approachable introduction, the explainer by [Noumenal Labs (2025), WTF is the FEP?](https://www.noumenal.ai/post/wtf-is-the-fep-a-short-explainer-on-the-free-energy-principle) is currently the most accessible resource I am aware of. + +In this lecture, we present only a simplified account. According to the FEP, the brain is a generative model for its sensory inputs, such as visual and auditory signals, and **continuously minimizes variational free energy** (VFE) in that model to stay aligned with these observations. Crucially, VFE minimization is the *only* ongoing process, and it underlies perception, learning, attention, emotions, consciousness, intelligent decision-making, etc. + +To illustrate the idea that perception arises from a (variational) inference process—driven by top-down predictions from the brain and corrected by bottom-up sensory inputs—consider the following figure: "The Gardener" by Giuseppe Arcimboldo (ca. 1590). + +![](https://github.com/bmlip/course/blob/v2/assets/figures/the-gardener.png?raw=true) + +On the left, you’ll likely perceive a bowl of vegetables. However, when the same image is turned upside down, most people first see a gardener’s face. + +This perceptual flip arises because the brain’s generative model assigns a much higher probability to being in an environment with upright human faces than with inverted bowls of vegetables. While the sensory input is consistent with both interpretations, the brain’s prior beliefs drive our perception toward seeing upright faces (and upright bowls of vegetables). + +In short, the FEP characterizes “intelligent” behavior as the outcome of a VFE minimization process. Next, we derive the dynamics of an *Active Inference* agent—an agent whose behavior is entirely governed by VFE minimization. We will demonstrate that minimizing VFE within a generative model constitutes a sufficient mechanism for producing basic intelligent behavior. +""" + +# ╔═╡ 5b8405f7-8878-43dd-8f84-bca17450924f +keyconcept("","The **Free Energy Principle** (FEP) can be seen as a specific instance of the Least Action Principle applied to biological systems, which are technically systems that act to preserve their functional and structural integrity.") + +# ╔═╡ 9708215c-72c9-408f-bd10-68ae02e17243 +md""" +# The Expected Free Energy Theorem +""" + +# ╔═╡ f9b241fd-d853-433e-9996-41d8a60ed9e8 +md""" +## Setup of Prior Beliefs + +Let's make the above notions more concrete. We consider an agent that interacts with its environment. At the current time ``t``, the agent holds a generative model to predict its future observations, + +```math +\begin{align} +p(y,x,u,\theta) \,, \tag{P1} +\end{align} +``` + +where ``y`` denotes future observations, ``x`` refers to internal (hidden) future states, ``u`` represents the agent's future actions, and ``\theta`` are model parameters. + +Since model (P1) is designed to predict how the future is expected to unfold, we refer to (P1) as the **predictive model**. A typical example is a rollout to the future of a state-space model, + +```math +p(y,x,u,\theta) = p(x_t) p(\theta)\underbrace{\prod_{k=t+1}^T p(y_k|x_k,\theta) p(x_k|x_{k-1},u_k) p(u_k)}_{\text{rollout to the future}}\,. +``` + +In addition to the predictive model, we assume that the agent holds beliefs ``\hat{p}(x)`` about the *desired* future states. For example, the owl in our earlier example holds the belief that it will not be hungry in the future. We refer to ``\hat{p}(x)`` as the **goal prior**. + +Finally, we assume that the agent also maintains **epistemic** (= information-seeking) prior beliefs, denoted by ``\tilde{p}(u)``, ``\tilde{p}(x)``, and ``\tilde{p}(y,x)``, which will be further specified below. + +The predictive model, together with the goal and epistemic priors, constitutes the agent’s complete set of prior beliefs about the future. + +""" + + +# ╔═╡ 97136f81-3468-439a-8a22-5aae96725937 +md""" + +## The Expected Free Energy Theorem + +We now state the [Expected Free Energy theorem](https://arxiv.org/pdf/2504.14898#page=8). Let the variational free energy functional ``F[q]`` be defined as +```math +\begin{align} +F[q] = \mathbb{E}_{q(y,x,u,\theta)} \bigg[ \log \frac{q(y,x,u,\theta)}{\underbrace{p(y,x,u,\theta)}_{\text{predictive}} \underbrace{\hat{p}(x)}_{\text{goal}} \underbrace{\tilde{p}(u) \tilde{p}(x) \tilde{p}(y,x)}_{\text{epistemics}}} \bigg] \,. \tag{F1} +\end{align} +``` + +Let the agent’s epistemic priors be defined as + +```math +\begin{align} +\tilde{p}(u) &= \exp\left( H[q(x|u)]\right) \tag{E1}\\ +\tilde{p}(x) &= \exp\left( -H[q(y|x)]\right) \tag{E2} \\ +\tilde{p}(y,x) &= \exp\left( D[q(\theta|y,x) , q(\theta|x)]\right) \tag{E3} +\end{align} +``` +where ``H[q] = \mathbb{E}_q\left[ -\log q\right]`` is the entropy functional, and ``D[q,p] = \mathbb{E}_q\left[ \log q - \log p\right]`` is the Kullback–Leibler divergence. + +Then, the variational free energy ``F[q]`` decomposes as + +```math +\begin{align} +F[q] = \underbrace{\mathbb{E}_{q(u)}\left[ G(u)\right]}_{\substack{ \text{expected policy} \\ \text{costs}} } + \underbrace{ \mathbb{E}_{q(y,x,u,\theta)}\left[ \log \frac{q(y,x,u,\theta)}{p(y,x,u,\theta)}\right]}_{\text{complexity}} \tag{F2}\,, +\end{align} +``` +where the function ``G(u)``, known as the **Expected Free Energy** (EFE) cost function, is given by +```math +\begin{align} +G(u) = \underbrace{\underbrace{\mathbb{E}_{q}\bigg[ \log \frac{q(x|u)}{\hat{p}(x)}\bigg]}_{\text{risk}}}_{\text{scores goal-driven behavior}} + \underbrace{\underbrace{\mathbb{E}_{q}\bigg[ \log \frac{1}{q(y|x)}\bigg]}_{\text{ambiguity}} - \underbrace{\mathbb{E}_{q}\bigg[ \log \frac{q(\theta|y,x)}{q(\theta|x)}\bigg]}_{\text{novelty}}}_{\text{scores information-seeking behavior}} \,. \tag{G1} +\end{align} +``` + + +""" + +# ╔═╡ 4e990b76-a2fa-49e6-8392-11f98d769ca8 +details("Click for proof of the EFE Theorem", + md""" + + For the following proof, see also Appendix A in [De Vries et.al., Expected Free Energy-based Planning as Variational Inference (2025)](https://arxiv.org/pdf/2504.14898#page=15). + + ```math + \begin{flalign} + F[q] &= E_{q(y x u \theta)}\bigg[ \log \frac{q(y x u \theta)}{p(y x u \theta) \hat{p}(x) \tilde{p}(u) \tilde{p}(x) \tilde{p}(yx)} \bigg] \\ + &= E_{q(u)}\bigg[ \log \frac{q(u)}{p(u)} + + \underbrace{E_{q(yx\theta | u)}\big[ \log \frac{q(y x \theta | u)}{p(yx \theta|u) \hat{p}(x) \tilde{p}(u) \tilde{p}(x) \tilde{p}(yx)}\big]}_{B(u)} + \bigg] \; &&\text{(C1)}\\ + &= E_{q(u)}\bigg[ \log \frac{q(u)}{p(u)} + + \underbrace{G(u) +E_{q(yx\theta | u)} \big[\log \frac{q(yx\theta|u)}{p(yx\theta|u)}\big]}_{=B(u) \text{ if conditions (E1), (E2) and (E3) hold}} + \bigg] &&\text{(C2)} \\ + &= E_{q(u)}\big[ G(u)\big]+ E_{q(yx u\theta)}\bigg[\log \frac{q(yx u \theta)}{p(yx u \theta) }\bigg]\,, + \end{flalign} + ``` + if the conditions in Eqs. ``(\mathrm{E}1)``, ``(\mathrm{E}2)``, and ``(\mathrm{E}3)`` hold. + + In the above derivation, we still need to prove the equivalence of ``B(u)`` in + Eqs. ``(\mathrm{C}1)`` and ``(\mathrm{C}2)``, which we address next. + In the following, all expectations are with respect to ``q(y,x,\theta|u)`` unless otherwise indicated. + + ```math + \begin{flalign} + B(&u) = E\bigg[ \log \frac{ \overbrace{q(yx\theta|u)}^{\text{posterior}} }{ \underbrace{p(yx\theta|u)}_{\text{predictive}} \underbrace{\hat{p}(x)}_{\text{goals}} \underbrace{\tilde{p}(u) \tilde{p}(x) \tilde{p}(yx)}_{\text{epistemic priors}}} \bigg] \; &&\text{(C3)} \\ + &= \underbrace{ E\bigg[\log\bigg( \underbrace{\frac{q(x|u)}{\hat{p}(x)}}_{\text{risk}}\cdot \underbrace{\frac{1}{q(y|x )}}_{\text{ambiguity}} \cdot \underbrace{\frac{ q(\theta|x)}{ q(\theta|yx )}}_{-\text{novelty}} \bigg) \bigg] }_{G(u) = \text{Expected Free Energy}} + \\ + &\quad + E\bigg[ \log\bigg( \underbrace{\frac{\hat{p}(x) q(y|x ) q(\theta| yx)}{q(x|u) q(\theta|x)}}_{\text{inverse factors from }G(u)} \cdot \underbrace{\frac{q(yx\theta|u)}{p(yx\theta|u) \hat{p}(x) \tilde{p}(u) \tilde{p}(x) \tilde{p}(yx) }}_{\text{leftover factors from (C3)}} \bigg)\bigg] \notag \\ + &= G(u) + \underbrace{E\bigg[ \log \frac{q(yx\theta|u)}{p(yx\theta|u)}\bigg]}_{=C(u)} + \underbrace{E\bigg[ \log \frac{q(y|x ) q(\theta|yx)}{q(x|u) q(\theta|x) \tilde{p}(u) \tilde{p}(x) \tilde{p}(yx)} \bigg]}_{\text{choose epistemic priors to let this vanish}} \\ + &= G(u) + C(u) + \\ + &\quad + E\bigg[\log \frac{1}{q(x|u) \tilde{p}(u)} \bigg] + E\bigg[ \log \frac{q(y|x)}{\tilde{p}(x)} \bigg] + E\bigg[ \log \frac{q(\theta|yx)}{q(\theta|x) \tilde{p}(yx) } \bigg] \notag \\ + &= G(u) + C(u) + \\ + &\qquad + \sum_{y\theta} q(y\theta|x) \bigg( \underbrace{\underbrace{-\sum_x q(x|u) \log q(x|u)}_{= H[q(x|u)]} - \sum_x q(x|u) \log \tilde{p}(u)}_{=0 \text{ if }\tilde{p}(u) = \exp(H[q(x|u)])}\bigg) \\ + &\qquad + \sum_{x} q(x|u) \bigg( \underbrace{\underbrace{\sum_{y} q(y|x) \log q(y|x)}_{= -H[q(y|x)]} - \sum_{y} q(y|x) \log \tilde{p}(x)}_{=0 \text{ if }\tilde{p}(x) = \exp(-H[q(y|x)])} \bigg) \notag \\ + &\qquad + \sum_{yx} q(yx|u) \bigg( \underbrace{\underbrace{\sum_\theta q(\theta|yx) \log \frac{q(\theta|yx)}{q(\theta|x)}}_{D[q(\theta|yx),q(\theta|x)]} - \sum_\theta q(\theta|yx) \log \tilde{p}(yx)}_{=0 \text{ if } \tilde{p}(yx) = \exp(D[q(\theta|yx),q(\theta|x)])} \bigg) \notag \\ + &= G(u) + E_{q(yx\theta|u)}\bigg[ \log \frac{q(yx\theta|u)}{p(yx\theta|u)}\bigg] \,, + \end{flalign} + ``` + if Eqs. (E1), (E2), and (E3) hold. + + """) + +# ╔═╡ aec84a6d-33fc-4541-80c0-091998f8c4d1 +begin + ambiguity_as_expected_entropy = details("Click to show derivation of ambiguity as an expected entropy", +md""" Starting from Eq.(G1), +```math +\begin{align} + \mathbb{E}_{q(y,x|u)}\bigg[ \log \frac{1}{q(y|x)}\bigg] &= \mathbb{E}_{q(x|u)}\bigg[ \mathbb{E}_{q(y|x)} \big[\log \frac{1}{q(y|x)}\big] \bigg] \\ + &= \mathbb{E}_{q(x|u)}\left[H[q(y|x)] \right] +\end{align} +``` +""") + +novelty_as_mutual_information = details("Click to show derivation of novelty in terms of mutual information", +md""" Starting from Eq.(G1), +```math +\begin{align} + \mathbb{E}_{q(y,x,\theta|u)}\bigg[ \log \frac{q(\theta|y,x)}{q(\theta|x)}\bigg] &= \mathbb{E}_{q(y,\theta|x) q(x|u)}\bigg[ \log \frac{q(\theta|y,x)}{q(\theta|x)}\bigg] \\ + &= \mathbb{E}_{q(x|u)}\bigg[ \mathbb{E}_{q(y,\theta|x)} \big[ \log \frac{q(\theta|y,x)}{q(\theta|x)} \big] \bigg] \\ + &= \mathbb{E}_{q(x|u)}\bigg[ \underbrace{\mathbb{E}_{q(y,\theta|x)} \big[ \log \frac{q(\theta,y|x)}{q(\theta|x) q(y|x)} \big]}_{I[\theta,y\,|x]} \bigg] \\ + &= \mathbb{E}_{q(x|u)}\big[ I[\theta,y\,|x] \big] + \end{align} +``` +""") +end; + +# ╔═╡ aaa07dc5-9105-4f70-b924-6e51e5c36600 +md""" +## Interpretation of Expected Free Energy ``G(u)`` + +``G(u)`` is a cost function defined over a sequence of future actions ``u = (u_{t+1},u_{t+2}, \ldots, u_{T})``, commonly referred to as a **policy**. ``G(u)`` decomposes into three distinct components: + +###### risk + - The risk term is the KL divergence between ``q(x|u)``, the *predicted* future states under policy ``u``, and ``\hat{p}(x)``, the *desired* future states (the goal prior). As a result, ``G(u)`` penalizes policies that lead to expectations which diverge from the agent’s preferences — that is, from what the agent wants to happen. + +###### ambiguity + - Ambiguity can be expressed as ``\mathbb{E}_{q(x|u)}\left[H[q(y|x)] \right]``, which quantifies the expected entropy of future observations ``y``, under policy ``u``. It measures how ambiguous or noisy the relationship is between hidden states ``x`` and observations ``y``. Policies with low ambiguity are preferable because they lead to observations that are more informative about the hidden state, thus facilitating more accurate inference and better decision-making. + - $(ambiguity_as_expected_entropy) + + +###### novelty + - The novelty term can be worked out to ``\mathbb{E}_{q(x|u)}\big[ I[\theta,y\,|x] \big]``, where ``I[\theta,y\,|x]`` is the [mutual information](https://en.wikipedia.org/wiki/Mutual_information) between parameters ``\theta`` and observations ``y``, given states ``x``. Novelty complements the ambiguity term. While ambiguity scores information-seeking behavior aimed at reducing uncertainty about hidden states ``x``, the novelty term extends this idea to parameters ``\theta`` of the generative model. It encourages policies that are expected to lead to observations that reduce uncertainty about ``\theta``, i.e., learning about the structure or dynamics of the environment itself. + - $(novelty_as_mutual_information) + +Clearly, policies with lower Expected Free Energy are preferred. Such policies strike a balance between goal-directed behavior—by minimizing risk—and information-seeking behavior—by minimizing ambiguity (to infer hidden states) and maximizing novelty (to learn about model parameters). This unified objective naturally promotes both exploitation and exploration. + +""" + +# ╔═╡ bed6a9bd-9bf8-4d7b-8ece-08c77fddb6d7 +md""" +# Active Inference +""" + +# ╔═╡ ef54a162-d0ba-47ef-af75-88c92276ed66 +md""" +## Optimal Planning by Variational Inference + +Assume that our agent is continually engaged in minimizing its variational free energy ``F[q]``, defined in Eq. (F2). This process tracks the following optimal posterior beliefs over policies, + +```math +\begin{align} +q^*(u) &\triangleq \arg\min_q F[q] \\ +&= \sigma\left( - G(u) -C(u) -P(u) \right) \,, \tag{Q*} +\end{align} +``` +where +- ``\sigma(\cdot)`` denotes the softmax function, +- ``G(u)`` is the expected free energy, defined in Eq. (G1), scoring both goal-directed and epistemic value of each policy, +- ``C(u) = \mathbb{E}_{q(y,x,\theta|u)}\Big[ \log \frac{q(y,x,\theta|u)}{p(y,x,\theta|u)}\Big]`` is a complexity term, capturing divergence between the variational posterior and prior beliefs for a given policy ``u``, +- ``P(u) = -\log p(u)`` reflects prior preferences over policies from the generative model. + +""" + +# ╔═╡ 94391132-dee6-4b22-9900-ba394f4ad66b +details(md"""Click for proof of ``q^*(u)``""", + md""" + Starting from Eq. (F2), + ```math + \begin{align} + F[q] &=\mathbb{E}_{q(u)}\left[ G(u)\right] + \mathbb{E}_{q(y,x,u,\theta)}\left[ \log \frac{q(y,x,u,\theta)}{p(y,x,u,\theta)}\right] \tag{F2} \\ + &=\mathbb{E}_{q(u)}\bigg[G(u) + \underbrace{\mathbb{E}_{q(y,x,\theta|u)}\Big[ \log \frac{q(y,x,\theta|u)}{p(y,x,\theta|u)}\Big]}_{C(u)} + \log \frac{q(u)}{p(u)} \bigg] \\ + &=\mathbb{E}_{q(u)}\bigg[ \log \frac{1}{\exp(-G(u))} + \log \frac{1}{\exp(-C(u))} + \log \frac{q(u)}{\exp(-P(u))} \Big] \bigg] \\ + &= \mathbb{E}_{q(u)}\bigg[ \log \frac{q(u)}{\exp(-G(u) - C(u) -P(u) )}\bigg] + \end{align} + ``` + which is (proportional to) a Kullback-Leibler divergence that is minimized for + ```math + \begin{align} + q^*(u) = \sigma\left(-G(u) - C(u) -P(u) \right) \,. + \end{align} + ``` + """) + +# ╔═╡ a8c88dff-b10c-4c25-8dbe-8f04ee04cffa +md""" +## An Active Inference Agent! + +Eq. (Q*) marks a central result: an agent that minimizes the variational free energy ``F[q]``, as defined in Eq.(F2), naturally selects policies that are goal-directed, epistemically valuable, and computationally parsimonious. +- Goal-directed policies **minimize risk** by steering predicted future states toward preferred or desired outcomes. +- Epistemically valuable policies reduce uncertainty by favoring informative observations (**low ambiguity**) and supporting model learning (**high novelty**). +- Computationally parsimonious policies **minimize complexity**, ensuring that posterior beliefs remain close to prior expectations. This limits the extent of belief updating, thereby *conserving computational resources* and reducing inference overhead. + +The process of minimizing ``F[q]`` is called an **Active Inference** (AIF) process, and an agent that realizes this process is referred to as an **active inference agent**. The “active” aspect highlights that an AIF agent does not passively consume a fixed data set, but instead actively selects its own data set through purposeful interaction with the environment. + +From an engineering perspective, if one accepts that effective decision-making systems should exhibit goal-directed behavior, epistemic exploration, and computational efficiency, then an AIF agent can be viewed as an "intelligent" controller. Given a well-defined set of predictive, goal-oriented, and epistemic prior beliefs, the agent’s behavior follows directly from the minimization of variational free energy. In this sense, the agent acts rationally—or Bayes-optimally—with respect to its design objectives and internal model. + +""" + +# ╔═╡ 63609dc2-2413-4822-8401-2d2ba22adfce +keyconcept("","The process underlying naturally intelligent behavior is termed **Active Inference** (AIF). It can be described as the minimization of a variational free energy under a generative model that incorporates a rollout into the future.") + +# ╔═╡ 5b66f8e5-4f01-4448-82e3-388bc8ea31de +md""" +## Interpretation of the Epistemic Priors + +In the formulation introduced in Eq. (E1), the epistemic prior +``\tilde{p}(u) = \exp\big(H[q(x | u)]\big)`` biases the agent toward selecting policies ``u`` that maximize the entropy of the predicted future states ``x``. + +This reflects an information-seeking preference: high entropy over future states implies that the agent is actively maintaining flexibility and postponing premature commitment. Rather than treating uncertainty as something to avoid, this formulation encourages the agent to seek out policies that enable adaptation as new observations arrive. + +Additionally, the epistemic prior ``\tilde{p}(x) = \exp(−H[q(y|x)])`` +in (E2), favors policies that reduce uncertainty about future states by +selecting observations that are informative about them. Together, ``\tilde{p}(u)`` and ``\tilde{p}(x)`` induce a **bias toward ambiguity-minimizing behavior**. + +Similarly, the epistemic priors ``\tilde{p}(u)`` and ``\tilde{p}(y,x)`` from (E1) and (E3), jointly shape a **preference for policies that maximize novelty**, i.e., that are expected to be informative about the parameters of the generative model. + +""" + +# ╔═╡ 65e34124-fda2-4a60-9722-ece2f68a39d9 +md""" +## Realization by Reactive Message Passing + +An AIF agent can be efficiently realized by an autonomous reactive message passing process in a Forney-style Factor Graph (FFG) representation of (a rollout to the future of) the generative model, augmented with goal and epistemic priors. +""" + +# ╔═╡ 6e14d8e3-9dc2-44fb-9fa5-c48f10cb1076 +Resource("https://github.com/bmlip/course/blob/v4/assets/figures/AIF-generative-model-as-FFG.png?raw=true", :alt => "FFG for an AIF agent", :style => "background: white; border-radius: 1em;") + +# ╔═╡ bece6e3d-57b2-4bf4-8bf8-d5a11ad8983f +md""" +In the above figure, the agent's generative (predictive) model +```math +\prod_{k=1}^T p(y_k|x_k) p(x_k|x_{k-1},u_k)\,, +``` +is represented by the white nodes in the factor graph. The initial and desired final states are constrained by initial and goal priors ``\hat{p}(x_0|x^+)`` and ``\hat{p}(x_T|x^+)``, which are typically generated by a higher-level state ``x^+`` and shown here as orange and blue nodes, respectively. + +At time ``k = 0``, the agent is tasked to infer a future action sequence (a "policy") ``u_{1:T}`` such that the posterior ``q(x_T|y_{1:T})`` matches the goal prior ``\hat{p}(x_T|x^+)`` as closely as possible. Inference proceeds entirely via reactive message passing in the factor graph, with no external control. + +The figure shows the state of the system at time ``t``, after having executed actions ``u_{1:t}`` and having observed ``y_{1:t}``. The future rollout for steps ``t+1`` to ``T`` terminates the predictive model (white) with both epistemic priors (green and red nodes) and the goal prior (blue node). As new actions are selected and new observations are sensed, the epistemic priors are replaced by posteriors (small black boxes), enabling an ongoing free energy minimization process. + +""" + +# ╔═╡ 64474167-bf52-456c-9099-def288bd17bf +challenge_solution("The Door-Key MiniGrid Problem", header_level=1,color="green") + +# ╔═╡ 2784f45e-d294-11ef-0439-1903016c1f14 +md""" + +We now return to the Door-Key MiniGrid problem from the [beginning of this lesson](#Challenge:-The-Door-Key-MiniGrid-Problem). Below, we present RxInfer pseudocode for the augmented generative model of the MiniGrid agent. The key insight from this code fragment is that there is no explicit “algorithmic” planning code: in an AIF agent, all processes reduce to VFE minimization (of [Eq. (F1)](#The-Expected-Free-Energy-Theorem)), which is carried out automatically by the RxInfer inference engine. + +*NB: A complete implementation of this solution is available [here](https://github.com/biaslab/EFEasVFE). Please note that the full code is a research prototype and not yet production-ready.* +""" + + + +# ╔═╡ 1f468b26-b4fe-4f61-af41-0a15fdc44365 +@model function minigrid_aif(prior_state, prior_key, prior_door, target_location, horizon, transition_params, observation_params) + initial_state ~ prior_state + key_location ~ prior_key + door_location ~ prior_door + + prev_state = initial_state + for t in 1:horizon + action[t] ~ ExplorationPrior() + state[t] ~ AmbiguityPrior() + state[t] ~ DiscreteTransition(prev_state, transition_params, key_location, door_location, action) + observation[t] ~ DiscreteTransition(state[t], observation_params, key_location, door_location) + end + state[end] ~ Goal(target_location) +end + +# ╔═╡ 8ac328de-b7ba-457f-add6-9af506832282 +md""" +The animation below is a recording of representative agent behavior during the VFE minimization process. Initially, the agent rotates to search for the key—an uncertainty-reducing strategy **driven by the ambiguity term** of the Expected Free Energy. Once the key’s location is revealed, the agent retrieves it and proceeds to the goal location. This constitutes goal-directed behavior that **minimizes the risk term** in the EFE. Because the environmental dynamics are assumed to be known, no novelty-driven exploration occurs in this example. +""" + +# ╔═╡ 651a4081-68f1-4237-9503-d4e28969a836 +Resource("https://github.com/bmlip/course/raw/refs/heads/main/assets/figures/minigrid%20loop.mp4", :autoplay => true, :loop=>true) + +# ╔═╡ f4509603-36be-4d24-8933-eb7a705eb933 +md""" +# Discussion +""" + +# ╔═╡ 8d7058c4-0e13-4d05-b131-32b1f118129f +md""" +The Free Energy Principle and active inference are deep and fast-moving areas of research. They bring fresh ideas to intelligent reasoning, control, and AI, with exciting applications in robotics, adaptive systems, cognitive modeling, and more. There’s a lot to unpack, but in this lecture, we’ve only had time to scratch the surface. To wrap up, we’ll end with a few closing thoughts. +""" + +# ╔═╡ 1c53d48b-6950-4921-bf03-292b5ed8980e +md""" +## Comparison Decision-theoretic vs Active Inference Agents + +The idea of framing decision-making and planning as the minimization of expected cost over future states has become foundational across many disciplines, including machine learning (e.g., reinforcement learning), control theory (e.g., model-predictive and optimal control), and economics (e.g., utility theory and operations research). In what follows, we will refer to such systems collectively as *decision-theoretic* (DT) agents. + +AIF agents fundamentally differ from DT agents in that variational free energy (VFE) minimization is the sole underlying process. As a result, policies are evaluated based on a function of beliefs about states, rather than directly on the states themselves. The FEP formally captures this distinction. + +From an engineering perspective, what is gained by moving from DT to AIF agents? While our treatment here is necessarily brief and not intended as a comprehensive academic assessment, several key advantages already stand out: + +- **A principled grounding in fundamental physics** + - If we aim to understand how brains—human or animal—give rise to intelligent behavior, we must start from the premise that they operate entirely within the laws of physics. The FEP is consistent with this physical grounding. + +- **Balanced goal-directed and information-seeking behavior** + - The epistemic components that emerge naturally from the EFE functional often need to be added through ad hoc mechanisms in decision-theoretic frameworks that do not explicitly score beliefs about future states. + +- **No need for task-specific reward (or value) functions** + - In DT agents, a recurring question is: where do the reward functions come from? These functions are typically hand-crafted. In an AIF agent, preferences are encoded as prior distributions over desired outcomes. These priors can be parameterized and updated through hyper-priors and Bayesian learning at higher levels of the generative model, allowing agents to adapt their preferences on the fly, rather than relying on externally specified reward functions. + +- **A universal cost function for all problems** + - A related limitation of the DT systems is that the value function must be specified anew for each problem. Brains, however, cannot afford to construct a different value function for every task, given that thousands of novel problems are encountered daily. In contrast, AIF agents employ the same free-energy functional ``F`` that measures the quality of the beliefs, for all problems. The structure of ``F`` (complexity minus accuracy) does not change and applies universally. + +- **AIF agents are explainable and trustworthy by nature** + - Explainability and trustworthiness are critical concerns in AI, for instance, in medical AI applications. An AIF agent’s reasoning process is Bayes-optimal, and therefore logically consistent and inherently *trustworthy*. Crucially, domain-specific knowledge and inference are cleanly separated: all domain-specific assumptions reside in the model. As a result, the agent’s behavior can be *explained* as the logical (Bayesian) consequence of its generative model. + +- **Robustness by realization as a reactive message passing process!** + - In contrast to decision-theoretic (DT) agents, an active inference (AIF) agent can be fully realized as a reactive variational message passing (RMP) process, since variational free energy (VFE) minimization is the only ongoing process. RMP is an event-driven, fully distributed process—both in time and space—that exhibits robustness to fluctuating computational resources. It “lands softly” when resources such as power, data, or time become limited. As a result, an AIF agent continues to function during power dips, handles missing or noisy observations gracefully, and can be interrupted at any time during decision-making without catastrophic failure, making it naturally suited for real-world, resource-constrained environments. + +- **Easy to code** + - Since VFE minimization can be automated by a toolbox, the engineer’s main task is to specify the generative model and priors, typically achievable within a single page of code. However, because a professional-level automated VFE minimization toolbox is not (yet) available, this “easy-to-code” feature has not (yet) been realized. + +- **Other advantages** + - Additional advantages include the potential for scalability, particularly in real-time applications. Realizing this potential will require further research into efficient, real-time message passing capabilities that are difficult to match in frameworks that cannot be implemented as reactive message passing processes. + +While the advantages listed above hold great promise for the future of synthetic AIF agents in solving complex engineering problems, it’s important to acknowledge current limitations. The vast majority of engineers and scientists have been trained within DT frameworks, and the **tooling and methodologies for DT agents are far more mature**. For many practical problems, several of the above-mentioned advantages of AIF agents have yet to be conclusively demonstrated in real-world applications. + + +""" + +# ╔═╡ e3b4d8cc-d028-4e00-b4f3-369f1601510d +keyconcept("","In principle, active inference offers a unified way to address several long-standing challenges faced by current approaches to agentic AI. In practice, however, the available toolboxes for active inference remain less mature than those for more conventional AI paradigms, such as deep learning, large language models, and reinforcement learning.") + +# ╔═╡ d823599e-a87f-4586-999f-fbbd99d0db65 +md""" +## The FEP: A New Frontier for Understanding Intelligent Behavior + + +The FEP is often misunderstood as a scientific theory that counterexamples can falsify. In reality, the **FEP is a principle**, a general modeling framework for describing the dynamics of systems that exhibit ("life-like") attractor dynamics, repeatedly returning to states that preserve their functional organization and structural integrity. According to the FEP, such systems can be interpreted as performing variational Bayesian inference in a generative model, where the goal priors correspond to the system’s attractors. + +In this lecture, we’ve seen how the FEP can be used to describe the dynamics of rational AI agents, but its reach goes far beyond AI and control. As a unifying framework for understanding adaptive self-organization, the FEP touches neuroscience, biology, cognition, and even physics. + +For example, the Expected Free Energy used to evaluate policies is not just an arbitrary cost function—it follows naturally from common assumptions in fundamental physics. EFE-based policy scoring also makes sense from a philosophical standpoint: if minimizing variational free energy is the only process driving the system, then it is a logical consequence to rank policies by how much VFE we expect them to minimize in the future. + +Looking ahead to the future of artificial intelligence, adaptive robotics, and agentic AI, the Free Energy Principle stands out as a framework with the potential to transform not only how we build intelligent systems, but how we fundamentally understand their nature, purpose, and place within the broader landscape of self-organizing life. + +""" + +# ╔═╡ df4950bc-4532-44e3-b8c7-18dd62fdfb09 +md""" +# Summary +""" + +# ╔═╡ c51232ba-9908-476a-949f-d5d0949d7960 +keyconceptsummary() + +# ╔═╡ aed24f2d-105e-4583-b9d6-24d1886002d8 +exercises(header_level=1) + +# ╔═╡ acefdbf6-1beb-4ce5-9106-0fc7be63dabe +md""" +There are no more exercises. If you understand the Free Energy Principle and active inference, you now hold a lens for seeing into the mechanics of life, consciousness, and intelligent behavior. The next insights are yours to discover. +""" + +# ╔═╡ 6d697856-cc58-4d6a-afd3-c0c6bfbc0d88 +md""" +# Optional Slides +""" + +# ╔═╡ 8627b90a-79d8-43bf-8d53-1043f6e816ab +md""" + +## The FEP is a Least Action Principle for "Things" + +Almost all of physics can be described as processes that minimize energy differences. This is formalized in the celebrated [Principle of Least Action](https://en.wikipedia.org/wiki/Action_principles) (PLA). + +For example, Newton’s second law ``F = ma`` [can be derived from minimizing the "action"](https://vixra.org/pdf/2501.0036v1.pdf)—the time integral of the difference between kinetic and potential energy for a particle. Many branches of physics that describe motion can be formulated through similar derivations. + +""" + +# ╔═╡ 58c51f5e-69a0-4802-892b-0a52462c4e55 +Resource("https://github.com/bmlip/course/blob/v4/assets/figures/FEP.png?raw=true", :style => "background: white; border-radius: 1em;") + +# ╔═╡ 14ef2403-cba3-4e76-91c7-4655656a632d +md""" + +The Free Energy Principle (FEP) can be viewed as a kind of PLA as well—one that governs the necessary “motion” of beliefs (ie, necessary information processing) in systems that maintain their structural and functional integrity over time. All living systems fall under its scope. + +""" + +# ╔═╡ 54cc2500-f06f-4f39-95f3-8d9d09c37234 +md""" +## Active Inference and The Scientific Inquiry Loop + +In the [Machine Learning Overview lecture](https://bmlip.github.io/course/lectures/Machine%20Learning%20Overview.html), we introduced a picture illustrating the [Scientific Inquiry Loop](https://bmlip.github.io/course/lectures/Machine%20Learning%20Overview.html#Machine-Learning-and-the-Scientific-Inquiry-Loop). + +Active inference completes this “scientific loop” as a fully variational inference process. Under the FEP, all processes, including state updating, learning, and trial design (in living systems: perception, learning, and control/behavior, respectively) are driven by VFE minimization. Bayesian probability theory, together with the FEP, provides all the equations needed to run the process of scientific inquiry. + +The figure below illustrates this process. We do not depict the epistemic priors as an external input, since they can be computed internally by the agent itself. +""" + +# ╔═╡ b900b7d4-3a49-4651-a94b-74fdbbf094d9 +Resource("https://github.com/bmlip/course/blob/v4/assets/figures/AIF-agent-loop.png?raw=true", :style => "background: white; border-radius: 1em;") + +# ╔═╡ cd2dafbe-5131-4ee0-8eb7-33bd04f3133f +md""" +If an agent has no goal priors, then active inference reduces to an automated (Bayes-optimal) scientist: the agent’s generative model will converge to a veridical (“true”) description of the environment. With goal priors, however, an active inference agent becomes a (Bayes-optimal) engineer: its model converges to beliefs that generate purposeful behavior. For example, the goal prior “I will not get hit by a car” leads to the inference of actions that allow safe crossing of the road. In the same way, carefully structured goal priors enable the brain to develop solutions for tasks such as object recognition, locomotion, and speech generation. + +In short, **AIF is an automated (Bayes-optimal) engineering design loop**. + +The challenge is computational efficiency: the human brain runs on about 20 [W], with the neocortex using just 4 [W], roughly the power of a bicycle light, yet performs tasks that would consume millions of times more power on current silicon hardware. + +""" + +# ╔═╡ be0dc5c0-6340-4d47-85ae-d70e06df1676 +md""" +# Code +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +RxInfer = "86711068-29c9-4ff7-b620-ae75d7495b3d" + +[compat] +BmlipTeachingTools = "~1.3.1" +RxInfer = "~4.6.2" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "86b15ea5fe65fe39dea8ac5342d4e576fcb3219b" + +[[deps.ADTypes]] +git-tree-sha1 = "27cecae79e5cc9935255f90c53bb831cc3c870d7" +uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +version = "1.18.0" + + [deps.ADTypes.extensions] + ADTypesChainRulesCoreExt = "ChainRulesCore" + ADTypesConstructionBaseExt = "ConstructionBase" + ADTypesEnzymeCoreExt = "EnzymeCore" + + [deps.ADTypes.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.4.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.4.0" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "d2cd034553ee6ca084edaaf8ed6c9d50fd01555d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.21.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceMetalExt = "Metal" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.ArrayLayouts]] +deps = ["FillArrays", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "355ab2d61069927d4247cd69ad0e1f140b31e30d" +uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +version = "1.12.0" +weakdeps = ["SparseArrays"] + + [deps.ArrayLayouts.extensions] + ArrayLayoutsSparseArraysExt = "SparseArrays" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BayesBase]] +deps = ["Distributions", "DomainSets", "LinearAlgebra", "Random", "SpecialFunctions", "StaticArrays", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "TinyHugeNumbers"] +git-tree-sha1 = "5b723bf6b1081cab4d263e425be097224e0f434f" +uuid = "b4ee3484-f114-42fe-b91c-797d54a0c67e" +version = "1.5.8" +weakdeps = ["FastCholesky"] + + [deps.BayesBase.extensions] + FastCholeskyExt = "FastCholesky" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BitSetTuples]] +deps = ["TupleTools"] +git-tree-sha1 = "aa19428fb6ad21db22f8568f068de4f443d3bacc" +uuid = "0f2f92aa-23a3-4d05-b791-88071d064721" +version = "1.1.5" + +[[deps.BlockArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra"] +git-tree-sha1 = "79e651aa489a7879107d66e3d1948e9aa1b4055e" +uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" +version = "1.7.2" + + [deps.BlockArrays.extensions] + BlockArraysAdaptExt = "Adapt" + BlockArraysBandedMatricesExt = "BandedMatrices" + + [deps.BlockArrays.weakdeps] + Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.ChunkCodecCore]] +git-tree-sha1 = "51f4c10ee01bda57371e977931de39ee0f0cdb3e" +uuid = "0b6fb165-00bc-4d37-ab8b-79f91016dbe1" +version = "1.0.0" + +[[deps.ChunkCodecLibZlib]] +deps = ["ChunkCodecCore", "Zlib_jll"] +git-tree-sha1 = "cee8104904c53d39eb94fd06cbe60cb5acde7177" +uuid = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" +version = "1.0.0" + +[[deps.ChunkCodecLibZstd]] +deps = ["ChunkCodecCore", "Zstd_jll"] +git-tree-sha1 = "34d9873079e4cb3d0c62926a225136824677073f" +uuid = "55437552-ac27-4d47-9aa3-63184e8fd398" +version = "1.0.0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.Combinatorics]] +git-tree-sha1 = "8010b6bb3388abe68d95743dcbea77650bb2eddf" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.3" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.1" + +[[deps.CommonWorldInvalidations]] +git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" +uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" +version = "1.0.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.CompositeTypes]] +git-tree-sha1 = "bce26c3dab336582805503bed209faab1c279768" +uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657" +version = "0.1.4" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" +weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dictionaries]] +deps = ["Indexing", "Random", "Serialization"] +git-tree-sha1 = "a86af9c4c4f33e16a2b2ff43c2113b2f390081fa" +uuid = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" +version = "0.4.5" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DifferentiationInterface]] +deps = ["ADTypes", "LinearAlgebra"] +git-tree-sha1 = "529bebbc74b36a4cfea09dd2aecb1288cd713a6d" +uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" +version = "0.7.9" + + [deps.DifferentiationInterface.extensions] + DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" + DifferentiationInterfaceDiffractorExt = "Diffractor" + DifferentiationInterfaceEnzymeExt = ["EnzymeCore", "Enzyme"] + DifferentiationInterfaceFastDifferentiationExt = "FastDifferentiation" + DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" + DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" + DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] + DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" + DifferentiationInterfaceGTPSAExt = "GTPSA" + DifferentiationInterfaceMooncakeExt = "Mooncake" + DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] + DifferentiationInterfaceReverseDiffExt = ["ReverseDiff", "DiffResults"] + DifferentiationInterfaceSparseArraysExt = "SparseArrays" + DifferentiationInterfaceSparseConnectivityTracerExt = "SparseConnectivityTracer" + DifferentiationInterfaceSparseMatrixColoringsExt = "SparseMatrixColorings" + DifferentiationInterfaceStaticArraysExt = "StaticArrays" + DifferentiationInterfaceSymbolicsExt = "Symbolics" + DifferentiationInterfaceTrackerExt = "Tracker" + DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] + + [deps.DifferentiationInterface.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" + Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + FastDifferentiation = "eb9bf01b-bf85-4b60-bf87-ee5de06c00be" + FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" + Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" + SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.DomainIntegrals]] +deps = ["CompositeTypes", "DomainSets", "FastGaussQuadrature", "GaussQuadrature", "HCubature", "IntervalSets", "LinearAlgebra", "QuadGK", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "934bf806ef2948114243f25e84a3ddf775d0f1a6" +uuid = "cc6bae93-f070-4015-88fd-838f9505a86c" +version = "0.5.2" + +[[deps.DomainSets]] +deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "c249d86e97a7e8398ce2068dce4c078a1c3464de" +uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" +version = "0.7.16" + + [deps.DomainSets.extensions] + DomainSetsMakieExt = "Makie" + DomainSetsRandomExt = "Random" + + [deps.DomainSets.weakdeps] + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EnumX]] +git-tree-sha1 = "bddad79635af6aec424f53ed8aad5d7555dc6f00" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.5" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.ExponentialFamily]] +deps = ["BayesBase", "BlockArrays", "Distributions", "DomainSets", "FastCholesky", "FillArrays", "ForwardDiff", "HCubature", "HypergeometricFunctions", "IntervalSets", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "PositiveFactorizations", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "StatsBase", "StatsFuns", "TinyHugeNumbers"] +git-tree-sha1 = "8351e116e111c97ad57718851da00ae5a5f92e0c" +uuid = "62312e5e-252a-4322-ace9-a5f4bf9b357b" +version = "2.1.1" + +[[deps.FastCholesky]] +deps = ["LinearAlgebra", "PositiveFactorizations"] +git-tree-sha1 = "1c0a81e006e40e9fcbd5f6f6cb42ac2700f86889" +uuid = "2d5283b6-8564-42b6-bb00-83ed8e915756" +version = "1.4.3" +weakdeps = ["StaticArraysCore"] + + [deps.FastCholesky.extensions] + StaticArraysCoreExt = "StaticArraysCore" + +[[deps.FastGaussQuadrature]] +deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "0044e9f5e49a57e88205e8f30ab73928b05fe5b6" +uuid = "442a2c76-b920-505d-bb47-c5924d526838" +version = "1.1.0" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "d60eb76f37d7e5a40cc2e7c36974d864b82dc802" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.17.1" +weakdeps = ["HTTP"] + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] +git-tree-sha1 = "9340ca07ca27093ff68418b7558ca37b05f8aeb1" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.29.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffSparseArraysExt = "SparseArrays" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedArguments]] +deps = ["TupleTools"] +git-tree-sha1 = "befa1ad59c77643dec6fc20d71fd6f5c3afcdadd" +uuid = "4130a065-6d82-41fe-881e-7a5c65156f7d" +version = "0.1.1" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "ba6ce081425d0afb2bedd00d9884464f764a9225" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.2.2" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" +version = "1.11.0" + +[[deps.GaussQuadrature]] +deps = ["SpecialFunctions"] +git-tree-sha1 = "eb6f1f48aa994f3018cbd029a17863c6535a266d" +uuid = "d54b0c1a-921d-58e0-8e36-89d8069c0969" +version = "0.5.8" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.GraphPPL]] +deps = ["BitSetTuples", "DataStructures", "Dictionaries", "MacroTools", "MetaGraphsNext", "NamedTupleTools", "Static", "StaticArrays", "TupleTools", "Unrolled"] +git-tree-sha1 = "db4aece54ddddaa9e8d2880eb7cfc6f29bd1a650" +uuid = "b3f8163a-e979-4e85-b43e-1f63d8c8b42c" +version = "4.6.5" + + [deps.GraphPPL.extensions] + GraphPPLDistributionsExt = "Distributions" + GraphPPLGraphVizExt = "GraphViz" + GraphPPLPlottingExt = ["Cairo", "GraphPlot"] + + [deps.GraphPPL.weakdeps] + Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" + Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" + GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231" + GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0" + +[[deps.Graphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "7a98c6502f4632dbe9fb1973a4244eaa3324e84d" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.13.1" + +[[deps.HCubature]] +deps = ["Combinatorics", "DataStructures", "LinearAlgebra", "QuadGK", "StaticArrays"] +git-tree-sha1 = "19ef9f0cb324eed957b7fe7257ac84e8ed8a48ec" +uuid = "19dc6840-f33b-545b-b366-655c7e3ffd49" +version = "1.7.0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HashArrayMappedTries]] +git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" +uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" +version = "0.2.0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.Indexing]] +git-tree-sha1 = "ce1566720fd6b19ff3411404d4b977acd4814f9f" +uuid = "313cdc1a-70c2-5d6a-ae34-0150d3930a38" +version = "1.1.1" + +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.IntervalSets]] +git-tree-sha1 = "5fbb102dcb8b1a858111ae81d56682376130517d" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.11" + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + + [deps.IntervalSets.weakdeps] + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.JLD2]] +deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] +git-tree-sha1 = "da2e9b4d1abbebdcca0aa68afa0aa272102baad7" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.6.2" +weakdeps = ["UnPack"] + + [deps.JLD2.extensions] + UnPackExt = "UnPack" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LazyArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "SparseArrays"] +git-tree-sha1 = "79ee64f6ba0a5a49930f51c86f60d7526b5e12c8" +uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" +version = "2.8.0" + + [deps.LazyArrays.extensions] + LazyArraysBandedMatricesExt = "BandedMatrices" + LazyArraysBlockArraysExt = "BlockArrays" + LazyArraysBlockBandedMatricesExt = "BlockBandedMatrices" + LazyArraysStaticArraysExt = "StaticArrays" + + [deps.LazyArrays.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.4.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MatrixCorrectionTools]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "73f93b21eae5714c282396bfae9d9f13d6ad04b6" +uuid = "41f81499-25de-46de-b591-c3cfc21e9eaf" +version = "1.2.0" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.MetaGraphsNext]] +deps = ["Graphs", "JLD2", "SimpleTraits"] +git-tree-sha1 = "c3f7e597f1cf5fe04e68e7907af47f055cad211c" +uuid = "fa8bd995-216d-47f1-8a91-f3b68fbeb377" +version = "0.7.4" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NLSolversBase]] +deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.10.0" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NamedTupleTools]] +git-tree-sha1 = "90914795fc59df44120fe3fff6742bb0d7adb1d0" +uuid = "d9ec5142-1e00-5aa0-9d6a-321866360f50" +version = "0.14.3" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Optim]] +deps = ["Compat", "EnumX", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "61942645c38dd2b5b78e2082c9b51ab315315d10" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.13.2" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" + + [deps.Pkg.extensions] + REPLExt = "REPL" + + [deps.Pkg.weakdeps] + REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PolyaGammaHybridSamplers]] +deps = ["Distributions", "Random", "SpecialFunctions", "StatsFuns"] +git-tree-sha1 = "9f6139650ff57f9d8528cd809ebc604c7e9738b1" +uuid = "c636ee4f-4591-4d8c-9fae-2dea21daa433" +version = "1.2.6" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "fbb92c6c56b34e1a2c4c36058f68f332bec840e7" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.ReactiveMP]] +deps = ["BayesBase", "DataStructures", "DiffResults", "Distributions", "DomainIntegrals", "DomainSets", "ExponentialFamily", "FastCholesky", "FastGaussQuadrature", "FixedArguments", "ForwardDiff", "HCubature", "LazyArrays", "LinearAlgebra", "MacroTools", "MatrixCorrectionTools", "Optim", "PolyaGammaHybridSamplers", "PositiveFactorizations", "Random", "Rocket", "SpecialFunctions", "StaticArrays", "StatsBase", "StatsFuns", "TinyHugeNumbers", "Tullio", "TupleTools", "Unrolled"] +git-tree-sha1 = "dcd2f85ba9f2f7be1b1b31708db889d078b161f6" +uuid = "a194aa59-28ba-4574-a09c-4a745416d6e3" +version = "5.6.2" + + [deps.ReactiveMP.extensions] + ReactiveMPOptimisersExt = "Optimisers" + ReactiveMPProjectionExt = "ExponentialFamilyProjection" + ReactiveMPRequiresExt = "Requires" + + [deps.ReactiveMP.weakdeps] + ExponentialFamilyProjection = "17f509fa-9a96-44ba-99b2-1c5f01f0931b" + Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.Rocket]] +deps = ["DataStructures", "Sockets", "Unrolled"] +git-tree-sha1 = "fe7373bf6b935c4431002fd91fa581d5eb835d09" +uuid = "df971d30-c9d6-4b37-b8ff-e965b2cb3a40" +version = "1.8.3" + +[[deps.RxInfer]] +deps = ["BayesBase", "DataStructures", "Dates", "Distributions", "DomainSets", "ExponentialFamily", "FastCholesky", "GraphPPL", "HTTP", "JSON", "LinearAlgebra", "Logging", "MacroTools", "Optim", "Preferences", "ProgressMeter", "Random", "ReactiveMP", "Reexport", "Rocket", "Static", "Statistics", "TupleTools", "UUIDs"] +git-tree-sha1 = "bcaf218d6b5329dc5e5be4299cbb5818c2c7bb19" +uuid = "86711068-29c9-4ff7-b620-ae75d7495b3d" +version = "4.6.2" + + [deps.RxInfer.extensions] + PrettyTablesExt = "PrettyTables" + ProjectionExt = "ExponentialFamilyProjection" + + [deps.RxInfer.weakdeps] + ExponentialFamilyProjection = "17f509fa-9a96-44ba-99b2-1c5f01f0931b" + PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SciMLPublic]] +git-tree-sha1 = "ed647f161e8b3f2973f24979ec074e8d084f1bee" +uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" +version = "1.0.0" + +[[deps.ScopedValues]] +deps = ["HashArrayMappedTries", "Logging"] +git-tree-sha1 = "c3b2323466378a2ba15bea4b2f73b081e022f473" +uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" +version = "1.5.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.2" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.5" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] +git-tree-sha1 = "49440414711eddc7227724ae6e570c7d5559a086" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.3.1" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.15" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TinyHugeNumbers]] +git-tree-sha1 = "83c6abf376718345a85c071b249ef6692a8936d4" +uuid = "783c9a47-75a3-44ac-a16b-f1ab7b3acf04" +version = "1.0.3" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.Tullio]] +deps = ["DiffRules", "LinearAlgebra", "Requires"] +git-tree-sha1 = "972698b132b9df8791ae74aa547268e977b55f68" +uuid = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc" +version = "0.3.8" + + [deps.Tullio.extensions] + TullioCUDAExt = "CUDA" + TullioChainRulesCoreExt = "ChainRulesCore" + TullioFillArraysExt = "FillArrays" + TullioTrackerExt = "Tracker" + + [deps.Tullio.weakdeps] + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.TupleTools]] +git-tree-sha1 = "41e43b9dc950775eac654b9f845c839cd2f1821e" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.6.0" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.Unrolled]] +deps = ["MacroTools"] +git-tree-sha1 = "6cc9d682755680e0f0be87c56392b7651efc2c7b" +uuid = "9602ed7d-8fef-5bc8-8597-8f21381861e8" +version = "0.1.5" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" +""" + +# ╔═╡ Cell order: +# ╟─278382c0-d294-11ef-022f-0d78e9e2d04c +# ╟─9fbae8bf-2132-4a9a-ab0b-ef99e1b954a4 +# ╟─27839788-d294-11ef-30a2-8ff6357aa68b +# ╟─2783a99e-d294-11ef-3163-bb455746bf52 +# ╟─aed436fd-6773-4932-a5d8-d01cf99c10ec +# ╟─983873d0-e1bc-4e1b-9b6c-3df0a17d83f6 +# ╟─2783b312-d294-11ef-2ebb-e5ede7a86583 +# ╟─939e74b0-8ceb-4214-bbc0-407c8f0b2f26 +# ╟─e3d5786b-49e0-40f7-9056-13e26e09a4cf +# ╟─2f38a3c9-67d4-4c45-ad0b-e757f62d6a5e +# ╟─4ed2ef1f-4d55-4f9b-b8f5-7f77b5fc62ca +# ╟─2783c686-d294-11ef-3942-c75d2b559fb3 +# ╟─126c3221-34b8-4a8f-b5b5-c14ff4c6a2a1 +# ╟─29592915-cadf-4674-958b-5743a8f73a8b +# ╟─5b8405f7-8878-43dd-8f84-bca17450924f +# ╟─9708215c-72c9-408f-bd10-68ae02e17243 +# ╟─f9b241fd-d853-433e-9996-41d8a60ed9e8 +# ╟─97136f81-3468-439a-8a22-5aae96725937 +# ╟─4e990b76-a2fa-49e6-8392-11f98d769ca8 +# ╟─aaa07dc5-9105-4f70-b924-6e51e5c36600 +# ╟─aec84a6d-33fc-4541-80c0-091998f8c4d1 +# ╟─bed6a9bd-9bf8-4d7b-8ece-08c77fddb6d7 +# ╟─ef54a162-d0ba-47ef-af75-88c92276ed66 +# ╟─94391132-dee6-4b22-9900-ba394f4ad66b +# ╟─a8c88dff-b10c-4c25-8dbe-8f04ee04cffa +# ╟─63609dc2-2413-4822-8401-2d2ba22adfce +# ╟─5b66f8e5-4f01-4448-82e3-388bc8ea31de +# ╟─65e34124-fda2-4a60-9722-ece2f68a39d9 +# ╟─6e14d8e3-9dc2-44fb-9fa5-c48f10cb1076 +# ╟─bece6e3d-57b2-4bf4-8bf8-d5a11ad8983f +# ╟─64474167-bf52-456c-9099-def288bd17bf +# ╟─2784f45e-d294-11ef-0439-1903016c1f14 +# ╠═0b5b816b-2dd2-4fe8-8f84-4eb2d58b5d59 +# ╠═1f468b26-b4fe-4f61-af41-0a15fdc44365 +# ╟─8ac328de-b7ba-457f-add6-9af506832282 +# ╟─651a4081-68f1-4237-9503-d4e28969a836 +# ╟─f4509603-36be-4d24-8933-eb7a705eb933 +# ╟─8d7058c4-0e13-4d05-b131-32b1f118129f +# ╟─1c53d48b-6950-4921-bf03-292b5ed8980e +# ╟─e3b4d8cc-d028-4e00-b4f3-369f1601510d +# ╟─d823599e-a87f-4586-999f-fbbd99d0db65 +# ╟─df4950bc-4532-44e3-b8c7-18dd62fdfb09 +# ╟─c51232ba-9908-476a-949f-d5d0949d7960 +# ╟─aed24f2d-105e-4583-b9d6-24d1886002d8 +# ╟─acefdbf6-1beb-4ce5-9106-0fc7be63dabe +# ╟─6d697856-cc58-4d6a-afd3-c0c6bfbc0d88 +# ╟─8627b90a-79d8-43bf-8d53-1043f6e816ab +# ╟─58c51f5e-69a0-4802-892b-0a52462c4e55 +# ╟─14ef2403-cba3-4e76-91c7-4655656a632d +# ╟─54cc2500-f06f-4f39-95f3-8d9d09c37234 +# ╟─b900b7d4-3a49-4651-a94b-74fdbbf094d9 +# ╟─cd2dafbe-5131-4ee0-8eb7-33bd04f3133f +# ╟─be0dc5c0-6340-4d47-85ae-d70e06df1676 +# ╠═97a0384a-0596-4714-a3fc-bf422aed4474 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/Latent Variable Models and VB.jl b/mlss/Latent Variable Models and VB.jl new file mode 100644 index 00000000..f7e592b5 --- /dev/null +++ b/mlss/Latent Variable Models and VB.jl @@ -0,0 +1,3479 @@ +### A Pluto.jl notebook ### +# v0.20.20 + +#> [frontmatter] +#> image = "https://imgur.com/oS96z4w.png" +#> language = "en-US" +#> title = "Latent Variable Models and Variational Bayes" +#> description = "Introduction to latent variable models and variational inference via free energy minimization." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ df171940-eb54-48e2-a2b8-1a8162cabf3e +using BmlipTeachingTools + +# ╔═╡ c90176ea-918b-4643-a10f-cef277c5ea75 +using LinearAlgebra, PDMats, SpecialFunctions, Random + +# ╔═╡ 58bd0d43-743c-4745-b353-4a89b35e85ba +using Distributions, Plots, StatsPlots + +# ╔═╡ 26c56fd8-d294-11ef-236d-81deef63f37c +title("Latent Variable Models and Variational Bayes") + +# ╔═╡ ce7d086b-ff20-4da1-a4e8-52b5b7dc9e2b +PlutoUI.TableOfContents() + +# ╔═╡ 26c58298-d294-11ef-2a53-2b42b48e0725 +md""" +## Preliminaries + +##### Goal + + * Introduction to latent variable models and variational inference by Free energy minimization + +##### Materials + + * Mandatory + + * These lecture notes + * Optional + + * Bishop (2016), [PRML book](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf), pp. 461-486 (sections 10.1, 10.2 and 10.3) + * Ariel Caticha (2010), [Entropic Inference](https://arxiv.org/abs/1011.0723) + + * tutorial on entropic inference, which is a generalization to Bayes rule and provides a foundation for variational inference. + * references $(HTML("")) + + * Blei et al. (2017), [Variational Inference: A Review for Statisticians](https://doi.org/10.1080/01621459.2017.1285773) + * Lanczos (1961), [The variational principles of mechanics](https://www.amazon.com/Variational-Principles-Mechanics-Dover-Physics/dp/0486650677) + * Senoz et al. (2021), [Variational Message Passing and Local Constraint Manipulation in Factor Graphs](https://research.tue.nl/nl/publications/variational-message-passing-and-local-constraint-manipulation-in-) + * Dauwels (2007), [On variational message passing on factor graphs](https://github.com/bmlip/course/blob/main/assets/files/Dauwels-2007-on-variational-message-passing-on-factor-graphs.pdf) + * Shore and Johnson (1980), [Axiomatic Derivation of the Principle of Maximum Entropy and the Principle of Minimum Cross-Entropy](https://github.com/bmlip/course/blob/main/assets/files/ShoreJohnson-1980-Axiomatic-Derivation-of-the-Principle-of-Maximum-Entropy.pdf) + +""" + +# ╔═╡ 2497529b-7703-4e3e-b9db-83f8dbf43fa8 +challenge_statement("Density Modeling for the Old Faithful Data Set", color="red", header_level=1) + + +# ╔═╡ a663d6d1-2d73-40c6-8a4c-9e41df74bc84 +md""" + + +You are asked to build a density model for a data set ([Old Faithful](https://en.wikipedia.org/wiki/Old_Faithful), Bishop pg. 681) that clearly is not distributed as a single Gaussian: + +""" + +# ╔═╡ f8c8013a-3e87-4d01-a3ae-86b39cf1f002 +md""" +# The Gaussian Mixture Model +""" + +# ╔═╡ 26c59b52-d294-11ef-1eba-d3f235f85eee +md""" +## Unobserved Classes + +Consider again a set of observed data ``D=\{x_1,\dotsc,x_N\}``. + +This time, we suspect that there are *unobserved* class labels that would help explain (or predict) the data, e.g., + + * the observed data are the color of living things; the unobserved classes are animals and plants. + * observed are wheel sizes; unobserved categories are trucks and personal cars. + * observed is an audio signal; unobserved classes include speech, music, traffic noise, etc. + +""" + +# ╔═╡ 26c5a1f6-d294-11ef-3565-39d027843fbb +md""" +Classification problems with unobserved classes are called **Clustering** problems. In clustering problems, the learning algorithm needs to *discover the underlying classes from the observed data*. + +""" + +# ╔═╡ 26c5a93a-d294-11ef-23a1-cbcf0c370fc9 +md""" +## The Gaussian Mixture Model + +The spread of the data in the Old Faithful data set looks like it could be modeled by two Gaussians. Let's develop a model for this data set. + +""" + +# ╔═╡ 26c5b896-d294-11ef-1d8e-0feb99d2d45b +md""" + +We associate a one-hot coded hidden class label ``z_n`` with each observation ``x_n``: + +```math +\begin{equation*} +z_{nk} = \begin{cases} 1 & \text{if } x_n \in \mathcal{C}_k \text{ (the $k$-th class)}\\ + 0 & \text{otherwise} \end{cases} +\end{equation*} +``` + +""" + +# ╔═╡ 26c5c1ae-d294-11ef-15c6-13cae5bc0dc8 +md""" +We consider the same model as we did in the [generative classification lesson](https://bmlip.github.io/course/lectures/Generative%20Classification.html#Model-Specification): the data for each class is distributed as a Gaussian: + +```math +\begin{align*} +p(x_n | z_{nk}=1) &= \mathcal{N}\left( x_n | \mu_k, \Sigma_k\right)\\ +p(z_{nk}=1) &= \pi_k +\end{align*} +``` + +which can be summarized with the selection variables ``z_{nk}`` as + +```math +\begin{align*} +p(x_n,z_n) &= \prod_{k=1}^K (\underbrace{\pi_k \cdot \mathcal{N}\left( x_n | \mu_k, \Sigma_k\right) }_{p(x_n,z_{nk}=1)})^{z_{nk}} +\end{align*} +``` + +*Again*, this is the same model as we defined for the generative classification model: A Gaussian-Categorical model but now with unobserved classes. + +This model (with **unobserved class labels**) is known as a **Gaussian Mixture Model** (GMM). + +""" + +# ╔═╡ dff0212b-f3e8-4592-8cd4-f52bcdb782fb +keyconcept("", +md""" +A **Gaussian Mixture Model** has the same form as the Gaussian-Categorical model, + +```math +\begin{align} +p(x_n | z_{nk}=1) &= \mathcal{N}\left( x_n | \mu_k, \Sigma_k\right)\\ +p(z_{nk}=1) &= \pi_k +\end{align} +``` +but now the class labels ``z_{nk}`` are *unobserved* in the data set. A model with unobserved ("latent") variables is referred to as a **latent variable model**. +""") + +# ╔═╡ 26c5cfb4-d294-11ef-05bb-59d5e27cf37c +md""" +## The Marginal Distribution for the GMM + +In the literature, the GMM is often introduced by the marginal distribution for an *observed* data point ``x_n``, given by + +```math +\begin{align*}{} +p(x_n) &= \sum_{z_n} p(x_n,z_n) \\ + &= \sum_{k=1}^K \pi_k \cdot \mathcal{N}\left( x_n | \mu_k, \Sigma_k \right) \tag{B-9.12} +\end{align*} +``` + + +""" + +# ╔═╡ c7351bf1-447e-475b-8965-d259c01bfd57 +hide_proof( +md""" + +```math +\begin{align} +p(x_n) &= \sum_{z_n} p(x_n,z_n) \\ + &= \sum_{z_n} \prod_{k=1}^K \left(\pi_k \cdot \mathcal{N}\left( x_n | \mu_k, \Sigma_k\right) \right)^{z_{nk}} \\ +&= \sum_{j=1}^K \prod_{k=1}^K \left( \pi_k \cdot \mathcal{N}\left( x_n | \mu_k, \Sigma_k\right) \right)^{I_{kj}} \;\; \text{(use }z_n \text{ is one-hot coded)}\\ +&= \sum_{j=1}^K \pi_j \cdot \mathcal{N}\left( x_n | \mu_j, \Sigma_j\right) + \end{align} +``` + +where ``I_{kj} = 1`` if ``k=j`` and ``0`` otherwise. + +""") + +# ╔═╡ 3deadfd0-9fbb-476a-a7de-5dd694e55a65 +md""" + + +Eq. B-9.12 reveals the link to the name Gaussian *mixture model*. The priors ``\pi_k`` for the ``k``-th class are also called **mixture coefficients**. + +Be aware that Eq. B-9.12 is not the generative model for the GMM! The generative model is the joint distribution ``p(x,z,\pi,\mu,\Sigma)`` over all variables, including the latent variables. +""" + +# ╔═╡ 26c5d734-d294-11ef-20a3-afd2c3324323 +md""" +## GMM is a Flexible Model + +GMMs are very popular models. They have decent computational properties and are **universal approximators of densities** (as long as there are enough Gaussians, of course). + +![](https://github.com/bmlip/course/blob/v2/assets/figures/fig-ZoubinG-GMM-universal-approximation.png?raw=true) + +(In the above figure, the Gaussian components are shown in $(html"red") and the pdf of the mixture models in $(html"blue")). + +""" + +# ╔═╡ 26c5f8d6-d294-11ef-3bcd-4d5e0391698d +md""" +## Latent Variable Models + +A GMM contains both **observed** variables ``\{x_n\}``, and **unobserved** variables, namely unobserved (synonym: latent, hidden) parameters ``\theta= \{\pi_k,\mu_k, \Sigma_k\}`` and unobserved class labels ``\{z_{nk}\}``. + +From a Bayesian viewpoint, both the class labels ``\{z_{nk}\}`` and the parameters ``\theta`` are just unobserved variables for which we can set a prior and compute a posterior by Bayes rule. + +Note that ``z_{nk}`` carries a subscript ``n``, indicating that its value depends not only on the class index ``k``, but also on the specific observation ``n``. This contrasts with global model parameters ``\theta``, which are shared across all data points. + +Observation-specific latent variables can be a powerful modeling tool for capturing additional structure in the data, particularly information about the hidden causes of individual observations. In the case of the Gaussian Mixture Model (GMM), the latent variables ``z_{nk}`` represent unobserved class memberships, specifying which component generated each data point. + +Models that incorporate unobserved variables, often specific to each observation, are broadly known as **Latent Variable Models** (LVMs). These latent variables help explain the hidden structure or generative process underlying the observed data. + +By adding model structure through (equations among) observation-dependent latent variables, we can often build more accurate models for very complex processes. Unfortunately, adding structure through observation-dependent latent variables in models is also often accompanied by a more complex inference task. + +""" + +# ╔═╡ 26c623f6-d294-11ef-13c0-19edd43592c0 +md""" +## Inference for GMM is Difficult + +Indeed, the fact that the observation-dependent class labels are *unobserved* for the GMM, leads to a problem for processing new data by Bayes rule in a GMM. + +Consider a given data set ``D = \{x_1,x_2,\ldots,x_N\}``. We recall here the log-likelihood for the Gaussian-Categorial Model, see the [generative classification lesson](https://bmlip.github.io/course/lectures/Generative%20Classification.html): + +```math +\log\, p(D|\theta) = \sum_{n,k} y_{nk} \underbrace{ \log\mathcal{N}(x_n|\mu_k,\Sigma) }_{ \text{Gaussian} } + \underbrace{ \sum_{n,k} y_{nk} \log \pi_k }_{ \text{multinomial} } \,. +``` + +""" + +# ╔═╡ 26c62ebe-d294-11ef-0cfb-ef186203e890 +md""" +Since the class labels ``y_{nk} \in \{0,1\}`` were assumed to be given by the data set, maximization of this expression decomposed into a set of simple update rules for the Gaussian and multinomial distributions. + +""" + +# ╔═╡ 26c6347c-d294-11ef-056f-7b78a9e22272 +md""" +However, for the Gaussian mixture model (same log-likelihood function with ``z_{nk}`` replacing ``y_{nk}``), the class labels ``\{z_{nk}\}`` are *unobserved* and they need to be estimated alongside with the parameters. + +""" + +# ╔═╡ 26c64174-d294-11ef-2bbc-ab1a84532311 +md""" +There is no known conjugate prior for the latent variables in the GMM likelihood. Therefore, Bayes rule does not yield a closed-form expression for the posterior over the latent variables: + +```math + \underbrace{p(\{z_{nk}\},\{\mu_k,\Sigma_k,\pi_k\} | D)}_{\text{posterior (no analytical solution)}} \propto \underbrace{p(D\,|\,\{z_{nk}\},\{\mu_k,\Sigma_k,\pi_k\})}_{\text{likelihood}} \cdot \underbrace{p( \{z_{nk}\},\{\mu_k,\Sigma_k,\pi_k\} )}_{\text{prior (no known conjugate)}} +``` + +""" + +# ╔═╡ 26c65092-d294-11ef-39cc-1953a725f285 +md""" +Can we still compute an approximate posterior? In this lesson, we introduce an approximate Bayesian inference method known as **Variational Bayes** (VB) (also known as **Variational Inference**) that can be used for Bayesian inference in models with latent variables. Later in this lesson, we will use VB to do inference in the GMM. + +""" + +# ╔═╡ f1f7407d-86a1-4f24-b78a-61a411d1f371 +md""" +# Variational Inference +""" + +# ╔═╡ 26c67f04-d294-11ef-03a4-838ae255689d +md""" +## The Variational Free Energy Functional + +We'll start from scratch. Consider a model ``p(x,z) = p(x|z) p(z)``, where ``x`` and ``z`` are observed and latent variables, respectively. ``z`` may include parameters but also observation-dependent latent variables. + +The goal of Bayesian inference is to transform the (known) *likelihood-times-prior* factorization of the full model to a *posterior-times-evidence* decomposition: + +```math + \underbrace{p(x|z) p(z)}_{\text{what we know}} \rightarrow \underbrace{p(z|x) p(x)}_{\text{what we want}} +``` + +Remember from the [Bayesian machine learning lesson](https://bmlip.github.io/course/lectures/Bayesian%20Machine%20Learning.html#Bayesian-model-evidence) that negative log-evidence can be decomposed as "complexity" minus "accuracy" terms (the CA decomposition): + +```math + -\log p(x) = \underbrace{ \int p(z|x) \log \frac{p(z|x)}{p(z)} \mathrm{d}z }_{\text{complexity}} - \underbrace{\int p(z|x) \log p(x|z) \mathrm{d}z}_{\text{accuracy}} + +``` + +The CA decomposition cannot be evaluated because it depends on the posterior ``p(z|x)``, which cannot be evaluated since it is the objective of the inference process. + +Let's now introduce a distribution ``q(z)`` (called the "variational" or "approximate" posterior distribution) that we will use to *approximate* the posterior ``p(z|x)``. Since we propose the distribution ``q(z)`` ourselves, we will assume that ``q(z)`` can be evaluated. + +If we substitute ``q(z)`` for ``p(z|x)`` in the CA decomposition, then we obtain + +```math + F[q] \triangleq \underbrace{ \int q(z) \log \frac{q(z)}{p(z)} \mathrm{d}z }_{\text{complexity}} - \underbrace{\int q(z) \log p(x|z) \mathrm{d}z}_{\text{accuracy}} + +``` + +This expression is called the **Variational Free Energy** (VFE), represented by the symbol ``F``. We treat ``F`` as a function of the posterior ``q(z)``. Technically, a function of a function is called a functional, and we write square brackets (e.g., ``F[q]``) to differentiate functionals from functions (e.g., ``q(z)``). + +Note that all factors in the CA decomposition of VFE (i.e., ``q(z)``, ``p(z)``, and ``p(x|z)``) can be evaluated as a function of ``z`` (and ``x`` is observed), and therefore the VFE can be evaluated. This is important: log-evidence ``\log p(x)`` cannot be evaluated, but ``F[q]`` *can* be evaluated! + +""" + +# ╔═╡ 87715fcd-c92e-4bfa-8b0a-15e469548f3d +keyconcept("", +md""" +For a model ``p(x,z) = p(x|z) p(x)``, the **variational free energy** functional +```math + F[q] = \underbrace{ \int q(z) \log \frac{q(z)}{p(z)} \mathrm{d}z }_{\text{complexity}} - \underbrace{\int q(z) \log p(x|z) \mathrm{d}z}_{\text{accuracy}} +``` +is considered a functional of a variational posterior ``q(z)`` over the latent variables ``z``. Minimizing ``F[q]`` accomplishes **approximate Bayesian inference** by + +```math +\begin{align*} +\hat{q}(z) &\approx p(z|x) \\ +F[\hat{q}] &\approx -\log p(x) + \end{align*} +``` +""") + +# ╔═╡ 26c6e002-d294-11ef-15a4-33e30d0d76ec +md""" +## The Global VFE Minimum Recovers Bayes Rule + +It turns out that we can perform (approximate) Bayesian inference by minimizing the Variational Free Energy (VFE) with respect to the variational distribution ``q``. + +To explain inference by VFE minimization (abbreviated as VFEM), we first rewrite the VFE in terms of "inference bound" minus "log-evidence" terms (the bound-evidence (BE) decomposition): + +```math +\begin{align*} + F[q] &= \underbrace{ \int q(z) \log \frac{q(z)}{p(z)} \mathrm{d}z }_{\text{complexity}} - \underbrace{\int q(z) \log p(x|z) \mathrm{d}z}_{\text{accuracy}} \\ + &= \underbrace{\int q(z) \log \frac{q(z)}{p(z|x)}\mathrm{d}z}_{\text{inference bound}\geq 0} - \underbrace{\log p(x)}_{\text{log-evidence}} + \end{align*} +``` + + + +""" + +# ╔═╡ ae7ed1fc-fc36-4327-be55-a142477ca0ad +hide_proof( +md""" +```math +\begin{align*} + F[q] &= \underbrace{ \int q(z) \log \frac{q(z)}{p(z)} \mathrm{d}z }_{\text{complexity}} - \underbrace{\int q(z) \log p(x|z) \mathrm{d}z}_{\text{accuracy}} \\ + &= \int q(z) \log \frac{q(z)}{ p(x|z) p(z) }\mathrm{d}z \\ + &= \int q(z) \log \frac{q(z)}{ p(z|x) p(x)}\mathrm{d}z \quad \text{( since } p(x|z) p(z) = p(z|x) p(x)\text{ )} \\ + &= \underbrace{\int q(z) \log \frac{q(z)}{p(z|x)}\mathrm{d}z}_{\text{inference bound}\geq 0} - \underbrace{\log p(x)}_{\text{log-evidence}} + \end{align*} +``` +""") + +# ╔═╡ b4d965d1-91d8-43f8-84a5-b37ad5c6cafa +md""" +Note that the inference bound is a [Kullback-Leibler (KL) divergence](https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence) between an (approximate) posterior ``q(z)`` and the (perfect) Bayesian posterior ``p(z|x)``. To learn more: + +""" + +# ╔═╡ 18f5d694-8869-4265-98ac-9ef7ff451eaf +NotebookCard("https://bmlip.github.io/course/minis/KL%20Divergence.html") + +# ╔═╡ c4b23b39-e6e4-44ec-b204-0c7d7d5a4026 +md""" + +Since the second term (log-evidence) does not involve ``q(z)``, VFEM over ``q`` will bring ``q(z)`` closer to the Bayesian posterior ``p(z|x)``. + +Since ``D_{\text{KL}}[q(z),p(z|x)]\geq 0`` for any ``q(z)``, and ``D_{\text{KL}}[q(z),p(z|x)]= 0`` only if ``q(z) = p(z|x)``, the VFE is always an upper-bound on (minus) log-evidence, i.e., + +```math +F[q] \geq -\log p(x) \,. +``` + +As a result, global minimization of VFE leads to + +```math +q^*(z) = \arg\min_q F[q] +``` + +where + +```math +\begin{align} + q^*(z) &= p(z|x) \tag{posterior}\\ + F[q^*] &= -\log p(x) \tag{evidence} +\end{align} +``` +""" + +# ╔═╡ baec0494-9557-49d1-b4d8-a8030d3281b7 +md""" +## Approximate Bayesian Inference by VFE Minimization + +In practice, even if we cannot attain the global minimum of VFE, we can still use a local minimum, + +```math +\hat{q}(z) \approx \arg\min_q F[q] +``` + +to accomplish **approximate Bayesian inference** by: + +```math +\begin{align*} +\hat{q}(z) &\approx p(z|x) \\ +F[\hat{q}] &\approx -\log p(x) + \end{align*} +``` + +Executing inference by minimizing the VFE functional is called **Variational Bayes** (VB) or **Variational Inference** (VI). + + +(As an aside), note that Bishop introduces in Eq. B-10.3 an *Evidence Lower BOund* (in modern machine learning literature abbreviated as **ELBO**) ``\mathcal{L}[q]`` that equals the *negative* VFE (``\mathcal{L}[q]=-F[q]``). In this class, we prefer to discuss inference in terms of minimizing VFE rather than maximizing ELBO, but note that these two concepts are equivalent. (The reason why we prefer the Free Energy formulation relates to the terminology in the Free Energy Principle, which we introduce in the [Intelligent Agents and active Inference lesson (B12)](https://bmlip.github.io/course/lectures/Intelligent%20Agents%20and%20Active%20Inference.html)). +""" + +# ╔═╡ 40ce0abb-a086-4977-9131-10f60ab44152 +keyconcept("", md"VFE minimization transforms a Bayesian inference problem (that involves integration) into an optimization problem! Generally, optimization problems are easier to solve than integration problems.") + +# ╔═╡ 26c6f63c-d294-11ef-1090-e9238dd6ad3f +md""" +## Constrained VFE Minimization + +It is common to add simplifying constraints to an optimization problem to make a difficult optimization task tractible. This is also standard practice when approximating Bayesian inference by FE minimization. + +There are three important cases of adding constraints to the VFE functional that often alleviate the VFE minimization task: + - form constraints on ``q(z)`` + - factorization constraints on ``q(z)`` + - other (ad hoc) constraints + +We will shortly discuss these simplifications below. + +""" + +# ╔═╡ aea77d69-9ecd-4be0-b6fd-c944d27d68df +md""" +##### 1. Form constraints + +For almost every practical setting, we constrain the posterior ``q(z)`` to belong to a **specific parameterized family** of probability distributions, e.g., + +```math +q(z) = \mathcal{N}\left( z | \mu, \Sigma \right)\,. +``` + +In this case, the *functional* minimization problem for ``F[q]`` simplifies to the minimization of an ordinary *function* + +```math +F(\mu,\Sigma) = \int \mathcal{N}\left( z | \mu, \Sigma \right) \log \frac{\mathcal{N}\left( z | \mu, \Sigma \right)}{p(x,z)}\mathrm{d}z +``` + +with respect to the parameters ``\mu`` and ``\Sigma``. + + +We can often use standard gradient-based optimization methods to minimize the function ``F(\mu,\Sigma)\,.`` + + +""" + +# ╔═╡ 3654551d-5d08-4bb0-8a0d-c7d42225bc69 +md""" +##### 2. Factorization constraints + +In addition to form constraints, it is also common to constrain the posterior ``q(z)`` by a specific factorization. For instance, in the *mean-field factorization* constraints, we constrain the variational posterior to factorize fully into a set of independent factors, i.e., + +```math +q(z) = \prod_{j=1}^m q_j(z_j)\,, \tag{B-10.5} +``` + +Variational inference with mean-field factorization has been worked out in detail as the **Coordinate Ascent Variational Inference** (CAVI) algorithm. See the [Optional Slide on CAVI](#CAVI) for details. + +Mean-field factorization is just an example of various _factorization constraints_ that have been successfully applied to VFEM. + + + +""" + +# ╔═╡ edb179df-5cff-4e7b-8645-6da4818dceee +md""" + +##### 3. Other constraints, e.g., the Expectation-Minimization (EM) algorithm + +Aside from form and factorization constraints on ``q(z)``, several ad hoc algorithms have been developed that ease the process of VFE minimization for particular models. + +In particular, the [Expectation-Maximization (EM) algorithm](https://en.wikipedia.org/wiki/Expectation%E2%80%93maximization_algorithm) is a famous special case of constrained VFE minimization. The EM algorithm places some constraints on both the posterior ``q(z)`` and the prior ``p(z)`` (see the [OPTIONAL SLIDE](#EM-Algorithm) for more info) that essentially reduce VFE minimization to maximum likelihood estimation. +""" + +# ╔═╡ 26c704f6-d294-11ef-1b3d-d52f0fb1c81d +md""" +## Visualization of Constrained VFEM + +The following image by [David Blei](https://www.cs.columbia.edu/~blei/) illustrates the Variational Bayes approach: + +![](https://github.com/bmlip/course/blob/v2/assets/figures/blei-variational-inference.png?raw=true) + + +""" + +# ╔═╡ 26c728f0-d294-11ef-0c01-6143abe8c3f0 +md""" +The Bayesian posterior ``p(z|x)`` (upper-right) is the posterior that would be obtained through executing Bayes rule, but unfortunately, Bayes rule is not tractable here. Instead, we propose a variational posterior ``q(z;\nu)`` that is parameterized by ``\nu``. The inside area of the ellipsis represents the area that is reachable by choosing values for the parameter ``\nu``. Note that ``p(z|x)`` is not reachable. We start the FE minimization process by choosing an initial value ``\nu^{\text{init}}``, which corresponds to posterior ``q(z;\nu^{\text{init}})``, as indicated in the figure. VFE minimization leads to a final value ``\nu^{*}`` that minimizes the KL-divergence between ``q(z;\nu)`` and ``p(z|x)``. + +""" + +# ╔═╡ 06512595-bdb7-4adf-88ae-62af20210891 +challenge_solution("Modeling of the Old Faithful Data Set"; header_level=1) + +# ╔═╡ 26c73cf0-d294-11ef-297b-354eb9c71f57 +md""" + +## Derivation of VFEM Update Equations + +Let's get back to the illustrative challenge at the beginning of this lesson: we want to do [density modeling for the Old Faithful data set](#challenge_hello). + +""" + +# ╔═╡ 3e897a59-e7b5-492c-8a8a-724248513a72 +md""" +##### Model Specification + +We consider a Gaussian Mixture Model, specified by + +```math +\begin{align*} +p(x,z|\theta) &= p(x|z,\mu,\Lambda)p(z|\pi) \\ +&= \prod_{n=1}^N \prod_{k=1}^K \mathcal{N}\left( x_n | \mu_k, \Lambda_k^{-1}\right)^{z_{nk}} \cdot \prod_{n=1}^N \prod_{k=1}^K \pi_k^{z_{nk}} \\ + &= \prod_{n=1}^N \prod_{k=1}^K \left(\pi_k \cdot \mathcal{N}\left( x_n | \mu_k, \Lambda_k^{-1}\right)\right)^{z_{nk}} \tag{B-10.37,38} +\end{align*} +``` + +Let us introduce some priors for the parameters ``\pi``, ``\mu``, and ``\Lambda``. We factorize the prior and choose conjugate distributions by + +```math +p(\pi,\mu,\Lambda) = p(\pi) p(\mu|\Lambda) p(\Lambda) +``` + +with + +```math +\begin{align} +p(\pi) &= \mathrm{Dir}(\pi|\alpha_0) = C(\alpha_0) \prod_k \pi_k^{\alpha_0-1} \tag{B-10.39} \\ +p(\mu|\Lambda) &= \prod_k \mathcal{N}\left(\mu_k | m_0, \left( \beta_0 \Lambda_k\right)^{-1} \right) \tag{B-10.40} \\ +p(\Lambda) &= \prod_k \mathcal{W}\left( \Lambda_k | W_0, \nu_0 \right) \tag{B-10.40} +\end{align} +``` + +where ``\mathcal{W}\left( \cdot \right)`` is a [Wishart distribution](https://en.wikipedia.org/wiki/Wishart_distribution) (i.e., a multi-dimensional Gamma distribution). + +The full generative model is now specified by + +```math +p(x,z,\pi,\mu,\Lambda) = \underbrace{p(x|z,\mu,\Lambda) p(z|\pi)}_{\text{B-10.37-38}} \underbrace{p(\pi) p(\mu|\Lambda) p(\Lambda)}_{\text{B-10.39-40}} \tag{B-10.41} +``` + +with hyperparameters ``\{ \alpha_0, m_0, \beta_0, W_0, \nu_0\}``. + +""" + +# ╔═╡ 93e7c7d5-a940-4764-8784-07af2f056e49 +md""" +##### Inference by Constrained VFEM + +Assume that we have observed ``D = \left\{x_1, x_2, \ldots, x_N\right\}`` and are interested to infer a posterior distribution for the parameters ``\pi``, ``\mu`` and ``\Lambda``. + +We will approximate Bayesian inference by VFE minimization. For the specified model, this leads to VFE minimization with respect to the hyperparameters, i.e., we need to minimize the function + +```math +F(\alpha_0, m_0, \beta_0, W_0, \nu_0) \,. +``` + +In general, this function can be optimized in various ways, e.g., by a gradient-descent procedure. + +It turns out that adding the following **factorization constraints** on the variational posterior makes the VFEM task analytically tractible: + +```math +\begin{equation} +q(z,\pi,\mu,\Lambda) = q(z) \cdot q(\pi,\mu,\Lambda) \,. \tag{B-10.42} +\end{equation} +``` + +""" + +# ╔═╡ 26c74c9a-d294-11ef-2d31-67bd57d56d7c +md""" + +##### Update Equations + +For this specific case (GMM model with factorization constraints), Bishop shows that the equations for the [optimal solutions (Eq. B-10.9)](#optimal-solutions) are analytically solvable, leading to the following variational update equations (for ``k=1,\ldots, K`` ): + +```math +\begin{align*} +\alpha_k &= \alpha_0 + N_k \tag{B-10.58} \\ +\beta_k &= \beta_0 + N_k \tag{B-10.60} \\ +m_k &= \frac{1}{\beta_k} \left( \beta_0 m_0 + N_k \bar{x}_k \right) \tag{B-10.61} \\ +W_k^{-1} &= W_0^{-1} + N_k S_k + \frac{\beta_0 N_k}{\beta_0 + N_k}\left( \bar{x}_k - m_0\right) \left( \bar{x}_k - m_0\right)^T \tag{B-10.62} \\ +\nu_k &= \nu_0 + N_k \tag{B-10.63} +\end{align*} +``` + +where we used + +```math +\begin{align*} +\log \rho_{nk} &= \mathbb{E}\left[ \log \pi_k\right] + \frac{1}{2}\mathbb{E}\left[ \log | \Lambda_k | \right] - \frac{D}{2} \log(2\pi) \\ + & \qquad - \frac{1}{2}\mathbb{E}\left[(x_k - \mu_k)^T \Lambda_k(x_k - \mu_k) \right] \tag{B-10.46} \\ +r_{nk} &= \frac{\rho_{nk}}{\sum_{j=1}^K \rho_{nj}} \tag{B-10.49} \\ +N_k &= \sum_{n=1}^N r_{nk} \tag{B-10.51} \\ +\bar{x}_k &= \frac{1}{N_k} \sum_{n=1}^N r_{nk} x_n \tag{B-10.52} \\ +S_k &= \frac{1}{N_k} \sum_{n=1}^N r_{nk} \left( x_n - \bar{x}_k\right) \left( x_n - \bar{x}_k\right)^T \tag{B-10.53} +\end{align*} +``` + +""" + +# ╔═╡ 26c75b5e-d294-11ef-173e-b3f46a1df536 +md""" +Exam guide: Working out VFE minimization for the GMM to these update equations (eqs B-10.58 through B-10.63) is not something that you need to reproduce without assistance at the exam. Rather, the essence is that *it is possible* to arrive at closed-form variational update equations for the GMM. You should understand though how FEM works conceptually and in principle be able to derive variational update equations for very simple models that do not involve clever mathematical tricks. + +""" + +# ╔═╡ 95d47a10-f3f8-479b-afe0-21241104b758 +code_example("VFEM for GMM on Old Faithfull data set") + + +# ╔═╡ 26c7696e-d294-11ef-25f2-dbc0946c0858 +md""" + + + +Below we exemplify training of a Gaussian Mixture Model on the Old Faithful data set by VFE minimization, with the constraints as specified above. + +""" + +# ╔═╡ 26c796c8-d294-11ef-25be-17dcd4a9d315 +md""" +The generated figure resembles Figure 10.6 in Bishop. The plots show VFEM results for a GMM of ``K = 6`` Gaussians applied to the Old Faithful data set. The ellipses denote the two standard-deviation density contours for each of the components, and the color coding of the data points reflects the "soft" class label assignments. + +""" + +# ╔═╡ 16d90f11-5933-4145-b219-19774eba25d6 +@htl """ + +""" + +# ╔═╡ 8b887c4a-273c-40fe-83e9-5c79ac6946f8 +md""" +### Implementation + +_Reading this lecture online? Click **"View code"** in the top right to read the implementation of this visualisation._ + +""" + +# ╔═╡ 666680b2-315a-4d95-8f7f-3ae50018e112 +K = 6; + +# ╔═╡ 4e0c025d-fa39-462d-8e7d-e66d220e9595 +max_iterations = 120; + +# ╔═╡ de0c41a3-6319-4ae3-8a1a-ae6935910fa3 +@bindname iteration_vfem Slider([0:10..., 10:10:max_iterations-1...]; default=2, show_value=true) + +# ╔═╡ f42a1a65-20ce-452f-9974-bc8146943574 +md""" +# Theoretical Underpinning of VFE Minimization +""" + +# ╔═╡ 26c7b428-d294-11ef-150a-bb37e37f4b5d +md""" +## Observations as Variational Constraints + +We derived variational inference by substituting a variational posterior ``q(z)`` for the Bayesian posterior ``p(z|x)`` in the CA decomposition of (negative log) Bayesian evidence for a model. This led to a straightforward derivation of the VFE functional, but revealed nothing about the foundations of variational inference. Is variational inference any good? + +To approach this question, let us first recognize that, in the context of a given model ``p(x,z)``, new observations ``x`` can generally be formulated as a constraint on a posterior distribution ``q``. For instance, observing a new data point ``x_1 = 5`` can be formalized as a constraint ``q(x_1) = \delta(x_1 - 5)``, where ``\delta(\cdot)`` is the Dirac delta function. + +Viewing observations as delta-function constraints enables us to interpret them as a specific instance of variational constraints, on par with form and factorization (and other) constraints, all of which shape the variational posterior in constrained VFE minimization. + + +""" + +# ╔═╡ b3bb7349-1965-4734-83ed-ba6fef0ccc41 +md""" + +## Variational Inference and The Maximum Entropy Principle + +In [Caticha (2010)](https://arxiv.org/abs/1011.0723) (based on earlier work by [Shore and Johnson (1980)](https://github.com/bmlip/course/blob/main/assets/files/ShoreJohnson-1980-Axiomatic-Derivation-of-the-Principle-of-Maximum-Entropy.pdf)), the [Principle of Maximum (Relative) Entropy](https://en.wikipedia.org/wiki/Principle_of_maximum_entropy) is developed as a method for rational updating of priors to posteriors when faced with new information in the form of constraints. + + +Caticha's argumentation is as follows: + + * Consider prior beliefs (i.e., a generative model) ``p(x,z)`` about observed and latent variables ``x`` and ``z``. Assume that new information in the form of constraints is obtained, and we are interested in the "best update" to posterior beliefs ``q(x,z)``. + + * In order to define what "best update" means, Caticha assumed a ranking function ``S[q]`` that generates a preference score for each candidate posterior ``q`` for a given prior ``p``. The best update from ``p`` to ``q`` is then identified as + +```math +q^* = \arg\max_q S[q]\,, \quad \text{subject to all constraints.} +``` + +Similarly to [Cox' method](https://en.wikipedia.org/wiki/Cox%27s_theorem) for deriving Probability Theory from a set of sensical axioms, Caticha then introduced the following axioms, based on a rational principle (the **principle of minimal updating**, see [Caticha 2010](https://arxiv.org/abs/1011.0723)), that the ranking function needs to adhere to: + + 1. *Locality*: local information has local effects. + 2. *Coordinate invariance*: the system of coordinates carries no information. + 3. *Independence*: When systems are known to be independent, it should not matter whether they are treated separately or jointly. + +It turns out that these three criteria **uniquely identify the Relative Entropy** as the proper ranking function: + +```math +\begin{align*} +S[q] = - \sum_z q(x,z) \log \frac{q(x,z)}{p(x,z)} +\end{align*} +``` + +This procedure for finding the variational posterior ``q`` is called the **Principle of Maximum (Relative) Entropy** (PME). Note that, since ``S[q]=-F[q]``, constrained Relative Entropy maximization is equivalent to constrained VFE minimization! + +Therefore, when information is supplied in the form of constraints on the posterior (such as form/factorization constraints and new observations as data constraints), we *should* select the posterior that minimizes the constrained Variational Free Energy. **Constrained FE minimization is the proper method for inference!** + +Bayes rule is the global solution of constrained VFEM when all constraints are data constraints, ie, delta distributions on ``q(x)``. Hence, Bayes rule is a special case of constrained VFEM. Bayes rule only applies to updating beliefs on the basis of new observations. + +""" + +# ╔═╡ 06170e31-e865-4178-8af0-41d82df95d71 +keyconcept("","Constrained VFE minimization is consistent with the **Maximum Entropy Principle**, which prescribes how to rationally update beliefs when new information becomes available. In this framework, the updated posterior is the distribution that minimizes VFE (or equivalently, KL divergence to the prior) subject to the imposed constraints. ") + +# ╔═╡ bbdca8c2-022f-42be-bcf7-80d86f7f269c +md""" + +## Model Performance Evaluation, Revisited + +Let us reconsider the Bound-Evidence decomposition of the VFE for a model ``p(x,z)`` with variational posterior ``q(z)``, + +```math +\begin{align} +\mathrm{F}[q] = \underbrace{\sum_z q(z) \log \frac{q(z)}{p(z|x)}}_{\text{inference bound}\geq 0} \underbrace{- \log p(x)}_{\text{surprise}} \tag{BE} +\end{align} +``` + +The VFE comprises two cost terms: + + - The **surprise** (or negative log-evidence), ``-\log p(x)``, reflects the cost of predicting the data ``x`` using a model ``p(x, z)``, assuming that (ideal) Bayesian inference can be performed. Specifically, the evidence ``p(x)`` is obtained from the joint model ``p(x, z)`` by marginalizing over the latent variables: +```math +p(x) = \sum_z p(x,z) \,. +``` + + - The **inference bound**, given by the Kullback–Leibler divergence +```math +\sum_z q(z) \log \frac{q(z)}{p(z |x)} \geq 0 \,, +``` +quantifies the cost of imperfect inference, i.e., the discrepancy between the variational posterior ``q(z)`` and the true Bayesian posterior ``p(z | x)``. + +In any practical setting, using a model *implies* performing inference within that model. Therefore, the effective cost of applying a model is not merely the surprise but also must include the cost of inference. + +Put more bluntly: a model with very high Bayesian evidence ``p(x)`` may still be practically unusable due to exorbitant inference costs. + +In the literature, the VFE is typically interpreted as an approximation (more precisely, an upper-bound) to the surprise, ``-\log p(x)``, which is often regarded as the “true” measure of model performance. However, we argue that this perspective should be reversed: the VFE should be considered the true performance metric in practice, as it accounts for both model fit and the tractability of inference. The surprise can be viewed as a special case of the VFE, corresponding to a zero inference bound, that only applies when ideal Bayesian inference is computationally feasible. + +""" + +# ╔═╡ 26c8068a-d294-11ef-3983-a1be55128b3f +md""" +## Variational Inference in Practice + +For most realistic models of complex real-world problems, Bayes rule is not tractable in closed form. As a result, the use of approximate variational Bayesian inference has seen rapid growth in practical applications. + +Toolboxes such as [RxInfer](http://rxinfer.com) enable users to define sophisticated probabilistic models and automate the inference process via constrained VFE minimization. Remarkably, specifying even complex models typically requires no more than a single page of code. + +In contrast to traditional algorithm design, where solving a problem might require implementing a custom solution in, say, ``40`` pages of code, automated inference in a probabilistic model offers a radically more efficient and modular approach. This shift has the potential to fundamentally change how we design and deploy information processing systems in the future. + +""" + +# ╔═╡ 60a50f12-063c-4247-9c9c-bb41d5dc9811 +md""" +# Summary +""" + +# ╔═╡ 4ff85bda-22bb-408d-a50a-461834b7c0ff +keyconceptsummary() + +# ╔═╡ 56bea391-b812-4fc4-8f27-fcb4cb984cf4 +exercises(header_level=1) + +# ╔═╡ 5a94e2a4-7134-462e-9dc5-56083769049f +md""" +#### Entropy and The Free Energy Functional (*) + +The Free energy functional ``\mathrm{F}[q] = -\sum_z q(z) \log p(x,z) - \sum_z q(z) \log \frac{1}{q(z)}`` decomposes into "Energy minus Entropy". So apparently the entropy of the posterior ``q(z)`` is maximized. This entropy maximization may seem puzzling at first because inference should intuitively lead to *more* informed posteriors, i.e., posterior distributions whose entropy is smaller than the entropy of the prior. Explain why entropy maximization is still a reasonable objective. + + +""" + +# ╔═╡ 747a7e1e-b921-4882-b00a-1b00bef8433d +hide_solution( +md""" + +Note that Free Energy minimization is a balancing act: FE minimization implies entropy maximization *and at the same time* energy minimization. Minimizing the energy term leads to aligning ``q(z)`` with ``\log p(x,z)``, ie, it tries to move the bulk of the function ``q(z)`` to areas in ``z``-space where ``p(x,z)`` is large (``p(x,z)`` is here just a function of ``z``, since x is observed). + +However, aside from aligning with ``p(x,z)``, we want ``q(z)`` to be as uninformative as possible. Everything that can be inferred should be represented in ``p(x,z)`` (which is prior times likelihood). We don't want to learn anything that is not in either the prior or the likelihood. The entropy term balances the energy term by favoring distributions that are as uninformative as possible. + +""") + +# ╔═╡ 2d4adbf6-6de8-4e3a-ad6f-fa8bbfa5999e +md""" + +#### Mean Updating (*) + +Explain the following update rule for the [mean of the Gaussian cluster-conditional data distribution](##Update-Equations): + +```math +m_k = \frac{1}{\beta_k} \left( \beta_0 m_0 + N_k \bar{x}_k \right) \tag{B-10.61} +``` + +""" + +# ╔═╡ 208ba1bb-a4bf-4b8c-93d2-0d6c6c8d16d4 +hide_solution( +md""" +We see here an example of "precision-weighted means add" when two sources of information are fused, just like precision-weighted means add when two Gaussians are multiplied, eg a prior and likelihood. In this case, the prior is ``m_0`` and the likelihood estimate is ``\bar{x}``. ``\beta_0`` can be interpreted as the number of pseudo-observations in the prior. + +""") + +# ╔═╡ 2f490e1f-e495-4f55-a3f8-60d6fd716d4e +md""" +#### The Expectation-Maximization (EM) algorithm (**) + +Consider a model ``p(x,z|\theta)``, where ``D=\{x_1,x_2,\ldots,x_N\}`` is observed, ``z`` are unobserved variables, and ``\theta`` are parameters. The **Expectation-Maximization** (EM) algorithm estimates the parameters by iterating over the following two equations (``i`` is the iteration index): + +```math +\begin{align*} +q^{(i)}(z) &= p(z|D,\theta^{(i-1)}) \\ +\theta^{(i)} &= \arg\max_\theta \sum_z q^{(i)}(z) \cdot \log p(D,z|\theta) +\end{align*} +``` + +Prove that this algorithm minimizes the Free Energy functional + +```math +\begin{align*} +F[q](\theta) = \sum_z q(z) \log \frac{q(z)}{p(D,z|\theta)} +\end{align*} +``` + + +""" + +# ╔═╡ b91bc3b6-b815-4942-b297-c0e2b4b99654 +hide_solution( +md""" + +Let's start with a prior estimate ``\theta^{(i-1)}`` and we want to minimize the free energy functional wrt ``q``. This leads to + + +```math +\begin{align*} +q^{(i)}(z) &= \arg\min_q F[q](\theta^{(i-1)}) \\ + &= \arg\min_q \sum_z q(z) \log \frac{q(z)}{p(D,z|\theta^{(i-1)})} \\ + &= \arg\min_q \sum_z q(z) \log \frac{q(z)}{p(z|D,\theta^{(i-1)}) \cdot p(D|\theta^{(i-1)})} \\ + &= p(z|D,\theta^{(i-1)}) +\end{align*} +``` + +Next, we use ``q^{(i)}(z)=p(z|D,\theta^{(i-1)})`` and minimize the free energy w.r.t. ``\theta``, leading to + +```math +\begin{align*} + \theta^{(i)} &= \arg\min_\theta F[q^{(i)}](\theta) \\ + &= \arg\min_\theta \sum_z p(z|D,\theta^{(i-1)}) \log \frac{p(z|D,\theta^{(i-1)})}{p(D,z|\theta)} \\ + &= \arg\max_\theta \sum_z \underbrace{p(z|D,\theta^{(i-1)})}_{q^{(i)}(z)} \log p(D,z|\theta) +\end{align*} +``` + """) + +# ╔═╡ 26c8160c-d294-11ef-2a74-6f7009a7c51e +md""" +# Optional Slides + +""" + +# ╔═╡ 26c82f16-d294-11ef-0fe1-07326b56282f +md""" +## VFE Minimization with Mean-field Factorization Constraints: $(HTML("the CAVI Approach")) + +Let's work out VFE minimization with additional mean-field constraints (=full factorization) constraints: + +```math +q(z) = \prod_{j=1}^m q_j(z_j)\,. +``` + +In other words, the posteriors for ``z_j`` are all considered independent. This is a strong constraint but often leads to good solutions. + +Given the mean-field constraints, it is possible to derive the following expression for the $(HTML("optimal solutions")) ``q_j^*(z_j)``, for ``j=1,\ldots,m``: + +```math +\begin{align} +\log q_j^*(z_j) &\propto \mathrm{E}_{q_{-j}^*}\left[ \log p(x,z) \right] \\ + &= \underbrace{\sum_{z_{-j}} q_{-j}^*(z_{-j}) \underbrace{\log p(x,z)}_{\text{"field"}}}_{\text{"mean field"}} +\end{align} +``` + +where we defined ``q_{-j}^*(z_{-j}) \triangleq q_1^*(z_1)q_2^*(z_2)\cdots q_{j-1}^*(z_{j-1})q_{j+1}^*(z_{j+1})\cdots q_m^*(z_m)``. + +**Proof** (from [Blei, 2017](https://doi.org/10.1080/01621459.2017.1285773)): We first rewrite the FE as a function of ``q_j(z_j)`` only: + +```math + F[q_j] = \mathbb{E}_{q_{j}}\left[ \mathbb{E}_{q_{-j}}\left[ \log p(x,z_j,z_{-j})\right]\right] - \mathbb{E}_{q_j}\left[ \log q_j(z_j)\right] + \mathtt{const.}\,, +``` + +where the constant holds all terms that do not depend on ``z_j``. This expression can be written as + +```math + F[q_j] = \sum_{z_j} q_j(z_j) \log \frac{q_j(z_j)}{\exp\left( \mathbb{E}_{q_{-j}}\left[ \log p(x,z_j,z_{-j})\right]\right)} +``` + +which is a KL-divergence that is minimized by Eq. B-10.9. (end proof) + +This is not yet a full solution to the FE minimization task since the solution ``q_j^*(z_j)`` depends on expectations that involve other solutions ``q_{i\neq j}^*(z_{i \neq j})``, and each of these other solutions ``q_{i\neq j}^*(z_{i \neq j})`` depends on an expection that involves ``q_j^*(z_j)``. + +In practice, we solve this chicken-and-egg problem by an iterative approach: we first initialize all ``q_j(z_j)`` (for ``j=1,\ldots,m``) to an appropriate initial distribution and then cycle through the factors in turn by solving eq.B-10.9 and update ``q_{-j}^*(z_{-j})`` with the latest estimates. (See [Blei, 2017](https://doi.org/10.1080/01621459.2017.1285773), Algorithm 1, p864). + +This algorithm for approximating Bayesian inference is known **Coordinate Ascent Variational Inference** (CAVI). + +""" + +# ╔═╡ 26c85a22-d294-11ef-3c8e-7b72a4313ced +md""" +## $(HTML("FE Minimization by the Expectation-Maximization (EM) Algorithm")) + +The EM algorithm is a special case of VFE minimization that focuses on Maximum-Likelihood estimation for models with latent variables. + +Consider a model + +```math +p(x,z,\theta) +``` + +with observations ``x = \{x_n\}``, latent variables ``z=\{z_n\}`` and parameters ``\theta``. + +We can write the following VFE functional for this model: + +```math +\begin{align*} +F[q] = \sum_z \sum_\theta q(z,\theta) \log \frac{q(z,\theta)}{p(x,z,\theta)} +\end{align*} +``` + +The EM algorithm makes the following simplifying assumptions: + +1. The prior for the parameters is uninformative (uniform). This implies that + +```math +p(x,z,\theta) = p(x,z|\theta) p(\theta) \propto p(x,z|\theta) +``` + +2. A factorization constraint + +```math +q(z,\theta) = q(z) q(\theta) +``` + +3. The posterior for the parameters is a delta function: + +```math +q(\theta) = \delta(\theta - \hat{\theta}) +``` + +Basically, these three assumptions turn VFE minimization into maximum likelihood estimation for the parameters ``\theta`` and the VFE simplifies to + +```math +\begin{align*} +F[q,\theta] = \sum_z q(z) \log \frac{q(z)}{p(x,z|\theta)} +\end{align*} +``` + +The EM algorithm minimizes this FE by iterating (iteration counter: ``i``) over + +```math +\begin{align} \mathcal{L}^{(i)}(\theta) &= \sum_z \overbrace{p(z|x,\theta^{(i-1)})}^{q^{(i)}(z)} \log p(x,z|\theta) \tag{the E-step} \\ +\theta^{(i)} &= \arg\max_\theta \mathcal{L}^{(i)}(\theta) \tag{the M-step} \end{align} + +``` + +These choices are optimal for the given FE functional. In order to see this, consider the two decompositions + +```math +\begin{align*} +F[q,\theta] &= \underbrace{-\sum_z q(z) \log p(x,z|\theta)}_{\text{energy}} - \underbrace{\sum_z q(z) \log \frac{1}{q(z)}}_{\text{entropy}} \qquad &&\text{(EE)}\\ + &= \underbrace{\sum_z q(z) \log \frac{q(z)}{p(z|x,\theta)}}_{\text{divergence}} - \underbrace{\log p(x|\theta)}_{\text{log-likelihood}} \qquad &&\text{(DE)} +\end{align*} +``` + +The DE decomposition shows that the FE is minimized for the choice ``q(z) := p(z|x,\theta)``. Also, for this choice, the FE equals the (negative) log-evidence (, which is this case simplifies to the log-likelihood). + +The EE decomposition shows that the FE is minimized wrt ``\theta`` by minimizing the energy term. The energy term is computed in the E-step and optimized in the M-step. + + * Note that in the EM literature, the energy term is often called the *expected complete-data log-likelihood*.) + +In order to execute the EM algorithm, it is assumed that we can analytically execute the E- and M-steps. For a large set of models (including models whose distributions belong to the exponential family of distributions), this is indeed the case and hence the large popularity of the EM algorithm. + +The EM algorihm imposes rather severe assumptions on the FE (basically approximating Bayesian inference by maximum likelihood estimation). Over the past few years, the rise of Probabilistic Programming languages has dramatically increased the range of models for which the parameters can by estimated autmatically by (approximate) Bayesian inference, so the popularity of EM is slowly waning. (More on this in the Probabilistic Programming lessons). + +Bishop (2006) works out EM for the GMM in section 9.2. + +""" + +# ╔═╡ 62868f61-95c7-4e07-854f-a171aadc667b +code_example("EM-algorithm for the GMM on the Old-Faithful data set") + +# ╔═╡ 26c867d8-d294-11ef-2372-d75ed0bcc02d +md""" + +We'll perform clustering on the data set from the [challenge](#challenge_hello) by fitting a GMM consisting of two Gaussians using the EM algorithm. + +""" + +# ╔═╡ 64819124-865e-48b8-a916-2ce08dba0acc +@htl """ + +""" + +# ╔═╡ 87d94630-c90b-4379-91bd-88641ee7b508 +md""" +### Implementation + +_Reading this lecture online? Click **"View code"** in the top right to read the implementation of this visualisation._ + +""" + +# ╔═╡ 26c8b682-d294-11ef-1331-2bcf8baec73f +md""" +## Message Passing for Free Energy Minimization + +The Sum-Product (SP) update rule implements perfect Bayesian inference. + +Sometimes, the SP update rule is not analytically solvable. + +Fortunately, for many well-known Bayesian approximation methods, a message passing update rule can be created, e.g. [Variational Message Passing](https://en.wikipedia.org/wiki/Variational_message_passing) (VMP) for variational inference. + +In general, all of these message passing algorithms can be interpreted as minimization of a constrained free energy (e.g., see [Senoz et al. (2021)](https://research.tue.nl/nl/publications/variational-message-passing-and-local-constraint-manipulation-in-), and hence these message passing schemes comply with [Caticha's Method of Maximum Relative Entropy](https://arxiv.org/abs/1011.0723), which, as discussed in the [variational Bayes lesson](https://bmlip.github.io/course/lectures/Latent%20Variable%20Models%20and%20VB.html) is the proper way for updating beliefs. + +Different message passing updates rules can be combined to get a hybrid inference method in one model. + +""" + +# ╔═╡ 26c8c7fa-d294-11ef-0444-6555ecf5c721 +md""" +## The Local Free Energy in a Factor Graph + +Consider an edge ``x_j`` in a Forney-style factor graph for a generative model ``p(x) = p(x_1,x_2,\ldots,x_N)``. + +Assume that the graph structure (factorization) is specified by + +```math +p(x) = \prod_{a=1}^M p_a(x_a) +``` + +where ``a`` is a set of indices. + +Also, we assume a mean-field approximation for the posterior: + +```math +q(x) = \prod_{i=1}^N q_i(x_i) +``` + +and consequently a corresponding free energy functional + +```math +\begin{align*} +F[q] &= \sum_x q(x) \log \frac{q(x)}{p(x)} \\ + &= \sum_i \sum_{x_i} \left(\prod_{i=1}^N q_i(x_i)\right) \log \frac{\prod_{i=1}^N q_i(x_i)}{\prod_{a=1}^M p_a(x_a)} +\end{align*} +``` + +With these assumptions, it can be shown that the FE evaluates to (exercise) + +```math +F[q] = \sum_{a=1}^M \underbrace{\sum_{x_a} \left( \prod_{j\in N(a)} q_j(x_j)\cdot \left(-\log p_a(x_a)\right) \right) }_{\text{node energy }U[p_a]} - \sum_{i=1}^N \underbrace{\sum_{x_i} q_i(x_i) \log \frac{1}{q_i(x_i)}}_{\text{edge entropy }H[q_i]} +``` + +In words, the FE decomposes into a sum of (expected) energies for the nodes minus the entropies on the edges. + +""" + +# ╔═╡ f17c9d8a-9291-4110-bcf4-c582d23f986b +md""" +## Variational Message Passing + +Let us now consider the local free energy that is associated with edge corresponding to ``x_j``. + +""" + +# ╔═╡ 90fbe618-fc81-480b-b685-69cd97e5b8ed +Resource("https://github.com/bmlip/course/blob/v2/assets/figures/VMP-two-nodes.png?raw=true", :style => "background: white; border-radius: 1em;") + +# ╔═╡ 32f0bbb4-dfc7-431e-9a3d-80162439edac +md""" +Apparently (see previous slide), there are three contributions to the free energy for ``x_j``: + + * one entropy term for the edge ``x_j`` + * two energy terms: one for each node that attaches to ``x_j`` (in the figure: nodes ``p_a`` and ``p_b``) + +The local free energy for ``x_j`` can be written as (exercise) + +```math + F[q_j] \propto \sum_{x_j} q(x_j) \log \frac{q_j(x_j)}{\nu_a(x_j)\cdot \nu_b(x_j)} + +``` + +where + +```math +\begin{align*} + \nu_a(x_j) &\propto \exp\left( \mathbb{E}_{q_{k}}\left[ \log p_a(x_a)\right]\right) \\ + \nu_b(x_j) &\propto \exp\left( \mathbb{E}_{q_{l}}\left[ \log p_b(x_b)\right]\right) + \end{align*} +``` + +and ``\mathbb{E}_{q_{k}}\left[\cdot\right]`` is an expectation w.r.t. all ``q(x_k)`` with ``k \in N(a)\setminus {j}``. + +``\nu_a(x_j)`` and ``\nu_b(x_j)`` can be locally computed in nodes ``a`` and ``b`` respectively and can be interpreted as colliding messages over edge ``x_j``. + +Local free energy minimization is achieved by setting + +```math + q_j(x_j) \propto \nu_a(x_j) \cdot \nu_b(x_j) + +``` + +Note that message ``\nu_a(x_j)`` depends on posterior beliefs over incoming edges (``k``) for node ``a``, and in turn, the message from node ``a`` towards edge ``x_k`` depends on the belief ``q_j(x_j)``. I.o.w., direct mutual dependencies exist between posterior beliefs over edges that attach to the same node. + +These considerations lead to the [Variational Message Passing](https://en.wikipedia.org/wiki/Variational_message_passing) procedure, which is an iterative free energy minimization procedure that can be executed completely through locally computable messages. + +Procedure VMP, see [Dauwels (2007), section 3](https://github.com/bmlip/course/blob/main/assets/files/Dauwels-2007-on-variational-message-passing-on-factor-graphs.pdf) + +> 1. Initialize all messages ``q`` and ``ν``, e.g., ``q(\cdot) \propto 1`` and ``\nu(\cdot) \propto 1``.
+> 2. Select an edge ``z_k`` in the factor graph of ``f(z_1,\ldots,z_m)``.
+> 3. Compute the two messages ``\overrightarrow{\nu}(z_k)`` and ``\overleftarrow{\nu}(z_k)`` by applying the following generic rule: +> ```math +> \overrightarrow{\nu}(y) \propto \exp\left( \mathbb{E}_{q}\left[ \log g(x_1,\dots,x_n,y)\right] \right) +> ``` +> 4. Compute the marginal ``q(z_k)`` +> ```math +> q(z_k) \propto \overrightarrow{\nu}(z_k) \overleftarrow{\nu}(z_k) +> ``` +> and send it to the two nodes connected to the edge ``x_k``. +> +> 5. Iterate 2–4 until convergence. + + +""" + +# ╔═╡ 26c9121e-d294-11ef-18e6-ed8105503adc +md""" +## The Bethe Free Energy and Belief Propagation + +We showed that, under mean field assumptions, the FE can be decomposed into a sum of local FE contributions for the nodes (``a``) and edges (``i``): + +```math +\begin{align*} +F[q] = \sum_{a=1}^M \underbrace{\sum_{x_a} \left( \prod_{j\in N(a)} q_j(x_j)\cdot \left(-\log p_a(x_a)\right) \right) }_{\text{node energy }U[p_a]} - \sum_{i=1}^N \underbrace{\sum_{x_i} q_i(x_i) \log \frac{1}{q_i(x_i)}}_{\text{edge entropy }H[q_i]} +\end{align*} +``` + +The mean field assumption is very strong and may lead to large inference costs (``\mathrm{KL}(q(x),p(x|\text{data}))``). A more relaxed assumption is to allow joint posterior beliefs over the variables that attach to a node. This idea is expressed by the Bethe Free Energy: + +```math +\begin{align*} +F_B[q] = \sum_{a=1}^M \left( \sum_{x_a} q_a(x_a) \log \frac{q_a(x_a)}{p_a(x_a)} \right) - \sum_{i=1}^N (d_i - 1) \sum_{x_i} q_i(x_i) \log {q_i(x_i)} +\end{align*} +``` + +where ``q_a(x_a)`` is the posterior joint belief over the variables ``x_a`` (i.e., the set of variables that attach to node ``a``), ``q_i(x_i)`` is the posterior marginal belief over the variable ``x_i`` and ``d_i`` is the number of factor nodes that link to edge ``i``. Moreover, ``q_a(x_a)`` and ``q_i(x_i)`` are constrained to obey the following equalities: + +```math +\begin{align*} + \sum_{x_a \backslash x_i} q_a(x_a) &= q_i(x_i), ~~~ \forall i, \forall a \\ + \sum_{x_i} q_i(x_i) &= 1, ~~~ \forall i \\ + \sum_{x_a} q_a(x_a) &= 1, ~~~ \forall a \\ +\end{align*} +``` + +We form the Lagrangian by augmenting the Bethe Free Energy functional with the constraints: + +```math +\begin{align*} +L[q] = F_B[q] + \sum_i\sum_{a \in N(i)} \lambda_{ai}(x_i) \left(q_i(x_i) - \sum_{x_a\backslash x_i} q(x_a) \right) + \sum_{i} \gamma_i \left( \sum_{x_i}q_i(x_i) - 1\right) + \sum_{a}\gamma_a \left( \sum_{x_a}q_a(x_a) -1\right) +\end{align*} +``` + +The stationary solutions for this Lagrangian are given by + +```math +\begin{align*} +q_a(x_a) &= f_a(x_a) \exp\left(\gamma_a -1 + \sum_{i \in N(a)} \lambda_{ai}(x_i)\right) \\ +q_i(x_i) &= \exp\left(1- \gamma_i + \sum_{a \in N(i)} \lambda_{ai}(x_i)\right) ^{\frac{1}{d_i - 1}} +\end{align*} +``` + +where ``N(i)`` denotes the factor nodes that have ``x_i`` in their arguments and ``N(a)`` denotes the set of variables in the argument of ``f_a``. + +Stationary solutions are functions of Lagrange multipliers. This means that Lagrange multipliers need to be determined. Lagrange multipliers can be determined by plugging the stationary solutions back into the constraint specification and solving for the multipliers which ensure that the constraint is satisfied. The first constraint we consider is normalization, which yields the following identification: + +```math +\begin{align*} +\gamma_a &= 1 - \log \Bigg(\sum_{x_a}f_a(x_a)\exp\left(\sum_{i \in N(a)}\lambda_{ai}(x_i)\right)\Bigg)\\ +\gamma_i &= 1 + (d_i-1) \log\Bigg(\sum_{x_i}\exp\left( \frac{1}{d_i-1}\sum_{a \in N(i)} \lambda_{ai}(x_i)\right)\Bigg). +\end{align*} +``` + +The functional form of the Lagrange multipliers that corresponds to the normalization constraint enforces us to obtain the Lagrange multipliers that correspond to the marginalization constraint. To do so we solve for + +```math +\begin{align*} \sum_{x_a \backslash x_i} f_a(x_a) \exp\left(\sum_{i \in N(a)} \lambda_{ai}(x_i)\right) &= \exp\left(\sum_{a \in N(i)} \lambda_{ai}(x_i)\right) ^{\frac{1}{d_i - 1}} \exp\left(\lambda_{ai}(x_i)\right)\sum_{x_a \backslash x_i} f_a(x_a) \exp\Bigg(\sum_{\substack{{j \in N(a)} j \neq i}}\lambda_{aj}(x_j)\Bigg) \\ +&= \exp\left(\sum_{a \in N(i)} \lambda_{ai}(x_i)\right) ^{\frac{1}{d_i - 1}} \exp\left(\lambda_{ai}(x_i) + \lambda_{ia}(x_i)\right) \\ +&= \exp\left(\sum_{a \in N(i)} \lambda_{ai}(x_i)\right) ^{\frac{1}{d_i - 1}}\, , +\end{align*} +``` + +where we defined an auxilary function + +```math +\begin{align*} +\exp(\lambda_{ia}(x_i)) \triangleq \sum_{x_a \backslash x_i} f_a(x_a) \exp\Bigg(\sum_{\substack{{j \in N(a)} j \neq i}}\lambda_{aj}(x_j)\Bigg) \,. +\end{align*} +``` + +This definition is valid since it can be inverted by the relation + +```math +\begin{align*} +\lambda_{ia}(x_i) = \frac{2-d_i}{d_i - 1}\lambda_{ai}(x_i) + \frac{1}{d_i -1}\sum_{\substack{c \in N(i)\\c \neq a}}\lambda_{ci}(x_i) +\end{align*} +``` + +In general it is not possible to solve for the Lagrange multipliers analytically and we resort to iteratively obtaining the solutions. This leads to the **Belief Propagation algorithm** where the exponentiated Lagrange multipliers (messages) are updated iteratively via + +```math +\begin{align*} +\mu_{ia}^{(k+1)}(x_i) &= \sum_{x_a \backslash x_i} f_a(x_a) \prod_{\substack{{j \in N(a)} j \neq i}}\mu^{(k)}_{aj}(x_j) \mu_{ai}^{(k)}(x_i) \\ +&= \prod_{\substack{c \in N(i) c \neq a}}\mu^{(k)}_{ic}(x_i)\,, +\end{align*} +``` + +where ``k`` denotes iteration number and the messages are defined as + +```math +\begin{align*} +\mu_{ia}(x_i) &\triangleq \exp(\lambda_{ia}(x_i))\\ +\mu_{ai}(x_i) &\triangleq \exp(\lambda_{ai}(x_i))\,. +\end{align*} +``` + +For a more complete overview of message passing as Bethe Free Energy minimization, see [Senoz et al. (2021)](https://research.tue.nl/nl/publications/variational-message-passing-and-local-constraint-manipulation-in-). + +""" + +# ╔═╡ 55570464-89c8-4d9b-b667-dfa64ac62294 +md""" +# Code +""" + +# ╔═╡ c18b7c1b-8011-469b-ad92-7d50c23c46e3 +const plot_lims = ( + xlim=(1.3, 5.5), + ylim=(41, 99), +) + +# ╔═╡ d208f60e-56ea-4767-bd18-f29a853b7536 +const cluster_colors = color_list(:seaborn_bright6) + +# ╔═╡ 0e9e62ea-1b2f-4e80-b78b-2001ae46093f +function get_color(xs; colors=cluster_colors) + if any(isnan, xs) + mean(cluster_colors) + else + sum(x*c for (x,c) in zip(xs, colors)) + end +end + +# ╔═╡ dd1242db-fb20-4732-ac55-a3e021bbd2b7 +const data_plot_kwargs = ( + markersize=4, + markerstrokewidth=0, + color=:red4, + opacity=.8, +) + +# ╔═╡ 489cbd24-1a69-4a00-a2e9-53c2c57cef65 +function plotGMM(X::Matrix, clusters::Vector, γ::Matrix; kwargs...) + # Plot data set and (fitted) mixture model consisting of two Gaussian distributions + # X contains a 2-d data set (every column holds a data point) + # clusters holds the 2 Gaussian elements of the mixture model + # γ contains p(cluster|X), and should contain NaN elements if not yet known + + # Plot contours of the element distributions + K = length(clusters) + result = plot(; plot_lims...) + for k=1:K + X1 = Matrix{Float64}(undef,50,50) + X2 = Matrix{Float64}(undef,50,50) + d = Matrix{Float64}(undef,50,50) + # Create bounding box for thse contour plot + lims = [-2*sqrt(cov(clusters[k])[1,1]) 2*sqrt(cov(clusters[k])[1,1]); + -2*sqrt(cov(clusters[k])[2,2]) 2*sqrt(cov(clusters[k])[2,2])] + repeat(mean(clusters[k]), 1, 2) + X1 = LinRange(lims[1,1], lims[1,2], 50) + X2 = LinRange(lims[2,1], lims[2,2], 50) + alpha = sum(γ[k,:])/sum(γ) + covellipse!(clusters[k].μ, clusters[k].Σ; label="", n_std=2, alpha=max(0.0, alpha), color=cluster_colors[k]) + end + + + # Plot data points + scatter!( + X[1,:], X[2,:]; + label="observations", + data_plot_kwargs..., + color=get_color.(eachcol(γ)), + kwargs... + ) + return result +end + +# ╔═╡ cc547bfa-a130-4382-af47-73de56e4741b +old_faithful = + # CSV.read(download("https://github.com/bmlip/course/blob/v2/assets/datasets/old_faithful.csv?raw=true"), DataFrame); + + # inlining the dataset is the most reliable :)s +[ + 3.600000 79.000000 + 1.800000 54.000000 + 3.333000 74.000000 + 2.283000 62.000000 + 4.533000 85.000000 + 2.883000 55.000000 + 4.700000 88.000000 + 3.600000 85.000000 + 1.950000 51.000000 + 4.350000 85.000000 + 1.833000 54.000000 + 3.917000 84.000000 + 4.200000 78.000000 + 1.750000 47.000000 + 4.700000 83.000000 + 2.167000 52.000000 + 1.750000 62.000000 + 4.800000 84.000000 + 1.600000 52.000000 + 4.250000 79.000000 + 1.800000 51.000000 + 1.750000 47.000000 + 3.450000 78.000000 + 3.067000 69.000000 + 4.533000 74.000000 + 3.600000 83.000000 + 1.967000 55.000000 + 4.083000 76.000000 + 3.850000 78.000000 + 4.433000 79.000000 + 4.300000 73.000000 + 4.467000 77.000000 + 3.367000 66.000000 + 4.033000 80.000000 + 3.833000 74.000000 + 2.017000 52.000000 + 1.867000 48.000000 + 4.833000 80.000000 + 1.833000 59.000000 + 4.783000 90.000000 + 4.350000 80.000000 + 1.883000 58.000000 + 4.567000 84.000000 + 1.750000 58.000000 + 4.533000 73.000000 + 3.317000 83.000000 + 3.833000 64.000000 + 2.100000 53.000000 + 4.633000 82.000000 + 2.000000 59.000000 + 4.800000 75.000000 + 4.716000 90.000000 + 1.833000 54.000000 + 4.833000 80.000000 + 1.733000 54.000000 + 4.883000 83.000000 + 3.717000 71.000000 + 1.667000 64.000000 + 4.567000 77.000000 + 4.317000 81.000000 + 2.233000 59.000000 + 4.500000 84.000000 + 1.750000 48.000000 + 4.800000 82.000000 + 1.817000 60.000000 + 4.400000 92.000000 + 4.167000 78.000000 + 4.700000 78.000000 + 2.067000 65.000000 + 4.700000 73.000000 + 4.033000 82.000000 + 1.967000 56.000000 + 4.500000 79.000000 + 4.000000 71.000000 + 1.983000 62.000000 + 5.067000 76.000000 + 2.017000 60.000000 + 4.567000 78.000000 + 3.883000 76.000000 + 3.600000 83.000000 + 4.133000 75.000000 + 4.333000 82.000000 + 4.100000 70.000000 + 2.633000 65.000000 + 4.067000 73.000000 + 4.933000 88.000000 + 3.950000 76.000000 + 4.517000 80.000000 + 2.167000 48.000000 + 4.000000 86.000000 + 2.200000 60.000000 + 4.333000 90.000000 + 1.867000 50.000000 + 4.817000 78.000000 + 1.833000 63.000000 + 4.300000 72.000000 + 4.667000 84.000000 + 3.750000 75.000000 + 1.867000 51.000000 + 4.900000 82.000000 + 2.483000 62.000000 + 4.367000 88.000000 + 2.100000 49.000000 + 4.500000 83.000000 + 4.050000 81.000000 + 1.867000 47.000000 + 4.700000 84.000000 + 1.783000 52.000000 + 4.850000 86.000000 + 3.683000 81.000000 + 4.733000 75.000000 + 2.300000 59.000000 + 4.900000 89.000000 + 4.417000 79.000000 + 1.700000 59.000000 + 4.633000 81.000000 + 2.317000 50.000000 + 4.600000 85.000000 + 1.817000 59.000000 + 4.417000 87.000000 + 2.617000 53.000000 + 4.067000 69.000000 + 4.250000 77.000000 + 1.967000 56.000000 + 4.600000 88.000000 + 3.767000 81.000000 + 1.917000 45.000000 + 4.500000 82.000000 + 2.267000 55.000000 + 4.650000 90.000000 + 1.867000 45.000000 + 4.167000 83.000000 + 2.800000 56.000000 + 4.333000 89.000000 + 1.833000 46.000000 + 4.383000 82.000000 + 1.883000 51.000000 + 4.933000 86.000000 + 2.033000 53.000000 + 3.733000 79.000000 + 4.233000 81.000000 + 2.233000 60.000000 + 4.533000 82.000000 + 4.817000 77.000000 + 4.333000 76.000000 + 1.983000 59.000000 + 4.633000 80.000000 + 2.017000 49.000000 + 5.100000 96.000000 + 1.800000 53.000000 + 5.033000 77.000000 + 4.000000 77.000000 + 2.400000 65.000000 + 4.600000 81.000000 + 3.567000 71.000000 + 4.000000 70.000000 + 4.500000 81.000000 + 4.083000 93.000000 + 1.800000 53.000000 + 3.967000 89.000000 + 2.200000 45.000000 + 4.150000 86.000000 + 2.000000 58.000000 + 3.833000 78.000000 + 3.500000 66.000000 + 4.583000 76.000000 + 2.367000 63.000000 + 5.000000 88.000000 + 1.933000 52.000000 + 4.617000 93.000000 + 1.917000 49.000000 + 2.083000 57.000000 + 4.583000 77.000000 + 3.333000 68.000000 + 4.167000 81.000000 + 4.333000 81.000000 + 4.500000 73.000000 + 2.417000 50.000000 + 4.000000 85.000000 + 4.167000 74.000000 + 1.883000 55.000000 + 4.583000 77.000000 + 4.250000 83.000000 + 3.767000 83.000000 + 2.033000 51.000000 + 4.433000 78.000000 + 4.083000 84.000000 + 1.833000 46.000000 + 4.417000 83.000000 + 2.183000 55.000000 + 4.800000 81.000000 + 1.833000 57.000000 + 4.800000 76.000000 + 4.100000 84.000000 + 3.966000 77.000000 + 4.233000 81.000000 + 3.500000 87.000000 + 4.366000 77.000000 + 2.250000 51.000000 + 4.667000 78.000000 + 2.100000 60.000000 + 4.350000 82.000000 + 4.133000 91.000000 + 1.867000 53.000000 + 4.600000 78.000000 + 1.783000 46.000000 + 4.367000 77.000000 + 3.850000 84.000000 + 1.933000 49.000000 + 4.500000 83.000000 + 2.383000 71.000000 + 4.700000 80.000000 + 1.867000 49.000000 + 3.833000 75.000000 + 3.417000 64.000000 + 4.233000 76.000000 + 2.400000 53.000000 + 4.800000 94.000000 + 2.000000 55.000000 + 4.150000 76.000000 + 1.867000 50.000000 + 4.267000 82.000000 + 1.750000 54.000000 + 4.483000 75.000000 + 4.000000 78.000000 + 4.117000 79.000000 + 4.083000 78.000000 + 4.267000 78.000000 + 3.917000 70.000000 + 4.550000 79.000000 + 4.083000 70.000000 + 2.417000 54.000000 + 4.183000 86.000000 + 2.217000 50.000000 + 4.450000 90.000000 + 1.883000 54.000000 + 1.850000 54.000000 + 4.283000 77.000000 + 3.950000 79.000000 + 2.333000 64.000000 + 4.150000 75.000000 + 2.350000 47.000000 + 4.933000 86.000000 + 2.900000 63.000000 + 4.583000 85.000000 + 3.833000 82.000000 + 2.083000 57.000000 + 4.367000 82.000000 + 2.133000 67.000000 + 4.350000 74.000000 + 2.200000 54.000000 + 4.450000 83.000000 + 3.567000 73.000000 + 4.500000 73.000000 + 4.150000 88.000000 + 3.817000 80.000000 + 3.917000 71.000000 + 4.450000 83.000000 + 2.000000 56.000000 + 4.283000 79.000000 + 4.767000 78.000000 + 4.533000 84.000000 + 1.850000 58.000000 + 4.250000 83.000000 + 1.983000 43.000000 + 2.250000 60.000000 + 4.750000 75.000000 + 4.117000 81.000000 + 2.150000 46.000000 + 4.417000 90.000000 + 1.817000 46.000000 + 4.467000 74.000000 +] + +# ╔═╡ 0349720e-5de4-4b39-babd-c0881588f1de +X = Array(Matrix{Float64}(old_faithful)') + +# ╔═╡ 3948225e-90d8-4b78-ba9b-5f98e228285a +scatter(X[1,:], X[2,:]; label="observations", data_plot_kwargs...) + +# ╔═╡ 8555aec9-4e80-49e7-8514-ef4a2236801b +N = size(X, 2) + +# ╔═╡ 86c33a7c-135a-461f-a17e-b50bca418e13 +function sufficientStatistics(X,r,k::Int) #function to compute sufficient statistics + N_k = sum(r[k,:]) + hat_x_k = sum([r[k,n]*X[:,n] for n in 1:N]) ./ N_k + S_k = sum([r[k,n]*(X[:,n]-hat_x_k)*(X[:,n]-hat_x_k)' for n in 1:N]) ./ N_k + return N_k, hat_x_k, S_k +end + +# ╔═╡ 98a0ed70-a627-48d6-a1f8-3dec7aba2bb2 +function updateMeanPrecisionPi(m_0,β_0,W_0,ν_0,α_0,r) #variational maximisation function + m = Array{Float64}(undef,2,K) #mean of the clusters + β = Array{Float64}(undef,K) #precision scaling for Gausian distribution + W = Array{Float64}(undef,2,2,K) #precision prior for Wishart distributions + ν = Array{Float64}(undef,K) #degrees of freedom parameter for Wishart distribution + α = Array{Float64}(undef,K) #Dirichlet distribution parameter + for k=1:K + sst = sufficientStatistics(X,r,k) + α[k] = α_0[k] + sst[1]; β[k] = β_0[k] + sst[1]; ν[k] = ν_0[k] .+ sst[1] + m[:,k] = (1/β[k])*(β_0[k].*m_0[:,k] + sst[1].*sst[2]) + W[:,:,k] = inv(inv(W_0[:,:,k])+sst[3]*sst[1] + ((β_0[k]*sst[1])/(β_0[k]+sst[1])).*(sst[2]-m_0[:,k])*(sst[2]-m_0[:,k])') + end + return m,β,W,ν,α +end + +# ╔═╡ 55a1c42b-20d8-47a3-aa00-7af905db537c +function updateR(Λ,m,α,ν,β) #variational expectation function + r = Array{Float64}(undef,K,N) #responsibilities + hat_π = Array{Float64}(undef,K) + hat_Λ = Array{Float64}(undef,K) + for k=1:K + hat_Λ[k] = 1/2*(2*log(2)+logdet(Λ[:,:,k])+digamma(ν[k]/2)+digamma((ν[k]-1)/2)) + hat_π[k] = exp(digamma(α[k])-digamma(sum(α))) + for n=1:N + r[k,n] = hat_π[k]*exp(hat_Λ[k]-1/β[k] - (ν[k]/2)*(X[:,n]-m[:,k])'*Λ[:,:,k]*(X[:,n]-m[:,k])) + end + end + for n=1:N + r[:,n] = r[:,n] ./ sum(r[:,n]) #normalize to ensure r represents probabilities + end + return r +end + +# ╔═╡ 4ee377c2-a126-4c40-8053-517d40c5ef9d +vfem_result = let + #store the inference results in these vectors + ν = fill(3.0, K, max_iterations) + β = fill(1.0, K, max_iterations) + α = fill(0.01, K, max_iterations) + R = Array{Float64}(undef,K,N,max_iterations) + M = Array{Float64}(undef,2,K,max_iterations) + Λ = Array{Float64}(undef,2,2,K,max_iterations) + clusters_vb = Array{Distribution}(undef,K,max_iterations) #clusters to be plotted + #initialize prior distribution parameters + M[:,:,1] = rand(MersenneTwister(43), 2, K) .* [4, 50] .+ [1, 50] + for k in 1:K + Λ[:,:,k,1] = [1.0 0;0 0.01] + R[k,:,1] = 1/(K)*ones(N) + clusters_vb[k,1] = MvNormal(M[:,k,1],PDMats.PDMat(convert(Matrix,Hermitian(inv(ν[1,1].*Λ[:,:,k,1]))))) + end + #variational inference + for i in 1:max_iterations-1 + #variational expectation + R[:,:,i+1] = updateR(Λ[:,:,:,i],M[:,:,i],α[:,i],ν[:,i],β[:,i]) + #variational minimisation + M[:,:,i+1],β[:,i+1],Λ[:,:,:,i+1],ν[:,i+1],α[:,i+1] = updateMeanPrecisionPi(M[:,:,i],β[:,i],Λ[:,:,:,i],ν[:,i],α[:,i],R[:,:,i+1]) + for k in 1:K + clusters_vb[k,i+1] = MvNormal(M[:,k,i+1],PDMats.PDMat(convert(Matrix,Hermitian(inv(ν[k,i+1].*Λ[:,:,k,i+1]))))) + end + end + + + (; clusters_vb, R) + +end + +# ╔═╡ 663ac0ef-0577-43af-8df5-15e046ef875c +let + i = iteration_vfem + 1 + plotGMM( + X, vfem_result.clusters_vb[:,i], vfem_result.R[:,:,i]; + title=i == 1 ? "Initial situation" : "After $(iteration_vfem) iteration$(iteration_vfem > 1 ? "s" : "")", + legend=nothing, + size=(600,300), + ) +end + +# ╔═╡ cd7cf2d0-aff7-49dc-bb12-dc73c6433768 +let + i = iteration_vfem + 1 + + # Get the current iteration's parameters + current_clusters = vfem_result.clusters_vb[:, i] + current_responsibilities = vfem_result.R[:, :, i] + + # Compute mixture weights (π) from responsibilities + π = vec(mean(current_responsibilities, dims=2)) + π = π ./ sum(π) # Normalize to ensure they sum to 1 + + # Generate synthetic data of the same size as original + N_synthetic = size(X, 2) # Same number of points as original data + X_synthetic = Matrix{Float64}(undef, 2, N_synthetic) + + # Sample from the mixture model + Random.seed!(42) # For reproducibility + components = rand(Categorical(π), N_synthetic) + + for n in 1:N_synthetic + # Sample which component to use + # Sample from that component + X_synthetic[:, n] = rand(current_clusters[components[n]]) + end + + # Create the plot + scatter( + X_synthetic[1,:], X_synthetic[2,:]; + title="Synthetic data from this model", + size=(600,300), + legend=nothing, + plot_lims..., + data_plot_kwargs..., + color=show_vfem_synthetic_labels ? cluster_colors[components] : :purple, + ) +end + +# ╔═╡ 7a3c0ff7-0b32-4954-ae28-b644f4d966ef +begin + # Initialize the GMM. We assume 2 clusters. + clusters = [MvNormal([4.;60.], [.5 0;0 10^2]); + MvNormal([2.;80.], [.5 0;0 10^2])]; + π_hat = [0.5; 0.5] # Mixing weights + γ = fill!(Matrix{Float64}(undef,2,N), NaN) # Responsibilities (row per cluster) + + # Define functions for updating the parameters and responsibilities + function updateResponsibilities!(γ, X, clusters, π_hat) + # Expectation step: update γ + norm = [pdf(clusters[1], X) pdf(clusters[2], X)] * π_hat + γ[1,:] = (π_hat[1] * pdf(clusters[1],X) ./ norm)' + γ[2,:] = 1 .- γ[1,:] + end + + function updateParameters!(clusters, π_hat, X, γ) + # Maximization step: update π_hat and clusters using ML estimation + m = sum(γ, dims=2) + + # [:] to update contents of π_hat, not create a new local variable + π_hat[:] = m / N + μ_hat = (X * γ') ./ m' + for k=1:2 + Z = (X .- μ_hat[:,k]) + Σ_k = Symmetric(((Z .* (γ[k,:])') * Z') / m[k]) + clusters[k] = MvNormal(μ_hat[:,k], convert(Matrix, Σ_k)) + end + end + + + rec() = deepcopy((; clusters, γ)) + em_result = [ + (0, :initial) => rec(), + ] + + # Execute the algorithm: iteratively update parameters and responsibilities + for i in 1:10 + updateResponsibilities!(γ, X, clusters, π_hat) + push!(em_result, (i, :E) => rec()) + + updateParameters!(clusters, π_hat, X, γ) + push!(em_result, (i, :M) => rec()) + end + + Text("em_result") +end + +# ╔═╡ 5af3ff1b-1655-4dd9-a089-91544fc85a0e +@bindname iteration_em Slider(eachindex(em_result); default=2, show_value=i->join(em_result[i][1], "-")) + +# ╔═╡ fd233604-120a-4838-a660-d5021bccecd0 +let + (i, step), res = em_result[iteration_em] + + plotGMM( + X, res.clusters, res.γ; + title=i == 0 ? + "Initial situation" : + "Iteration $(i), $(step)-step", + legend=nothing, + size=(600,300), + ) +end + +# ╔═╡ a7fb83cb-1f40-4c8a-9fda-2165f91e413e +let + (i, step), res = em_result[iteration_em] + + # Get the current iteration's parameters + current_clusters = res.clusters + current_responsibilities = res.γ + + + # Compute mixture weights (π) from responsibilities + π = vec(mean(current_responsibilities, dims=2)) + if any(isnan, π) + π = ones(size(π)) + end + π = π ./ sum(π) # Normalize to ensure they sum to 1 + + + # Generate synthetic data of the same size as original + N_synthetic = size(X, 2) # Same number of points as original data + X_synthetic = Matrix{Float64}(undef, 2, N_synthetic) + + # Sample from the mixture model + Random.seed!(42) # For reproducibility + components = rand(Categorical(π), N_synthetic) + for n in 1:N_synthetic + # Sample which component to use + # Sample from that component + X_synthetic[:, n] = rand(current_clusters[components[n]]) + end + + # Create the plot + scatter( + X_synthetic[1,:], X_synthetic[2,:]; + title="Synthetic data from this model", + size=(600,300), + legend=nothing, + plot_lims..., + data_plot_kwargs..., + color=show_em_synthetic_labels ? cluster_colors[components] : :purple, + ) +end + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" +StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd" + +[compat] +BmlipTeachingTools = "~1.3.1" +Distributions = "~0.25.122" +PDMats = "~0.11.36" +Plots = "~1.40.17" +SpecialFunctions = "~2.6.1" +StatsPlots = "~0.15.8" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "0e46b49a348ca542dcb870e7a80b150862787303" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.4.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Arpack]] +deps = ["Arpack_jll", "Libdl", "LinearAlgebra", "Logging"] +git-tree-sha1 = "9b9b347613394885fd1c8c7729bfc60528faa436" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.5.4" + +[[deps.Arpack_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "OpenBLAS_jll", "Pkg"] +git-tree-sha1 = "5ba6c757e8feccf03a1554dfaf3e26b3cfc7fd5e" +uuid = "68821587-b530-5797-8361-c406ea357684" +version = "3.5.1+1" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "e4c6a16e77171a5f5e25e9646617ab1c276c5607" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.26.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.Clustering]] +deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "Random", "SparseArrays", "Statistics", "StatsBase"] +git-tree-sha1 = "3e22db924e2945282e70c33b75d4dde8bfa44c94" +uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5" +version = "0.15.8" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.12" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "97f08406df914023af55ade2f843c39e99c5d969" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.10.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.11+0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2025.2.0+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "65d505fa4c0d7072990d659ef3fc086eb6da8208" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.16.2" + + [deps.Interpolations.extensions] + InterpolationsForwardDiffExt = "ForwardDiff" + InterpolationsUnitfulExt = "Unitful" + + [deps.Interpolations.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "ba51324b894edaf1df3ab16e2cc6bc3280a2f1a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.10" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +version = "1.11.0" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "282cadc186e7b2ae0eeadbd7a4dffed4196ae2aa" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2025.2.0+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.MultivariateStats]] +deps = ["Arpack", "Distributions", "LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI", "StatsBase"] +git-tree-sha1 = "816620e3aac93e5b5359e4fdaf23ca4525b00ddf" +uuid = "6f286f6a-111f-5878-ab1e-185364afe411" +version = "0.10.3" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "ca7e18198a166a1f3eb92a3650d53d94ed8ca8a1" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.22" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.OffsetArrays]] +git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.17.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.8" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.15" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StatsPlots]] +deps = ["AbstractFFTs", "Clustering", "DataStructures", "Distributions", "Interpolations", "KernelDensity", "LinearAlgebra", "MultivariateStats", "NaNMath", "Observables", "Plots", "RecipesBase", "RecipesPipeline", "Reexport", "StatsBase", "TableOperations", "Tables", "Widgets"] +git-tree-sha1 = "88cf3587711d9ad0a55722d339a013c4c56c5bbc" +uuid = "f3b207a7-027a-5e70-b257-86293d7955fd" +version = "0.15.8" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableOperations]] +deps = ["SentinelArrays", "Tables", "Test"] +git-tree-sha1 = "e383c87cf2a1dc41fa30c093b2a19877c83e1bc1" +uuid = "ab02a1b2-a7df-11e8-156e-fb1833f50b87" +version = "1.2.0" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.12.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.Widgets]] +deps = ["Colors", "Dates", "Observables", "OrderedCollections"] +git-tree-sha1 = "e9aeb174f95385de31e70bd15fa066a505ea82b9" +uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" +version = "0.6.7" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─26c56fd8-d294-11ef-236d-81deef63f37c +# ╟─ce7d086b-ff20-4da1-a4e8-52b5b7dc9e2b +# ╟─26c58298-d294-11ef-2a53-2b42b48e0725 +# ╟─2497529b-7703-4e3e-b9db-83f8dbf43fa8 +# ╟─a663d6d1-2d73-40c6-8a4c-9e41df74bc84 +# ╟─3948225e-90d8-4b78-ba9b-5f98e228285a +# ╟─0349720e-5de4-4b39-babd-c0881588f1de +# ╠═8555aec9-4e80-49e7-8514-ef4a2236801b +# ╟─f8c8013a-3e87-4d01-a3ae-86b39cf1f002 +# ╟─26c59b52-d294-11ef-1eba-d3f235f85eee +# ╟─26c5a1f6-d294-11ef-3565-39d027843fbb +# ╟─26c5a93a-d294-11ef-23a1-cbcf0c370fc9 +# ╟─26c5b896-d294-11ef-1d8e-0feb99d2d45b +# ╟─26c5c1ae-d294-11ef-15c6-13cae5bc0dc8 +# ╟─dff0212b-f3e8-4592-8cd4-f52bcdb782fb +# ╟─26c5cfb4-d294-11ef-05bb-59d5e27cf37c +# ╟─c7351bf1-447e-475b-8965-d259c01bfd57 +# ╟─3deadfd0-9fbb-476a-a7de-5dd694e55a65 +# ╟─26c5d734-d294-11ef-20a3-afd2c3324323 +# ╟─26c5f8d6-d294-11ef-3bcd-4d5e0391698d +# ╟─26c623f6-d294-11ef-13c0-19edd43592c0 +# ╟─26c62ebe-d294-11ef-0cfb-ef186203e890 +# ╟─26c6347c-d294-11ef-056f-7b78a9e22272 +# ╟─26c64174-d294-11ef-2bbc-ab1a84532311 +# ╟─26c65092-d294-11ef-39cc-1953a725f285 +# ╟─f1f7407d-86a1-4f24-b78a-61a411d1f371 +# ╟─26c67f04-d294-11ef-03a4-838ae255689d +# ╟─26c6e002-d294-11ef-15a4-33e30d0d76ec +# ╟─ae7ed1fc-fc36-4327-be55-a142477ca0ad +# ╟─b4d965d1-91d8-43f8-84a5-b37ad5c6cafa +# ╟─18f5d694-8869-4265-98ac-9ef7ff451eaf +# ╟─c4b23b39-e6e4-44ec-b204-0c7d7d5a4026 +# ╟─baec0494-9557-49d1-b4d8-a8030d3281b7 +# ╟─87715fcd-c92e-4bfa-8b0a-15e469548f3d +# ╟─40ce0abb-a086-4977-9131-10f60ab44152 +# ╟─26c6f63c-d294-11ef-1090-e9238dd6ad3f +# ╟─aea77d69-9ecd-4be0-b6fd-c944d27d68df +# ╟─3654551d-5d08-4bb0-8a0d-c7d42225bc69 +# ╟─edb179df-5cff-4e7b-8645-6da4818dceee +# ╟─26c704f6-d294-11ef-1b3d-d52f0fb1c81d +# ╟─26c728f0-d294-11ef-0c01-6143abe8c3f0 +# ╟─06512595-bdb7-4adf-88ae-62af20210891 +# ╟─26c73cf0-d294-11ef-297b-354eb9c71f57 +# ╟─3e897a59-e7b5-492c-8a8a-724248513a72 +# ╟─93e7c7d5-a940-4764-8784-07af2f056e49 +# ╟─26c74c9a-d294-11ef-2d31-67bd57d56d7c +# ╟─26c75b5e-d294-11ef-173e-b3f46a1df536 +# ╟─95d47a10-f3f8-479b-afe0-21241104b758 +# ╟─26c7696e-d294-11ef-25f2-dbc0946c0858 +# ╟─de0c41a3-6319-4ae3-8a1a-ae6935910fa3 +# ╟─663ac0ef-0577-43af-8df5-15e046ef875c +# ╟─26c796c8-d294-11ef-25be-17dcd4a9d315 +# ╟─cd7cf2d0-aff7-49dc-bb12-dc73c6433768 +# ╟─16d90f11-5933-4145-b219-19774eba25d6 +# ╟─8b887c4a-273c-40fe-83e9-5c79ac6946f8 +# ╠═666680b2-315a-4d95-8f7f-3ae50018e112 +# ╠═4e0c025d-fa39-462d-8e7d-e66d220e9595 +# ╟─4ee377c2-a126-4c40-8053-517d40c5ef9d +# ╟─86c33a7c-135a-461f-a17e-b50bca418e13 +# ╟─98a0ed70-a627-48d6-a1f8-3dec7aba2bb2 +# ╟─55a1c42b-20d8-47a3-aa00-7af905db537c +# ╟─f42a1a65-20ce-452f-9974-bc8146943574 +# ╟─26c7b428-d294-11ef-150a-bb37e37f4b5d +# ╟─b3bb7349-1965-4734-83ed-ba6fef0ccc41 +# ╟─06170e31-e865-4178-8af0-41d82df95d71 +# ╟─bbdca8c2-022f-42be-bcf7-80d86f7f269c +# ╟─26c8068a-d294-11ef-3983-a1be55128b3f +# ╟─60a50f12-063c-4247-9c9c-bb41d5dc9811 +# ╟─4ff85bda-22bb-408d-a50a-461834b7c0ff +# ╟─56bea391-b812-4fc4-8f27-fcb4cb984cf4 +# ╟─5a94e2a4-7134-462e-9dc5-56083769049f +# ╟─747a7e1e-b921-4882-b00a-1b00bef8433d +# ╟─2d4adbf6-6de8-4e3a-ad6f-fa8bbfa5999e +# ╟─208ba1bb-a4bf-4b8c-93d2-0d6c6c8d16d4 +# ╟─2f490e1f-e495-4f55-a3f8-60d6fd716d4e +# ╟─b91bc3b6-b815-4942-b297-c0e2b4b99654 +# ╟─26c8160c-d294-11ef-2a74-6f7009a7c51e +# ╟─26c82f16-d294-11ef-0fe1-07326b56282f +# ╟─26c85a22-d294-11ef-3c8e-7b72a4313ced +# ╟─62868f61-95c7-4e07-854f-a171aadc667b +# ╟─26c867d8-d294-11ef-2372-d75ed0bcc02d +# ╟─5af3ff1b-1655-4dd9-a089-91544fc85a0e +# ╟─fd233604-120a-4838-a660-d5021bccecd0 +# ╟─a7fb83cb-1f40-4c8a-9fda-2165f91e413e +# ╟─64819124-865e-48b8-a916-2ce08dba0acc +# ╟─87d94630-c90b-4379-91bd-88641ee7b508 +# ╟─7a3c0ff7-0b32-4954-ae28-b644f4d966ef +# ╟─26c8b682-d294-11ef-1331-2bcf8baec73f +# ╟─26c8c7fa-d294-11ef-0444-6555ecf5c721 +# ╟─f17c9d8a-9291-4110-bcf4-c582d23f986b +# ╟─90fbe618-fc81-480b-b685-69cd97e5b8ed +# ╟─32f0bbb4-dfc7-431e-9a3d-80162439edac +# ╟─26c9121e-d294-11ef-18e6-ed8105503adc +# ╟─55570464-89c8-4d9b-b667-dfa64ac62294 +# ╠═df171940-eb54-48e2-a2b8-1a8162cabf3e +# ╠═c90176ea-918b-4643-a10f-cef277c5ea75 +# ╠═58bd0d43-743c-4745-b353-4a89b35e85ba +# ╠═489cbd24-1a69-4a00-a2e9-53c2c57cef65 +# ╠═c18b7c1b-8011-469b-ad92-7d50c23c46e3 +# ╠═d208f60e-56ea-4767-bd18-f29a853b7536 +# ╠═0e9e62ea-1b2f-4e80-b78b-2001ae46093f +# ╠═dd1242db-fb20-4732-ac55-a3e021bbd2b7 +# ╟─cc547bfa-a130-4382-af47-73de56e4741b +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/Probability Theory Review.jl b/mlss/Probability Theory Review.jl new file mode 100644 index 00000000..3b872cae --- /dev/null +++ b/mlss/Probability Theory Review.jl @@ -0,0 +1,2936 @@ +### A Pluto.jl notebook ### +# v0.20.19 + +#> [frontmatter] +#> description = "Review of probability theory as a foundation for rational reasoning and Bayesian inference." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ eeb9a1f5-b857-4843-920b-2e4a9656f66b +using Plots, LaTeXStrings + +# ╔═╡ 5394e37c-ae00-4042-8ada-3bbf32fbca9e +using Distributions + +# ╔═╡ b305a905-06c2-4a15-8042-72ef6375720f +using BmlipTeachingTools + +# ╔═╡ 42b47af6-b850-4987-a2d7-805a2cb64e43 +# The Disease Diagnosis example uses a combination of: +# - PlutoUI.Scrubbable for the interactive input percentages +# - MarkdownLiteral to be able to interpolate numbers into markdown math +# - PrintF for consistent formatting +using MarkdownLiteral: @mdx + +# ╔═╡ a66ab9df-897c-42e5-8b0f-c520ceaffa23 +using Printf + +# ╔═╡ 3e17df5e-d294-11ef-38c7-f573724871d8 +title("Probability Theory Review") + +# ╔═╡ bcb4be20-0439-4809-a166-8c50b6b9206b +PlutoUI.TableOfContents() + +# ╔═╡ 3e1803d0-d294-11ef-0304-df2b9b698cd1 +md""" +## Preliminaries + +##### Goal + +- Review of Probability Theory as a theory for rational/logical reasoning with uncertainties (i.e., a Bayesian interpretation) + +##### Materials + +- Mandatory + + - These lecture notes + +- Optional + + - Bishop pp. 12-24 + + - [3Blue1Brown, YouTube video on Bayes theorem (2019)](https://youtu.be/HZGCoVF3YvM?si=JaXdesPjU8B_BtrC) + - Nice animated tutorial on Bayes rule. + + - [Edwin Jaynes, Probability Theory–The Logic of Science (2003)](http://www.med.mcgill.ca/epidemiology/hanley/bios601/GaussianModel/JaynesProbabilityTheory.pdf). + - Brilliant book on the Bayesian view of probability theory. Just for fun, scan the annotated bibliography and references. + + - [Aubrey Clayton, Bernoulli's Fallacy–Statistical Illogic and the Crisis of Modern Science (2021)](https://aubreyclayton.com/bernoulli) + - A very readable account of the history of statistics and probability theory. Discusses why most popular statistics recipes are very poor scientific analysis tools. Use probability theory instead! + + - [Ariel Caticha, Entropic Inference and the Foundations of Physics (2012)](https://github.com/bmlip/course/blob/main/assets/files/Caticha-2012-Entropic-Inference-and-the-Foundations-of-Physics.pdf), pp.7-56 (ch.2: probability) + - Great introduction to probability theory, in particular w.r.t. its correct interpretation as a state-of-knowledge. + - Absolutely worth your time to read the whole chapter, even if you skip section 2.2.4 (pp.15-18) on Cox's proof. + + - [Joram Soch et al ., The Book of Statistical Proofs (2023 - )](https://statproofbook.github.io/) + - Online resource for proofs in probability theory and statistical inference. + +""" + +# ╔═╡ 9b9be452-9681-43e8-bb09-cc8728df384f +md""" +## 📕 Data Analysis: A Bayesian Tutorial + +The following is an excerpt from the book [Data Analysis: A Bayesian Tutorial](https://global.oup.com/academic/product/data-analysis-9780198568322) (2006), by D.S. Sivia with J.S. Skilling: +""" + +# ╔═╡ 9f4125a2-d5d2-4acf-8bad-82f94af230e8 +blockquote( + md""" + +#### Preface +"As an undergraduate, I always found the subject of statistics to be rather mysterious. This topic wasn’t entirely new to me, as we had been taught a little bit about probability earlier at high school; for example, I was already familiar with the binomial, Poisson and normal distributions. Most of this made sense, but only seemed to relate to things like rolling dice, flipping coins, shuffling cards and so on. However, having aspirations of becoming a scientist, what I really wanted to know was how to analyse experimental data. Thus, I eagerly looked forward to the lectures on statistics. Sadly, they were a great disappointment. Although many of the tests and procedures expounded were intuitively reasonable, there was something deeply unsatisfactory about the whole affair: there didn’t seem to be any underlying basic principles! Hence, the course on ‘probability and statistics’ had led to an unfortunate dichotomy: probability made sense, but was just a game; statistics was important, but it was a bewildering collection of tests with little obvious rhyme or reason. While not happy with this situation, I decided to put aside the subject and concentrate on real science. After all, the predicament was just a reflection of my own inadequacies and I’d just have to work at it when the time came to really analyse my data. + +The story above is not just my own, but is the all too common experience of many scientists. Fortunately, it doesn’t have to be like this. What we were not told in our undergraduate lectures is that there is an alternative approach to the whole subject of data analysis which uses only probability theory. In one sense, it makes the topic of statistics entirely superfluous. In another, it provides the logical justification for many of the prevalent statistical tests and procedures, making explicit the conditions and approximations implicitly assumed in their use." +""", + # "D.S. Sivia" +) + +# ╔═╡ f8c8ba53-df36-48a6-afde-2952cbcfbe48 +md""" +Does this fragment resonate with your own experience? + +In this lesson we introduce *Probability Theory* (PT) again. As we will see in the next lessons, PT is all you need to make sense of machine learning, artificial intelligence, statistics, etc. + +""" + +# ╔═╡ 61713e1c-8e37-45d9-9f58-c3db69e15b66 +challenge_statement("Disease Diagnosis",header_level=1) + +# ╔═╡ 840ab4dc-0d2e-4bf8-acc7-5f1ee2b0dcaf +md""" +# Probability Theory as Rational Reasoning +""" + +# ╔═╡ 41bee964-a0a9-4a7f-8505-54a9ee12ef0d +md""" +## Propositional (Boolean) Logic + +Define an **event** (or "proposition") ``A`` as a statement that can be considered for its truth by a person. For instance, + +```math +𝐴= \texttt{``there is life on Mars''} +``` + +Boolean logic (or propositional logic) is a formal system of logic based on binary truth values: every proposition is either true (with assigned value ``1``) or false (with assigned value ``0``). It is named after George Boole, who developed the algebraic formulation of logic in the mid-19th century. + +With Boolean operators (``\lor``, ``\land``, ``\implies``, etc.), we can create and evaluate compound propositions, e.g., + +- Given two events ``A`` and ``B``, the **conjunction** (logical-and) ``A \land B`` is true if-and-only-if both ``A`` and ``B`` are true. We write ``A \land B`` also shortly as ``AB`` (or use a comma as in a joint probability distribution ``p(A,B)``). + +- The **disjunction** (logical-or) ``A \lor B``, is true if either ``A`` or ``B`` is true or both ``A`` and ``B`` are true. We write ``A \lor B`` also as ``A + B`` (Note that the plus-sign is here not an arithmetic operator, but rather a logical operator to process truth values.) + +- The denial of ``A``, i.e., the event **not**-A, is written as ``\bar{A}``. + +Boolean logic provides the rules of inference for **deductive reasoning** and underpins all formal reasoning systems in mathematics and philosophy. +""" + +# ╔═╡ 3e1889b8-d294-11ef-17bb-496655fbd618 +md""" +## The Design of Probability Theory + +In the real world, we are rarely completely certain of something. Instead of a truth value for the proposition ``A``, we can attach a **degree-of-belief** ``p(A)`` that represents how likely we think ``A`` is. + +Now consider the truth value of the proposition +```math +𝐴= \texttt{``there is life on Mars''} +``` + +with + +```math +I = \texttt{``All known life forms require water''} +``` + +as background information. Now, assume that a new piece of information + +```math +B = \texttt{``There is water on Mars''} +``` + +becomes available, how **should** our degree of belief in event ``A`` be affected *if we were rational*? + +""" + +# ╔═╡ 3e18b2fa-d294-11ef-1255-df048f0dcec2 +md""" +[Richard T. Cox (1946)](https://aapt.scitation.org/doi/10.1119/1.1990764) developed a **calculus for rational reasoning** about how to represent and update the **degree-of-belief** about the truth value of an event when faced with new information. + +""" + +# ╔═╡ 3e18c25c-d294-11ef-11bc-a93c2572b107 +md""" +In developing this calculus, only some very agreeable assumptions were made, including: + +- Degrees of belief are represented by real numbers. + +- Plausibility assessments are consistent, e.g., + - if ``A`` becomes more plausible under new information ``B``, the assigned degree-of-belief should increase accordingly. + - If the belief in ``A`` is greater than the belief in ``B``, and the belief in ``B`` is greater than the belief in ``C``, then the belief in ``A`` must be greater than the belief in ``C``. + +- Logical equivalences are preserved, e.g., + - If the belief in an event can be inferred in two different ways, for example, either by first updating on information ``I_1`` and then ``I_2`` or the other way around, then the two ways must agree on the resulting belief. + +""" + +# ╔═╡ 3e18d2ea-d294-11ef-35e9-2332dd31dbf0 +md""" +Under these assumptions, Cox showed that any consistent system of reasoning about uncertainty must obey the **rules of probability theory** (see [Cox theorem, 1946](https://en.wikipedia.org/wiki/Cox%27s_theorem), and [Caticha, 2012](https://github.com/bmlip/course/blob/main/assets/files/Caticha-2012-Entropic-Inference-and-the-Foundations-of-Physics.pdf), pp.7-26). These rules are the sum and product rules: + +##### The sum rule + +- The degree of belief in the disjunction of two events ``A`` and ``B``, with given background information ``I``, is evaluated as + +```math + p(A+B|I) = p(A|I) + p(B|I) - p(A,B|I) +``` + +##### The product rule + +- The degree of belief in the conjunction of two events ``A`` and ``B``, with given background information ``I``, is evaluated as + +```math + p(A,B|I) = p(A|B,I)\,p(B|I) +``` + +Cox’s Theorem derives the rules of probability theory from first principles, not as arbitrary postulates but as consequences of rational reasoning. +In other words: **Probability = extended logic**. + +""" + +# ╔═╡ dd11e93a-3dad-4e97-8642-fb70edfa6aae +md""" +##### Some notational conventions + +In the above sum and product rules, + - the **conditional probability** of ``A`` given ``I``, denoted by ``p(A|I)``, indicates the degree of belief in event ``A``, given that ``I`` is true. +- ``p(A,B|I)`` should be read as the *joint* probabability that both ``A`` and ``B`` are true, given that ``I`` is true. +- Similarly, ``p(A|B,I)`` is the probability that ``A`` is true, given that both ``B`` and ``I`` are true. + + +""" + +# ╔═╡ 3e18e4bc-d294-11ef-38bc-cb97cb4e0963 +keyconcept(" ", + md""" + + When assigning real numbers to **degrees of belief**, logical consistency forces adherence to the sum and product rules of probability theory. This makes probability theory the optimal framework for information processing in the face of uncertainty. + + """ +) + +# ╔═╡ 3e18f18c-d294-11ef-33e4-b7f9495e0508 +md""" +## Why Probability Theory for Machine Learning? + +Machine learning concerns updating our beliefs about appropriate settings for model parameters from new information (namely a data set), and therefore PT provides the *optimal calculus for machine learning*. + +""" + +# ╔═╡ 3e1906ea-d294-11ef-236e-c966a9474170 +md""" +In general, nearly all interesting questions in machine learning (and information processing in general) can be stated in the following form (a conditional probability): + +```math +p(\texttt{whatever-we-want-to-know}\, | \,\texttt{whatever-we-do-know}) +``` + +where ``p(A|B)`` means the probability that ``A`` is true, given that ``B`` is true. + +""" + +# ╔═╡ 3e191b6c-d294-11ef-3174-d1b4b36e252b +md""" +##### Examples + + * Predictions + +```math +p(\,\texttt{future-observations}\,|\,\texttt{past-observations}\,) +``` + + * Classify a received data point ``x`` + +```math +p(\,x\texttt{-belongs-to-class-}k \,|\,x\,) +``` + + * Update a model based on a new observation + +```math +p(\,\texttt{model-parameters} \,|\,\texttt{new-observation},\,\texttt{past-observations}\,) +``` + +""" + +# ╔═╡ 3e192ef4-d294-11ef-1fc4-87175eeec5eb +md""" +## Frequentist vs. Bayesian Interpretation of Probabilities + +The interpretation of a probability as a **degree-of-belief** about the truth value of an event is also called the **Bayesian** interpretation. + +""" + +# ╔═╡ 3e19436c-d294-11ef-11c5-f9914f7a3a57 +md""" +In the **Bayesian** interpretation, the probability is associated with a **state-of-knowledge** (usually held by a person, but formally by a rational agent). + + * For instance, in a coin tossing experiment, ``p(\texttt{outcome} = \texttt{tail}) = 0.4`` should be interpreted as the belief that there is a 40% chance that ``\texttt{tail}`` comes up if the coin were tossed. + * Under the Bayesian interpretation, PT calculus (sum and product rules) **extends boolean logic to rational reasoning with uncertainty**. + +""" + +# ╔═╡ 4edf38ab-a940-4ab0-be22-fa95cf571146 +md""" +In the Bayesian interpretation, all probabilities are, in principle, conditional probabilities of the type ``p(A|I)``, since there is always some background knowledge. However, we often write ``p(A)`` rather than ``p(A|I)`` if the background knowledge ``I`` is assumed to be obviously present. E.g., we usually write ``p(A)`` rather than ``p(\,A\,|\,\text{the-sun-comes-up-tomorrow}\,)``. + +""" + +# ╔═╡ 3e194ef2-d294-11ef-3b38-1ddc3063ff35 +md""" +The Bayesian interpretation contrasts with the **frequentist** interpretation of a probability as the relative frequency that an event would occur under repeated execution of an experiment. + + * For instance, if the experiment is tossing a coin, then ``p(\texttt{outcome} = \texttt{tail}) = 0.4`` means that in the limit of a large number of coin tosses, 40% of outcomes turn up as ``\texttt{tail}``. + +""" + +# ╔═╡ 3e1964b4-d294-11ef-373d-712257fc130f +md""" +The Bayesian viewpoint is more generally applicable than the frequentist viewpoint, e.g., it is hard to apply the frequentist viewpoint to events like ``\texttt{"it will rain tomorrow"}``. + +""" + +# ╔═╡ 3e196d6a-d294-11ef-0795-41c045079251 +md""" +The Bayesian viewpoint is clearly favored in the machine learning community. (In this class, we also strongly favor the Bayesian interpretation). + +""" + +# ╔═╡ 3e198336-d294-11ef-26fd-03cd15876486 +md""" +Aubrey Clayton, in his wonderful book [Bernoulli's fallacy](https://aubreyclayton.com/bernoulli) (2021), writes about this issue: + +> “Compared with Bayesian methods, standard [frequentist] statistical techniques use only a small fraction of the available information about a research hypothesis (how well it predicts some observation), so naturally they will struggle when that limited information proves inadequate. Using standard statistical methods is like driving a car at night on a poorly lit highway: to keep from going in a ditch, we could build an elaborate system of bumpers and guardrails and equip the car with lane departure warnings and sophisticated navigation systems, and even then we could at best only drive to a few destinations. Or we could turn on the headlights.” + + +""" + +# ╔═╡ 3e198ba6-d294-11ef-3fe7-d70bf4833fa6 +md""" +In this class, we aim to turn on the headlights and illuminate the elegance and power of the Bayesian approach to information processing. + +""" + +# ╔═╡ 3e19e95a-d294-11ef-3da4-6d23922a5150 +md""" +## Variable Assignments as Propositions + + +""" + +# ╔═╡ 3e1a69f4-d294-11ef-103e-efc47025fb8f +md""" +If ``X`` is a variable, then an *assignment* ``X=x`` (where ``x`` is a value, e.g., ``X=5``) can be interpreted as an event. Hence, the expression ``p(X=5)`` should be interpreted as the *degree-of-belief of the event* that variable ``X`` takes on the value ``5``. + +""" + +# ╔═╡ 3e1a7c8e-d294-11ef-1f97-55e608d49141 +md""" +If ``X`` is a *discretely* valued variable, then ``p(X=x)`` is a probability *mass* function (PMF) with ``0\le p(X=x)\le 1`` and normalization ``\sum_x p(x) =1``. + +""" + +# ╔═╡ 3e1a8eca-d294-11ef-1ef0-c15b24d05990 +md""" +If ``X`` is *continuously* valued, then ``p(X=x)`` is a probability *density* function (PDF) with ``p(X=x)\ge 0`` and normalization ``\int_x p(x)\mathrm{d}x=1``. + + * Note that if ``X`` is continuously valued, then the value of ``p(x)`` is not necessarily ``\le 1``. E.g., a uniform distribution on the continuous domain ``[0,.5]`` has value ``p(x) = 2`` over its domain. + +""" + +# ╔═╡ 3e1fc4da-d294-11ef-12f5-d51f9728fcc0 +md""" +## Notational Conventions + +Here is a notational convention that you should be precise about (but many authors are not). + +If you want to write that a variable ``x`` is distributed as a Gaussian with mean ``\mu`` and covariance matrix ``\Sigma``, you can write this in either of two ways: + +```math +\begin{align*} +p(x) &= \mathcal{N}(x|\mu,\Sigma) \\ +x &\sim \mathcal{N}(\mu,\Sigma) +\end{align*} +``` + +In the second version, the symbol ``\sim`` can be interpreted as "is distributed as" (a Gaussian with parameters ``\mu`` and ``\Sigma``). + +Don't write ``p(x) = \mathcal{N}(\mu,\Sigma)`` because ``p(x)`` is a function of ``x`` but ``\mathcal{N}(\mu,\Sigma)`` is not. + +Also, ``x \sim \mathcal{N}(x|\mu,\Sigma)`` is not entirely proper because you already named the argument on the right-hand-site. On the other hand, ``x \sim \mathcal{N}(\cdot|\mu,\Sigma)`` is fine, as is the shorter ``x \sim \mathcal{N}(\mu,\Sigma)``. + +""" + +# ╔═╡ 3e1ab104-d294-11ef-1a98-412946949fba +md""" +# $(HTML("Probability Theory Calculus")) + +""" + +# ╔═╡ fea8ae4c-8ef9-4b74-ad13-1314afef97de +md""" +## True and False Events + +In probability theory, events that are certainly true or certainly false are treated as special cases of general events, and they correspond to probabilities of ``1`` and ``0``, respectively. + +Let ``\Omega`` be the sample space, i.e., the set of all possible outcomes of an experiment. Then: + - The true event corresponds to the entire sample space ``\Omega``. + - It always happens, regardless of the outcome. + - For example, for the outcome of a throw of a dice, the sample space is ``\Omega = \{1,2,3,4,5,6\}``. + - Its probability is +```math +p(\Omega) = 1\,. +``` + +The false event corresponds to the empty set ``\emptyset``. + - It never happens (no possible outcomes). + - Its probability is +```math +p(\emptyset) = 0 \,. +``` + +""" + +# ╔═╡ 3e1b4b1c-d294-11ef-0423-9152887cc403 +md""" +## Independent, Exclusive, and Exhaustive Events + +It will be helpful to introduce some terms concerning special relationships between events. + +##### Joint events + +The expression ``p(A,B)`` for the probability of the conjuction ``A \land B`` is also called the **joint probability** of events ``A`` and ``B``. Note that + +```math +p(A,B) = p(B,A)\,, +``` + +since ``A\land B = B \land A``. Therefore, the order of arguments in a joint probability distribution does not matter: ``p(A,B,C,D) = p(C,A,D,B)``, etc. + +##### Independent events + +Two events ``A`` and ``B`` are said to be **independent** if the probability of one event is not altered by information about the truth of the other event, i.e., + +```math +p(A|B) = p(A)\,. +``` + +It follows that, if ``A`` and ``B`` are independent, then the product rule simplifies to + +```math +p(A,B) = p(A) p(B)\,. +``` + +``A`` and ``B`` with given background ``I`` are said to be **conditionally independent** for given ``I``, if + +```math +p(A|B,I) = p(A|I)\,. +``` + +In that case, the product rule simplifies to ``p(A,B|I) = p(A|I) p(B|I)``. + +##### Mutually exclusive events + +Two events ``A_1`` and ``A_2`` are said to be **mutually exclusive** ('disjoint') if they cannot be true simultaneously, i.e., if + +```math +p(A_1,A_2)=0 \,. +``` + +For mutually exclusive events, probabilities add (this follows from the sum rule), hence + +```math +p(A_1 + A_2) = p(A_1) + p(A_2) +``` + +##### Collectively exhaustive events + +A set of events ``A_1, A_2, \ldots, A_N`` is said to be **collectively exhaustive** if one of the statements is necessarily true, i.e., ``A_1+A_2+\cdots +A_N=\mathrm{TRUE}``, or equivalently + +```math +p(A_1+A_2+\cdots +A_N) = 1 \,. +``` + +##### Partitioning the universe + +If a set of events ``A_1, A_2, \ldots, A_n`` is both **mutually exclusive** and **collectively exhaustive**, then we say that they **partition the universe**. Technically, this means that + +```math +\sum_{n=1}^N p(A_n) = p(A_1 + \ldots + A_N) = 1 +``` + + + +""" + +# ╔═╡ 3e1b5c9c-d294-11ef-137f-d75b3731eae4 +md""" +We mentioned before that every inference problem in PT can be evaluated through the sum and product rules. Next, we present two useful corollaries: (1) *Marginalization* and (2) *Bayes rule*. + +""" + +# ╔═╡ 3e1b7d14-d294-11ef-0d10-1148a928dd57 +md""" +## Marginalization + +Let ``A`` and ``B_1,B_2,\ldots,B_n`` be events, where ``B_1,B_2,\ldots,B_n`` partitions the universe. Then + +```math +\sum_{i=1}^n p(A,B_i) = p(A) \,. +``` + +This rule is called the [law of total probability](https://en.wikipedia.org/wiki/Law_of_total_probability). + +""" + +# ╔═╡ 5377c5a4-77c4-4fa7-9f84-0c511e3bf708 +hide_proof( + md""" + ```math +\begin{align*} + \sum_i p(A,B_i) &= p\big(\sum_i AB_i\big) &&\quad \text{(since all $AB_i$ are disjoint)}\\ + &= p\big(A,\sum_i B_i\big) \\ + &= p(A,\Omega) &&\quad \text{($\Omega$ is true event, since $B_i$ are exhaustive)} \\ + &= p(A) + \end{align*} +``` +""") + +# ╔═╡ 3e1b8bf4-d294-11ef-04cc-6364e46fdd64 +md""" +A very practical application of this law is to get rid of a variable that we are not interested in. For instance, if ``X`` and ``Y \in \{y_1,y_2,\ldots,y_n\}`` are discrete variables, then + +```math +p(X) = \sum_{i=1}^n p(X,Y=y_i)\,. +``` + +""" + +# ╔═╡ 3e1b9ba8-d294-11ef-18f2-db8eed3d87d0 +md""" +Summing ``Y`` out of a joint distribution ``p(X,Y)`` is called **marginalization** and the result ``p(X)`` is sometimes referred to as the **marginal probability** of ``X``. + +""" + +# ╔═╡ 3e1babca-d294-11ef-37c1-cd821a6488b2 +md""" +Note that marginalization can be understood as applying a "generalized" sum rule. Bishop (p.14) and some other authors also refer to this as the sum rule, but we do not follow that terminology. + +""" + +# ╔═╡ 3e1bba8e-d294-11ef-1f61-295af16078ce +md""" +Of course, in the continuous domain, marginalization becomes + +```math +p(X)=\int_Y p(X,Y) \,\mathrm{d}Y +``` + +""" + +# ╔═╡ 3e1bcb00-d294-11ef-2795-bd225bd00496 +md""" +## $(HTML("Bayes Rule")) + +Consider two variables ``D`` and ``\theta``. It follows from symmetry arguments that + +```math +p(D,\theta)=p(\theta,D)\,, +``` + +and hence that + +```math +p(D|\theta)p(\theta)=p(\theta|D)p(D)\,, +``` + +or equivalently, + +```math + p(\theta|D) = \frac{p(D|\theta) }{p(D)}p(\theta)\,.\qquad \text{(Bayes rule)} +``` + +""" + +# ╔═╡ 3e1bdd02-d294-11ef-19e8-2f44eccf58af +md""" +This last formula is called **Bayes rule**, named after its inventor [Thomas Bayes](https://en.wikipedia.org/wiki/Thomas_Bayes) (1701-1761). While Bayes rule is always true, a particularly useful application occurs when ``D`` refers to an observed data set and ``\theta`` is set of unobserved model parameters. In that case, + + * the **prior** probability ``p(\theta)`` represents our **state-of-knowledge** about proper values for ``\theta``, before seeing the data ``D``. + * the **posterior** probability ``p(\theta|D)`` represents our state-of-knowledge about ``\theta`` after we have seen the data. + +""" + +# ╔═╡ 3e1bf116-d294-11ef-148b-f7a1ca3f3bad +md""" + +Bayes rule tells us how to update our knowledge about model parameters when facing new data. Hence, +""" + +# ╔═╡ 16c2eb59-16b8-4347-9aab-6e4b99016c79 +keyconcept("", md"Bayes rule is the fundamental rule for learning from data!") + +# ╔═╡ 3e1bffec-d294-11ef-2a49-9ff0f6331add +md""" +## Bayes Rule Nomenclature + +Some nomenclature associated with Bayes rule: + +```math +\underbrace{p(\theta | D)}_{\text{posterior}} = \frac{\overbrace{p(D|\theta)}^{\text{likelihood}} \times \overbrace{p(\theta)}^{\text{prior}}}{\underbrace{p(D)}_{\text{evidence}}} +``` + +""" + +# ╔═╡ 3e1c0e80-d294-11ef-0d19-375e01988f16 +md""" +Note that the evidence (a.k.a. *marginal likelihood* ) can be computed from the numerator through marginalization since + +```math + p(D) = \int p(D,\theta) \,\mathrm{d}\theta = \int p(D|\theta)\,p(\theta) \,\mathrm{d}\theta +``` + +""" + +# ╔═╡ 3e1c1e3e-d294-11ef-0955-bdf9d0ba3c53 +md""" +Hence, having access to likelihood and prior is in principle sufficient to compute both the evidence and the posterior. To emphasize that point, Bayes rule is sometimes written as a transformation: + +```math + \underbrace{\underbrace{p(\theta|D)}_{\text{posterior}}\cdot \underbrace{p(D)}_{\text{evidence}}}_{\text{this is what we want to compute}} = \underbrace{\underbrace{p(D|\theta)}_{\text{likelihood}}\cdot \underbrace{p(\theta)}_{\text{prior}}}_{\text{this is available}} +``` + +""" + +# ╔═╡ 3e1c4224-d294-11ef-2707-49470aaae6eb +md""" +For a given data set ``D``, the posterior probabilities of the parameters scale relatively against each other as + +```math +p(\theta|D) \propto p(D|\theta) p(\theta) +``` + +Hence, all that we can learn from the observed data is contained in the likelihood function ``p(D|\theta)``. This is called the **likelihood principle**. + +""" + +# ╔═╡ 3e1c51e2-d294-11ef-2c6d-d32a98308c6f +md""" +## The Likelihood Function vs the Sampling Distribution + +Consider a distribution ``p(D|\theta)``, where ``D`` relates to variables that are observed (i.e., a "data set") and ``\theta`` are model parameters. + +""" + +# ╔═╡ 3e1c60ba-d294-11ef-3a01-cf9e97512857 +md""" +In general, ``p(D|\theta)`` is just a function of the two variables ``D`` and ``\theta``. We distinguish two interpretations of this function, depending on which variable is observed (or given by other means). + +""" + +# ╔═╡ 3e1c70be-d294-11ef-14ed-0d46515541c5 +md""" +The **sampling distribution** (a.k.a. the **data-generating** distribution) + +```math +p(D|\theta=\theta_0) +``` + +(which is a function of ``D`` only) describes a probability distribution for data ``D``, assuming that it is generated by the given model with parameters fixed at ``\theta = \theta_0``. + +""" + +# ╔═╡ 3e1c806a-d294-11ef-1fad-17e5625279f7 +md""" +In a machine learning context, often the data is observed, and ``\theta`` is the free variable. In that case, for given observations ``D=D_0``, the **likelihood function** (which is a function only of the model parameters ``\theta``) is defined as + +```math +L(\theta) \triangleq p(D=D_0|\theta) +``` + +""" + +# ╔═╡ 3e1c9184-d294-11ef-3e35-5393d97fbc44 +md""" +Note that ``L(\theta)`` is not a probability distribution for ``\theta`` since in general ``\sum_\theta L(\theta) \neq 1``. + +""" + +# ╔═╡ 3e1d33c8-d294-11ef-0a08-bdc419949925 +md""" +## Probabilistic Inference + +**Probabilistic inference** refers to computing + +```math +p(\,\text{whatever-we-want-to-know}\, | \,\text{whatever-we-already-know}\,) +``` + +For example: + +```math +\begin{align*} + p(\,\text{Mr.S.-killed-Mrs.S.} \;&|\; \text{he-has-her-blood-on-his-shirt}\,) \\ + p(\,\text{transmitted-codeword} \;&|\;\text{received-codeword}\,) + \end{align*} +``` + +This can be accomplished by repeatedly applying the sum and product rules. + +In particular, consider a joint distribution ``p(X,Y,Z)``. Assume we are interested in ``p(X|Z)``: + +```math +\begin{align*} +p(X|Z) \stackrel{p}{=} \frac{p(X,Z)}{p(Z)} \stackrel{s}{=} \frac{\sum_Y p(X,Y,Z)}{\sum_{X,Y} p(X,Y,Z)} \,, +\end{align*} +``` + +where the ``s`` and ``p`` above the equality sign indicate whether the sum or product rule was used. + +In the rest of this course, we'll encounter many lengthy probabilistic derivations. For each manipulation, you should be able to associate an 's' (for sum rule), a 'p' (for product or Bayes rule) or an 'm' (for a simplifying model assumption like conditional independency) above any equality sign. +""" + +# ╔═╡ 3e1b05ee-d294-11ef-33de-efed64d01c0d +keyconcept( + "", + md""" + All valid probabilistic relations can be derived from just two fundamental principles: the **sum rule** and the **product rule**. These two rules form the foundation of probability theory, from which more complex constructs such as conditional probabilities, Bayes’ theorem, and marginalization naturally follow. + + """ +) + +# ╔═╡ b176ceae-884e-4460-9f66-020c1ac447f1 +md""" +# Examples +""" + +# ╔═╡ e3157dc0-5a64-4479-a37a-40fe25cccc07 +code_example("Sampling Distribution and Likelihood Function for the Coin Toss") + +# ╔═╡ 7d493e09-f7cc-4e13-a506-b792edcbf390 +md""" + +and the likelihood function + +```math +L(\theta) \triangleq p(y=1|\theta) = \theta \,. +``` + +""" + +# ╔═╡ 3e1d20e0-d294-11ef-2044-e1fe6590a600 +md""" +!!! note + The (discrete) sampling distribution is a valid probability distribution. + + However, the likelihood function ``L(\theta)`` clearly isn't, since ``\int_0^1 L(\theta) \mathrm{d}\theta = 0.5 \neq 1``. +""" + +# ╔═╡ fc733d61-fd0f-4a13-9afc-4505ac0253df +f(y,θ) = θ.^y .* (1 .- θ).^(1 .- y) # p(y|θ) + +# ╔═╡ ab223dea-8ba8-4d30-94f4-72c8e070aadf +θ_bond = @bind θ Scrubbable(0.0:0.02:1; format=".2f"); + +# ╔═╡ d93f73d4-2783-4777-b0ce-cdc0444cb300 +md""" + +Consider the following simple model for the outcome ``y \in \{0,1\}`` (tail = ``0``, head = ``1``) of a biased coin toss with a real parameter $θ_bond ``= \theta \in [0,1]``: + +```math +\begin{align*} +p(y|\theta) = \theta^y (1-\theta)^{1-y}\\ +\end{align*} +``` + +Next, we use Julia to plot both the sampling distribution + +""" + +# ╔═╡ 8a7dd8b7-5faf-4091-8451-9769f842accb +let + p1 = plot( + [0,1], f([0,1], θ); + line=:stem, + marker=:circle, + xrange=(-0.5, 1.5), yrange=(0,1), + title="Sampling Distribution", + xlabel="y", ylabel=L"p(y|θ=%$θ)", label="" + ) + + _θ = 0:0.01:1 + y=1 + p2 = plot( + _θ, f(y, _θ); + ylabel=L"p(y=%$y | θ)", xlabel=L"θ", + title="Likelihood Function", label="" + ) + scatter!(p2, + [θ], [f(y, θ)]; + label=nothing, + ) + + plot(p1, p2) +end + +# ╔═╡ b7445b9b-7fbb-4560-b947-a23af0fcf101 +md""" +Click and drag this number to change ``\theta``: $θ_bond. +""" + +# ╔═╡ 922770f4-ddc8-4089-b378-f14088276b43 +exercise_statement("Which color does the ball have?"; prefix="Inference ") + +# ╔═╡ 3e1de32c-d294-11ef-1f63-f190c8361404 +md""" + +##### Problem + +- A bag contains one ball, known to be either white or black. A white ball is put in , and the bag is shaken. Next, a ball is drawn out, which proves to be white. If we now take out another ball, what is the probability it will be white? + + +""" + +# ╔═╡ 4c639e65-e06b-4c5e-b6e7-aabed6b6c0b4 +hide_solution( + md""" +There are two hypotheses: let ``H = 0`` mean that the original ball in the bag was white and ``H = 1`` that it was black. Assume the prior probabilities are equal, i.e., +```math + P(H =0) = 1/2, \quad P(H =1) = 1/2 \,. +``` +The data is that when a randomly selected ball was drawn from the bag, which contained a white one and the unknown one, it turned out to be white. The probability of this result according to each hypothesis is: +```math + P(D|H =0) = 1, \quad P(D|H =1) = 1/2 \,. +``` +So by Bayes theorem, +```math +\begin{align} +P(H=0|D) &= \frac{P(H=0,D)}{P(D)} \\ + &= \frac{P(D|H=0) P(H=0)}{P(D|H=0) P(H=0) + P(D|H=1) P(H=1)} \\ + &= \frac{1 \cdot \frac{1}{2}}{1 \cdot \frac{1}{2} + \frac{1}{2} \cdot \frac{1}{2}} \\ + &= \frac{2}{3} +\end{align} +``` +and consequently, +```math + P(H =1|D) = 1 - P(H =0|D) = \frac{1}{3} +``` +""") + +# ╔═╡ ff9142ba-3a85-48cf-8b78-07e0b554e280 +md""" +Note that the physical state of the bag—either containing one black ball or one white ball—remains unchanged after the “put one in, take one out” procedure. +Yet, the probability we assign to the color of the ball in the bag changes. +This illustrates a key point: probabilities describe a person’s state of knowledge, not an intrinsic property of nature. +""" + +# ╔═╡ 3e027ede-4ac1-4521-a026-dc00bfca4adf +exercise_statement("Causality?"; prefix="Inference ") + +# ╔═╡ 3e1e2b96-d294-11ef-3a68-fdc78232142e +md""" + +##### Problem + +- A dark bag contains five red balls and seven green ones. + - (a) What is the probability of drawing a red ball on the first draw? +- Balls are not returned to the bag after each draw. + - (b) If you know that on the second draw the ball was a green one, what is now the probability of drawing a red ball on the first draw? + + +""" + +# ╔═╡ 727dc817-0284-4c0f-9a92-21dcbea50807 +hide_solution( +md""" + +(a) ``p(S_1=R) = \frac{N_\text{red}}{N_\text{red}+N_\text{green}} = \frac{5}{12}`` + +(b) The outcome of the ``n``-th draw is referred to by ``S_n``. Use Bayes rule to get, +```math +\begin{align} +p(S_1=\text{R} | S_2=\text{G}) &= \frac{p(S_2=\text{G} | S_1=\text{R}) p(S_1=\text{R})} {p(S_2=\text{G} | S_1 = \text{R}) p(S_1=\text{R}) + p(S_2=\text{G} | S_1=\text{G}) p(S_1=\text{G})} \\ + &= \frac{\frac{7}{11}\cdot\frac{5}{12}}{\frac{7}{11}\cdot\frac{5}{12}+\frac{6}{11}\cdot\frac{7}{12}} \\ + &= \frac{5}{11} +\end{align} +``` +""") + +# ╔═╡ fae6f2ce-ac8f-4ea6-b2cf-38b30a7e20d4 +md""" +In this case, knowledge about the future influences our state of knowledge about the present. Once again, we see that conditional probabilities capture implications for a state of knowledge, not temporal causality. + +""" + +# ╔═╡ ea803646-b18e-4f13-ab6a-fc5080d44e92 +challenge_solution("Disease Diagnosis",header_level=1) + +# ╔═╡ 9b85a92b-c56b-48a3-97c1-6b1882e33a22 +@htl """ + +""" + +# ╔═╡ ef264651-854e-4374-8ea8-5476c85150c4 +md"# Moments and Transformations" + +# ╔═╡ 3e1e4dda-d294-11ef-33b7-4bbe3300ca22 +md""" +## Moments of the PDF + +Distributions can often usefully be summarized by a set of values known as moments of the distribution. + +Consider a distribution ``p(x)``. The first moment, also known as **expected value** or **mean** of ``p(x)`` is defined as + +```math +\mu_x = \mathbb{E}[x] \triangleq \int x \,p(x) \,\mathrm{d}{x} +``` + +""" + +# ╔═╡ 3e1e5a5a-d294-11ef-2fdf-efee4eb1a0f2 +md""" +The second central moment, also known as **variance** of ``x`` is defined as + +```math +\Sigma_x \triangleq \mathbb{E} \left[(x-\mu_x)(x-\mu_x)^T \right] +``` + +""" + +# ╔═╡ 3e1e7742-d294-11ef-1204-f9be24da07ab +md""" +The **covariance** matrix between *vectors* ``x`` and ``y`` is a mixed central moment, defined as + +```math +\begin{align*} + \Sigma_{xy} &\triangleq \mathbb{E}\left[ (x-\mu_x) (y-\mu_y)^T \right]\\ + &= \mathbb{E}\left[ (x-\mu_x) (y^T-\mu_y^T) \right]\\ + &= \mathbb{E}[x y^T] - \mu_x \mu_y^T +\end{align*} +``` + +Clearly, if ``x`` and ``y`` are independent, then ``\Sigma_{xy} = 0``, since in that case ``\mathbb{E}[x y^T] = \mathbb{E}[x] \mathbb{E}[y^T] = \mu_x \mu_y^T``. + +Home exercise: Prove that ``\Sigma_{xy} = \Sigma_{yx}^{T}`` (making use of ``(AB)^T = B^TA^T``). + +""" + +# ╔═╡ 3e1e9224-d294-11ef-38b3-137c2be22400 +md""" +## Linear Transformations + +Consider an arbitrary distribution ``p(x)`` with mean ``\mu_x`` and covariance matrix ``\Sigma_x``. Define + +```math +z = A x + b \,. +``` + +No matter the specification of ``p(x)``, the mean and covariance matrix for ``z`` are given by +```math +\begin{align*} +\mu_z &= A\mu_x + b \\ +\Sigma_z &= A\,\Sigma_x\,A^T +\end{align*} +``` + + +""" + +# ╔═╡ d2202628-e4f9-4289-b48e-23b5a0073f94 +hide_proof( +md""" +Let ``\mathbb{E}[\cdot]`` refer to the expectation (mean) operator. By linearity of expectation and the fact that ``A`` and ``b`` are constants, +```math +\mu_z = \mathbb{E}[z] = \mathbb{E}[A x + b] = A\,\mathbb{E}[x] + b = A\mu_x + b\,. +``` +For the covariance matrix, +```math +\begin{align} +\Sigma_z &= \mathbb{E}\big[(z-\mu_z)(z-\mu_z)^T \big] \\ +&= \mathbb{E}\big[(Ax + b - (A\mu_x + b))(Ax + b - (A\mu_x + b))^T \big] \\ +&= \mathbb{E}\big[(Ax - A\mu_x)(Ax - A\mu_x)^T \big] \\ +&= A\,\mathbb{E}\big[(x-\mu_x)(x-\mu_x)^\top\big]A^T \\ +&= A\Sigma_x A^T \,. +\end{align} +``` +""" +) + +# ╔═╡ 726e7e9f-3d68-4d02-9954-1edd98b74fdc +keyconcept("", +md""" +No matter the specification of ``p(x)``, the mean and covariance matrix for ``z=Ax + b`` are given by +```math +\begin{align} +\mu_z &= A\mu_x + b \\ +\Sigma_z &= A\,\Sigma_x\,A^T +\end{align} +``` +""") + +# ╔═╡ 58f70d3e-4b64-414e-b560-327be2a0c4c2 +exercise_statement("The PDF for the Sum of Two Variables") + +# ╔═╡ 3e1ea442-d294-11ef-1364-8dd9986325f7 +md""" + +You should now be able to derive the following: for any distribution of variables ``X`` and ``Y``, show that the mean and variance of the sum ``Z = X+Y`` is given by + +```math +\begin{align*} + \mu_z &= \mu_x + \mu_y \\ + \Sigma_z &= \Sigma_x + \Sigma_y + \Sigma_{xy} + \Sigma_{yx} +\end{align*} +``` +where ``\Sigma_{yx} = \Sigma_{xy}^T``. +""" + +# ╔═╡ 6d07be25-53d0-46b9-b197-a3680d830952 +hide_solution( +md""" +Define ``A = \begin{pmatrix} I & I \end{pmatrix}`` and ``w = \begin{pmatrix} x \\ y \end{pmatrix}``, where ``I`` is the identity matrix. Then +```math +z = A w\,. +``` +Let ``\mathbb{E}[\cdot]`` refer to the expectation operator. Now apply the formula for the mean and variance of a variable after a linear transformation: + +```math +\mathbb{E}[z] = \mathbb{E}[Aw] = \mathbb{E}[x+y] = \mathbb{E}[x] + \mathbb{E}[y] \,. +``` +For the covariance matrix, first note that +```math +\begin{align} + \Sigma_w &= \mathbb{E} \bigg[ \begin{pmatrix} x - \mu_x \\ y- \mu_y\end{pmatrix} \begin{pmatrix} x - \mu_x \\ y- \mu_y\end{pmatrix}^T \bigg] \\ + &= \begin{pmatrix} \Sigma_x & \Sigma_{xy} \\ \Sigma_{yx} & \Sigma_y\end{pmatrix} +\end{align} +``` +and we note that ``\Sigma_{yx} = \Sigma_{xy}^T``. Then, ``\Sigma_z`` evaluates to +```math +\begin{align} +\Sigma_z &= A \Sigma_w A^T \\ + &= \begin{pmatrix} I & I \end{pmatrix} \begin{pmatrix} \Sigma_x & \Sigma_{xy} \\ \Sigma_{yx} & \Sigma_y\end{pmatrix} \begin{pmatrix}I \\ I \end{pmatrix} \\ + &= \Sigma_x + \Sigma_y + \Sigma_{xy} + \Sigma_{yx} \,. +\end{align} +``` +""" ) + +# ╔═╡ 3e1eba72-d294-11ef-2f53-b56f1862fcbb +md""" +Clearly, it follows that if ``X`` and ``Y`` are **independent**, then + +```math +\Sigma_z = \Sigma_x + \Sigma_y +``` + +""" + +# ╔═╡ 3e1ed1a4-d294-11ef-2de4-d7cc540e06a1 +md""" +More generally, assume two jointly continuous variables ``X`` and ``Y``, with joint PDF ``p_{xy}(x,y)``. Let ``Z=X+Y``, then + +```math +\begin{align*} +\text{Prob}(Z\leq z) &= \text{Prob}(X+Y\leq z)\\ +&= \int_{-\infty}^\infty \biggl( \int_{-\infty}^{z-x} p_{xy}(x,y) \mathrm{d}y \biggr) \mathrm{d}x \\ +&= \int_{-\infty}^\infty \biggl( \int_{-\infty}^{z} p_{xy}(x,t-x) \mathrm{d}t \biggr) \mathrm{d}x \\ +&= \int_{-\infty}^z \biggl( \underbrace{\int_{-\infty}^{\infty} p_{xy}(x,t-x) \mathrm{d}x}_{p_z(t)} \biggr) \mathrm{d}t +\end{align*} +``` + +Hence, the PDF for the sum ``Z`` is given by ``p_z(z) = \int_{-\infty}^{\infty} p_{xy}(x,z-x) \mathrm{d}x``. + +In particular, if ``X`` and ``Y`` are **independent** variables, then + +```math +p_z (z) = \int_{-\infty}^{\infty} p_x(x) p_y(z - x)\,\mathrm{d}{x} = p_x(z) * p_y(z)\,, +``` + +which is the **convolution** of the two marginal PDFs. + +""" + +# ╔═╡ 3e1eeb14-d294-11ef-1702-f5d2cf6fe60a +md""" +[Wikipedia's List of convolutions of probability distributions](https://en.wikipedia.org/wiki/List_of_convolutions_of_probability_distributions) shows how these convolutions work out for a few common probability distributions. + +""" + +# ╔═╡ e5902178-6df2-4eb4-ac13-7370b3d00c9c +md""" +## Working with Distributions in code + +Take a look at this mini lecture to see some simple examples of using distributions in Julia: +""" + +# ╔═╡ 6bc443b4-1a07-4f56-99fb-c30a4370da92 +NotebookCard("https://bmlip.github.io/course/minis/Distributions%20in%20Julia.html") + +# ╔═╡ 3e1f225a-d294-11ef-04c6-f3ca018ab286 +md""" +$(code_example("Sum of Two Gaussian-distributed Variables"; big=true, header_level=2)) + +Consider two independent Gaussian-distributed variables ``X`` and ``Y`` (see [wikipedia normal distribution](https://en.wikipedia.org/wiki/Normal_distribution) for definition of a Gaussian (=Normal) distribution): + +```math +\begin{align*} +p_X(x) &= \mathcal{N}(\,x\,|\,\mu_X,\sigma_X^2\,) \\ +p_Y(y) &= \mathcal{N}(\,y\,|\,\mu_Y,\sigma_Y^2\,) +\end{align*} +``` + +Let ``Z = X + Y``. Performing the convolution (nice exercise) yields a Gaussian PDF for ``Z``: + +```math +p_Z(z) = \mathcal{N}(\,z\,|\,\mu_X+\mu_Y,\sigma_X^2+\sigma_Y^2\,). +``` + +We illustrate the distributions for ``X``, ``Y`` and ``Z`` using Julia: + +""" + +# ╔═╡ 98fa17a6-7c8b-46e4-b32d-52db183d88f8 +md""" +Set the parameters for the distributions of ``X`` and ``Y``: +""" + +# ╔═╡ 27ec154a-a4c3-4d71-b2a0-45f2b456a8e4 +μx = 2.0; σx = 1.0; + +# ╔═╡ de4dbfc9-9340-4ae2-b323-49abfd77f198 +μy = 2.0; σy = 0.5; + +# ╔═╡ 1cb8b2c4-e1ae-4973-ba53-fc6c7fe1f37a +md""" +Compute the parameters for the distribution of ``Z = X + Y``: +""" + +# ╔═╡ 91a91472-ee6d-416b-b18e-acbedc03a7fe +μz = μx + μy + +# ╔═╡ 6485575d-c5a5-4891-8210-f50d6f75476f +σz = sqrt(σx^2 + σy^2) + +# ╔═╡ 0abaed25-decc-4dcd-aa04-b68ec0d5c73e + + +# ╔═╡ 218d3b6e-50b6-4b98-a00c-a19dd33d2c03 +md""" +Let's plot the distributions for ``X``, ``Y``, and ``Z`` +""" + +# ╔═╡ e836f877-5ed6-4865-ba3a-1ca5a86b2349 +begin + x = Normal(μx, σx) + y = Normal(μy, σy) + z = Normal(μz, σz) +end; + +# ╔═╡ c0ea3253-a06b-426c-91a3-a6dd33e42779 +let + + # Calculate the x-range for plotting + range_min = min(μx-2*σx, μy-2*σy, μz-2*σz) + range_max = max(μx+2*σx, μy+2*σy, μz+2*σz) + range_grid = range(range_min, stop=range_max, length=100) + + plot(range_grid, t -> pdf(x,t), label=L"p_x", fill=(0, 0.1)) + plot!(range_grid, t -> pdf(y,t), label=L"p_y", fill=(0, 0.1)) + plot!(range_grid, t -> pdf(z,t), label=L"p_z", fill=(0, 0.1)) +end + +# ╔═╡ 3e1f4f46-d294-11ef-29b8-69e546763781 +md""" +## PDF for the Product of Two Variables + +For two continuous **independent** variables ``X`` and ``Y``, with PDF's ``p_x(x)`` and ``p_y(y)``, the PDF of ``Z = X Y`` is given by + +```math +p_z(z) = \int_{-\infty}^{\infty} p_x(x) \,p_y(z/x)\, \frac{1}{|x|}\,\mathrm{d}x\,. +``` + +For proof, see [https://en.wikipedia.org/wiki/Product_distribution](https://en.wikipedia.org/wiki/Product_distribution). + +""" + +# ╔═╡ 3e1f68fa-d294-11ef-31b2-e7670da8c08c +md""" +Generally, this integral does not lead to an analytical expression for ``p_z(z)``. + +As a crucial example, [the product of two independent variables that are both Gaussian-distributed does **not** lead to a Gaussian distribution](https://bmlip.github.io/course/minis/Sum%20and%20product%20of%20Gaussians.html). + + * Exception: the distribution of the product of two variables that both have [log-normal distributions](https://en.wikipedia.org/wiki/Log-normal_distribution) is again a lognormal distribution. (If ``X`` has a normal distribution, then ``Y=\exp(X)`` has a log-normal distribution.) + +""" + +# ╔═╡ 3e1f7d5e-d294-11ef-2878-05744036f32c +md""" +## General Variable Transformations + +Suppose ``x`` is a **discrete** variable with probability **mass** function ``P_x(x)``, and ``y = h(x)`` is a one-to-one function with ``x = g(y) = h^{-1}(y)``. Then + +```math +P_y(y) = P_x(g(y))\,. +``` + +""" + +# ╔═╡ 3e1f8e48-d294-11ef-0f8a-b58294a8543d +hide_proof( +md""" +```math +P_y(\hat{y}) = P(y=\hat{y}) = P(h(x)=\hat{y}) = P(x=g(\hat{y})) = P_x(g(\hat{y})) \,. +``` +""") + +# ╔═╡ 3e1fa04a-d294-11ef-00c3-a51d1aaa5553 +md""" +If ``x`` is defined on a **continuous** domain, and ``p_x(x)`` is a probability **density** function, then probability mass is represented by the area under a (density) curve. In that case, +```math +p_y(y) = p_x(g(y)) g^\prime(y)\,, +``` + +which is also known as the [Change-of-Variable theorem](https://en.wikipedia.org/wiki/Probability_density_function#Function_of_random_variables_and_change_of_variables_in_the_probability_density_function). + + +""" + +# ╔═╡ 50bdc2fe-f48d-4c4e-8b4e-170782681366 +hide_proof( +md""" +We assume again that ``y = h(x)`` is a one-to-one function with ``x = g(y) = h^{-1}(y)``. Let ``a=g(c)`` and ``b=g(d)``. Then + +```math +\begin{align} +P(a ≤ x ≤ b) &= \int_a^b p_x(x)\mathrm{d}x \\ + &= \int_{g(c)}^{g(d)} p_x(x)\mathrm{d}x \\ + &= \int_c^d p_x(g(y))\mathrm{d}g(y) \\ + &= \int_c^d \underbrace{p_x(g(y)) g^\prime(y)}_{p_y(y)}\mathrm{d}y \\ + &= P(c ≤ y ≤ d) +\end{align} +``` + +Equating the two probability masses, ``p_y(y)\mathrm{d}y = p_x(x)\mathrm{d}x``, leads to the identification of the relation +```math +p_y(y) = p_x(g(y)) g^\prime(y)\,, +``` +""" +) + +# ╔═╡ db73766d-643c-41d7-a1eb-f376c657f860 +md""" +If the transformation ``y=h(x)`` is not invertible, then ``x=g(y)`` does not exist. In that case, you can still work out the transformation by equating equivalent probability masses in the two domains. +""" + +# ╔═╡ 3e1fb370-d294-11ef-1fb6-63a41a024691 +md""" +$(exercise_statement("Transformation of a Gaussian Variable"; big=true, header_level=2)) + +##### Problem + +Let ``p_x(x) = \mathcal{N}(x|\mu,\sigma^2)`` and ``y = \frac{x-\mu}{\sigma}``. +Evaluate ``p_y(y)`` as a Gaussian distribution. + +""" + +# ╔═╡ 317707a3-9ef1-4c67-b451-6adcfcff50f0 +hide_solution( +md""" +Note that ``h(x)`` is invertible with ``x = g(y) = \sigma y + \mu``. The change-of-variable formula leads to + +```math +\begin{align*} +p_y(y) &= p_x(g(y)) \cdot g^\prime(y) \\ + &= p_x(\sigma y + \mu) \cdot \sigma \\ + &= \frac{1}{\sigma\sqrt(2 \pi)} \exp\left( - \frac{(\sigma y + \mu - \mu)^2}{2\sigma^2}\right) \cdot \sigma \\ + &= \frac{1}{\sqrt(2 \pi)} \exp\left( - \frac{y^2 }{2}\right)\\ + &= \mathcal{N}(y|0,1) +\end{align*} +``` + +In the statistics literature, ``y = \frac{x-\mu}{\sigma}`` is called the **standardized** variable since it transforms a general normal variable into a standard normal one.) +""") + +# ╔═╡ 9b92fc89-2036-4525-979b-d296ab29329c +md""" +# Summary +""" + +# ╔═╡ 5da42e9a-4318-48ea-9f43-4c1e1c97bceb +keyconceptsummary() + +# ╔═╡ 03692f4d-0daf-4dfc-a7ff-6b954326e4d0 +exercises() + + +# ╔═╡ 3a1d380e-df80-4727-9772-f199214cf05d +md""" +##### The Sum Rule (**) + +Derive the general sum rule, +```math +p(A + B) = p(A) + p(B) - p(A,B) +``` +from the elementary sum rule ``p(A) + p(\bar A) = 1`` and the sum and product rules. + +""" + +# ╔═╡ 99d9099f-4908-4bb3-8d59-da9cb69af04c +hint( + md""" + Here, you may make use of the (Boolean logic) fact that ``A + B = \overline {\bar A \bar B }``. + """ +) + +# ╔═╡ 3b1b0869-b815-4697-9dba-3c4b4cb5ac47 +hide_solution( +md""" +```math +\begin{align} +p\left( A + B \right) &\underset{\mathrm{bool}}{=} p\left( \overline {\bar A \bar B } \right) \\ + &\underset{\mathrm{sum}}{=} 1 - p\left( \bar{A} \bar{B} \right) \\ + &\underset{\mathrm{prod}}{=} 1 - p\left( \bar{A} |\bar{B} \right) p\left(\bar{B} \right) \\ + &\underset{\mathrm{sum}}{=} 1 - \left( 1 - p\left(A|\bar B \right) \right) \left( 1 - p\left( B \right) \right) \\ + &= p(B) + \left( {1 - p\left( B \right)} \right)p\left( {A|\bar B } \right) \\ + &\underset{\mathrm{prod}}{=} p(B) + \left( 1 - p\left( B \right) \right) p\left( \bar{B} |A \right) \frac{ p\left( A \right) }{ p\left(\bar{B}\right)} \\ + &\underset{\mathrm{sum}}{=} p(B) + p\left(\bar{B} |A \right) p\left( A \right) \\ + &\underset{\mathrm{sum}}{=} p(B) + \left( 1 - p\left( {B|A} \right) \right) p\left( A \right) \\ + &\underset{\mathrm{sum}}{=} p\left( A \right) + p(B) - p\left( A,B \right) +\end{align} +``` +Note that, aside from the first boolean rewrite, everything follows straight application of sum and product rules. + + +""") + +# ╔═╡ 5f377237-d9a5-4778-aa4d-1c6ce109b705 +md""" +##### Apples and Oranges + +Box 1 contains 8 apples and 4 oranges. Box 2 contains 10 apples and 2 oranges. Boxes are chosen with equal probability. You pick a box and then select a fruit from that box. +- (a) (*) What is the probability of choosing an apple? +- (b) (**) If an apple is chosen, what is the probability that it came from box 1? +""" + +# ╔═╡ 5613e9b7-ff0d-435a-9de6-aaf293ebf592 +hide_solution( +md""" +The following probabilities are given in the problem statement, +```math +\begin{align} +p(b_1) &= p(b_2) = 1/2 \\ +p(a|b_1) &= 8/12, \quad p(a|b_2) = 10/12 \\ +p(o|b_1) &= 4/12, \quad p(o|b_2) = 2/12 +\end{align} +``` +(a) +```math +p(a) = \sum_i p(a,b_i) = \sum_i p(a|b_i)p(b_i)=\frac{8}{12}\cdot\frac{1}{2} + \frac{10}{12}\cdot\frac{1}{2} = \frac{3}{4} +``` +(b) +```math +p(b_1|a) = \frac{p(a,b_1)}{p(a)} = \frac{p(a|b_1)p(b_1)}{p(a)} = \frac{\frac{8}{12}\cdot\frac{1}{2}}{\frac{3}{4}} = \frac{4}{9} +``` +""" +) + +# ╔═╡ fc3151f9-e143-4e31-b7b7-3f25b4fe9dab +md""" +##### What is a Random Signal? (*) +Is a speech signal a "probabilistic" (random) or a deterministic signal? +""" + +# ╔═╡ 66ebe33c-8360-4938-9b51-625e5bed176c +hide_solution( +md""" +That depends. The term “probabilistic” refers to a state-of-knowledge (or beliefs) about something—in this case, about the values of a speech signal. The key point is that the signal itself is neither inherently probabilistic nor deterministic; these labels describe our knowledge about it. + +If you had a perfect microphone and recorded the speech signal flawlessly at its source, you would know all its values exactly—no uncertainty—so you could call it deterministic. + +However, before making the recording, how would you represent your knowledge about the signal values you are going to measure? You face uncertainty, so the appropriate description is a probability distribution over all possible signal values. +""") + +# ╔═╡ 5b681e41-ad14-4c58-8ea0-4b6d85885c51 +md""" +##### Who Speaks the Truth? (***) +The inhabitants of an island tell the truth one-third of the time. They lie with probability ``2/3``. On an occasion, after one of them made a statement, you ask another person "was that statement true?" and he says "yes". What is the probability that the statement was indeed true? + +""" + +# ╔═╡ 91dd40f0-c373-48b3-b83b-6e8df2c43e5a +hide_solution( +md""" +We use variables ``S_1 \in \{\text{t},\text{f}\}`` and ``S_2 \in \{\text{y},\text{n}\}`` for statements 1 and 2 and shorthand "y", "n", "t" and "f" for "yes", "no", "true" and "false", respectively. The problem statement provides us with the following probabilities, +```math +\begin{align} +p(S_1=\text{t}) &= 1/3 \\ +p(S_1=\text{f}) &= 1 - p(S_1=\text{t}) = 2/3\\ +p(S_2=\text{y} | S_1=\text{t}) &= 1/3 \\ +p(S_2=\text{y} | S_1=\text{f}) &= 2/3 +\end{align} +``` +We are asked to compute ``p(S_1=\text{t} | S_2=\text{y})``. Use Bayes rule, +```math +\begin{align} +p(S_1=\text{t} | S_2=\text{y}) &= \frac{p(S_1=\text{t},S_2=\text{y})}{p(S_2=\text{y})} \\ +&= \frac{\overbrace{p(S_2=\text{y}|S_1=\text{t})p(S_1=\text{t})}^{\text{both speak the truth}}}{\underbrace{p(S_2=\text{y}|S_1=\text{t})p(S_1=\text{t})}_{\text{both speak the truth}}+\underbrace{p(S_2=\text{y}|S_1=\text{f})p(S_1=\text{f})}_{\text{both lie}}}\\ +&= \frac{\frac{1}{3}\cdot\frac{1}{3}}{\frac{1}{3}\cdot\frac{1}{3}+\frac{2}{3}\cdot\frac{2}{3}} = \frac{1}{5} +\end{align} +``` +""") + +# ╔═╡ a8d4a517-84a7-426e-a49e-482c5fd047ae +md""" +##### The Likelihood Function is a Function of What? (*) + +When considering the distribution ``p(D|\theta)``, is it more correct to speak about the likelihood of the model parameters ``\theta`` than about the likelihood of the observed data set ``D``. And why? + +""" + +# ╔═╡ d3b003c6-70ca-419f-a343-e35b266323f3 +hide_solution( +md""" +Yes, it’s more correct to speak about the likelihood of the model parameters, not of the observed data set. Once ``D`` has been observed, it is no longer a random variable; it’s just a fixed outcome. What varies is ``\theta``, so ``L(\theta) = p(D|\theta)`` is a function of the parameters, not of the data. + +Saying “likelihood of the data” is misleading because it confuses likelihood with the sampling distribution ``p(D|\theta)`` seen as a function of ``D`` (where ``\theta`` is fixed). The latter is a probability distribution over possible data sets before observing them. +""") + +# ╔═╡ dd31ec7c-708d-4fd7-958d-f9887798a5bc +md""" +# Code +""" + +# ╔═╡ 70d79732-0f55-40ba-929d-fba431318848 +md""" +##### Disease diagnosis implementation +""" + +# ╔═╡ 4f6dd225-c64d-4b76-b075-0bf71c863b5a +begin + prevalence_bond = @bind prevalence Scrubbable(0:0.01:1; format=".0%", default=0.01) + sensitivity_bond = @bind sensitivity Scrubbable(0:0.01:1; format=".0%", default=0.95) + specificity_bond = @bind specificity Scrubbable(0:0.01:1; format=".0%", default=0.85) +end; + +# ╔═╡ 3e185ab0-d294-11ef-3f7d-9bd465518274 +md""" +##### Problem + - Given is a disease with a prevalence of $(prevalence_bond) and a test procedure with sensitivity ('true positive' rate) of $(sensitivity_bond), and specificity ('true negative' rate) of $(specificity_bond). What is the chance that somebody who tests positive actually has the disease? + +##### Solution + - Use probabilistic inference, to be discussed in this lecture. +""" + +# ╔═╡ 3e1d6d00-d294-11ef-1081-e11b8397eb91 +md""" +##### Problem + +- Given a disease ``D \in \{0, 1\}`` with prevalence (overall occurence percentage) of $(prevalence_bond) and a test procedure ``T \in \{0, 1\}`` with sensitivity (true positive rate) of $(sensitivity_bond) and specificity (true negative' rate) of $(specificity_bond), what is the chance that somebody who tests positive actually has the disease? + +_The percentages are interactive! **Click and drag** to change the values._ + +""" + +# ╔═╡ a8046381-ff11-40af-ae2b-078d71c586e7 +result = (sensitivity * prevalence) / (sensitivity * prevalence + (1 - specificity)*(1 - prevalence)) + +# ╔═╡ 4a81342c-17c7-4eb9-933b-edb98df7b9c4 +n(x; digits=2) = @sprintf("%.*f", digits, x) + +# ╔═╡ 079157c9-5d97-4dbc-8c47-afa8b661db06 +let + θ_str = n(θ) + @mdx """ + ```math + p(y|\\theta=$(n(θ))) = \\begin{cases} $(n(1-θ)) & \\text{if }y=0 \\\\ $(n(θ)) & \\text{if } y=1 \\end{cases} + ``` + """ +end + +# ╔═╡ 2156f96e-eebe-4190-8ce9-c76825c6da71 +if show_disease_diagnosis_solution + @mdx(""" +
+ + +- The given information is ``p(D=1)=$(n(prevalence))``, ``p(T=1|D=1)=$(n(sensitivity))`` and ``p(T=0|D=0)=$(n(specificity))``. We are asked to derive ``p( D=1 | T=1)``. We just follow the sum and product rules to derive the requested probability: + +```math +\\begin{align*} +p( D=1 &| T=1) \\\\ +&\\stackrel{p}{=} \\frac{p(T=1,D=1)}{p(T=1)} \\\\ +&\\stackrel{p}{=} \\frac{p(T=1|D=1)p(D=1)}{p(T=1)} \\\\ +&\\stackrel{s}{=} \\frac{p(T=1|D=1)p(D=1)}{p(T=1|D=1)p(D=1)+p(T=1|D=0)p(D=0)} \\\\ +&= \\frac{$(n(sensitivity))\\times$(n(prevalence))}{$(n(sensitivity))\\times$(n(prevalence)) + $(n(1 - specificity))\\times$(n(1 - prevalence))} = \\boldsymbol{$(n(result; digits=4))} +\\end{align*} +``` + + +Note that ``p(\\text{sick}|\\text{positive test}) = $(n(result))`` while ``p(\\text{positive test} | \\text{sick}) = $(n(sensitivity))``. This is a huge difference that is sometimes called the "medical test paradox" or the [base rate fallacy](https://en.wikipedia.org/wiki/Base_rate_fallacy). + +Many people have trouble distinguishing ``p(A|B)`` from ``p(B|A)`` in their heads. This has led to major negative consequences. For instance, unfounded convictions in the legal arena and numerous unfounded conclusions in the pursuit of scientific results. See [Ioannidis (2005)](https://journals.plos.org/plosmedicine/article?id=10.1371/journal.pmed.0020124) and [Clayton (2021)](https://aubreyclayton.com/bernoulli). + +""") +end + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +MarkdownLiteral = "736d6165-7244-6769-4267-6b50796e6954" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[compat] +BmlipTeachingTools = "~1.3.1" +Distributions = "~0.25.122" +LaTeXStrings = "~1.4.0" +MarkdownLiteral = "~0.1.2" +Plots = "~1.40.17" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "cf118b3f89c5063d349d6130b7c24f50472cb168" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.CommonMark]] +deps = ["PrecompileTools"] +git-tree-sha1 = "351d6f4eaf273b753001b2de4dffb8279b100769" +uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" +version = "0.9.1" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MarkdownLiteral]] +deps = ["CommonMark", "HypertextLiteral"] +git-tree-sha1 = "f7d73634acd573bf3489df1ee0d270a5d6d3a7a3" +uuid = "736d6165-7244-6769-4267-6b50796e6954" +version = "0.1.2" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─3e17df5e-d294-11ef-38c7-f573724871d8 +# ╟─bcb4be20-0439-4809-a166-8c50b6b9206b +# ╟─3e1803d0-d294-11ef-0304-df2b9b698cd1 +# ╟─9b9be452-9681-43e8-bb09-cc8728df384f +# ╟─9f4125a2-d5d2-4acf-8bad-82f94af230e8 +# ╟─f8c8ba53-df36-48a6-afde-2952cbcfbe48 +# ╟─61713e1c-8e37-45d9-9f58-c3db69e15b66 +# ╟─3e185ab0-d294-11ef-3f7d-9bd465518274 +# ╟─840ab4dc-0d2e-4bf8-acc7-5f1ee2b0dcaf +# ╟─41bee964-a0a9-4a7f-8505-54a9ee12ef0d +# ╟─3e1889b8-d294-11ef-17bb-496655fbd618 +# ╟─3e18b2fa-d294-11ef-1255-df048f0dcec2 +# ╟─3e18c25c-d294-11ef-11bc-a93c2572b107 +# ╟─3e18d2ea-d294-11ef-35e9-2332dd31dbf0 +# ╟─dd11e93a-3dad-4e97-8642-fb70edfa6aae +# ╟─3e18e4bc-d294-11ef-38bc-cb97cb4e0963 +# ╟─3e18f18c-d294-11ef-33e4-b7f9495e0508 +# ╟─3e1906ea-d294-11ef-236e-c966a9474170 +# ╟─3e191b6c-d294-11ef-3174-d1b4b36e252b +# ╟─3e192ef4-d294-11ef-1fc4-87175eeec5eb +# ╟─3e19436c-d294-11ef-11c5-f9914f7a3a57 +# ╟─4edf38ab-a940-4ab0-be22-fa95cf571146 +# ╟─3e194ef2-d294-11ef-3b38-1ddc3063ff35 +# ╟─3e1964b4-d294-11ef-373d-712257fc130f +# ╟─3e196d6a-d294-11ef-0795-41c045079251 +# ╟─3e198336-d294-11ef-26fd-03cd15876486 +# ╟─3e198ba6-d294-11ef-3fe7-d70bf4833fa6 +# ╟─3e19e95a-d294-11ef-3da4-6d23922a5150 +# ╟─3e1a69f4-d294-11ef-103e-efc47025fb8f +# ╟─3e1a7c8e-d294-11ef-1f97-55e608d49141 +# ╟─3e1a8eca-d294-11ef-1ef0-c15b24d05990 +# ╟─3e1fc4da-d294-11ef-12f5-d51f9728fcc0 +# ╟─3e1ab104-d294-11ef-1a98-412946949fba +# ╟─fea8ae4c-8ef9-4b74-ad13-1314afef97de +# ╟─3e1b4b1c-d294-11ef-0423-9152887cc403 +# ╟─3e1b5c9c-d294-11ef-137f-d75b3731eae4 +# ╟─3e1b7d14-d294-11ef-0d10-1148a928dd57 +# ╟─5377c5a4-77c4-4fa7-9f84-0c511e3bf708 +# ╟─3e1b8bf4-d294-11ef-04cc-6364e46fdd64 +# ╟─3e1b9ba8-d294-11ef-18f2-db8eed3d87d0 +# ╟─3e1babca-d294-11ef-37c1-cd821a6488b2 +# ╟─3e1bba8e-d294-11ef-1f61-295af16078ce +# ╟─3e1bcb00-d294-11ef-2795-bd225bd00496 +# ╟─3e1bdd02-d294-11ef-19e8-2f44eccf58af +# ╟─3e1bf116-d294-11ef-148b-f7a1ca3f3bad +# ╟─16c2eb59-16b8-4347-9aab-6e4b99016c79 +# ╟─3e1bffec-d294-11ef-2a49-9ff0f6331add +# ╟─3e1c0e80-d294-11ef-0d19-375e01988f16 +# ╟─3e1c1e3e-d294-11ef-0955-bdf9d0ba3c53 +# ╟─3e1c4224-d294-11ef-2707-49470aaae6eb +# ╟─3e1c51e2-d294-11ef-2c6d-d32a98308c6f +# ╟─3e1c60ba-d294-11ef-3a01-cf9e97512857 +# ╟─3e1c70be-d294-11ef-14ed-0d46515541c5 +# ╟─3e1c806a-d294-11ef-1fad-17e5625279f7 +# ╟─3e1c9184-d294-11ef-3e35-5393d97fbc44 +# ╟─3e1d33c8-d294-11ef-0a08-bdc419949925 +# ╟─3e1b05ee-d294-11ef-33de-efed64d01c0d +# ╟─b176ceae-884e-4460-9f66-020c1ac447f1 +# ╟─e3157dc0-5a64-4479-a37a-40fe25cccc07 +# ╟─d93f73d4-2783-4777-b0ce-cdc0444cb300 +# ╟─079157c9-5d97-4dbc-8c47-afa8b661db06 +# ╟─7d493e09-f7cc-4e13-a506-b792edcbf390 +# ╟─8a7dd8b7-5faf-4091-8451-9769f842accb +# ╟─b7445b9b-7fbb-4560-b947-a23af0fcf101 +# ╟─3e1d20e0-d294-11ef-2044-e1fe6590a600 +# ╠═fc733d61-fd0f-4a13-9afc-4505ac0253df +# ╟─ab223dea-8ba8-4d30-94f4-72c8e070aadf +# ╟─922770f4-ddc8-4089-b378-f14088276b43 +# ╟─3e1de32c-d294-11ef-1f63-f190c8361404 +# ╟─4c639e65-e06b-4c5e-b6e7-aabed6b6c0b4 +# ╟─ff9142ba-3a85-48cf-8b78-07e0b554e280 +# ╟─3e027ede-4ac1-4521-a026-dc00bfca4adf +# ╟─3e1e2b96-d294-11ef-3a68-fdc78232142e +# ╟─727dc817-0284-4c0f-9a92-21dcbea50807 +# ╟─fae6f2ce-ac8f-4ea6-b2cf-38b30a7e20d4 +# ╟─ea803646-b18e-4f13-ab6a-fc5080d44e92 +# ╟─3e1d6d00-d294-11ef-1081-e11b8397eb91 +# ╟─9b85a92b-c56b-48a3-97c1-6b1882e33a22 +# ╟─2156f96e-eebe-4190-8ce9-c76825c6da71 +# ╟─ef264651-854e-4374-8ea8-5476c85150c4 +# ╟─3e1e4dda-d294-11ef-33b7-4bbe3300ca22 +# ╟─3e1e5a5a-d294-11ef-2fdf-efee4eb1a0f2 +# ╟─3e1e7742-d294-11ef-1204-f9be24da07ab +# ╟─3e1e9224-d294-11ef-38b3-137c2be22400 +# ╟─d2202628-e4f9-4289-b48e-23b5a0073f94 +# ╟─726e7e9f-3d68-4d02-9954-1edd98b74fdc +# ╟─58f70d3e-4b64-414e-b560-327be2a0c4c2 +# ╟─3e1ea442-d294-11ef-1364-8dd9986325f7 +# ╟─6d07be25-53d0-46b9-b197-a3680d830952 +# ╟─3e1eba72-d294-11ef-2f53-b56f1862fcbb +# ╟─3e1ed1a4-d294-11ef-2de4-d7cc540e06a1 +# ╟─3e1eeb14-d294-11ef-1702-f5d2cf6fe60a +# ╟─e5902178-6df2-4eb4-ac13-7370b3d00c9c +# ╟─6bc443b4-1a07-4f56-99fb-c30a4370da92 +# ╟─3e1f225a-d294-11ef-04c6-f3ca018ab286 +# ╟─98fa17a6-7c8b-46e4-b32d-52db183d88f8 +# ╠═27ec154a-a4c3-4d71-b2a0-45f2b456a8e4 +# ╠═de4dbfc9-9340-4ae2-b323-49abfd77f198 +# ╟─1cb8b2c4-e1ae-4973-ba53-fc6c7fe1f37a +# ╠═91a91472-ee6d-416b-b18e-acbedc03a7fe +# ╠═6485575d-c5a5-4891-8210-f50d6f75476f +# ╟─0abaed25-decc-4dcd-aa04-b68ec0d5c73e +# ╟─218d3b6e-50b6-4b98-a00c-a19dd33d2c03 +# ╠═e836f877-5ed6-4865-ba3a-1ca5a86b2349 +# ╟─c0ea3253-a06b-426c-91a3-a6dd33e42779 +# ╟─3e1f4f46-d294-11ef-29b8-69e546763781 +# ╟─3e1f68fa-d294-11ef-31b2-e7670da8c08c +# ╟─3e1f7d5e-d294-11ef-2878-05744036f32c +# ╟─3e1f8e48-d294-11ef-0f8a-b58294a8543d +# ╟─3e1fa04a-d294-11ef-00c3-a51d1aaa5553 +# ╟─50bdc2fe-f48d-4c4e-8b4e-170782681366 +# ╟─db73766d-643c-41d7-a1eb-f376c657f860 +# ╟─3e1fb370-d294-11ef-1fb6-63a41a024691 +# ╟─317707a3-9ef1-4c67-b451-6adcfcff50f0 +# ╟─9b92fc89-2036-4525-979b-d296ab29329c +# ╟─5da42e9a-4318-48ea-9f43-4c1e1c97bceb +# ╟─03692f4d-0daf-4dfc-a7ff-6b954326e4d0 +# ╟─3a1d380e-df80-4727-9772-f199214cf05d +# ╟─99d9099f-4908-4bb3-8d59-da9cb69af04c +# ╟─3b1b0869-b815-4697-9dba-3c4b4cb5ac47 +# ╟─5f377237-d9a5-4778-aa4d-1c6ce109b705 +# ╟─5613e9b7-ff0d-435a-9de6-aaf293ebf592 +# ╟─fc3151f9-e143-4e31-b7b7-3f25b4fe9dab +# ╟─66ebe33c-8360-4938-9b51-625e5bed176c +# ╟─5b681e41-ad14-4c58-8ea0-4b6d85885c51 +# ╟─91dd40f0-c373-48b3-b83b-6e8df2c43e5a +# ╟─a8d4a517-84a7-426e-a49e-482c5fd047ae +# ╟─d3b003c6-70ca-419f-a343-e35b266323f3 +# ╟─dd31ec7c-708d-4fd7-958d-f9887798a5bc +# ╠═eeb9a1f5-b857-4843-920b-2e4a9656f66b +# ╠═5394e37c-ae00-4042-8ada-3bbf32fbca9e +# ╠═b305a905-06c2-4a15-8042-72ef6375720f +# ╟─70d79732-0f55-40ba-929d-fba431318848 +# ╠═4f6dd225-c64d-4b76-b075-0bf71c863b5a +# ╟─a8046381-ff11-40af-ae2b-078d71c586e7 +# ╠═42b47af6-b850-4987-a2d7-805a2cb64e43 +# ╠═a66ab9df-897c-42e5-8b0f-c520ceaffa23 +# ╠═4a81342c-17c7-4eb9-933b-edb98df7b9c4 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/archive/Course Syllabus.jl b/mlss/archive/Course Syllabus.jl new file mode 100644 index 00000000..27aa976e --- /dev/null +++ b/mlss/archive/Course Syllabus.jl @@ -0,0 +1,602 @@ +### A Pluto.jl notebook ### +# v0.20.20 + +#> [frontmatter] +#> description = "Course Syllabus" +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# ╔═╡ f96d047f-9efa-4889-8b4e-a8d96677d072 +using BmlipTeachingTools + +# ╔═╡ 0cfd4bc0-d294-11ef-3537-630954a9dd27 +title("5SSD0 Course Syllabus") + +# ╔═╡ 467c8189-b5d3-4eaf-8886-6ae53136dd8f +PlutoUI.TableOfContents() + +# ╔═╡ 0cffef7e-d294-11ef-3dd5-1fd862260b70 +md""" +## Learning Goals + +This course provides an introduction to Bayesian machine learning and information processing systems. The Bayesian approach affords a unified and consistent treatment of many useful information processing systems. + +Upon successful completion of the course, students should be able to: + + * understand the essence of the Bayesian approach to information processing. + * specify a solution to an information processing problem as a Bayesian inference task on a probabilistic model. + * design a probabilistic model by a specifying a likelihood function and prior distribution; + * Code the solution in a probabilistic programming package. + * execute the Bayesian inference task either analytically or approximately. + * evaluate the resulting solution by examination of Bayesian evidence. + * be aware of the properties of commonly used probability distribitions such as the Gaussian, Gamma and multinomial distribution; models such as hidden Markov models and Gaussian mixture models; and inference methods such as the Laplace approximation, variational Bayes and message passing in a factor graph. + +""" + +# ╔═╡ 0d013750-d294-11ef-333c-d9eb7578fab2 +md""" +## Entrance Requirements (pre-knowledge) + +Undergraduate courses in Linear Algebra and Probability Theory (or Statistics). + +Some scientific programming experience, eg in MATLAB or Python. In this class, we use the [Julia](https://julialang.org/) programming language, which has a similar syntax to MATLAB, but is (close to) as fast as C. + +""" + +# ╔═╡ 0d0142b6-d294-11ef-0297-e5bb923ad942 +md""" +## Important Links + +Please bookmark the following three websites: + +1. The course homepage [http://bmlip.nl](http://bmlip.nl) contains links to all materials, such as lecture notes and video lectures. +2. The [Piazza course site](https://piazza.com/tue.nl/winter2026/5ssd0/home) will be used for Q&A and communication. +3. The [Canvas course site](https://canvas.tue.nl/courses/33478) will be sparingly used for communication (mostly by ESA staff) + +""" + +# ╔═╡ 0d015ab4-d294-11ef-2e53-5339062c435c +md""" +## Materials + +All materials can be accessed from the [course homepage](http://bmlip.nl). The materials consist of the following resources: + +##### Mandatory materials for the exam + + * Lecture notes + * Probabilistic Programming (PP) notes + * The lecture notes and probabilistic programming notes contain the mandatory materials. Some lecture notes are extended by a reading assignment, see the first cell ("Preliminaries") in the lecture notes. These reading assignments are also part of the mandatory materials. + +##### Optional materials to help understand the lectures and PP notes + + * video recordings of the Q2-2023/24 lecture series + * Q&A at Piazza + * practice exams + * In the lecture notes, slides that are not required for the exam are moved to the end of the notes in the **Optional Slides** section. + + +Source materials are available at GitHub repo at [https://github.com/bmlip/course](https://github.com/bmlip/course). If you spot an error in the materials, please raise an issue at Piazza. + +""" + +# ╔═╡ ab61d2fe-312c-4aca-9029-e446aaf2bfa2 +keyconcept("", +md""" All study materials are accessible at the course homepage [`http://bmlip.nl`](http://bmlip.nl).""") + +# ╔═╡ 0d016cf8-d294-11ef-0c84-336979a02dd7 +md""" +## Study Guide + +1. **Please study the lecture notes BEFORE you come to class!!** + - Optionally, you can view the video recordings of the Q2-2023/24 lecture series for additional explanations. + +2. Then come to the class! + - During the scheduled classroom meetings, I will not cover all of the material from the lecture notes in detail. Instead, I will begin with a summary of the notes and then be available to address any additional questions you may have. + - Pose your questions in the classroom so others can also learn from the answers and/or discussion. + +3. If you still have questions after class, or later on when preparing for the exam, pose your question at the **Piazza site**! + - Your questions will be answered at the Piazza site by fellow students and accorded (or corrected) by the teaching staff. + +Each class is accompanied by a set of exercises (at bottom of lecture notes). These are often somewhat challenging and emphasize _quantitative skills beyond what will be required for the exam_. You may use this [**Formula Sheet**](https://github.com/bmlip/course/blob/main/assets/files/5SSD0_formula_sheet.pdf) when working on the exercises; the same sheet will also be provided during the written exam. + + +""" + +# ╔═╡ 646b8c08-bcd8-4c20-973a-b03583a7d472 +keyconcept("", +"Study the materials _before_ you come to the class.") + +# ╔═╡ 0d017b82-d294-11ef-2d11-df36557202c9 +md""" +## Piazza (Q&A) + +We will be using [Piazza](https://piazza.com/) for Q&A and course announcements. Piazza is designed to get you help quickly and efficiently, both from classmates and the teaching staff. + +👉 [Sign up for Piazza](http://piazza.com/tue.nl/winter2026/5ssd0) today if you haven’t already, and consider installing the Piazza app on your phone. + +The sooner you start asking questions on Piazza (instead of sending emails), the sooner you’ll benefit from the collective knowledge of your classmates and instructors. Don’t hesitate to ask questions when something is unclear—you can even post anonymously if you prefer. + +All **course-related announcements** will also be disseminated via Piazza. Unless it concerns a personal matter, please post your course-related questions there (in the appropriate folder). + +We also encourage you to contribute by answering questions on Piazza: + + - You may answer anonymously if you wish. + - Explaining material to others is an excellent way to deepen your own understanding. + - Each question has one “student answer,” which the class can edit collaboratively, and one “instructor answer” for the teaching staff. + +Piazza also supports **LaTeX**, please use it for math. And don’t forget to try the **search** function before posting a new question. + +""" + +# ╔═╡ 74dedaac-0a3e-4b83-a081-d76cdb301d56 +keyconcept("", +md""" Piazza is a great resource for continuing discussion outside the classroom, where you can both ask and answer questions.""") + +# ╔═╡ 8317254e-249d-49c8-acfb-1725c6349df8 +md""" +## Pluto + +All lectures were developed in executable [Julia](https://julialang.org/) code. Julia is an open-source programming language with a MATLAB-like syntax and performance comparable to C. + +We created interactive course notebooks using [Pluto](https://plutojl.org/), which allows students to modify simulation conditions and immediately observe the results. + +We look forward to receiving your feedback on your experiences with Pluto as an educational tool for playing with interactive learning materials. + +""" + +# ╔═╡ 0d018ee2-d294-11ef-3b3d-e34d0532a953 +md""" +## Exam Guide + +The course will be scored by two programming assignments and a final written exam. See the [course homepage](https://github.com/bmlip/course?tab=readme-ov-file#exams--assignments) for how the final score is computed. + +**The written exam is in multiple-choice format.** + +You are not allowed to use books, smartphones, calculators, or bring printed or handwritten formula sheets to the exam. All difficult-to-remember formulas are included on this [Formula Sheet](https://github.com/bmlip/course/blob/main/assets/files/5SSD0_formula_sheet.pdf), which will be provided together with the exam. + +The class homepage contains [two representative practice exams](https://github.com/bmlip/course?tab=readme-ov-file#exams--assignments) from previous terms. **It is highly recommended to practice with these previous exams when preparing for the exam.**. + + +""" + +# ╔═╡ 31f8669b-b547-4a11-acc6-64e02e6e9dc0 +keyconcept("","The written exam will be in multiple-choice format. Two previous exams, along with their answers, are available on the course homepage.") + +# ╔═╡ f46ccac8-e87c-4cbe-9d2c-fdb4723c639e +keyconcept("",md"""When working on exercises or preparing for the written exam, you may use this [Formula Sheet](https://github.com/bmlip/course/blob/main/assets/files/5SSD0_formula_sheet.pdf), which will also be provided during the exam.""" ) + +# ╔═╡ e56f489e-bd51-4499-aa80-1844c8651184 +md""" +## Results of Previous Exams +![](https://github.com/bmlip/course/blob/main/assets/figures/exam-results.png?raw=true) +""" + +# ╔═╡ 0d019cde-d294-11ef-0563-6b41bc2ca80f +TwoColumn( +md""" +## Preview +Check out [a recording from last year](https://youtu.be/k9DO26O6dIg?si=b8EiK12O_s76btPn) to understand what this class will be like. +""", +md""" +![](https://github.com/bmlip/course/blob/main/assets/figures/Professor-Terguson.png?raw=true) +""") + +# ╔═╡ f0a4b221-b4cd-425c-9a35-44c68c64e341 +md""" +# Summary +""" + +# ╔═╡ 9b1342f1-fcc9-469a-abfe-ed73a5b56d75 +keyconceptsummary() + +# ╔═╡ f3b97e01-f8d2-4865-ae81-2df412f7515a +md""" +# Code +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" + +[compat] +BmlipTeachingTools = "~1.3.1" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "3e0db0a10f1d7687b8c53fc91306ce22ead0cdba" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" + + [deps.Pkg.extensions] + REPLExt = "REPL" + + [deps.Pkg.weakdeps] + REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + + [deps.Statistics.weakdeps] + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" +""" + +# ╔═╡ Cell order: +# ╟─0cfd4bc0-d294-11ef-3537-630954a9dd27 +# ╟─467c8189-b5d3-4eaf-8886-6ae53136dd8f +# ╟─0cffef7e-d294-11ef-3dd5-1fd862260b70 +# ╟─0d013750-d294-11ef-333c-d9eb7578fab2 +# ╟─0d0142b6-d294-11ef-0297-e5bb923ad942 +# ╟─0d015ab4-d294-11ef-2e53-5339062c435c +# ╟─ab61d2fe-312c-4aca-9029-e446aaf2bfa2 +# ╟─0d016cf8-d294-11ef-0c84-336979a02dd7 +# ╟─646b8c08-bcd8-4c20-973a-b03583a7d472 +# ╟─0d017b82-d294-11ef-2d11-df36557202c9 +# ╟─74dedaac-0a3e-4b83-a081-d76cdb301d56 +# ╟─8317254e-249d-49c8-acfb-1725c6349df8 +# ╟─0d018ee2-d294-11ef-3b3d-e34d0532a953 +# ╟─31f8669b-b547-4a11-acc6-64e02e6e9dc0 +# ╟─f46ccac8-e87c-4cbe-9d2c-fdb4723c639e +# ╟─e56f489e-bd51-4499-aa80-1844c8651184 +# ╟─0d019cde-d294-11ef-0563-6b41bc2ca80f +# ╟─f0a4b221-b4cd-425c-9a35-44c68c64e341 +# ╟─9b1342f1-fcc9-469a-abfe-ed73a5b56d75 +# ╟─f3b97e01-f8d2-4865-ae81-2df412f7515a +# ╠═f96d047f-9efa-4889-8b4e-a8d96677d072 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/archive/Discriminative Classification.jl b/mlss/archive/Discriminative Classification.jl new file mode 100644 index 00000000..005119fa --- /dev/null +++ b/mlss/archive/Discriminative Classification.jl @@ -0,0 +1,2560 @@ +### A Pluto.jl notebook ### +# v0.20.21 + +#> [frontmatter] +#> image = "https://github.com/bmlip/course/blob/v2/assets/figures/Figure4.9.png?raw=true" +#> description = "Introduction to discriminative classification models and Bayesian logistic regression." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ e379cc2a-43f8-432f-84fc-a88fd4f3ad0a +using BmlipTeachingTools + +# ╔═╡ a759653c-0da4-40b7-9e9e-1e3d2e4df4ea +using Random, Plots, LaTeXStrings + +# ╔═╡ ad196ae6-c65e-4aaa-b0cc-bd72daa41952 +using MarkdownLiteral: @mdx + +# ╔═╡ 616e84d7-063d-4d9d-99e4-56aecf3c7ee4 +using Distributions, ExponentialFamily, LinearAlgebra, LogExpFunctions, StatsFuns, BayesBase, Optim + +# ╔═╡ 25eefb10-d294-11ef-0734-2daf18636e8e +title("Discriminative Classification") + +# ╔═╡ e7c45ff8-9fa2-4ea3-a06f-5769d877540e +PlutoUI.TableOfContents() + +# ╔═╡ 25ef12bc-d294-11ef-1557-d98ba829a804 +md""" +## Preliminaries + +##### Goal + + * Introduction to discriminative classification models + +##### Materials + + * Mandatory + + * These lecture notes + * Optional + + * [Bishop PRML book](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf) (2006), pp. 213 - 217 (Laplace approximation) + * [Bishop PRML book](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf) (2006), pp. 217 - 220 (Bayesian logistic regression) + * [T. Minka (2005), Discriminative models, not discriminative training](https://github.com/bmlip/course/blob/main/assets/files/Minka-2005-Discriminative-models-not-discriminative-training.pdf) + +""" + +# ╔═╡ fe66a986-2f55-4417-a71d-b3b99f6369cc +challenge_statement("difficult class-conditional data distributions" , header_level=1, color= "red" ) + +# ╔═╡ 25ef2806-d294-11ef-3cb6-0f3e76b9177e +md""" +Our task will be the same as in the preceding class on (generative) classification. But this time, the class-conditional data distributions look very non-Gaussian, yet the linear discriminative boundary looks easy enough. + +""" + +# ╔═╡ 4ceede48-a4d5-446b-bb34-26cec4af357a +begin + N_bond = @bindname N Slider(9:200; default=120, show_value=true) +end + +# ╔═╡ 7e7cab21-09ab-4d06-9716-ab7864b229ab +md""" +See [data generation code](#Data-Generation). +""" + +# ╔═╡ aeee1072-5173-4eae-8027-3fbf2e338d95 +md""" +### Why Not Generative Classification? +Like in the [last lecture](https://bmlip.github.io/course/lectures/Generative%20Classification.html), let's try to fit a generative distribution to the data. This is what we get when fitting two Gaussians to the two classes: +""" + +# ╔═╡ 93083660-6a49-4147-b00c-d62a4453f222 +md""" +That's not a good fit! + +Now, we could continue down this road, and try to fit a more complex distribution to the ``y = 1`` class to make it fit. **But let's explore a different approach**, modeling the discrimative boundary directly. +""" + +# ╔═╡ d1bbdc6a-e5ff-4cd6-9175-860b5ec04f3c +md""" +# Bayesian Logistic Regression +""" + +# ╔═╡ 25ef6ece-d294-11ef-270a-999c8d457b24 +md""" +## Framework + +A data set is given by ``D = \{(x_1,y_1),\dotsc,(x_N,y_N)\}`` with ``x_n \in \mathbb{R}^M`` and ``y_n \in \mathcal{C}_k``, with ``k=1,\ldots,K``. + +""" + +# ╔═╡ 25ef7f54-d294-11ef-3f05-0d85fe6e7a17 +md""" +Sometimes, the precise assumptions of the (Gaussian-Categorical) generative model + +```math +p(x_n,y_n\in\mathcal{C}_k|\theta) = \pi_k \cdot \mathcal{N}(x_n|\mu_k,\Sigma) +``` + +clearly do not match the data distribution. + +""" + +# ╔═╡ 25efa2fe-d294-11ef-172f-9bb09277f59e +md""" +Here's an **IDEA**! Let's model the posterior + +```math +p(y_n\in\mathcal{C}_k|x_n) +``` + +*directly*, without any assumptions on the class densities. + +""" + +# ╔═╡ 25efbe42-d294-11ef-3e4e-cfea366757da +md""" +Similarly to regression, we will assume that the inputs ``x`` are given, so we wil not add a model ``p(x)`` for input uncertainties. + +""" + +# ╔═╡ 25efd6b6-d294-11ef-3b21-6363ef531eb5 +md""" +## Model Specification +We will work this idea out for a 2-class problem. Assume a data set is given by ``D = \{(x_1,y_1),\dotsc,(x_N,y_N)\}`` with ``x_n \in \mathbb{R}^M`` and ``y_n \in \{0,1\}``. + +""" + +# ╔═╡ 25f02ac6-d294-11ef-26c4-f142b8ac4b5f +md""" +What model should we use for the posterior distribution ``p(y_n \in \mathcal{C}_k|x_n)``? + +""" + +# ╔═╡ 25f0adde-d294-11ef-353e-4b4773df9ff5 +md""" +#### Data-generating distribution + +We will take inspiration from the [generative classification](https://bmlip.github.io/course/lectures/Generative%20Classification.html#softmax) approach, where we derived the class posterior + +```math +p(y_{nk} = 1\,|\,x_n,\beta_k,\gamma_k) = \sigma(\beta_k^T x_n + \gamma_k) +``` + +as a **softmax** function of a linear map of the input. + +Here, in logistic regression, we *choose* the 2-class softmax function (which is called the [**logistic** function](https://en.wikipedia.org/wiki/Logistic_function)) with linear discrimination bounderies for the posterior class probability: + +```math +p(y_n =1 \,|\, x_n, w) = \sigma(w^T x_n) \,. +``` + +where + +```math +\sigma(a) = \frac{1}{1+e^{-a}} +``` + +is the *logistic* function. + +Clearly, it follows from this assumption that ``p(y_n =0 \,|\, x_n, w) = 1- \sigma(w^T x_n)``. + +""" + +# ╔═╡ 22121f20-6b90-4782-8bed-25486cc23ae7 +NotebookCard("https://bmlip.github.io/course/minis/Softmax.html") + +# ╔═╡ 56cae988-2f51-4618-8676-f46fa2924ea3 +let + logistic_function(a) = 1 / (1 + exp(-a)) + + probit(p) = cdf(Normal(0, 1), p) + scaled_proibit(a; λ=sqrt(π/8)) = probit(a*λ) + + p = plot( + xlim=(-9, 9), + ylim=(0,1), + size=(600,250), + ) + + plot!(logistic_function; label="logistic", lw=2) + plot!(scaled_proibit; label="probit", lw=2) +end + +# ╔═╡ 66351c02-1921-44dc-b461-84a536c40fd5 +md""" +The logistic function ``\sigma(a) = 1/(1+e^{-a})`` (red), together with the $(HTML("scaled probit function")) ``\Phi(\lambda a)``, for ``\lambda^2=\pi/8`` (in blue). We will use this approximation later in the [Laplace approximation](https://bmlip.github.io/course/minis/Laplace%20Approximation.html#gaussian-cdf). _Based on Bishop fig.4.9._ +""" + +# ╔═╡ e3173267-bd90-47df-9d7f-bd9fd3f688ac + + +# ╔═╡ 25f12528-d294-11ef-0c65-97c61935e9c2 +md""" +Adding the other class (``y_n=0``) leads to the following posterior class distribution: + +```math +\begin{align*} +p(y_n \,|\, x_n, w) &= \mathrm{Bernoulli}\left(y_n \,|\, \sigma(w^T x_n) \right) \\ +&= \sigma(w^T x_n)^{y_n} \left(1 - \sigma(w^T x_n)\right)^{(1-y_n)} \tag{B-4.89} \\ + &= \sigma\left( (2y_n-1) w^T x_n\right) +\end{align*} +``` + +Note that for the 3rd equality, we have made use of the fact that ``\sigma(-a) = 1-\sigma(a)``. + +Each of these three models in B-4.89 are **equivalent**. We mention all three notational options since they all appear in the literature. + +""" + +# ╔═╡ 25f14226-d294-11ef-369f-e545d5fe2700 +md""" +This choice for the class posterior is called **logistic regression**, in analogy to [linear regression](https://bmlip.github.io/course/lectures/Regression.html#likelihood-function): + +```math +\begin{align} +p(y_n|x_n,w) &= \mathcal{N}(y_n|w^T x_n,\beta^{-1}) \tag{for linear regression} \\ +p(y_n|x_n,w) &= \mathrm{Bernoulli}\left(y_n \,|\, \sigma(w^T x_n) \right) \tag{for logistic regression} +\end{align} +``` + +""" + +# ╔═╡ 25f14f82-d294-11ef-02fb-2dc632b8f118 +md""" +In the discriminative approach, the parameters ``w`` are **not** structured into ``\{\mu,\Sigma,\pi \}``. In principle they are "free" parameters for which we can choose any value that seems appropriate. This provides discriminative approach with more flexibility than the generative approach. + +""" + +# ╔═╡ 25f15e0a-d294-11ef-3737-79a68c9b3c61 +md""" +#### Prior + +In *Bayesian* logistic regression, we often add a **Gaussian prior on the weights**: + +```math +\begin{align*} +p(w) = \mathcal{N}(w \,|\, m_0, S_0) \tag{B-4.140} +\end{align*} +``` +""" + +# ╔═╡ 22f4972e-0f6d-49a1-bd1f-10569b77a852 +keyconcept("", +md""" +Discriminative classification follows the approach we used for Regression, namely, a direct model + +```math +\begin{align} +p(y_n \,|\, x_n, w) &= \mathrm{Bernoulli}\left(y_n \,|\, \sigma(w^T x_n) \right) \\ +p(w) &= \mathcal{N}(w \,|\, m_0, S_0) +\end{align} +``` + +for outputs ``y_n``, given inputs ``x_n``. +""") + +# ╔═╡ 25f19ed8-d294-11ef-3298-efa16dda1dde +md""" +## Parameter Inference + +Note that for generative classification, for the sake of simplicity, we used maximum likelihood estimation for the model parameters. We could have used Bayesian parameter estimation for the generative classification model but the math is not suited for an introductory lesson. + +In this lesson on discriminative classification, we specify both a prior and likelihood function for the parameters ``w``, which allows us to compute a Bayesian posterior for the weights. + +As before, once the model is specified, everything else follows directly from the rules of probability theory. + + +""" + +# ╔═╡ 25f1390c-d294-11ef-364d-17e4c93b9a57 +md""" +For the data set ``D = \{(x_1,y_1),\dotsc,(x_N,y_N)\}``, the **likelihood function** for the parameters ``w`` is given by + +```math +p(D|w) = \prod_{n=1}^N p(y_n|x_n,w) = \prod_{n=1}^N \sigma\left( (2y_n-1) w^T x_n\right) +``` + +""" + +# ╔═╡ bda07a2e-3769-4ffe-9bc5-2b8a515247f6 +md""" + + +The posterior for the weights follows by Bayes rule, + +```math +\begin{align*} +\underbrace{p(w \,|\, D)}_{\text{posterior}} &= \frac{p(w) p(D|w)}{\int p(w) p(D|w) \mathrm{d}w} \\ &= \frac{\overbrace{\mathcal{N}(w \,|\, m_0, S_0)}^{\text{prior}} \cdot \overbrace{\prod_{n=1}^N \sigma\left( (2y_n-1) w^T x_n\right)}^{\text{likelihood}}}{\underbrace{\int \mathcal{N}(w \,|\, m_0, S_0) \prod_{n=1}^N \sigma\left( (2y_n-1) w^T x_n\right) \mathrm{d}w}_{\text{evidence}}} \tag{B-4.142} +\end{align*} +``` + +In principle, Bayesian learning of the parameters is done now! + +Unfortunately, the posterior ``p(w | D)`` is not Gaussian, and the evidence ``p(D)`` is also not analytically computable. (We will deal with this later). +""" + +# ╔═╡ 25f1ab08-d294-11ef-32ed-493792e121b7 +md""" +## Application: the predictive distribution + +For a new data point ``x_\bullet``, the predictive distribution for ``y_\bullet=1`` is given by + +```math +\begin{align*} +p(y_\bullet = 1 | x_\bullet, D) &= \int p(y_\bullet = 1 \,|\, x_\bullet, w) \, p(w| D) \,\mathrm{d}w \\ + &= \int \sigma(w^T x_\bullet) \, p(w| D) \,\mathrm{d}w \tag{B-4.145} +\end{align*} +``` + +""" + +# ╔═╡ 25f1b404-d294-11ef-1c3a-a5a8142bb202 +md""" +While Eq. B-4.145 gives the expression for the Bayesian predictive class distribution, the integral becomes analytically intractable when we substitute the posterior distribution over weights, ``p(w | D)`` (from Eq. B-4.142), into it :( + +""" + +# ╔═╡ 25f1c2a0-d294-11ef-009c-69b64e87e5fb +md""" +Many methods have been developed to approximate these types of Bayesian integrals. Here, we present the **Laplace approximation**, which is one of the simplest methods with broad applicability to Bayesian calculations. + +""" + +# ╔═╡ 3422dd29-6da9-4e0f-a4ab-646f223c2244 +md""" +## Working out Numerics with Laplace Approximation +""" + +# ╔═╡ 8b0bb225-bdc1-45ec-bd34-68d674d6f08d +md""" +The **Laplace Approximation** approximates a function by a Gaussian-shaped function. In this case, we will approximate the weight posterior ``p(w|D)`` by a Gaussian distribution + +```math +q(w) = \mathcal{N}\left(w\,|\, m_{N}, S_N\right) \tag{B-4.144} +``` + +with + +```math +\begin{align} +m_N &= \arg\max_w \log p(w|D) \\ +S_N^{-1} &= S_0^{-1} + \sum_n \sigma_n (1-\sigma_n) x_n x_n^T \tag{B-4.143} +\end{align} +``` +where we used short-hand ``\sigma_n = \sigma\left((2y_n-1) m_N^T x_n\right)``. + +If we substitute the Gaussian approximation from Eq. B-4.143 into the expression for the predictive class distribution (Eq. B-4.145), we obtain (after some additional approximations): + +```math +\begin{align*} +p(y_\bullet = 1 \mid x_\bullet, D) &= \int p(y_\bullet = 1 \,|\, x_\bullet, w) \cdot p(w\,|\, D) \,\mathrm{d}w \\ +&\approx \int p(y_\bullet = 1 \,|\, x_\bullet, w) \cdot q(w) \,\mathrm{d}w \\ + &= \int \sigma(w^T x_\bullet) \cdot \mathcal{N}\left(w \,|\, m_N, S_N\right) \,\mathrm{d}w \tag{B-4.145} \\ +&\approx \Phi\left( \frac{\mu_a}{\sqrt(\lambda^{-2} +\sigma_a^2)}\right) \tag{B-4.152} +\end{align*} +``` + +where + +```math +\begin{align} +\lambda^2 &= \pi / 8 \\ +\mu_a &= m^T_{N} x_\bullet \tag{B-4.149} \\ +\sigma_a^2 &= x^T_\bullet S_N x_\bullet \tag{B-4.150} +\end{align} +``` +and ``\Phi(x)= \frac{1}{\sqrt(2\pi)}\int_{-\infty}^{x}e^{-t^2/2}\mathrm{d}t`` is the Gaussian cumulative distribution function (CDF) . The Gaussian CDF closely approximates the logistic sigmoid function, with +``\Phi(\sqrt{\pi/8} a) \approx \sigma(a)``. + + +""" + +# ╔═╡ ae2b23f0-853e-4237-aab2-81c961f52cf6 +md""" +Although the intermediate equations may look intimidating, the final result for the predictive distribution Eq. B-4.152 has a simple closed-form expression. + +""" + +# ╔═╡ e4cc517b-d3b5-4517-a28b-efb8aba24496 +md""" +The numerical issues associated with the Laplace approximation and the evaluation of the predictive class distribution are discussed in detail in the following mini-lecture. +""" + +# ╔═╡ 33b859f2-9ea8-4f8b-b0f8-08a19c6a96fc +NotebookCard("https://bmlip.github.io/course/minis/Laplace%20Approximation.html") + +# ╔═╡ 9704ee6a-e233-49f1-8c66-d81543927342 +keyconcept("", +md""" +It is easy to write down the Bayesian equations for the weight posterior and the predictive distribution of ``y_\bullet``, but in practice these do not admit closed-form solutions. A traditional workaround is the **Laplace approximation**, which has long been used to approximate the marginalization integrals in Bayesian inference. +""") + +# ╔═╡ 4ab4bcca-da6e-4137-858d-257c04388277 +keyconcept("", +md""" +The Laplace approximation renders a closed-form and interpretable (approximate) solution for the predictive class distribution, +```math +p(y_\bullet = 1 | x_\bullet, D) \approx \Phi\left( \frac{m^T_{N} x_\bullet}{\sqrt{(8/\pi) +x^T_\bullet S_N x_\bullet)}}\right)\,. +``` + +""") + +# ╔═╡ 38b4854f-be02-4696-802f-2106481e3aea +md""" +## Bayesian Processing of Uncertainties + +We now make an important observation: According to Eq. B-4.143, the posterior covariance matrix ``S_N`` of the weight vector depends on both the prior variance ``S_0`` and the distribution of the training data ``\{(x_n, y_n)\}_{n=1}^N``. In regions with limited training data and/or an uninformative prior (i.e., large ``S_0``), the posterior uncertainty about the weights remains high. This increased uncertainty raises ``\sigma_a^2`` in Eq. B-4.150, **causing the posterior class probability in Eq. B-4.152 to approach ``0.5``** (since ``\Phi(0) = 0.5``, see [Gaussian CDF image](https://en.wikipedia.org/wiki/Normal_distribution#/media/File:Normal_Distribution_CDF.svg)), thereby reflecting greater uncertainty in the prediction. + +In other words, if you draw a new feature ``x_\bullet`` from a region with little training data, then the predictive class probability ``p(y_\bullet | x_\bullet, D)`` naturally tends toward ``0.5``, a built-in expression of uncertainty, courtesy of the Bayesian framework. + +In contrast, if you eliminate uncertainty by representing the weights as fixed-point estimates (i.e., as mere numbers), then the model becomes overconfident. It will still produce sharp predictions, even in regions where it has seen no data, exactly when it should be most uncertain. + +""" + +# ╔═╡ 7932fff4-0568-49de-b34c-711e51487ae3 +challenge_solution("Bayesian Logistic Regression" , color= "green", header_level=1 ) + +# ╔═╡ 25f3bef2-d294-11ef-1438-e9f7e469336f +md""" + +Let us perform Bayesian inference to estimate the posterior distribution of ``w`` given the data set from the introduction. To allow an offset in the discrimination boundary, we add a constant 1 to the feature vector ``x``. +""" + +# ╔═╡ aaf764da-cf1b-4bc7-83ea-6d25a80ca3ab +N_bond + +# ╔═╡ 69706576-0333-43bf-8523-e7838f373529 +md""" +Note that we get a full predictive posterior distribution over the assignment of class labels for every datapoint, so instead of assigning a point to a class, we get a measure of uncertainty over our class assignment! + +""" + +# ╔═╡ 98ef7093-f8ed-4a44-a153-0a64ab483f65 +md""" +## Implementation Issues +""" + +# ╔═╡ 0045e569-dc3c-4998-86da-9d96f599c599 +md""" +# Maximum Likelihood Estimation + +""" + +# ╔═╡ 25f365e2-d294-11ef-300e-9914333b1233 +md""" + +Rather than the computationally involved Laplace approximation, in practice, discriminative classification is often executed through maximum likelihood estimation. + +With the usual 1-of-K encoding scheme for classes, + +```math +y_{nk} = \begin{cases} 1 & \text{if } x_n \in \mathcal{C}_k \\ + 0 & \text{otherwise} \,,\end{cases} +``` + +the log-likelihood for a ``K``-dimensional discriminative classifier evaluates to + +```math +\begin{align*} + \mathrm{L}(w) &= \log \prod_n \prod_k {p(\mathcal{C}_k|x_n,w)}^{y_{nk}} \\ + &= \sum_n \sum_k y_{kn} \log \bigg( \underbrace{\frac{e^{w_k^T x_n}}{ \sum_j e^{w_j^T x_n}}}_{=\text{softmax}(w_k^T x_n)} \bigg) + \end{align*} +``` + +The gradient ``\nabla_{w_k} \mathrm{L}(w)`` to the weight ``w_k`` can be worked out to +```math +\nabla_{w_k} \mathrm{L}(w) = \sum_n \underbrace{\big( \underbrace{y_{nk}}_{\text{target}} - \underbrace{\frac{e^{w_k^T x_n}}{ \sum_j e^{w_j^T x_n}}}_{\text{prediction}} \big)}_{\text{prediction error}}\cdot x_n . +``` + +""" + +# ╔═╡ 3b24b142-2239-4951-9177-ff87b5da4b68 +hide_proof( + md""" +The Log-likelihood is + +```math +\mathrm{L}(w) = \log \prod_n \prod_k {\underbrace{p(y_{nk}=1|x_n,w)}_{p_{nk}}}^{y_{nk}} = \sum_{n,k} y_{nk} \log p_{nk} +``` + +Use the fact that the softmax ``\phi_k \equiv e^{a_k} / {\sum_j e^{a_j}}`` has analytical derivative, + +```math + \begin{align*} + \frac{\partial \phi_k}{\partial a_j} &= \frac{(\sum_j e^{a_j})e^{a_k}\delta_{kj}-e^{a_j}e^{a_k}}{(\sum_j e^{a_j})^2} = \frac{e^{a_k}}{\sum_j e^{a_j}}\delta_{kj} - \frac{e^{a_j}}{\sum_j e^{a_j}} \frac{e^{a_k}}{\sum_j e^{a_j}}\\ + &= \phi_k \cdot(\delta_{kj}-\phi_j) \,. + \end{align*} +``` + +Take the derivative of ``\mathrm{L}(w)`` (or: how to spend an hour ...) + +```math +\begin{align*} +\nabla_{w_j} \mathrm{L}(w) &= \sum_{n,k} \frac{\partial \mathrm{L}_{nk}}{\partial p_{nk}} \cdot\frac{\partial p_{nk}}{\partial a_{nj}}\cdot\frac{\partial a_{nj}}{\partial w_j} \\ + &= \sum_{n,k} \frac{y_{nk}}{p_{nk}} \cdot p_{nk} (\delta_{kj}-p_{nj}) \cdot x_n \\ + &= \sum_n \Big( y_{nj} (1-p_{nj}) -\sum_{k\neq j} y_{nk} p_{nj} \Big) \cdot x_n \\ + &= \sum_n \left( y_{nj} - p_{nj} \right)\cdot x_n \\ + &= \sum_n \Big( \underbrace{y_{nj}}_{\text{target}} - \underbrace{\frac{e^{w_j^T x_n}}{\sum_{j^\prime} e^{w_{j^\prime}^T x_n}}}_{\text{prediction}} \Big)\cdot x_n +\end{align*} +``` + + + """) + +# ╔═╡ ff31d8c1-db35-4c85-a609-67fc40e9e78d +md""" + +The parameter vector ``w`` for logistic regression can then be estimated through iterative gradient-based adaptation. For instance, start with a random weight ``\hat{w} = w_0``, and iterate through + +```math +\hat{w}^{(i+1)} = \hat{w}^{(i)} + \eta \cdot \left. \nabla_w \mathrm{L}(w) \right|_{w = \hat{w}^{(i)}} +``` +until convergence. + +""" + +# ╔═╡ 1f2bfcf4-fef4-4612-8683-d5c86a326eef +md""" +# Closing Thoughts +""" + +# ╔═╡ 25f3ff84-d294-11ef-0031-63b23d23324d +md""" +## Why be Bayesian? + +Why should you embrace the Bayesian approach to logistic regression? After all, Maximum Likelihood for logistic regression seems simpler. + +Still, consider the following: + + * Bayesian logistic regression with the Laplace approximation ultimately leads to very simple analytic rules. Moreover, modern probabilistic programming languages and packages are able to automate the above inference derivations. (We just do them here to gain insight into a difficult inference process.) + + * Bayesian logistic regression allows for the computation of model evidence, enabling principled comparison of model performance across alternative models. + + * Perhaps most importantly, Bayesian logistic regression processes uncertainties, e.g., in places where almost no data is observed, the posterior class probability will pull back to the prior class probability rather than predicting some arbitrary probability. + +""" + +# ╔═╡ 5d91a2ae-975c-4913-b8ff-3df043cb1f03 +md""" +## Recap Classification +""" + +# ╔═╡ 25f41118-d294-11ef-13a8-3fa6587c1bf3 +@mdx """ + +Let us recapitulate the differences between the generative and discriminative approaches to classification in a table: + + + + + + + + +
Generative Discriminative (ML)
1Like density estimation, model joint prob. + +```math +p(\\mathcal{C}_k) p(x|\\mathcal{C}_k) = \\pi_k \\mathcal{N}(\\mu_k,\\Sigma) +``` + + Like (linear) regression, model conditional + +```math +p(\\mathcal{C}_k|x,\\theta) +``` + +
2Leads to softmax posterior class probability + +```math + p(\\mathcal{C}_k|x,\\theta ) = e^{\\theta_k^T x}/Z +``` + +with structured ``\\theta`` Choose also softmax posterior class probability + +```math + p(\\mathcal{C}_k|x,\\theta ) = e^{\\theta_k^T x}/Z +``` + +but now with 'free' ``\\theta``
3 + +For Gaussian ``p(x|\\mathcal{C}_k)`` and multinomial priors, + +```math +\\hat \\theta_k = \\left[ {\\begin{array}{c} + { - \\frac{1}{2} \\mu_k^T \\sigma^{-1} \\mu_k + \\log \\pi_k} \\\\ + {\\sigma^{-1} \\mu_k } \\\\ +\\end{array}} \\right] +``` + +in one shot. Find ``\\hat\\theta_k`` through gradient-based adaptation + +```math +\\nabla_{\\theta_k}\\mathrm{L}(\\theta) = \\sum_n \\Big( y_{nk} - \\frac{e^{\\theta_k^T x_n}}{\\sum_{k^\\prime} e^{\\theta_{k^\\prime}^T x_n}} \\Big)\\, x_n +``` + +
+ +""" + +# ╔═╡ 25f19230-d294-11ef-2dfd-6d4927e86f57 +md""" +## Discriminative Training or Discriminative Models? + +In this lecture series, we presented two approaches to classification, namely the generative and the discriminative approach. + +While the discriminative approach is intuitive and effective for many tasks, it sits somewhat uncomfortably with the [Bayesian modeling approach](https://bmlip.github.io/course/lectures/Bayesian%20Machine%20Learning.html#The-Bayesian-Modeling-Approach) outlined in the Bayesian Machine Learning lecture. Specifically, the discriminative approach does not define a full joint model over all variables in the system. Instead, it focuses only on modeling the conditional distribution ``p(y | x)``, effectively ignoring the input distribution ``p(x)`` that would normally be part of a fully generative Bayesian model. + +In a short paper by [T. Minka (2005)](https://github.com/bmlip/course/blob/main/assets/files/Minka-2005-Discriminative-models-not-discriminative-training.pdf), the model assumptions underlying discriminative classification are reinterpreted as arising from a special case of a generative model. This effectively restores discriminative approaches as fully compatible with the Bayesian modeling framework. (Note: the Minka paper is not required reading for the exam.) + +""" + +# ╔═╡ 173e545a-9125-4dc4-8df4-c3aa84a4b88a +md""" +# Summary +""" + +# ╔═╡ 557c4545-2208-43c9-9302-991e78202734 +keyconceptsummary() + +# ╔═╡ a00c545c-2274-4086-94ca-319d1436fa26 +exercises(header_level=1) + +# ╔═╡ b94644f8-725d-49bf-9641-3dad8b647f45 +md""" + +#### Discrimination boundaries (*) + +Show that for logistic regression with ``p(y_n =1 \,|\, x_n) = \sigma(w^T x_n)``, the discrimination boundary, which can be computed by + +```math +\frac{p(y_n =1|x_n)}{p(y_n =0|x_n)} \overset{!}{=} 1 +``` + +is a straight line. +""" + +# ╔═╡ 9554ed0b-69dd-443c-9538-03a4117eeb78 +hide_proof( +md""" + +```math +\begin{align} +\frac{ p(y_n =1 |x_n) }{ p(y_n =0|x_n) } &= \frac{ \sigma(w^T x_n)}{1 - \sigma(w^T x_n)} \\ +&= \frac{ \frac{1}{1+\exp(-w^T x_n)} }{ 1 -\frac{1}{1+\exp(-w^T x_n)} } \\ +&= \frac{1}{1+\exp(-w^T x_n) - 1} \\ +&= \exp(w^T x) +\end{align} +``` +Setting ``\exp(w^T x) \overset{!}{=} 1``, leads to +```math + w^T x = 0 +``` +for the discrimination boundary, which is a line. + """) + +# ╔═╡ 6eee35ee-fd55-498f-9441-f18c2508de19 +md""" +# Code +""" + +# ╔═╡ fcec3c3a-8b0b-4dfd-b010-66abbf330069 +function generate_dataset(N::Int64) + Random.seed!(1234) + # Generate dataset {(x1,y1),...,(xN,yN)} + # x is a 2d feature vector [x1;x2] + # y ∈ {false,true} is a binary class label + # p(x|y) is multi-modal (mixture of uniform and Gaussian distributions) + # srand(123) + X = Matrix{Float64}(undef,2,N); y = Vector{Bool}(undef,N) + for n=1:N + if (y[n]=(rand()>0.6)) # p(y=true) = 0.6 + # Sample class 1 conditional distribution + if rand()<0.5 + X[:,n] = [6.0; 0.5] .* rand(2) .+ [3.0; 6.0] + else + X[:,n] = sqrt(0.5) * randn(2) .+ [5.5, 0.0] + end + else + # Sample class 2 conditional distribution + X[:,n] = randn(2) .+ [1., 4.] + end + end + + return (X, y) +end + +# ╔═╡ b8790891-1546-48e0-9f96-e09eade31c12 +logσ(x) = -softplus(x) + +# ╔═╡ b48f8800-473d-48e4-ab78-eb07653db7a5 +function log_likelihood(w, X, y) + return sum(logσ.((2*y .- 1) .* (X' * w))) +end + + +# ╔═╡ 1bfac9c5-e5cf-4a70-b077-11bb00cb1482 +""" +This function computes the posterior distribution over regression weights using the Laplace Approximation. We use `logσ` as a numerically stable alternative to `logistic`, and we avoid matrix inversions by computing the precision matrix of the posterior distribution instead of the covariance. + +The math in this function corresponds to eq. B-4.143 +""" +function bayesian_discrimination_boundary(prior_w, X::Matrix, y::Vector{Bool}) + m_0 = mean(prior_w) + p_0 = precision(prior_w) + negative_unnormalized_posterior = w -> -log_likelihood(w, X, y) - logpdf(prior_w, w) + MAP_w = Optim.minimizer(optimize(negative_unnormalized_posterior, zeros(3))) + σ_n = logistic.((2y .- 1) .* (X' * MAP_w)) + inv_Σ = p_0 + for i in 1:length(y) + slice = view(X, :, i) + inv_Σ .+= σ_n[i] * (1.0 - σ_n[i]) .* (slice * slice') + end + + return MvNormalMeanPrecision(MAP_w, inv_Σ) +end + +# ╔═╡ fd908bf5-71a1-4ae8-8416-cc1fdf084dcb +""" +Computes the predictive posterior eq. B-4.152 using the given approximation to the sigmoid function. +""" +function predictive_posterior(x, weight_posterior) + λsq = π / 8 + wN = mean(weight_posterior) + μ = wN' * x + σ = x' * cov(weight_posterior) * x + query_point = μ / (sqrt(inv(λsq) + σ )) + return normcdf(0, 1, query_point) +end + +# ╔═╡ cf829697-6283-4d2f-b0dd-bbfbd689a145 +md""" +#### Data Generation +""" + +# ╔═╡ 5e4bb719-ea9b-4a30-8800-5d753f405fd1 +X, y = generate_dataset(N); # Generate data set, collect in matrix X and vector y + +# ╔═╡ 6b56ec96-4b9d-4281-bd63-061df324867f +X_c1 = X[:,findall(.!y)]' # Split X based on class label + +# ╔═╡ f8bb4fcd-9b20-44e5-8e22-e792e74b69df +X_c2 = X[:,findall(y)]' + +# ╔═╡ b5a19a34-b210-41ec-853d-c5df13ae17ce +X_test = [3.75; 1.0]; # Features of 'new' data point + +# ╔═╡ a65ca01a-0e9a-42cb-b1d7-648102a77eb5 +function plot_dataset() + result = scatter(X_c1[:,1], X_c1[:,2],markersize=4, label=L"y=0", xlabel=L"x_1", ylabel=L"x_2", xlims=(-1.6, 9), ylims=(-2, 7)) + scatter!(X_c2[:,1], X_c2[:,2],markersize=4, label=L"y=1") + scatter!([X_test[1]], [X_test[2]], markersize=7, marker=:star, label=L"y=?") + plot!(legend=:bottomright) + return result +end + +# ╔═╡ d29ccc9e-d4a6-46ae-b907-2bc68c8d99bc +plot_dataset() + +# ╔═╡ f37ac438-cd56-4a09-bc8e-a75469955a2f +let + d1 = fit_mle(MvNormal, X_c1') + d2 = fit_mle(MvNormal, X_c2') + + plot_dataset() + + xrange = range(-1.6, 9; length=20) + yrange = range(-2, 7; length=15) + + contour!( + xrange, yrange, + (x,y) -> pdf(d1, [x,y]); + opacity=.4, + color=:blues, + ) + + + contour!( + xrange, yrange, + (x,y) -> pdf(d2, [x,y]); + opacity=.4, + color=:red, + colorbar=nothing, + ) +end + +# ╔═╡ fce5d561-ea76-4bd8-9cce-6f707f72fc60 +bayesian_plot = let + X_ext = vcat(X, ones(1, length(y))) + + # Define a prior distribution over parameters, play with this to see the result change! + prior = MvNormalMeanCovariance(zeros(3), 100 .* diagm(ones(3))) + posterior = bayesian_discrimination_boundary(prior, X_ext, y) + + # Plot 50% boundary + θ = mean(posterior) + disc_boundary(x1) = -1 / θ[2] * (θ[1]*x1 + θ[3]) + plot_dataset() + plot!([-2., 10.], disc_boundary; label="Discr. boundary", linewidth=2) + + # Plot heatmap + xrange = range(-1.6, 9; length=50) + yrange = range(-2, 7; length=30) + heatmap!( + xrange, yrange, (x,y) -> predictive_posterior([x, y, 1], posterior); + alpha=0.5, color=:redblue, + ) +end; + +# ╔═╡ 75076ca1-7226-4229-8e70-06cc586507c3 +bayesian_plot + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BayesBase = "b4ee3484-f114-42fe-b91c-797d54a0c67e" +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +ExponentialFamily = "62312e5e-252a-4322-ace9-a5f4bf9b357b" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +MarkdownLiteral = "736d6165-7244-6769-4267-6b50796e6954" +Optim = "429524aa-4258-5aef-a3af-852621145aeb" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c" + +[compat] +BayesBase = "~1.5.8" +BmlipTeachingTools = "~1.3.1" +Distributions = "~0.25.122" +ExponentialFamily = "~2.1.1" +LaTeXStrings = "~1.4.0" +LogExpFunctions = "~0.3.29" +MarkdownLiteral = "~0.1.2" +Optim = "~1.13.2" +Plots = "~1.40.17" +StatsFuns = "~1.5.0" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "6c3dd68af2e626ed33e0c26a2dd1c4e83dc100b4" + +[[deps.ADTypes]] +git-tree-sha1 = "27cecae79e5cc9935255f90c53bb831cc3c870d7" +uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +version = "1.18.0" + + [deps.ADTypes.extensions] + ADTypesChainRulesCoreExt = "ChainRulesCore" + ADTypesConstructionBaseExt = "ConstructionBase" + ADTypesEnzymeCoreExt = "EnzymeCore" + + [deps.ADTypes.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.4.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "d2cd034553ee6ca084edaaf8ed6c9d50fd01555d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.21.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceMetalExt = "Metal" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.ArrayLayouts]] +deps = ["FillArrays", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "355ab2d61069927d4247cd69ad0e1f140b31e30d" +uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +version = "1.12.0" +weakdeps = ["SparseArrays"] + + [deps.ArrayLayouts.extensions] + ArrayLayoutsSparseArraysExt = "SparseArrays" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BayesBase]] +deps = ["Distributions", "DomainSets", "LinearAlgebra", "Random", "SpecialFunctions", "StaticArrays", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "TinyHugeNumbers"] +git-tree-sha1 = "5b723bf6b1081cab4d263e425be097224e0f434f" +uuid = "b4ee3484-f114-42fe-b91c-797d54a0c67e" +version = "1.5.8" +weakdeps = ["FastCholesky"] + + [deps.BayesBase.extensions] + FastCholeskyExt = "FastCholesky" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BlockArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra"] +git-tree-sha1 = "79e651aa489a7879107d66e3d1948e9aa1b4055e" +uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" +version = "1.7.2" + + [deps.BlockArrays.extensions] + BlockArraysAdaptExt = "Adapt" + BlockArraysBandedMatricesExt = "BandedMatrices" + + [deps.BlockArrays.weakdeps] + Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.Combinatorics]] +git-tree-sha1 = "8010b6bb3388abe68d95743dcbea77650bb2eddf" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.3" + +[[deps.CommonMark]] +deps = ["PrecompileTools"] +git-tree-sha1 = "351d6f4eaf273b753001b2de4dffb8279b100769" +uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" +version = "0.9.1" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.1" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.CompositeTypes]] +git-tree-sha1 = "bce26c3dab336582805503bed209faab1c279768" +uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657" +version = "0.1.4" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" +weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DifferentiationInterface]] +deps = ["ADTypes", "LinearAlgebra"] +git-tree-sha1 = "529bebbc74b36a4cfea09dd2aecb1288cd713a6d" +uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" +version = "0.7.9" + + [deps.DifferentiationInterface.extensions] + DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" + DifferentiationInterfaceDiffractorExt = "Diffractor" + DifferentiationInterfaceEnzymeExt = ["EnzymeCore", "Enzyme"] + DifferentiationInterfaceFastDifferentiationExt = "FastDifferentiation" + DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" + DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" + DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] + DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" + DifferentiationInterfaceGTPSAExt = "GTPSA" + DifferentiationInterfaceMooncakeExt = "Mooncake" + DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] + DifferentiationInterfaceReverseDiffExt = ["ReverseDiff", "DiffResults"] + DifferentiationInterfaceSparseArraysExt = "SparseArrays" + DifferentiationInterfaceSparseConnectivityTracerExt = "SparseConnectivityTracer" + DifferentiationInterfaceSparseMatrixColoringsExt = "SparseMatrixColorings" + DifferentiationInterfaceStaticArraysExt = "StaticArrays" + DifferentiationInterfaceSymbolicsExt = "Symbolics" + DifferentiationInterfaceTrackerExt = "Tracker" + DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] + + [deps.DifferentiationInterface.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" + Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + FastDifferentiation = "eb9bf01b-bf85-4b60-bf87-ee5de06c00be" + FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" + Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" + SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.DomainSets]] +deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "c249d86e97a7e8398ce2068dce4c078a1c3464de" +uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" +version = "0.7.16" + + [deps.DomainSets.extensions] + DomainSetsMakieExt = "Makie" + DomainSetsRandomExt = "Random" + + [deps.DomainSets.weakdeps] + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EnumX]] +git-tree-sha1 = "bddad79635af6aec424f53ed8aad5d7555dc6f00" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.5" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.ExponentialFamily]] +deps = ["BayesBase", "BlockArrays", "Distributions", "DomainSets", "FastCholesky", "FillArrays", "ForwardDiff", "HCubature", "HypergeometricFunctions", "IntervalSets", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "PositiveFactorizations", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "StatsBase", "StatsFuns", "TinyHugeNumbers"] +git-tree-sha1 = "8351e116e111c97ad57718851da00ae5a5f92e0c" +uuid = "62312e5e-252a-4322-ace9-a5f4bf9b357b" +version = "2.1.1" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FastCholesky]] +deps = ["LinearAlgebra", "PositiveFactorizations"] +git-tree-sha1 = "1c0a81e006e40e9fcbd5f6f6cb42ac2700f86889" +uuid = "2d5283b6-8564-42b6-bb00-83ed8e915756" +version = "1.4.3" +weakdeps = ["StaticArraysCore"] + + [deps.FastCholesky.extensions] + StaticArraysCoreExt = "StaticArraysCore" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] +git-tree-sha1 = "9340ca07ca27093ff68418b7558ca37b05f8aeb1" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.29.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffSparseArraysExt = "SparseArrays" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "ba6ce081425d0afb2bedd00d9884464f764a9225" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.2.2" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" +version = "1.11.0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HCubature]] +deps = ["Combinatorics", "DataStructures", "LinearAlgebra", "QuadGK", "StaticArrays"] +git-tree-sha1 = "19ef9f0cb324eed957b7fe7257ac84e8ed8a48ec" +uuid = "19dc6840-f33b-545b-b366-655c7e3ffd49" +version = "1.7.0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.IntervalSets]] +git-tree-sha1 = "5fbb102dcb8b1a858111ae81d56682376130517d" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.11" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.4.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MarkdownLiteral]] +deps = ["CommonMark", "HypertextLiteral"] +git-tree-sha1 = "f7d73634acd573bf3489df1ee0d270a5d6d3a7a3" +uuid = "736d6165-7244-6769-4267-6b50796e6954" +version = "0.1.2" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NLSolversBase]] +deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.10.0" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Optim]] +deps = ["Compat", "EnumX", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "61942645c38dd2b5b78e2082c9b51ab315315d10" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.13.2" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.2" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.15" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TinyHugeNumbers]] +git-tree-sha1 = "83c6abf376718345a85c071b249ef6692a8936d4" +uuid = "783c9a47-75a3-44ac-a16b-f1ab7b3acf04" +version = "1.0.3" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─25eefb10-d294-11ef-0734-2daf18636e8e +# ╟─e7c45ff8-9fa2-4ea3-a06f-5769d877540e +# ╟─25ef12bc-d294-11ef-1557-d98ba829a804 +# ╟─fe66a986-2f55-4417-a71d-b3b99f6369cc +# ╟─25ef2806-d294-11ef-3cb6-0f3e76b9177e +# ╟─4ceede48-a4d5-446b-bb34-26cec4af357a +# ╟─d29ccc9e-d4a6-46ae-b907-2bc68c8d99bc +# ╟─7e7cab21-09ab-4d06-9716-ab7864b229ab +# ╟─aeee1072-5173-4eae-8027-3fbf2e338d95 +# ╟─f37ac438-cd56-4a09-bc8e-a75469955a2f +# ╟─93083660-6a49-4147-b00c-d62a4453f222 +# ╟─d1bbdc6a-e5ff-4cd6-9175-860b5ec04f3c +# ╟─25ef6ece-d294-11ef-270a-999c8d457b24 +# ╟─25ef7f54-d294-11ef-3f05-0d85fe6e7a17 +# ╟─25efa2fe-d294-11ef-172f-9bb09277f59e +# ╟─25efbe42-d294-11ef-3e4e-cfea366757da +# ╟─25efd6b6-d294-11ef-3b21-6363ef531eb5 +# ╟─25f02ac6-d294-11ef-26c4-f142b8ac4b5f +# ╟─25f0adde-d294-11ef-353e-4b4773df9ff5 +# ╟─22121f20-6b90-4782-8bed-25486cc23ae7 +# ╟─56cae988-2f51-4618-8676-f46fa2924ea3 +# ╟─66351c02-1921-44dc-b461-84a536c40fd5 +# ╟─e3173267-bd90-47df-9d7f-bd9fd3f688ac +# ╟─25f12528-d294-11ef-0c65-97c61935e9c2 +# ╟─25f14226-d294-11ef-369f-e545d5fe2700 +# ╟─25f14f82-d294-11ef-02fb-2dc632b8f118 +# ╟─25f15e0a-d294-11ef-3737-79a68c9b3c61 +# ╟─22f4972e-0f6d-49a1-bd1f-10569b77a852 +# ╟─25f19ed8-d294-11ef-3298-efa16dda1dde +# ╟─25f1390c-d294-11ef-364d-17e4c93b9a57 +# ╟─bda07a2e-3769-4ffe-9bc5-2b8a515247f6 +# ╟─25f1ab08-d294-11ef-32ed-493792e121b7 +# ╟─25f1b404-d294-11ef-1c3a-a5a8142bb202 +# ╟─25f1c2a0-d294-11ef-009c-69b64e87e5fb +# ╟─3422dd29-6da9-4e0f-a4ab-646f223c2244 +# ╟─8b0bb225-bdc1-45ec-bd34-68d674d6f08d +# ╟─ae2b23f0-853e-4237-aab2-81c961f52cf6 +# ╟─e4cc517b-d3b5-4517-a28b-efb8aba24496 +# ╟─33b859f2-9ea8-4f8b-b0f8-08a19c6a96fc +# ╟─9704ee6a-e233-49f1-8c66-d81543927342 +# ╟─4ab4bcca-da6e-4137-858d-257c04388277 +# ╟─38b4854f-be02-4696-802f-2106481e3aea +# ╟─7932fff4-0568-49de-b34c-711e51487ae3 +# ╟─25f3bef2-d294-11ef-1438-e9f7e469336f +# ╟─aaf764da-cf1b-4bc7-83ea-6d25a80ca3ab +# ╟─75076ca1-7226-4229-8e70-06cc586507c3 +# ╟─69706576-0333-43bf-8523-e7838f373529 +# ╟─98ef7093-f8ed-4a44-a153-0a64ab483f65 +# ╠═fce5d561-ea76-4bd8-9cce-6f707f72fc60 +# ╟─0045e569-dc3c-4998-86da-9d96f599c599 +# ╟─25f365e2-d294-11ef-300e-9914333b1233 +# ╟─3b24b142-2239-4951-9177-ff87b5da4b68 +# ╟─ff31d8c1-db35-4c85-a609-67fc40e9e78d +# ╟─1f2bfcf4-fef4-4612-8683-d5c86a326eef +# ╟─25f3ff84-d294-11ef-0031-63b23d23324d +# ╟─5d91a2ae-975c-4913-b8ff-3df043cb1f03 +# ╟─25f41118-d294-11ef-13a8-3fa6587c1bf3 +# ╟─25f19230-d294-11ef-2dfd-6d4927e86f57 +# ╟─173e545a-9125-4dc4-8df4-c3aa84a4b88a +# ╟─557c4545-2208-43c9-9302-991e78202734 +# ╟─a00c545c-2274-4086-94ca-319d1436fa26 +# ╟─b94644f8-725d-49bf-9641-3dad8b647f45 +# ╟─9554ed0b-69dd-443c-9538-03a4117eeb78 +# ╟─6eee35ee-fd55-498f-9441-f18c2508de19 +# ╠═e379cc2a-43f8-432f-84fc-a88fd4f3ad0a +# ╠═a759653c-0da4-40b7-9e9e-1e3d2e4df4ea +# ╠═ad196ae6-c65e-4aaa-b0cc-bd72daa41952 +# ╠═616e84d7-063d-4d9d-99e4-56aecf3c7ee4 +# ╠═fcec3c3a-8b0b-4dfd-b010-66abbf330069 +# ╟─a65ca01a-0e9a-42cb-b1d7-648102a77eb5 +# ╟─b8790891-1546-48e0-9f96-e09eade31c12 +# ╟─b48f8800-473d-48e4-ab78-eb07653db7a5 +# ╠═1bfac9c5-e5cf-4a70-b077-11bb00cb1482 +# ╠═fd908bf5-71a1-4ae8-8416-cc1fdf084dcb +# ╟─cf829697-6283-4d2f-b0dd-bbfbd689a145 +# ╠═5e4bb719-ea9b-4a30-8800-5d753f405fd1 +# ╠═6b56ec96-4b9d-4281-bd63-061df324867f +# ╠═f8bb4fcd-9b20-44e5-8e22-e792e74b69df +# ╠═b5a19a34-b210-41ec-853d-c5df13ae17ce +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/archive/Dynamic Models.jl b/mlss/archive/Dynamic Models.jl new file mode 100644 index 00000000..eb3b897d --- /dev/null +++ b/mlss/archive/Dynamic Models.jl @@ -0,0 +1,3591 @@ +### A Pluto.jl notebook ### +# v0.20.19 + +#> [frontmatter] +#> image = "https://github.com/bmlip/course/blob/v2/assets/figures/Faragher-2012-cart-1.png?raw=true" +#> description = "Introduction to dynamic latent variable models, including HMMs and Kalman filters." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ e66b2193-87c8-4645-bfcc-643ee006383a +using BmlipTeachingTools + +# ╔═╡ f2a42c4d-9607-4f50-bbda-9a9a4942faab +using RxInfer, LinearAlgebra + +# ╔═╡ 60201d93-64e8-42ce-85ab-8eb661223427 +using Plots, Distributions, Images, LaTeXStrings, StatsPlots + +# ╔═╡ 27289f68-d294-11ef-37d6-e399ed72a1d0 +title("Dynamic Models") + +# ╔═╡ 6107b57e-cda2-46fb-b6f8-bd0e3787516d +PlutoUI.TableOfContents() + +# ╔═╡ 2728adf0-d294-11ef-2467-f176bb42fb8b +md""" +## Preliminaries + +##### Goal + + * Introduction to dynamic (=temporal) Latent Variable Models, including the Hidden Markov Model and Kalman filter. + +##### Materials + + * Mandatory + + * These lecture notes + * Optional + + * [Bishop PRML](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf) (2006), pp.605-615 on Hidden Markov Models + * [Bishop PRML](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf) (2006), pp.635-641 on Kalman filters + * Faragher (2012), [Understanding the Basis of the Kalman Filter](https://github.com/bmlip/course/blob/main/assets/files/Faragher-2012-Understanding-the-Basis-of-the-Kalman-Filter.pdf) + * Minka (1999), [From Hidden Markov Models to Linear Dynamical Systems](https://github.com/bmlip/course/blob/main/assets/files/Minka-1999-from-HMM-to-LDS.pdf) + +""" + +# ╔═╡ 50c601c9-ec68-4155-932c-190bced1ac9a +challenge_statement("Tracking of Cart Position"; color="red", header_level=1) + +# ╔═╡ 2728b7c8-d294-11ef-06e6-5329a76c16be +md""" + +##### Problem + +We consider a one-dimensional cart position tracking problem, see [Faragher (2012)](https://github.com/bmlip/course/blob/main/assets/files/Faragher-2012-Understanding-the-Basis-of-the-Kalman-Filter.pdf). + +The equations of motion are given by + +```math +\begin{align*} +\begin{bmatrix} z_t \\ \dot{z_t}\end{bmatrix} &= \begin{bmatrix} 1 & \Delta t \\ 0 & 1\end{bmatrix} \begin{bmatrix} z_{t-1} \\ \dot z_{t-1}\end{bmatrix} + \begin{bmatrix} (\Delta t)^2/2 \\ \Delta t\end{bmatrix} u_t + \epsilon^{(z)}_t \,, \qquad \epsilon^{(z)}_t\sim \mathcal{N}(0,\Sigma_z) \\ +x_t &= \begin{bmatrix} z_t \\ \dot{z_t}\end{bmatrix} + \epsilon^{(x)}_t\,, \qquad \epsilon^{(x)}_t\sim \mathcal{N}(0,\Sigma_x) +\end{align*} +``` + +The hidden states are the position ``z_t`` and velocity ``\dot z_t`` of the cart. We can apply an external acceleration/breaking force ``u_t``. (Noisy) observations are represented by ``x_t``. + +![](https://github.com/bmlip/course/blob/v2/assets/figures/Faragher-2012-cart-1.png?raw=true) + +Task: Infer the position ``z_t`` after 10 time steps, i.e., infer ``p(z_{10}|x_{1:10})``. + + +""" + +# ╔═╡ 91fb40f2-8c2d-4e0e-8a8a-8d823ed869dc +md""" +Move the time step slider below to show the real cart position ``z_t`` (the vertical dashed line), and a (probabilistic) prediction for the measured position ``x_t``. +""" + +# ╔═╡ 6b7f6d3b-8ad6-434a-babe-2597e86299fa +md""" + + +##### Solution + +See later in this lecture. + + +""" + +# ╔═╡ fc919736-d9e3-4ca0-a53c-5fac18539ab5 +md""" +# Common Models for Ordered Sequences +""" + +# ╔═╡ 2728c344-d294-11ef-1c5e-8d601b7ac3f9 +md""" + + +In this lecture, we consider models where the sequence order of observations matters. + +We will use the notation ``x_t^T`` to denote the **ordered sequence** ``(x_t,x_{t+1},\ldots,x_T)`` and drop the subscript if ``t=1``, so ``x^T = x_1^T = \left(x_1,x_2,\ldots,x_T\right)``. + +""" + +# ╔═╡ 2728d136-d294-11ef-27bc-6de51ace159c +md""" + +## Autoregressive Model + +Assume that we wish to develop a generative model ``p( x^T )`` for the ordered time series ``x^T = \left(x_1,x_2,\ldots,x_T\right)``. + + +We cannot use the IID assumption ``p( x^T ) = \prod_t p(x_t )`` for a time series, since consecutive observations may have statistical dependencies. In general, we can *always* use the **chain rule** (a.k.a. **the general product rule**) + +```math +\begin{align*} +p(x^T) &= p(x_T|x^{T-1}) \,p(x^{T-1}) \\ + &= p(x_T|x^{T-1}) \,p(x_{T-1}|x^{T-2}) \cdots p(x_2|x_1)\,p(x_1) \\ + &= p(x_1)\prod_{t=2}^T p(x_t\,|\,x^{t-1}) +\end{align*} +``` + +which is true for any model ``p(x^T)``. + +In practice, we often wish to limit the depth of dependencies on past observations. A widely used approach is the ``K``-th order linear **Auto-Regressive** (AR) model, which restricts the dependency of ``x_t`` to the previous ``K`` samples. It is defined as + +```math +p(x_t \mid x^{t-1}) = \mathcal{N}\left(x_t \,\middle|\, \sum_{k=1}^K a_k x_{t-k},\, \sigma^2 \right), +``` + +where ``a_1, \ldots, a_K`` are the **autoregressive coefficients**, and ``\sigma^2`` is the noise variance. This model captures temporal structure by modeling each observation as a linear function of the preceding ``K`` values, plus Gaussian noise. + + +""" + +# ╔═╡ 73104616-8cb4-4665-b09b-1c771ecdf372 +keyconcept("", +"Dynamical systems do not obey the sample-by-sample independence assumption, but still can be specified, and state and parameter estimation equations can be solved by similar tools as for static models. +") + +# ╔═╡ 2728dece-d294-11ef-2dda-af89555d838f +md""" +## State-space Models + +A limitation of AR models is that they need a lot of parameters in order to create a flexible model. E.g., if ``x_t \in \mathbb{R}^M`` is an ``M``-dimensional time series, then the ``K``-th order AR model for ``x_t`` will have ``KM^2`` parameters. + +""" + +# ╔═╡ 2728e5c2-d294-11ef-1788-9b3699bb4ccd +md""" +Similar to our approach in Gaussian Mixture Models, we can introduce *additional structure* into temporal dependencies by incorporating latent (unobserved) variables ``z^{T} \triangleq (z_1, z_2, \dots, z_T)``, where each observation ``x_t`` is associated with a corresponding latent variable ``z_t``. + +In the context of dynamic systems, such observation-specific latent variables ``z_t`` are commonly referred to as **state variables**. + +A **state-space model** (SSM) is a probabilistic model used to describe time-evolving systems with latent (unobserved) state variables that generate observable data. It’s a general framework for modeling dynamical systems, widely used in signal processing, control theory, time series analysis, and machine learning. + +A state space model is defined by + +```math +\begin{align} + p(x^T,z^T) &= \underbrace{p(z_1)}_{\text{initial state}} \prod_{t=2}^T \underbrace{p(z_t\,|\,z_{t-1})}_{\text{state transitions}}\,\prod_{t=1}^T \underbrace{p(x_t\,|\,z_t)}_{\text{observations}} +\end{align} +``` + +The condition ``p(z_t\,|\,z^{t-1}) = p(z_t\,|\,z_{t-1})`` (``z_t`` only depends on the previous state ``z_{t-1}``) is called a ``1``-st order Markov condition. + + +""" + +# ╔═╡ 2729087c-d294-11ef-3f71-51112552f7b9 +md""" +The Forney-style factor graph for a state-space model looks as follows: + +""" + +# ╔═╡ 5d9d2972-0507-47a1-a726-26bb129f62f9 +@htl """ + + + +""" + +# ╔═╡ 63f422ca-ba15-41ad-b36b-7a6aa4cc5e2a +html""" + +""" + +# ╔═╡ 27290f78-d294-11ef-2ac4-b179be83b812 +md""" +## Hidden Markov Models + +A **Hidden Markov Model** (HMM) is a specific state-space model with *discrete-valued* state variables ``z_t``. + +Typically, ``z_t = (z_{t1},z_{t2},\ldots,z_{tK})`` is a ``K``-dimensional one-hot coded latent "class indicator" vector with transition probabilities ``a_{jk} \triangleq p(z_{tk}=1\,|\,z_{t-1,j}=1)``, or equivalently, + +```math +p(z_t|z_{t-1}) = \prod_{k=1}^K \prod_{j=1}^K a_{jk}^{z_{t-1,j}\cdot z_{tk}} \,, \tag{state transition} +``` + +which is usually accompanied by an initial state distribution ``p(z_{1k}=1) = \pi_k``. + +While the classical HMM assumes discrete observations, the general framework allows for arbitrary probabilistic observation models ``p(x_t | z_t)``. This flexibility enables coupling the discrete hidden state dynamics with rich observation models, including Gaussian, exponential family, or even neural network-based likelihoods. + + +""" + +# ╔═╡ 27295340-d294-11ef-3a56-131df0415315 +md""" +## Linear Dynamical Systems + +Another well-known state-space model with *continuous* state variables ``z_t \in \mathbb{R}`` is the **(Linear) Gaussian Dynamical System** (LGDS), which is defined as + +```math +\begin{align*} +p(z_t\,|\,z_{t-1}) &= \mathcal{N}\left(z_t \,|\, A z_{t-1},\,\Sigma_z\right) \tag{state transition}\\ +p(x_t\,|\,z_t) &= \mathcal{N}\left(x_t\,|\, C z_t,\,\Sigma_x\right) \tag{data generation}\\ +p(z_1) &= \mathcal{N}\left(z_1\,|\, \mu_1,\,\Sigma_1\right) \tag{initial state} +\end{align*} +``` + + + +""" + +# ╔═╡ 27296132-d294-11ef-0d39-9da05d6c20b7 +md""" +Note that the joint distribution over all states and observations ``\{(x_1,z_1),\ldots,(x_t,z_t)\}`` is a (large-dimensional) Gaussian distribution. This means that, in principle, every inference problem on the LGDS model also leads to a Gaussian distribution. + +""" + +# ╔═╡ 6bcabd28-f72b-47d9-b846-b1528f3758bb +keyconcept("", +md""" +A very common and flexible probabilistic dynamical model is the **state-space model**, +```math +\begin{align} + p(x^T,z^T) &= \underbrace{p(z_1)}_{\text{initial state}} \prod_{t=2}^T \underbrace{p(z_t\,|\,z_{t-1})}_{\text{state transitions}}\,\prod_{t=1}^T \underbrace{p(x_t\,|\,z_t)}_{\text{observations}}\,, +\end{align} +``` +with observations ``x_t`` and latent states ``z_t``. +""") + +# ╔═╡ 27298004-d294-11ef-06db-490237bf9408 +md""" +## Message Passing-based Inference in State-space models + +HMMs and LGDSs, including their many extensions, serve as fundamental building blocks in diverse information processing domains, ranging from speech and language modeling, robotic control, and autonomous navigation, to bioinformatics tasks such as DNA sequence analysis. + +Inference in probabilistic dynamic systems with temporal dependencies can quickly become cumbersome and error-prone when approached manually. A practical and scalable solution is to represent the generative model as a factor graph and perform automated message passing to infer the posterior distribution over the hidden variables. + +Here are some examples of message passing-based inference in dynamic models. + +##### Filtering + +Filtering (also known as state estimation) refers to the estimation of the latent state at time step ``t``, based on all observations up to and including time ``t``. The FFG below shows the needed messages to compute ``p(z_t|x_{1:t})``. + + +""" + +# ╔═╡ d51bd37b-a12f-426a-87ca-6d4e6701fdb4 +@htl """ + + + +""" + +# ╔═╡ 030d6de1-1f63-47d3-bea0-abe3ddf24be4 +md""" + + +##### Smoothing + +In contrast to filtering, which uses only past and current observations, smoothing aims to estimate a latent state by incorporating information from both past and future observations. This is achieved by passing backward messages through the factor graph, typically from later time steps toward earlier ones. + + +""" + +# ╔═╡ 99ef8d0f-679a-43d1-9bbb-91bd8ad725ec +@htl """ + + + +""" + +# ╔═╡ 69446a18-bb7d-45e2-b480-dcaa76fa66c0 +md""" +##### Prediction + +Prediction involves the estimation of a future state or observation based only on past (and possibly current) observations, without incorporating any future information. + +""" + +# ╔═╡ 620a77a8-50c4-4005-a41b-6a6221391434 +@htl """ + + + +""" + +# ╔═╡ 2f439fb0-012c-4318-bb8b-90c37d2ff43c +md""" +# Kalman Filtering +""" + +# ╔═╡ a24760e2-055a-4902-a78e-65aa59b80f68 +md""" + + +In the filtering setting, the posterior distribution ``p(z_t | x^t)`` is typically computed recursively, using the previous posterior ``p(z_{t-1} | x^{t-1})`` as a prior and incorporating the new observation ``x_t`` in a likelihood function. + +Generally, this recursive inference update can be efficiently processed by message passing on an FFG. For instance, the posterior ``p(z_2 | x_{1:2})`` can be computed from the previously inferred ``p(z_1 | x_1)`` (represented by "prior" message ``4``) and by incorporating the new observation ``x_2``, which is processed through messages ``5`` through ``8``. + +Technically, the solution to the recursive estimation (inference) of the hidden state ``z_t`` based on past observations in an LGDS is called a [**Kalman filter**](https://en.wikipedia.org/wiki/Kalman_filter). + +In a toolbox like RxInfer, Kalman filtering can be performed automatically and efficiently. For comparison, we manually derive the Kalman filter below. + +""" + +# ╔═╡ 27298d26-d294-11ef-080e-dbe7270d9191 +md""" +## An Analytical Derivation of the $(HTML("Kalman Filter")) + +""" + +# ╔═╡ 27299a12-d294-11ef-1026-ddb5ffc81543 +md""" + +##### Problem + + +Consider the following model specification (a scalar linear Gaussian dynamical system): + +```math +\begin{align} + p(z_t\,|\,z_{t-1}) &= \mathcal{N}(z_t\,|\,a z_{t-1},\sigma_z^2) \tag{state transition} \\ + p(x_t\,|\,z_t) &= \mathcal{N}(x_t\,|\,c z_t,\sigma_x^2) \tag{observation} +\end{align} +``` + +We are interested in computing ``p(z_t\,|\,x^t)`` from a given (previous) estimate + +```math +\begin{align} +p(z_{t-1}\,|\,x^{t-1}) = \mathcal{N}(z_{t-1} \,|\, \mu_{t-1}, \sigma_{t-1}^2) +\end{align} +``` +and a new observation ``x_t``. +""" + +# ╔═╡ 2729b6dc-d294-11ef-390f-6fa53c0b04f1 +md""" + +##### Solution + +Let's follow Bayes rule, + + +```math +\begin{align} +\overbrace{p(z_t\,|\,x^t)}^{\text{posterior}}& \cdot \overbrace{p(x_t\,|\,x^{t-1})}^{\text{evidence}} = p(x_t\,|\,z_t) \cdot p(z_t\,|\,x^{t-1}) \\ + &= p(x_t\,|\,z_t) \, \int p(z_t,z_{t-1}\,|\,x^{t-1}) \mathrm{d}z_{t-1} \\ + &= \underbrace{p(x_t\,|\,z_t)}_{\text{likelihood}} \, \int \underbrace{p(z_t\,|\,z_{t-1})}_{\text{state transition}} \, \underbrace{p(z_{t-1}\,|\,x^{t-1})}_{\text{prior}} \mathrm{d}z_{t-1} \\ + &= \mathcal{N}(x_t|c z_t, \sigma_x^2) \, \int \mathcal{N}(z_t\,|\,a z_{t-1},\sigma_z^2) \, \mathcal{N}(z_{t-1} \,|\, \mu_{t-1}, \sigma_{t-1}^2) \mathrm{d}z_{t-1} \quad \text{(KF-1)} + \end{align} +``` +This result (KF-1) comprises only Gaussians and can be further worked out to closed-form expressions for the posterior and evidence, resulting in + +```math +\begin{align} +p(z_{t}\,|\,x^{t}) &= \mathcal{N}(z_{t} \,|\, \mu_{t}, \sigma_{t}^2) \tag{posterior}\\ + p(x_t|x^{t-1}) &= \mathcal{N}\left(x_t \,|\, ca \mu_{t-1}, \sigma_x^2 + c^2(\sigma_z^2+a^2\sigma_{t-1}^2) \right) \tag{evidence} +\end{align} +``` + +where ``\mu_{t}`` and ``\sigma_{t}^2`` in the posterior Gaussian are recursively computed from ``\mu_{t-1}``, ``\sigma_{t-1}^2`` and new observation ``x_t`` by +```math +\begin{align*} + \rho_t^2 &= a^2 \sigma_{t-1}^2 + \sigma_z^2 \quad &&\text{(predicted variance)} \tag{KF-2a}\\ + K_t &= \frac{c \rho_t^2}{c^2 \rho_t^2 + \sigma_x^2} \quad &&\text{(Kalman gain)} \tag{KF-2b} \\ + \mu_t &= a \mu_{t-1} + K_t \cdot \left( x_t - c a \mu_{t-1}\right) \quad &&\text{(posterior mean)} \tag{KF-2c} \\ + \sigma_t^2 &= \left( 1 - c\cdot K_t \right) \rho_t^2 \quad &&\text{(posterior variance)} \tag{KF-2d} +\end{align*} +``` + +These last four equations (KF-2, the "Kalman filter update equations") correspond to messages 5–8 in the filtering FFG presented above. + +""" + +# ╔═╡ 2729c4ba-d294-11ef-1ccc-df1f4ef5f3d4 +Foldable("Proof of KF-2", +md""" +In the following, we often run into Gaussians of the form ``\mathcal{N}(x\,|\,cz,\sigma^2)`` that we need to rewrite as an argument of ``z``. We will use the following "mean-transformation" identity: + +```math +\mathcal{N}(x\,|\,cz,\sigma^2) = \frac{1}{c}\mathcal{N}\left(z \,\middle|\,\frac{x}{c},\left(\frac{\sigma}{c}\right)^2\right)\, \tag{1}. +``` + +Let's now further work out the Kalman filter, starting from Eq. KF-1: + +```math +\begin{align*} + \underbrace{\mathcal{N}(x_t|c z_t, \sigma_x^2)}_{\text{likelihood}} &\, \int \underbrace{\mathcal{N}(z_t\,|\,a z_{t-1},\sigma_z^2)}_{\substack{\text{state transition,} \\ \text{use (1)}} } \, \underbrace{\mathcal{N}(z_{t-1} \,|\, \mu_{t-1}, \sigma_{t-1}^2) }_{\text{prior}} \mathrm{d}z_{t-1} = \\ +&= \mathcal{N}(x_t|c z_t, \sigma_x^2) \, \int \frac{1}{a}\underbrace{\mathcal{N}\left(z_{t-1}\bigm| \frac{z_t}{a},\left(\frac{\sigma_z}{a}\right)^2 \right) \mathcal{N}(z_{t-1} \,|\, \mu_{t-1}, \sigma_{t-1}^2)}_{\text{use Gaussian multiplication formula SRG-6}} \mathrm{d}z_{t-1} \\ +&= \frac{1}{a} \mathcal{N}(x_t|c z_t, \sigma_x^2) \, \int \underbrace{\mathcal{N}\left(\mu_{t-1}\bigm| \frac{z_t}{a},\left(\frac{\sigma_z}{a}\right)^2 + \sigma_{t-1}^2 \right)}_{\text{not a function of }z_{t-1}} \underbrace{\mathcal{N}(z_{t-1} \,|\, \cdot, \cdot)}_{\text{integrates to }1} \mathrm{d}z_{t-1} \\ +&= \frac{1}{a} \underbrace{\mathcal{N}(x_t|c z_t, \sigma_x^2)}_{\text{use (1))}} \, \underbrace{\mathcal{N}\left(\mu_{t-1}\bigm| \frac{z_t}{a},\left(\frac{\sigma_z}{a}\right)^2 + \sigma_{t-1}^2 \right)}_{\text{use (1)}} \\ +&= \frac{1}{c} \underbrace{\mathcal{N}\left(z_t \bigm| \frac{x_t}{c}, \left( \frac{\sigma_x}{c}\right)^2 \right) \mathcal{N}\left(z_t\, \bigm|\,a \mu_{t-1},\sigma_z^2 + \left(a \sigma_{t-1}\right)^2 \right)}_{\text{use SRG-6 again}} \\ +&= \underbrace{\frac{1}{c} \mathcal{N}\left( \frac{x_t}{c} \bigm| a \mu_{t-1}, \left( \frac{\sigma_x}{c}\right)^2+ \sigma_z^2 + \left(a \sigma_{t-1}\right)^2\right)}_{\text{use (1)}} \, \mathcal{N}\left( z_t \,|\, \mu_t, \sigma_t^2\right)\\ + &= \underbrace{\mathcal{N}\left(x_t \,|\, ca \mu_{t-1}, \sigma_x^2 + c^2(\sigma_z^2+a^2\sigma_{t-1}^2) \right)}_{\text{evidence } p(x_t|x^{t-1})} \cdot \underbrace{\mathcal{N}\left( z_t \,|\, \mu_t, \sigma_t^2\right)}_{\text{posterior }p(z_t|x^t) } +\end{align*} +``` + +where the posterior mean ``\mu_t`` and posterior variance ``\sigma^2_t`` are given by the Kalman update equations (KF-2). +""") + + + + +# ╔═╡ 2729ec24-d294-11ef-2547-cbb5238bb18d +md""" + +Note that the above derivation includes updating the "instant" evidence + +```math +p(x_t|x^{t-1}) = \mathcal{N}\left(x_t \,|\, ca \mu_{t-1}, \sigma_x^2 + c^2(\sigma_z^2+a^2\sigma_{t-1}^2) \right) \,. +``` + +For an observed sequence ``x^t``, the evidence ``p(x_t|x^{t-1})`` is a scalar number that scores how well the model predicts ``x_t``, based on past observations ``x^{t-1}``. + +!!! info "Exam Guide" + The above manual derivation of the Kalman filter is too long and error-prone to be asked at an exam. You should be able to follow the derivation in detail, but you will not be requested to reproduce the full derivation without some guidance. The complexity of the derivation underlines why inference should be automated by a toolbox (like RxInfer). + +""" + +# ╔═╡ 272a00a6-d294-11ef-18ba-a3700f78b13f +md""" +## Multi-dimensional Kalman Filtering + +The Kalman filter equations can also be derived for multidimensional state-space models. In particular, for the model + +```math +\begin{align*} +z_t &= A z_{t-1} + \epsilon^{(z)}_t, \quad && \epsilon^{(z)}_t \sim \mathcal{N}(0,\Gamma) \\ +x_t &= C z_t + \epsilon^{(x)}_t \quad && \epsilon^{(x)}_t \sim \mathcal{N}(0,\Sigma) \,, +\end{align*} +``` + +the Kalman filter update equations for the posterior ``p(z_t |x^t) = \mathcal{N}(z_t | \mu_t, V_t )`` are given by (see Bishop, pg.639) + +```math +\begin{align*} +P_t &= A V_{t-1} A^T + \Gamma \tag{predicted variance}\\ +K_t &= P_t C^T \cdot \left(C P_t C^T + \Sigma \right)^{-1} \tag{Kalman gain} \\ +\mu_t &= A \mu_{t-1} + K_t\cdot\left(x_t - C A \mu_{t-1} \right) \tag{posterior state mean}\\ +V_t &= \left(I-K_t C \right) P_{t} \tag{posterior state variance} +\end{align*} +``` + +""" + +# ╔═╡ e44c6138-7f59-48f3-8f4d-7c5db8e1c016 +keyconcept("", +md""" +Two of the more famous and powerful models with latent states include the hidden Markov model (with discrete states) and the Linear Gaussian Dynamical system (with continuous states). The LDGS model is +```math +\begin{align*} +z_t &= A z_{t-1} + \epsilon^{(z)}_t, \quad && \epsilon^{(z)}_t \sim \mathcal{N}(0,\Gamma) \\ +x_t &= C z_t + \epsilon^{(x)}_t \quad && \epsilon^{(x)}_t \sim \mathcal{N}(0,\Sigma) \, +\end{align*} +``` +""") + +# ╔═╡ bbaa44b9-9bac-4fb8-8014-fbf400a93039 +challenge_solution("Tracking of Cart Position", color="green", header_level=1) + +# ╔═╡ 599e21c8-1141-4192-9dd7-46b83314a1ef +md""" +Let's use the Kalman filtering equations to solve the cart position tracking challenge. +""" + +# ╔═╡ 272a0d3a-d294-11ef-2537-39a6e410e56b +md""" + +## Inference by Explicit Kalman Filtering + +We can now solve the cart tracking problem of the introductory example by executing the Kalman filter equations KF-2. +""" + +# ╔═╡ f2e5dd92-b4bf-495a-8c11-2f34f2667041 +md""" +Center the graph around cart position? $(@bind closed_form_rolling CheckBox(default=false)) +""" + +# ╔═╡ ec3b781d-8b44-4bf4-9562-c5362eeb8913 +md""" +#### Model Specification +""" + +# ╔═╡ e3056eeb-777a-4323-9d2e-f376cae2e1ca +begin + n_steps = 20; + Δt = 1.0; + + z_start = [10.0; 0.0]; + u = 0.2 * ones(n_steps) # constant force + A = [1.0 Δt; + 0.0 1.0] + b = [0.5*Δt^2; Δt] + Σz = collect(Diagonal([0.2*Δt; 0.1*Δt])) + Σx = collect(Diagonal([1.0; 2.0])) +end; + +# ╔═╡ 49fd6d97-8ef1-49cd-8dcb-dafddb14814c +@bind intro_i Slider(2:n_steps; show_value=true) + +# ╔═╡ 83587586-8a88-4bbb-b2bf-1ca9a8cf6339 +md""" +Select a time step: $(@bind closed_form_i Slider(3:n_steps; show_value=true)) +""" + +# ╔═╡ 130edb3e-f5f9-40d2-970d-d0fc822fd82a +md""" +#### Noisy observations + +The measurements are organized per time step, with each element comprising a two-dimensional observation of `[position, velocity]`. +""" + +# ╔═╡ 272a4b2e-d294-11ef-2762-47a3479186ad +md""" +## Inference by Message Passing + +Let's now solve the cart tracking problem by sum-product message passing in a factor graph. All we have to do is create factor nodes for the state-transition model ``p(z_t|z_{t-1})`` and the observation model ``p(x_t|z_t)``. Then we let [RxInfer](https://rxinfer.com) execute the message passing schedule. + +#### Model Specification in RxInfer + +We only need to specify a single time step (and the initial values): +""" + +# ╔═╡ 6e8e7cea-7f97-418e-9453-c25a5896bc71 +@model function cart_tracking_filter(x, A, B, Σz, Σx, z_prev_m_0, z_prev_v_0, u) + + z_prev ~ MvNormalMeanCovariance(z_prev_m_0, z_prev_v_0) + + z ~ MvNormalMeanCovariance(A*z_prev + B*u, Σz) + x ~ MvNormalMeanCovariance(z, Σx) + + return z +end + +# ╔═╡ 557b0052-b1a4-489e-be53-2327033954f2 +md""" +Select a time step: $(@bind rxinfer_i Slider(1:n_steps; show_value=true)) +""" + +# ╔═╡ b7d0c2e7-418b-417d-992a-c93ae3598f9e +md""" +Center the graph around cart position? $(@bind rxinfer_rolling CheckBox(default=false)) +""" + +# ╔═╡ 272ab9b2-d294-11ef-0510-c3b68d2f1099 +md""" +Note that both the analytical Kalman filtering solution and the message passing solution lead to the same results. The advantage of message passing-based inference with RxInfer is that we did not need to derive any inference equations. RxInfer took care of all that. + +""" + +# ╔═╡ d6d3b368-8be5-4201-989f-44617d0cb34e +md""" + +#### Inference by RxInfer + +""" + +# ╔═╡ 331415dc-70fd-4b58-8536-8ed47b071e25 +# By default, RxInfer applies smoothing when it receives a static dataset. Since we want to do filtering, we will enable the option `autoupdates` when doing inference . +autoupdates = @autoupdates begin + z_prev_m_0, z_prev_v_0 = mean_cov(q(z)) +end + +# ╔═╡ 272afaec-d294-11ef-3953-5f868ec73cb8 +keyconcept("", +md""" +Generally, we will want to automate inference processes in dynamic models. We showed how Kalman filtering *emerged naturally* by automated message passing. + + +""") + + +# ╔═╡ 95ca53f8-d60a-4262-911b-b1010e0c7752 +md""" +# Summary +""" + +# ╔═╡ 27a6880c-b007-4d39-9e21-e7e24fc9d059 +keyconceptsummary() + +# ╔═╡ 7505d957-0c4d-41ba-a662-45ba4dfe4d05 +exercises(header_level=1) + +# ╔═╡ 3a188b49-919d-4168-b789-ce6a5cebf509 +md""" + +#### Markov Blankets (***) + +Given the Markov property + +```math +p(x_n|x_{n-1},x_{n-2},\ldots,x_1) = p(x_n|x_{n-1}) \tag{A1} +``` + +Prove that, for any ``n``, + +```math +\begin{align} +p(x_n,&x_{n-1},\ldots,x_{k+1},x_{k-1},\ldots,x_1|x_k) \\ +&= p(x_n,x_{n-1},\ldots,x_{k+1}|x_k) \cdot p(x_{k-1},x_{k-2},\ldots,x_1|x_k) \tag{A2} +\end{align} +``` + +In statistics and machine learning, the **Markov blanket** of a set of random variables ``S`` is the minimal set of other variables that renders ``S`` conditionally independent of all remaining variables in the system. Hence, if (A1) holds, the present state ``x_k`` serves as a Markov blanket for the future ``(x_n,x_{n-1},\ldots,x_{k+1})``, since conditioning on ``x_k`` makes the future independent of the past ``(x_{k-1},x_{k-2},\ldots,x_1)``. + +""" + +# ╔═╡ e8cab5ea-4906-4c64-b1bb-f33e267762a1 +hide_proof( +md""" +First, we rewrite (A2) as + + +```math +\begin{flalign} +p(&x_n,x_{n-1},\ldots,x_{k+1},x_{k-1},\ldots,x_1|x_k) \\ +&= \frac{p(x_n,x_{n-1},\ldots,x_1)}{p(x_k)} \\ +&= \frac{p(x_n,x_{n-1},\ldots,x_{k+1}|x_k,\ldots,x_1) \cdot p(x_k,x_{k-1},\ldots,x_1)}{p(x_k)} \\ +&= \frac{p(x_n,x_{n-1},\ldots,x_{k+1}|x_k,\ldots,x_1) \cdot p(x_{k-1},\ldots,x_1|x_k) p(x_k)}{p(x_k)} \\ +&= p(x_n,x_{n-1},\ldots,x_{k+1}|x_k,\ldots,x_1) \cdot p(x_{k-1},\ldots,x_1|x_k) \tag{A3} +\end{flalign} +``` + +If (A1) holds, then the first factor in (A3) can be simplified to + +```math +\begin{align} +p(&x_n,x_{n-1},\ldots,x_{k+1}|x_k,x_{k-1},\ldots,x_1) \\ +&= p(x_n|x_{n-1},\ldots,x_1) \cdot p(x_{n-1}|x_{n-2},\ldots,x_1) \cdots p(x_{k+1}|x_{k},\ldots,x_1) \\ +&= p(x_n|x_{n-1},\ldots,x_k) \cdot p(x_{n-1}|x_{n-2},\ldots,x_k) \cdots p(x_{k+1}|x_{k}) \\ +&= p(x_n,x_{n-1},\ldots,x_{k+1}|x_k) \tag{A4} +\end{align} +``` + +Substitution of (A4) into (A3) leads to A2. +""") + +# ╔═╡ d5d13c2e-3e8d-454e-b0d7-cb224aed063c +md""" +#### Rehearsal (*) + +- (a) What's the difference between a hidden Markov model and a linear Dynamical system? + +- (b) For the same number of state variables, which of these two models has a larger memory capacity, and why? + +- (c) What is the 1st-order Markov assumption? + +- (d) Derive the joint probability distribution ``p(x_{1:T},z_{0:T})`` (where ``x_t`` and ``z_t`` are observed and latent variables respectively) for the state-space model with transition and observation models ``p(z_t|z_{t-1})`` and ``p(x_t|z_t)``. + +- (e) What is a Hidden Markov Model (HMM)? + +- (f) What is a Linear Dynamical System (LDS)? + +- (g) What is a Kalman Filter? + +- (h) How does the Kalman Filter relate to the LDS? + +- (i) Explain the popularity of Kalman filtering and HMMs? + +- (j) How does a HMM relate to a GMM? + +""" + +# ╔═╡ 0c65804b-bd3f-40b7-9752-96f730dbdc96 +details("Click for answers", +md""" + +#### Rehearsal (*) + +- (a) What's the difference between a hidden Markov model and a linear Dynamical system? + +HMM has binary-valued (on-off) states, where the LDS has continuously valued states. + +- (b) For the same number of state variables, which of these two models has a larger memory capacity, and why? + +The latter holds more capacity because, eg, a 16-bit representation of a continuously-valued variable holds ``2^{16}`` different states. + +- (c) What is the 1st-order Markov assumption? + +An auto-regressive model is first-order Markov if + +```math +p(x_t|x_{t-1},x_{t-2},\ldots,x_1) = p(x_t|x_{t-1})\,. +``` + +- (d) Derive the joint probability distribution ``p(x_{1:T},z_{0:T})`` (where ``x_t`` and ``z_t`` are observed and latent variables respectively) for the state-space model with transition and observation models ``p(z_t|z_{t-1})`` and ``p(x_t|z_t)``. + +```math +p(x_{1:T},z_{0:T}) = p(z_0)\prod_{t=1}^Tp(z_t|z_{t-1}) \prod_{t=1}^T p(x_t|z_t) +``` + +- (e) What is a Hidden Markov Model (HMM)? + +An HMM is a state-space model where the latent variable ``z_t`` is discretely valued. I.o.w., the HMM has hidden clusters. + + +- (f) What is a Linear Dynamical System (LDS)? + +An LDS is a state-space model, but now the latent variable ``z_t`` is continuously valued. + +- (g) What is a Kalman Filter? + +A Kalman filter is a recursive solution to the inference problem ``p(z_t|x_t,x_{t-1},\dots,x_1)``, based on a state estimate at the previous time step ``p(z_{t-1}|x_{t-1},x_{t-2},\dots,x_1)`` and a new observation ``x_t``. Basically, it's a recursive filter that updates the optimal Bayesian estimate of the current state ``z_t`` based on all past observations ``x_t,x_{t-1},\dots,x_1``. + +- (h) How does the Kalman Filter relate to the LDS? + +The LDS describes a (generative) *model*. The Kalman filter does not describe a model, but rather describes an *inference process* on the LDS model. + +- (i) Explain the popularity of Kalman filtering and HMMs? + +The LDS and HMM models are both quite general and flexible generative probabilistic models for time series. There exist very efficient algorithms for executing the latent state inference tasks (Kalman filter for LDS, and there is a similar algorithm for the HMM). That makes these models flexible and practical. Hence, the popularity of these models. + + +- (j) How does an HMM relate to a GMM? +An HMM can be interpreted as a Gaussian-Mixture-model-over-time. + + +""") + +# ╔═╡ 272b07f8-d294-11ef-3bfe-bffd9e3623aa +md""" +# Optional Slides + +""" + +# ╔═╡ 272b17b6-d294-11ef-1e58-a75484ab56d9 +md""" +## Extensions of Generative Gaussian Models + +Using the methods of the previous lessons, it is possible to create your own new models based on stacking Gaussian and categorical distributions in new ways: + +![](https://github.com/bmlip/course/blob/v2/assets/figures/fig-generative-Gaussian-models.png?raw=true) + +""" + +# ╔═╡ f44e0303-dd28-48ad-9de2-7f7882f3923d +md""" +# Code +""" + +# ╔═╡ dab295ff-5a02-4e4f-8f46-b0842b6bf1ff +import RxInfer.ReactiveMP: messageout, getinterface, materialize! + +# ╔═╡ 07fe12dc-501c-407b-ab39-ba9a4845762c +import RxInfer.Rocket: getrecent + +# ╔═╡ ae8c57ce-b74d-4543-b25b-eee57ad2e415 +function plotCartPrediction( + ; + predictive::Union{Nothing,Normal}=nothing, + measurement::Union{Nothing,Normal}=nothing, + corrected::Union{Nothing,Normal}=nothing, + real::Union{Nothing,Float64}=nothing, + rolling::Bool=false, + kwargs... +) + result = plot( + ; + xlim=rolling ? (real - 4, real + 4) : (10,50), + ylim=(-.5, 1), + xlabel="Position", legend=:bottomright, + kwargs... + ) + + isnothing(predictive) || plot!(predictive; + label="Prediction "*L"p(z[n]|z[n-1],u[n])", fill=(0, .1), + ) + + isnothing(measurement) || plot!(measurement; + label="Noisy measurement "*L"p(z[n]|x[n])", fill=(0, .1), + ) + + isnothing(corrected) || plot!(corrected; + label="Corrected prediction "*L"p(z[n]|z[n-1],u[n],x[n])", fill=(0, .1), + ) + + isnothing(real) || vline!([real]; + label="Real cart position", color=:purple, style=:dash, + ) + return result +end + +# ╔═╡ 84018669-bff5-4d06-a8f1-df515910c4d9 +function generateNoisyMeasurements( z_start::Vector{Float64}, + u::Vector{Float64}, + A::Matrix{Float64}, + b::Vector{Float64}, + Σz::Matrix{Float64}, + Σx::Matrix{Float64}) + # Simulate linear state-space model + # z[t] = A*z[t-1] + b*u[t] + N(0,Σz) + # x[t] = N(z[t],Σx) + + # Return noisy observations [x[1],...,x[n]] + + n = length(u) + d = length(z_start) + + # Sanity checks + @assert(n>0, "u should contain at least one value") + @assert(d>0, "z_start has an invalid dimensionality") + @assert(size(A) == (d,d), "Transition matrix A does not have correct dimensions") + @assert(length(b) == d, "b does not have the correct dimensionality") + @assert(size(Σz) == (d,d), "Covariance matrix Σz does not have correct dimensions") + @assert(size(Σx) == (d,d), "Covariance matrix Σx does not have correct dimensions") + + result = Vector[] # result will be a list of n vectors of size d + z = copy(z_start) + + for i=1:n + # the new position is calculated from the old one, with process noise + z = rand(MvNormal(A*z + b*u[i], Σz)) + # we observe this position, with measurement noise + output = rand(MvNormal(z, Σx)) + push!(result, output) + end + + return accumulate(1:n; init=(z_start, z_start)) do (z, z_observed), i + z = rand(MvNormal(A*z + b*u[i], Σz)) + z_observed = rand(MvNormal(z, Σx)) + return z, z_observed + end + + return result +end + +# ╔═╡ 24f6c005-173d-4831-8c93-c54a9ba0334e +begin + gen_measurements_output = generateNoisyMeasurements(z_start, u, A, b, Σz, Σx); + xs_real = first.(gen_measurements_output) + xs_measurement = last.(gen_measurements_output) +end; + +# ╔═╡ 4940b72d-182d-47bb-a446-51ce42724beb +plotCartPrediction( + measurement=Normal(xs_measurement[intro_i][1], Σx[1,1]), + real=xs_real[intro_i][1], +) + +# ╔═╡ ad05de22-40db-413e-85bd-24e6ef448656 +let + local m_pred_z, V_pred_z # (these will be defined later) + + ## Kalman filter code + m_z = xs_measurement[1] # initial predictive mean + V_z = A * (1e8*Diagonal(I,2) * A') + Σz # initial predictive covariance + + for t = 2:closed_form_i + ## predict + m_pred_z = A * m_z + b * u[t] # predictive mean + V_pred_z = A * V_z * A' + Σz # predictive covariance + + ## update + gain = V_pred_z * inv(V_pred_z + Σx) # Kalman gain + m_z = m_pred_z + gain * (xs_measurement[t]-m_pred_z) # posterior mean update + V_z = (Diagonal(I,2)-gain)*V_pred_z # posterior covariance update + end + + ## Make the plot + plotCartPrediction( + predictive=Normal(m_pred_z[1], V_pred_z[1]), + corrected=Normal(m_z[1], V_z[1]), + measurement=Normal(xs_measurement[closed_form_i][1], Σx[1,1]), + real=xs_real[closed_form_i][1], + rolling=closed_form_rolling, + ) +end + +# ╔═╡ 2618d09b-4fd6-4cdc-9d80-45f7d0b262db +xs_measurement # see code in Appendix how measurements are generated + +# ╔═╡ 25b3697e-6171-402c-97a5-201ca6bbe3a7 +begin + z_prev_m_0 = xs_measurement[1] + z_prev_v_0 = A * (1e8*diageye(2) * A') + Σz + init = @initialization begin + q(z) = MvNormalMeanCovariance(z_prev_m_0, z_prev_v_0) + end +end; + +# ╔═╡ 32f7bc6a-cf3d-44f3-9603-8c4fe5c1a32d +engine = infer( + model=cart_tracking_filter(A=A, B=b, Σz=Σz, Σx=Σx, u=u[1]), + data=(x = xs_measurement,), + autoupdates = autoupdates, + initialization = init, + keephistory = n_steps, + free_energy = true, + autostart = true, +) + +# ╔═╡ 272aaaf6-d294-11ef-0162-c76ba8ba7232 +let + if rxinfer_i == 1 + z_prev_m, z_prev_v = (z_prev_m_0, z_prev_v_0) + else + z_prev_m, z_prev_v = mean_cov(engine.history[:z][rxinfer_i-1]) + end + + μz_prediction, Σz_prediction = (A*z_prev_m + b*u[rxinfer_i], A*z_prev_v*A' + Σz) + μz_posterior, Σz_posterior = mean_cov(engine.history[:z][rxinfer_i]) + + plotCartPrediction( + predictive=Normal(μz_prediction[1], Σz_prediction[1]), + corrected=Normal(μz_posterior[1], Σz_posterior[1]), + measurement=Normal(xs_measurement[rxinfer_i][1], Σx[1,1]), + real=xs_real[rxinfer_i][1], + rolling=rxinfer_rolling, + ) +end + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +RxInfer = "86711068-29c9-4ff7-b620-ae75d7495b3d" +StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd" + +[compat] +BmlipTeachingTools = "~1.3.1" +Distributions = "~0.25.122" +Images = "~0.26.2" +LaTeXStrings = "~1.4.0" +Plots = "~1.40.17" +RxInfer = "~4.6.2" +StatsPlots = "~0.15.8" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "0657f8a5b01cdc7168325fefc2ac7e081ab09f15" + +[[deps.ADTypes]] +git-tree-sha1 = "27cecae79e5cc9935255f90c53bb831cc3c870d7" +uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +version = "1.18.0" + + [deps.ADTypes.extensions] + ADTypesChainRulesCoreExt = "ChainRulesCore" + ADTypesConstructionBaseExt = "ConstructionBase" + ADTypesEnzymeCoreExt = "EnzymeCore" + + [deps.ADTypes.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + +[[deps.AbstractFFTs]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" +uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] + + [deps.AbstractFFTs.extensions] + AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.4.0" +weakdeps = ["SparseArrays", "StaticArrays"] + + [deps.Adapt.extensions] + AdaptSparseArraysExt = "SparseArrays" + AdaptStaticArraysExt = "StaticArrays" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.4.0" + +[[deps.Arpack]] +deps = ["Arpack_jll", "Libdl", "LinearAlgebra", "Logging"] +git-tree-sha1 = "9b9b347613394885fd1c8c7729bfc60528faa436" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.5.4" + +[[deps.Arpack_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "OpenBLAS_jll", "Pkg"] +git-tree-sha1 = "5ba6c757e8feccf03a1554dfaf3e26b3cfc7fd5e" +uuid = "68821587-b530-5797-8361-c406ea357684" +version = "3.5.1+1" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra"] +git-tree-sha1 = "d2cd034553ee6ca084edaaf8ed6c9d50fd01555d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.21.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] + ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceMetalExt = "Metal" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceSparseArraysExt = "SparseArrays" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.ArrayLayouts]] +deps = ["FillArrays", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "355ab2d61069927d4247cd69ad0e1f140b31e30d" +uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +version = "1.12.0" +weakdeps = ["SparseArrays"] + + [deps.ArrayLayouts.extensions] + ArrayLayoutsSparseArraysExt = "SparseArrays" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.AxisAlgorithms]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] +git-tree-sha1 = "01b8ccb13d68535d73d2b0c23e39bd23155fb712" +uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" +version = "1.1.0" + +[[deps.AxisArrays]] +deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"] +git-tree-sha1 = "4126b08903b777c88edf1754288144a0492c05ad" +uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" +version = "0.4.8" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BayesBase]] +deps = ["Distributions", "DomainSets", "LinearAlgebra", "Random", "SpecialFunctions", "StaticArrays", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "TinyHugeNumbers"] +git-tree-sha1 = "5b723bf6b1081cab4d263e425be097224e0f434f" +uuid = "b4ee3484-f114-42fe-b91c-797d54a0c67e" +version = "1.5.8" +weakdeps = ["FastCholesky"] + + [deps.BayesBase.extensions] + FastCholeskyExt = "FastCholesky" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BitSetTuples]] +deps = ["TupleTools"] +git-tree-sha1 = "aa19428fb6ad21db22f8568f068de4f443d3bacc" +uuid = "0f2f92aa-23a3-4d05-b791-88071d064721" +version = "1.1.5" + +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.6" + +[[deps.BlockArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra"] +git-tree-sha1 = "79e651aa489a7879107d66e3d1948e9aa1b4055e" +uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" +version = "1.7.2" + + [deps.BlockArrays.extensions] + BlockArraysAdaptExt = "Adapt" + BlockArraysBandedMatricesExt = "BandedMatrices" + + [deps.BlockArrays.weakdeps] + Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.CEnum]] +git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" +uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" +version = "0.5.0" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Preferences", "Static"] +git-tree-sha1 = "f3a21d7fc84ba618a779d1ed2fcca2e682865bab" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.7" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.CatIndices]] +deps = ["CustomUnitRanges", "OffsetArrays"] +git-tree-sha1 = "a0f80a09780eed9b1d106a1bf62041c2efc995bc" +uuid = "aafaddc9-749c-510e-ac4f-586e18779b91" +version = "0.2.2" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "e4c6a16e77171a5f5e25e9646617ab1c276c5607" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.26.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ChunkCodecCore]] +git-tree-sha1 = "51f4c10ee01bda57371e977931de39ee0f0cdb3e" +uuid = "0b6fb165-00bc-4d37-ab8b-79f91016dbe1" +version = "1.0.0" + +[[deps.ChunkCodecLibZlib]] +deps = ["ChunkCodecCore", "Zlib_jll"] +git-tree-sha1 = "cee8104904c53d39eb94fd06cbe60cb5acde7177" +uuid = "4c0bbee4-addc-4d73-81a0-b6caacae83c8" +version = "1.0.0" + +[[deps.ChunkCodecLibZstd]] +deps = ["ChunkCodecCore", "Zstd_jll"] +git-tree-sha1 = "34d9873079e4cb3d0c62926a225136824677073f" +uuid = "55437552-ac27-4d47-9aa3-63184e8fd398" +version = "1.0.0" + +[[deps.CloseOpenIntervals]] +deps = ["Static", "StaticArrayInterface"] +git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" +uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" +version = "0.1.13" + +[[deps.Clustering]] +deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "Random", "SparseArrays", "Statistics", "StatsBase"] +git-tree-sha1 = "3e22db924e2945282e70c33b75d4dde8bfa44c94" +uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5" +version = "0.15.8" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.Combinatorics]] +git-tree-sha1 = "8010b6bb3388abe68d95743dcbea77650bb2eddf" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.3" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.1" + +[[deps.CommonWorldInvalidations]] +git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" +uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" +version = "1.0.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.CompositeTypes]] +git-tree-sha1 = "bce26c3dab336582805503bed209faab1c279768" +uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657" +version = "0.1.4" + +[[deps.ComputationalResources]] +git-tree-sha1 = "52cb3ec90e8a8bea0e62e275ba577ad0f74821f7" +uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3" +version = "0.3.2" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.ConstructionBase]] +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.6.0" +weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.CoordinateTransformations]] +deps = ["LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "a692f5e257d332de1e554e4566a4e5a8a72de2b2" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.6.4" + +[[deps.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + +[[deps.CustomUnitRanges]] +git-tree-sha1 = "1a3f97f907e6dd8983b744d2642651bb162a3f7a" +uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce" +version = "1.0.2" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Dictionaries]] +deps = ["Indexing", "Random", "Serialization"] +git-tree-sha1 = "a86af9c4c4f33e16a2b2ff43c2113b2f390081fa" +uuid = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" +version = "0.4.5" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.DifferentiationInterface]] +deps = ["ADTypes", "LinearAlgebra"] +git-tree-sha1 = "529bebbc74b36a4cfea09dd2aecb1288cd713a6d" +uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" +version = "0.7.9" + + [deps.DifferentiationInterface.extensions] + DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" + DifferentiationInterfaceDiffractorExt = "Diffractor" + DifferentiationInterfaceEnzymeExt = ["EnzymeCore", "Enzyme"] + DifferentiationInterfaceFastDifferentiationExt = "FastDifferentiation" + DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" + DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" + DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] + DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" + DifferentiationInterfaceGTPSAExt = "GTPSA" + DifferentiationInterfaceMooncakeExt = "Mooncake" + DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] + DifferentiationInterfaceReverseDiffExt = ["ReverseDiff", "DiffResults"] + DifferentiationInterfaceSparseArraysExt = "SparseArrays" + DifferentiationInterfaceSparseConnectivityTracerExt = "SparseConnectivityTracer" + DifferentiationInterfaceSparseMatrixColoringsExt = "SparseMatrixColorings" + DifferentiationInterfaceStaticArraysExt = "StaticArrays" + DifferentiationInterfaceSymbolicsExt = "Symbolics" + DifferentiationInterfaceTrackerExt = "Tracker" + DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] + + [deps.DifferentiationInterface.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" + Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + FastDifferentiation = "eb9bf01b-bf85-4b60-bf87-ee5de06c00be" + FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" + Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" + SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.12" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" +version = "1.11.0" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.DomainIntegrals]] +deps = ["CompositeTypes", "DomainSets", "FastGaussQuadrature", "GaussQuadrature", "HCubature", "IntervalSets", "LinearAlgebra", "QuadGK", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "934bf806ef2948114243f25e84a3ddf775d0f1a6" +uuid = "cc6bae93-f070-4015-88fd-838f9505a86c" +version = "0.5.2" + +[[deps.DomainSets]] +deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "c249d86e97a7e8398ce2068dce4c078a1c3464de" +uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" +version = "0.7.16" + + [deps.DomainSets.extensions] + DomainSetsMakieExt = "Makie" + DomainSetsRandomExt = "Random" + + [deps.DomainSets.weakdeps] + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EnumX]] +git-tree-sha1 = "bddad79635af6aec424f53ed8aad5d7555dc6f00" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.5" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.ExponentialFamily]] +deps = ["BayesBase", "BlockArrays", "Distributions", "DomainSets", "FastCholesky", "FillArrays", "ForwardDiff", "HCubature", "HypergeometricFunctions", "IntervalSets", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "PositiveFactorizations", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "StatsBase", "StatsFuns", "TinyHugeNumbers"] +git-tree-sha1 = "8351e116e111c97ad57718851da00ae5a5f92e0c" +uuid = "62312e5e-252a-4322-ace9-a5f4bf9b357b" +version = "2.1.1" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FFTViews]] +deps = ["CustomUnitRanges", "FFTW"] +git-tree-sha1 = "cbdf14d1e8c7c8aacbe8b19862e0179fd08321c2" +uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd" +version = "0.3.2" + +[[deps.FFTW]] +deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] +git-tree-sha1 = "97f08406df914023af55ade2f843c39e99c5d969" +uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +version = "1.10.0" + +[[deps.FFTW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" +version = "3.3.11+0" + +[[deps.FastCholesky]] +deps = ["LinearAlgebra", "PositiveFactorizations"] +git-tree-sha1 = "1c0a81e006e40e9fcbd5f6f6cb42ac2700f86889" +uuid = "2d5283b6-8564-42b6-bb00-83ed8e915756" +version = "1.4.3" +weakdeps = ["StaticArraysCore"] + + [deps.FastCholesky.extensions] + StaticArraysCoreExt = "StaticArraysCore" + +[[deps.FastGaussQuadrature]] +deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "0044e9f5e49a57e88205e8f30ab73928b05fe5b6" +uuid = "442a2c76-b920-505d-bb47-c5924d526838" +version = "1.1.0" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "d60eb76f37d7e5a40cc2e7c36974d864b82dc802" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.17.1" +weakdeps = ["HTTP"] + + [deps.FileIO.extensions] + HTTPExt = "HTTP" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] +git-tree-sha1 = "9340ca07ca27093ff68418b7558ca37b05f8aeb1" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.29.0" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffSparseArraysExt = "SparseArrays" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedArguments]] +deps = ["TupleTools"] +git-tree-sha1 = "befa1ad59c77643dec6fc20d71fd6f5c3afcdadd" +uuid = "4130a065-6d82-41fe-881e-7a5c65156f7d" +version = "0.1.1" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "ba6ce081425d0afb2bedd00d9884464f764a9225" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "1.2.2" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" +version = "1.11.0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GaussQuadrature]] +deps = ["SpecialFunctions"] +git-tree-sha1 = "eb6f1f48aa994f3018cbd029a17863c6535a266d" +uuid = "d54b0c1a-921d-58e0-8e36-89d8069c0969" +version = "0.5.8" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Giflib_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6570366d757b50fabae9f4315ad74d2e40c0560a" +uuid = "59f7168a-df46-5410-90c8-f2779963d0ec" +version = "5.2.3+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.GraphPPL]] +deps = ["BitSetTuples", "DataStructures", "Dictionaries", "MacroTools", "MetaGraphsNext", "NamedTupleTools", "Static", "StaticArrays", "TupleTools", "Unrolled"] +git-tree-sha1 = "db4aece54ddddaa9e8d2880eb7cfc6f29bd1a650" +uuid = "b3f8163a-e979-4e85-b43e-1f63d8c8b42c" +version = "4.6.5" + + [deps.GraphPPL.extensions] + GraphPPLDistributionsExt = "Distributions" + GraphPPLGraphVizExt = "GraphViz" + GraphPPLPlottingExt = ["Cairo", "GraphPlot"] + + [deps.GraphPPL.weakdeps] + Cairo = "159f3aea-2a34-519c-b102-8c37f9878175" + Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" + GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231" + GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0" + +[[deps.Graphics]] +deps = ["Colors", "LinearAlgebra", "NaNMath"] +git-tree-sha1 = "a641238db938fff9b2f60d08ed9030387daf428c" +uuid = "a2bd30eb-e257-5431-a919-1863eab51364" +version = "1.1.3" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Graphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "7a98c6502f4632dbe9fb1973a4244eaa3324e84d" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.13.1" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HCubature]] +deps = ["Combinatorics", "DataStructures", "LinearAlgebra", "QuadGK", "StaticArrays"] +git-tree-sha1 = "19ef9f0cb324eed957b7fe7257ac84e8ed8a48ec" +uuid = "19dc6840-f33b-545b-b366-655c7e3ffd49" +version = "1.7.0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HashArrayMappedTries]] +git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" +uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74" +version = "0.2.0" + +[[deps.HistogramThresholding]] +deps = ["ImageBase", "LinearAlgebra", "MappedArrays"] +git-tree-sha1 = "7194dfbb2f8d945abdaf68fa9480a965d6661e69" +uuid = "2c695a8d-9458-5d45-9878-1b8a99cf7853" +version = "0.3.1" + +[[deps.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.17" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.ImageAxes]] +deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"] +git-tree-sha1 = "e12629406c6c4442539436581041d372d69c55ba" +uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac" +version = "0.6.12" + +[[deps.ImageBase]] +deps = ["ImageCore", "Reexport"] +git-tree-sha1 = "eb49b82c172811fd2c86759fa0553a2221feb909" +uuid = "c817782e-172a-44cc-b673-b171935fbb9e" +version = "0.1.7" + +[[deps.ImageBinarization]] +deps = ["HistogramThresholding", "ImageCore", "LinearAlgebra", "Polynomials", "Reexport", "Statistics"] +git-tree-sha1 = "33485b4e40d1df46c806498c73ea32dc17475c59" +uuid = "cbc4b850-ae4b-5111-9e64-df94c024a13d" +version = "0.3.1" + +[[deps.ImageContrastAdjustment]] +deps = ["ImageBase", "ImageCore", "ImageTransformations", "Parameters"] +git-tree-sha1 = "eb3d4365a10e3f3ecb3b115e9d12db131d28a386" +uuid = "f332f351-ec65-5f6a-b3d1-319c6670881a" +version = "0.3.12" + +[[deps.ImageCore]] +deps = ["ColorVectorSpace", "Colors", "FixedPointNumbers", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "PrecompileTools", "Reexport"] +git-tree-sha1 = "8c193230235bbcee22c8066b0374f63b5683c2d3" +uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534" +version = "0.10.5" + +[[deps.ImageCorners]] +deps = ["ImageCore", "ImageFiltering", "PrecompileTools", "StaticArrays", "StatsBase"] +git-tree-sha1 = "24c52de051293745a9bad7d73497708954562b79" +uuid = "89d5987c-236e-4e32-acd0-25bd6bd87b70" +version = "0.1.3" + +[[deps.ImageDistances]] +deps = ["Distances", "ImageCore", "ImageMorphology", "LinearAlgebra", "Statistics"] +git-tree-sha1 = "08b0e6354b21ef5dd5e49026028e41831401aca8" +uuid = "51556ac3-7006-55f5-8cb3-34580c88182d" +version = "0.2.17" + +[[deps.ImageFiltering]] +deps = ["CatIndices", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "ImageBase", "ImageCore", "LinearAlgebra", "OffsetArrays", "PrecompileTools", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "TiledIteration"] +git-tree-sha1 = "52116260a234af5f69969c5286e6a5f8dc3feab8" +uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5" +version = "0.7.12" + +[[deps.ImageIO]] +deps = ["FileIO", "IndirectArrays", "JpegTurbo", "LazyModules", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs", "WebP"] +git-tree-sha1 = "696144904b76e1ca433b886b4e7edd067d76cbf7" +uuid = "82e4d734-157c-48bb-816b-45c225c6df19" +version = "0.6.9" + +[[deps.ImageMagick]] +deps = ["FileIO", "ImageCore", "ImageMagick_jll", "InteractiveUtils"] +git-tree-sha1 = "8e64ab2f0da7b928c8ae889c514a52741debc1c2" +uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1" +version = "1.4.2" + +[[deps.ImageMagick_jll]] +deps = ["Artifacts", "Bzip2_jll", "FFTW_jll", "Ghostscript_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "OpenJpeg_jll", "Zlib_jll", "Zstd_jll", "libpng_jll", "libwebp_jll", "libzip_jll"] +git-tree-sha1 = "d670e8e3adf0332f57054955422e85a4aec6d0b0" +uuid = "c73af94c-d91f-53ed-93a7-00f77d67a9d7" +version = "7.1.2005+0" + +[[deps.ImageMetadata]] +deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"] +git-tree-sha1 = "2a81c3897be6fbcde0802a0ebe6796d0562f63ec" +uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49" +version = "0.9.10" + +[[deps.ImageMorphology]] +deps = ["DataStructures", "ImageCore", "LinearAlgebra", "LoopVectorization", "OffsetArrays", "Requires", "TiledIteration"] +git-tree-sha1 = "cffa21df12f00ca1a365eb8ed107614b40e8c6da" +uuid = "787d08f9-d448-5407-9aad-5290dd7ab264" +version = "0.4.6" + +[[deps.ImageQualityIndexes]] +deps = ["ImageContrastAdjustment", "ImageCore", "ImageDistances", "ImageFiltering", "LazyModules", "OffsetArrays", "PrecompileTools", "Statistics"] +git-tree-sha1 = "783b70725ed326340adf225be4889906c96b8fd1" +uuid = "2996bd0c-7a13-11e9-2da2-2f5ce47296a9" +version = "0.3.7" + +[[deps.ImageSegmentation]] +deps = ["Clustering", "DataStructures", "Distances", "Graphs", "ImageCore", "ImageFiltering", "ImageMorphology", "LinearAlgebra", "MetaGraphs", "RegionTrees", "SimpleWeightedGraphs", "StaticArrays", "Statistics"] +git-tree-sha1 = "7196039573b6f312864547eb7a74360d6c0ab8e6" +uuid = "80713f31-8817-5129-9cf8-209ff8fb23e1" +version = "1.9.0" + +[[deps.ImageShow]] +deps = ["Base64", "ColorSchemes", "FileIO", "ImageBase", "ImageCore", "OffsetArrays", "StackViews"] +git-tree-sha1 = "3b5344bcdbdc11ad58f3b1956709b5b9345355de" +uuid = "4e3cecfd-b093-5904-9786-8bbb286a6a31" +version = "0.3.8" + +[[deps.ImageTransformations]] +deps = ["AxisAlgorithms", "CoordinateTransformations", "ImageBase", "ImageCore", "Interpolations", "OffsetArrays", "Rotations", "StaticArrays"] +git-tree-sha1 = "dfde81fafbe5d6516fb864dc79362c5c6b973c82" +uuid = "02fcd773-0e25-5acc-982a-7f6622650795" +version = "0.10.2" + +[[deps.Images]] +deps = ["Base64", "FileIO", "Graphics", "ImageAxes", "ImageBase", "ImageBinarization", "ImageContrastAdjustment", "ImageCore", "ImageCorners", "ImageDistances", "ImageFiltering", "ImageIO", "ImageMagick", "ImageMetadata", "ImageMorphology", "ImageQualityIndexes", "ImageSegmentation", "ImageShow", "ImageTransformations", "IndirectArrays", "IntegralArrays", "Random", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "TiledIteration"] +git-tree-sha1 = "a49b96fd4a8d1a9a718dfd9cde34c154fc84fcd5" +uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0" +version = "0.26.2" + +[[deps.Imath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0936ba688c6d201805a83da835b55c61a180db52" +uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1" +version = "3.1.11+0" + +[[deps.Indexing]] +git-tree-sha1 = "ce1566720fd6b19ff3411404d4b977acd4814f9f" +uuid = "313cdc1a-70c2-5d6a-ae34-0150d3930a38" +version = "1.1.1" + +[[deps.IndirectArrays]] +git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f" +uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959" +version = "1.0.0" + +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.IntegralArrays]] +deps = ["ColorTypes", "FixedPointNumbers", "IntervalSets"] +git-tree-sha1 = "b842cbff3f44804a84fda409745cc8f04c029a20" +uuid = "1d092043-8f09-5a30-832f-7509e371ab51" +version = "0.1.6" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2025.2.0+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.Interpolations]] +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "65d505fa4c0d7072990d659ef3fc086eb6da8208" +uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +version = "0.16.2" +weakdeps = ["ForwardDiff", "Unitful"] + + [deps.Interpolations.extensions] + InterpolationsForwardDiffExt = "ForwardDiff" + InterpolationsUnitfulExt = "Unitful" + +[[deps.IntervalSets]] +git-tree-sha1 = "5fbb102dcb8b1a858111ae81d56682376130517d" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.11" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.IterTools]] +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.10.0" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLD2]] +deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] +git-tree-sha1 = "da2e9b4d1abbebdcca0aa68afa0aa272102baad7" +uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +version = "0.6.2" +weakdeps = ["UnPack"] + + [deps.JLD2.extensions] + UnPackExt = "UnPack" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo]] +deps = ["CEnum", "FileIO", "ImageCore", "JpegTurbo_jll", "TOML"] +git-tree-sha1 = "9496de8fb52c224a2e3f9ff403947674517317d9" +uuid = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +version = "0.1.6" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.KernelDensity]] +deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] +git-tree-sha1 = "ba51324b894edaf1df3ab16e2cc6bc3280a2f1a7" +uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" +version = "0.6.10" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LayoutPointers]] +deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "a9eaadb366f5493a5654e843864c13d8b107548c" +uuid = "10f19ff3-798f-405d-979b-55457f8fc047" +version = "0.1.17" + +[[deps.LazyArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "SparseArrays"] +git-tree-sha1 = "79ee64f6ba0a5a49930f51c86f60d7526b5e12c8" +uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" +version = "2.8.0" + + [deps.LazyArrays.extensions] + LazyArraysBandedMatricesExt = "BandedMatrices" + LazyArraysBlockArraysExt = "BlockArrays" + LazyArraysBlockBandedMatricesExt = "BlockBandedMatrices" + LazyArraysStaticArraysExt = "StaticArrays" + + [deps.LazyArrays.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" +version = "1.11.0" + +[[deps.LazyModules]] +git-tree-sha1 = "a560dd966b386ac9ae60bdd3a3d3a326062d3c3e" +uuid = "8cdb02fc-e678-4876-92c5-9defec4f444e" +version = "0.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.4.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LittleCMS_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll"] +git-tree-sha1 = "8e6a74641caf3b84800f2ccd55dc7ab83893c10b" +uuid = "d3a379c0-f9a3-5b72-a4c0-6bf4d2e8af0f" +version = "2.17.0+0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.LoopVectorization]] +deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] +git-tree-sha1 = "a9fc7883eb9b5f04f46efb9a540833d1fad974b3" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.173" + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + ForwardDiffNNlibExt = ["ForwardDiff", "NNlib"] + SpecialFunctionsExt = "SpecialFunctions" + + [deps.LoopVectorization.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" + SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] +git-tree-sha1 = "282cadc186e7b2ae0eeadbd7a4dffed4196ae2aa" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2025.2.0+0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.MappedArrays]] +git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" +uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900" +version = "0.4.2" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MatrixCorrectionTools]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "73f93b21eae5714c282396bfae9d9f13d6ad04b6" +uuid = "41f81499-25de-46de-b591-c3cfc21e9eaf" +version = "1.2.0" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.MetaGraphs]] +deps = ["Graphs", "JLD2", "Random"] +git-tree-sha1 = "3a8f462a180a9d735e340f4e8d5f364d411da3a4" +uuid = "626554b9-1ddb-594c-aa3c-2596fe9399a5" +version = "0.8.1" + +[[deps.MetaGraphsNext]] +deps = ["Graphs", "JLD2", "SimpleTraits"] +git-tree-sha1 = "c3f7e597f1cf5fe04e68e7907af47f055cad211c" +uuid = "fa8bd995-216d-47f1-8a91-f3b68fbeb377" +version = "0.7.4" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MosaicViews]] +deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"] +git-tree-sha1 = "7b86a5d4d70a9f5cdf2dacb3cbe6d251d1a61dbe" +uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389" +version = "0.3.4" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.MultivariateStats]] +deps = ["Arpack", "Distributions", "LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI", "StatsBase"] +git-tree-sha1 = "816620e3aac93e5b5359e4fdaf23ca4525b00ddf" +uuid = "6f286f6a-111f-5878-ab1e-185364afe411" +version = "0.10.3" + +[[deps.NLSolversBase]] +deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.10.0" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NamedTupleTools]] +git-tree-sha1 = "90914795fc59df44120fe3fff6742bb0d7adb1d0" +uuid = "d9ec5142-1e00-5aa0-9d6a-321866360f50" +version = "0.14.3" + +[[deps.NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "ca7e18198a166a1f3eb92a3650d53d94ed8ca8a1" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.22" + +[[deps.Netpbm]] +deps = ["FileIO", "ImageCore", "ImageMetadata"] +git-tree-sha1 = "d92b107dbb887293622df7697a2223f9f8176fcd" +uuid = "f09324ee-3d7c-5217-9330-fc30815ba969" +version = "1.1.1" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Observables]] +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" +uuid = "510215fc-4207-5dde-b226-833fc4488ee2" +version = "0.5.5" + +[[deps.OffsetArrays]] +git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.17.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenEXR]] +deps = ["Colors", "FileIO", "OpenEXR_jll"] +git-tree-sha1 = "97db9e07fe2091882c765380ef58ec553074e9c7" +uuid = "52e1d378-f018-4a11-a4be-720524705ac7" +version = "0.3.3" + +[[deps.OpenEXR_jll]] +deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "8292dd5c8a38257111ada2174000a33745b06d4e" +uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" +version = "3.2.4+0" + +[[deps.OpenJpeg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libtiff_jll", "LittleCMS_jll", "libpng_jll"] +git-tree-sha1 = "215a6666fee6d6b3a6e75f2cc22cb767e2dd393a" +uuid = "643b3616-a352-519d-856d-80112ee9badc" +version = "2.5.5+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Optim]] +deps = ["Compat", "EnumX", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] +git-tree-sha1 = "61942645c38dd2b5b78e2082c9b51ab315315d10" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "1.13.2" + + [deps.Optim.extensions] + OptimMOIExt = "MathOptInterface" + + [deps.Optim.weakdeps] + MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.PNGFiles]] +deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"] +git-tree-sha1 = "cf181f0b1e6a18dfeb0ee8acc4a9d1672499626c" +uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883" +version = "0.4.4" + +[[deps.PaddedViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "0fac6313486baae819364c52b4f483450a9d793f" +uuid = "5432bcbf-9aad-5242-b902-cca2824c8663" +version = "0.5.12" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PkgVersion]] +deps = ["Pkg"] +git-tree-sha1 = "f9501cc0430a26bc3d156ae1b5b0c1b47af4d6da" +uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688" +version = "0.3.3" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PolyaGammaHybridSamplers]] +deps = ["Distributions", "Random", "SpecialFunctions", "StatsFuns"] +git-tree-sha1 = "9f6139650ff57f9d8528cd809ebc604c7e9738b1" +uuid = "c636ee4f-4591-4d8c-9fae-2dea21daa433" +version = "1.2.6" + +[[deps.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "645bed98cd47f72f67316fd42fc47dee771aefcd" +uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" +version = "0.2.2" + +[[deps.Polynomials]] +deps = ["LinearAlgebra", "OrderedCollections", "RecipesBase", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "972089912ba299fba87671b025cd0da74f5f54f7" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "4.1.0" + + [deps.Polynomials.extensions] + PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" + PolynomialsMakieExt = "Makie" + PolynomialsMutableArithmeticsExt = "MutableArithmetics" + + [deps.Polynomials.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" + +[[deps.PositiveFactorizations]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.4" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "fbb92c6c56b34e1a2c4c36058f68f332bec840e7" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.QOI]] +deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] +git-tree-sha1 = "8b3fc30bc0390abdce15f8822c889f669baed73d" +uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" +version = "1.0.1" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "994cc27cdacca10e68feb291673ec3a76aa2fae9" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.6" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.RangeArrays]] +git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5" +uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d" +version = "0.3.2" + +[[deps.Ratios]] +deps = ["Requires"] +git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" +uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" +version = "0.4.5" +weakdeps = ["FixedPointNumbers"] + + [deps.Ratios.extensions] + RatiosFixedPointNumbersExt = "FixedPointNumbers" + +[[deps.ReactiveMP]] +deps = ["BayesBase", "DataStructures", "DiffResults", "Distributions", "DomainIntegrals", "DomainSets", "ExponentialFamily", "FastCholesky", "FastGaussQuadrature", "FixedArguments", "ForwardDiff", "HCubature", "LazyArrays", "LinearAlgebra", "MacroTools", "MatrixCorrectionTools", "Optim", "PolyaGammaHybridSamplers", "PositiveFactorizations", "Random", "Rocket", "SpecialFunctions", "StaticArrays", "StatsBase", "StatsFuns", "TinyHugeNumbers", "Tullio", "TupleTools", "Unrolled"] +git-tree-sha1 = "dcd2f85ba9f2f7be1b1b31708db889d078b161f6" +uuid = "a194aa59-28ba-4574-a09c-4a745416d6e3" +version = "5.6.2" + + [deps.ReactiveMP.extensions] + ReactiveMPOptimisersExt = "Optimisers" + ReactiveMPProjectionExt = "ExponentialFamilyProjection" + ReactiveMPRequiresExt = "Requires" + + [deps.ReactiveMP.weakdeps] + ExponentialFamilyProjection = "17f509fa-9a96-44ba-99b2-1c5f01f0931b" + Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RegionTrees]] +deps = ["IterTools", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "4618ed0da7a251c7f92e869ae1a19c74a7d2a7f9" +uuid = "dee08c22-ab7f-5625-9660-a9af2021b33f" +version = "0.3.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.Rocket]] +deps = ["DataStructures", "Sockets", "Unrolled"] +git-tree-sha1 = "fe7373bf6b935c4431002fd91fa581d5eb835d09" +uuid = "df971d30-c9d6-4b37-b8ff-e965b2cb3a40" +version = "1.8.3" + +[[deps.Rotations]] +deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays"] +git-tree-sha1 = "5680a9276685d392c87407df00d57c9924d9f11e" +uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc" +version = "1.7.1" +weakdeps = ["RecipesBase"] + + [deps.Rotations.extensions] + RotationsRecipesBaseExt = "RecipesBase" + +[[deps.RxInfer]] +deps = ["BayesBase", "DataStructures", "Dates", "Distributions", "DomainSets", "ExponentialFamily", "FastCholesky", "GraphPPL", "HTTP", "JSON", "LinearAlgebra", "Logging", "MacroTools", "Optim", "Preferences", "ProgressMeter", "Random", "ReactiveMP", "Reexport", "Rocket", "Static", "Statistics", "TupleTools", "UUIDs"] +git-tree-sha1 = "bcaf218d6b5329dc5e5be4299cbb5818c2c7bb19" +uuid = "86711068-29c9-4ff7-b620-ae75d7495b3d" +version = "4.6.2" + + [deps.RxInfer.extensions] + PrettyTablesExt = "PrettyTables" + ProjectionExt = "ExponentialFamilyProjection" + + [deps.RxInfer.weakdeps] + ExponentialFamilyProjection = "17f509fa-9a96-44ba-99b2-1c5f01f0931b" + PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SIMD]] +deps = ["PrecompileTools"] +git-tree-sha1 = "e24dc23107d426a096d3eae6c165b921e74c18e4" +uuid = "fdea26ae-647d-5447-a871-4b548cad5224" +version = "3.7.2" + +[[deps.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "456f610ca2fbd1c14f5fcf31c6bfadc55e7d66e0" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.43" + +[[deps.SciMLPublic]] +git-tree-sha1 = "ed647f161e8b3f2973f24979ec074e8d084f1bee" +uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" +version = "1.0.0" + +[[deps.ScopedValues]] +deps = ["HashArrayMappedTries", "Logging"] +git-tree-sha1 = "c3b2323466378a2ba15bea4b2f73b081e022f473" +uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" +version = "1.5.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.8" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.2" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +version = "1.11.0" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.5" + +[[deps.SimpleWeightedGraphs]] +deps = ["Graphs", "LinearAlgebra", "Markdown", "SparseArrays"] +git-tree-sha1 = "3e5f165e58b18204aed03158664c4982d691f454" +uuid = "47aef6b3-ad0c-573a-a1e2-d07658019622" +version = "1.5.0" + +[[deps.Sixel]] +deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"] +git-tree-sha1 = "0494aed9501e7fb65daba895fb7fd57cc38bc743" +uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47" +version = "0.1.5" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.StackViews]] +deps = ["OffsetArrays"] +git-tree-sha1 = "be1cf4eb0ac528d96f5115b4ed80c26a8d8ae621" +uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15" +version = "0.1.2" + +[[deps.Static]] +deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] +git-tree-sha1 = "49440414711eddc7227724ae6e570c7d5559a086" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "1.3.1" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] +git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.8.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.15" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StatsPlots]] +deps = ["AbstractFFTs", "Clustering", "DataStructures", "Distributions", "Interpolations", "KernelDensity", "LinearAlgebra", "MultivariateStats", "NaNMath", "Observables", "Plots", "RecipesBase", "RecipesPipeline", "Reexport", "StatsBase", "TableOperations", "Tables", "Widgets"] +git-tree-sha1 = "88cf3587711d9ad0a55722d339a013c4c56c5bbc" +uuid = "f3b207a7-027a-5e70-b257-86293d7955fd" +version = "0.15.8" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableOperations]] +deps = ["SentinelArrays", "Tables", "Test"] +git-tree-sha1 = "e383c87cf2a1dc41fa30c093b2a19877c83e1bc1" +uuid = "ab02a1b2-a7df-11e8-156e-fb1833f50b87" +version = "1.2.0" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.12.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.ThreadingUtilities]] +deps = ["ManualMemory"] +git-tree-sha1 = "d969183d3d244b6c33796b5ed01ab97328f2db85" +uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" +version = "0.5.5" + +[[deps.TiffImages]] +deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "PrecompileTools", "ProgressMeter", "SIMD", "UUIDs"] +git-tree-sha1 = "98b9352a24cb6a2066f9ababcc6802de9aed8ad8" +uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" +version = "0.11.6" + +[[deps.TiledIteration]] +deps = ["OffsetArrays", "StaticArrayInterface"] +git-tree-sha1 = "1176cc31e867217b06928e2f140c90bd1bc88283" +uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac" +version = "0.5.0" + +[[deps.TinyHugeNumbers]] +git-tree-sha1 = "83c6abf376718345a85c071b249ef6692a8936d4" +uuid = "783c9a47-75a3-44ac-a16b-f1ab7b3acf04" +version = "1.0.3" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.Tullio]] +deps = ["DiffRules", "LinearAlgebra", "Requires"] +git-tree-sha1 = "972698b132b9df8791ae74aa547268e977b55f68" +uuid = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc" +version = "0.3.8" + + [deps.Tullio.extensions] + TullioCUDAExt = "CUDA" + TullioChainRulesCoreExt = "ChainRulesCore" + TullioFillArraysExt = "FillArrays" + TullioTrackerExt = "Tracker" + + [deps.Tullio.weakdeps] + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.TupleTools]] +git-tree-sha1 = "41e43b9dc950775eac654b9f845c839cd2f1821e" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.6.0" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unrolled]] +deps = ["MacroTools"] +git-tree-sha1 = "6cc9d682755680e0f0be87c56392b7651efc2c7b" +uuid = "9602ed7d-8fef-5bc8-8597-8f21381861e8" +version = "0.1.5" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "d1d9a935a26c475ebffd54e9c7ad11627c43ea85" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.72" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.WebP]] +deps = ["CEnum", "ColorTypes", "FileIO", "FixedPointNumbers", "ImageCore", "libwebp_jll"] +git-tree-sha1 = "aa1ca3c47f119fbdae8770c29820e5e6119b83f2" +uuid = "e3aaa7dc-3e4b-44e0-be63-ffb868ccd7c1" +version = "0.1.3" + +[[deps.Widgets]] +deps = ["Colors", "Dates", "Observables", "OrderedCollections"] +git-tree-sha1 = "e9aeb174f95385de31e70bd15fa066a505ea82b9" +uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62" +version = "0.6.7" + +[[deps.WoodburyMatrices]] +deps = ["LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" +version = "1.0.0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libsixel_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "libpng_jll"] +git-tree-sha1 = "c1733e347283df07689d71d61e14be986e49e47a" +uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" +version = "1.10.5+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.libwebp_jll]] +deps = ["Artifacts", "Giflib_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libglvnd_jll", "Libtiff_jll", "libpng_jll"] +git-tree-sha1 = "4e4282c4d846e11dce56d74fa8040130b7a95cb3" +uuid = "c5f90fcd-3b7e-5836-afba-fc50a0988cb2" +version = "1.6.0+0" + +[[deps.libzip_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "OpenSSL_jll", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "86addc139bca85fdf9e7741e10977c45785727b7" +uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1" +version = "1.11.3+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.oneTBB_jll]] +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f" +uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" +version = "2022.0.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─27289f68-d294-11ef-37d6-e399ed72a1d0 +# ╟─6107b57e-cda2-46fb-b6f8-bd0e3787516d +# ╟─2728adf0-d294-11ef-2467-f176bb42fb8b +# ╟─50c601c9-ec68-4155-932c-190bced1ac9a +# ╟─2728b7c8-d294-11ef-06e6-5329a76c16be +# ╟─91fb40f2-8c2d-4e0e-8a8a-8d823ed869dc +# ╟─49fd6d97-8ef1-49cd-8dcb-dafddb14814c +# ╟─4940b72d-182d-47bb-a446-51ce42724beb +# ╟─6b7f6d3b-8ad6-434a-babe-2597e86299fa +# ╟─fc919736-d9e3-4ca0-a53c-5fac18539ab5 +# ╟─2728c344-d294-11ef-1c5e-8d601b7ac3f9 +# ╟─2728d136-d294-11ef-27bc-6de51ace159c +# ╟─73104616-8cb4-4665-b09b-1c771ecdf372 +# ╟─2728dece-d294-11ef-2dda-af89555d838f +# ╟─2728e5c2-d294-11ef-1788-9b3699bb4ccd +# ╟─2729087c-d294-11ef-3f71-51112552f7b9 +# ╟─5d9d2972-0507-47a1-a726-26bb129f62f9 +# ╟─63f422ca-ba15-41ad-b36b-7a6aa4cc5e2a +# ╟─27290f78-d294-11ef-2ac4-b179be83b812 +# ╟─27295340-d294-11ef-3a56-131df0415315 +# ╟─27296132-d294-11ef-0d39-9da05d6c20b7 +# ╟─6bcabd28-f72b-47d9-b846-b1528f3758bb +# ╟─27298004-d294-11ef-06db-490237bf9408 +# ╟─d51bd37b-a12f-426a-87ca-6d4e6701fdb4 +# ╟─030d6de1-1f63-47d3-bea0-abe3ddf24be4 +# ╟─99ef8d0f-679a-43d1-9bbb-91bd8ad725ec +# ╟─69446a18-bb7d-45e2-b480-dcaa76fa66c0 +# ╟─620a77a8-50c4-4005-a41b-6a6221391434 +# ╟─2f439fb0-012c-4318-bb8b-90c37d2ff43c +# ╟─a24760e2-055a-4902-a78e-65aa59b80f68 +# ╟─27298d26-d294-11ef-080e-dbe7270d9191 +# ╟─27299a12-d294-11ef-1026-ddb5ffc81543 +# ╟─2729b6dc-d294-11ef-390f-6fa53c0b04f1 +# ╟─2729c4ba-d294-11ef-1ccc-df1f4ef5f3d4 +# ╟─2729ec24-d294-11ef-2547-cbb5238bb18d +# ╟─272a00a6-d294-11ef-18ba-a3700f78b13f +# ╟─e44c6138-7f59-48f3-8f4d-7c5db8e1c016 +# ╟─bbaa44b9-9bac-4fb8-8014-fbf400a93039 +# ╟─599e21c8-1141-4192-9dd7-46b83314a1ef +# ╟─272a0d3a-d294-11ef-2537-39a6e410e56b +# ╟─83587586-8a88-4bbb-b2bf-1ca9a8cf6339 +# ╟─f2e5dd92-b4bf-495a-8c11-2f34f2667041 +# ╠═ad05de22-40db-413e-85bd-24e6ef448656 +# ╟─ec3b781d-8b44-4bf4-9562-c5362eeb8913 +# ╠═e3056eeb-777a-4323-9d2e-f376cae2e1ca +# ╟─130edb3e-f5f9-40d2-970d-d0fc822fd82a +# ╠═2618d09b-4fd6-4cdc-9d80-45f7d0b262db +# ╟─272a4b2e-d294-11ef-2762-47a3479186ad +# ╠═6e8e7cea-7f97-418e-9453-c25a5896bc71 +# ╟─557b0052-b1a4-489e-be53-2327033954f2 +# ╟─b7d0c2e7-418b-417d-992a-c93ae3598f9e +# ╟─272aaaf6-d294-11ef-0162-c76ba8ba7232 +# ╟─272ab9b2-d294-11ef-0510-c3b68d2f1099 +# ╟─d6d3b368-8be5-4201-989f-44617d0cb34e +# ╠═32f7bc6a-cf3d-44f3-9603-8c4fe5c1a32d +# ╠═25b3697e-6171-402c-97a5-201ca6bbe3a7 +# ╠═331415dc-70fd-4b58-8536-8ed47b071e25 +# ╟─272afaec-d294-11ef-3953-5f868ec73cb8 +# ╟─95ca53f8-d60a-4262-911b-b1010e0c7752 +# ╟─27a6880c-b007-4d39-9e21-e7e24fc9d059 +# ╟─7505d957-0c4d-41ba-a662-45ba4dfe4d05 +# ╟─3a188b49-919d-4168-b789-ce6a5cebf509 +# ╟─e8cab5ea-4906-4c64-b1bb-f33e267762a1 +# ╟─d5d13c2e-3e8d-454e-b0d7-cb224aed063c +# ╟─0c65804b-bd3f-40b7-9752-96f730dbdc96 +# ╟─272b07f8-d294-11ef-3bfe-bffd9e3623aa +# ╟─272b17b6-d294-11ef-1e58-a75484ab56d9 +# ╟─f44e0303-dd28-48ad-9de2-7f7882f3923d +# ╠═e66b2193-87c8-4645-bfcc-643ee006383a +# ╠═f2a42c4d-9607-4f50-bbda-9a9a4942faab +# ╠═dab295ff-5a02-4e4f-8f46-b0842b6bf1ff +# ╠═07fe12dc-501c-407b-ab39-ba9a4845762c +# ╠═60201d93-64e8-42ce-85ab-8eb661223427 +# ╟─ae8c57ce-b74d-4543-b25b-eee57ad2e415 +# ╠═24f6c005-173d-4831-8c93-c54a9ba0334e +# ╠═84018669-bff5-4d06-a8f1-df515910c4d9 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/archive/Generative Classification.jl b/mlss/archive/Generative Classification.jl new file mode 100644 index 00000000..c2f73cf3 --- /dev/null +++ b/mlss/archive/Generative Classification.jl @@ -0,0 +1,2231 @@ +### A Pluto.jl notebook ### +# v0.20.19 + +#> [frontmatter] +#> image = "https://imgur.com/TGISnuj.png" +#> description = "Can you teach a computer to tell apples from peaches? Discover generative classification!" +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ f1a40378-a27c-4aa0-a62c-600ffde0032f +using BmlipTeachingTools + +# ╔═╡ 6631c0e4-4941-442e-8dd4-fa307ee7a8c0 +using Random + +# ╔═╡ f1575443-c9fb-4674-bbce-bf3a5a6d5a8d +using Plots, Distributions + +# ╔═╡ 26853cdc-0644-4f44-b6db-b5624a4a8689 +using MarkdownLiteral: @mdx + +# ╔═╡ 50cbe27e-009f-4df1-b80a-cf1e73fc525e +using LaTeXStrings + +# ╔═╡ 23c689fc-d294-11ef-086e-47c4f871bed2 +title("Generative Classification") + +# ╔═╡ fe9d4fbc-f264-459b-8fbe-26663500f6c5 +PlutoUI.TableOfContents() + +# ╔═╡ 23c6997e-d294-11ef-09a8-a50563e5975b +md""" +## Preliminaries + +##### Goal + + * Introduction to linear generative classification with a Gaussian-categorical generative model + +##### Materials + + * Mandatory + + * These lecture notes + * Optional + + * [Bishop PRML book](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf) (2006), pp. 196-202 (section 4.2 focuses on binary classification, whereas in these lecture notes we describe generative classification for multiple classes). + +""" + +# ╔═╡ f7a19975-a919-4659-9b6a-d8963a1cd6d9 +challenge_statement("Apple or Peach?" , color= "red", header_level=1 ) + +# ╔═╡ 876f47d8-b272-4e23-b5ec-5c7d615ff618 +begin + N_bond = @bindname N Slider(1:250; show_value=true, default=50) +end + +# ╔═╡ f63b65b9-86c8-420b-b2d5-28268782f155 +md""" +In the scatter plot, the two features are represented along the two ``x``-coordinates, while the fruit label ``y \in \{\text{apple}, \text{peach}\}`` is encoded by the marker style. + +""" + +# ╔═╡ 70a620bc-47c7-46c4-870b-22b3e05039a1 +md""" +The features are stored in two matrices, corresponding to the two classes: +""" + +# ╔═╡ 5730758d-80cd-4d95-b16c-399c38cf585b +md""" +# Bayesian Generative Classification +""" + +# ╔═╡ 23c73302-d294-11ef-0c12-571686b202a9 +md""" +The plan for generative classification is as follows: +We begin by constructing a model for the joint distribution + +```math +p(x, y) = p(x | y)\, p(y), +``` +which combines a **class-conditional likelihood** ``p(x | y)`` with a **prior** ``p(y)`` over classes. +Then, we apply Bayes rule to compute the posterior class probabilities, + +```math +p(y|x) = \frac{p(x|y) p(y)}{\sum_{y^\prime} p(x|y^\prime) p(y^\prime)} \propto p(x|y)\,p(y) +``` +This posterior can then be used for classification by selecting the class with the highest probability. + +Next, we discuss the three modeling stages: (1) model specification, (2) parameter learning, (3) application (classification). + +""" + +# ╔═╡ 23c73b54-d294-11ef-0ef8-8d9159139a1b +md""" +## Model Specification + +#### Representation + +The above data set will be represented as ``D = \{(x_1,y_1),\dotsc,(x_N,y_N)\}``, where + * inputs ``x_n \in \mathbb{R}^M`` are called **features**. + * outputs ``y_n \in \mathcal{C}_k``, with ``k=1,\ldots,K``; The **discrete** targets ``\mathcal{C}_k`` are called **classes**. + +Similar to our representation of the categorical distribution, we will again use the 1-of-K (or one-hot) encoding to represent the discrete class labels. We define binary **class selection variables** + +```math +y_{nk} = \begin{cases} 1 & \text{if } \, y_n \in \mathcal{C}_k\\ +0 & \text{otherwise} \end{cases} +``` + +Hence, the notations ``y_{nk}=1`` and ``y_n \in \mathcal{C}_k`` mean the same thing. + +""" + +# ╔═╡ 0d52466f-b092-4569-8c2d-b43c725887ae +md""" + +#### Likelihood + +Assume a Gaussian **class-conditional data-generating distribution** with **equal covariance matrix** across the classes, + +```math + p(x_n|\mathcal{C}_{k}) = \mathcal{N}(x_n|\mu_k,\Sigma) \tag{1} + +``` + +with notational shorthand: ``\mathcal{C}_{k} \triangleq (y_n \in \mathcal{C}_{k})``. + +""" + +# ╔═╡ 23c74748-d294-11ef-2170-bf45b6379e4d +md""" +#### Prior + +We use a categorical distribution for the class labels ``y_{nk}``: + +```math +p(\mathcal{C}_{k}) = \pi_k \tag{2} +``` + +""" + +# ╔═╡ 23c75dc8-d294-11ef-3c57-614e75f06d8f +md""" +We will refer to this model (specified by Eqs. 1 and 2) as the **Gaussian-Categorical Model** ($(HTML("GCM"))). + + * N.B. In the literature, this model (with possibly unequal ``\Sigma_k`` across classes) is often called the Gaussian Discriminant Analysis model and the special case with equal covariance matrices ``\Sigma_k=\Sigma`` is also called Linear Discriminant Analysis. We think these names are a bit unfortunate as it may lead to confusion with the [discriminative method for classification](https://bmlip.github.io/course/lectures/Discriminative%20Classification.html). + +""" + +# ╔═╡ 23c763ce-d294-11ef-015b-736be1a5e9d6 +md""" +As usual, once the model has been specified, the rest (inference for parameters and application) can be executed through straight probability theory. + +""" + +# ╔═╡ 20cd1582-d7f7-448c-8685-607f7cc1dc9c +keyconcept("",md""" +A common generative model for classification is the **Gaussian–Categorical model**: + +```math +p(x,\mathcal{C}_k|\,\theta) = \pi_k \cdot \mathcal{N}(x|\mu_k,\Sigma) \,. +``` + +""") + +# ╔═╡ 23c7779a-d294-11ef-2e2c-6ba6cadb1381 +md""" +## Parameter Estimation + +In principle, a full Bayesian treatment requires us to specify prior distributions over the model parameters ``\theta = \{ \{\pi_k\}, \{\mu_k\}, \Sigma \}``, and then apply Bayes rule to obtain the corresponding posterior distributions. While this is certainly possible, the mathematics quickly becomes bewildering. Therefore, we opt for maximum likelihood estimation of the parameters as a more practical alternative. + + +""" + +# ╔═╡ ffc80e65-a454-4b45-a9b7-76b01c7e96c0 +exercise_statement("Evaluate log-likelihood" , color= "yellow", header_level=4 ) + +# ╔═╡ 2e1ccf78-6097-4097-8bc8-1f1ec2d9c3ff +md""" + +Show that the log-likelihood for the parameters evaluates to + +```math +\log\, p(D|\theta) = \sum_{n,k} y_{nk} \underbrace{ \log\mathcal{N}(x_n|\mu_k,\Sigma) }_{ \text{see Gaussian lecture} } + \underbrace{ \sum_k m_k \log \pi_k }_{ \text{see multinomial lecture} } \tag{3} +``` + +where we used ``m_k \triangleq \sum_n y_{nk}``. + +""" + +# ╔═╡ 32cb67f6-1ed2-4d30-8493-e4eed9651526 +hide_solution( +md""" +```math +\begin{align*} +\log\, p(D|\theta) &= \log \prod_n p(x_n,y_n|\theta ) \quad \text{(assume IID data)} \\ + &= \sum_n \log p(x_n,y_n|\theta ) \\ + &= \sum_n \log \prod_k p(x_n,y_{nk}=1\,|\,\theta)^{y_{nk}} \\ + &= \sum_{n,k} y_{nk} \log p(x_n,y_{nk}=1\,|\,\theta) \\ + &= \sum_{n,k} y_{nk} \log p(x_n|y_{nk}=1) + \sum_{n,k} y_{nk} \log p(y_{nk}=1) \\ + &= \sum_{n,k} y_{nk} \log\mathcal{N}(x_n|\mu_k,\Sigma) + \sum_{n,k} y_{nk} \log \pi_k \\ + &= \sum_{n,k} y_{nk} \log\mathcal{N}(x_n|\mu_k,\Sigma)+ \sum_k m_k \log \pi_k +\end{align*} +``` +""" + ) + +# ╔═╡ 23c78d3e-d294-11ef-0309-ff10f58f0252 +md""" +#### Maximization of log-likelihood + +Maximization of the LLH for the GDA model breaks down into + + * **Gaussian density estimation** for parameters ``\mu_k, \Sigma``, since the first term contains exactly the log-likelihood for MVG density estimation. We've already done this, see the [Gaussian distribution lesson](https://bmlip.github.io/course/lectures/The%20Gaussian%20Distribution.html#ML-for-Gaussian). + * **Multinomial density estimation** for class priors ``\pi_k``, since the second term holds exactly the log-likelihood for multinomial density estimation, see the [Multinomial distribution lesson](https://bmlip.github.io/course/lectures/The%20Multinomial%20Distribution.html#ML-for-multinomial). + +""" + +# ╔═╡ 23c798ce-d294-11ef-0190-f342f30e2266 +md""" +The ML for multinomial class prior (we've done this before!) + +```math +\begin{align*} +\hat \pi_k = \frac{m_k}{N} +\end{align*} +``` + +""" + +# ╔═╡ 23c7a54c-d294-11ef-0252-ef7a043e995c +md""" +Now group the data into separate classes and do MVG ML estimation for class-conditional parameters (we've done this before as well): + +```math +\begin{align*} + \hat \mu_k &= \frac{ \sum_n y_{nk} x_n} { \sum_n y_{nk} } = \frac{1}{m_k} \sum_n y_{nk} x_n \\ + \hat \Sigma &= \frac{1}{N} \sum_{n,k} y_{nk} (x_n-\hat \mu_k)(x_n-\hat \mu_k)^T \\ + &= \sum_k \hat \pi_k \cdot \underbrace{ \left( \frac{1}{m_k} \sum_{n} y_{nk} (x_n-\hat \mu_k)(x_n-\hat \mu_k)^T \right) }_{ \text{class-cond. variance} } \\ + &= \sum_k \hat \pi_k \cdot \hat \Sigma_k +\end{align*} +``` + +where ``\hat \pi_k``, ``\hat{\mu}_k`` and ``\hat{\Sigma}_k`` are the sample proportion, sample mean and sample variance for the ``k``th class, respectively. + +""" + +# ╔═╡ 23c7ab20-d294-11ef-1926-afae49e79923 +md""" +Note that the binary class selection variable ``y_{nk}`` groups data from the same class. + +""" + +# ╔═╡ 14362031-7977-4a0c-b329-23da9b5b2f62 +keyconcept("", +md""" +ML estimation for ``\{\pi_k,\mu_k,\Sigma\}`` in the GCM model breaks down to simple density estimation for Gaussian and multinomial/categorical distributions. + +""") + +# ╔═╡ 23c7baa4-d294-11ef-22c1-31b0d86f5586 +md""" +## Application: Class prediction for new Data + +##### the posterior class probability + +Let's apply the trained model to predict the class for a "new" input ``x_\bullet``: + +```math +\begin{align*} +p(\mathcal{C}_k|x_\bullet,D ) &= \int p(\mathcal{C}_k|x_\bullet,\theta ) p(\theta|D) \mathrm{d}\theta \\ + &= \sigma\left( \beta_k^T x_\bullet + \gamma_k\right) \tag{4} +\end{align*} +``` + +where +```math +\sigma(a)_k \triangleq \frac{\exp(a_k)}{\sum_{k^\prime}\exp(a_{k^\prime})} +``` +is $(HTML("called a")) [**softmax**](https://en.wikipedia.org/wiki/Softmax_function) (a.k.a., **normalized exponential**) function, and + +```math +\begin{align*} +\beta_k &= \hat{\Sigma}^{-1} \hat{\mu}_k \\ +\gamma_k &= - \frac{1}{2} \hat{\mu}_k^T \hat{\Sigma}^{-1} \hat{\mu}_k + \log \hat{\pi}_k +\end{align*} +``` + +""" + +# ╔═╡ 84353cd1-e4fb-4689-9e90-d8995cbe2e9b +details("Click for proof of (4)", +md""" ```math +\begin{align*} +p(\mathcal{C}_k|x_\bullet,D ) &= \int p(\mathcal{C}_k|x_\bullet,\theta ) \underbrace{p(\theta|D)}_{=\delta(\theta - \hat{\theta})} \mathrm{d}\theta \\ +&= p(\mathcal{C}_k|x_\bullet,\hat{\theta} ) \\ +&\propto p(\mathcal{C}_k)\,p(x_\bullet|\mathcal{C}_k) \\ +&= \hat{\pi}_k \cdot \mathcal{N}(x_\bullet | \hat{\mu}_k, \hat{\Sigma}) \\ + &\propto \hat{\pi}_k \exp \left\{ { - {\frac{1}{2}}(x_\bullet - \hat{\mu}_k )^T \hat{\Sigma}^{ - 1} (x_\bullet - \hat{\mu}_k )} \right\}\\ + &=\exp \Big\{ \underbrace{-\frac{1}{2}x_\bullet^T \hat{\Sigma}^{ - 1} x_\bullet}_{\text{not a function of }k} + \underbrace{\hat{\mu}_k^T \hat{\Sigma}^{-1}}_{\beta_k^T} x_\bullet \underbrace{- {\frac{1}{2}}\hat{\mu}_k^T \hat{\Sigma}^{ - 1} \hat{\mu}_k + \log \hat{\pi}_k }_{\gamma_k} \Big\} \\ + &\propto \frac{1}{Z}\exp\{\beta_k^T x_\bullet + \gamma_k\} \\ + &= \sigma\left( \beta_k^T x_\bullet + \gamma_k\right) +\end{align*} +``` """ ) + + +# ╔═╡ 23c7c920-d294-11ef-1b6d-d98dd54dcbe3 +md""" + +##### The softmax function + +The softmax function can be viewed as a smooth approximation to the maximum function. +Importantly, we did not impose the softmax posterior by assumption; rather, it emerged naturally by applying Bayes rule to our chosen prior and likelihood models. +""" + +# ╔═╡ 2f2cb20f-ff7c-4b7f-8aa0-f5b3addb9299 +NotebookCard("https://bmlip.github.io/course/minis/Softmax.html") + +# ╔═╡ 866d8e7a-2b33-4635-84c0-6cbf900b523b +keyconcept("", +md"""For the GCM with equal covariances, the posterior class probability is a softmax function, + +```math + p(\mathcal{C}_k|x,\theta ) \propto \exp\{\beta_k^T x + \gamma_k\} +``` + +where ``\beta _k= \Sigma^{-1} \mu_k`` and ``\gamma_k=- \frac{1}{2} \mu_k^T \Sigma^{-1} \mu_k + \log \pi_k``. +""") + +# ╔═╡ 23c82154-d294-11ef-0945-c9c94fc2a44d +md""" +#### Making a Decision + +How should we classify a new input ``x_\bullet``? + +The Bayesian answer is to compute the posterior distribution over classes, +```math +p(\mathcal{C}_k | x_\bullet,D)\,, +``` +and this completes the classification task: the posterior encapsulates all available information about class membership given the input and data. + +If a definite classification **must** be made, a natural choice is the class with the highest posterior probability: + +```math +\begin{align*} +k^* &= \arg\max_k p(\mathcal{C}_k|x_\bullet,D) \\ + &= \arg\max_k \left( \beta _k^T x_\bullet + \gamma_k \right) +\end{align*} +``` +This corresponds to a maximum a posteriori (MAP) decision rule, which is both simple and effective in many practical settings. + +""" + +# ╔═╡ 23c7e4a0-d294-11ef-16e9-6f96a41baf97 +md""" +## Discrimination Boundaries + +The class log-posterior ``\log p(\mathcal{C}_k|x) \propto \beta_k^T x + \gamma_k`` is a linear function of the input features. + +""" + +# ╔═╡ 23c7f170-d294-11ef-1340-fbdf4ce5fd44 +md""" +Therefore, the contours of equal probability (also known as **discriminant functions**, or **decision boundaries**), given by + +```math +\log \frac{{p(\mathcal{C}_k|x,D )}}{{p(\mathcal{C}_j|x,D )}} \overset{!}{=} 0 \,, +``` +are lines (hyperplanes) in the feature space. + + +""" + +# ╔═╡ 5c746070-19a9-464b-aedc-401d016dfdb6 +exercise_statement("Discrimination boundaries" , color= "yellow", header_level=4 ) + +# ╔═╡ 8d78f9d3-7ba8-46b0-8d6f-231e681caa49 +md""" +Show that the discrimination boundaries for the posterior class probabilities in Eq. (4) evaluates to a line (or hyperplane). +""" + +# ╔═╡ 25e18c78-9cac-4faa-bb7c-ac036d0eac90 +hide_solution( +md""" +```math +\begin{align} +&\log \frac{{p(\mathcal{C}_k|x,D )}}{{p(\mathcal{C}_j|x,D )}} \overset{!}{=} 0 \\ +\implies &\frac{\beta_k^T x + \gamma_k}{\beta_j^T x + \gamma_j} = 1 \\ +\implies &\beta_k^T x + \gamma_k = \beta_j^T x + \gamma_j \\ +\implies &\beta_{kj}^T x + \gamma_{kj} = 0 \quad \text{(this is a line)}\,, +\end{align} +``` + +where we defined ``\beta_{kj} \triangleq \beta_k - \beta_j`` and similarly for ``\gamma_{kj}``. +""" + + ) + +# ╔═╡ 117f3f65-a9bd-4b25-93e2-42ac1e576b6d +keyconcept("", +md""" If the class-conditional distributions are Gaussian with equal covariance matrices across classes (i.e., ``\Sigma_k = \Sigma``), then the discriminant functions are hyperplanes in feature space. +""") + +# ╔═╡ a8adaf31-bee2-40e9-8d9b-bb9f1ad996ca +md""" +Now assume that the class-conditional feature distributions are modeled with class-dependent covariance matrices, i.e., +```math + p(x_n|\mathcal{C}_{k}) = \mathcal{N}(x_n|\mu_k,\Sigma_k) + +``` +What do the decision boundaries look like in this case? +""" + +# ╔═╡ b01a4a56-bed2-4a06-991a-831adc84aa3e +hide_solution( +md""" +Following the same derivation as above (in the cell "Click for proof of (4)"), the posterior class probability evaluates to + ```math +\begin{align*} +p(\mathcal{C}_k|x_\bullet,D ) \propto \exp \Big\{ \underbrace{-\frac{1}{2}x_\bullet^T \hat{\Sigma}_k^{ - 1} x_\bullet}_{\text{now a function of }k} + \underbrace{\hat{\mu}_k^T \hat{\Sigma}_k^{-1}}_{\beta_k^T} x_\bullet \underbrace{- {\frac{1}{2}}\hat{\mu}_k^T \hat{\Sigma}_k^{ - 1} \hat{\mu}_k + \log \hat{\pi}_k }_{\gamma_k} \Big\} \,. +\end{align*} +``` +Because the quadratic term ``x_\bullet^T \hat{\Sigma}_k^{-1} x_\bullet`` is now class-dependent, the decision boundaries are given by quadratic equations in ``x``. Hence, the decision boundaries are generally (hyper-)parabolic surfaces. + +""" ) + +# ╔═╡ 1a890e4b-b8a9-4a6e-b1f3-17863e1416d7 +challenge_solution("Apple or Peach", header_level=1, color="green") + +# ╔═╡ 689ea1f9-0a72-478e-b8a9-ebf450ce95ef +N_bond + +# ╔═╡ 4481b38d-dc67-4c1f-ac0b-b348f0aea461 +md""" + +## Implementation Issues + +We can fit a Bernouilly distribution to [`y` (see definition)](#y), this is simple: +""" + +# ╔═╡ 5092090d-cfac-4ced-b61e-fb7107a4c638 +md""" +#### Estimate class-conditional distributions +Now, for each class, we fit a Gaussian distribution to the data of that class: +""" + +# ╔═╡ 3228f074-7c1d-420a-bfb0-c3bd693003ad +md""" +Our model assumes that both distributions have the same covariance matrix. We get this in practice by taking the weighted average of the two: +""" + +# ╔═╡ e91effb4-b3ac-4d7a-b93f-33a78a125110 +md""" + +We now have class-conditional Gaussian distributions for each class: +""" + +# ╔═╡ 845f19c4-c3c5-4368-a48a-a7b57687ddf9 +N_bond + +# ╔═╡ 21602809-d98b-43d7-8c41-80dc8de6da57 +md""" +# Closing Thoughts +""" + +# ╔═╡ 23c85d90-d294-11ef-375e-7101d4d3cbfa +md""" +## Why Be Bayesian? + +A student in one of the previous years posed the following question at Piazza: + +> "After re-reading topics regarding generative classification, this question popped into my mind: Besides the sole purpose of the lecture, which is getting to know the concepts of generative classification and how to implement them, are there any advantages of using this instead of using deep neural nets (DNN), as they seem simpler and more powerful?" + + +The following answer was provided: + +If you are only interested in approximating a function, and you have lots of examples of desired behavior, then often a non-probabilistic DNN is a fine approach. However, if you are willing to formulate your models in a probabilistic framework, you can frequently improve on the deterministic approach in many ways. We list a few below: + +1. **Bayesian Evidence as a Performance Metric** + - Model performance is evaluated using the evidence ``p(D|m)`` for a model, which inherently balances fit and complexity. This enables the use of the entire dataset for learning: there is no need for arbitrary splits into training and test sets. + +2. **Parameter Uncertainty Enables Active Learning** + - By maintaining uncertainty over model parameters, Bayesian models support active learning, i.e., the selection of data points that are expected to be most informative (See the [lesson on intelligent agents](https://bmlip.github.io/course/lectures/Intelligent%20Agents%20and%20Active%20Inference.html)). This allows learning from smaller datasets, unlike deterministic deep networks, which often require massive amounts of labeled data. + +3. **Predictions with Confidence Bounds** + - Bayesian models naturally yield predictive distributions, enabling uncertainty quantification (e.g., confidence intervals) around predictions. + +4. **Explicit and Modular Assumptions** + - Priors, likelihoods, and structural assumptions are explicitly specified and can be independently modified, promoting transparency and model modularity. + +5. **Unified Treatment of Accuracy and Complexity** + - Both data fit and model complexity are scored in the same probabilistic units. In contrast, how would you penalize overparameterized architectures (e.g., deep networks) in a deterministic framework? + +6. **Data-Dependent, Optimal Learning Rates** + - Learning rates emerge naturally from Bayesian updates. Contrast this with the trial-and-error tuning needed in standard optimization. + - Example: The Kalman gain is an optimal learning rate based on current uncertainty. + +7. **Principled Knowledge Transfer** + - Bayesian inference enables posterior-to-prior propagation: results from one experiment (posterior) can inform the next (as a prior). This provides a principled mechanism for sequential learning and integration of heterogeneous information sources. + + +Admittedly, the probabilistic approach can be challenging to grasp at first, but the effort often pays off. It provides a principled, flexible, and robust framework for reasoning under uncertainty. + + +""" + +# ╔═╡ 45f1f80d-18fc-465c-aaf3-54bbcd8bc95e +md""" +# Summary +""" + +# ╔═╡ 358fac57-7458-40b5-9f69-50ad4ca7edde +keyconceptsummary() + +# ╔═╡ ca11db2d-aa15-4bf1-b949-529c7487d11d +exercises(header_level=1) + +# ╔═╡ 24a08e5c-c2c1-4f1f-a2c1-998b30147e61 +md""" + +#### Fanta or Orangina? (**) + +You have a machine that measures property ``x``, the "orangeness" of liquids. You wish to discriminate between ``C_1 = \text{`Fanta'}`` and ``C_2 = \text{`Orangina'}``. It is known that + +```math +\begin{align*} +p(x|C_1) &= \begin{cases} 10 & 1.0 \leq x \leq 1.1\\ + 0 & \text{otherwise} + \end{cases}\\ +p(x|C_2) &= \begin{cases} 200(x - 1) & 1.0 \leq x \leq 1.1\\ +0 & \text{otherwise} +\end{cases} +\end{align*} +``` + +The prior probabilities ``p(C_1) = 0.6`` and ``p(C_2) = 0.4`` are also known from experience. + +- (a) A "Bayes Classifier" is given by + +```math + \text{Decision} = \begin{cases} C_1 & \text{if } p(C_1|x)>p(C_2|x) \\ + C_2 & \text{otherwise} + \end{cases} +``` + +Derive the optimal Bayes classifier. + +- (b) The probability of making the wrong decision, given ``x``, is + +```math +p(\text{error}|x)= p(C_1|\text{we-decide-} C_2, x) + p(C_2|\text{we-decide-}C_1, x) +``` + +Compute the **total** error probability ``p(\text{error})`` for the Bayes classifier in this example. + +""" + +# ╔═╡ 66172ab6-7df8-4068-a748-b33b3f345d6d +hide_solution( +md""" +- (a) We choose ``C_1`` if ``p(C_1|x)/p(C_2|x) > 1``. This condition can be worked out as + + +```math +\frac{p(C_1|x)}{p(C_2|x)} = \frac{p(x|C_1)p(C_1)}{p(x|C_2)p(C_2)} = \frac{10 \times 0.6}{200(x-1)\times 0.4}>1 +``` + +which evaluates to choosing + +```math +\mathrm{Decision} = \begin{cases} +C_1 & \text{ if $1.0\leq x < 1.075$} \\ +C_2 & \text{ if $1.075 \leq x \leq 1.1$ } +\end{cases} +``` + +The probability that ``x`` falls outside the interval ``[1.0,1.1]`` is zero. + + +- (b) The total probability of error is + +```math +p(\text{error})=\int_x p(\text{error}|x)p(x) \mathrm{d}{x} \,. +``` + +We can work this out as + + +```math +\begin{align*} +p(\text{error}) &= \int_x p(\text{error}|x)p(x)\mathrm{d}{x}\\ +&= \int_{1.0}^{1.075} p(C_2|x)p(x) \mathrm{d}{x} + \int_{1.075}^{1.1} p(C_1|x)p(x) \mathrm{d}{x}\\ +&= \int_{1.0}^{1.075} p(x|C_2)p(C_2) \mathrm{d}{x} + \int_{1.075}^{1.1} p(x|C_1)p(C_1) \mathrm{d}{x}\\ +&= \int_{1.0}^{1.075}0.4\cdot 200(x-1) \mathrm{d}{x} + \int_{1.075}^{1.1} 0.6\cdot 10 \mathrm{d}{x}\\ +&=80\cdot[x^2/2-x]_{1.0}^{1.075} + 6\cdot[x]_{1.075}^{1.1}\\ +&=0.225 + 0.15\\ +&=0.375 +\end{align*} +``` + +""") + +# ╔═╡ 7e5213d6-4a68-4843-ab4c-77ea3ed8b0cd +md""" +#### [Bishop exercise 4.8](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf#page=241) (**) + +Using (4.57) and (4.58) (from Bishop's book), derive the result (4.65) for the posterior class probability in the two-class generative model with Gaussian densities, and verify the results (4.66) and (4.67) for the parameters ``w`` and ``w0``. + +""" + +# ╔═╡ ef1e5885-7153-4b55-9f97-1e984c2504e6 +hide_solution( +md""" +Substitute 4.64 into 4.58 to get + +```math +\begin{align*} +a &= \log \left( \frac{ \frac{1}{(2\pi)^{D/2}} \cdot \frac{1}{|\Sigma|^{1/2}} \cdot \exp\left( -\frac{1}{2}(x-\mu_1)^T \Sigma^{-1} (x-\mu_1)\right) \cdot p(C_1)}{\frac{1}{(2\pi)^{D/2}} \cdot \frac{1}{|\Sigma|^{1/2}}\cdot \exp\left( -\frac{1}{2}(x-\mu_2)^T \Sigma^{-1} (x-\mu_2)\right) \cdot p(C_2)}\right) \\ +&= \log \left( \exp\left(-\frac{1}{2}(x-\mu_1)^T \Sigma^{-1} (x-\mu_1) + \frac{1}{2}(x-\mu_2)^T \Sigma^{-1} (x-\mu_2) \right) \right) + \log \frac{p(C_1)}{p(C_2)} \\ +&\qquad\vdots \\ +&=( \mu_1-\mu_2)^T\Sigma^{-1}x - 0.5\left(\mu_1^T\Sigma^{-1}\mu_1 - \mu_2^T\Sigma^{-1} \mu_2\right)+ \log \frac{p(C_1)}{p(C_2)} +\end{align*} +``` + +Substituting this into the right-most form of (4.57) we obtain (4.65), with ``w`` and ``w0`` given by (4.66) and (4.67), respectively. + +""") + +# ╔═╡ e65e0e33-3e4f-4765-84ea-a4fb5d43269e +md""" +# Code +""" + +# ╔═╡ a4463d74-04ea-428a-b5a5-504d96432a0a +md""" +Our data is structured as follows: +- ``y`` is whether a data point is an apple (`true`) or a peach (`false`) +- ``x`` has one column of data per fruit +""" + +# ╔═╡ 3842654e-6dd7-427c-bb77-8b35a2f324fb +const Σ_secret = [0.2 0.1; 0.1 0.3]; + +# ╔═╡ c91ed138-9885-43ce-a00e-1ba6e996f1aa +const p_apple_secret = Bernoulli(0.7); + +# ╔═╡ 841ddfc8-85e0-47ee-9288-2d90a84a5dc3 +y = rand(MersenneTwister(23), p_apple_secret, N) + +# ╔═╡ fedb7530-6fce-496c-a55a-3e9908f9711a +y .|> Int |> join + +# ╔═╡ cc8144d9-9ecf-4cbd-aea9-0c7a2fca2d94 +p_apple_est = sum(y) / length(y) # or: p_apple_est = fit_mle(Bernoulli, y).p + +# ╔═╡ 19360d53-93d8-46fe-82d5-357015e75e22 +π_hat = [p_apple_est; 1-p_apple_est] + +# ╔═╡ eac2821e-b25c-4605-857a-cd3bd06303c1 +X = let + Σ = Σ_secret + p_given_apple = MvNormal([1.0, 1.0], Σ) # p(X|y=apple) + p_given_peach = MvNormal([1.7, 2.5], Σ) # p(X|y=peach) + + # Apple or peach? + X = Matrix{Float64}(undef,2,N); + + rng = MersenneTwister(76) + + for n in 1:N + X[:,n] = rand(rng, y[n] ? p_given_apple : p_given_peach) + end # for + X + end; + +# ╔═╡ 24d3c1f4-432f-419f-8854-69d8bfc135f8 +X_apples, X_peaches = collect(X[:,findall(y)]'), collect(X[:,findall(.!y)]'); + +# ╔═╡ cff683bf-0488-41d2-9858-cf8776a48992 +X_apples, X_peaches + +# ╔═╡ 10bfb9ea-46a6-4f4d-980e-ed2afce7b39a +d1 = fit_mle(FullNormal, X_apples') # MLE density estimation d1 = N(μ₁, Σ₁) + +# ╔═╡ cd310392-aabd-40e0-b06f-f8297c7eed6f +d2 = fit_mle(FullNormal, X_peaches') # MLE density estimation d2 = N(μ₂, Σ₂) + +# ╔═╡ ba9fa93f-093c-4783-988f-27f4ba228e88 +Σ_computed = Σ = π_hat[1]*cov(d1) + π_hat[2]*cov(d2) # Combine Σ₁ and Σ₂ into Σ + +# ╔═╡ 46d2d5e9-bb6b-409a-acdc-cdffd1a6f797 +conditionals = [ + MvNormal(mean(d1), Σ_computed) + MvNormal(mean(d2), Σ_computed) +] # p(x|C) + +# ╔═╡ 33d5d6e7-1208-4c5b-b651-429b3b6ad50b +# calculate p(C_k | point) +function predict_class(k::Int64, point::Vector{<:Real})::Real + norm = + π_hat[1]*pdf(conditionals[1],point) + + π_hat[2]*pdf(conditionals[2],point) + + return π_hat[k]*pdf(conditionals[k], point) ./ norm +end + +# ╔═╡ d9efe8bb-c32c-40f4-89d9-8ace7a0665ba +x_test = [2.3; 1.5] # Features of 'new' data point + +# ╔═╡ bf39f423-7df3-4990-a254-c28a1bdf23bf +x_test + +# ╔═╡ 723e09fc-ec63-4c47-844c-d821515ce0f4 +@mdx("``p(\\text{apple}|x=x_∙) = $(round(predict_class(1,x_test), digits=3))``") + +# ╔═╡ ffa01b68-c3ba-4509-8df6-00596974be0f +const plot_lims = ( + xlim=(-.3, 3.1), ylim=(-.4, 4.1), +) + +# ╔═╡ 69732524-90fd-46f4-9706-c07ce6226d2b +let + # plot training data + scatter(X_apples[:,1], X_apples[:,2], label="apple", marker=:x, markerstrokewidth=3) + scatter!(X_peaches[:,1], X_peaches[:,2], label="peach", marker=:+, markerstrokewidth=3) + plot!(; plot_lims..., legend=:topleft) + + # plot test point + scatter!([x_test[1]], [x_test[2]], label="unknown", c=:yellow, ms=9) +end # let + +# ╔═╡ 36e6b874-a1b8-40d7-8762-f0c5f9121e40 +let + plot(; plot_lims..., legend=:topleft) + scatter!(X_apples[:,1], X_apples[:,2], label="apple", marker=:x, markerstrokewidth=3) + scatter!(X_peaches[:,1], X_peaches[:,2], label="peach", marker=:+, markerstrokewidth=3) + scatter!([x_test[1]], [x_test[2]], label="unknown", color="yellow") # 'new' unlabelled data point + + x = y = range(-1, stop = 5, length = 40) + for distr in conditionals + contour!(x, y, (x, y) -> pdf(distr, [x,y]); opacity=.4, color=cgrad(:grays, rev=true)) + end + plot!() +end + +# ╔═╡ 4ada77d1-09f2-49c7-a44f-1928e0dc5421 +let + plot(; plot_lims..., legend=:topleft, title=L"p(apple | x)") + scatter!(X_apples[:,1], X_apples[:,2], label="apple", marker=:x, markerstrokewidth=3) + scatter!(X_peaches[:,1], X_peaches[:,2], label="peach", marker=:+, markerstrokewidth=3) + scatter!([x_test[1]], [x_test[2]], label="unknown", color="yellow") # 'new' unlabelled data point + + x = range(plot_lims.xlim..., length=60) + y = range(plot_lims.ylim..., length=60) + heatmap!(x, y, (x, y) -> predict_class(1, [x,y]); opacity=.4, color=cgrad(:bluesreds, rev=true)) + plot!() +end + +# ╔═╡ c79525b1-7b44-4585-8292-84abe20a1a3d +md""" +Markers +""" + +# ╔═╡ 79fa1b47-460f-457e-aebc-646f60ffecc1 +unknown_marker = @htl """ + + """ + +# ╔═╡ fe324e92-d753-46cd-aad9-794a76dc806b +md""" + +You are also given a test fruit $unknown_marker, which has known feature values but an **unknown fruit label**. + +""" + +# ╔═╡ a985e1d3-4867-4991-a60e-e85a9730311b +apple_marker = @htl """ + + +""" + +# ╔═╡ 90b862a5-d5bc-4122-a942-f01062daa86a +md""" +### Posterior class probability of ``x_∙`` (prediction) + +Now we can answer the question from the challenge, and calculate the probability that ``x_∙`` is an apple $apple_marker. +""" + +# ╔═╡ 9973e8e5-4744-4ff6-9494-1c93503f11c1 +md""" +We can use this function on every point of the plot, to draw a heatmap of apple $apple_marker probability: +""" + +# ╔═╡ e8cbfc78-04dd-4196-8011-90283969e5b1 +peach_marker = @htl """ + + +""" + +# ╔═╡ 51a46b5e-0c35-4841-a4f3-413d5d294805 +md""" + +You're given the numerical values for two features (let's say, _sugar content_ and _acidity_) of a bunch of fruits. Each piece of fruit is either an apple $apple_marker or a peach $peach_marker. + +Generate this data yourself by selecting the total number of fruits with the slider: +""" + +# ╔═╡ 77280f3b-e391-482f-936f-703d1d3c4006 +md""" + +##### Problem + + - Based on the observed data, what is the probability that the test fruit is an apple $apple_marker, and not a peach $peach_marker? + +##### Solution + + - Later in this lecture. +""" + +# ╔═╡ 23c82e10-d294-11ef-286a-ff6fee0f2805 +md""" + +We'll apply the above results to solve the "apple $apple_marker or peach $peach_marker" example problem. + +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +MarkdownLiteral = "736d6165-7244-6769-4267-6b50796e6954" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[compat] +BmlipTeachingTools = "~1.3.1" +Distributions = "~0.25.122" +LaTeXStrings = "~1.4.0" +MarkdownLiteral = "~0.1.2" +Plots = "~1.40.17" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "7c2148a417390ed2e53a59f6046d1571771e2044" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.CommonMark]] +deps = ["PrecompileTools"] +git-tree-sha1 = "351d6f4eaf273b753001b2de4dffb8279b100769" +uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" +version = "0.9.1" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MarkdownLiteral]] +deps = ["CommonMark", "HypertextLiteral"] +git-tree-sha1 = "f7d73634acd573bf3489df1ee0d270a5d6d3a7a3" +uuid = "736d6165-7244-6769-4267-6b50796e6954" +version = "0.1.2" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─23c689fc-d294-11ef-086e-47c4f871bed2 +# ╟─fe9d4fbc-f264-459b-8fbe-26663500f6c5 +# ╟─23c6997e-d294-11ef-09a8-a50563e5975b +# ╟─f7a19975-a919-4659-9b6a-d8963a1cd6d9 +# ╟─51a46b5e-0c35-4841-a4f3-413d5d294805 +# ╟─876f47d8-b272-4e23-b5ec-5c7d615ff618 +# ╟─69732524-90fd-46f4-9706-c07ce6226d2b +# ╟─f63b65b9-86c8-420b-b2d5-28268782f155 +# ╟─841ddfc8-85e0-47ee-9288-2d90a84a5dc3 +# ╠═fedb7530-6fce-496c-a55a-3e9908f9711a +# ╟─70a620bc-47c7-46c4-870b-22b3e05039a1 +# ╠═cff683bf-0488-41d2-9858-cf8776a48992 +# ╟─fe324e92-d753-46cd-aad9-794a76dc806b +# ╠═bf39f423-7df3-4990-a254-c28a1bdf23bf +# ╟─77280f3b-e391-482f-936f-703d1d3c4006 +# ╟─5730758d-80cd-4d95-b16c-399c38cf585b +# ╟─23c73302-d294-11ef-0c12-571686b202a9 +# ╟─23c73b54-d294-11ef-0ef8-8d9159139a1b +# ╟─0d52466f-b092-4569-8c2d-b43c725887ae +# ╟─23c74748-d294-11ef-2170-bf45b6379e4d +# ╟─23c75dc8-d294-11ef-3c57-614e75f06d8f +# ╟─23c763ce-d294-11ef-015b-736be1a5e9d6 +# ╟─20cd1582-d7f7-448c-8685-607f7cc1dc9c +# ╟─23c7779a-d294-11ef-2e2c-6ba6cadb1381 +# ╟─ffc80e65-a454-4b45-a9b7-76b01c7e96c0 +# ╟─2e1ccf78-6097-4097-8bc8-1f1ec2d9c3ff +# ╟─32cb67f6-1ed2-4d30-8493-e4eed9651526 +# ╟─23c78d3e-d294-11ef-0309-ff10f58f0252 +# ╟─23c798ce-d294-11ef-0190-f342f30e2266 +# ╟─23c7a54c-d294-11ef-0252-ef7a043e995c +# ╟─23c7ab20-d294-11ef-1926-afae49e79923 +# ╟─14362031-7977-4a0c-b329-23da9b5b2f62 +# ╟─23c7baa4-d294-11ef-22c1-31b0d86f5586 +# ╟─84353cd1-e4fb-4689-9e90-d8995cbe2e9b +# ╟─23c7c920-d294-11ef-1b6d-d98dd54dcbe3 +# ╟─2f2cb20f-ff7c-4b7f-8aa0-f5b3addb9299 +# ╟─866d8e7a-2b33-4635-84c0-6cbf900b523b +# ╟─23c82154-d294-11ef-0945-c9c94fc2a44d +# ╟─23c7e4a0-d294-11ef-16e9-6f96a41baf97 +# ╟─23c7f170-d294-11ef-1340-fbdf4ce5fd44 +# ╟─5c746070-19a9-464b-aedc-401d016dfdb6 +# ╟─8d78f9d3-7ba8-46b0-8d6f-231e681caa49 +# ╟─25e18c78-9cac-4faa-bb7c-ac036d0eac90 +# ╟─117f3f65-a9bd-4b25-93e2-42ac1e576b6d +# ╟─a8adaf31-bee2-40e9-8d9b-bb9f1ad996ca +# ╟─b01a4a56-bed2-4a06-991a-831adc84aa3e +# ╟─1a890e4b-b8a9-4a6e-b1f3-17863e1416d7 +# ╟─23c82e10-d294-11ef-286a-ff6fee0f2805 +# ╟─36e6b874-a1b8-40d7-8762-f0c5f9121e40 +# ╟─689ea1f9-0a72-478e-b8a9-ebf450ce95ef +# ╟─4481b38d-dc67-4c1f-ac0b-b348f0aea461 +# ╠═cc8144d9-9ecf-4cbd-aea9-0c7a2fca2d94 +# ╠═19360d53-93d8-46fe-82d5-357015e75e22 +# ╟─5092090d-cfac-4ced-b61e-fb7107a4c638 +# ╠═10bfb9ea-46a6-4f4d-980e-ed2afce7b39a +# ╠═cd310392-aabd-40e0-b06f-f8297c7eed6f +# ╟─3228f074-7c1d-420a-bfb0-c3bd693003ad +# ╠═ba9fa93f-093c-4783-988f-27f4ba228e88 +# ╠═46d2d5e9-bb6b-409a-acdc-cdffd1a6f797 +# ╟─e91effb4-b3ac-4d7a-b93f-33a78a125110 +# ╠═90b862a5-d5bc-4122-a942-f01062daa86a +# ╠═33d5d6e7-1208-4c5b-b651-429b3b6ad50b +# ╟─723e09fc-ec63-4c47-844c-d821515ce0f4 +# ╟─9973e8e5-4744-4ff6-9494-1c93503f11c1 +# ╟─4ada77d1-09f2-49c7-a44f-1928e0dc5421 +# ╟─845f19c4-c3c5-4368-a48a-a7b57687ddf9 +# ╟─21602809-d98b-43d7-8c41-80dc8de6da57 +# ╟─23c85d90-d294-11ef-375e-7101d4d3cbfa +# ╟─45f1f80d-18fc-465c-aaf3-54bbcd8bc95e +# ╟─358fac57-7458-40b5-9f69-50ad4ca7edde +# ╟─ca11db2d-aa15-4bf1-b949-529c7487d11d +# ╟─24a08e5c-c2c1-4f1f-a2c1-998b30147e61 +# ╟─66172ab6-7df8-4068-a748-b33b3f345d6d +# ╟─7e5213d6-4a68-4843-ab4c-77ea3ed8b0cd +# ╟─ef1e5885-7153-4b55-9f97-1e984c2504e6 +# ╟─e65e0e33-3e4f-4765-84ea-a4fb5d43269e +# ╠═f1a40378-a27c-4aa0-a62c-600ffde0032f +# ╠═6631c0e4-4941-442e-8dd4-fa307ee7a8c0 +# ╠═f1575443-c9fb-4674-bbce-bf3a5a6d5a8d +# ╠═26853cdc-0644-4f44-b6db-b5624a4a8689 +# ╠═50cbe27e-009f-4df1-b80a-cf1e73fc525e +# ╟─a4463d74-04ea-428a-b5a5-504d96432a0a +# ╠═3842654e-6dd7-427c-bb77-8b35a2f324fb +# ╠═c91ed138-9885-43ce-a00e-1ba6e996f1aa +# ╠═eac2821e-b25c-4605-857a-cd3bd06303c1 +# ╠═24d3c1f4-432f-419f-8854-69d8bfc135f8 +# ╠═d9efe8bb-c32c-40f4-89d9-8ace7a0665ba +# ╠═ffa01b68-c3ba-4509-8df6-00596974be0f +# ╟─c79525b1-7b44-4585-8292-84abe20a1a3d +# ╟─79fa1b47-460f-457e-aebc-646f60ffecc1 +# ╟─a985e1d3-4867-4991-a60e-e85a9730311b +# ╟─e8cbfc78-04dd-4196-8011-90283969e5b1 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/archive/Machine Learning Overview.jl b/mlss/archive/Machine Learning Overview.jl new file mode 100644 index 00000000..d3680178 --- /dev/null +++ b/mlss/archive/Machine Learning Overview.jl @@ -0,0 +1,746 @@ +### A Pluto.jl notebook ### +# v0.20.19 + +#> [frontmatter] +#> image = "https://github.com/bmlip/course/blob/v2/assets/figures/scientific-inquiry-loop.png?raw=true" +#> description = "What type of problem can be solved using Machine Learning? Can we apply the Bayesian approach?" +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# ╔═╡ a5d43e01-8f73-4c48-b565-f10eb807a9ab +using BmlipTeachingTools + +# ╔═╡ 3ceb490e-d294-11ef-1883-a50aadd2d519 +title("Machine Learning Overview") + +# ╔═╡ d7d20de9-53c6-4e30-a1bd-874fca52f017 +PlutoUI.TableOfContents() + +# ╔═╡ 3cebc804-d294-11ef-32bd-29507524ddb2 +md""" +## Preliminaries + +##### Goal + + * Top-level overview of machine learning + +##### Materials + + * Mandatory + + * this notebook + * Optional + + * Study Bishop pp. 1-4 + +""" + +# ╔═╡ 3cebf2d4-d294-11ef-1fde-bf03ecfb9b99 +md""" +## What is Machine Learning? + +Machine Learning relates to **building models from data and using these models in applications**. + +""" + +# ╔═╡ 3cec06e6-d294-11ef-3359-5740f25965da +md""" +##### Problem + + - Suppose we want to develop an algorithm for a complex process about which we have little knowledge (so hand-programming is not possible). + +""" + +# ╔═╡ 3cec1032-d294-11ef-1b9d-237c491b2eb2 +md""" +##### Solution + + - Get the computer to develop the algorithm by itself by showing it examples of the behavior that we want. + +""" + +# ╔═╡ 3cec1832-d294-11ef-1317-07fe5c4e69c2 +md""" +Practically, we choose a library of models, and write a program that picks a model and tunes it to fit the data. + +""" + +# ╔═╡ 3cec20f4-d294-11ef-1012-c19579a786e4 +md""" +This field is known in various scientific communities with slight variations under different names such as machine learning, statistical inference, system identification, data mining, source coding, data compression, data science, etc. + +""" + +# ╔═╡ 3cec3062-d294-11ef-3dd6-bfc5588bdf1f +md""" +## Machine Learning and the Scientific Method + + +The **scientific method** (or scientific inquiry loop) is a systematic approach for building models of the world. It comprises three stages: + + 1. **Hypothesis formulation / Experimental ("Trial") design** – a trial is designed and executed, based on an analysis of the uncertainties in the current model. + + 2. **Observation / Data collection** – the world’s response to the trial is measured in the form of new observations. + + 3. **Analysis / Model updating** – the model is revised in light of the observations. + +The cycle repeats, incrementally improving the model and our understanding. In an engineering context, the model can be used for various applications, such as predicting the future, or recognizing observations as objects. + +![](https://github.com/bmlip/course/blob/v2/assets/figures/scientific-inquiry-loop.png?raw=true) + + +Machine learning can be viewed analogously, as the process of constructing models of the world. While one may debate whether the experimental design stage is part of the machine learning field, the model updating stage, driven by observations, clearly is. This explains why machine learning methods are applied so widely across the sciences and engineering disciplines. + +In this course, we will revisit this scientific inquiry loop and progressively annotate it with the mathematical formulas that underlie each stage of the scientific method. + +""" + +# ╔═╡ a3ae8443-0100-41f7-a91a-c7d128064b88 +keyconcept("", +"Machine learning is about building models of the environment and is therefore an integral part of the scientific inquiry loop. Consequently, we see machine learning applied across the sciences, engineering, and society at large.") + +# ╔═╡ 3cec43d4-d294-11ef-0a9f-43eb506527a6 +md""" +## Machine Learning is Difficult + +##### Modeling (Learning) Problems + + * Is there any regularity in the data anyway? + * What is our prior knowledge and how to express it mathematically? + * How to pick the model library? + * How to tune the models to the data? + * How to measure the generalization performance? + +""" + +# ╔═╡ 3cec5b96-d294-11ef-39e0-15e93768d2b1 +md""" +##### Quality of Observed Data + + * Not enough data + * Too much data? + * Available data may be messy (measurement noise, missing data points, outliers) + +""" + +# ╔═╡ 3cec86cc-d294-11ef-267d-7743fd241c64 +md""" +# A Machine Learning Taxonomy + +Machine learning methods can be grouped, in broad terms, into four categories: + + - Supervised learning + + - Unsupervised learning + + - Trial design / decision-making + + - Other frameworks + - Other stuff, like preference learning, learning to rank, etc., can often be (re-)formulated as special cases of either a supervised, unsupervised, or trial design problem. + +We will briefly introduce these categories below and, in the forthcoming lectures, expand on how each can be framed within the Bayesian machine learning perspective. + +![](https://github.com/bmlip/course/blob/v2/assets/figures/ml-taxonomy.png?raw=true) + + +""" + +# ╔═╡ a66c3b31-0f1f-41ff-b19c-0926ea1c2ff5 +keyconcept("", +"The three major paradigms of machine learning are supervised learning, unsupervised learning, and trial design. Most other applications can be reframed within one of these three frameworks." ) + +# ╔═╡ 6f95adeb-d0a9-47fd-900a-0e55d497bab6 +md""" +## Supervised Learning +""" + +# ╔═╡ 3ced0d0c-d294-11ef-3000-7b63362a2351 +md""" + +**Supervised learning** is about learning functions. [Functions describe the world!!](https://youtu.be/BWZTlfrneD8?si=FNhUu7QH9O9xx2Bp) + +In supervised learning, we are given observations of desired input–output behavior, + +```math +D = \{(x_1, y_1), \dots, (x_N, y_N)\}, +``` + +where ``x_n`` are inputs and ``y_n`` are the corresponding outputs. The goal is to estimate the conditional probability distribution ``p(y_n | x_n)``, i.e., to capture how ``y_n`` depends on ``x_n``. The term "supervised" reflects the fact that the correct outputs ``y_n`` are provided in the training dataset ``D``. (The reasons for using probabilities will be discussed in the [Probability Theory lecture](https://bmlip.github.io/course/lectures/Probability%20Theory%20Review.html).) + +Generally, we distinguish between **classification** and **regression** as two different supervised learning problems. + +""" + +# ╔═╡ e1122eab-a25b-4441-a053-b0121b334731 +md""" +#### Classification + +In a classification problem, the target variable ``y`` is a *discrete-valued* vector representing class labels. + +The special case ``y \in \{\text{true},\text{false}\}`` is called **detection**. + + +![](https://imgur.com/XSCNBN9.png) + +""" + +# ╔═╡ b00872c2-96d0-47e7-8495-a3d6e559ea63 +NotebookCard("https://bmlip.github.io/course/lectures/Generative%20Classification.html"; link_text="Go to lecture") + +# ╔═╡ 3ced29ae-d294-11ef-158b-09fcdaa47d1c +md""" +#### Regression + +Regression, also called **curve fitting**, is the supervised learning task of estimating the conditional distribution ``p(y_n | x_n)``, where ``x_n`` are input variables and ``y_n`` represent __continuous__ output variables. + +![](https://imgur.com/lKUUjWr.png) + +""" + +# ╔═╡ 672c35c0-c7ab-4e17-a280-867bf3cf2f27 +NotebookCard("https://bmlip.github.io/course/lectures/Regression.html"; link_text="Go to lecture") + +# ╔═╡ 3cec9250-d294-11ef-01ac-9d94676a65a3 +md""" +## Unsupervised Learning + +In the unsupervised learning setting, we are given a data set + +```math +D=\{x_1,\ldots,x_N\}\,. +``` + +The task is to model the unconditional probability distribution ``p(x_n)``. The absence of target variables ``y_n`` in the dataset gives rise to the term unsupervised. + +Because no targets are provided, unsupervised learning problems are generally considered more challenging than supervised ones. As in supervised learning, however, we can distinguish two main types of tasks: **clustering** (discovering structure in the data) and **compression** (learning efficient representations of the data). + + +""" + +# ╔═╡ c5bfab8f-4985-420a-b46e-b4ff6d359d3d +md""" +#### Clustering + +If the unobserved target variables take on discrete values, the task is referred to as clustering. In this sense, clustering can be regarded as "unsupervised classification". + +![](https://imgur.com/yIvpvD6.png) +""" + +# ╔═╡ bb485cc3-02e2-4cb4-9e4d-80574b8eb66c +NotebookCard("https://bmlip.github.io/course/lectures/Latent%20Variable%20Models%20and%20VB.html"; link_text="Go to lecture") + +# ╔═╡ 3ced567c-d294-11ef-2657-df20e23a00fa +md""" +#### Compression + +In contrast, if the unobserved target variables are continuously valued, the task is referred to as **compression**. For example, compressing an image ``x`` produces an output ``y`` that is much smaller in size than the original. The objective is to learn a mapping ``y = f(x)`` (the encoder) such that the inverse mapping ``\hat{x} = g(y) \approx f^{-1}(y)`` reconstructs ``\hat{x}`` as close as possible (ideally identical) to the original input ``x``. + +Compression can be interpreted as ''unsupervised regression''. + +![](https://github.com/bmlip/course/blob/v2/assets/figures/fig-compression-example.png?raw=true) + +In this lecture series, we unfortunately do not have enough time to discuss compression in detail in a separate lecture. [Chapter 12 in Bishop (2006)](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf#page=579) contains a nice introduction to compression. + +""" + +# ╔═╡ 0d6029ef-87ba-4881-b7af-9de2dad1ed99 +md""" +## Trial Design +""" + +# ╔═╡ 3cecbc46-d294-11ef-24cb-2d9e41fb35d9 +md""" + +**Trial design** concerns learning which actions (trials) to perform in order to gain information about the environment and/or to achieve certain specific goals (such as crossing a street). In the broader literature, this idea is presented under various related labels, including **experimental design**, **active learning**, **decision-making under uncertainty**, **sequential decision-making**, **hypothesis testing**, **policy learning**, **planning**, and **control**. The sheer number of terms (often differing only in nuance) underscores the central importance of this task within the scientific inquiry process. + +In trial design problems, the model is not only a description of the environment but also acts upon it, thereby influencing which data will be observed in the future. Such systems are called "agents". In addition to the labels mentioned above, the term [Agentic AI](https://en.wikipedia.org/wiki/Agentic_AI) has recently gained popularity. + +In the machine learning and AI community, two prominent approaches to trial design are reinforcement learning and active inference: + + - **Reinforcement Learning**: Given an observed sequence of input signals and (occasionally observed) rewards for those inputs, *learn* to select actions that maximize *expected* future rewards. + + - **Active inference**: Given an observed sequence of input signals and a prior probability distribution about future observations, *learn* to select actions that minimize *expected* prediction errors (i.e., minimize actual minus predicted sensation). + + +""" + +# ╔═╡ 5971fb3c-1489-4e66-a77a-2c6e9714b8a2 +Resource("https://github.com/bmlip/course/raw/refs/heads/main/assets/figures/minigrid%20loop.mp4", :autoplay => true, :loop=>true) + +# ╔═╡ d2f07ece-5cea-4c00-8ed8-a70752e113b7 +NotebookCard("https://bmlip.github.io/course/lectures/Intelligent%20Agents%20and%20Active%20Inference.html"; link_text="Go to lecture") + +# ╔═╡ 3ced839a-d294-11ef-3dd0-1f8c5ef11b75 +md""" +## $(HTML("Some Machine Learning Applications")) + +- computer speech recognition, speaker recognition + +- face recognition, iris identification + +- printed and handwritten text parsing + +- financial prediction, outlier detection (credit-card fraud) + +- user preference modeling (amazon); modeling of human perception + +- modeling of the web (google) + +- machine translation + +- medical expert systems for disease diagnosis (e.g., mammogram) + +- strategic games (chess, go, backgammon), self-driving cars + +In summary, **any 'knowledge-poor' but 'data-rich' problem** + +""" + +# ╔═╡ 438981cd-8450-4678-8b61-9cc5c0c0ebf1 +md""" +# Summary +""" + +# ╔═╡ f47f4370-4d6f-4e36-bbef-63f806130dbe +keyconceptsummary() + +# ╔═╡ 86a2a956-fee6-4306-b8cb-f4b977ad3dbd +md""" +# Code +""" + +# ╔═╡ fa1d5123-db02-4fda-93d2-3e5e2efed515 +html""" + +""" + +# ╔═╡ 3ced947a-d294-11ef-0403-512f2407a2d2 +md""" + +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" + +[compat] +BmlipTeachingTools = "~1.3.1" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "3e0db0a10f1d7687b8c53fc91306ce22ead0cdba" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" + + [deps.Pkg.extensions] + REPLExt = "REPL" + + [deps.Pkg.weakdeps] + REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + + [deps.Statistics.weakdeps] + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" +""" + +# ╔═╡ Cell order: +# ╟─3ceb490e-d294-11ef-1883-a50aadd2d519 +# ╟─d7d20de9-53c6-4e30-a1bd-874fca52f017 +# ╟─3cebc804-d294-11ef-32bd-29507524ddb2 +# ╟─3cebf2d4-d294-11ef-1fde-bf03ecfb9b99 +# ╟─3cec06e6-d294-11ef-3359-5740f25965da +# ╟─3cec1032-d294-11ef-1b9d-237c491b2eb2 +# ╟─3cec1832-d294-11ef-1317-07fe5c4e69c2 +# ╟─3cec20f4-d294-11ef-1012-c19579a786e4 +# ╟─3cec3062-d294-11ef-3dd6-bfc5588bdf1f +# ╟─a3ae8443-0100-41f7-a91a-c7d128064b88 +# ╟─3cec43d4-d294-11ef-0a9f-43eb506527a6 +# ╟─3cec5b96-d294-11ef-39e0-15e93768d2b1 +# ╟─3cec86cc-d294-11ef-267d-7743fd241c64 +# ╟─a66c3b31-0f1f-41ff-b19c-0926ea1c2ff5 +# ╟─6f95adeb-d0a9-47fd-900a-0e55d497bab6 +# ╟─3ced0d0c-d294-11ef-3000-7b63362a2351 +# ╟─e1122eab-a25b-4441-a053-b0121b334731 +# ╟─b00872c2-96d0-47e7-8495-a3d6e559ea63 +# ╟─3ced29ae-d294-11ef-158b-09fcdaa47d1c +# ╟─672c35c0-c7ab-4e17-a280-867bf3cf2f27 +# ╟─3cec9250-d294-11ef-01ac-9d94676a65a3 +# ╟─c5bfab8f-4985-420a-b46e-b4ff6d359d3d +# ╟─bb485cc3-02e2-4cb4-9e4d-80574b8eb66c +# ╟─3ced567c-d294-11ef-2657-df20e23a00fa +# ╟─0d6029ef-87ba-4881-b7af-9de2dad1ed99 +# ╟─3cecbc46-d294-11ef-24cb-2d9e41fb35d9 +# ╟─5971fb3c-1489-4e66-a77a-2c6e9714b8a2 +# ╟─d2f07ece-5cea-4c00-8ed8-a70752e113b7 +# ╟─3ced839a-d294-11ef-3dd0-1f8c5ef11b75 +# ╟─438981cd-8450-4678-8b61-9cc5c0c0ebf1 +# ╟─f47f4370-4d6f-4e36-bbef-63f806130dbe +# ╟─86a2a956-fee6-4306-b8cb-f4b977ad3dbd +# ╟─a5d43e01-8f73-4c48-b565-f10eb807a9ab +# ╟─fa1d5123-db02-4fda-93d2-3e5e2efed515 +# ╟─3ced947a-d294-11ef-0403-512f2407a2d2 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/archive/Regression.jl b/mlss/archive/Regression.jl new file mode 100644 index 00000000..ec8e3ffa --- /dev/null +++ b/mlss/archive/Regression.jl @@ -0,0 +1,2261 @@ +### A Pluto.jl notebook ### +# v0.20.21 + +#> [frontmatter] +#> image = "https://i.imgur.com/azbCpRW.png" +#> description = "Introduction to Bayesian linear regression and predictive modeling for continuous data." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ f8c69b91-4415-454e-a50d-c4a37ada89d1 +using BmlipTeachingTools + +# ╔═╡ 33ca4c67-d96f-457f-bc19-171f4b4b03c6 +using LinearAlgebra, Random + +# ╔═╡ 3ff2bd04-1490-4be6-8b26-b82d1902bb07 +using Plots, Distributions, LaTeXStrings + +# ╔═╡ 234b77a8-d294-11ef-15d5-ff54ed5bec1e +title("Regression") + +# ╔═╡ 66998cd5-78d6-4b22-a9c9-886436cba4dd +PlutoUI.TableOfContents() + +# ╔═╡ 234b8c8e-d294-11ef-296a-3b38564babc4 +md""" +## Preliminaries + +##### Goal + +* Introduction to Bayesian (Linear) Regression + +##### Materials + +* Mandatory + + * These lecture notes + +* Optional + + * [Bishop PRML book](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf), pp. 152-158 + + * Matrix Calculus + * In this and forthcoming lectures, we will make use of some elementary matrix calculus. Please see the [Formula Cheatsheet](https://github.com/bmlip/course/blob/main/assets/files/5SSD0_formula_sheet.pdf) for formulas that will be made available to you at the written exam. + + * [RxInfer Bayesian Linear Regression example](https://examples.rxinfer.com/categories/basic_examples/bayesian_linear_regression/) + * A tutorial on Bayesian linear regression with RxInfer. + + * Jaynes (1990), [Straight Line Fitting - A Bayesian Solution](https://github.com/bmlip/course/blob/main/assets/files/Jaynes-1990-straight-line-fitting-a-Bayesian-solution.pdf) + * A fully Bayesian solution on straight line fitting with uncertainties in both ``x`` and ``y`` coordinates. + + +""" + +# ╔═╡ 234ba8c2-d294-11ef-36f6-b1f61f65557a + + +challenge_statement("Finding a Secret Function", header_level=1 ) + + + +# ╔═╡ e248df9b-0c48-4803-8d1e-b466ab07692e +begin + secret_function_bond = @bindname secret_function Select([ + (x -> sin(x * 2π)) => "sin(x * 2π)", + (x -> sign(0.4 - x)) => "sign(0.4 - x)", + (x -> x ^ 2) => "x ^ 2", + ]) +end + +# ╔═╡ f1bf64f6-09f9-45a3-acd1-7975ab9e79fc +md""" + +##### Problem + +We consider an unknown data-generating process for ``y``, + +```math +y = f(x) = \sin(2 \pi x)\,, +``` +from which we observe a set of noisy measurements of the function values ``y_n``, for a given set of inputs ``x_n``. + +Let's generate some random observations from this function. You can change the **number of observations** and the **measurement noise**. +""" + +# ╔═╡ 37f06a96-07ac-43e0-ae4d-c64db09bde76 +begin + N_bond = @bindname N Slider(1:150; show_value=true, default=13) +end + +# ╔═╡ 2baf33ce-2ffe-4c99-ab61-a0d578da5117 +begin + σ_noise_bond = @bindname σ_data_noise Slider(0.0:0.01:0.2; default=0.12, show_value=true) +end + +# ╔═╡ f2387991-2d70-46ce-950d-73a9e2c0e8db +md""" +Here is the randomly generated dataset: +""" + +# ╔═╡ 2ff8c0d7-30f5-4593-9533-fee6114a3443 +md""" +The challenge is to uncover the underlying data-generating process and predict responses for future inputs ``x_\bullet``. + +##### Solution + +To be solved [later in this lecture](#Challenge-Revisited:-Finding-a-Secret-Function). +""" + +# ╔═╡ 234c3684-d294-11ef-1c08-d9d61fc3d471 +md""" +# Bayesian Linear Regression + + +""" + +# ╔═╡ 234bb452-d294-11ef-24cb-3d171fe9cb4e +md""" +## Regression as Discriminative Learning +""" + +# ╔═╡ 234be90e-d294-11ef-2257-496f155c2b59 +md""" + +We observe ``N`` IID data **pairs** ``D=\{(x_1,y_1),\dotsc,(x_N,y_N)\}`` with ``x_n \in \mathbb{R}^M`` and ``y_n \in \mathbb{R}``. + +Assume that, based on the data set, we are interested in predicting the response ``y_\bullet`` for a new **given and fixed** input observation ``x_\bullet = a``? + +In a Bayesian (generative) modeling context, we should develop a joint model for all variables, i.e., we should develop a model ``p(y_n,x_n)``, but in this case we already know ``p(x_n) = \delta(x_n-a)``. + +Since +```math +\begin{align} +p(y_n,x_n) &= p(y_n|x_n) p(x_n) \\ + &= p(y_n|x_n) \delta(x_n-a) \,, +\end{align} +``` + +we can focus attention on developing a model for the **conditional distribution** ``p(y_n|x_n)`` only. + +Building a conditional model ``p(y_n|x_n)`` directly for outputs ``y_n`` and given inputs ``x_n``, is called the **discriminative** approach to Bayesian modelling. We will see more of this approach in the [discriminative classification lecture](https://bmlip.github.io/course/lectures/Discriminative%20Classification.html#Discriminative-Classification). + +Next, we discuss (1) model specification, (2) Inference, and (3) a prediction application for a Bayesian linear regression problem. + +""" + +# ╔═╡ 8a7af8b4-f56c-48b2-83b6-afef30bb423e +keyconcept("", "Regression problems can be formulated as the task of developing a predictive model ``p(y | x)`` for outputs ``y`` given inputs ``x``. This is referred to as the **discriminative approach** to probabilistic modeling.") + +# ╔═╡ 234c5394-d294-11ef-1614-c9847412c8fb +md""" + +## Model Specification + + +#### Data-Generating Distribution + +In a traditional *regression* model, we try to "explain the data" by a purely deterministic function ``f(x_n,w)``, plus a purely random term ``\epsilon_n`` for 'unexplained noise': + +```math + y_n = f(x_n,w) + \epsilon_n +``` + +""" + +# ╔═╡ 234c6104-d294-11ef-0a18-15e51a878079 +md""" +In a *linear regression* model, i.e., linear with respect to the parameters ``w``, we assume that + +```math +f(x_n,w)= \sum_{j=0}^{M-1} w_j \phi_j(x_n) = w^T \phi(x_n) +``` + +where ``\phi_j(x)`` are called basis functions. + +For notational simplicity, from now on we will assume ``f(x_n,w) = w^T x_n``, with ``x_n \in \mathbb{R}^M``. + +""" + +# ╔═╡ 234c7766-d294-11ef-36fa-1d2beee3dec0 +md""" +In *ordinary linear regression* , it is further assumed that the noise process ``\epsilon_n`` is zero-mean Gaussian with constant variance, i.e., + +```math +\epsilon_n \sim \mathcal{N}(0,\beta^{-1}) \,. +``` + +""" + +# ╔═╡ 2c2dd8ea-aa41-430a-9066-8c2a20ce9b71 +md""" +💡 _We model our function as a **linear combination of basis functions**. Check out this mini to learn more about this:_ +""" + +# ╔═╡ 23010dab-3e07-401a-aa09-bcba760f0894 +NotebookCard("https://bmlip.github.io/course/minis/Basis%20Functions.html") + +# ╔═╡ 234c8850-d294-11ef-3707-6722628bd9dc +md""" + +#### Likelihood Function + +For an observed data set ``D=\{(x_1,y_1),\dotsc,(x_N,y_N)\}``., the likelihood function for ``w`` is then + +```math +\begin{align*} +p(y\,|\,X,w,\beta) &= \mathcal{N}(y\,|\,X w,\beta^{-1} I) \\ + &= \prod_n \mathcal{N}(y_n\,|\,w^T x_n,\beta^{-1}) \tag{B-3.10} +\end{align*} +``` + +where ``w = \left(\begin{matrix} w_1 \\ w_2 \\ \vdots \\ w_{M} \end{matrix} \right)``, and the observed data set is represented by the ``(N\times M)``-dimensional matrix ``X = \left(\begin{matrix}x_1^T \\ x_2^T \\ \vdots \\ x_N^T \end{matrix} \right) = \left(\begin{matrix}x_{11},x_{12},\dots,x_{1M}\\ x_{21},x_{22},\dots,x_{2M} \\ \vdots \\ x_{N1},x_{N2},\dots,x_{NM} \end{matrix} \right) $ and $y = \left(\begin{matrix} y_1 \\ y_2 \\ \vdots \\ y_N \end{matrix} \right)``. + +Note that, if parameter ``\beta`` is given, then Eq. B-3.10 is a proper likelihood function for the parameters ``w``. + +""" + +# ╔═╡ 234cab14-d294-11ef-1e7c-777fc35ddbd9 +md""" +#### Prior + +For full Bayesian learning of the weights ``w``, we should also choose a prior ``p(w)``. Let's choose a Gaussian prior, + +```math +\begin{equation} +p(w\,|\,\alpha) = \mathcal{N}(w\,|\,0,\alpha^{-1}I) \,.\tag{B-3.52} +\end{equation} +``` + +For simplicity, we will assume that ``\alpha`` and ``\beta`` are fixed and known. + +""" + +# ╔═╡ 234cdca6-d294-11ef-0ba3-dd5356b65236 +md""" +## Inference for ``w`` + +We'll do Bayesian inference for the parameters ``w``. + +```math +\begin{align} +p(w|D) &\propto p(D|w)\cdot p(w) \\ + &= \mathcal{N}(y\,|\,X w,\beta^{-1} I) \cdot \mathcal{N}(w\,|\,0,\alpha^{-1} I) \\ + &\propto \exp \big( -\frac{\beta}{2} \big( {y - X w } \big)^T \big( {y - X w } \big) - \frac{\alpha}{2}w^T w \big) \tag{B-3.55} \\ + &= \exp\big( -\frac{1}{2} w^T\big(\underbrace{\beta X^T X + \alpha I}_{\Lambda_N}\big)w + \big(\underbrace{\beta X^T y}_{\eta_N}\big)^T w - \frac{\beta}{2}y^T y \big) \\ + &\propto \mathcal{N}_c\left(w\,|\,\eta_N,\Lambda_N \right) +\end{align} +``` + +with natural parameters (see the [natural parameterization of Gaussian](https://bmlip.github.io/course/lectures/The%20Gaussian%20Distribution.html#natural-parameterization)): + +```math +\begin{align*} +\eta_N &= \beta X^T y \\ +\Lambda_N &= \beta X^T X + \alpha I +\end{align*} +``` + +Or equivalently (in the [moment parameterization of the Gaussian](https://bmlip.github.io/course/lectures/The%20Gaussian%20Distribution.html#The-Moment-Parameterization)): + +```math +\begin{align*} +p(w|D) &= \mathcal{N}\left(w\,|\,m_N,S_N \right) \tag{B-3.49} \\ +m_N &= \beta S_N X^T y \tag{B-3.53}\\ +S_N &= \left(\alpha I + \beta X^T X\right)^{-1} \tag{B-3.54} +\end{align*} +``` + +Note that Eqs. B-3.53 and B-3.54 combine to + +```math +m_N = \left(\frac{\alpha}{\beta}I + X^T X \right)^{-1} X^T y\,, +``` +which comprises only given variables, so ``m_N`` evaluates to a fixed vector. +""" + +# ╔═╡ 234d6dd8-d294-11ef-3abf-8d6cb00b1907 +md""" +## Application: Predicting Future Data Points + +Assume we are interested in the distribution ``p(y_\bullet \,|\, x_\bullet, D)`` for a new input ``x_\bullet``. This can be worked out to + +```math +\begin{align*} +p(y_\bullet \,|\, x_\bullet, D) &= \int p(y_\bullet \,|\, x_\bullet, w) p(w\,|\,D)\,\mathrm{d}w \\ +&= \int \mathcal{N}(y_\bullet \,|\, w^T x_\bullet, \beta^{-1}) \mathcal{N}(w\,|\,m_N,S_N)\,\mathrm{d}w \\ +&= \mathcal{N}\left(y_\bullet\,|\, m_N^T x_\bullet, \sigma_N^2(x_\bullet) \right) +\end{align*} +``` + +where + +```math +\begin{align*} +m_N &= \beta S_N X^T y \tag{B-3.53}\\ +S_N &= \left(\alpha I + \beta X^T X\right)^{-1} \tag{B-3.54} \\ +\sigma_N^2(x_\bullet) &= \beta^{-1} + x^T_\bullet S_N x_\bullet \tag{B-3.59} +\end{align*} +``` + +Thus, the uncertainty ``\sigma_N^2(x_\bullet)`` about the output ``y_\bullet`` contains both uncertainty about the generative process (through ``\beta^{-1}``), and uncertainty about the weights (through ``x^T_\bullet S_N x_\bullet``). + +""" + +# ╔═╡ ab3baeb4-51d7-4f50-9e06-ed00bb783ebd +details("details of the derivation", +md""" + ```math +\begin{align*} +p(y_\bullet \,|\, x_\bullet, D) &= \int p(y_\bullet \,|\, x_\bullet, w) p(w\,|\,D)\,\mathrm{d}w \\ +&= \int \mathcal{N}(y_\bullet \,|\, w^T x_\bullet, \beta^{-1}) \mathcal{N}(w\,|\,m_N,S_N)\,\mathrm{d}w \\ +&= \int \mathcal{N}(y_\bullet \,|\, z, \beta^{-1}) \underbrace{\mathcal{N}(z\,|\,x_\bullet^T m_N,x_\bullet^T S_N x_\bullet)\,\mathrm{d}z}_{=\mathcal{N}(w\,|\,m_N,S_N)\,\mathrm{d}w} \quad \text{(sub. }z=x_\bullet^T w \text{)} \\ +&= \int \underbrace{\underbrace{\mathcal{N}(z \,|\, y_\bullet, \beta^{-1})}_{\text{switch }z \text{ and }y_\bullet} \mathcal{N}(z\,|\,x_\bullet^T m_N,x_\bullet^T S_N x_\bullet)}_{\text{Use Gaussian product formula}}\,\mathrm{d}z \\ +&= \int \mathcal{N}\left(y_\bullet\,|\, m_N^T x_\bullet, \sigma_N^2(x_\bullet) \right) \underbrace{\mathcal{N}\left(z\,|\, \cdot, \cdot\right)}_{\text{integrate this out}} \mathrm{d}z\\ +&= \mathcal{N}\left(y_\bullet\,|\, m_N^T x_\bullet, \sigma_N^2(x_\bullet) \right) +\end{align*} +``` + +where + + ```math +\begin{align*} +m_N &= \beta S_N X^T y \tag{B-3.53}\\ +S_N &= \left(\alpha I + \beta X^T X\right)^{-1} \tag{B-3.54} \\ +\sigma_N^2(x_\bullet) &= \beta^{-1} + x^T_\bullet S_N x_\bullet \tag{B-3.59} +\end{align*} +``` + +In the above derivation, the substitution of ``\mathcal{N}(w\,|\,m_N,S_N)\,\mathrm{d}w`` by ``\mathcal{N}(z\,|\,x_\bullet^T m_N,x_\bullet^T S_N x_\bullet)\,\mathrm{d}z`` is tricky, and depends on the [change-of-variables theorem](https://bmlip.github.io/course/lectures/Probability%20Theory%20Review.html#General-Variable-Transformations): + +Since ``z = x^T w`` (drop the bullet for notational simplicity), we have + +```math +p(z) = \mathcal{N}(z|m_z,\Sigma_z) +``` + +with + +```math +\begin{aligned} m_z &:= E[z] = E[x^T w] = x^T E[w] = x^T m_N \\ \Sigma_z &:= E[(z-m_z)(z-m_z)^T] \\   &= E[(x^T w - x^T m_N)(x^T w - x^T m_N)^T] \\   &= x^T E[(w - m_N)(w - m_N)^T]x \\   &= x^T S_N x \end{aligned} +``` + +Then we equate probability masses in both domains: + +```math + \mathcal{N}(z|m_z,\Sigma_z)\mathrm{d}z = \mathcal{N}(w|m_N,S_N)\mathrm{d}w +``` + +```math + \Rightarrow \mathcal{N}(z|x^T m_N,x^T S_N x)\mathrm{d}z = \mathcal{N}(w|m_N,S_N)\mathrm{d}w +``` + +""" + ) + +# ╔═╡ fb113692-f00c-4b48-85cc-d7bba88c7099 +keyconcept("", md"For an ordinary linear regression task, with inputs ``x``, outputs ``y``, and weights ``w``, placing a Gaussian prior on the weights ``w`` leads to both a Gaussian posterior over the weights and a Gaussian predictive distribution for the outputs. Importantly, both distributions can be computed in closed form. ") + +# ╔═╡ f600c228-e048-42aa-b79a-60592b367dec +challenge_solution("Finding a Secret Function" , color="green", header_level=1) + +# ╔═╡ c0c57aa6-155a-49a9-9ed2-d568de1b5be2 +md""" +We can use this model to approximate the secret function! Let's see it in action: +""" + +# ╔═╡ b48b93c3-1ff2-4be0-8fad-181035f3e50e +md""" +We also have a _prior_ for the weights: ``w \sim \mathcal{N}(0,σ_{prior}^2)``: +""" + +# ╔═╡ 3fe01c67-6f95-4f6d-8c7f-5a389272ff65 +@bindname σ_prior² Slider([(2.0 .^ (-14:2))..., 1e10]; show_value=true, default=0.5) + +# ╔═╡ 018b6c7b-36bc-4867-a058-3802b43fd1eb + + +# ╔═╡ 90cb881a-7b5d-44e3-a7d1-bb93bef4a82b +md""" +## Implementation Issues + +#### Basic functions + +See the [Mini about Basis Functions](https://bmlip.github.io/course/minis/Basis%20Functions.html) to learn more! +""" + +# ╔═╡ 142f4700-ccf4-4019-b3a9-57035c458276 +σ_basis² = 0.01; + +# ╔═╡ 70ca3a3f-ee1c-4f3d-9d77-bf55e8e808c1 +μ_basis = range(0.0, 1.0; length=10); + +# ╔═╡ 3a3b7ff2-68aa-411c-b7fb-c6cd00d0dd7b +ϕ(μ, x) = exp(-(x - μ)^2 / σ_basis²); + +# ╔═╡ 290bc994-d0f9-4af3-bd63-78de1640c85c +function f(w, x) + sum(enumerate(μ_basis)) do (i, μ) + w[i] * ϕ(μ, x) + end +end; + +# ╔═╡ 4d2be102-8849-4b8d-9962-8b45099ab8f2 +md""" +#### Bayesian inference +We have a closed-form solution for the posterior: +""" + +# ╔═╡ ec0ccf94-e12e-422d-b4d2-dcb933453146 +md""" +# Special Cases +""" + +# ╔═╡ 234da212-d294-11ef-1fdc-c38e13cb41db +md""" +## Maximum Likelihood Estimation for Linear Regression Model + +Recall the posterior mean for the weight vector + +```math +m_N = \left(\frac{\alpha}{\beta}I + X^T X \right)^{-1} X^T y +``` + +where ``\alpha`` is the prior precision for the weights. + +""" + +# ╔═╡ 234dab5e-d294-11ef-30b4-39c5e05dfb31 +md""" +The Maximum Likelihood solution for ``w`` is obtained by letting ``\alpha \rightarrow 0``, which leads to + +```math +\begin{equation*} +\hat w_{\text{ML}} = (X^T X)^{-1} X^T y +\end{equation*} +``` + +""" + +# ╔═╡ 234dbda6-d294-11ef-05fe-bd3d1320470a +md""" +The matrix ``X^\dagger \equiv (X^T X)^{-1}X^T`` is also known as the **Moore-Penrose pseudo-inverse** (which is sort-of-an-inverse for non-square matrices). + +""" + +# ╔═╡ 234dc704-d294-11ef-158b-a9ae9e157251 +md""" +Note that if we have fewer training samples than input dimensions, i.e., if ``N f(w, x); + opacity=.3, + color=2, + label=i==1 ? "Posterior samples" : nothing, + ) + end + end + + plot_data!(D) +end + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[compat] +BmlipTeachingTools = "~1.3.1" +Distributions = "~0.25.122" +LaTeXStrings = "~1.4.0" +Plots = "~1.40.17" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "dcda262a8eaf03d120df81abad0b16c73eab2a8d" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─234b77a8-d294-11ef-15d5-ff54ed5bec1e +# ╟─66998cd5-78d6-4b22-a9c9-886436cba4dd +# ╟─234b8c8e-d294-11ef-296a-3b38564babc4 +# ╟─234ba8c2-d294-11ef-36f6-b1f61f65557a +# ╟─e248df9b-0c48-4803-8d1e-b466ab07692e +# ╟─f1bf64f6-09f9-45a3-acd1-7975ab9e79fc +# ╟─37f06a96-07ac-43e0-ae4d-c64db09bde76 +# ╟─2baf33ce-2ffe-4c99-ab61-a0d578da5117 +# ╟─f2387991-2d70-46ce-950d-73a9e2c0e8db +# ╟─72fcb6a3-36ee-4840-bdc3-ddb743e5c149 +# ╟─5d48e25f-9a98-43ce-8f23-d9ab28f69996 +# ╟─2ff8c0d7-30f5-4593-9533-fee6114a3443 +# ╟─234c3684-d294-11ef-1c08-d9d61fc3d471 +# ╟─234bb452-d294-11ef-24cb-3d171fe9cb4e +# ╟─234be90e-d294-11ef-2257-496f155c2b59 +# ╟─8a7af8b4-f56c-48b2-83b6-afef30bb423e +# ╟─234c5394-d294-11ef-1614-c9847412c8fb +# ╟─234c6104-d294-11ef-0a18-15e51a878079 +# ╟─234c7766-d294-11ef-36fa-1d2beee3dec0 +# ╟─2c2dd8ea-aa41-430a-9066-8c2a20ce9b71 +# ╟─23010dab-3e07-401a-aa09-bcba760f0894 +# ╟─234c8850-d294-11ef-3707-6722628bd9dc +# ╟─234cab14-d294-11ef-1e7c-777fc35ddbd9 +# ╟─234cdca6-d294-11ef-0ba3-dd5356b65236 +# ╟─234d6dd8-d294-11ef-3abf-8d6cb00b1907 +# ╟─ab3baeb4-51d7-4f50-9e06-ed00bb783ebd +# ╟─fb113692-f00c-4b48-85cc-d7bba88c7099 +# ╟─f600c228-e048-42aa-b79a-60592b367dec +# ╟─c0c57aa6-155a-49a9-9ed2-d568de1b5be2 +# ╟─9fd4a9b4-3296-4fe3-931f-17744bc4df81 +# ╟─b48b93c3-1ff2-4be0-8fad-181035f3e50e +# ╟─3fe01c67-6f95-4f6d-8c7f-5a389272ff65 +# ╟─f9a5c91e-12be-4e8b-930d-74e46e39ea58 +# ╟─018b6c7b-36bc-4867-a058-3802b43fd1eb +# ╟─90cb881a-7b5d-44e3-a7d1-bb93bef4a82b +# ╠═142f4700-ccf4-4019-b3a9-57035c458276 +# ╠═70ca3a3f-ee1c-4f3d-9d77-bf55e8e808c1 +# ╠═3a3b7ff2-68aa-411c-b7fb-c6cd00d0dd7b +# ╠═290bc994-d0f9-4af3-bd63-78de1640c85c +# ╟─4d2be102-8849-4b8d-9962-8b45099ab8f2 +# ╠═98d729ab-79f8-4a0f-9db5-387f488fc19d +# ╠═8a2730b8-3262-48cc-81f0-777cf85b9836 +# ╟─ec0ccf94-e12e-422d-b4d2-dcb933453146 +# ╟─234da212-d294-11ef-1fdc-c38e13cb41db +# ╟─234dab5e-d294-11ef-30b4-39c5e05dfb31 +# ╟─234dbda6-d294-11ef-05fe-bd3d1320470a +# ╟─234dc704-d294-11ef-158b-a9ae9e157251 +# ╟─234ddbd8-d294-11ef-1cb3-d15a8ffe31a8 +# ╟─234df3ca-d294-11ef-08d9-65d1a42b3fcb +# ╟─234e0a18-d294-11ef-1713-1d7ef92d6ba5 +# ╟─234e1f6c-d294-11ef-149a-1785e7fd2901 +# ╟─234e3470-d294-11ef-35f6-bb410b10dfad +# ╟─234e492e-d294-11ef-327a-2bd72cfeccae +# ╟─234e617a-d294-11ef-1ce4-fd2e1ebf33a1 +# ╟─234e75c0-d294-11ef-0b53-bb3518de0d77 +# ╟─c2b63afc-3528-4ea9-af8c-1266f2091256 +# ╟─234e89d2-d294-11ef-238a-73aac596dbeb +# ╟─691429de-2966-485e-8123-cbcb20c7f218 +# ╟─234ec962-d294-11ef-1033-7b1599057825 +# ╟─b6443a13-9301-4559-a5c3-396bae2a27b9 +# ╟─234ef126-d294-11ef-17a9-3da87a7e7d0a +# ╟─e9804f92-29b0-4463-bf37-872183061ee2 +# ╟─234f5d32-d294-11ef-279f-f331396e47ad +# ╟─9577225a-9ce3-4cf2-ac63-499ae8e905bd +# ╟─70ddbde1-5de4-4bc0-ace0-9414ac616888 +# ╟─8e2b2c1d-81f3-4283-ae2e-d8b3e9c201b3 +# ╟─bbb461b0-d1eb-4584-89b0-96af3e615484 +# ╟─2705ce62-baea-484d-a7fe-6f284a4a8f71 +# ╟─d92d1dd3-736b-4911-a8d8-dcf7a297f48d +# ╟─d8e384c8-fe26-47c3-a7d4-04ae4c592ee5 +# ╟─234f7254-d294-11ef-316a-05ef2edb9699 +# ╟─c6532830-3161-4b2a-97c4-6d27d24762c9 +# ╠═f8c69b91-4415-454e-a50d-c4a37ada89d1 +# ╠═33ca4c67-d96f-457f-bc19-171f4b4b03c6 +# ╠═3ff2bd04-1490-4be6-8b26-b82d1902bb07 +# ╟─22e76656-b9f4-463e-9bf8-bd383e92948b +# ╟─338ee8e9-b786-48e1-b084-a0e8a6d12118 +# ╟─0e9435fc-3206-4249-b5ff-42cc35c98d47 +# ╟─88a2bd82-6663-48cc-a535-5b3e47d814a9 +# ╟─68141653-e444-4e29-bbec-4cd7359cb84c +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/archive/The Gaussian Distribution.jl b/mlss/archive/The Gaussian Distribution.jl new file mode 100644 index 00000000..59db4e76 --- /dev/null +++ b/mlss/archive/The Gaussian Distribution.jl @@ -0,0 +1,3350 @@ +### A Pluto.jl notebook ### +# v0.20.21 + +#> [frontmatter] +#> image = "https://github.com/bmlip/course/blob/v2/assets/figures/fig-linear-system.png?raw=true" +#> description = "Review of information processing with Gaussian distributions in linear systems." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). +macro bind(def, element) + #! format: off + return quote + local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end + local el = $(esc(element)) + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el) + el + end + #! format: on +end + +# ╔═╡ 9edd80d4-d088-4b2f-8843-abaa7a5d9c5e +using Random + +# ╔═╡ 5638c1d0-db95-49e4-bd80-528f79f2947e +using HCubature, LinearAlgebra# Numerical integration package + +# ╔═╡ 03a36e87-2378-4efc-bcac-9c0609b52784 +using MarkdownLiteral: @mdx + +# ╔═╡ c97c495c-f7fe-4552-90df-e2fb16f81d15 +using BmlipTeachingTools + +# ╔═╡ 3ec821fd-cf6c-4603-839d-8c59bb931fa9 +using Distributions, Plots, LaTeXStrings + +# ╔═╡ 00482666-0772-4e5d-bb35-df7b6fb67a1b +using SpecialFunctions + +# ╔═╡ b9a38e20-d294-11ef-166b-b5597125ed6d +title("Continuous Data and the Gaussian Distribution") + +# ╔═╡ 5e9a51b1-c6e5-4fb5-9df3-9b189f3302e8 +PlutoUI.TableOfContents() + +# ╔═╡ b9a46c3e-d294-11ef-116f-9b97e0118e5b +md""" +## Preliminaries + +##### Goal + + * Review of information processing with Gaussian distributions in linear systems + +##### Materials + + * Mandatory + + * These lecture notes + * Optional + + * [Bishop PRML book](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf) (2006), pp. 85-93 + + * [MacKay - 2006 - The Humble Gaussian Distribution](https://github.com/bmlip/course/blob/main/assets/files/Mackay-2006-The-humble-Gaussian-distribution.pdf) (highly recommended!) + * [Ariel Caticha - 2012 - Entropic Inference and the Foundations of Physics](https://github.com/bmlip/course/blob/main/assets/files/Caticha-2012-Entropic-Inference-and-the-Foundations-of-Physics.pdf), pp.30-34, section 2.8, the Gaussian distribution + * References + + * [E.T. Jaynes - 2003 - The central, Gaussian or normal distribution, ch.7 in: Probability Theory, The Logic of Science](https://github.com/bmlip/course/blob/main/assets/files/Jaynes%20-%202003%20-%20Probability%20theory%20-%20ch-7%20-%20Gaussian%20distribution.pdf) (Very insightful chapter in Jaynes' book on the Gaussian distribution.) + +""" + +# ╔═╡ 8e436806-af9d-4aa4-88a4-d37e10b69c36 +challenge_statement("Gaussian Density Estimation",header_level=1) + +# ╔═╡ b9a48c60-d294-11ef-3b90-03053fcd82fb +md""" + +Consider a data set as shown in the figure below + +""" + + +# ╔═╡ 3200f4f9-4c43-46c0-8bdb-9afc95d116e0 +md""" + +##### Setup + +We have a dataset `D` of observations. `D` is a Matrix, where each column is an observation ``\in \mathbb{R}^2``: +""" + +# ╔═╡ 4e6c4e40-f744-49e7-9d67-cf982c9fc58d +md""" +We now draw an extra observation ``x_\bullet = (a,b)`` from the same data-generating process: +""" + +# ╔═╡ 148f82be-5012-4c12-9002-6a8bcbf5ad08 +md""" +``D`` and ``x_\bullet`` are shown in the plot above. +""" + +# ╔═╡ b1b9bc8f-2653-42af-ad49-6aaaba2ae70e + + +# ╔═╡ c2208520-020b-400a-8bb4-c8fb6786ccf3 +md""" +##### Problem + +What is the probability that ``x_\bullet`` lies within the shaded rectangle ``S = \{ (x,y) \in \mathbb{R}^2 | 0 \leq x \leq 2, 1 \leq y \leq 2 \} ``? +""" + +# ╔═╡ 3d05a2eb-87aa-4d6a-9caf-feb5758e000a +S = [[0.0, 2.0], [1.0, 2.0]] + +# ╔═╡ 55380883-d269-4f61-bec6-2944765db271 + + +# ╔═╡ 02853a5c-f6aa-4af8-8a25-bfffd4b96afc +md""" + +##### Solution + +- See [later in this lecture](#Challenge-Revisited:-Gaussian-Density-Estimation). +""" + +# ╔═╡ 71f1c8ee-3b65-4ef8-b36f-3822837de410 +md""" +# The Gaussian Distribution +""" + +# ╔═╡ b9a4eb62-d294-11ef-06fa-af1f586cbc15 +md""" +## The Moment Parameterization + +Consider a random (vector) variable ``x \in \mathbb{R}^M`` that is "normally" (i.e., Gaussian) distributed. The *moment* parameterization of the Gaussian distribution is completely specified by its *mean* ``\mu`` and *variance* ``\Sigma`` parameters, and given by + +```math +p(x | \mu, \Sigma) = \mathcal{N}(x|\mu,\Sigma) \triangleq \frac{1}{\sqrt{(2\pi)^M |\Sigma|}} \,\exp\left(-\frac{1}{2}(x-\mu)^T \Sigma^{-1} (x-\mu) \right)\,, +``` + +where ``|\Sigma| \triangleq \mathrm{det}(\Sigma)`` is the determinant of ``\Sigma``. + +For a scalar real variable ``x \in \mathbb{R}``, this works out to + +```math +p(x | \mu, \sigma^2) = \frac{1}{\sqrt{2\pi\sigma^2 }} \,\exp\left(-\frac{(x-\mu)^2}{2 \sigma^2} \right)\,. +``` + +It is common to write the (scalar) variance parameter as `` \sigma^2 `` to emphasize that the variance is non-negative. + +""" + +# ╔═╡ b9a50d0c-d294-11ef-0e60-2386cf289478 +md""" + +## The Canonical (Natural) Parameterization + +Alternatively, the $(HTML(""))*canonical* (a.k.a. *natural* or *information* ) parameterization of the Gaussian distribution is given by + +```math +\begin{equation*} +p(x | \eta, \Lambda) = \mathcal{N}_c(x|\eta,\Lambda) = \exp\left( a + \eta^T x - \frac{1}{2}x^T \Lambda x \right) \,, +\end{equation*} +``` +where +```math +a = -\frac{1}{2} \left( M \log(2 \pi) - \log |\Lambda| + \eta^T \Lambda \eta\right) +``` + +is the *normalizing* constant that ensures that ``\int p(x)\mathrm{d}x = 1``, and + +```math +\Lambda = \Sigma^{-1} +``` + +is called the *precision* matrix. The parameter + +```math +\eta = \Sigma^{-1} \mu +``` + +is the *natural* mean, or for clarity, often called the *precision-weighted* mean. + +The Gaussian distribution can be expressed in both moment and natural parameterizations, which are mathematically equivalent but differ in how the parameters are defined. + +""" + +# ╔═╡ b9a52b18-d294-11ef-2d42-19c5e3ef3549 +md""" +## Why the Gaussian? +""" + +# ╔═╡ b9a5589a-d294-11ef-3fc3-0552a69df7b2 +md""" + +Why is the Gaussian distribution so ubiquitously used in science and engineering? + +1. Operations on probability distributions tend to lead to Gaussian distributions: + + * Any smooth function with a single rounded maximum goes into a Gaussian function, if raised to higher and higher powers. This is particularly useful in sequential Bayesian inference where repeated updates leads to Gaussian posteriors. (See also this [tweet](https://x.com/Almost_Sure/status/1745480056288186768)). + * The [Gaussian distribution has higher entropy](https://en.wikipedia.org/wiki/Differential_entropy#Maximization_in_the_normal_distribution) than any other with the same variance. + * Therefore, any operation on a probability distribution that discards information but preserves variance gets us closer to a Gaussian. + * As an example, see [Jaynes, section 7.1.4](https://github.com/bmlip/course/blob/main/assets/files/Jaynes%20-%202003%20-%20Probability%20theory%20-%20ch-7%20-%20Gaussian%20distribution.pdf) for how this leads to the [Central Limit Theorem](https://en.wikipedia.org/wiki/Central_limit_theorem), which results from performing convolution operations on distributions. + + +2. Once the Gaussian has been attained, this form tends to be preserved. e.g., + + * The convolution of two Gaussian functions is another Gaussian function (useful in the sum of 2 variables and linear transformations) + * The product of two Gaussian functions is another Gaussian function (useful in Bayes rule). + * The Fourier transform of a Gaussian function is another Gaussian function. + +See also [Jaynes, section 7.14](https://github.com/bmlip/course/blob/main/assets/files/Jaynes%20-%202003%20-%20Probability%20theory%20-%20ch-7%20-%20Gaussian%20distribution.pdf), and the whole chapter 7 in his book for more details on why the Gaussian distribution is so useful. + +""" + +# ╔═╡ 085233ee-f5ad-4731-89bb-84773182bba6 +keyconcept("", +md""" +Why is the Gaussian distribution so ubiquitously used in science and engineering? + + - Operations on probability distributions tend to lead to Gaussian distributions. + - Once the Gaussian has been attained, this form tends to be preserved. + +""") + +# ╔═╡ 9501922f-b928-46e2-8f23-8eb9c64f6198 +md""" +# Computing with Gaussians +""" + +# ╔═╡ b9a5889c-d294-11ef-266e-d90225222e10 +md""" +## Linear Transformations of Gaussian Variables + +As shown in the [probability theory lecture](https://bmlip.github.io/course/lectures/Probability%20Theory%20Review.html#linear-transformation), under the linear transformation + +```math +z = Ax + b \,, +``` +for given ``A`` and ``b``, the mean and covariance of ``z`` are given by ``\mu_z = A\mu_x + b`` and ``\Sigma_z = A\Sigma_x A^\top``, regardless of the distribution of ``x``. + +Since a Gaussian distribution is fully specified by its mean and covariance matrix, it follows that a linear transformation ``z=Ax+b`` of a Gaussian variable ``x \sim \mathcal{N}(\mu_x,\Sigma_x)`` is Gaussian distributed as + +```math +p(z) = \mathcal{N} \left(z \,|\, A\mu_x+b, A\Sigma_x A^T \right) \,. +``` + +In case ``x`` is not Gaussian, higher order moments may be needed to specify the distribution for ``z``. + + +""" + +# ╔═╡ 56510a09-073c-4fc8-b0b7-17b20dbb95f0 +section_outline("Exercises:", "Linear Transformations" , color= "yellow" ) + +# ╔═╡ a82378ae-d1be-43f9-b63a-2f897767d1fb +md""" +##### The Sum of Gaussian Variables + +A commonly occurring example of a linear transformation is the *sum of two independent Gaussian variables*: + +Let ``x \sim \mathcal{N} \left(\mu_x, \sigma_x^2 \right)`` and ``y \sim \mathcal{N} \left(\mu_y, \sigma_y^2 \right)``. Prove that the PDF for ``z=x+y`` is given by + +```math +p(z) = \mathcal{N} \left(z\,|\,\mu_x+\mu_y, \sigma_x^2 +\sigma_y^2 \right) +``` + + +""" + +# ╔═╡ 36eff7bc-72f2-4b48-a109-1861af6834aa +hide_proof( +md""" +First, recognize that ``z=x+y`` can be written as a linear transformation ``z=A w``, where +```math +A = \begin{bmatrix} 1 & 1\end{bmatrix} +``` +and +```math +w = \begin{bmatrix} x \\ y\end{bmatrix} \sim \mathcal{N}\left( \begin{bmatrix} \mu_x \\ \mu_y\end{bmatrix}, \begin{bmatrix} \sigma_x^2 & 0 \\ 0 & \sigma_y^2\end{bmatrix}\right) \,. +``` + +Making use of the above formula for linear transformations, it follows that +```math +\begin{align*} +p(z) &= \mathcal{N}\big(z\,\big|\,A \mu_w, A \Sigma_w A^T \big) \\ + &= \mathcal{N}\bigg(z\, \bigg|\,\begin{bmatrix} 1 & 1 \end{bmatrix} \begin{bmatrix} \mu_x \\ \mu_y \end{bmatrix}, \begin{bmatrix} 1 & 1 \end{bmatrix} \begin{bmatrix} \sigma_x^2 & 0 \\ 0 & \sigma_y^2 \end{bmatrix} \begin{bmatrix} 1 \\ 1 \end{bmatrix} \bigg) \\ + &= \mathcal{N} \left(z\,|\,\mu_x+\mu_y, \sigma_x^2 +\sigma_y^2 \right) +\end{align*} +``` + """ + ) + +# ╔═╡ 87f400ac-36f2-4778-a3ba-06dd7652e279 +md""" +Following the example above, now compute the PDF for ``z`` if ``x`` and ``y`` were *dependent* Gaussian variables? +""" + +# ╔═╡ 9c2bf0a2-4bb6-4769-b47b-6a02c4e73044 +hide_solution( +md""" +In this case, we assume that +```math +w = \begin{bmatrix} x \\ y\end{bmatrix} \sim \mathcal{N}\Big( \begin{bmatrix} x \\ y\end{bmatrix}, \begin{bmatrix} \sigma_x^2 & \sigma_{xy} \\ \sigma_{xy} & \sigma_y^2\end{bmatrix}\Big) \,. +``` +This leads to +```math +\begin{align*} +p(z) &= \mathcal{N}\big(z\,\big|\,A \mu_w, A \Sigma_w A^T \big) \\ + + &= \mathcal{N} \left(z\,|\,\mu_x+\mu_y, \sigma_x^2 +\sigma_y^2 + 2\sigma_{xy} \right) +\end{align*} +``` + """ + ) + +# ╔═╡ 8f7ecb91-d251-4ac9-bb32-0dd7215382e3 +md""" + +Consequently, the sum of two independent Gaussian random variables remains Gaussian, with its mean given by the sum of the means and its variance given by the sum of the variances. + +A common mistake is to confuse the *sum of two Gaussian-distributed variables*, which remains Gaussian-distributed (see above), with the *sum of two Gaussian distributions*, which is typically not a Gaussian distribution. +""" + +# ╔═╡ 1df7a10d-c4f6-40d6-8f5a-cbd79ef1d415 +TwoColumn( +md""" +#### Gaussian Signals in a Linear System (**) + +Given independent variables ``x \sim \mathcal{N}(\mu_x, \sigma_x^2)`` and ``y \sim \mathcal{N}(\mu_y, \sigma_x^y)``, what is the PDF for + +```math +z =a \cdot (x-y) + b \,\text{?} +``` + +""", +@htl """ + + + +""") + +# ╔═╡ 673360e8-27ed-471c-a866-15af550df5e7 +hide_solution( +md""" + + +Let ``z \sim \mathcal{N}(\mu_z, \sigma_z^2)``. We proceed by working out the mean and variance for ``z`` explicitly, yielding + + +```math +\begin{align} +\mu_z &= \mathrm{E}\left[ z\right] \\ +&= \mathrm{E}\left[ a\cdot(x -y) + b\right] \\ +&= a\cdot\mathrm{E}\left[ (x -y)\right] + b \\ +&= a\cdot(\mu_x -\mu_y) + b +\end{align} +``` +and +```math +\begin{align} +\sigma_z^2 &= \mathrm{E}\left[ (z-\mu_z)(z-\mu_z)^T\right] \\ +&= \mathrm{E}\left[ a\cdot \big( (x - \mu_x) - (y - \mu_y) \big) \big( (x - \mu_x) - (y - \mu_y) \big)^T \cdot a^T\right] \\ +&= a\cdot(\sigma_x^2 - 2 \underbrace{\sigma_{xy}}_{-0} + \sigma_y^2) \cdot a^T \\ +&= a^2\cdot(\sigma_x^2 + \sigma_y^2) +\end{align} +``` + + + + """ + ) + +# ╔═╡ 9eb3e920-fab5-4a6a-8fe1-5734ebc6b25c +md""" +# Maximum Likelihood Estimation +""" + +# ╔═╡ 883e8244-270e-4c6c-874b-b69d8989c24c + +md""" + +## MLE for a Gaussian + +We are given an IID data set ``D = \{x_1,x_2,\ldots,x_N\}``, where ``x_n \in \mathbb{R}^M``. Assume that the data were drawn from a multivariate Gaussian (MVG) + +```math +p(x_n|\theta) = \mathcal{N}(x_n|\,\mu,\Sigma) \,. +``` + +Let us derive the maximum likelihood estimates for the parameters ``\mu`` and ``\Sigma``. +""" + +# ╔═╡ f02aa0b1-2261-4f65-9bd0-3be33230e0d6 +md""" + +##### Evaluation of log-likelihood function +Let ``\theta =\{\mu,\Sigma\}``. Prove that the log-likelihood (LLH) function ``\log p(D|\theta)`` can be worked out to + +```math +\log p(D|\theta) = + \frac{N}{2}\log |\Sigma|^{-1} - \frac{1}{2}\sum_n (x_n-\mu)^T \Sigma^{-1}(x_n-\mu) + \mathrm{const.} + +``` + +""" + +# ╔═╡ f008a742-6900-4e18-ab4e-b5da53fb64a6 +hide_proof( + md""" +Hint: it may be helpful here to use the matrix calculus rules from the [5SSD0 Formula Sheet](https://github.com/bmlip/course/blob/main/assets/files/5SSD0_formula_sheet.pdf). + + ```math +\begin{align*} +\log p(D|\theta) &= \log \prod_n p(x_n|\theta) \\ + &= \log \prod_n \mathcal{N}(x_n|\mu, \Sigma) \\ +&= \log \prod_n (2\pi)^{-M/2} |\Sigma|^{-1/2} \exp\left\{ -\frac{1}{2}(x_n-\mu)^T \Sigma^{-1}(x_n-\mu)\right\} \\ +&= \sum_n \left( \log (2\pi)^{-M/2} + \log |\Sigma|^{-1/2} -\frac{1}{2}(x_n-\mu)^T \Sigma^{-1}(x_n-\mu)\right) \\ +&= \frac{N}{2}\log |\Sigma|^{-1} - \frac{1}{2}\sum_n (x_n-\mu)^T \Sigma^{-1}(x_n-\mu) + \mathrm{const.} +\end{align*} +``` +""" ) + +# ╔═╡ 75e35350-af22-42b1-bb55-15e16cb9c375 +md""" +##### Maximum likelihood estimate of mean + +Prove that the maximum likelihood estimate of the mean is given by +```math +\hat{\mu} = \frac{1}{N}\sum_n x_n \,. +``` + +""" + +# ╔═╡ 8d2732e8-479f-4744-9b1f-d0364f0c6488 +hide_proof( +md""" +```math +\begin{align*} +\nabla_{\mu} \log p(D|\theta) &\propto - \sum_n \nabla_{\mu} \left(x_n-\mu \right)^T\Sigma^{-1}\left(x_n-\mu \right) \\ +&= - \sum_n \nabla_{\mu} \left(-2 \mu^T\Sigma^{-1}x_n + \mu^T \Sigma^{-1}\mu \right) \\ +&= - \sum_n \left(-2 \Sigma^{-1}x_n + 2\Sigma^{-1}\mu \right) \\ +&= -2 \Sigma^{-1} \sum_n (x_n - \mu) \\ +&= -2 \Sigma^{-1} \Big( \sum_n x_n - N \mu \Big) +\end{align*} +``` + +Since the map ``Ax=0`` for invertible ``A`` can only be true if ``x=0``, it follows that setting the gradient to ``0`` leads to +```math + \hat{\mu} = \frac{1}{N}\sum_n x_n \,. +``` + +""") + +# ╔═╡ 0f9feb8d-971e-4a94-8c70-3e1f0d284314 +md""" +##### Maximum likelihood estimate of variance + +The gradient of the LLH with respect to the variance ``\Sigma`` is a bit more involved. It's actually easier to estimate ``\Sigma`` by taking the derivative to the precision. Compute ``\nabla_{\Sigma^{-1}} \log p(D|\theta)``, and show that the maximum likelihood estimate for ``\Sigma`` is given by + +```math +\hat{\Sigma} = \frac{1}{N}\sum_n (x_n-\hat{\mu}) (x_n-\hat{\mu})^T +``` +""" + + +# ╔═╡ 2767b364-6f9a-413d-aa9e-88741cd2bbb1 +hide_proof( +md""" +```math +\begin{align*} +\nabla_{\Sigma^{-1}} \log p(D|\theta) &= \nabla_{\Sigma^{-1}} \left( \frac{N}{2} \log |\Sigma| ^{-1} -\frac{1}{2}\sum_n (x_n-\mu)^T +\Sigma^{-1} (x_n-\mu)\right) \\ +&= \nabla_{\Sigma^{-1}} \left( \frac{N}{2} \log |\Sigma| ^{-1} - \frac{1}{2}\sum_n \mathrm{Tr}\left[(x_n-\mu) +(x_n-\mu)^T \Sigma^{-1} \right]\right) \\ +&=\frac{N}{2}\Sigma - \frac{1}{2}\sum_n (x_n-\mu) +(x_n-\mu)^T +\end{align*} +``` + +Setting the derivative to zero leads to ``\hat{\Sigma} = \frac{1}{N}\sum_n (x_n-\hat{\mu}) +(x_n-\hat{\mu})^T``. + +""") + + +# ╔═╡ c6753ff3-7b5e-45b8-8adc-e0bbaa6be7d3 +md""" +# Simple Bayesian Inference +""" + +# ╔═╡ b9a5cbc2-d294-11ef-214a-c71fb1272326 +md""" +## Bayesian Inference for Estimation of a Constant + +##### Problem + +Let's estimate a constant ``\theta`` from one ''noisy'' measurement ``x`` about that constant. + +We assume the following measurement equations (the tilde ``\sim`` means: 'is distributed as'): + +```math +\begin{align*} +x &= \theta + \epsilon \\ +\epsilon &\sim \mathcal{N}(0,\sigma^2) +\end{align*} +``` + +Also, let's assume a Gaussian prior for ``\theta`` + +```math +\begin{align*} +\theta &\sim \mathcal{N}(\mu_0,\sigma_0^2) \\ +\end{align*} +``` + +For simplicity, we will assume that ``\sigma^2``, ``\mu_0`` and ``\sigma_0^2`` are given. + +What is the PDF for the posterior ``p(\theta|x)`` ? +""" + +# ╔═╡ b9a5dcc0-d294-11ef-2c85-657a460db5cd +md""" +#### Model specification + +Note that you can rewrite these specifications in probabilistic notation as follows: + +```math +\begin{align*} + p(x|\theta) &= \mathcal{N}(x|\theta,\sigma^2) \\ + p(\theta) &=\mathcal{N}(\theta|\mu_0,\sigma_0^2) +\end{align*} +``` + +""" + +# ╔═╡ 7b415578-10fa-4eb1-ab1f-ce3ff57dcf45 +md""" +#### Inference +""" + +# ╔═╡ b9a67d06-d294-11ef-297b-eb9039786ea7 +md""" +Let's do Bayes rule for the posterior PDF ``p(\theta|x)``. + +```math +\begin{align*} +p(\theta|x) &= \frac{p(x|\theta) p(\theta)}{p(x)} \propto p(x|\theta) p(\theta) \\ + &= \mathcal{N}(x|\theta,\sigma^2) \mathcal{N}(\theta|\mu_0,\sigma_0^2) \\ + &\propto \exp \left\{ -\frac{(x-\theta)^2}{2\sigma^2} - \frac{(\theta-\mu_0)^2}{2\sigma_0^2} \right\} \\ + &\propto \exp \left\{ \theta^2 \cdot \left( -\frac{1}{2 \sigma_0^2} - \frac{1}{2\sigma^2} \right) + \theta \cdot \left( \frac{\mu_0}{\sigma_0^2} + \frac{x}{\sigma^2}\right) \right\} \\ + &= \exp\left\{ -\frac{\sigma_0^2 + \sigma^2}{2 \sigma_0^2 \sigma^2} \left( \theta - \frac{\sigma_0^2 x + \sigma^2 \mu_0}{\sigma^2 + \sigma_0^2}\right)^2 \right\} +\end{align*} +``` + +which we recognize as a Gaussian distribution w.r.t. ``\theta``. + +""" + +# ╔═╡ b9a68d3a-d294-11ef-2335-093a39648007 +md""" +(Just as an aside,) this computational 'trick' for multiplying two Gaussians is called **completing the square**. The procedure makes use of the equality + +```math +ax^2+bx+c_1 = a\left(x+\frac{b}{2a}\right)^2+c_2 +``` + +""" + +# ╔═╡ b9a697fa-d294-11ef-3a57-7b7ba1f4fd70 +md""" +In particular, it follows that the posterior for ``\theta`` is + +```math +\begin{equation*} + p(\theta|x) = \mathcal{N} (\theta |\, \mu_1, \sigma_1^2) +\end{equation*} +``` + +where + +```math +\begin{align*} + \frac{1}{\sigma_1^2} &= \frac{\sigma_0^2 + \sigma^2}{\sigma^2 \sigma_0^2} = \frac{1}{\sigma_0^2} + \frac{1}{\sigma^2} \\ + \mu_1 &= \frac{\sigma_0^2 x + \sigma^2 \mu_0}{\sigma^2 + \sigma_0^2} = \sigma_1^2 \, \left( \frac{1}{\sigma_0^2} \mu_0 + \frac{1}{\sigma^2} x \right) +\end{align*} +``` + +So, multiplication of two Gaussian distributions yields another (unnormalized) Gaussian with + + * posterior precision equals **sum of prior precisions** + * posterior precision-weighted mean equals **sum of prior precision-weighted means** + + +""" + +# ╔═╡ b9a6b7b2-d294-11ef-06dc-4de5ef25c1fd +md""" + +## Conjugate Distributions + +As we just saw, a Gaussian prior, combined with a Gaussian likelihood, makes Bayesian inference analytically solvable (!), since + +```math +\begin{equation*} +\underbrace{\text{Gaussian}}_{\text{posterior}} + \propto \underbrace{\text{Gaussian}}_{\text{likelihood}} \times \underbrace{\text{Gaussian}}_{\text{prior}} \,. +\end{equation*} +``` + + +""" + +# ╔═╡ 702e7b10-14a4-42da-a192-f7c02a3d470a +md""" +When applying Bayes rule, if the posterior distribution belongs to the same family as the prior (e.g., both are Gaussian distributions), we say that the prior and the likelihood form a conjugate pair. +""" + +# ╔═╡ 51d81901-213f-42ce-b77e-10f7ca4a4145 + +keyconcept("", md"In Bayesian inference, a Gaussian prior distribution is **conjugate** to a Gaussian likelihood (when the variance is known), which ensures that the posterior distribution remains Gaussian. This conjugacy greatly simplifies calculation of Bayes rule.") + + +# ╔═╡ b9a6c7b6-d294-11ef-0446-c372aa610df8 +md""" + +## (Multivariate) Gaussian Multiplication + + +$(HTML("")) In general, the multiplication of two multi-variate Gaussians over ``x`` yields an (unnormalized) Gaussian over ``x``: + +```math +\begin{equation*} +\mathcal{N}(x|\mu_a,\Sigma_a) \cdot \mathcal{N}(x|\mu_b,\Sigma_b) = \underbrace{\mathcal{N}(\mu_a|\, \mu_b, \Sigma_a + \Sigma_b)}_{\text{normalization constant}} \cdot \mathcal{N}(x|\mu_c,\Sigma_c) +\end{equation*} +``` + +where + +```math +\begin{align*} +\Sigma_c^{-1} &= \Sigma_a^{-1} + \Sigma_b^{-1} \\ +\Sigma_c^{-1} \mu_c &= \Sigma_a^{-1}\mu_a + \Sigma_b^{-1}\mu_b +\end{align*} +``` + +""" + +# ╔═╡ b9a6ecd2-d294-11ef-02af-37c977f2814b +md""" +Check out that normalization constant ``\mathcal{N}(\mu_a|\, \mu_b, \Sigma_a + \Sigma_b)``. Amazingly, this constant can also be expressed by a Gaussian! + +""" + +# ╔═╡ b9a6f916-d294-11ef-38cb-b78c0c448550 +md""" + +Also note that Bayesian inference is trivial in the [*canonical* parameterization of the Gaussian](#natural-parameterization), where we would get + +```math +\begin{align*} + \Lambda_c &= \Lambda_a + \Lambda_b \quad &&\text{(precisions add)}\\ + \eta_c &= \eta_a + \eta_b \quad &&\text{(precision-weighted means add)} +\end{align*} +``` + +This property is an important reason why the canonical parameterization of the Gaussian distribution is useful in Bayesian data processing. + +""" + +# ╔═╡ d2bedf5f-a0ea-4604-b5da-adf9f11e80be +md""" +It is important to distinguish between two concepts: the *product of Gaussian distributions*, which results in a (possibly unnormalized) Gaussian distribution, and the *product of Gaussian-distributed variables*, which generally does not yield a Gaussian-distributed variable. See the [optional slides below](#OPTIONAL-SLIDES) for further discussion. +""" + +# ╔═╡ b9a7073a-d294-11ef-2330-49ffa7faff21 +md""" +$(code_example("Product of Two Gaussian PDFs")) + +Let's plot the exact product of two Gaussian PDFs as well as the normalized product according to the above derivation. +""" + +# ╔═╡ 45c2fb37-a078-4284-9e04-176156cffb1e +begin + d1 = Normal(0.0, 1); # μ=0, σ^2=1 + d2 = Normal(2.5, 2); # μ=2.5, σ^2=4 + s2_prod = (d1.σ^-2 + d2.σ^-2)^-1 + m_prod = s2_prod * ((d1.σ^-2)*d1.μ + (d2.σ^-2)*d2.μ) + d_prod = Normal(m_prod, sqrt(s2_prod)) # (Note that we neglect the normalization constant.) +end; + +# ╔═╡ df8867ed-0eff-4a52-8f5e-2472467e1aa2 +let + x = range(-4, stop=8, length=100) + fill = (0, 0.1) + + # Plot the first Gaussian + plot(x, pdf.(d1,x); label=L"\mathcal{N}(0,1)", fill) + + # Plot the second Gaussian + plot!(x, pdf.(d2,x); label=L"\mathcal{N}(3,4)", fill) + + # Plot the exact product + plot!(x, pdf.(d1,x) .* pdf.(d2,x); label=L"\mathcal{N}(0,1) \mathcal{N}(3,4)", fill) + + # Plot the normalized Gaussian product + plot!(x, pdf.(d_prod,x); label=L"Z^{-1} \mathcal{N}(0,1) \mathcal{N}(3,4)", fill) +end + +# ╔═╡ 3a0f7324-0955-4c1c-8acc-0d33ebd16f78 +md""" +Check out this mini lecture to learn more about this topic! +""" + +# ╔═╡ db730ca7-4850-49c7-a93d-746d393b509b +NotebookCard("https://bmlip.github.io/course/minis/Sum%20and%20product%20of%20Gaussians.html") + +# ╔═╡ b9a885a8-d294-11ef-079e-411d3f1cda03 +md""" +## Conditioning and Marginalization of a Gaussian + +Let ``z = \begin{bmatrix} x \\ y \end{bmatrix}`` be jointly normal distributed as + +```math +\begin{align*} +p(z) &= \mathcal{N}(z | \mu, \Sigma) + =\mathcal{N} \left( \begin{bmatrix} x \\ y \end{bmatrix} \left| \begin{bmatrix} \mu_x \\ \mu_y \end{bmatrix}, + \begin{bmatrix} \Sigma_x & \Sigma_{xy} \\ \Sigma_{yx} & \Sigma_y \end{bmatrix} \right. \right) +\end{align*} +``` + +Since covariance matrices are by definition symmetric, it follows that ``\Sigma_x`` and ``\Sigma_y`` are symmetric and ``\Sigma_{xy} = \Sigma_{yx}^T``. + +Let's factorize ``p(z) = p(x,y)`` as ``p(x,y) = p(y|x) p(x)`` through conditioning and marginalization. + +##### conditioning +```math +\begin{equation*} +p(y|x) = \mathcal{N}\left(y\,|\,\mu_y + \Sigma_{yx}\Sigma_x^{-1}(x-\mu_x),\, \Sigma_y - \Sigma_{yx}\Sigma_x^{-1}\Sigma_{xy} \right) +\end{equation*} +``` + +##### marginalization +```math +\begin{equation*} + p(x) = \mathcal{N}\left( x|\mu_x, \Sigma_x \right) +\end{equation*} +``` + +**proof**: in [Bishop](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf) pp.87-89 + +Hence, conditioning and marginalization in Gaussians lead to Gaussians again. This is very useful for applications in Bayesian inference in jointly Gaussian systems. + +With a natural parameterization of the Gaussian ``p(z) = \mathcal{N}_c(z|\eta,\Lambda)`` with precision matrix ``\Lambda = \Sigma^{-1} = \begin{bmatrix} \Lambda_x & \Lambda_{xy} \\ \Lambda_{yx} & \Lambda_y \end{bmatrix}``, the conditioning operation results in a simpler result, see Bishop pg.90, eqs. 2.96 and 2.97. + +As an exercise, interpret the formula for the conditional mean (``\mathbb{E}[y|x]=\mu_y + \Sigma_{yx}\Sigma_x^{-1}(x-\mu_x)``) as a prediction-correction operation. + +""" + +# ╔═╡ b9a9565c-d294-11ef-1b67-83d1ab18035b +md""" +$(code_example("Joint, Marginal, and Conditional Gaussian Distributions")) + +Let's plot the joint, marginal, and conditional distributions for some Gaussians. + +""" + +# ╔═╡ 59599e04-3e81-4518-b232-3264d9bde4f7 +let + + # up_or_down_one_order_of_magnitude = 10 .^ (-1.0:0.1:1.0) + range = [(0:.1:1)..., (1.2:.2:2)..., (2.5:.5:10)...] + + Σb11 = @bind example_Σ_11 Scrubbable(range; default=0.3) + Σb12 = @bind example_Σ_12 Scrubbable(range; default=0.7) + Σb22 = @bind example_Σ_22 Scrubbable(range; default=2.0) + + + μb1 = @bind example_μ_1 Scrubbable(range; default=1.0) + μb2 = @bind example_μ_2 Scrubbable(range; default=2.0) + + + + grid2(xs...) = @htl """
$(xs)
""" + + + a(s) = @htl """$s""" + + + + @htl """ + $(a(:μ)) = $( + grid2(μb1, μb2) + ), $(a(:Σ)) = $( + grid2(Σb11, Σb12, Σb12, Σb22) + ) + + + + """ +end + +# ╔═╡ b9a99fcc-d294-11ef-3de4-5369d9796de7 +let + # Define the joint distribution p(x,y) + μ = [example_μ_1, example_μ_2] + Σ = [ + example_Σ_11 example_Σ_12 + example_Σ_12 example_Σ_22 + ] + + ohno = [:😔, :😤, :😖, :🥶] + + try + + + joint = MvNormal(μ,Σ) + + # Define the marginal distribution p(x) + marginal_x = Normal(μ[1], sqrt(Σ[1,1])) + + # Plot p(x,y) + x_range = y_range = range(-2,stop=5,length=100) + + joint_pdf = [ pdf(joint, [x_range[i];y_range[j]]) for j=1:length(y_range), i=1:length(x_range)] + plot_1 = heatmap(x_range, y_range, joint_pdf, title = L"p(x, y)") + + # Plot p(x) + plot_2 = plot(range(-2,stop=5,length=1000), pdf.(marginal_x, range(-2,stop=5,length=1000)), title = L"p(x)", label="", fill=(0, 0.1)) + + # Plot p(y|x = 0.1) + x = 0.1 + conditional_y_m = μ[2]+Σ[2,1]*inv(Σ[1,1])*(x-μ[1]) + conditional_y_s2 = Σ[2,2] - Σ[2,1]*inv(Σ[1,1])*Σ[1,2] + conditional_y = Normal(conditional_y_m, sqrt.(conditional_y_s2)) + plot_3 = plot(range(-2,stop=5,length=1000), pdf.(conditional_y, range(-2,stop=5,length=1000)), title = L"p(y|x = %$x)", label="", fill=(0, 0.1)) + + # Combined + plot(plot_1, plot_2, plot_3, layout=(1,3), size=(1200,300)) + + catch e + str = sprint(showerror, e) + Text("$str $(rand(ohno))") + end + +end + +# ╔═╡ b9a9b8e0-d294-11ef-348d-c197c4ce2b8c +md""" +As is clear from the plots, the conditional distribution is a renormalized slice from the joint distribution. + +""" + +# ╔═╡ b9a9dca8-d294-11ef-04ec-a9202c319f89 +md""" +## Gaussian Conditioning Revisited + +Consider (again) the system + +```math +\begin{align*} +p(x\,|\,\theta) &= \mathcal{N}(x\,|\,\theta,\sigma^2) \\ +p(\theta) &= \mathcal{N}(\theta\,|\,\mu_0,\sigma_0^2) +\end{align*} +``` + +""" + +# ╔═╡ b9a9f98e-d294-11ef-193a-0dbdbfffa86f +md""" +Let ``z = \begin{bmatrix} x \\ \theta \end{bmatrix}``. The distribution for ``z`` is then given by (see [exercise below](#Conversion-to-Joint-Distribution-(**))) + +```math +p(z) = p\left(\begin{bmatrix} x \\ \theta \end{bmatrix}\right) = \mathcal{N} \left( \begin{bmatrix} x\\ + \theta \end{bmatrix} + \,\left|\, \begin{bmatrix} \mu_0\\ + \mu_0\end{bmatrix}, + \begin{bmatrix} \sigma_0^2+\sigma^2 & \sigma_0^2\\ + \sigma_0^2 &\sigma_0^2 + \end{bmatrix} + \right. \right) +``` + +""" + +# ╔═╡ b9aa27da-d294-11ef-0780-af9d89f9f599 +md""" +Direct substitution of the rule for Gaussian conditioning leads to the $(HTML("posterior")) (derivation as an Exercise): + +```math +\begin{align*} +p(\theta|x) &= \mathcal{N} \left( \theta\,|\,\mu_1, \sigma_1^2 \right)\,, +\end{align*} +``` + +with + +```math +\begin{align*} +K &= \frac{\sigma_0^2}{\sigma_0^2+\sigma^2} \qquad \text{($K$ is called: Kalman gain)}\\ +\mu_1 &= \mu_0 + K \cdot (x-\mu_0)\\ +\sigma_1^2 &= \left( 1-K \right) \sigma_0^2 +\end{align*} +``` + +Hence, for jointly Gaussian systems, inference can be performed in a single step using closed-form expressions for conditioning and marginalization of (multivariate) Gaussian distributions. +""" + +# ╔═╡ b426f9c8-4506-43ef-92fa-2ee30be621ca +md""" +# Inference with Multiple Observations +""" + + +# ╔═╡ b9a80522-d294-11ef-39d8-53a536d66bf9 + +md""" + +## Estimation of a Constant + +#### model specification + +Now consider that we measure a data set ``D = \{x_1, x_2, \ldots, x_N\}``, with measurements + +```math +\begin{aligned} +x_n &= \theta + \epsilon_n \\ +\epsilon_n &\sim \mathcal{N}(0,\sigma^2) \,, +\end{aligned} +``` + +and the same prior for ``\theta``: + +```math +\theta \sim \mathcal{N}(\mu_0,\sigma_0^2) \\ +``` + +Let's derive the predictive distribution ``p(x_{N+1}|D)`` for the next sample. + + +#### inference + +First, we derive the posterior for ``\theta``: + +```math +\begin{align*} +p(\theta|D) \propto \underbrace{\mathcal{N}(\theta|\mu_0,\sigma_0^2)}_{\text{prior}} \cdot \underbrace{\prod_{n=1}^N \mathcal{N}(x_n|\theta,\sigma^2)}_{\text{likelihood}} \,. +\end{align*} +``` + +Since the posterior is formed by multiplying ``N+1`` Gaussian distributions in ``\theta``, the result is also Gaussian in ``\theta``, due to the closure of the Gaussian family under multiplication (up to a normalization constant). + +Using the property that precisions and precision-weighted means add when Gaussians are multiplied, we can immediately write the posterior as + +```math +p(\theta|D) = \mathcal{N} (\theta |\, \mu_N, \sigma_N^2) +``` + +where + +```math +\begin{align*} + \frac{1}{\sigma_N^2} &= \frac{1}{\sigma_0^2} + \sum_n \frac{1}{\sigma^2} \tag{B-2.142} \\ + \mu_N &= \sigma_N^2 \, \left( \frac{1}{\sigma_0^2} \mu_0 + \sum_n \frac{1}{\sigma^2} x_n \right) \tag{B-2.141} +\end{align*} +``` + + +""" + +# ╔═╡ 364cd002-92ee-4fb6-b89a-3251eff7502c +md""" +#### application: prediction of future sample + +With the posterior over the model parameters in hand, we can now evaluate the posterior predictive distribution for the next sample ``x_{N+1}``. Proof for yourself that + +```math +\begin{align*} + p(x_{N+1}|D) &= \int p(x_{N+1}|\theta) p(\theta|D)\mathrm{d}\theta \\ + &=\mathcal{N}(x_{N+1}|\mu_N, \sigma^2_N +\sigma^2 ) +\end{align*} +``` + +Note that uncertainty about ``x_{N+1}`` involves both uncertainty about the parameter (``\sigma_N^2``) and observation noise ``\sigma^2``. + +""" + +# ╔═╡ 922f0eb6-9e29-4b6c-9701-cb7b2f07bb7a +hide_solution( +md""" +```math +\begin{align*} + p(x_{N+1}|D) &= \int p(x_{N+1}|\theta) p(\theta|D)\mathrm{d}\theta \\ + &= \int \mathcal{N}(x_{N+1}|\theta,\sigma^2) \mathcal{N}(\theta|\mu_N,\sigma^2_N) \mathrm{d}\theta \\ + &\stackrel{1}{=} \int \mathcal{N}(\theta|x_{N+1},\sigma^2) \mathcal{N}(\theta|\mu_N,\sigma^2_N) \mathrm{d}\theta \\ + &\stackrel{2}{=} \int \mathcal{N}(x_{N+1}|\mu_N, \sigma^2_N +\sigma^2 ) \mathcal{N}(\theta|\cdot,\cdot)\mathrm{d}\theta \\ + &= \mathcal{N}(x_{N+1}|\mu_N, \sigma^2_N +\sigma^2 ) \underbrace{\int \mathcal{N}(\theta|\cdot,\cdot)\mathrm{d}\theta}_{=1} \\ + &=\mathcal{N}(x_{N+1}|\mu_N, \sigma^2_N +\sigma^2 ) +\end{align*} +``` + +To follow the above derivation of ``p(x_{N+1}|D)``, note that transition ``1`` relies on the identity +```math +\mathcal{N}(x|\mu,\Sigma) = \mathcal{N}(\mu|x,\Sigma) +``` +and transition ``2`` derives from using the multiplication rule for Gaussians. +""") + +# ╔═╡ 9bd38e28-73d4-4c6c-a1fe-35c7a0e750b3 +challenge_solution("Gaussian Density Estimation", header_level=1) + +# ╔═╡ b9ac2d3c-d294-11ef-0d37-65a65525ad28 +md""" + +Let's solve the challenge from the beginning of the lecture. We apply maximum likelihood estimation to fit a 2-dimensional Gaussian model (``m``) to data set ``D``. Next, we evaluate ``p(x_\bullet \in S | m)`` by (numerical) integration of the Gaussian pdf over ``S``: ``p(x_\bullet \in S | m) = \int_S p(x|m) \mathrm{d}x``. + +""" + +# ╔═╡ b9a85716-d294-11ef-10e0-a7b08b800a98 +md""" +## Maximum Likelihood Estimation (MLE) Revisited + +##### MLE as a special case of Bayesian Inference + +To determine the MLE of ``\mu`` as a special case of Bayesian inference, we let ``\sigma_0^2 \rightarrow \infty`` in the Bayesian posterior for ``\mu`` (Eq. B-2.141) to get a uniform prior for ``\mu``. This yields + +```math +\begin{align} + \mu_{\text{ML}} = \left.\mu_N\right\vert_{\sigma_0^2 \rightarrow \infty} = \frac{1}{N} \sum_{n=1}^N x_n +\end{align} +``` + + +""" + +# ╔═╡ 0d303dba-51d4-4413-8001-73ed98bf74df +hide_proof( +md""" +```math +\begin{align} + \mu_{\text{ML}} &= \left.\mu_N\right\vert_{\sigma_0^2 \rightarrow \infty} = \Bigg. \underbrace{\left(\frac{1}{\sigma_0^2} + \sum_n \frac{1}{\sigma^2}\right)^{-1}}_{\text{Eq. B-2.142}} \cdot \underbrace{\left( \frac{1}{\sigma_0^2} \mu_0 + \sum_n \frac{1}{\sigma^2} x_n \right)}_{\text{Eq. B-2.141 }} \Bigg\vert_{\sigma_0^2 \rightarrow \infty} \\ +&= \left(\sum_n \frac{1}{\sigma^2}\right)^{-1} \cdot \left( \sum_n \frac{1}{\sigma^2} x_n \right) \\ +&= \left(\frac{N}{\sigma^2}\right)^{-1} \cdot \left( \frac{1}{\sigma^2} \sum_n x_n \right) \\ +&= \frac{1}{N} \sum_{n=1}^N x_n +\end{align} +``` + """) + +# ╔═╡ 4a2cd378-0960-4089-81ad-87bf1be9a3b2 +md""" +This is a reassuring result: it matches the maximum likelihood estimate for ``\mu`` that we [previously derived by setting the gradient of the log-likelihood function to zero](#Maximum-Likelihood-Estimation). + +Of course, in practical applications, the maximum likelihood estimate is not obtained by first computing the full Bayesian posterior and then applying simplifications. This derivation (see proof) is included solely to illuminate the connection between Bayesian inference and maximum likelihood estimation. + +""" + +# ╔═╡ 50d90759-8e7f-4da5-a741-89b997eae40b +md""" +##### A prediction-correction decomposition + +Having an expression for the maximum likelihood estimate, it is now possible to rewrite the (Bayesian) posterior mean for ``\mu`` as the combination of a prior-based prediction and likelihood-based (data-based) correction. + +Prove that + +```math +\underbrace{\mu_N}_{\substack{\text{posterior} \\ \text{mean}}}= \overbrace{\underbrace{\mu_0}_{\substack{\text{prior} \\ \text{mean}}}}^{\substack{\text{prior-based} \\ \text{prediction}}} + \overbrace{\underbrace{\frac{N \sigma_0^2}{N \sigma_0^2 + \sigma^2}}_{\text{gain}}\cdot \underbrace{\left(\mu_{\text{ML}} - \mu_0 \right)}_{\text{prediction error}}}^{\text{data-based correction}}\tag{B-2.141} +``` + + +""" + +# ╔═╡ d05975bb-c5cc-470a-a6f3-60bc43c51e89 +hide_proof( +md""" +```math +\begin{align*} +\mu_N &= \sigma_N^2 \, \left( \frac{1}{\sigma_0^2} \mu_0 + \sum_n \frac{1}{\sigma^2} x_n \right) \tag{B-2.141 } \\ + &= \frac{\sigma_0^2 \sigma^2}{N\sigma_0^2 + \sigma^2} \, \left( \frac{1}{\sigma_0^2} \mu_0 + \sum_n \frac{1}{\sigma^2} x_n \right) \tag{used B-2.142}\\ + &= \frac{ \sigma^2}{N\sigma_0^2 + \sigma^2} \mu_0 + \frac{N \sigma_0^2}{N\sigma_0^2 + \sigma^2} \mu_{\text{ML}} \\ + &= \mu_0 + \frac{N \sigma_0^2}{N \sigma_0^2 + \sigma^2}\cdot \left(\mu_{\text{ML}} - \mu_0 \right) +\end{align*} +``` +""") + +# ╔═╡ e8e26e57-ae94-478a-8bb2-2868de5d99e0 +md""" + +Hence, the posterior mean always lies somewhere between the prior mean ``\mu_0`` and the maximum likelihood estimate (the "data" mean) ``\mu_{\text{ML}}``. + +""" + +# ╔═╡ cfa0d29a-ffd8-4e14-b3fd-03c824db395f +md""" +# Recursive Bayesian Inference +""" + +# ╔═╡ b9aa930a-d294-11ef-37ec-8d17be226c74 +md""" +## Kalman Filtering (simple case) + +##### Problem + +Consider a signal + +```math +x_t=\theta+\epsilon_t \, \text{, with } \epsilon_t \sim \mathcal{N}(0,\sigma^2)\,, +``` +where ``D_t= \left\{x_1,\ldots,x_t\right\}`` is observed *sequentially* (over time). Derive a **recursive** algorithm for +```math +p(\theta|D_t) \,, +``` +i.e., an update rule for (posterior) ``p(\theta|D_t)``, based on (prior) ``p(\theta|D_{t-1})`` and (a new observation) ``x_t``. + +""" + +# ╔═╡ b9aabe9a-d294-11ef-2489-e9fc0dbb760a +md""" +#### Model specification + +The data-generating distribution is given as +```math +p(x_t|\theta) = \mathcal{N}(x_t\,|\, \theta,\sigma^2)\,. +``` + +For a given new measurement ``x_t`` and given ``\sigma^2``, this equation can also be read as a likelihood function for $\theta$. + +We now need a prior for $\theta$. Let's define the estimate for $\theta$ after ``t`` observations (i.e., our *solution* ) as ``p(\theta|D_t) = \mathcal{N}(\theta\,|\,\mu_t,\sigma_t^2)``. The prior is then given by + +```math +p(\theta|D_{t-1}) = \mathcal{N}(\theta\,|\,\mu_{t-1},\sigma_{t-1}^2)\,. +``` + +""" + +# ╔═╡ b9aad50e-d294-11ef-23d2-8d2bb3b47574 +md""" +#### Inference + +Use Bayes rule, + +```math +\begin{align*} +p(\theta|D_t) &= p(\theta|x_t,D_{t-1}) \\ + &\propto p(x_t,\theta | D_{t-1}) \\ + &= p(x_t|\theta) \, p(\theta|D_{t-1}) \\ + &= \mathcal{N}(x_t|\theta,\sigma^2) \, \mathcal{N}(\theta\,|\,\mu_{t-1},\sigma_{t-1}^2) \\ + &= \mathcal{N}(\theta|x_t,\sigma^2) \, \mathcal{N}(\theta\,|\,\mu_{t-1},\sigma_{t-1}^2) \;\;\text{(note this trick)}\\ + &\propto \mathcal{N}(\theta|\mu_t,\sigma_t^2) \;\;\text{(use Gaussian multiplication formula)} +\end{align*} +``` + +with + +```math +\begin{align*} +K_t &= \frac{\sigma_{t-1}^2}{\sigma_{t-1}^2+\sigma^2} \qquad \text{(Kalman gain)}\\ +\mu_t &= \mu_{t-1} + K_t \cdot (x_t-\mu_{t-1})\\ +\sigma_t^2 &= \left( 1-K_t \right) \sigma_{t-1}^2 +\end{align*} +``` + +""" + +# ╔═╡ b9aaee4a-d294-11ef-2ed7-0dcb360d8bb7 +md""" +This online (recursive) estimator of the mean and variance of Gaussian observations is known as the **Kalman filter**. + +In this simplified case, the process mean (``\theta``) is assumed to remain constant. In the general Kalman filter, however, the mean may evolve over time; see the [Dynamic Models lecture](https://bmlip.github.io/course/lectures/Dynamic%20Models.html) for details. + + + +""" + +# ╔═╡ b9aafc6e-d294-11ef-1b1a-df718c1f1a58 +md""" +Note that the so-called Kalman gain ``K_t`` serves as a "learning rate" (step size) in the update equation for the posterior mean ``\mu_t``. + +""" + +# ╔═╡ e2fc4945-4f88-4520-b56c-c7208b62c29d +keyconcept("", md"Bayesian inference does not require manual tuning of a learning rate; instead, it adapts its own effective learning rate via balancing prior beliefs with incoming evidence.") + + +# ╔═╡ b9ab0b46-d294-11ef-13c5-8314655f7867 +md""" +Note that the uncertainty about ``\theta`` decreases over time (since ``0<(1-K_t)<1``). If we assume that the statistics of the system do not change (stationarity), each new sample provides new information about the process, so the uncertainty decreases. + +""" + +# ╔═╡ b9ab1dd4-d294-11ef-2e86-31c4a4389475 +md""" +Recursive Bayesian estimation as discussed here is the basis for **adaptive signal processing** algorithms such as the [Least Mean Squares](https://en.wikipedia.org/wiki/Least_mean_squares_filter) (LMS) filter and the [Recursive Least Squares](https://en.wikipedia.org/wiki/Recursive_least_squares_filter) (RLS) filter. Both RLS and LMS are special cases of Recursive Bayesian estimation. + +""" + +# ╔═╡ b9ab2e32-d294-11ef-2ccc-9760ead59972 +md""" +$(code_example("Kalman Filtering")) + +Let's implement the Kalman filter described above. We'll use it to recursively estimate the value of ``\theta`` based on noisy observations. + +""" + +# ╔═╡ 3a53f67c-f291-4530-a2ba-f95a97b27960 +@bindname N_data_kalman Slider(1:100; default=100, show_value=true) + +# ╔═╡ b9ab9e28-d294-11ef-3a73-1f5cefdab3d8 +md""" +The shaded area represents 2 standard deviations of posterior ``p(\theta|D)``. The variance of the posterior is guaranteed to decrease monotonically for the standard Kalman filter. + +""" + +# ╔═╡ ffa570a9-ceda-4a21-80a7-a193de12fa2c +md""" +### Implementation +Here is the implementation, but feel free to skip this part. +""" + +# ╔═╡ 85b15f0a-650f-44be-97ab-55d52cb817ed +begin + n = N_data_kalman # number of observations + θ = 2.0 # true value of the parameter we would like to estimate + noise_σ2 = 0.3 # variance of observation noise + observations = noise_σ2 * randn(MersenneTwister(1), n) .+ θ +end; + +# ╔═╡ 115eabf2-c476-40f8-8d7b-868a7359c1b6 +function perform_kalman_step(prior :: Normal, x :: Float64, noise_σ2 :: Float64) + K = prior.σ / (noise_σ2 + prior.σ) # compute the Kalman gain + posterior_μ = prior.μ + K*(x - prior.μ) # update the posterior mean + posterior_σ = prior.σ * (1.0 - K) # update the posterior standard deviation + return Normal(posterior_μ, posterior_σ) # return the posterior +end; + +# ╔═╡ 61764e4a-e5ef-4744-8c71-598b2155f4d9 +begin + post_μ = fill!(Vector{Float64}(undef,n + 1), NaN) # means of p(θ|D) over time + post_σ2 = fill!(Vector{Float64}(undef,n + 1), NaN) # variances of p(θ|D) over time + + # specify the prior distribution (you can play with the parameterization of this to get a feeling of how the Kalman filter converges) + prior = Normal(0, 1) + + # save prior mean and variance to show these in plot + post_μ[1] = prior.μ + post_σ2[1] = prior.σ + + + # note that this loop demonstrates Bayesian learning on streaming data; we update the prior distribution using observation(s), after which this posterior becomes the new prior for future observations + for (i, x) in enumerate(observations) + # compute the posterior distribution given the observation + posterior = perform_kalman_step(prior, x, noise_σ2) + # save the mean of the posterior distribution + post_μ[i + 1] = posterior.μ + # save the variance of the posterior distribution + post_σ2[i + 1] = posterior.σ + # the posterior becomes the prior for future observations + prior = posterior + end +end + +# ╔═╡ 661082eb-f0c9-49a9-b046-8705f4342b37 +let + obs_scale = collect(2:n+1) + # scatter the observations + scatter(obs_scale, observations, label=L"D", ) + post_scale = collect(1:n+1) + # lineplot our estimated means of intermediate posterior distributions + plot!(post_scale, post_μ, ribbon=sqrt.(post_σ2), linewidth=3, label=L"p(θ | D_t)") + # plot the true value of θ + plot!(post_scale, θ*ones(n + 1), linewidth=2, label=L"θ") +end + +# ╔═╡ b9ac7486-d294-11ef-13e5-29b7ffb440bc +md""" +# Summary + +A **linear transformation** ``z=Ax+b`` of a Gaussian variable ``x \sim \mathcal{N}(\mu_x,\Sigma_x)`` is Gaussian distributed as + +```math +p(z) = \mathcal{N} \left(z \,|\, A\mu_x+b, A\Sigma_x A^T \right) +``` + +Bayesian inference with a Gaussian prior and Gaussian likelihood leads to an analytically computable Gaussian posterior, because of the **multiplication rule for Gaussians**: + +```math +\begin{equation*} +\mathcal{N}(x|\mu_a,\Sigma_a) \cdot \mathcal{N}(x|\mu_b,\Sigma_b) = \underbrace{\mathcal{N}(\mu_a|\, \mu_b, \Sigma_a + \Sigma_b)}_{\text{normalization constant}} \cdot \mathcal{N}(x|\mu_c,\Sigma_c) +\end{equation*} +``` + +where + +```math +\begin{align*} +\Sigma_c^{-1} &= \Sigma_a^{-1} + \Sigma_b^{-1} \\ +\Sigma_c^{-1} \mu_c &= \Sigma_a^{-1}\mu_a + \Sigma_b^{-1}\mu_b +\end{align*} +``` + +**Conditioning and marginalization** of a multivariate Gaussian distribution yields Gaussian distributions. In particular, the joint distribution + +```math +\mathcal{N} \left( \begin{bmatrix} x \\ y \end{bmatrix} \left| \begin{bmatrix} \mu_x \\ \mu_y \end{bmatrix}, + \begin{bmatrix} \Sigma_x & \Sigma_{xy} \\ \Sigma_{yx} & \Sigma_y \end{bmatrix} \right. \right) +``` + +can be decomposed as + +```math +\begin{align*} + p(y|x) &= \mathcal{N}\left(y\,|\,\mu_y + \Sigma_{yx}\Sigma_x^{-1}(x-\mu_x),\, \Sigma_y - \Sigma_{yx}\Sigma_x^{-1}\Sigma_{xy} \right) \\ +p(x) &= \mathcal{N}\left( x|\mu_x, \Sigma_x \right) +\end{align*} +``` + +Here's a nice [summary of Gaussian calculations](https://github.com/bertdv/AIP-5SSB0/raw/master/lessons/notebooks/files/RoweisS-gaussian_formulas.pdf) by Sam Roweis. + +""" + +# ╔═╡ b89360b8-39fa-46e9-96c8-7eece50fcb90 +md""" +# Summary +""" + +# ╔═╡ a439c0a7-afa1-4d9a-8737-58d341744016 +keyconceptsummary() + +# ╔═╡ 79a99a22-3bb5-431b-bf84-5dce5cccfe25 +exercises(header_level=1) + +# ╔═╡ 14b3edcc-0d16-4055-9b1c-7f324514a0a9 +md""" +#### Gaussian Message Passing (**) + +This exercise is a continuation of the [exercise on message passing for an addition node](https://bmlip.github.io/course/lectures/Factor%20Graphs.html#Messages-for-the-Addition-Node-(*)). +""" + +# ╔═╡ dd7786e2-d6ac-4dba-abca-3686242c067d +TwoColumn( +md""" +Consider an addition node + +```math +f_+(x,y,z) = \delta(z-x-y) +``` +Assume that both incoming messages are Gaussian, namely ``\overrightarrow{\mu}_{X}(x) \sim \mathcal{N}(\overrightarrow{m}_X,\overrightarrow{V}_X)`` and ``\overrightarrow{\mu}_{Y}(y) \sim \mathcal{N}(\overrightarrow{m}_Y,\overrightarrow{V}_Y)``. + +""", + +@htl """ + + + +""") + +# ╔═╡ b7a810a3-dc38-4e72-ab10-2ad2f064bdbb +md""" + +- (a) Evaluate the outgoing message ``\overrightarrow{\mu}_{Z}(z)``. + +- (b) For the same summation node, work out the SP update rule for the backward message ``\overleftarrow{\mu}_{X}(x)`` as a function of ``\overrightarrow{\mu}_{Y}(y)`` and ``\overleftarrow{\mu}_{Z}(z)``. And further refine the answer for Gaussian messages. + + +""" + +# ╔═╡ f711b053-dccf-4bf1-b285-e8da94a48b68 +hide_solution( +md""" + +- (a) Evaluate the outgoing message ``\overrightarrow{\mu}_{Z}(z)``. + +In the [exercise on message passing for an addition node](https://bmlip.github.io/course/lectures/Factor%20Graphs.html#Messages-for-the-Addition-Node-(*)), we found that the outgoing message is given by + +```math +\begin{align*} + \overrightarrow{\mu}_{Z}(z) &= \iint \overrightarrow{\mu}_{X}(x) \overrightarrow{\mu}_{Y}(y) \,\delta(z-x-y) \,\mathrm{d}x \mathrm{d}y \\ + &= \int \overrightarrow{\mu}_{X}(x) \overrightarrow{\mu}_{Y}(z-x) \,\mathrm{d}x \,, + \end{align*} +``` + + +For Gaussian incoming messages, these update rules evaluate to ``\overrightarrow{\mu}_{Z}(z) \sim \mathcal{N}(\overrightarrow{m}_Z,\overrightarrow{V}_Z)`` with + + +```math +\begin{align*} + \overrightarrow{m}_Z &= \overrightarrow{m}_X + \overrightarrow{m}_Y \\ + \overrightarrow{V}_z &= \overrightarrow{V}_X + \overrightarrow{V}_Y \,. +\end{align*} +``` + +- (b) For the same summation node, work out the SP update rule for the backward message ``\overleftarrow{\mu}_{X}(x)`` as a function of ``\overrightarrow{\mu}_{Y}(y)`` and ``\overleftarrow{\mu}_{Z}(z)``. And further refine the answer for Gaussian messages. + +```math +\begin{align*} + \overleftarrow{\mu}_{X}(x) &= \iint \overrightarrow{\mu}_{Y}(y) \overleftarrow{\mu}_{Z}(z) \,\delta(z-x-y) \,\mathrm{d}y \mathrm{d}z \\ + &= \int \overrightarrow{\mu}_{Y}(z-x) \overleftarrow{\mu}_{Z}(z) \,\mathrm{d}z + \end{align*} +``` + +and now further with Gaussian messages, + + +```math +\begin{align*} + \overleftarrow{\mu}_{X}(x) &= \int \mathcal{N}(z-x | m_y,V_y) \mathcal{N}(z | m_z,V_z)\,\mathrm{d}z \\ + &= \int \mathcal{N}(z | x+ m_y,V_y) \mathcal{N}(z | m_z,V_z)\,\mathrm{d}z \\ + &= \int \mathcal{N}(x+m_y | m_z,V_y+V_z) \mathcal{N}(z | \cdot,\cdot)\,\mathrm{d}z \\ + &= \mathcal{N}(x | m_z-m_y, V_y+V_z) +\end{align*} +``` + + +""") + +# ╔═╡ 22539cfe-3694-4100-8120-ca6ac1e66b31 +md""" +#### Estimation of a Constant (**) + +We make ``N`` IID observations ``D=\{x_1 \dots x_N\}`` and assume the following model + +```math +\begin{align} +x_k &= A + \epsilon_k \\ +A &\sim \mathcal{N}(m_A,v_A) \\ +\epsilon_k &\sim \mathcal{N}(0,\sigma^2) \,. +\end{align} +``` + +We assume that ``\sigma`` has a known value and are interested in deriving an estimator for ``A``. + +- (a) Derive the Bayesian (posterior) estimate ``p(A|D)``. + +- (b) Derive the Maximum Likelihood estimate for ``A``. + +- (c) Derive the MAP estimates for ``A``. + +- (d) Now assume that we do not know the variance of the noise term? Describe the procedure for Bayesian estimation of both ``A`` and ``\sigma^2`` (No need to fully work out to closed-form estimates). + +""" + +# ╔═╡ fa197526-6706-47ce-b84b-5675eee00610 +hide_solution( +md""" +- (a) Derive the Bayesian (posterior) estimate ``p(A|D)``. + +Since ``p(D|A) = \prod_k \mathcal{N}(x_k|A,\sigma^2)`` is a Gaussian likelihood and ``p(A)`` is a Gaussian prior, their multiplication is proportional to a Gaussian. We will work this out with the canonical parameterization of the Gaussian since it is easier to multiply Gaussians in that domain. This means the posterior ``p(A|D)`` is + + +```math +\begin{align*} + p(A|D) &\propto p(A) p(D|A) \\ + &= \mathcal{N}(A|m_A,v_A) \prod_{k=1}^N \mathcal{N}(x_k|A,\sigma^2) \\ + &= \mathcal{N}(A|m_A,v_A) \prod_{k=1}^N \mathcal{N}(A|x_k,\sigma^2) \\ + &= \mathcal{N}_c\big(A \Bigm|\frac{m_A}{v_A},\frac{1}{v_A}\big)\prod_{k=1}^N \mathcal{N}_c\big(A\Bigm| \frac{x_k}{\sigma^2},\frac{1}{\sigma^2}\big) \\ + &\propto \mathcal{N}_c\big(A \Bigm| \frac{m_A}{v_A} + \frac{1}{\sigma^2} \sum_k x_k , \frac{1}{v_A} + \frac{N}{\sigma^2} \big) \,, + \end{align*} +``` + +where we have made use of the fact that precision-weighted means and precisions add when multiplying Gaussians. In principle, this description of the posterior completes the answer. + +- (b) Derive the Maximum Likelihood estimate for ``A``. + +The ML estimate can be found by + + +```math +\begin{align*} + \nabla \log p(D|A) &=0\\ + \nabla \sum_k \log \mathcal{N}(x_k|A,\sigma^2) &= 0 \\ + \nabla \frac{-1}{2}\sum_k \frac{(x_k-A)^2}{\sigma^2} &=0\\ + \sum_k(x_k-A) &= 0 \\ + \Rightarrow \hat{A}_{ML} = \frac{1}{N}\sum_{k=1}^N x_k +\end{align*} +``` + +- (c) Derive the MAP estimates for ``A``. + +The MAP is simply the location where the posterior has its maximum value, which for a Gaussian posterior is its mean value. We computed in (a) the precision-weighted mean, so we need to divide by precision (or multiply by variance) to get the location of the mean: + + +```math +\begin{align*} +\hat{A}_{MAP} &= \left( \frac{m_A}{v_A} + \frac{1}{\sigma^2} \sum_k x_k\right)\cdot \left( \frac{1}{v_A} + \frac{N}{\sigma^2} \right)^{-1} \\ +&= \frac{v_A \sum_k x_k + \sigma^2 m_A}{N v_A + \sigma^2} +\end{align*} +``` + +- (d) Now assume that we do not know the variance of the noise term? Describe the procedure for Bayesian estimation of both ``A`` and ``\sigma^2`` (No need to fully work out to closed-form estimates). + +A Bayesian treatment requires putting a prior on the unknown variance. The variance is constrained to be positive; hence the support of the prior distribution needs to be on the positive reals. (In a multivariate case, positivity needs to be extended to symmetric positive definiteness.) Choosing a conjugate prior will simplify matters greatly. In this scenerio, the inverse Gamma distribution is the conjugate prior for the unknown variance. In the literature, this model is called a Normal-Gamma distribution. See [Murphy (2007)](https://www.seas.harvard.edu/courses/cs281/papers/murphy-2007.pdf) for the analytical treatment. +""") + +# ╔═╡ 645308ac-c9e3-4d6f-bcff-82327fbb8edf +md""" +#### Conversion to Joint Distribution (**) + +Show that the system + +```math +\begin{align*} +p(x\,|\,\theta) &= \mathcal{N}(x\,|\,\theta,\sigma^2) \\ +p(\theta) &= \mathcal{N}(\theta\,|\,\mu_0,\sigma_0^2) +\end{align*} +``` + +can be written as + +```math +p(z) = p\left(\begin{bmatrix} x \\ \theta \end{bmatrix}\right) = \mathcal{N} \left( \begin{bmatrix} x\\ + \theta \end{bmatrix} + \,\left|\, \begin{bmatrix} \mu_0\\ + \mu_0\end{bmatrix}, + \begin{bmatrix} \sigma_0^2+\sigma^2 & \sigma_0^2\\ + \sigma_0^2 &\sigma_0^2 + \end{bmatrix} + \right. \right) +``` + +""" + +# ╔═╡ 03c399e1-d0d8-493a-9f95-4209918d132a +hide_solution( +md""" +Let's first compute the moments for the marginals ``p(x)`` and ``p(\theta)``: + + +```math +\begin{align*} +p(x) &= \int p(x|\theta) p(\theta) \mathrm{d}\theta \\ + &= \int \mathcal{N}(x|\theta,\sigma^2) \mathcal{N}(\theta|\mu_0,\sigma_0^2) \mathrm{d}\theta \\ + &= \int \mathcal{N}(\theta|x,\sigma^2) \mathcal{N}(\theta|\mu_0,\sigma_0^2) \mathrm{d}\theta \\ + &= \mathcal{N}(x|\mu_0,\sigma^2+\sigma_0^2) \underbrace{\int \mathcal{N}(\theta| \cdot,\cdot) \mathrm{d}\theta}_{=1} \\ + &= \mathcal{N}(x|\mu_0,\sigma^2+\sigma_0^2) +\end{align*} +``` + +and for ``p(\theta)``: + + +```math +\begin{align*} +p(\theta) &= \int p(x|\theta) p(\theta) \mathrm{d}x \\ + &= \mathcal{N}(\theta|\mu_0,\sigma_0^2) \underbrace{\int \mathcal{N}(x|\theta,\sigma^2) \mathrm{d}x}_{=1} \\ + &= \mathcal{N}(\theta|\mu_0,\sigma_0^2) +\end{align*} +``` + +With this information, we have + + +```math +p(z) = p\left(\begin{bmatrix} x \\ \theta \end{bmatrix}\right) = \mathcal{N} \left( \begin{bmatrix} x\\ + \theta \end{bmatrix} + \,\left|\, \begin{bmatrix} \mu_0\\ + \mu_0\end{bmatrix}, + \begin{bmatrix} \sigma_0^2+\sigma^2 & \cdot \\ + \cdot &\sigma_0^2 + \end{bmatrix} + \right. \right) +``` + +So, we only need to compute ``\Sigma_{x\theta} = \Sigma_{\theta x}^T``. It helps here to write the system as + + +```math +\begin{align*} +x &= \theta + \epsilon \\ +\theta &\sim \mathcal{N}(\mu_0,\sigma_0^2) \\ +\epsilon &\sim \mathcal{N}(0,\sigma^2) +\end{align*} +``` + +Now we work out ``\Sigma_{x\theta}``: + + +```math +\begin{align*} +\Sigma_{x\theta} &= E[(x-E[x])(\theta-E[\theta])^T] \\ +&= E[(x-\mu_0)(\theta-\mu_0)^T] \\ +&= E[x\theta^T] - \mu_0 E[\theta^T] - E[x]\mu_0^T + \mu_0 \mu_0^T \\ +&= E[x\theta^T] - \mu_0 \mu_0^T \\ +&= E[(\theta + \epsilon)\theta^T] - \mu_0 \mu_0^T \\ +&= E[\theta \theta^T] + \underbrace{E[\epsilon]}_{=0} E[\theta^T] - \mu_0 \mu_0^T \\ +&= Var[\theta] + E[\theta] E[\theta]^T - \mu_0 \mu_0^T \\ +&= \sigma_0^2 + \mu_0 \mu_0^T - \mu_0 \mu_0^T \\ +&= \sigma_0^2 +\end{align*} +``` +( I am sure one of you can do it simpler and faster. Let me know:) + + +""") + +# ╔═╡ 6dfc31a0-d0d7-4901-a876-890df9ab4258 +md""" +# Optional Slides +""" + +# ╔═╡ b9acd5d4-d294-11ef-1ae5-ed4e13d238ef +md""" +## $(HTML("Inference for the Precision Parameter of the Gaussian")) + + + +""" + + + +# ╔═╡ b9acf7a8-d294-11ef-13d9-81758355cb1e +md""" + +#### Problem + + + +Consider again a Gaussian data-generating (measurement) model + +```math +\mathcal{N}\left(x_n \,|\, \mu, \lambda^{-1} \right) \,. +``` + +(We express here the variance as the inverse of a precision parameter ``\lambda``, rather than using ``\sigma^2``, since this simplifies the subsequent Bayesian computations.) + +Earlier in this lecture, we discussed Bayesian inference from a data set for the mean ``\mu``, when the variance ``\lambda^{-1}`` was given. + +We now derive the posterior distribution over the precision parameter ``\lambda``, assuming that the mean ``\mu`` is known. We omit the more general case in which both ``\mu`` and ``\lambda`` are treated as unknowns, since the resulting calculations are considerably more involved (but still result in a closed-form solution). + + +""" + +# ╔═╡ b9ad0842-d294-11ef-2035-31bceab4ace1 +md""" +#### model specification + +The likelihood for the precision parameter is + +```math +\begin{align*} +p(D|\lambda) &= \prod_{n=1}^N \mathcal{N}\left(x_n \,|\, \mu, \lambda^{-1} \right) \\ + &\propto \lambda^{N/2} \exp\left\{ -\frac{\lambda}{2}\sum_{n=1}^N \left(x_n - \mu \right)^2\right\} \tag{B-2.145} +\end{align*} +``` + +""" + +# ╔═╡ b9ad1b70-d294-11ef-3931-d1dcd2343ac9 +md""" +The conjugate distribution for this function of ``\lambda`` is the [*Gamma* distribution](https://en.wikipedia.org/wiki/Gamma_distribution), given by + +```math +p(\lambda\,|\,a,b) = \mathrm{Gam}\left( \lambda\,|\,a,b \right) \triangleq \frac{1}{\Gamma(a)} b^{a} \lambda^{a-1} \exp\left\{ -b \lambda\right\}\,, \tag{B-2.146} +``` + +where ``a>0`` and ``b>0`` are known as the *shape* and *rate* parameters, respectively. + +![](https://github.com/bmlip/course/blob/v2/assets/figures/B-fig-2.13.png?raw=true) + +(Bishop fig.2.13). Plots of the Gamma distribution ``\mathrm{Gam}\left( \lambda\,|\,a,b \right)`` for different values of ``a`` and ``b``. + +""" + +# ╔═╡ b9ad299e-d294-11ef-36d7-2f73d3cd1fa7 +md""" +The mean and variance of the Gamma distribution evaluate to ``\mathrm{E}\left( \lambda\right) = \frac{a}{b}`` and ``\mathrm{var}\left[\lambda\right] = \frac{a}{b^2}``. + +For this example, we consider a prior +```math +p(\lambda) = \mathrm{Gam}\left( \lambda\,|\,a_0, b_0\right) \,. +``` + +""" + +# ╔═╡ b9ad5100-d294-11ef-0e8b-3f67ddb2d86d +md""" +#### inference + +The posterior is given by Bayes rule, + +```math +\begin{align*} +p(\lambda\,|\,D) &\propto \underbrace{\lambda^{N/2} \exp\left\{ -\frac{\lambda}{2}\sum_{n=1}^N \left(x_n - \mu \right)^2\right\} }_{\text{likelihood}} \cdot \underbrace{\frac{1}{\Gamma(a_0)} b_0^{a_0} \lambda^{a_0-1} \exp\left\{ -b_0 \lambda\right\}}_{\text{prior}} \\ + &\propto \mathrm{Gam}\left( \lambda\,|\,a_N,b_N \right) +\end{align*} +``` + +with + +```math +\begin{align*} +a_N &= a_0 + \frac{N}{2} \qquad &&\text{(B-2.150)} \\ +b_N &= b_0 + \frac{1}{2}\sum_n \left( x_n-\mu\right)^2 \qquad &&\text{(B-2.151)} +\end{align*} +``` + +""" + +# ╔═╡ b9ad6238-d294-11ef-3fed-bbcc7d7443ee +md""" +Hence the **posterior is again a Gamma distribution**. By inspection of B-2.150 and B-2.151, we deduce that we can interpret ``2a_0`` as the number of a priori (pseudo-)observations. + +""" + +# ╔═╡ b9ad71a6-d294-11ef-185f-f1f6e6ac4464 +md""" +Since the most uninformative prior is given by ``a_0=b_0 \rightarrow 0``, we can derive the **maximum likelihood estimate** for the precision as + +```math +\lambda_{\text{ML}} = \left.\mathrm{E}\left[ \lambda\right]\right\vert_{a_0=b_0\rightarrow 0} = \left. \frac{a_N}{b_N}\right\vert_{a_0=b_0\rightarrow 0} = \frac{N}{\sum_{n=1}^N \left(x_n-\mu \right)^2} +``` + +""" + +# ╔═╡ b9ad85a4-d294-11ef-2af2-953ac0ab8927 +md""" +In short, if we do density estimation with a Gaussian distribution ``\mathcal{N}\left(x_n\,|\,\mu,\sigma^2 \right)`` for an observed data set ``D = \{x_1, x_2, \ldots, x_N\}``, the $(HTML("maximum likelihood estimates")) for ``\mu`` and ``\sigma^2`` are given by + +```math +\begin{align*} +\mu_{\text{ML}} &= \frac{1}{N} \sum_{n=1}^N x_n \qquad &&\text{(B-2.121)} \\ +\sigma^2_{\text{ML}} &= \frac{1}{N} \sum_{n=1}^N \left(x_n - \mu_{\text{ML}} \right)^2 \qquad &&\text{(B-2.122)} +\end{align*} +``` + +These estimates are also known as the *sample mean* and *sample variance* respectively. + +""" + +# ╔═╡ b9abadce-d294-11ef-14a6-9131c5b1b802 +md""" +## $(HTML("Product of Normally Distributed Variables")) + +(We've seen that) the sum of two Gausssian-distributed variables is also Gaussian distributed. + +Has the *product* of two Gaussian distributed variables also a Gaussian distribution? + +**No**! In general, this is a difficult computation. As an example, let's compute ``p(z)`` for ``Z=XY`` for the special case that ``X\sim \mathcal{N}(0,1)`` and ``Y\sim \mathcal{N}(0,1)``. + +```math +\begin{align*} +p(z) &= \int_{X,Y} p(z|x,y)\,p(x,y)\,\mathrm{d}x\mathrm{d}y \\ + &= \frac{1}{2 \pi}\int \delta(z-xy) \, e^{-(x^2+y^2)/2} \, \mathrm{d}x\mathrm{d}y \\ + &= \frac{1}{\pi} \int_0^\infty \frac{1}{x} e^{-(x^2+z^2/x^2)/2} \, \mathrm{d}x \\ + &= \frac{1}{\pi} \mathrm{K}_0( \lvert z\rvert )\,. +\end{align*} +``` + +where ``\mathrm{K}_n(z)`` is a [modified Bessel function of the second kind](http://mathworld.wolfram.com/ModifiedBesselFunctionoftheSecondKind.html). + +""" + +# ╔═╡ b9abdc7e-d294-11ef-394a-a708c96c86fc +md""" +$(code_example("Product of Gaussian Distributions")) + + +We plot ``p(Z=XY)`` and ``p(X)p(Y)`` for ``X\sim\mathcal{N}(0,1)`` and ``Y \sim \mathcal{N}(0,1)`` to give an idea of how these distributions differ. + +""" + + +# ╔═╡ b9abf984-d294-11ef-1eaa-3358379f8b44 +let + X = Normal(0, 1) + Y = Normal(0, 1) + pdf_product_std_normals(z::Real) = besselk(0, abs(z))/π + + range1 = range(-4,stop=4,length=100) + plot(range1, t -> pdf(X, t); label=L"p(X)=p(Y)=\mathcal{N}(0,1)", fill=(0, 0.1)) + plot!(range1, t -> pdf(X,t)*pdf(Y,t); label=L"p(X)*p(Y)", fill=(0, 0.1)) + plot!(range1, pdf_product_std_normals; label=L"p(Z=X*Y)", fill=(0, 0.1)) +end + +# ╔═╡ b9ac09c4-d294-11ef-2cb8-270289d01f25 +md""" +In short, Gaussian-distributed variables remain Gaussian in linear systems, but this is not the case in non-linear systems. + +""" + +# ╔═╡ f78bc1f5-cf7b-493f-9c5c-c2fbd6788616 +md""" +# Code +""" + +# ╔═╡ 026da6b9-dee1-485e-af00-3b9e35f71b6b +md""" +#### Introduction +""" + +# ╔═╡ 6ffabd68-4c38-4024-a21b-1d6fa7c3a6d7 +d(x; kwargs...) = PlutoUI.ExperimentalLayout.Div([x]; kwargs...) + +# ╔═╡ 7a8e77b8-1692-41b7-88ef-26560aad5f08 +begin + intro_bonds = PlutoUI.ExperimentalLayout.Div([ + d(@bindname(N, Slider(3:100; default=90, show_value=true)); style="flex: 1 0 max-content"), + d(@bind(redraw_button_clicked_count, CounterButton("Redraw x.")); style="flex: 1 1 50%") +]; + style="display: flex; flex-drection: row; flex-wrap: wrap; + ") +end + +# ╔═╡ 9fc14c8b-98bc-4fe9-9b58-6c5774ac5f64 +intro_bonds + +# ╔═╡ ce16666b-aa90-42ae-b3a7-690e71301024 +# macro StableRandom(x=nothing) +# :(MersenneTwister($(hash(__source__)) + hash($(esc(x))))) +# end + +# ╔═╡ 724cac08-a54d-4dea-8416-0bce33c75405 +stable_rand(args...; seed=nothing) = rand(MersenneTwister(543432 + hash(seed)), args...) + +# ╔═╡ 92efa7c1-dde6-4b21-bf3b-0fa91931620c +secret_generative_dist = MvNormal([0,1.], [0.8 0.5; 0.5 1.0]); + +# ╔═╡ 46465948-90e1-480f-b656-74bf542756ef +D = stable_rand(secret_generative_dist, N) + +# ╔═╡ c48bd024-4afb-4e5e-af2d-56b2466511c7 +x_dot = stable_rand(secret_generative_dist; seed=redraw_button_clicked_count) + +# ╔═╡ 3d0f7af2-082d-4305-a271-349d41fcd166 +md""" +#### Challenge solution +""" + +# ╔═╡ eaf6794e-66a1-45f0-95ff-7d13983aafa2 +baseplot() = plot(; xlim=(-3,3), ylim=(-2,3)) + +# ╔═╡ ba57ecbb-b64e-4dd8-8398-a90af1ac71f3 +let + baseplot() + scatter!(D[1,:], D[2,:], marker=:x, markerstrokewidth=3, label=L"D") + scatter!([x_dot[1]], [x_dot[2]], label=L"x_\bullet") + plot!(S[1], fill(S[2][1], 2), fillrange=S[2][2], alpha=0.4, color=:gray,label=L"S") +end + +# ╔═╡ b9ac5190-d294-11ef-0a99-a9d369b34045 +let + baseplot() + + # Maximum likelihood estimation of 2D Gaussian + μ = 1/N * sum(D,dims=2)[:,1] + D_min_μ = D - repeat(μ, 1, N) + Σ = Hermitian(1/N * D_min_μ*D_min_μ') + global m = MvNormal(μ, convert(Matrix, Σ)); + + contour!(range(-3, 4, length=100), range(-3, 4, length=100), (x, y) -> pdf(m, [x, y])) + scatter!(D[1,:], D[2,:]; marker=:x, markerstrokewidth=3, label=L"D") + scatter!([x_dot[1]], [x_dot[2]]; label=L"x_\bullet") + plot!(range(0, 2), [1., 1., 1.]; fillrange=2, alpha=0.4, color=:gray, label=L"S") +end + +# ╔═╡ dbf97d8d-62f2-4996-a6aa-5ae4601d456b +let + # We can use HCubature.jl to numerically evaluate the integral and get a good approximation. + + (val,err) = hcubature( + (x)->pdf(m,x), # function to integrate + first.(S), last.(S), # start and end coordinates + ) + + @mdx "Answer: ``p(x_⋅ ∈ S | m) ≈ $(round(val; digits=4))``" +end + +# ╔═╡ bc7a875f-e4fa-43fd-b001-cec6aadea3bc +md""" +#### Packages +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +HCubature = "19dc6840-f33b-545b-b366-655c7e3ffd49" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MarkdownLiteral = "736d6165-7244-6769-4267-6b50796e6954" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" + +[compat] +BmlipTeachingTools = "~1.3.1" +Distributions = "~0.25.122" +HCubature = "~1.7.0" +LaTeXStrings = "~1.4.0" +MarkdownLiteral = "~0.1.2" +Plots = "~1.40.17" +SpecialFunctions = "~2.6.1" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "94302a71d22ef6fb75344b8281a09b73c9d325dc" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.AliasTables]] +deps = ["PtrArrays", "Random"] +git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" +uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" +version = "1.1.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BitFlags]] +git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.9" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.9+0" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.5+0" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.8" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + +[[deps.Combinatorics]] +git-tree-sha1 = "8010b6bb3388abe68d95743dcbea77650bb2eddf" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.3" + +[[deps.CommonMark]] +deps = ["PrecompileTools"] +git-tree-sha1 = "351d6f4eaf273b753001b2de4dffb8279b100769" +uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" +version = "0.9.1" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.18.1" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.5.0" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.22" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.16.2+0" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.Distributions]] +deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.122" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.5" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+1" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.11" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.7.3+0" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "83dc665d0312b41367b7263e8a4d172eac1897f4" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.4" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "3a948313e7a41eb1db7a1e733e6335f17b4ab3c4" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "7.1.1+0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.14.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] +git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.17.1+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.4+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.17+0" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.4.0+2" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] +git-tree-sha1 = "1828eb7275491981fa5f1752a5e126e8f26f8741" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.17" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "27299071cc29e409488ada41ec7643e0ab19091f" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.17+0" + +[[deps.GettextRuntime_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] +git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" +uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" +version = "0.22.4+0" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.86.0+0" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.15+0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HCubature]] +deps = ["Combinatorics", "DataStructures", "LinearAlgebra", "QuadGK", "StaticArrays"] +git-tree-sha1 = "19ef9f0cb324eed957b7fe7257ac84e8ed8a48ec" +uuid = "19dc6840-f33b-545b-b366-655c7e3ffd49" +version = "1.7.0" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.19" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "8.5.1+0" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.6" + +[[deps.JLFzf]] +deps = ["REPL", "Random", "fzf_jll"] +git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.11" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.3+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "4.0.1+0" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "18.1.8+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.3+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.4.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.7.1+1" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.18.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.41.2+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.7.2+0" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.41.2+0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.29" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.2.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MarkdownLiteral]] +deps = ["CommonMark", "HypertextLiteral"] +git-tree-sha1 = "f7d73634acd573bf3489df1ee0d270a5d6d3a7a3" +uuid = "736d6165-7244-6769-4267-6b50796e6954" +version = "0.1.2" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.10+0" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.1.3" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.6+0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.7+0" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "f1a7e086c677df53e064e0fdd2c9d0b0833e3f6e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.5.0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.6+0" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.5.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.44.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "d922b4d80d1e12c658da7785e754f4796cc1d60d" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.36" +weakdeps = ["StatsBase"] + + [deps.PDMats.extensions] + StatsBaseExt = "StatsBase" + +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "1f7f9bbd5f7a2e5a9f7d96e51c9754454ea7f60b" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.56.4+0" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.44.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" +weakdeps = ["REPL"] + + [deps.Pkg.extensions] + REPLExt = "REPL" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] +git-tree-sha1 = "3ca9a356cd2e113c420f2c13bea19f8d3fb1cb18" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.3" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "bfe839e9668f0c58367fb62d8757315c0eac8777" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.20" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PtrArrays]] +git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" +version = "1.3.0" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.8.2+2" + +[[deps.Qt6Declarative_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] +git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" +version = "6.8.2+1" + +[[deps.Qt6ShaderTools_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" +version = "6.8.2+1" + +[[deps.Qt6Wayland_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] +git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" +version = "6.8.2+2" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.11.2" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + +[[deps.REPL]] +deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "4395a4cad612f95c1d08352f8c53811d6af3060b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.8.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.5.1+0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.3.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.2.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +version = "1.11.0" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.2" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.12.0" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.6.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StableRNGs]] +deps = ["Random"] +git-tree-sha1 = "95af145932c2ed859b63329952ce8d633719f091" +uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" +version = "1.0.3" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.15" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" +weakdeps = ["SparseArrays"] + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.1" + +[[deps.StatsBase]] +deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.6" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.5.0" + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + + [deps.StatsFuns.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.8.3+2" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.11.3" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.24.0" + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" + InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" + + [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "af305cc62419f9bd61b6644d19170a4d258c7967" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.7.0" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.24.0+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.8.1+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.1.2+0" + +[[deps.Xorg_libSM_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] +git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.6+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.12+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.13+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.4+0" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.6+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.7+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.8.3+0" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] +git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.6+0" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.5+0" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.12+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] +git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.17.1+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.3+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.6+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] +git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.1+0" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.10+0" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] +git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.2+0" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.7+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.44.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.6.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.7+1" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.14+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.61.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.13.1+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.17.4+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.13.4+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.4+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.28.1+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.50+0" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] +git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.8+0" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.7+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "10164.0.1+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "4.1.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.9.2+0" +""" + +# ╔═╡ Cell order: +# ╟─b9a38e20-d294-11ef-166b-b5597125ed6d +# ╟─5e9a51b1-c6e5-4fb5-9df3-9b189f3302e8 +# ╟─b9a46c3e-d294-11ef-116f-9b97e0118e5b +# ╟─8e436806-af9d-4aa4-88a4-d37e10b69c36 +# ╟─b9a48c60-d294-11ef-3b90-03053fcd82fb +# ╟─7a8e77b8-1692-41b7-88ef-26560aad5f08 +# ╟─ba57ecbb-b64e-4dd8-8398-a90af1ac71f3 +# ╟─3200f4f9-4c43-46c0-8bdb-9afc95d116e0 +# ╠═46465948-90e1-480f-b656-74bf542756ef +# ╟─4e6c4e40-f744-49e7-9d67-cf982c9fc58d +# ╠═c48bd024-4afb-4e5e-af2d-56b2466511c7 +# ╟─148f82be-5012-4c12-9002-6a8bcbf5ad08 +# ╟─b1b9bc8f-2653-42af-ad49-6aaaba2ae70e +# ╟─c2208520-020b-400a-8bb4-c8fb6786ccf3 +# ╠═3d05a2eb-87aa-4d6a-9caf-feb5758e000a +# ╟─55380883-d269-4f61-bec6-2944765db271 +# ╟─02853a5c-f6aa-4af8-8a25-bfffd4b96afc +# ╟─71f1c8ee-3b65-4ef8-b36f-3822837de410 +# ╟─b9a4eb62-d294-11ef-06fa-af1f586cbc15 +# ╟─b9a50d0c-d294-11ef-0e60-2386cf289478 +# ╟─b9a52b18-d294-11ef-2d42-19c5e3ef3549 +# ╟─b9a5589a-d294-11ef-3fc3-0552a69df7b2 +# ╟─085233ee-f5ad-4731-89bb-84773182bba6 +# ╟─9501922f-b928-46e2-8f23-8eb9c64f6198 +# ╟─b9a5889c-d294-11ef-266e-d90225222e10 +# ╟─56510a09-073c-4fc8-b0b7-17b20dbb95f0 +# ╟─a82378ae-d1be-43f9-b63a-2f897767d1fb +# ╟─36eff7bc-72f2-4b48-a109-1861af6834aa +# ╟─87f400ac-36f2-4778-a3ba-06dd7652e279 +# ╟─9c2bf0a2-4bb6-4769-b47b-6a02c4e73044 +# ╟─8f7ecb91-d251-4ac9-bb32-0dd7215382e3 +# ╟─1df7a10d-c4f6-40d6-8f5a-cbd79ef1d415 +# ╟─673360e8-27ed-471c-a866-15af550df5e7 +# ╟─9eb3e920-fab5-4a6a-8fe1-5734ebc6b25c +# ╟─883e8244-270e-4c6c-874b-b69d8989c24c +# ╟─f02aa0b1-2261-4f65-9bd0-3be33230e0d6 +# ╟─f008a742-6900-4e18-ab4e-b5da53fb64a6 +# ╟─75e35350-af22-42b1-bb55-15e16cb9c375 +# ╟─8d2732e8-479f-4744-9b1f-d0364f0c6488 +# ╟─0f9feb8d-971e-4a94-8c70-3e1f0d284314 +# ╟─2767b364-6f9a-413d-aa9e-88741cd2bbb1 +# ╟─c6753ff3-7b5e-45b8-8adc-e0bbaa6be7d3 +# ╟─b9a5cbc2-d294-11ef-214a-c71fb1272326 +# ╟─b9a5dcc0-d294-11ef-2c85-657a460db5cd +# ╟─7b415578-10fa-4eb1-ab1f-ce3ff57dcf45 +# ╟─b9a67d06-d294-11ef-297b-eb9039786ea7 +# ╟─b9a68d3a-d294-11ef-2335-093a39648007 +# ╟─b9a697fa-d294-11ef-3a57-7b7ba1f4fd70 +# ╟─b9a6b7b2-d294-11ef-06dc-4de5ef25c1fd +# ╟─702e7b10-14a4-42da-a192-f7c02a3d470a +# ╟─51d81901-213f-42ce-b77e-10f7ca4a4145 +# ╟─b9a6c7b6-d294-11ef-0446-c372aa610df8 +# ╟─b9a6ecd2-d294-11ef-02af-37c977f2814b +# ╟─b9a6f916-d294-11ef-38cb-b78c0c448550 +# ╟─d2bedf5f-a0ea-4604-b5da-adf9f11e80be +# ╟─b9a7073a-d294-11ef-2330-49ffa7faff21 +# ╟─45c2fb37-a078-4284-9e04-176156cffb1e +# ╟─df8867ed-0eff-4a52-8f5e-2472467e1aa2 +# ╟─3a0f7324-0955-4c1c-8acc-0d33ebd16f78 +# ╟─db730ca7-4850-49c7-a93d-746d393b509b +# ╟─b9a885a8-d294-11ef-079e-411d3f1cda03 +# ╟─b9a9565c-d294-11ef-1b67-83d1ab18035b +# ╟─59599e04-3e81-4518-b232-3264d9bde4f7 +# ╟─b9a99fcc-d294-11ef-3de4-5369d9796de7 +# ╟─b9a9b8e0-d294-11ef-348d-c197c4ce2b8c +# ╟─b9a9dca8-d294-11ef-04ec-a9202c319f89 +# ╟─b9a9f98e-d294-11ef-193a-0dbdbfffa86f +# ╟─b9aa27da-d294-11ef-0780-af9d89f9f599 +# ╟─b426f9c8-4506-43ef-92fa-2ee30be621ca +# ╟─b9a80522-d294-11ef-39d8-53a536d66bf9 +# ╟─364cd002-92ee-4fb6-b89a-3251eff7502c +# ╟─922f0eb6-9e29-4b6c-9701-cb7b2f07bb7a +# ╟─9bd38e28-73d4-4c6c-a1fe-35c7a0e750b3 +# ╟─b9ac2d3c-d294-11ef-0d37-65a65525ad28 +# ╟─9fc14c8b-98bc-4fe9-9b58-6c5774ac5f64 +# ╟─b9ac5190-d294-11ef-0a99-a9d369b34045 +# ╟─dbf97d8d-62f2-4996-a6aa-5ae4601d456b +# ╟─b9a85716-d294-11ef-10e0-a7b08b800a98 +# ╟─0d303dba-51d4-4413-8001-73ed98bf74df +# ╟─4a2cd378-0960-4089-81ad-87bf1be9a3b2 +# ╟─50d90759-8e7f-4da5-a741-89b997eae40b +# ╟─d05975bb-c5cc-470a-a6f3-60bc43c51e89 +# ╟─e8e26e57-ae94-478a-8bb2-2868de5d99e0 +# ╟─cfa0d29a-ffd8-4e14-b3fd-03c824db395f +# ╟─b9aa930a-d294-11ef-37ec-8d17be226c74 +# ╟─b9aabe9a-d294-11ef-2489-e9fc0dbb760a +# ╟─b9aad50e-d294-11ef-23d2-8d2bb3b47574 +# ╟─b9aaee4a-d294-11ef-2ed7-0dcb360d8bb7 +# ╟─b9aafc6e-d294-11ef-1b1a-df718c1f1a58 +# ╟─e2fc4945-4f88-4520-b56c-c7208b62c29d +# ╟─b9ab0b46-d294-11ef-13c5-8314655f7867 +# ╟─b9ab1dd4-d294-11ef-2e86-31c4a4389475 +# ╟─b9ab2e32-d294-11ef-2ccc-9760ead59972 +# ╟─3a53f67c-f291-4530-a2ba-f95a97b27960 +# ╟─661082eb-f0c9-49a9-b046-8705f4342b37 +# ╟─b9ab9e28-d294-11ef-3a73-1f5cefdab3d8 +# ╟─ffa570a9-ceda-4a21-80a7-a193de12fa2c +# ╠═9edd80d4-d088-4b2f-8843-abaa7a5d9c5e +# ╠═85b15f0a-650f-44be-97ab-55d52cb817ed +# ╠═115eabf2-c476-40f8-8d7b-868a7359c1b6 +# ╠═61764e4a-e5ef-4744-8c71-598b2155f4d9 +# ╟─b9ac7486-d294-11ef-13e5-29b7ffb440bc +# ╟─b89360b8-39fa-46e9-96c8-7eece50fcb90 +# ╟─a439c0a7-afa1-4d9a-8737-58d341744016 +# ╟─79a99a22-3bb5-431b-bf84-5dce5cccfe25 +# ╟─14b3edcc-0d16-4055-9b1c-7f324514a0a9 +# ╟─dd7786e2-d6ac-4dba-abca-3686242c067d +# ╟─b7a810a3-dc38-4e72-ab10-2ad2f064bdbb +# ╟─f711b053-dccf-4bf1-b285-e8da94a48b68 +# ╟─22539cfe-3694-4100-8120-ca6ac1e66b31 +# ╟─fa197526-6706-47ce-b84b-5675eee00610 +# ╟─645308ac-c9e3-4d6f-bcff-82327fbb8edf +# ╟─03c399e1-d0d8-493a-9f95-4209918d132a +# ╟─6dfc31a0-d0d7-4901-a876-890df9ab4258 +# ╟─b9acd5d4-d294-11ef-1ae5-ed4e13d238ef +# ╟─b9acf7a8-d294-11ef-13d9-81758355cb1e +# ╟─b9ad0842-d294-11ef-2035-31bceab4ace1 +# ╟─b9ad1b70-d294-11ef-3931-d1dcd2343ac9 +# ╟─b9ad299e-d294-11ef-36d7-2f73d3cd1fa7 +# ╟─b9ad5100-d294-11ef-0e8b-3f67ddb2d86d +# ╟─b9ad6238-d294-11ef-3fed-bbcc7d7443ee +# ╟─b9ad71a6-d294-11ef-185f-f1f6e6ac4464 +# ╟─b9ad85a4-d294-11ef-2af2-953ac0ab8927 +# ╟─b9abadce-d294-11ef-14a6-9131c5b1b802 +# ╟─b9abdc7e-d294-11ef-394a-a708c96c86fc +# ╟─b9abf984-d294-11ef-1eaa-3358379f8b44 +# ╟─b9ac09c4-d294-11ef-2cb8-270289d01f25 +# ╟─f78bc1f5-cf7b-493f-9c5c-c2fbd6788616 +# ╟─026da6b9-dee1-485e-af00-3b9e35f71b6b +# ╠═6ffabd68-4c38-4024-a21b-1d6fa7c3a6d7 +# ╠═ce16666b-aa90-42ae-b3a7-690e71301024 +# ╠═724cac08-a54d-4dea-8416-0bce33c75405 +# ╠═92efa7c1-dde6-4b21-bf3b-0fa91931620c +# ╟─3d0f7af2-082d-4305-a271-349d41fcd166 +# ╠═5638c1d0-db95-49e4-bd80-528f79f2947e +# ╠═eaf6794e-66a1-45f0-95ff-7d13983aafa2 +# ╠═03a36e87-2378-4efc-bcac-9c0609b52784 +# ╟─bc7a875f-e4fa-43fd-b001-cec6aadea3bc +# ╠═c97c495c-f7fe-4552-90df-e2fb16f81d15 +# ╠═3ec821fd-cf6c-4603-839d-8c59bb931fa9 +# ╠═00482666-0772-4e5d-bb35-df7b6fb67a1b +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/archive/The Multinomial Distribution.jl b/mlss/archive/The Multinomial Distribution.jl new file mode 100644 index 00000000..115652f5 --- /dev/null +++ b/mlss/archive/The Multinomial Distribution.jl @@ -0,0 +1,940 @@ +### A Pluto.jl notebook ### +# v0.20.21 + +#> [frontmatter] +#> description = "Bayesian and maximum likelihood density estimation for discretely valued data sets." +#> +#> [[frontmatter.author]] +#> name = "BMLIP" +#> url = "https://github.com/bmlip" + +using Markdown +using InteractiveUtils + +# ╔═╡ d3a4a1dc-3fdf-479d-a51c-a1e23073c556 +using BmlipTeachingTools + +# ╔═╡ d8422bf2-d294-11ef-0144-098f414c6454 +title("Discrete Data and the Multinomial Distribution") + +# ╔═╡ 1c6d16be-e8e8-45f1-aa32-c3fb08af19ce +PlutoUI.TableOfContents() + +# ╔═╡ d8424e52-d294-11ef-0083-fbb77df4d853 +md""" +## Preliminaries + +##### Goal + + * Simple Bayesian and maximum likelihood-based density estimation for discretely valued data sets + +##### Materials + + * Mandatory + + * These lecture notes + * Optional + + * [Bishop PRML book](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf) (2006), pp. 67-70, 74-76, 93-94 + +""" + +# ╔═╡ d842ad86-d294-11ef-3266-253f80ecf4b7 +md""" +## Discrete Data: the 1-of-K Coding Scheme + +Consider a coin-tossing experiment with outcomes ``x \in\{0,1\}`` (tail and head, respectively) and let ``0\leq \mu \leq 1`` represent the probability of heads. The data generating distribution for this model can written as a [**Bernoulli distribution**](https://en.wikipedia.org/wiki/Bernoulli_distribution): + +```math + +p(x|\mu) = \mu^{x}(1-\mu)^{1-x} +``` + +Note that the variable ``x`` acts as a (binary) **selector** for the tail or head probabilities. Think of this as an 'if'-statement in programming. + +""" + +# ╔═╡ d842d368-d294-11ef-024d-45e58ca994e0 +md""" +Now consider a ``K``-sided coin (e.g., a six-faced *die* (pl.: dice)). How should we encode outcomes? Two natural options present themselves: + +##### Option 1: label encoding + +```math +x \in \{1,2,\ldots,K\} \,. +``` + - E.g., for ``K=6``, if the die lands on the 3rd face, then ``x=3``. + - This coding scheme is called **label** (or **index**) encoding. + +##### Option 2: one-hot encoding + +```math +x = (x_1,\ldots,x_K)^T +``` +where ``x_k`` are **binary selection variables**, given by +```math +x_k = \begin{cases} 1 & \text{if die landed on $k$th face}\\ +0 & \text{otherwise} \end{cases} +``` + - For instance, for ``K=6``, if the die lands on the ``3``-rd face, then ``x=(0,0,1,0,0,0)^T``. + + - This coding scheme is called a **1-of-K** or **one-hot** coding scheme. + +It turns out that the one-hot coding scheme is mathematically more convenient! + +""" + +# ╔═╡ f9977fc0-0d3f-467e-822d-72f3a338f717 +keyconcept("", "Discrete event outcomes are typically represented via one-hot encoding, in which each outcome corresponds to a unique binary indicator vector.") + +# ╔═╡ d842fe4c-d294-11ef-15a9-a9a6e359f47d +md""" +## The Categorical Distribution + +Consider a toss with a ``K``-sided die. We use a one-hot coding scheme, i.e., the outcome is encoded as +```math +x_{k} = \begin{cases} 1 & \text{if the throw landed on $k$-th face}\\ +0 & \text{otherwise} \end{cases} \,. +``` + +Assume the probabilities + + +```math +p(x_{k}=1) = \mu_k \quad \text{with } \mu_k \geq 0 \text{ and }\sum_k \mu_k = 1 \,. +``` +The data generating distribution for one-hot encoded outcome ``x = (x_{1},x_{2},\ldots,x_{K})`` (and ``\mu = (\mu_1,\mu_2,\dots,\mu_k)^T``) is then given by + +```math +p(x|\mu) = \mu_1^{x_1} \mu_2^{x_2} \cdots \mu_K^{x_K}=\prod_{k=1}^K \mu_k^{x_k} \tag{B-2.26} +``` + +This generalized Bernoulli distribution is called the [**categorical distribution**](https://en.wikipedia.org/wiki/Categorical_distribution). + +""" + +# ╔═╡ d843540a-d294-11ef-3846-2bf27b7e9b30 +md""" +# Bayesian Density Estimation for a Loaded Die + +Now let's proceed with learning the parameters for a model for ``N`` independent-and-identically-distributed (IID) rolls of a ``K``-sided die, based on observed data set ``D=\{x_1,\ldots,x_N\}``. + + +""" + +# ╔═╡ d84369a4-d294-11ef-38f7-7f393869b705 +md""" +## Model specification + +#### data-generating distribution + +The outcomes ``x_n`` are encoded as +```math +x_{nk} = \begin{cases} 1 & \text{if the $n$-th throw landed on $k$-th face}\\ +0 & \text{otherwise} \end{cases} +``` + +and the likelihood function for ``\mu`` is now + +```math +p(D|\mu) = \prod_n \prod_k \mu_k^{x_{nk}} = \prod_k \mu_k^{\sum_n x_{nk}} = \prod_k \mu_k^{m_k} \tag{B-2.29} +``` + +where ``m_k= \sum_n x_{nk}`` is the total number of occurrences that the outcome landed on face ``k``. The vector ``m = (m_1,m_2, \ldots, m_K)^T`` is known as the **count vector**. Note that ``\sum_k m_k = N``. + +This distribution depends on the observations **only** through the ''observed'' counts ``\{m_k\}``. For given counts ``\{m_k\}``, ``p(D|\mu)`` can be interpreted as a likelihood function for ``\mu``. + +""" + +# ╔═╡ d8439866-d294-11ef-230b-dfde21aedfbf +md""" + +#### prior distribution + +Next, we need a prior for the parameters ``\mu = (\mu_1,\mu_2,\ldots,\mu_K)^T``. + +In the [binary coin toss example](https://bmlip.github.io/course/lectures/Bayesian%20Machine%20Learning.html#beta-prior), we used a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) that was conjugate with the binomial and forced us to choose prior pseudo-counts. + +The generalization of the beta prior to ``K`` parameters ``\{\mu_k\}`` is the [Dirichlet distribution](https://en.wikipedia.org/wiki/Dirichlet_distribution): + +```math +p(\mu|\alpha) = \mathrm{Dir}(\mu|\alpha) = \frac{\Gamma\left(\sum_k \alpha_k\right)}{\Gamma(\alpha_1)\cdots \Gamma(\alpha_K)} \prod_{k=1}^K \mu_k^{\alpha_k-1} +``` + +where ``\Gamma(\cdot)`` is the [Gamma function](https://en.wikipedia.org/wiki/Gamma_function). + + - The Gamma function can be interpreted as a generalization of the factorial function to the real (``\mathbb{R}``) numbers. If ``n`` is a natural number (``1,2,3, \ldots $), then $\Gamma(n) = (n-1)!``, where ``(n-1)! = (n-1)\cdot (n-2) \cdot 1``. + +As before for the Beta distribution in the coin toss experiment, you can interpret ``\alpha_k`` as the prior number of (pseudo-)observations that the die landed on the ``k``-th face. + +""" + +# ╔═╡ d843a338-d294-11ef-2748-b95f2af1396b +md""" +## Inference for ``\{\mu_k\}`` + +The posterior for ``\{\mu_k\}`` can be obtained through Bayes rule: + +```math +\begin{align*} +p(\mu|D,\alpha) &\propto p(D|\mu) \cdot p(\mu|\alpha) \\ + &\propto \prod_k \mu_k^{m_k} \cdot \prod_k \mu_k^{\alpha_k-1} \\ + &= \prod_k \mu_k^{\alpha_k + m_k -1}\\ + &\propto \mathrm{Dir}\left(\mu\,|\,\alpha + m \right) \tag{B-2.41} \\ + &= \frac{\Gamma\left(\sum_k (\alpha_k + m_k) \right)}{\Gamma(\alpha_1+m_1) \Gamma(\alpha_2+m_2) \cdots \Gamma(\alpha_K + m_K)} \prod_{k=1}^K \mu_k^{\alpha_k + m_k -1} +\end{align*} +``` + +where ``m = (m_1,m_2,\ldots,m_K)^T`` is the count vector. + +""" + +# ╔═╡ d843b33c-d294-11ef-195d-2708fbfba49d +md""" +We recognize the ``(\alpha_k)``'s as prior pseudo-counts and the Dirichlet distribution shows to be a [conjugate prior](https://en.wikipedia.org/wiki/Conjugate_prior) to the categorical/multinomial: + +```math +\begin{align*} +\underbrace{\text{Dirichlet}}_{\text{posterior}} &\propto \underbrace{\text{categorical}}_{\text{likelihood}} \cdot \underbrace{\text{Dirichlet}}_{\text{prior}} +\end{align*} +``` + +""" + +# ╔═╡ d843c228-d294-11ef-0d34-3520dc97859c +md""" +This is actually a generalization of the conjugate relation that we found for the binary coin toss: + +```math +\begin{align*} +\underbrace{\text{beta}}_{\text{posterior}} &\propto \underbrace{\text{binomial}}_{\text{likelihood}} \cdot \underbrace{\text{beta}}_{\text{prior}} +\end{align*} +``` + +""" + +# ╔═╡ d843d0c4-d294-11ef-10b6-cb982615d58a +md""" +## $(HTML("Prediction of next toss for the loaded die")) + +Let's apply what we have learned about the loaded die to compute the probability that we throw the ``k``-th face at the next toss. + +```math +\begin{align*} +p(x_{\bullet,k}=1|D) &= \int p(x_{\bullet,k}=1|\mu)\,p(\mu|D) \,\mathrm{d}\mu \\ + &= \int_0^1 \mu_k \times \mathcal{Dir}(\mu|\,\alpha+m) \,\mathrm{d}\mu \\ + &= \mathrm{E}\left[ \mu_k | D\right] \\ + &= \frac{m_k + \alpha_k }{ N+ \sum_k \alpha_k} +\end{align*} +``` + +(You can find the mean of the Dirichlet distribution ``\mathrm{E}\left[ \mu_k \right]`` at its [Wikipedia site](https://en.wikipedia.org/wiki/Dirichlet_distribution)). + +This result is simply a generalization of [**Laplace's rule of succession**](https://en.wikipedia.org/wiki/Rule_of_succession). + +""" + +# ╔═╡ d843defc-d294-11ef-358b-f56f514dcf93 +md""" +## Categorical, Multinomial and Related Distributions + +In the above derivation, we noticed that the data generating distribution for ``N`` die tosses with data outcomes ``D=\{x_1,\ldots,x_N\}`` only depends on the **counts** ``m_k``: + +```math +p(D|\mu) = \prod_n \underbrace{\prod_k \mu_k^{x_{nk}}}_{\text{categorical dist.}} = \prod_k \mu_k^{\sum_n x_{nk}} = \prod_k \mu_k^{m_k} \tag{B-2.29} +``` + +""" + +# ╔═╡ d843efdc-d294-11ef-0f3a-630ecdd0acee +md""" +A related distribution is the distribution over count observations ``D_m=\{m_1,\ldots,m_K\}``, which is called the **multinomial distribution**, + +```math +p(D_m|\mu) =\frac{N!}{m_1! m_2!\ldots m_K!} \,\prod_k \mu_k^{m_k}\,. +``` + +""" + +# ╔═╡ d84422a6-d294-11ef-148b-c762a90cd620 +md""" +(We insert this slide only to alert you to the difference between using one-hot encoded outcomes ``D=\{x_1,x_2,\ldots,x_N\}`` as the data, versus using counts ``D_m = \{m_1,m_2,\ldots,m_K\}`` as the data. When used as a likelihood function for ``\mu``, it makes no difference whether you use ``p(D|\mu)`` or ``p(D_m|\mu)``.) + +""" + +# ╔═╡ d8449f1a-d294-11ef-3cfa-4fc33a5daa00 +md""" +## Maximum Likelihood Estimation for the Multinomial + +#### Maximum likelihood as a special case of Bayesian estimation + +We can obtain the maximum likelihood estimate for ``\mu_k`` based on ``N`` throws of a ``K``-sided die within the Bayesian framework by letting the prior for ``\mu`` approach a uniform distribution. For a Dirichlet prior ``\mathrm{Dir}(\mu | \alpha)``, this corresponds to setting +``\alpha \rightarrow (1, 1, \dots, 1)``. + + +Prove for yourself that + +```math +\begin{align*} +\hat{\mu}_k &= \arg\max_{\mu_k} p(D|\mu) = \frac{m_k}{N}\,. +\end{align*} +``` + +""" + +# ╔═╡ 4482e857-af6b-4459-a0a2-cd7ad57ed94f +hide_proof( +md""" +```math +\begin{align*} +\hat{\mu}_k &= \arg\max_{\mu_k} p(D|\mu) \\ +&= \arg\max_{\mu_k} p(D|\mu) \cdot \underbrace{\left.\mathrm{Dir}(\mu|\alpha)\right|_{\alpha=(1,1,\ldots,1)}}_{\text{uniform distr.}} \\ +&= \arg\max_{\mu_k} \left.p(\mu|D,\alpha)\right|_{\alpha=(1,1,\ldots,1)} \\ +&= \arg\max_{\mu_k} \left.\mathrm{Dir}\left( \mu | m + \alpha \right)\right|_{\alpha=(1,1,\ldots,1)} \\ +&= \frac{m_k}{\sum_k m_k} = \frac{m_k}{N} +\end{align*} +``` + +where we used the fact that the [maximum of the Dirichlet distribution](https://en.wikipedia.org/wiki/Dirichlet_distribution#Mode) ``\mathrm{Dir}(\{\alpha_1,\ldots,\alpha_K\})`` is obtained at ``(\alpha_k-1)/(\sum_k\alpha_k - K)``. + + """) + +# ╔═╡ d844bcfa-d294-11ef-0874-b154f3ed810b +md""" +#### $(HTML("Maximum likelihood estimation by optimizing a constrained log-likelihood")) + +Of course, we shouldn't have to go through the full Bayesian framework to get the maximum likelihood estimate. Alternatively, we can find the maximum likelihood (ML) solution directly by optimizing the (constrained) log-likelihood. + +The log-likelihood for the multinomial distribution is given by + +```math +\begin{align*} +\mathrm{L}(\mu) &\triangleq \log p(D_m|\mu) \propto \log \prod_k \mu_k^{m_k} = \sum_k m_k \log \mu_k +\end{align*} +``` + +""" + +# ╔═╡ d844d564-d294-11ef-0454-416352d43524 +md""" +When doing ML estimation, we must obey the constraint ``\sum_k \mu_k = 1``, which can be accomplished by a [Lagrange multiplier](https://en.wikipedia.org/wiki/Lagrange_multiplier). The **constrained log-likelihood** with Lagrange multiplier is then + +```math +\tilde{\mathrm{L}}(\mu) = \sum_k m_k \log \mu_k + \lambda \cdot \big(1 - \sum_k \mu_k \big) +``` + +The method of Lagrange multipliers is a mathematical method for transforming a constrained optimization problem to an unconstrained optimization problem (see [Bishop App.E](https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf#page=727)). Unconstrained optimization problems can be solved by setting the derivative to zero. + +""" + +# ╔═╡ d844fa76-d294-11ef-172a-85e68842c252 +md""" +Setting the derivative of ``\tilde{\mathrm{L}}(\mu)`` to zero yields the **sample proportion** for ``\mu_k`` + +```math +\begin{equation*} +\nabla_{\mu_k} \tilde{\mathrm{L}}(\mu) = \frac{m_k } +{\hat\mu_k } - \lambda \overset{!}{=} 0 \; \Rightarrow \; \hat\mu_k = \frac{m_k }{N} +\end{equation*} +``` + +where we get ``\lambda`` from the constraint + +```math +\begin{equation*} +\sum_k \hat \mu_k = \sum_k \frac{m_k} +{\lambda} = \frac{N}{\lambda} \overset{!}{=} 1 +\end{equation*} +``` + + + +""" + +# ╔═╡ 63cc56b7-588a-43c3-8327-ad6367608601 +md""" +# Summary +""" + +# ╔═╡ acdc5bfa-7188-4a37-80e6-5026ecd1a813 +keyconceptsummary() + +# ╔═╡ 204bec3f-6fde-48c1-b2b6-9f88d484c130 +exercises(header_level=1) + +# ╔═╡ 62b42d1d-be91-4740-bac6-b4527494959d +md""" + +#### Maximum Likelihood estimation (**) + +We consider IID data ``D = \{x_1,x_2,\ldots,x_N\}`` obtained from tossing a ``K``-sided die. We use a *binary selection variable* + +```math +x_{nk} \equiv \begin{cases} 1 & \text{if $x_n$ lands on $k$-th face}\\ + 0 & \text{otherwise} +\end{cases} +``` + +with probabilities ``p(x_{nk} = 1)=\mu_k``. + +- (a) Derive the log-likelihood ``\log p(D|\mu)``. +- (b) Derive the maximum likelihood estimate for ``\mu``. + +""" + +# ╔═╡ 01c4c590-fece-49a5-8979-6e0d54f7850a +hide_solution( +md""" +Derivations are in the lecture notes. + +- (a) + + +```math +p(x_n|\mu) = \prod_k \mu_k^{x_{nk}} \quad \text{subject to} \quad \sum_k \mu_k = 1 \,. +``` + +```math +p(D|\mu) = \sum_k m_k \log \mu_k +``` + +where ``m_k = \sum_n x_{nk}``. + +- (b) + + +```math +\hat \mu = \frac{m_k}{N}\,, +``` + +which is the *sample proportion*. +""") + +# ╔═╡ d8443e38-d294-11ef-25db-b16df87850f4 +md""" +#### Discrete Distributions (*) + +Show that + +- (a) the categorial distribution is a special case of the multinomial for ``N=1``. + +- (b) the Bernoulli is a special case of the categorial distribution for ``K=2``. + +- (c) the binomial is a special case of the multinomial for ``K=2``. + +""" + +# ╔═╡ 448d0679-b47a-4db9-ad7d-a45786350fef +hide_solution( +md""" + +- (a) The probability mass function of a **multinomial distribution** is +```math + p(D_m|\mu) =\frac{N!}{m_1! m_2!\ldots m_K!} \,\prod_k \mu_k^{m_k} +``` +over the data frequencies ``D_m=\{m_1,\ldots,m_K\}`` with constraints that ``\sum_k \mu_k = 1`` and ``\sum_k m_k=N``. + +Setting ``N=1``, we see that ``p(D_m|\mu) \propto \prod_k \mu_k^{m_k}`` with ``\sum_k m_k=1``, making the sample-space one-hot coded. This is the **categorical distribution**. + +- (b) When ``K=2``, the constraint for the categorical distribution takes the form ``m_1=1-m_2`` leading to + +```math + p(D_m|\mu) \propto \mu_1^{m_1}(1-\mu_1)^{1-m_1} +``` +which is associated with the **Bernoulli distribution**. + +- (c) Plugging ``K=2`` into the multinomial distribution leads to ``p(D_m|\mu) =\frac{N!}{m_1! m_2!}\mu_1^{m_1}\left(\mu_2^{m_2}\right)`` with the constraints ``m_1+m_2=N`` and ``\mu_1+\mu_2=1``. Then plugging the constraints back in we obtain +```math + p(D_m|\mu) = \frac{N!}{m_1! (N-m1)!}\mu_1^{m_1}\left(1-\mu_1\right)^{N-m_1} +``` +which is the **binomial distribution**. + + +""") + +# ╔═╡ 72f24b54-ab22-4a54-9ece-7433048f4769 +md""" + +#### Laplace's Generalized Rule of Succession (**) + +Show that Laplace's generalized rule of succession can be worked out to a prediction that is composed of a prior prediction and data-based correction term. + + +""" + +# ╔═╡ 3c2ee96d-18a6-45d0-a2cf-f2ebbf5e22f0 +hide_solution( +md""" + +```math +\begin{align*} +p(&x_{\bullet,k}=1|D) = \frac{m_k + \alpha_k }{ N+ \sum_k \alpha_k} \\ +&= \frac{m_k}{N+\sum_k \alpha_k} + \frac{\alpha_k}{N+\sum_k \alpha_k}\\ +&= \frac{m_k}{N+\sum_k \alpha_k} \cdot \frac{N}{N} + \frac{\alpha_k}{N+\sum_k \alpha_k}\cdot \frac{\sum_k \alpha_k}{\sum_k\alpha_k} \\ +&= \frac{N}{N+\sum_k \alpha_k} \cdot \frac{m_k}{N} + \frac{\sum_k \alpha_k}{N+\sum_k \alpha_k} \cdot \frac{\alpha_k}{\sum_k\alpha_k} \\ +&= \frac{N}{N+\sum_k \alpha_k} \cdot \frac{m_k}{N} + \bigg( \frac{\sum_k \alpha_k}{N+\sum_k \alpha_k} + \underbrace{\frac{N}{N+\sum_k \alpha_k} - \frac{N}{N+\sum_k \alpha_k}}_{0}\bigg) \cdot \frac{\alpha_k}{\sum_k\alpha_k} \\ +&= \frac{N}{N+\sum_k \alpha_k} \cdot \frac{m_k}{N} + \bigg( 1 - \frac{N}{N+\sum_k \alpha_k}\bigg) \cdot \frac{\alpha_k}{\sum_k\alpha_k} \\ +&= \underbrace{\frac{\alpha_k}{\sum_k\alpha_k}}_{\text{prior prediction}} + \underbrace{\frac{N}{N+\sum_k \alpha_k} \cdot \underbrace{\left(\frac{m_k}{N} - \frac{\alpha_k}{\sum_k\alpha_k}\right)}_{\text{prediction error}}}_{\text{data-based correction}} +\end{align*} +``` + +(If you know how to do it shorter and more elegantly, please post in Piazza.) + +This decomposition is the natural consequence of doing Bayesian estimation, which always involves a prior-based prediction term and a likelihood-based (or data-based) correction term that can be interpreted as a (precision-weighted) prediction error. + + """) + +# ╔═╡ 93b8ac65-ac41-4a03-bddd-5f01ccb5b42d +md""" + +#### Evidence for the Multinomial-Dirichlet model (**) + +As above, consider the following model assumptions for $N$ tosses with a $K$-sided die with parameters $\mu = (\mu_1,\mu_2, \ldots,\mu_K)$. + +```math +\begin{align} +p(D|\mu) &= \prod_{n=1}^N \mathrm{Cat}(x_n|\mu) = \prod_{k=1}^{K} \mu_k^{m_k} \tag{likelihood}\\ +p(\mu|\alpha) &= \mathrm{Dir}(\mu|\alpha) = \frac{1}{B(\alpha)} \prod_{k=1}^{K} \mu_k^{\alpha_k -1} \tag{prior} +\end{align} +``` +where $B(\alpha) = \frac{\prod_k \Gamma(\alpha_k)}{\Gamma(\sum_k \alpha_k)}$ is known as the [Beta function](https://en.wikipedia.org/wiki/Beta_function). + +Work out both the model evidence and the posterior distribution for $\mu$. +""" + +# ╔═╡ 81b5aea0-8101-46e2-a875-1058029ebf99 +hide_solution( + md""" + + ```math + \begin{align} + \overbrace{\prod_{k=1}^{K} \mu_k^{m_k}}^{\text{likelihood }p(D|\mu)} \cdot \overbrace{\frac{1}{B(\alpha)} \prod_{k=1}^{K} \mu_k^{\alpha_k -1}}^{\text{prior }p(\mu|\alpha)} + &= \frac{1}{B(\alpha)} \prod_{k=1}^{K} \mu_k^{m_k + \alpha_k -1} \\ + &= \frac{B(m+\alpha)}{B(\alpha)} \frac{1}{B(m+\alpha)}\prod_{k=1}^{K} \mu_k^{m_k + \alpha_k -1} \\ + &= \underbrace{\frac{B(m+\alpha)}{B(\alpha)}}_{\text{evidence }p(D|\alpha)} \,\underbrace{\mathrm{Dir}(\mu|m+\alpha)}_{\text{posterior }p(\mu|D,\alpha)} + \end{align} + ``` + + This equation is the equivalent of the [Gaussian multiplication formula](https://bmlip.github.io/course/lectures/The%20Gaussian%20Distribution.html#(Multivariate)-Gaussian-Multiplication) for discrete data. Note that the evidence is a scalar normalizer for given observations $m$ and pseudo-observations ("prior" observations) $\alpha$. + """) + +# ╔═╡ 59fb1e66-cf05-4f2b-8027-7ff3b1a57c15 +md""" +# Code +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +BmlipTeachingTools = "656a7065-6f73-6c65-7465-6e646e617262" + +[compat] +BmlipTeachingTools = "~1.3.1" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.12.1" +manifest_format = "2.0" +project_hash = "3e0db0a10f1d7687b8c53fc91306ce22ead0cdba" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.BmlipTeachingTools]] +deps = ["HypertextLiteral", "InteractiveUtils", "Markdown", "PlutoTeachingTools", "PlutoUI", "Reexport"] +git-tree-sha1 = "806eadb642467b05f9d930f0d127f1e6fa5130f0" +uuid = "656a7065-6f73-6c65-7465-6e646e617262" +version = "1.3.1" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.3.0+1" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.Ghostscript_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] +git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" +uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" +version = "9.55.1+0" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.7.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.1.3+0" + +[[deps.JuliaSyntaxHighlighting]] +deps = ["StyledStrings"] +uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" +version = "1.12.0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.4.0" + +[[deps.Latexify]] +deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.10" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SparseArraysExt = "SparseArrays" + SymEngineExt = "SymEngine" + TectonicExt = "tectonic_jll" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.11.1+1" + +[[deps.LibGit2]] +deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.9.0+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.3+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +version = "1.12.0" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.MIMEs]] +git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "1.1.0" + +[[deps.MacroTools]] +git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.16" + +[[deps.Markdown]] +deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" +version = "1.11.0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2025.5.20" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.3.0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.29+0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.5.1+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.8.1" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.3" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.12.0" + + [deps.Pkg.extensions] + REPLExt = "REPL" + + [deps.Pkg.weakdeps] + REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.PlutoTeachingTools]] +deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] +git-tree-sha1 = "dacc8be63916b078b592806acd13bb5e5137d7e9" +uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" +version = "0.4.6" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "3faff84e6f97a7f18e0dd24373daa229fd358db5" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.73" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.3.3" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.5.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.1" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.Statistics]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.11.1" + + [deps.Statistics.extensions] + SparseArraysExt = ["SparseArrays"] + + [deps.Statistics.weakdeps] + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.StyledStrings]] +uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" +version = "1.11.0" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.Tricks]] +git-tree-sha1 = "372b90fe551c019541fafc6ff034199dc19c8436" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.12" + +[[deps.URIs]] +git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.6.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.3.1+2" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.15.0+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.64.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.5.0+2" +""" + +# ╔═╡ Cell order: +# ╟─d8422bf2-d294-11ef-0144-098f414c6454 +# ╟─1c6d16be-e8e8-45f1-aa32-c3fb08af19ce +# ╟─d8424e52-d294-11ef-0083-fbb77df4d853 +# ╟─d842ad86-d294-11ef-3266-253f80ecf4b7 +# ╟─d842d368-d294-11ef-024d-45e58ca994e0 +# ╟─f9977fc0-0d3f-467e-822d-72f3a338f717 +# ╟─d842fe4c-d294-11ef-15a9-a9a6e359f47d +# ╟─d843540a-d294-11ef-3846-2bf27b7e9b30 +# ╟─d84369a4-d294-11ef-38f7-7f393869b705 +# ╟─d8439866-d294-11ef-230b-dfde21aedfbf +# ╟─d843a338-d294-11ef-2748-b95f2af1396b +# ╟─d843b33c-d294-11ef-195d-2708fbfba49d +# ╟─d843c228-d294-11ef-0d34-3520dc97859c +# ╟─d843d0c4-d294-11ef-10b6-cb982615d58a +# ╟─d843defc-d294-11ef-358b-f56f514dcf93 +# ╟─d843efdc-d294-11ef-0f3a-630ecdd0acee +# ╟─d84422a6-d294-11ef-148b-c762a90cd620 +# ╟─d8449f1a-d294-11ef-3cfa-4fc33a5daa00 +# ╟─4482e857-af6b-4459-a0a2-cd7ad57ed94f +# ╟─d844bcfa-d294-11ef-0874-b154f3ed810b +# ╟─d844d564-d294-11ef-0454-416352d43524 +# ╟─d844fa76-d294-11ef-172a-85e68842c252 +# ╟─63cc56b7-588a-43c3-8327-ad6367608601 +# ╟─acdc5bfa-7188-4a37-80e6-5026ecd1a813 +# ╟─204bec3f-6fde-48c1-b2b6-9f88d484c130 +# ╟─62b42d1d-be91-4740-bac6-b4527494959d +# ╟─01c4c590-fece-49a5-8979-6e0d54f7850a +# ╟─d8443e38-d294-11ef-25db-b16df87850f4 +# ╟─448d0679-b47a-4db9-ad7d-a45786350fef +# ╟─72f24b54-ab22-4a54-9ece-7433048f4769 +# ╟─3c2ee96d-18a6-45d0-a2cf-f2ebbf5e22f0 +# ╟─93b8ac65-ac41-4a03-bddd-5f01ccb5b42d +# ╟─81b5aea0-8101-46e2-a875-1058029ebf99 +# ╟─59fb1e66-cf05-4f2b-8027-7ff3b1a57c15 +# ╠═d3a4a1dc-3fdf-479d-a51c-a1e23073c556 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/mlss/bdv-Nov2025-AIF-lecture.ppsx b/mlss/bdv-Nov2025-AIF-lecture.ppsx new file mode 100644 index 00000000..23b32a2b Binary files /dev/null and b/mlss/bdv-Nov2025-AIF-lecture.ppsx differ diff --git a/mlss/bdv-Nov2025-AIF-lecture.pptx b/mlss/bdv-Nov2025-AIF-lecture.pptx new file mode 100644 index 00000000..f9966b52 Binary files /dev/null and b/mlss/bdv-Nov2025-AIF-lecture.pptx differ