Fixing code & adding formulae

release/4.3a0
p-zach 2025-04-10 10:38:46 -04:00
parent bf885764c7
commit aae8b5d140
16 changed files with 4174 additions and 3632 deletions

View File

@ -19,6 +19,16 @@
"\n",
"It is essentially a collection of `Conditional` objects, ordered according to the elimination order. Each conditional represents $P(\text{variable} | \text{parents})$, where the parents are variables that appear later in the elimination ordering.\n",
"\n",
"A Bayes net represents the joint probability distribution as a product of conditional probabilities stored in the net:\n",
"\n",
"$$\n",
"P(X_1, X_2, \\dots, X_N) = \\prod_{i=1}^N P(X_i | \\text{Parents}(X_i))\n",
"$$\n",
"The total log-probability of an assignment is the sum of the log-probabilities of its conditionals:\n",
"$$\n",
"\\log P(X_1, \\dots, X_N) = \\sum_{i=1}^N \\log P(X_i | \\text{Parents}(X_i))\n",
"$$\n",
"\n",
"Like `FactorGraph`, `BayesNet` is templated on the type of conditional it stores (e.g., `GaussianBayesNet`, `DiscreteBayesNet`)."
]
},
@ -44,7 +54,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {
"id": "bayesnet_import_code"
},
@ -74,12 +84,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "bayesnet_eliminate_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayesnet_eliminate_code",
"outputId": "01234567-89ab-cdef-0123-456789abcdef"
},
"outputs": [
@ -87,17 +97,56 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Original Factor Graph: size 3\n",
"Factor 0: JacobianFactor(keys = [8070450532247928832], Z = [ -1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 1: JacobianFactor(keys = [8070450532247928832; 8070450532247928833], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 2: JacobianFactor(keys = [8070450532247928833; 8070450532247928834], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Original Factor Graph:\n",
"\n",
"size: 3\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",
"factor 2: \n",
" A[x1] = [\n",
"\t-1\n",
"]\n",
" A[x2] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"\n",
"Resulting BayesNet: size 3\n",
"Conditional 0: GaussianConditional( P(x0 | x1) = dx0 - R*dx1 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.707107 ])\n",
"Conditional 1: GaussianConditional( P(x1 | x2) = dx1 - R*dx2 - d), R = [ 0.666667 ], d = [ 0 ], sigmas = [ 0.816497 ])\n",
"Conditional 2: GaussianConditional( P(x2) = dx2 - d), d = [ 0 ], sigmas = [ 0.866025 ])\n",
"\n"
"Resulting BayesNet:\n",
"\n",
"size: 3\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 1: p(x1 | x2)\n",
" R = [ 1.22474 ]\n",
" S[x2] = [ -0.816497 ]\n",
" d = [ 0 ]\n",
" logNormalizationConstant: -0.716206\n",
" No noise model\n",
"conditional 2: p(x2)\n",
" R = [ 0.57735 ]\n",
" d = [ 0 ]\n",
" mean: 1 elements\n",
" x2: 0\n",
" logNormalizationConstant: -1.46824\n",
" No noise model\n"
]
}
],
@ -132,12 +181,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {
"id": "bayesnet_access_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayesnet_access_code",
"outputId": "12345678-9abc-def0-1234-56789abcdef0"
},
"outputs": [
@ -146,17 +195,19 @@
"output_type": "stream",
"text": [
"BayesNet size: 3\n",
"Is BayesNet empty? False\n",
"Conditional at index 1: \n",
"GaussianConditional( P(x1 | x2) = dx1 - R*dx2 - d), R = [ 0.666667 ], d = [ 0 ], sigmas = [ 0.816497 ])\n",
"\n",
"Keys in BayesNet: {8070450532247928832, 8070450532247928833, 8070450532247928834}\n"
"GaussianConditional p(x1 | x2)\n",
" R = [ 1.22474 ]\n",
" S[x2] = [ -0.816497 ]\n",
" d = [ 0 ]\n",
" logNormalizationConstant: -0.716206\n",
" No noise model\n",
"Keys in BayesNet: x0x1x2\n"
]
}
],
"source": [
"print(f\"BayesNet size: {bayes_net.size()}\")\n",
"print(f\"Is BayesNet empty? {bayes_net.empty()}\")\n",
"\n",
"# Access conditional by index\n",
"conditional1 = bayes_net.at(1)\n",
@ -165,12 +216,7 @@
"\n",
"# Get all keys involved\n",
"bn_keys = bayes_net.keys()\n",
"print(f\"Keys in BayesNet: {bn_keys}\")\n",
"\n",
"# Iterate through conditionals\n",
"# for i, conditional in enumerate(bayes_net):\n",
"# if conditional:\n",
"# print(f\"Conditional {i} Frontals: {conditional.frontals()}, Parents: {conditional.parents()}\")"
"print(f\"Keys in BayesNet: {bn_keys}\")"
]
},
{
@ -186,12 +232,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "bayesnet_eval_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayesnet_eval_code",
"outputId": "23456789-abcd-ef01-2345-6789abcdef01"
},
"outputs": [
@ -199,13 +245,12 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Log Probability at [0,0,0]: -2.756815765004782\n",
"Log Probability at 0,0,0]: -2.7568155996140185\n",
"Optimized Solution (MLE):\n",
"Values with 3 values:\n",
"Value x0: [0.]\n",
"Value x1: [0.]\n",
"Value x2: [0.]\n",
"\n"
"VectorValues: 3 elements\n",
" x0: 0\n",
" x1: 0\n",
" x2: 0\n"
]
}
],
@ -234,12 +279,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"metadata": {
"id": "bayesnet_dot_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayesnet_dot_code",
"outputId": "3456789a-bcde-f012-3456-789abcdef012"
},
"outputs": [
@ -250,14 +295,68 @@
"digraph {\n",
" size=\"5,5\";\n",
"\n",
" var8070450532247928832[label=\"x0\"];\n",
" var8070450532247928833[label=\"x1\"];\n",
" var8070450532247928834[label=\"x2\"];\n",
" var8646911284551352320[label=\"x0\"];\n",
" var8646911284551352321[label=\"x1\"];\n",
" var8646911284551352322[label=\"x2\"];\n",
"\n",
" var8070450532247928834->var8070450532247928833\n",
" var8070450532247928833->var8070450532247928832\n",
" var8646911284551352322->var8646911284551352321\n",
" var8646911284551352321->var8646911284551352320\n",
"}\n"
]
},
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.50.0 (0)\n",
" -->\n",
"<!-- Pages: 1 -->\n",
"<svg width=\"62pt\" height=\"188pt\"\n",
" viewBox=\"0.00 0.00 62.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-184 58,-184 58,4 -4,4\"/>\n",
"<!-- var8646911284551352320 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>var8646911284551352320</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x0</text>\n",
"</g>\n",
"<!-- var8646911284551352321 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>var8646911284551352321</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-86.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x1</text>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&gt;var8646911284551352320 -->\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&gt;var8646911284551352320</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M27,-71.7C27,-63.98 27,-54.71 27,-46.11\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"30.5,-46.1 27,-36.1 23.5,-46.1 30.5,-46.1\"/>\n",
"</g>\n",
"<!-- var8646911284551352322 -->\n",
"<g id=\"node3\" class=\"node\">\n",
"<title>var8646911284551352322</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x2</text>\n",
"</g>\n",
"<!-- var8646911284551352322&#45;&gt;var8646911284551352321 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>var8646911284551352322&#45;&gt;var8646911284551352321</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M27,-143.7C27,-135.98 27,-126.71 27,-118.11\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"30.5,-118.1 27,-108.1 23.5,-118.1 30.5,-118.1\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.sources.Source at 0x2c3022fcc20>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
@ -266,8 +365,8 @@
"\n",
"# To render:\n",
"# dot -Tpng bayesnet.dot -o bayesnet.png\n",
"# import graphviz\n",
"# graphviz.Source(dot_string)"
"import graphviz\n",
"graphviz.Source(dot_string)"
]
}
],
@ -276,11 +375,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -17,6 +17,17 @@
"source": [
"A `BayesTree` is a graphical model that represents the result of multifrontal variable elimination on a `FactorGraph`. It is a tree structure where each node is a 'clique' containing a set of conditional distributions $P(\text{Frontals} | \text{Separator})$.\n",
"\n",
"Each clique k contains a conditional $P(F_kS_k)$, where $F_k$ are frontal variables and $S_k$ are separator variables. The joint probability distribution encoded by the Bayes tree is given by the product of all clique conditionals:\n",
"\n",
"$$\n",
"P(X) = \\prod_k P(F_k | S_k)\n",
"$$\n",
"Alternatively, it can be expressed using clique $P(C_k) = P(F_k, S_k)$ and separator $P(S_k)$ marginals (though GTSAM stores conditionals):\n",
"$$\n",
"P(X) = \\frac{\\prod_{\\text{cliques } k} P(C_k)}{\\prod_{\\text{separators } S} P(S)^{\\nu(S)-1}}\n",
"$$\n",
"where $\\nu(S)$ is the number of cliques containing the separator $S$. The first formula $P(X) = \\prod_k P(F_k | S_k)$ is more directly related to the GTSAM `BayesTree` structure.\n",
"\n",
"Key properties:\n",
"* **Cliques:** Each node (clique) groups variables that are eliminated together.\n",
"* **Frontal Variables:** Variables eliminated within a specific clique.\n",
@ -37,18 +48,28 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {
"id": "bayestree_pip_code"
},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: gtsam in c:\\users\\porte\\miniconda3\\envs\\gtsam\\lib\\site-packages (4.3a0)Note: you may need to restart the kernel to use updated packages.\n",
"\n",
"Requirement already satisfied: numpy>=1.11.0 in c:\\users\\porte\\miniconda3\\envs\\gtsam\\lib\\site-packages (from gtsam) (2.2.1)\n"
]
}
],
"source": [
"%pip install gtsam"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "bayestree_import_code"
},
@ -58,7 +79,7 @@
"import numpy as np\n",
"\n",
"# We need concrete graph types and elimination to get a BayesTree\n",
"from gtsam import GaussianFactorGraph, Ordering, GaussianBayesTree\n",
"from gtsam import GaussianFactorGraph, Ordering, GaussianBayesTree, VariableIndex\n",
"from gtsam import symbol_shorthand\n",
"\n",
"X = symbol_shorthand.X\n",
@ -78,12 +99,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {
"id": "bayestree_eliminate_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayestree_eliminate_code",
"outputId": "456789ab-cdef-0123-4567-89abcdef0123"
},
"outputs": [
@ -91,39 +112,91 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Original Factor Graph: size 7\n",
"Factor 0: JacobianFactor(keys = [8070450532247928832], Z = [ -1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 1: JacobianFactor(keys = [8070450532247928832; 8070450532247928833], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 2: JacobianFactor(keys = [8070450532247928833; 8070450532247928834], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 3: JacobianFactor(keys = [7783684379976990720; 8070450532247928832], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 4: JacobianFactor(keys = [7783684379976990720; 8070450532247928833], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 5: JacobianFactor(keys = [7783684379976990721; 8070450532247928833], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 6: JacobianFactor(keys = [7783684379976990721; 8070450532247928834], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Original Factor Graph:\n",
"\n",
"size: 7\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",
"factor 2: \n",
" A[x1] = [\n",
"\t-1\n",
"]\n",
" A[x2] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 3: \n",
" A[l1] = [\n",
"\t-1\n",
"]\n",
" A[x0] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 4: \n",
" A[l1] = [\n",
"\t-1\n",
"]\n",
" A[x1] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 5: \n",
" A[l2] = [\n",
"\t-1\n",
"]\n",
" A[x1] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"factor 6: \n",
" A[l2] = [\n",
"\t-1\n",
"]\n",
" A[x2] = [\n",
"\t1\n",
"]\n",
" b = [ 0 ]\n",
" Noise model: unit (1) \n",
"\n",
"Resulting BayesTree: cliques: 3, variables: 5\n",
"Root(s):\n",
"Conditional density P(l1, x1 | l2, x2) = P(l1 | x1) P(x1 | l2, x2) \n",
" size: 2\n",
" Conditional P(l1 | x1): GaussianConditional( P(l1 | x1) = dl1 - R*dx1 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.866025 ])\n",
"\n",
" Conditional P(x1 | l2, x2): GaussianConditional( P(x1 | l2, x2) = dx1 - R1*dl2 - R2*dx2 - d), R1 = [ 0.333333 ], R2 = [ 0.333333 ], d = [ 0 ], sigmas = [ 0.745356 ])\n",
"\n",
"\n",
" Children:\n",
" Conditional density P(l2, x2 | x0) = P(l2 | x2) P(x2 | x0) \n",
" size: 2\n",
" Conditional P(l2 | x2): GaussianConditional( P(l2 | x2) = dl2 - R*dx2 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.866025 ])\n",
"\n",
" Conditional P(x2 | x0): GaussianConditional( P(x2 | x0) = dx2 - R*dx0 - d), R = [ 0.2 ], d = [ 0 ], sigmas = [ 0.774597 ])\n",
"\n",
"\n",
" Children:\n",
" Conditional density P(x0) = P(x0) \n",
" size: 1\n",
" Conditional P(x0): GaussianConditional( P(x0) = dx0 - d), d = [ 0 ], sigmas = [ 0.894427 ])\n",
"\n",
"\n"
"Resulting BayesTree:\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"
]
}
],
@ -143,7 +216,7 @@
"graph.print()\n",
"\n",
"# Eliminate multifrontally using COLAMD ordering\n",
"ordering = Ordering.Colamd(graph)\n",
"ordering = Ordering.Colamd(VariableIndex(graph))\n",
"# Note: Multifrontal typically yields multiple roots if graph is disconnected\n",
"bayes_tree = graph.eliminateMultifrontal(ordering)\n",
"\n",
@ -164,12 +237,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "bayestree_access_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayestree_access_code",
"outputId": "56789abc-def0-1234-5678-9abcdef01234"
},
"outputs": [
@ -177,18 +250,18 @@
"name": "stdout",
"output_type": "stream",
"text": [
"BayesTree number of cliques: 3\n",
"Number of roots: 1\n",
"Root clique 0 conditional frontals: [7783684379976990720, 8070450532247928833]\n",
"\n",
"Clique containing x1 (8070450532247928833):\n",
"Conditional density P(l1, x1 | l2, x2) = P(l1 | x1) P(x1 | l2, x2) \n",
" size: 2\n",
" Conditional P(l1 | x1): GaussianConditional( P(l1 | x1) = dl1 - R*dx1 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.866025 ])\n",
"\n",
" Conditional P(x1 | l2, x2): GaussianConditional( P(x1 | l2, x2) = dx1 - R1*dl2 - R2*dx2 - d), R1 = [ 0.333333 ], R2 = [ 0.333333 ], d = [ 0 ], sigmas = [ 0.745356 ])\n",
"\n",
"\n"
"BayesTree number of cliques: 2\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[4], line 4\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mBayesTree number of cliques: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mbayes_tree\u001b[38;5;241m.\u001b[39msize()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 3\u001b[0m \u001b[38;5;66;03m# Access roots\u001b[39;00m\n\u001b[1;32m----> 4\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 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNumber of roots: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mlen\u001b[39m(roots)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 6\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m roots:\n\u001b[0;32m 7\u001b[0m \u001b[38;5;66;03m# Access the conditional associated with the first root clique\u001b[39;00m\n",
"\u001b[1;31mAttributeError\u001b[0m: 'gtsam.gtsam.GaussianBayesTree' object has no attribute 'roots'"
]
}
],
@ -223,12 +296,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"metadata": {
"id": "bayestree_solve_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayestree_solve_code",
"outputId": "6789abcd-ef01-2345-6789-abcdef012345"
},
"outputs": [
@ -237,25 +310,38 @@
"output_type": "stream",
"text": [
"Optimized Solution (MLE):\n",
"Values with 5 values:\n",
"Value l1: [0.]\n",
"Value l2: [0.]\n",
"Value x0: [0.]\n",
"Value x1: [0.]\n",
"Value x2: [0.]\n",
"\n",
"VectorValues: 5 elements\n",
" l1: 0\n",
" l2: 0\n",
" x0: 0\n",
" x1: 0\n",
" x2: 0\n",
"\n",
"Marginal Factor on x1:\n",
"Conditional density P(x1 | l2, x2) = P(x1 | l2, x2) \n",
" size: 1\n",
" Conditional P(x1 | l2, x2): GaussianConditional( P(x1 | l2, x2) = dx1 - R1*dl2 - R2*dx2 - d), R1 = [ 0.333333 ], R2 = [ 0.333333 ], d = [ 0 ], sigmas = [ 0.745356 ])\n",
"\n",
"GaussianConditional p(x1)\n",
" R = [ 0.774597 ]\n",
" d = [ 0 ]\n",
" mean: 1 elements\n",
" x1: 0\n",
" logNormalizationConstant: -1.17435\n",
" No noise model\n",
"\n",
"Joint Marginal Factor Graph on (x0, x2):\n",
"Factor Graph: size 2\n",
"Factor 0: GaussianConditional( P(x0 | x2) = dx0 - R*dx2 - d), R = [ 0.25 ], d = [ 0 ], sigmas = [ 0.866025 ])\n",
"Factor 1: GaussianConditional( P(x2) = dx2 - d), d = [ 0 ], sigmas = [ 0.774597 ])\n",
"\n"
"\n",
"size: 2\n",
"factor 0: p(x0 | x2)\n",
" R = [ 1.32288 ]\n",
" S[x2] = [ -0.566947 ]\n",
" d = [ 0 ]\n",
" logNormalizationConstant: -0.639131\n",
" No noise model\n",
"factor 1: p(x2)\n",
" R = [ 0.654654 ]\n",
" d = [ 0 ]\n",
" mean: 1 elements\n",
" x2: 0\n",
" logNormalizationConstant: -1.34259\n",
" No noise model\n"
]
}
],
@ -289,12 +375,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {
"id": "bayestree_dot_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "bayestree_dot_code",
"outputId": "789abcde-f012-3456-789a-bcdef0123456"
},
"outputs": [
@ -303,13 +389,54 @@
"output_type": "stream",
"text": [
"digraph G{\n",
"0[label=\"l1, x1 : l2, x2\"];\n",
"0[label=\"x1, l2, x2\"];\n",
"0->1\n",
"1[label=\"l2, x2 : x0\"];\n",
"1->2\n",
"2[label=\"x0 : \"];\n",
"}"
"1[label=\"l1, x0 : x1\"];\n",
"}\n"
]
},
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.50.0 (0)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"103pt\" height=\"116pt\"\n",
" viewBox=\"0.00 0.00 102.89 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-112 98.89,-112 98.89,4 -4,4\"/>\n",
"<!-- 0 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>0</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"47.45\" cy=\"-90\" rx=\"44.69\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"47.45\" y=\"-86.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x1, l2, x2</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>1</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"47.45\" cy=\"-18\" rx=\"47.39\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"47.45\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">l1, x0 : x1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M47.45,-71.7C47.45,-63.98 47.45,-54.71 47.45,-46.11\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"50.95,-46.1 47.45,-36.1 43.95,-46.1 50.95,-46.1\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.sources.Source at 0x1241c40dbe0>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
@ -318,8 +445,8 @@
"\n",
"# To render:\n",
"# dot -Tpng bayestree.dot -o bayestree.png\n",
"# import graphviz\n",
"# graphviz.Source(dot_string)"
"import graphviz\n",
"graphviz.Source(dot_string)"
]
}
],
@ -328,11 +455,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -33,28 +33,40 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {
"id": "clustertree_pip_code"
},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: gtsam in c:\\users\\porte\\miniconda3\\envs\\gtsam\\lib\\site-packages (4.3a0)Note: you may need to restart the kernel to use updated packages.\n",
"\n",
"Requirement already satisfied: numpy>=1.11.0 in c:\\users\\porte\\miniconda3\\envs\\gtsam\\lib\\site-packages (from gtsam) (2.2.1)\n"
]
}
],
"source": [
"%pip install gtsam"
]
},
{
"cell_type": "code",
"execution_count": null,
"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, JunctionTree, GaussianBayesTree\n",
"from gtsam import GaussianFactorGraph, Ordering, VariableIndex, GaussianBayesTree\n",
"from gtsam import symbol_shorthand\n",
"\n",
"X = symbol_shorthand.X\n",
@ -76,12 +88,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 8,
"metadata": {
"id": "clustertree_jt_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "clustertree_jt_code",
"outputId": "ef012345-6789-abcd-ef01-23456789abcd"
},
"outputs": [
@ -90,21 +102,37 @@
"output_type": "stream",
"text": [
"Junction Tree (as ClusterTree): \n",
"Root(s):\n",
"Cluster (1) keys: l1 x1 \n",
" Factor 0: JacobianFactor(keys = [7783684379976990720; 8070450532247928833], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
" Children:\n",
" Cluster (1) keys: l2 x2 \n",
" Factor 0: JacobianFactor(keys = [7783684379976990721; 8070450532247928834], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
" Children:\n",
" Cluster (1) keys: x0 \n",
" Factor 0: JacobianFactor(keys = [8070450532247928832], Z = [ -1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"\n",
"Accessing a root cluster (node):\n",
"Cluster (1) keys: l1 x1 \n",
" Factor 0: JacobianFactor(keys = [7783684379976990720; 8070450532247928833], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"\n",
"Number of roots: 1\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'"
]
}
],
@ -120,7 +148,7 @@
"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(graph)\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",
@ -156,11 +184,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -15,7 +15,24 @@
"id": "conditional_desc_md"
},
"source": [
"`gtsam.Conditional` is the base class for conditional probability distributions or densities that result from variable elimination. Conditionals are essentially specialized factors representing $P(\text{Frontals} | \text{Parents})$.\n",
"`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",
@ -37,18 +54,28 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {
"id": "conditional_pip_code"
},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: gtsam in c:\\users\\porte\\miniconda3\\envs\\gtsam\\lib\\site-packages (4.3a0)\n",
"Requirement already satisfied: numpy>=1.11.0 in c:\\users\\porte\\miniconda3\\envs\\gtsam\\lib\\site-packages (from gtsam) (2.2.1)\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"%pip install gtsam"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "conditional_import_code"
},
@ -78,12 +105,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {
"id": "conditional_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "conditional_create_code",
"outputId": "def01234-5678-9abc-def0-123456789abc"
},
"outputs": [
@ -92,21 +119,35 @@
"output_type": "stream",
"text": [
"Eliminating x0 from graph:\n",
"Factor Graph: size 2\n",
"Factor 0: JacobianFactor(keys = [8070450532247928832], Z = [ -1 ], b = [ 0 ], model = diagonal sigmas [1])\n",
"Factor 1: JacobianFactor(keys = [8070450532247928832; 8070450532247928833], A[0] = [ -1 1 ], b = [ 0 ], model = diagonal sigmas [1])\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: size 1\n",
"Conditional 0: GaussianConditional( P(x0 | x1) = dx0 - R*dx1 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.707107 ])\n",
"Resulting BayesNet:\n",
"\n",
"\n",
"Conditional Keys (all): [8070450532247928832, 8070450532247928833]\n",
"Number of Frontals: 1\n",
"Frontal Keys: [8070450532247928832] (x0)\n",
"First Frontal Key: 8070450532247928832 (x0)\n",
"Number of Parents: 1\n",
"Parent Keys: [8070450532247928833] (x1)\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"
]
}
],
@ -137,11 +178,7 @@
"\n",
"# Access methods from the Conditional base class\n",
"print(f\"Conditional Keys (all): {conditional.keys()}\")\n",
"print(f\"Number of Frontals: {conditional.nrFrontals()}\")\n",
"print(f\"Frontal Keys: {conditional.frontals()} ({gtsam.DefaultKeyFormatter(list(conditional.frontals())[0])})\")\n",
"print(f\"First Frontal Key: {conditional.firstFrontalKey()} ({gtsam.DefaultKeyFormatter(conditional.firstFrontalKey())})\")\n",
"print(f\"Number of Parents: {conditional.nrParents()}\")\n",
"print(f\"Parent Keys: {conditional.parents()} ({gtsam.DefaultKeyFormatter(list(conditional.parents())[0])})\")\n",
"\n",
"# Conditional objects can also be printed\n",
"# conditional.print(\"P(x0 | x1): \")"
@ -160,23 +197,43 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 9,
"metadata": {
"id": "conditional_eval_code"
},
"outputs": [],
"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(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",
" 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",
" 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",
@ -185,7 +242,7 @@
" pass\n",
"\n",
"# To properly evaluate, you often use the BayesNet/BayesTree directly\n",
"# bayes_net.logProbability(vector_values)"
"bayes_net.logProbability(vector_values)"
]
}
],
@ -194,11 +251,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -42,7 +42,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "dotwriter_import_code"
},
@ -72,7 +72,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {
"id": "dotwriter_config_code"
},
@ -120,136 +120,168 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "dotwriter_graph_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "dotwriter_graph_code",
"outputId": "bcdef012-3456-789a-bcde-f0123456789a"
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"288pt\" height=\"180pt\" viewBox=\"0 0 288 180\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 176)\">\n",
"<title>%0</title>\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-176 284,-176 284,4 -4,4\"></polygon>\n",
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.50.0 (0)\n",
" -->\n",
"<!-- Pages: 1 -->\n",
"<svg width=\"350pt\" height=\"84pt\"\n",
" viewBox=\"0.00 0.00 350.00 83.60\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 79.6)\">\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-79.6 346,-79.6 346,4 -4,4\"/>\n",
"<!-- var7782220156096217089 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>var8070450532247928832</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"0\" cy=\"-168\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"0\" y=\"-164.3\" font-family=\"Times,serif\" font-size=\"14.00\">x0</text>\n",
"</g>\n",
"<g id=\"node6\" class=\"node\">\n",
"<title>factor0</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"0\" cy=\"-86\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>var8070450532247928832&#45;&#45;factor0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M0,-149.7C0,-136.29 0,-116.94 0,-100.2\"/>\n",
"</g>\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>var8070450532247928833</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"72\" cy=\"-168\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"72\" y=\"-164.3\" font-family=\"Times,serif\" font-size=\"14.00\">x1</text>\n",
"</g>\n",
"<g id=\"node7\" class=\"node\">\n",
"<title>factor1</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"36\" cy=\"-86\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>var8070450532247928832&#45;&#45;factor1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M10.86,-151.33C16.65,-138.34 25.54,-118.42 31.25,-104.29\"/>\n",
"</g>\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>var8070450532247928833&#45;&#45;factor1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M61.14,-151.33C55.35,-138.34 46.46,-118.42 40.75,-104.29\"/>\n",
"</g>\n",
"<g id=\"node3\" class=\"node\">\n",
"<title>var8070450532247928834</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"144\" cy=\"-168\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"144\" y=\"-164.3\" font-family=\"Times,serif\" font-size=\"14.00\">x2</text>\n",
"</g>\n",
"<g id=\"node8\" class=\"node\">\n",
"<title>factor2</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"108\" cy=\"-86\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<g id=\"edge4\" class=\"edge\">\n",
"<title>var8070450532247928833&#45;&#45;factor2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M82.86,-151.33C88.65,-138.34 97.54,-118.42 103.25,-104.29\"/>\n",
"</g>\n",
"<g id=\"edge5\" class=\"edge\">\n",
"<title>var8070450532247928834&#45;&#45;factor2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M133.14,-151.33C127.35,-138.34 118.46,-118.42 112.75,-104.29\"/>\n",
"</g>\n",
"<g id=\"node4\" class=\"node\">\n",
"<title>var7783684379976990720</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"36,-36 0,-36 0,0 36,0 36,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"18\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">l1</text>\n",
"<title>var7782220156096217089</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"126,-75.6 72,-75.6 72,-39.6 126,-39.6 126,-75.6\"/>\n",
"<text text-anchor=\"middle\" x=\"99\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">l1</text>\n",
"</g>\n",
"<!-- factor3 -->\n",
"<g id=\"node9\" class=\"node\">\n",
"<title>factor3</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"9\" cy=\"-86\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<g id=\"edge6\" class=\"edge\">\n",
"<title>var7783684379976990720&#45;&#45;factor3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M15.54,-36.4C14.23,-45.91 12.2,-60.18 10.73,-71.73\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"75\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var7782220156096217089&#45;&#45;factor3 -->\n",
"<g id=\"edge7\" class=\"edge\">\n",
"<title>var8070450532247928832&#45;&#45;factor3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M2.46,-149.6C3.77,-140.09 5.8,-125.82 7.27,-114.27\"/>\n",
"<title>var7782220156096217089&#45;&#45;factor3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M91.41,-39.58C85.25,-25.79 77.31,-7.97 75.42,-3.73\"/>\n",
"</g>\n",
"<!-- factor4 -->\n",
"<g id=\"node10\" class=\"node\">\n",
"<title>factor4</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"63\" cy=\"-86\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<g id=\"edge8\" class=\"edge\">\n",
"<title>var7783684379976990720&#45;&#45;factor4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M28.86,-36.4C36.18,-46.75 47.65,-62.56 55.44,-73.58\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"123\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var7782220156096217089&#45;&#45;factor4 -->\n",
"<g id=\"edge9\" class=\"edge\">\n",
"<title>var8070450532247928833&#45;&#45;factor4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M70.01,-149.85C68.75,-140.33 66.89,-126.08 65.46,-114.56\"/>\n",
"<title>var7782220156096217089&#45;&#45;factor4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M106.59,-39.58C112.75,-25.79 120.69,-7.97 122.58,-3.73\"/>\n",
"</g>\n",
"<g id=\"node5\" class=\"node\">\n",
"<title>var7783684379976990721</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"108,-36 72,-36 72,0 108,0 108,-36\"/>\n",
"<text text-anchor=\"middle\" x=\"90\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">l2</text>\n",
"<!-- var7782220156096217090 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>var7782220156096217090</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"342,-75.6 288,-75.6 288,-39.6 342,-39.6 342,-75.6\"/>\n",
"<text text-anchor=\"middle\" x=\"315\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">l2</text>\n",
"</g>\n",
"<!-- factor5 -->\n",
"<g id=\"node11\" class=\"node\">\n",
"<title>factor5</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"81\" cy=\"-86\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<g id=\"edge10\" class=\"edge\">\n",
"<title>var7783684379976990721&#45;&#45;factor5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M87.54,-36.4C86.23,-45.91 84.2,-60.18 82.73,-71.73\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"243\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var7782220156096217090&#45;&#45;factor5 -->\n",
"<g id=\"edge11\" class=\"edge\">\n",
"<title>var8070450532247928833&#45;&#45;factor5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.46,-149.6C75.77,-140.09 77.8,-125.82 79.27,-114.27\"/>\n",
"<title>var7782220156096217090&#45;&#45;factor5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M292.22,-39.58C273.76,-25.79 249.92,-7.97 244.25,-3.73\"/>\n",
"</g>\n",
"<!-- factor6 -->\n",
"<g id=\"node12\" class=\"node\">\n",
"<title>factor6</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"135\" cy=\"-86\" rx=\"4\" ry=\"4\"/>\n",
"</g>\n",
"<g id=\"edge12\" class=\"edge\">\n",
"<title>var7783684379976990721&#45;&#45;factor6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M100.86,-36.4C108.18,-46.75 119.65,-62.56 127.44,-73.58\"/>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"279\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var7782220156096217090&#45;&#45;factor6 -->\n",
"<g id=\"edge13\" class=\"edge\">\n",
"<title>var8070450532247928834&#45;&#45;factor6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M142.01,-149.85C140.75,-140.33 138.89,-126.08 137.46,-114.56\"/>\n",
"<title>var7782220156096217090&#45;&#45;factor6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M303.61,-39.58C294.38,-25.79 282.46,-7.97 279.62,-3.73\"/>\n",
"</g>\n",
"<!-- var8646911284551352320 -->\n",
"<g id=\"node3\" class=\"node\">\n",
"<title>var8646911284551352320</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x0</text>\n",
"</g>\n",
"<!-- factor0 -->\n",
"<g id=\"node6\" class=\"node\">\n",
"<title>factor0</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"27\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var8646911284551352320&#45;&#45;factor0 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>var8646911284551352320&#45;&#45;factor0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M27,-39.58C27,-25.79 27,-7.97 27,-3.73\"/>\n",
"</g>\n",
"<!-- factor1 -->\n",
"<g id=\"node7\" class=\"node\">\n",
"<title>factor1</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"100\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var8646911284551352320&#45;&#45;factor1 -->\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>var8646911284551352320&#45;&#45;factor1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M44.67,-43.58C64.25,-29.15 93.78,-7.38 99.15,-3.43\"/>\n",
"</g>\n",
"<!-- var8646911284551352320&#45;&#45;factor3 -->\n",
"<g id=\"edge6\" class=\"edge\">\n",
"<title>var8646911284551352320&#45;&#45;factor3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M40.37,-41.61C52.8,-27.68 69.99,-8.41 74.09,-3.81\"/>\n",
"</g>\n",
"<!-- var8646911284551352321 -->\n",
"<g id=\"node4\" class=\"node\">\n",
"<title>var8646911284551352321</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"171\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x1</text>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor1 -->\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M153.81,-43.58C134.77,-29.15 106.05,-7.38 100.83,-3.43\"/>\n",
"</g>\n",
"<!-- factor2 -->\n",
"<g id=\"node8\" class=\"node\">\n",
"<title>factor2</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"178\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor2 -->\n",
"<g id=\"edge4\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M173.21,-39.58C175.01,-25.79 177.33,-7.97 177.88,-3.73\"/>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor4 -->\n",
"<g id=\"edge8\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M157.63,-41.61C145.2,-27.68 128.01,-8.41 123.91,-3.81\"/>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor5 -->\n",
"<g id=\"edge10\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M188.43,-43.58C207.74,-29.15 236.87,-7.38 242.16,-3.43\"/>\n",
"</g>\n",
"<!-- var8646911284551352322 -->\n",
"<g id=\"node5\" class=\"node\">\n",
"<title>var8646911284551352322</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"243\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"243\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x2</text>\n",
"</g>\n",
"<!-- var8646911284551352322&#45;&#45;factor2 -->\n",
"<g id=\"edge5\" class=\"edge\">\n",
"<title>var8646911284551352322&#45;&#45;factor2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M226.6,-43.02C209.75,-29.08 185.18,-8.74 179.3,-3.87\"/>\n",
"</g>\n",
"<!-- var8646911284551352322&#45;&#45;factor6 -->\n",
"<g id=\"edge12\" class=\"edge\">\n",
"<title>var8646911284551352322&#45;&#45;factor6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M253.61,-40.75C262.9,-26.86 275.37,-8.22 278.34,-3.78\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.files.Source at 0x7f87c4e3f340>"
"<graphviz.sources.Source at 0x1cdd6cacc20>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "display_data"
"output_type": "execute_result"
}
],
"source": [
@ -277,11 +309,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -40,7 +40,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "edgekey_import_code"
},
@ -63,12 +63,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {
"id": "edgekey_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "edgekey_create_code",
"outputId": "cdef1234-5678-90ab-cdef-1234567890ab"
},
"outputs": [
@ -77,7 +77,9 @@
"output_type": "stream",
"text": [
"EdgeKey from (10, 20): {10, 20}\n",
"EdgeKey from key 42949672980: {10, 20}\n"
"\n",
"EdgeKey from key 42949672980: {10, 20}\n",
"\n"
]
}
],
@ -107,12 +109,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "edgekey_access_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "edgekey_access_code",
"outputId": "def12345-6789-0abc-def1-234567890abc"
},
"outputs": [
@ -121,9 +123,10 @@
"output_type": "stream",
"text": [
"EdgeKey: {123, 456}\n",
"\n",
" i: 123\n",
" j: 456\n",
" Key: 528280977848\n"
" Key: 528280977864\n"
]
}
],
@ -142,11 +145,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -46,11 +46,23 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "etree_import_code"
},
"outputs": [],
"outputs": [
{
"ename": "ImportError",
"evalue": "cannot import name 'GaussianEliminationTree' from 'gtsam' (c:\\Users\\porte\\miniconda3\\envs\\gtsam\\Lib\\site-packages\\gtsam\\__init__.py)",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mImportError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[2], line 5\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mnumpy\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mas\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mnp\u001b[39;00m\n\u001b[0;32m 4\u001b[0m \u001b[38;5;66;03m# EliminationTree is templated, need concrete types\u001b[39;00m\n\u001b[1;32m----> 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mgtsam\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m GaussianFactorGraph, Ordering, GaussianEliminationTree, GaussianBayesNet\n\u001b[0;32m 6\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mgtsam\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m symbol_shorthand\n\u001b[0;32m 8\u001b[0m X \u001b[38;5;241m=\u001b[39m symbol_shorthand\u001b[38;5;241m.\u001b[39mX\n",
"\u001b[1;31mImportError\u001b[0m: cannot import name 'GaussianEliminationTree' from 'gtsam' (c:\\Users\\porte\\miniconda3\\envs\\gtsam\\Lib\\site-packages\\gtsam\\__init__.py)"
]
}
],
"source": [
"import gtsam\n",
"import numpy as np\n",
@ -78,10 +90,10 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "etree_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "etree_create_code",
"outputId": "f0123456-789a-bcde-f012-3456789abcde"
},
"outputs": [
@ -147,10 +159,10 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "etree_eliminate_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "etree_eliminate_code",
"outputId": "01234567-89ab-cdef-0123-456789abcdef"
},
"outputs": [
@ -186,11 +198,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -17,7 +17,18 @@
"source": [
"`gtsam.Factor` is the abstract base class for all factors in GTSAM, including nonlinear factors, Gaussian factors, discrete factors, and conditionals. It defines the basic interface common to all factors, primarily centered around the set of variables (keys) the factor involves.\n",
"\n",
"You typically do not instantiate `gtsam.Factor` directly but rather work with its derived classes like `gtsam.NonlinearFactor`, `gtsam.JacobianFactor`, `gtsam.DiscreteFactor`, etc."
"You typically do not instantiate `gtsam.Factor` directly but rather work with its derived classes like `gtsam.NonlinearFactor`, `gtsam.JacobianFactor`, `gtsam.DiscreteFactor`, etc.\n",
"\n",
"The `error` function of a factor is typically related to a probability or likelihood $P(X)$ or $\\phi(X)$ via the negative log-likelihood:\n",
"\n",
"$$\n",
"\\text{error}(X) = - \\log \\phi(X) + K\n",
"$$\n",
"or equivalently:\n",
"$$\n",
"\\phi(X) \\propto \\exp(-\\text{error}(X))\n",
"$$\n",
"where $X$ are the variables involved in the factor, $\\phi(X)$ is the potential function (proportional to probability or likelihood), and $K$ is some constant. Minimizing the error corresponds to maximizing the probability/likelihood represented by the factor."
]
},
{
@ -42,7 +53,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 7,
"metadata": {
"id": "factor_import_code"
},
@ -52,7 +63,7 @@
"from gtsam.utils.test_case import GtsamTestCase\n",
"\n",
"# We need a concrete factor type for demonstration\n",
"from gtsam import PriorFactorPose2, BetweenFactorPose2, Pose2, Rot2, Point2\n",
"from gtsam import PriorFactorPose2, BetweenFactorPose2, Pose2, Point3\n",
"from gtsam import symbol_shorthand\n",
"\n",
"X = symbol_shorthand.X"
@ -71,12 +82,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 8,
"metadata": {
"id": "factor_keys_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "factor_keys_code",
"outputId": "01234567-89ab-cdef-0123-456789abcdef"
},
"outputs": [
@ -84,9 +95,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Prior factor keys: [8070450532247928832] (x0)\n",
"Prior factor keys: [8646911284551352320] (x0)\n",
"Prior factor size: 1\n",
"Between factor keys: [8070450532247928832, 8070450532247928833] (x0, x1)\n",
"Between factor keys: [8646911284551352320, 8646911284551352321] (x0, x1)\n",
"Between factor size: 2\n",
"Is prior factor empty? False\n"
]
@ -127,12 +138,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 9,
"metadata": {
"id": "factor_error_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "factor_error_code",
"outputId": "12345678-9abc-def0-1234-56789abcdef0"
},
"outputs": [
@ -166,11 +177,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -17,7 +17,20 @@
"source": [
"A `FactorGraph` represents a factor graph, a bipartite graph connecting variables and factors. In GTSAM, the `FactorGraph` class (and its templated instantiations like `GaussianFactorGraph`, `NonlinearFactorGraph`, etc.) primarily stores a collection of factors.\n",
"\n",
"This class serves as the base for different types of factor graphs. You typically work with specific instantiations like `gtsam.GaussianFactorGraph` or `gtsam.NonlinearFactorGraph`."
"This class serves as the base for different types of factor graphs. You typically work with specific instantiations like `gtsam.GaussianFactorGraph` or `gtsam.NonlinearFactorGraph`.\n",
"\n",
"The total probability $P(X)$ represented by a factor graph is proportional to the product of its individual factor potentials $\\phi_i$:\n",
"$$\n",
"P(X) \\propto \\prod_i \\phi_i(X_i)\n",
"$$\n",
"where $X_i$ are the variables involved in factor $i$. In terms of error (negative log-likelihood):\n",
"$$\n",
"P(X) \\propto \\exp\\left(-\\sum_i \\text{error}_i(X_i)\\right)\n",
"$$\n",
"The total error for the graph given an assignment $X$ is the sum of the errors of the individual factors:\n",
"$$\n",
"\\text{error}(X) = \\sum_i \\text{error}_i(X_i)\n",
"$$"
]
},
{
@ -42,7 +55,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "fg_import_code"
},
@ -71,12 +84,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "fg_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "fg_create_code",
"outputId": "23456789-abcd-ef01-2345-6789abcdef01"
},
"outputs": [
@ -84,7 +97,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Graph size after adding factors: 3\n"
"Graph size after adding factors: 2\n"
]
}
],
@ -104,10 +117,6 @@
"graph.add(factor1) # add is synonym for push_back\n",
"graph.push_back(factor2)\n",
"\n",
"# Can also add using += or ,\n",
"graph += factor3\n",
"# graph += factor2, factor3 # Chaining also works\n",
"\n",
"print(f\"Graph size after adding factors: {graph.size()}\")"
]
},
@ -122,12 +131,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"metadata": {
"id": "fg_access_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "fg_access_code",
"outputId": "3456789a-bcde-f012-3456-789abcdef012"
},
"outputs": [
@ -136,14 +145,13 @@
"output_type": "stream",
"text": [
"Is graph empty? False\n",
"Number of factors (size): 3\n",
"Number of non-null factors (nrFactors): 3\n",
"Number of factors (size): 2\n",
"Number of non-null factors (nrFactors): 2\n",
"Factor at index 1: \n",
"BetweenFactor on 8070450532247928832 8070450532247928833\n",
"BetweenFactor(x0,x1)\n",
" measured: (1, 0, 0)\n",
" noise model: diagonal sigmas [0.2; 0.2; 0.1]\n",
"\n",
"Keys involved in the graph: {8070450532247928832, 8070450532247928833, 8070450532247928834}\n"
" noise model: diagonal sigmas [0.2; 0.2; 0.1];\n",
"Keys involved in the graph: x0x1\n"
]
}
],
@ -180,12 +188,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {
"id": "fg_error_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "fg_error_code",
"outputId": "456789ab-cdef-0123-4567-89abcdef0123"
},
"outputs": [
@ -194,7 +202,7 @@
"output_type": "stream",
"text": [
"Total graph error at ground truth: 0.0\n",
"Total graph error with incorrect x2: 50.0\n"
"Total graph error with incorrect x2: 0.0\n"
]
}
],
@ -226,12 +234,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 8,
"metadata": {
"id": "fg_dot_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "fg_dot_code",
"outputId": "56789abc-def0-1234-5678-9abcdef01234"
},
"outputs": [
@ -242,31 +250,89 @@
"graph {\n",
" size=\"5,5\";\n",
"\n",
" var8070450532247928832[label=\"x0\"];\n",
" var8070450532247928833[label=\"x1\"];\n",
" var8070450532247928834[label=\"x2\"];\n",
" var8646911284551352320[label=\"x0\", pos=\"0,0!\"];\n",
" var8646911284551352321[label=\"x1\", pos=\"0,1!\"];\n",
"\n",
" factor0[label=\"\", shape=point];\n",
" var8070450532247928832--factor0;\n",
" var8646911284551352320--factor0;\n",
" factor1[label=\"\", shape=point];\n",
" var8070450532247928832--factor1;\n",
" var8070450532247928833--factor1;\n",
" factor2[label=\"\", shape=point];\n",
" var8070450532247928833--factor2;\n",
" var8070450532247928834--factor2;\n",
"}\n"
" var8646911284551352320--factor1;\n",
" var8646911284551352321--factor1;\n",
"}\n",
"\n"
]
},
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.50.0 (0)\n",
" -->\n",
"<!-- Pages: 1 -->\n",
"<svg width=\"134pt\" height=\"84pt\"\n",
" viewBox=\"0.00 0.00 134.00 83.60\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 79.6)\">\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-79.6 130,-79.6 130,4 -4,4\"/>\n",
"<!-- var8646911284551352320 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>var8646911284551352320</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"27\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x0</text>\n",
"</g>\n",
"<!-- factor0 -->\n",
"<g id=\"node3\" class=\"node\">\n",
"<title>factor0</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"27\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var8646911284551352320&#45;&#45;factor0 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>var8646911284551352320&#45;&#45;factor0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M27,-39.58C27,-25.79 27,-7.97 27,-3.73\"/>\n",
"</g>\n",
"<!-- factor1 -->\n",
"<g id=\"node4\" class=\"node\">\n",
"<title>factor1</title>\n",
"<ellipse fill=\"black\" stroke=\"black\" cx=\"74\" cy=\"-1.8\" rx=\"1.8\" ry=\"1.8\"/>\n",
"</g>\n",
"<!-- var8646911284551352320&#45;&#45;factor1 -->\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>var8646911284551352320&#45;&#45;factor1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M40.09,-41.61C52.26,-27.68 69.09,-8.41 73.11,-3.81\"/>\n",
"</g>\n",
"<!-- var8646911284551352321 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>var8646911284551352321</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-57.6\" rx=\"27\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"99\" y=\"-53.9\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">x1</text>\n",
"</g>\n",
"<!-- var8646911284551352321&#45;&#45;factor1 -->\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>var8646911284551352321&#45;&#45;factor1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M91.36,-40.17C84.93,-26.32 76.46,-8.1 74.44,-3.76\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.sources.Source at 0x1c24ffedfd0>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dot_string = graph.dot()\n",
"dot_string = graph.dot(values)\n",
"print(dot_string)\n",
"\n",
"# To render, save dot_string to a file (e.g., graph.dot) and run:\n",
"# dot -Tpng graph.dot -o graph.png\n",
"# Or use a Python library like graphviz\n",
"# import graphviz\n",
"# graphviz.Source(dot_string)"
"import graphviz\n",
"graphviz.Source(dot_string)"
]
},
{
@ -286,11 +352,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -44,7 +44,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "isam_import_code"
},
@ -74,12 +74,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"metadata": {
"id": "isam_init_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "isam_init_code",
"outputId": "89abcdef-0123-4567-89ab-cdef01234567"
},
"outputs": [
@ -87,33 +87,32 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Initial ISAM (empty):\n",
": cliques: 0, variables: 0\n",
"\n",
"Initial BayesTree:\n",
": cliques: 1, variables: 1\n",
"Root(s):\n",
"Conditional density P(x0) = P(x0) \n",
" size: 1\n",
" Conditional P(x0): GaussianConditional( P(x0) = dx0 - d), d = [ 0 ], sigmas = [ 1 ])\n",
"\n",
"\n",
"ISAM from BayesTree:\n",
": cliques: 1, variables: 1\n",
"Root(s):\n",
"Conditional density P(x0) = P(x0) \n",
" size: 1\n",
" Conditional P(x0): GaussianConditional( P(x0) = dx0 - d), d = [ 0 ], sigmas = [ 1 ])\n",
"\n",
"\n"
"- p(x0)\n",
" R = [ 1 ]\n",
" d = [ 0 ]\n",
" mean: 1 elements\n",
" x0: 0\n",
" logNormalizationConstant: -0.918939\n",
" No noise model\n"
]
},
{
"ename": "TypeError",
"evalue": "__init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.GaussianISAM()\n\nInvoked with: : cliques: 1, variables: 1\n- p(x0)\n R = [ 1 ]\n d = [ 0 ]\n mean: 1 elements\n x0: 0\n logNormalizationConstant: -0.918939\n No noise model\n",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[5], line 13\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInitial BayesTree:\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 11\u001b[0m initial_bayes_tree\u001b[38;5;241m.\u001b[39mprint()\n\u001b[1;32m---> 13\u001b[0m isam2 \u001b[38;5;241m=\u001b[39m \u001b[43mGaussianISAM\u001b[49m\u001b[43m(\u001b[49m\u001b[43minitial_bayes_tree\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 14\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mISAM from BayesTree:\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 15\u001b[0m isam2\u001b[38;5;241m.\u001b[39mprint()\n",
"\u001b[1;31mTypeError\u001b[0m: __init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.GaussianISAM()\n\nInvoked with: : cliques: 1, variables: 1\n- p(x0)\n R = [ 1 ]\n d = [ 0 ]\n mean: 1 elements\n x0: 0\n logNormalizationConstant: -0.918939\n No noise model\n"
]
}
],
"source": [
"# Create an empty ISAM object\n",
"isam1 = GaussianISAM()\n",
"print(\"Initial ISAM (empty):\")\n",
"isam1.print()\n",
"\n",
"# Create from an existing Bayes Tree (e.g., from an initial batch solve)\n",
"initial_graph = GaussianFactorGraph()\n",
@ -142,55 +141,24 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {
"id": "isam_update_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "isam_update_code",
"outputId": "9abcdef0-1234-5678-9abc-def012345678"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ISAM after first update (x0, x1):\n",
": cliques: 2, variables: 2\n",
"Root(s):\n",
"Conditional density P(x0 | x1) = P(x0 | x1) \n",
" size: 1\n",
" Conditional P(x0 | x1): GaussianConditional( P(x0 | x1) = dx0 - R*dx1 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.707107 ])\n",
"\n",
"\n",
" Children:\n",
" Conditional density P(x1) = P(x1) \n",
" size: 1\n",
" Conditional P(x1): GaussianConditional( P(x1) = dx1 - d), d = [ 0 ], sigmas = [ 0.707107 ])\n",
"\n",
"\n",
"\n",
"ISAM after second update (x0, x1, x2):\n",
": cliques: 3, variables: 3\n",
"Root(s):\n",
"Conditional density P(x0 | x1) = P(x0 | x1) \n",
" size: 1\n",
" Conditional P(x0 | x1): GaussianConditional( P(x0 | x1) = dx0 - R*dx1 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.707107 ])\n",
"\n",
"\n",
" Children:\n",
" Conditional density P(x1 | x2) = P(x1 | x2) \n",
" size: 1\n",
" Conditional P(x1 | x2): GaussianConditional( P(x1 | x2) = dx1 - R*dx2 - d), R = [ 0.666667 ], d = [ 0 ], sigmas = [ 0.816497 ])\n",
"\n",
"\n",
" Children:\n",
" Conditional density P(x2) = P(x2) \n",
" size: 1\n",
" Conditional P(x2): GaussianConditional( P(x2) = dx2 - d), d = [ 0 ], sigmas = [ 0.866025 ])\n",
"\n",
"\n",
"\n"
"ename": "TypeError",
"evalue": "__init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.GaussianISAM()\n\nInvoked with: : cliques: 1, variables: 1\n- p(x0)\n R = [ 1 ]\n d = [ 0 ]\n mean: 1 elements\n x0: 0\n logNormalizationConstant: -0.918939\n No noise model\n",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[6], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# Start with the ISAM object containing the prior on x0\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m isam \u001b[38;5;241m=\u001b[39m \u001b[43mGaussianISAM\u001b[49m\u001b[43m(\u001b[49m\u001b[43minitial_bayes_tree\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3\u001b[0m model \u001b[38;5;241m=\u001b[39m gtsam\u001b[38;5;241m.\u001b[39mnoiseModel\u001b[38;5;241m.\u001b[39mIsotropic\u001b[38;5;241m.\u001b[39mSigma(\u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m1.0\u001b[39m)\n\u001b[0;32m 5\u001b[0m \u001b[38;5;66;03m# --- First Update ---\u001b[39;00m\n",
"\u001b[1;31mTypeError\u001b[0m: __init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.GaussianISAM()\n\nInvoked with: : cliques: 1, variables: 1\n- p(x0)\n R = [ 1 ]\n d = [ 0 ]\n mean: 1 elements\n x0: 0\n logNormalizationConstant: -0.918939\n No noise model\n"
]
}
],
@ -229,25 +197,24 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 7,
"metadata": {
"id": "isam_solve_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "isam_solve_code",
"outputId": "abcdef01-2345-6789-abcd-ef0123456789"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Optimized Solution after updates:\n",
"Values with 3 values:\n",
"Value x0: [0.]\n",
"Value x1: [0.]\n",
"Value x2: [0.]\n",
"\n"
"ename": "NameError",
"evalue": "name 'isam' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[7], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# Get the solution from the final ISAM state\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m solution \u001b[38;5;241m=\u001b[39m \u001b[43misam\u001b[49m\u001b[38;5;241m.\u001b[39moptimize()\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mOptimized Solution after updates:\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 4\u001b[0m solution\u001b[38;5;241m.\u001b[39mprint()\n",
"\u001b[1;31mNameError\u001b[0m: name 'isam' is not defined"
]
}
],
@ -264,11 +231,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -46,7 +46,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {
"id": "jtree_import_code"
},
@ -56,7 +56,7 @@
"import numpy as np\n",
"\n",
"# JunctionTree is templated, need concrete types\n",
"from gtsam import GaussianFactorGraph, Ordering, GaussianJunctionTree, GaussianBayesTree\n",
"from gtsam import GaussianFactorGraph, Ordering, VariableIndex\n",
"from gtsam import symbol_shorthand\n",
"\n",
"X = symbol_shorthand.X\n",
@ -76,12 +76,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 7,
"metadata": {
"id": "jtree_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "jtree_create_code",
"outputId": "12345678-9abc-def0-1234-56789abcdef0"
},
"outputs": [
@ -90,30 +90,26 @@
"output_type": "stream",
"text": [
"Resulting BayesTree (structure mirrors JunctionTree):\n",
": cliques: 3, variables: 5\n",
"Root(s):\n",
"Conditional density P(l1, x1 | l2, x2) = P(l1 | x1) P(x1 | l2, x2) \n",
" size: 2\n",
" Conditional P(l1 | x1): GaussianConditional( P(l1 | x1) = dl1 - R*dx1 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.866025 ])\n",
"\n",
" Conditional P(x1 | l2, x2): GaussianConditional( P(x1 | l2, x2) = dx1 - R1*dl2 - R2*dx2 - d), R1 = [ 0.333333 ], R2 = [ 0.333333 ], d = [ 0 ], sigmas = [ 0.745356 ])\n",
"\n",
"\n",
" Children:\n",
" Conditional density P(l2, x2 | x0) = P(l2 | x2) P(x2 | x0) \n",
" size: 2\n",
" Conditional P(l2 | x2): GaussianConditional( P(l2 | x2) = dl2 - R*dx2 - d), R = [ 0.5 ], d = [ 0 ], sigmas = [ 0.866025 ])\n",
"\n",
" Conditional P(x2 | x0): GaussianConditional( P(x2 | x0) = dx2 - R*dx0 - d), R = [ 0.2 ], d = [ 0 ], sigmas = [ 0.774597 ])\n",
"\n",
"\n",
" Children:\n",
" Conditional density P(x0) = P(x0) \n",
" size: 1\n",
" Conditional P(x0): GaussianConditional( P(x0) = dx0 - d), d = [ 0 ], sigmas = [ 0.894427 ])\n",
"\n",
"\n",
"\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"
]
}
],
@ -129,7 +125,7 @@
"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(graph)\n",
"ordering = Ordering.Colamd(VariableIndex(graph))\n",
"\n",
"# Perform multifrontal elimination, which uses a JunctionTree internally\n",
"bayes_tree, remaining_graph = graph.eliminatePartialMultifrontal(ordering)\n",
@ -148,11 +144,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -40,7 +40,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "key_import_code"
},
@ -64,12 +64,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {
"id": "key_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "key_create_code",
"outputId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
},
"outputs": [
@ -77,13 +77,20 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Symbol Key (x0): 8070450532247928832\n",
"Type: <class 'int'>\n",
"LabeledSymbol Key (aB1): 6988956933745737729\n",
"Type: <class 'int'>\n",
"Plain Integer Key: 12345\n",
"Symbol Key (x0): 8646911284551352320\n",
"Type: <class 'int'>\n"
]
},
{
"ename": "TypeError",
"evalue": "__init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.LabeledSymbol(full_key: int)\n 2. gtsam.gtsam.LabeledSymbol(key: gtsam.gtsam.LabeledSymbol)\n 3. gtsam.gtsam.LabeledSymbol(valType: int, label: int, j: int)\n\nInvoked with: 'a', 'B', 1",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[3], line 6\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSymbol Key (x0): \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mkey_from_symbol\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mType: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(key_from_symbol)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m----> 6\u001b[0m lsym \u001b[38;5;241m=\u001b[39m \u001b[43mLabeledSymbol\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43ma\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mB\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 7\u001b[0m key_from_labeled_symbol \u001b[38;5;241m=\u001b[39m lsym\u001b[38;5;241m.\u001b[39mkey()\n\u001b[0;32m 8\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mLabeledSymbol Key (aB1): \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mkey_from_labeled_symbol\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
"\u001b[1;31mTypeError\u001b[0m: __init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.LabeledSymbol(full_key: int)\n 2. gtsam.gtsam.LabeledSymbol(key: gtsam.gtsam.LabeledSymbol)\n 3. gtsam.gtsam.LabeledSymbol(valType: int, label: int, j: int)\n\nInvoked with: 'a', 'B', 1"
]
}
],
"source": [
@ -116,12 +123,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "key_format_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "key_format_code",
"outputId": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
},
"outputs": [
@ -130,19 +137,18 @@
"output_type": "stream",
"text": [
"Default Formatter:\n",
" Symbol Key: x0\n",
" LabeledSymbol Key: 6988956933745737729 (Default doesn't know LabeledSymbol)\n",
" Plain Key: 12345\n",
"\n",
"MultiRobot Formatter:\n",
" Symbol Key: x0\n",
" LabeledSymbol Key: aB1\n",
" Plain Key: 12345\n",
"\n",
"Custom Formatter:\n",
" Symbol Key: KEY[x0]\n",
" LabeledSymbol Key: KEY[aB1]\n",
" Plain Key: KEY[12345]\n"
" Symbol Key: x0\n"
]
},
{
"ename": "NameError",
"evalue": "name 'key_from_labeled_symbol' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[4], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mDefault Formatter:\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 2\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m Symbol Key: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mgtsam\u001b[38;5;241m.\u001b[39mDefaultKeyFormatter(key_from_symbol)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m----> 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m LabeledSymbol Key: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mgtsam\u001b[38;5;241m.\u001b[39mDefaultKeyFormatter(\u001b[43mkey_from_labeled_symbol\u001b[49m)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m Plain Key: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mgtsam\u001b[38;5;241m.\u001b[39mDefaultKeyFormatter(plain_key)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 6\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMultiRobot Formatter:\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
"\u001b[1;31mNameError\u001b[0m: name 'key_from_labeled_symbol' is not defined"
]
}
],
@ -190,11 +196,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -40,7 +40,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {
"id": "lsymbol_import_code"
},
@ -63,21 +63,24 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "lsymbol_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "lsymbol_create_code",
"outputId": "f1a2b3c4-d5e6-7890-f1a2-bcdef1234567"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LabeledSymbol from char/label/index: xA7\n",
"LabeledSymbol from key 8107010787457335296: xA0\n"
"ename": "TypeError",
"evalue": "__init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.LabeledSymbol(full_key: int)\n 2. gtsam.gtsam.LabeledSymbol(key: gtsam.gtsam.LabeledSymbol)\n 3. gtsam.gtsam.LabeledSymbol(valType: int, label: int, j: int)\n\nInvoked with: 'x', 'A', 7",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[2], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# Create LabeledSymbol 'x' from robot 'A' with index 7\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m lsym1 \u001b[38;5;241m=\u001b[39m \u001b[43mLabeledSymbol\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mx\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mA\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m7\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mLabeledSymbol from char/label/index: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mlsym1\u001b[38;5;241m.\u001b[39mstring()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 5\u001b[0m \u001b[38;5;66;03m# Get the underlying integer key\u001b[39;00m\n",
"\u001b[1;31mTypeError\u001b[0m: __init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.LabeledSymbol(full_key: int)\n 2. gtsam.gtsam.LabeledSymbol(key: gtsam.gtsam.LabeledSymbol)\n 3. gtsam.gtsam.LabeledSymbol(valType: int, label: int, j: int)\n\nInvoked with: 'x', 'A', 7"
]
}
],
@ -110,24 +113,24 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {
"id": "lsymbol_access_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "lsymbol_access_code",
"outputId": "a2b3c4d5-e6f7-8901-a2b3-cdef12345678"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LabeledSymbol: lB3\n",
" Char (Type): l\n",
" Label (Robot): B\n",
" Index: 3\n",
" Key: 7783740146724503555\n"
"ename": "TypeError",
"evalue": "__init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.LabeledSymbol(full_key: int)\n 2. gtsam.gtsam.LabeledSymbol(key: gtsam.gtsam.LabeledSymbol)\n 3. gtsam.gtsam.LabeledSymbol(valType: int, label: int, j: int)\n\nInvoked with: 'l', 'B', 3",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[3], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m robotB_landmark \u001b[38;5;241m=\u001b[39m \u001b[43mLabeledSymbol\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43ml\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mB\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m3\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mLabeledSymbol: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrobotB_landmark\u001b[38;5;241m.\u001b[39mstring()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m Char (Type): \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mrobotB_landmark\u001b[38;5;241m.\u001b[39mchr()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
"\u001b[1;31mTypeError\u001b[0m: __init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.LabeledSymbol(full_key: int)\n 2. gtsam.gtsam.LabeledSymbol(key: gtsam.gtsam.LabeledSymbol)\n 3. gtsam.gtsam.LabeledSymbol(valType: int, label: int, j: int)\n\nInvoked with: 'l', 'B', 3"
]
}
],
@ -158,20 +161,24 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "lsymbol_shorthand_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "lsymbol_shorthand_code",
"outputId": "b3c4d5e6-f7a8-9012-b3c4-def123456789"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"LabeledSymbol('p', 'C', 2).key() == gtsam.mrsymbol(ord('p'), ord('C'), 2): True\n"
"ename": "TypeError",
"evalue": "__init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.LabeledSymbol(full_key: int)\n 2. gtsam.gtsam.LabeledSymbol(key: gtsam.gtsam.LabeledSymbol)\n 3. gtsam.gtsam.LabeledSymbol(valType: int, label: int, j: int)\n\nInvoked with: 'p', 'C', 2",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[4], line 4\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# Note: mrsymbol expects integer representations of chars (use ord())\u001b[39;00m\n\u001b[0;32m 2\u001b[0m pc2_key \u001b[38;5;241m=\u001b[39m gtsam\u001b[38;5;241m.\u001b[39mmrsymbol(\u001b[38;5;28mord\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mp\u001b[39m\u001b[38;5;124m'\u001b[39m), \u001b[38;5;28mord\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mC\u001b[39m\u001b[38;5;124m'\u001b[39m), \u001b[38;5;241m2\u001b[39m)\n\u001b[1;32m----> 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mLabeledSymbol(\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mp\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mC\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m, 2).key() == gtsam.mrsymbol(ord(\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mp\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m), ord(\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mC\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m), 2): \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[43mLabeledSymbol\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mp\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;250;43m \u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mC\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;250;43m \u001b[39;49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mkey()\u001b[38;5;250m \u001b[39m\u001b[38;5;241m==\u001b[39m\u001b[38;5;250m \u001b[39mpc2_key\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
"\u001b[1;31mTypeError\u001b[0m: __init__(): incompatible constructor arguments. The following argument types are supported:\n 1. gtsam.gtsam.LabeledSymbol(full_key: int)\n 2. gtsam.gtsam.LabeledSymbol(key: gtsam.gtsam.LabeledSymbol)\n 3. gtsam.gtsam.LabeledSymbol(valType: int, label: int, j: int)\n\nInvoked with: 'p', 'C', 2"
]
}
],
@ -188,11 +195,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -42,14 +42,14 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "ordering_import_code"
},
"outputs": [],
"source": [
"import gtsam\n",
"from gtsam import Ordering\n",
"from gtsam import Ordering, VariableIndex\n",
"# Need a graph type for automatic ordering\n",
"from gtsam import SymbolicFactorGraph\n",
"from gtsam import symbol_shorthand\n",
@ -71,12 +71,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "ordering_manual_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ordering_manual_code",
"outputId": "6789abcd-ef01-2345-6789-abcdef012345"
},
"outputs": [
@ -84,12 +84,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Manual Ordering: \n",
"Position 0: x1\n",
"Position 1: l1\n",
"Position 2: x2\n",
"Position 3: l2\n",
"Position 4: x0\n"
"Manual Ordering: Position 0: x1, l1, x2, l2, x0\n"
]
}
],
@ -101,12 +96,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 7,
"metadata": {
"id": "ordering_auto_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ordering_auto_code",
"outputId": "789abcde-f012-3456-789a-bcdef0123456"
},
"outputs": [
@ -114,19 +109,18 @@
"name": "stdout",
"output_type": "stream",
"text": [
"COLAMD Ordering: \n",
"Position 0: x0\n",
"Position 1: l1\n",
"Position 2: x1\n",
"Position 3: l2\n",
"Position 4: x2\n",
"\n",
"Constrained COLAMD (x0, x2 last): \n",
"Position 0: l1\n",
"Position 1: l2\n",
"Position 2: x1\n",
"Position 3: x0\n",
"Position 4: x2\n"
"COLAMD Ordering: Position 0: l1, x0, x1, l2, x2\n"
]
},
{
"ename": "AttributeError",
"evalue": "type object 'gtsam.gtsam.Ordering' has no attribute 'ColamdConstrainedLast'",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[7], line 17\u001b[0m\n\u001b[0;32m 14\u001b[0m colamd_ordering\u001b[38;5;241m.\u001b[39mprint(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCOLAMD Ordering: \u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 16\u001b[0m \u001b[38;5;66;03m# Constrained COLAMD (force x0 and x2 to be eliminated last)\u001b[39;00m\n\u001b[1;32m---> 17\u001b[0m constrained_ordering \u001b[38;5;241m=\u001b[39m \u001b[43mOrdering\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mColamdConstrainedLast\u001b[49m(graph, gtsam\u001b[38;5;241m.\u001b[39mKeyVector([X(\u001b[38;5;241m0\u001b[39m), X(\u001b[38;5;241m2\u001b[39m)]))\n\u001b[0;32m 18\u001b[0m constrained_ordering\u001b[38;5;241m.\u001b[39mprint(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mConstrained COLAMD (x0, x2 last): \u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 20\u001b[0m \u001b[38;5;66;03m# METIS ordering (if GTSAM was built with METIS support)\u001b[39;00m\n",
"\u001b[1;31mAttributeError\u001b[0m: type object 'gtsam.gtsam.Ordering' has no attribute 'ColamdConstrainedLast'"
]
}
],
@ -143,7 +137,7 @@
"graph.push_factor(X(2), L(2))\n",
"\n",
"# COLAMD (Column Approximate Minimum Degree) ordering\n",
"colamd_ordering = Ordering.Colamd(graph)\n",
"colamd_ordering = Ordering.Colamd(VariableIndex(graph))\n",
"colamd_ordering.print(\"COLAMD Ordering: \")\n",
"\n",
"# Constrained COLAMD (force x0 and x2 to be eliminated last)\n",
@ -175,12 +169,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 11,
"metadata": {
"id": "ordering_access_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ordering_access_code",
"outputId": "89abcdef-0123-4567-89ab-cdef01234567"
},
"outputs": [
@ -189,20 +183,18 @@
"output_type": "stream",
"text": [
"Ordering size: 5\n",
"Key at position 0: x0\n",
"Key at position 2: x1\n",
"Iterating through ordering:\n",
" x0\n",
" l1\n",
" x1\n",
" l2\n",
" x2\n",
"Inverted map (Key -> Position):\n",
" x0 -> 0\n",
" l1 -> 1\n",
" x1 -> 2\n",
" l2 -> 3\n",
" x2 -> 4\n"
"Key at position 0: l1\n"
]
},
{
"ename": "AttributeError",
"evalue": "'gtsam.gtsam.Ordering' object has no attribute 'invert'",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[11], line 8\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mKey at position 0: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mgtsam\u001b[38;5;241m.\u001b[39mDefaultKeyFormatter(key_at_0)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 7\u001b[0m \u001b[38;5;66;03m# Invert the ordering (map from Key to its position)\u001b[39;00m\n\u001b[1;32m----> 8\u001b[0m inverted \u001b[38;5;241m=\u001b[39m \u001b[43mcolamd_ordering\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvert\u001b[49m()\n\u001b[0;32m 9\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInverted map (Key -> Position):\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 10\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m key, pos \u001b[38;5;129;01min\u001b[39;00m inverted\u001b[38;5;241m.\u001b[39mitems():\n",
"\u001b[1;31mAttributeError\u001b[0m: 'gtsam.gtsam.Ordering' object has no attribute 'invert'"
]
}
],
@ -211,14 +203,7 @@
"\n",
"# Access by index\n",
"key_at_0 = colamd_ordering.at(0)\n",
"key_at_2 = colamd_ordering[2] # Also supports [] operator\n",
"print(f\"Key at position 0: {gtsam.DefaultKeyFormatter(key_at_0)}\")\n",
"print(f\"Key at position 2: {gtsam.DefaultKeyFormatter(key_at_2)}\")\n",
"\n",
"# Iterate through the ordering\n",
"print(\"Iterating through ordering:\")\n",
"for key in colamd_ordering:\n",
" print(f\" {gtsam.DefaultKeyFormatter(key)}\")\n",
"\n",
"# Invert the ordering (map from Key to its position)\n",
"inverted = colamd_ordering.invert()\n",
@ -240,12 +225,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 13,
"metadata": {
"id": "ordering_append_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ordering_append_code",
"outputId": "9abcdef0-1234-5678-9abc-def012345678"
},
"outputs": [
@ -253,22 +238,14 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Appended Ordering: \n",
"Position 0: x0\n",
"Position 1: l1\n",
"Position 2: x1\n",
"Position 3: l2\n",
"Position 4: x2\n",
"Position 5: l0\n",
"Position 6: x3\n"
"Appended Ordering: Position 0: l1, x0, x1, l2, x2, l0, x3\n"
]
}
],
"source": [
"appended_ordering = Ordering(colamd_ordering)\n",
"appended_ordering.push_back(L(0))\n",
"appended_ordering += X(3)\n",
"# appended_ordering += L(0), X(3) # Can also chain\n",
"appended_ordering.push_back(X(3))\n",
"\n",
"appended_ordering.print(\"Appended Ordering: \")"
]
@ -279,11 +256,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -40,7 +40,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {
"id": "symbol_import_code"
},
@ -63,12 +63,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "symbol_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "symbol_create_code",
"outputId": "c1d2e3f4-a5b6-7890-bcde-f12345678901"
},
"outputs": [
@ -77,7 +77,7 @@
"output_type": "stream",
"text": [
"Symbol from char/index: x5\n",
"Symbol from key 8070450532247928837: x5\n"
"Symbol from key 8646911284551352325: x5\n"
]
}
],
@ -107,12 +107,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {
"id": "symbol_access_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "symbol_access_code",
"outputId": "d2e3f4a5-b6c7-8901-cdef-123456789012"
},
"outputs": [
@ -121,9 +121,9 @@
"output_type": "stream",
"text": [
"Symbol: l10\n",
" Char: l\n",
" Char: 108\n",
" Index: 10\n",
" Key: 7783684379976990730\n"
" Key: 7782220156096217098\n"
]
}
],
@ -153,12 +153,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {
"id": "symbol_shorthand_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "symbol_shorthand_code",
"outputId": "e3f4a5b6-c7d8-9012-def0-234567890123"
},
"outputs": [
@ -187,11 +187,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,

View File

@ -42,14 +42,14 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"metadata": {
"id": "vindex_import_code"
},
"outputs": [],
"source": [
"import gtsam\n",
"from gtsam import VariableIndex\n",
"from gtsam import VariableIndex, Ordering\n",
"# Need a graph type for creation\n",
"from gtsam import SymbolicFactorGraph\n",
"from gtsam import symbol_shorthand\n",
@ -71,12 +71,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {
"id": "vindex_create_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "vindex_create_code",
"outputId": "abcdef01-2345-6789-abcd-ef0123456789"
},
"outputs": [
@ -84,14 +84,12 @@
"name": "stdout",
"output_type": "stream",
"text": [
"VariableIndex: \n",
"nEntries = 13, nFactors = 7\n",
"VariableIndex: nEntries = 13, nFactors = 7\n",
"var l1: 3 4\n",
"var l2: 5 6\n",
"var x0: 0 1 3\n",
"var x1: 1 2 4 5\n",
"var x2: 2 6 \n",
"\n"
"var x2: 2 6\n"
]
}
],
@ -126,12 +124,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {
"id": "vindex_access_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "vindex_access_code",
"outputId": "bcdef012-3456-789a-bcde-f0123456789a"
},
"outputs": [
@ -141,17 +139,18 @@
"text": [
"Number of variables (size): 5\n",
"Number of factors (nFactors): 7\n",
"Number of variable-factor entries (nEntries): 13\n",
"\n",
"Factors involving x1: [1, 2, 4, 5]\n",
"Factors involving l1: [3, 4]\n",
"\n",
"Iterating through VariableIndex:\n",
" Variable l1 involves factors: [3, 4]\n",
" Variable l2 involves factors: [5, 6]\n",
" Variable x0 involves factors: [0, 1, 3]\n",
" Variable x1 involves factors: [1, 2, 4, 5]\n",
" Variable x2 involves factors: [2, 6]\n"
"Number of variable-factor entries (nEntries): 13\n"
]
},
{
"ename": "TypeError",
"evalue": "'gtsam.gtsam.VariableIndex' object is not subscriptable",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[3], line 6\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNumber of variable-factor entries (nEntries): \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mvariable_index\u001b[38;5;241m.\u001b[39mnEntries()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 5\u001b[0m \u001b[38;5;66;03m# Get factors involving a specific variable\u001b[39;00m\n\u001b[1;32m----> 6\u001b[0m factors_x1 \u001b[38;5;241m=\u001b[39m \u001b[43mvariable_index\u001b[49m\u001b[43m[\u001b[49m\u001b[43mX\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;66;03m# Returns a FactorIndices (FastVector<size_t>)\u001b[39;00m\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFactors involving x1: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfactors_x1\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 9\u001b[0m \u001b[38;5;66;03m# Use key directly\u001b[39;00m\n",
"\u001b[1;31mTypeError\u001b[0m: 'gtsam.gtsam.VariableIndex' object is not subscriptable"
]
}
],
@ -187,12 +186,12 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {
"id": "vindex_use_code",
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "vindex_use_code",
"outputId": "cdef0123-4567-89ab-cdef-0123456789ab"
},
"outputs": [
@ -200,12 +199,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"COLAMD Ordering from VariableIndex: \n",
"Position 0: x0\n",
"Position 1: l1\n",
"Position 2: x1\n",
"Position 3: l2\n",
"Position 4: x2\n"
"COLAMD Ordering from VariableIndex: Position 0: l1, x0, x1, l2, x2\n"
]
}
],
@ -221,11 +215,21 @@
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"display_name": "gtsam",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"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,