gtsam/gtsam/inference/doc/Conditional.ipynb

267 lines
8.7 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "conditional_intro_md"
},
"source": [
"# Conditional"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "conditional_desc_md"
},
"source": [
"`gtsam.Conditional` is the base class for conditional probability distributions or densities that result from variable elimination.\n",
"\n",
"Let $F$ be the set of frontal variables and $S$ be the set of parent (separator) variables. A conditional represents:\n",
"\n",
"$$\n",
"P(F | S)\n",
"$$\n",
"The methods `evaluate`, `logProbability`, and `error` are related:\n",
"$$\n",
"\\text{evaluate}(F, S) = P(F | S)\n",
"$$\n",
"$$\n",
"\\text{logProbability}(F, S) = \\log P(F | S)\n",
"$$\n",
"$$\n",
"\\text{logProbability}(F, S) = -(\\text{negLogConstant} + \\text{error}(F, S))\n",
"$$\n",
"where `negLogConstant` is $-\\log k$ for the normalization constant $k$ ensuring $\\int P(F|S) dF = 1$.\n",
"\n",
"Like `gtsam.Factor`, you typically don't instantiate `gtsam.Conditional` directly. Instead, you work with derived classes obtained from elimination, such as:\n",
"* `gtsam.GaussianConditional`\n",
"* `gtsam.DiscreteConditional`\n",
"* `gtsam.HybridGaussianConditional`\n",
"* `gtsam.SymbolicConditional`\n",
"\n",
"This notebook demonstrates the common interface provided by the base class."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "conditional_colab_md"
},
"source": [
"<a href=\"https://colab.research.google.com/github/borglab/gtsam/blob/develop/gtsam/inference/doc/Conditional.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "conditional_pip_code",
"tags": [
"remove-cell"
]
},
"outputs": [],
"source": [
"%pip install --quiet gtsam-develop"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "conditional_import_code"
},
"outputs": [],
"source": [
"import gtsam\n",
"import numpy as np\n",
"\n",
"# We need concrete graph types and elimination to get a Conditional\n",
"from gtsam import GaussianFactorGraph, Ordering\n",
"from gtsam import symbol_shorthand\n",
"\n",
"X = symbol_shorthand.X\n",
"L = symbol_shorthand.L"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "conditional_example_md"
},
"source": [
"## Example: Obtaining and Inspecting a Conditional\n",
"\n",
"We'll create a simple `GaussianFactorGraph` and eliminate one variable to get a `GaussianConditional`."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "conditional_create_code",
"outputId": "def01234-5678-9abc-def0-123456789abc"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Eliminating x0 from graph:\n",
"\n",
"size: 2\n",
"factor 0: \n",
" A[x0] = [\n",
"\t-1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 1: \n",
" A[x0] = [\n",
"\t-1\n",
"]\n",
" A[x1] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"\n",
"Resulting BayesNet:\n",
"\n",
"size: 1\n",
"conditional 0: p(x0 | x1)\n",
" R = [ 1.41421 ]\n",
" S[x1] = [ -0.707107 ]\n",
" d = [ 0 ]\n",
" logNormalizationConstant: -0.572365\n",
" No noise model\n",
"Conditional Keys (all): [8646911284551352320, 8646911284551352321]\n",
"First Frontal Key: 8646911284551352320 (x0)\n"
]
}
],
"source": [
"# Create a simple Gaussian Factor Graph P(x0) P(x1|x0)\n",
"graph = GaussianFactorGraph()\n",
"model1 = gtsam.noiseModel.Isotropic.Sigma(1, 1.0)\n",
"model2 = gtsam.noiseModel.Isotropic.Sigma(1, 1.0)\n",
"\n",
"# Prior on x0\n",
"graph.add(X(0), -np.eye(1), np.zeros(1), model1)\n",
"# Factor between x0 and x1\n",
"graph.add(X(0), -np.eye(1), X(1), np.eye(1), np.zeros(1), model2)\n",
"\n",
"print(\"Eliminating x0 from graph:\")\n",
"graph.print()\n",
"\n",
"# Eliminate x0\n",
"ordering = Ordering([X(0)])\n",
"bayes_net, remaining_graph = graph.eliminatePartialSequential(ordering)\n",
"\n",
"print(\"\\nResulting BayesNet:\")\n",
"bayes_net.print()\n",
"\n",
"# Get the resulting conditional P(x0 | x1)\n",
"# In this case, it's a GaussianConditional\n",
"conditional = bayes_net.at(0) # or bayes_net[0]\n",
"\n",
"# Access methods from the Conditional base class\n",
"print(f\"Conditional Keys (all): {conditional.keys()}\")\n",
"print(f\"First Frontal Key: {conditional.firstFrontalKey()} ({gtsam.DefaultKeyFormatter(conditional.firstFrontalKey())})\")\n",
"\n",
"# Conditional objects can also be printed\n",
"# conditional.print(\"P(x0 | x1): \")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "conditional_eval_md"
},
"source": [
"## Evaluation (Derived Class Methods)\n",
"\n",
"Concrete conditional classes provide methods like `logProbability(values)` or `evaluate(values)` to compute the conditional probability (or density) given values for the parent variables. These methods are defined in the derived classes, not the `Conditional` base class itself."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "conditional_eval_code"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Log Probability P(x0|x1=1.0): -0.8223649429247\n",
"Probability P(x0|x1=1.0): 0.43939128946772243\n"
]
},
{
"data": {
"text/plain": [
"-0.8223649429247"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Example for GaussianConditional (requires VectorValues)\n",
"vector_values = gtsam.VectorValues()\n",
"vector_values.insert(X(0), np.array([0.0])) # Value for frontal variable\n",
"vector_values.insert(X(1), np.array([1.0])) # Value for parent variable\n",
"\n",
"# These methods are specific to GaussianConditional / other concrete types\n",
"try:\n",
" log_prob = conditional.logProbability(vector_values)\n",
" print(f\"\\nLog Probability P(x0|x1=1.0): {log_prob}\")\n",
" prob = conditional.evaluate(vector_values)\n",
" print(f\"Probability P(x0|x1=1.0): {prob}\")\n",
"except AttributeError:\n",
" print(\"\\nNote: logProbability/evaluate called on base Conditional pointer, needs derived type.\")\n",
" # In C++, you'd typically have a shared_ptr<GaussianConditional>.\n",
" # In Python, if you know the type, you might access methods directly,\n",
" # but the base class wrapper doesn't expose derived methods.\n",
" pass\n",
"\n",
"# To properly evaluate, you often use the BayesNet/BayesTree directly\n",
"bayes_net.logProbability(vector_values)"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}