ClusterTree

release/4.3a0
p-zach 2025-04-14 18:59:40 -04:00
parent db8ead2c9a
commit 06a13bed70
1 changed files with 1 additions and 150 deletions

View File

@ -19,156 +19,7 @@
"\n",
"`ClusterTree` itself is a base class. `EliminatableClusterTree` adds the ability to perform elimination, and `JunctionTree` is a specific type of `EliminatableClusterTree` derived from an `EliminationTree`.\n",
"\n",
"Direct use of `ClusterTree` in typical Python applications is less common than `JunctionTree` or `BayesTree`, as it's often an intermediate representation."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "clustertree_colab_md"
},
"source": [
"<a href=\"https://colab.research.google.com/github/borglab/gtsam/blob/develop/gtsam/inference/doc/ClusterTree.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": "clustertree_pip_code",
"tags": [
"remove-cell"
]
},
"outputs": [],
"source": [
"%pip install gtsam"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "clustertree_import_code"
},
"outputs": [],
"source": [
"import gtsam\n",
"import numpy as np\n",
"\n",
"# Note: ClusterTree itself might not be directly exposed or used.\n",
"# We typically interact with JunctionTree or BayesTree which build upon it.\n",
"# We'll demonstrate concepts using JunctionTree which inherits Cluster features.\n",
"from gtsam import GaussianFactorGraph, Ordering, VariableIndex, GaussianBayesTree\n",
"from gtsam import symbol_shorthand\n",
"\n",
"X = symbol_shorthand.X\n",
"L = symbol_shorthand.L"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "clustertree_concept_md"
},
"source": [
"## Concept and Relation to JunctionTree\n",
"\n",
"A `JunctionTree` *is a* `ClusterTree` (specifically, an `EliminatableClusterTree`). It's constructed during multifrontal elimination. Each node in the `JunctionTree` is a `Cluster` containing factors that will be eliminated together to form a clique in the resulting `BayesTree`.\n",
"\n",
"We will create a `JunctionTree` and examine its properties, which include those inherited from `ClusterTree`."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "clustertree_jt_code",
"outputId": "ef012345-6789-abcd-ef01-23456789abcd"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Junction Tree (as ClusterTree): \n",
": cliques: 2, variables: 5\n",
"- p(x1 l2 x2 )\n",
" R = [ 1.61245 -0.620174 -0.620174 ]\n",
" [ 0 1.27098 -1.08941 ]\n",
" [ 0 0 0.654654 ]\n",
" d = [ 0 0 0 ]\n",
" mean: 3 elements\n",
" l2: 0\n",
" x1: 0\n",
" x2: 0\n",
" logNormalizationConstant: -2.46292\n",
" No noise model\n",
"| - p(l1 x0 | x1)\n",
" R = [ 1.41421 -0.707107 ]\n",
" [ 0 1.58114 ]\n",
" S[x1] = [ -0.707107 ]\n",
" [ -0.948683 ]\n",
" d = [ 0 0 ]\n",
" logNormalizationConstant: -1.03316\n",
" No noise model\n"
]
},
{
"ename": "AttributeError",
"evalue": "'gtsam.gtsam.GaussianBayesTree' object has no attribute 'roots'",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[8], line 28\u001b[0m\n\u001b[0;32m 25\u001b[0m bayes_tree\u001b[38;5;241m.\u001b[39mprint() \u001b[38;5;66;03m# Printing BayesTree shows clique structure\u001b[39;00m\n\u001b[0;32m 27\u001b[0m \u001b[38;5;66;03m# Access root cluster(s)\u001b[39;00m\n\u001b[1;32m---> 28\u001b[0m roots \u001b[38;5;241m=\u001b[39m \u001b[43mbayes_tree\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mroots\u001b[49m()\n\u001b[0;32m 29\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m roots:\n\u001b[0;32m 30\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mAccessing a root cluster (node):\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
"\u001b[1;31mAttributeError\u001b[0m: 'gtsam.gtsam.GaussianBayesTree' object has no attribute 'roots'"
]
}
],
"source": [
"# Create a graph (same as BayesTree example)\n",
"graph = GaussianFactorGraph()\n",
"model = gtsam.noiseModel.Isotropic.Sigma(1, 1.0)\n",
"graph.add(X(0), -np.eye(1), np.zeros(1), model)\n",
"graph.add(X(0), -np.eye(1), X(1), np.eye(1), np.zeros(1), model)\n",
"graph.add(X(1), -np.eye(1), X(2), np.eye(1), np.zeros(1), model)\n",
"graph.add(L(1), -np.eye(1), X(0), np.eye(1), np.zeros(1), model)\n",
"graph.add(L(1), -np.eye(1), X(1), np.eye(1), np.zeros(1), model)\n",
"graph.add(L(2), -np.eye(1), X(1), np.eye(1), np.zeros(1), model)\n",
"graph.add(L(2), -np.eye(1), X(2), np.eye(1), np.zeros(1), model)\n",
"\n",
"ordering = Ordering.Colamd(VariableIndex(graph))\n",
"\n",
"# Create a Junction Tree (implicitly uses ClusterTree structure)\n",
"# Note: JunctionTree constructor might not be directly exposed.\n",
"# It's usually an intermediate in eliminateMultifrontal.\n",
"# We might need to construct it indirectly or focus on BayesTree access.\n",
"\n",
"# Let's get the BayesTree first, as JunctionTree creation is internal.\n",
"bayes_tree = graph.eliminateMultifrontal(ordering)\n",
"\n",
"# We can print the BayesTree, which shows the cluster structure\n",
"# (Cliques in BayesTree correspond to Clusters in JunctionTree)\n",
"print(\"Junction Tree (as ClusterTree): \")\n",
"bayes_tree.print() # Printing BayesTree shows clique structure\n",
"\n",
"# Access root cluster(s)\n",
"roots = bayes_tree.roots()\n",
"if roots:\n",
" print(\"\\nAccessing a root cluster (node):\")\n",
" root_clique = roots[0]\n",
" # In the JunctionTree, this node would contain the factors that *produced*\n",
" # the conditional in the BayesTree clique. We can see the involved keys.\n",
" root_clique.print(\"\", gtsam.DefaultKeyFormatter) # Print clique details\n",
"\n",
"print(f\"\\nNumber of roots: {len(roots)}\")\n",
"\n",
"# Direct instantiation or manipulation of Cluster/JunctionTree nodes\n",
"# is less common in Python than using the results (BayesTree)."
"Direct use of `ClusterTree` in Python applications is uncommon; see the subclasses."
]
}
],