diff --git a/python_examples/diff_factor.html b/python_examples/diff_factor.html new file mode 100644 index 0000000..4bd6f8e --- /dev/null +++ b/python_examples/diff_factor.html @@ -0,0 +1,13168 @@ + + + + +diff_factor + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+

Factor2Poses2D

+
+
+
+
+
+
+

From source code for Factor2Poses2D residuals calculated:

+$$ +\begin{equation} +\overline{r} = R_i^T\cdot(\overline{x}_{t+1} - \overline{x}_t) - \overline{z}_t, +\end{equation} +$$$$ +\overline{x}_t = (x_t, y_t,\theta_t)^T +$$

where:

+$$ +\begin{equation} +R_i^T = \left[ +\begin{array}{cc} +cos(\theta_t) & sin(\theta_t)\\ +-sin(\theta_t) & cos(\theta_t)\\ +\end{array} +\right] \in \mathbb{R}^{2 \times 2} +\end{equation} +$$

and +$$ +\begin{equation} +\dfrac{dR_i^T}{d\theta_t} = \left[ +\begin{array}{cc} +-sin(\theta_t) & cos(\theta_t)\\ +-cos(\theta_t) & -sin(\theta_t)\\ +\end{array} +\right] \in \mathbb{R}^{2 \times 2} +\end{equation} +$$

+

and

+$$ +\delta x = x_{t+1} - x_{t}\\ +\delta y = y_{t+1} - y_{t}\\ +$$ +
+
+
+
+
+
+

Thus, for residuals have the following derivatives:

+$$ +\boxed{ +\dfrac{d \overline{r}}{d \overline{x}_t} = \left[ +\begin{array}{ccc} +-R_i^T & | & \dfrac{dR_i^T}{d\theta_t} \left(\begin{array}{c}\delta x\\ \delta y\\ \end{array}\right)\\ +\hline\\ +\begin{array}{cc} 0&0\\ \end{array} & | &-1\\ +\end{array} +\right] \in \mathbb{R}^{3 \times 3} +} +$$$$ +\boxed{ +\dfrac{d \overline{r}}{d\overline{z}_t} = -I \in \mathbb{R}^{3 \times 3} +} +$$$$ +\boxed{ +\dfrac{d^2\overline{r}}{d\overline{x}_t d\overline{z}_t} = 0 \in \mathbb{R}^{3 \times 3\times 3} +} +$$ +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + diff --git a/python_examples/diff_factor.ipynb b/python_examples/diff_factor.ipynb new file mode 100644 index 0000000..724c578 --- /dev/null +++ b/python_examples/diff_factor.ipynb @@ -0,0 +1,556 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import mrob\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "node 1 id = 0 , node 2 id = 1\n", + "Status of graph: Nodes = 3, Factors = 0, Diff Factors = 16, Eigen Factors = 0\n", + "Printing NodePose2d: 0, state = \n", + "3.68043e-06\n", + " 6.5575e-08\n", + " 0.785395\n", + "Printing NodePose2d: 1, state = \n", + "0.665415\n", + "0.994039\n", + " 1.7854\n", + "Printing NodePose2d: 2, state = \n", + " 0.6122\n", + " 2.40725\n", + "-2.71189\n", + "Printing DiffFactor: 0, obs= \n", + " 0\n", + " 0\n", + "0.785398\n", + " Residuals= \n", + "0.0789196\n", + " 0.271168\n", + " -2.5328 \n", + "and Information matrix\n", + "1e+06 0 0\n", + " 0 1e+06 0\n", + " 0 0 1e+06\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 3.24741e+06 and neighbour Nodes 1\n", + "Printing DiffFactor:1, obs= \n", + "1\n", + "1\n", + "1\n", + " Residuals=\n", + " -1.91812\n", + "-0.31305\n", + " 1.57043 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + " 0.175686 0.984446 0.68695 -0.175686 -0.984446 0\n", + "-0.984446 0.175686 0.918121 0.984446 -0.175686 0\n", + " 0 0 -1 0 0 1\n", + " Chi2 error = 3.12173 and neighbour Nodes 2\n", + "Printing DiffFactor:2, obs= \n", + "1\n", + "1\n", + "1\n", + " Residuals=\n", + " -1.91812\n", + "-0.31305\n", + " 1.57043 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + " 0.175686 0.984446 0.68695 -0.175686 -0.984446 0\n", + "-0.984446 0.175686 0.918121 0.984446 -0.175686 0\n", + " 0 0 -1 0 0 1\n", + " Chi2 error = 3.12173 and neighbour Nodes 2\n", + "Printing DiffFactor: 3, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 4, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 5, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 6, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 7, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 8, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 9, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 10, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 11, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 12, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor: 13, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals= \n", + "-0.083514\n", + "0.0543216\n", + "-0.962362 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Chi2 error = 0.468033 and neighbour Nodes 1\n", + "Printing DiffFactor:14, obs= \n", + " 1\n", + " 1\n", + "1.7854\n", + " Residuals=\n", + " -1\n", + " -1\n", + "-1.7854 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "-0.679998 -0.733214 0 0.679998 0.733214 0\n", + " 0.733214 -0.679998 -0 -0.733214 0.679998 0\n", + " 0 0 -1 0 0 1\n", + " Chi2 error = 2.59382 and neighbour Nodes 2\n", + "Printing DiffFactor:15, obs= \n", + " 1\n", + " 1\n", + "1.7864\n", + " Residuals=\n", + " -1\n", + " -1\n", + "-1.7864 \n", + "and Information matrix\n", + "1 0 0\n", + "0 1 0\n", + "0 0 1\n", + " Calculated Jacobian = \n", + "-0.679998 -0.733214 0 0.679998 0.733214 0\n", + " 0.733214 -0.679998 -0 -0.733214 0.679998 0\n", + " 0 0 -1 0 0 1\n", + " Chi2 error = 2.59561 and neighbour Nodes 2\n" + ] + } + ], + "source": [ + "graph = mrob.FGraphDiff()\n", + "\n", + "# TODO give more nodes, such as a rectangle.\n", + "x = np.random.randn(3)\n", + "n1 = graph.add_node_pose_2d(x)\n", + "x = 1 + np.random.randn(3)*1e-1\n", + "n2 = graph.add_node_pose_2d(x)\n", + "print('node 1 id = ', n1, ' , node 2 id = ', n2)\n", + "\n", + "\n", + "invCov = np.identity(3)\n", + "graph.add_factor_1pose_2d_diff(np.array([0,0,np.pi/4]),n1,1e6*invCov)\n", + "graph.add_factor_2poses_2d_diff(np.ones(3),n1,n2,invCov)\n", + "graph.add_factor_2poses_2d_diff(np.ones(3),n1,n2,invCov)\n", + "\n", + "graph.add_factor_1pose_2d_diff(np.ones(3) + np.array([0,0,np.pi/4]),n2,invCov)\n", + "\n", + "[graph.add_factor_1pose_2d_diff(np.ones(3) + np.array([0,0,np.pi/4]),n2,invCov) for i in range(10)]\n", + "\n", + "n3 = graph.add_node_pose_2d(x)\n", + "graph.add_factor_2poses_2d_diff(np.ones(3) + np.array([0,0,np.pi/4]),n2,n3,invCov)\n", + "graph.add_factor_2poses_2d_diff(np.ones(3) + np.array([0,0,np.pi/4+0.001]),n2,n3,invCov)\n", + "\n", + "graph.solve(mrob.FGraphDiff_GN)\n", + "graph.print(True)\n", + "gradient = graph.get_dchi2_dz()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, 'state dim')" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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zkV6ejrc3NwQGxuL6upqAEBCQgIqKyuxZ88eZGdn48MPP4STk9MdjzlmzBjk5+cjLS0NGzduxKJFi1BUVHTPrNOnT8df//pXZGZmwtbWFi+88AImT56MefPm4ccff0ROTg6mTZv2YCeEiCyTuVebJiKqc+3aNWFnZydWrVolt1VVVQlvb28xZ84cIYQQaWlpAoBYu3at3OfKlSvC0dFRrFu3TgghxMMPPyxmzJhh0jGPHz8uAIiDBw/KbUePHhUAxKeffiq3ARCbN28WQgiRm5srAIhly5bJ29esWSMAiJ07d8ptycnJIjg42PQTQERWg1ewiKjROHXqFKqrq9GzZ0+5zc7ODuHh4Th69KhB38jISPm9q6srgoOD5T6vv/463nvvPfTs2RPTp0/HoUOH7njMo0ePwtbWFmFhYXJbu3bt0KxZs3vmDQ0Nld97eHgAAB5++GGDNlOuhBGR9WGBRURW56WXXsLp06fx4osvIjs7G926dcOCBQtUP46dnZ38XpKkettqa2tVPy4RNX4ssIio0WjdujXs7e3x008/yW3V1dVIT09HSEiIQd/9+/fL769evYoTJ06gffv2cpuvry9eeeUVpKam4q233sLnn39e7zHbtWuHmpoaZGRkyG3Hjx9v8OdsEZF142MaiKjR0Gq1mDBhAt5++224urrCz88Pc+bMwfXr1zFu3DiDvrNmzUKLFi3g4eGBd999Fy1btsTgwYMBAImJiejfvz/atm2Lq1evIi0tzaD4ul1wcDCefPJJvPzyy1i8eDFsbW2RmJgIR0fHhv7jEpEV4xUsImpUZs+ejWHDhuHFF19E165dkZOTg23bthk95HP27Nl44403EBYWhosXL+Lrr7+Gvb09AECv1yMhIQHt27fHk08+ibZt22LRokV3POby5cvh7e2NqKgoDB06FH/605/g7u7eoH9OIrJukhBCmDsEERERkTXhFSwiIiIilbHAIiIiIlIZCywiIiIilbHAIiIiIlIZCywiIiIilbHAIiIiIlIZCywiIiIilbHAIiIiIlIZCywiIiIilbHAIiIiIlIZCywiIiIilbHAIiIiIlLZ/wErigoiR5Qr5AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(7,7))\n", + "plt.imshow(np.log(gradient**2+0.001))\n", + "plt.title('Gradient heatmap')\n", + "plt.xlabel('obs dim')\n", + "plt.ylabel('state dim')" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Traceback (most recent call last):\n", + " File \"_pydevd_bundle/pydevd_cython.pyx\", line 1078, in _pydevd_bundle.pydevd_cython.PyDBFrame.trace_dispatch\n", + " File \"_pydevd_bundle/pydevd_cython.pyx\", line 297, in _pydevd_bundle.pydevd_cython.PyDBFrame.do_wait_suspend\n", + " File \"/home/nosmokingsurfer/miniconda3/envs/theseus_env/lib/python3.8/site-packages/debugpy/_vendored/pydevd/pydevd.py\", line 1976, in do_wait_suspend\n", + " keep_suspended = self._do_wait_suspend(thread, frame, event, arg, suspend_type, from_this_thread, frames_tracker)\n", + " File \"/home/nosmokingsurfer/miniconda3/envs/theseus_env/lib/python3.8/site-packages/debugpy/_vendored/pydevd/pydevd.py\", line 2011, in _do_wait_suspend\n", + " time.sleep(0.01)\n", + "KeyboardInterrupt\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m A \u001b[38;5;241m=\u001b[39m \u001b[43mgraph\u001b[49m\u001b[38;5;241m.\u001b[39mget_adjacency_matrix()\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# plt.imshow(A.todense())\u001b[39;00m\n\u001b[1;32m 3\u001b[0m plt\u001b[38;5;241m.\u001b[39mspy(A\u001b[38;5;241m.\u001b[39mtodense())\n", + "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m A \u001b[38;5;241m=\u001b[39m \u001b[43mgraph\u001b[49m\u001b[38;5;241m.\u001b[39mget_adjacency_matrix()\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# plt.imshow(A.todense())\u001b[39;00m\n\u001b[1;32m 3\u001b[0m plt\u001b[38;5;241m.\u001b[39mspy(A\u001b[38;5;241m.\u001b[39mtodense())\n", + "File \u001b[0;32m_pydevd_bundle/pydevd_cython.pyx:1363\u001b[0m, in \u001b[0;36m_pydevd_bundle.pydevd_cython.SafeCallWrapper.__call__\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32m_pydevd_bundle/pydevd_cython.pyx:662\u001b[0m, in \u001b[0;36m_pydevd_bundle.pydevd_cython.PyDBFrame.trace_dispatch\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32m_pydevd_bundle/pydevd_cython.pyx:1087\u001b[0m, in \u001b[0;36m_pydevd_bundle.pydevd_cython.PyDBFrame.trace_dispatch\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32m_pydevd_bundle/pydevd_cython.pyx:1078\u001b[0m, in \u001b[0;36m_pydevd_bundle.pydevd_cython.PyDBFrame.trace_dispatch\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32m_pydevd_bundle/pydevd_cython.pyx:297\u001b[0m, in \u001b[0;36m_pydevd_bundle.pydevd_cython.PyDBFrame.do_wait_suspend\u001b[0;34m()\u001b[0m\n", + "File \u001b[0;32m~/miniconda3/envs/theseus_env/lib/python3.8/site-packages/debugpy/_vendored/pydevd/pydevd.py:1976\u001b[0m, in \u001b[0;36mPyDB.do_wait_suspend\u001b[0;34m(self, thread, frame, event, arg, exception_type)\u001b[0m\n\u001b[1;32m 1973\u001b[0m from_this_thread\u001b[38;5;241m.\u001b[39mappend(frame_custom_thread_id)\n\u001b[1;32m 1975\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_threads_suspended_single_notification\u001b[38;5;241m.\u001b[39mnotify_thread_suspended(thread_id, stop_reason):\n\u001b[0;32m-> 1976\u001b[0m keep_suspended \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_do_wait_suspend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mthread\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mframe\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mevent\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43marg\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msuspend_type\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfrom_this_thread\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mframes_tracker\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1978\u001b[0m frames_list \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 1980\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m keep_suspended:\n\u001b[1;32m 1981\u001b[0m \u001b[38;5;66;03m# This means that we should pause again after a set next statement.\u001b[39;00m\n", + "File \u001b[0;32m~/miniconda3/envs/theseus_env/lib/python3.8/site-packages/debugpy/_vendored/pydevd/pydevd.py:2011\u001b[0m, in \u001b[0;36mPyDB._do_wait_suspend\u001b[0;34m(self, thread, frame, event, arg, suspend_type, from_this_thread, frames_tracker)\u001b[0m\n\u001b[1;32m 2008\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_mpl_hook()\n\u001b[1;32m 2010\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprocess_internal_commands()\n\u001b[0;32m-> 2011\u001b[0m \u001b[43mtime\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0.01\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2013\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcancel_async_evaluation(get_current_thread_id(thread), \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28mid\u001b[39m(frame)))\n\u001b[1;32m 2015\u001b[0m \u001b[38;5;66;03m# process any stepping instructions\u001b[39;00m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "A = graph.get_adjacency_matrix()\n", + "# plt.imshow(A.todense())\n", + "plt.spy(A.todense())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhYAAACNCAYAAADreTN6AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAATJElEQVR4nO3df2xV9f3H8Vd/2AvC7ZUibWnaQmVMBkg3qcXKNqNUSUMIOEOMabJayZLpRajNktks/oq6lrGQTofAdKskWnAYC9OICJ1cRqDalnVBoxUcG9dgqS7j3tLJLbn3fP/wy513tHBPe0/P/fF8JCd6zz3nvt/6TnPe+ZzP+Zw0wzAMAQAAxEC63QkAAIDkQWMBAABihsYCAADEDI0FAACIGRoLAAAQMzQWAAAgZmgsAABAzNBYAACAmKGxAAAAMUNjAQAAYsb2xmLTpk2aOXOmJkyYoEWLFun999+3O6WUdPDgQS1fvlwFBQVKS0vTrl27Ir43DEOPPfaYpk+frokTJ6qyslLHjx+3J9kU09jYqJtuuklOp1O5ublauXKlent7I445f/683G63pk6dqsmTJ+vuu+/WmTNnbMo4dWzevFkLFixQdna2srOzVVFRoT179oS/py7xo6mpSWlpaaqrqwvvoz7WsLWxePXVV1VfX6/HH39cR48eVWlpqZYuXar+/n4700pJg4ODKi0t1aZNm4b9/le/+pWeffZZbdmyRe+9954mTZqkpUuX6vz58+OcaerxeDxyu93q6OjQvn37dOHCBd15550aHBwMH/Pwww/rjTfe0M6dO+XxeHT69Gn96Ec/sjHr1FBYWKimpiZ1d3erq6tLt99+u1asWKEPP/xQEnWJF52dndq6dasWLFgQsZ/6WMSwUXl5ueF2u8Ofg8GgUVBQYDQ2NtqYFSQZbW1t4c+hUMjIz883NmzYEN539uxZw+FwGNu3b7chw9TW399vSDI8Ho9hGF/X4qqrrjJ27twZPuajjz4yJBlHjhyxK82UNWXKFOPFF1+kLnFiYGDAmD17trFv3z7j1ltvNdatW2cYBn83VrJtxGJoaEjd3d2qrKwM70tPT1dlZaWOHDliV1oYxsmTJ9XX1xdRK5fLpUWLFlErG/h8PklSTk6OJKm7u1sXLlyIqM+cOXNUXFxMfcZRMBjUjh07NDg4qIqKCuoSJ9xut5YtWxZRB4m/Gytl2hX4yy+/VDAYVF5eXsT+vLw8ffzxxzZlheH09fVJ0rC1uvgdxkcoFFJdXZ0WL16s+fPnS/q6PllZWbrmmmsijqU+4+PYsWOqqKjQ+fPnNXnyZLW1tWnu3Lnq6emhLjbbsWOHjh49qs7Ozku+4+/GOrY1FgDMc7vd+uCDD3To0CG7U8H/u/7669XT0yOfz6fXXntNNTU18ng8dqeV8rxer9atW6d9+/ZpwoQJdqeTUmy7FXLttdcqIyPjkhm4Z86cUX5+vk1ZYTgX60Gt7LVmzRq9+eabevfdd1VYWBjen5+fr6GhIZ09ezbieOozPrKysvStb31LCxcuVGNjo0pLS/Wb3/yGutisu7tb/f39uvHGG5WZmanMzEx5PB49++yzyszMVF5eHvWxiG2NRVZWlhYuXKj29vbwvlAopPb2dlVUVNiVFoZRUlKi/Pz8iFr5/X6999571GocGIahNWvWqK2tTX/+859VUlIS8f3ChQt11VVXRdSnt7dXp06doj42CIVCCgQC1MVmS5Ys0bFjx9TT0xPeysrKVF1dHf536mMNW2+F1NfXq6amRmVlZSovL1dzc7MGBwdVW1trZ1op6dy5czpx4kT488mTJ9XT06OcnBwVFxerrq5OTz/9tGbPnq2SkhI9+uijKigo0MqVK+1LOkW43W61trZq9+7dcjqd4fu/LpdLEydOlMvl0urVq1VfX6+cnBxlZ2froYceUkVFhW6++Wabs09uDQ0NqqqqUnFxsQYGBtTa2qoDBw5o79691MVmTqczPA/pokmTJmnq1Knh/dTHInY/lvLcc88ZxcXFRlZWllFeXm50dHTYnVJKevfddw1Jl2w1NTWGYXz9yOmjjz5q5OXlGQ6Hw1iyZInR29trb9IpYri6SDJaWlrCx3z11VfGgw8+aEyZMsW4+uqrjbvuusv4/PPP7Us6Rdx///3GjBkzjKysLGPatGnGkiVLjHfeeSf8PXWJL9983NQwqI9V0gzDMGzqaQAAQJKxfUlvAACQPGgsAABAzNBYAACAmKGxAAAAMUNjAQAAYobGAgAAxExcNBaBQEBPPPGEAoGA3angf1Cb+EVt4hv1iV/UxlpxsY6F3++Xy+WSz+dTdna23engG6hN/KI28Y36xC9qY624GLEAAADJgcYCAADEzLi/hCwUCun06dNyOp1KS0uT9PWw1Df/ifhBbeIXtYlv1Cd+UZvRMQxDAwMDKigoUHr6yOMS4z7H4rPPPlNRUdF4hgQAADHi9XpVWFg44vejGrHYtGmTNmzYoL6+PpWWluq5555TeXl5VOc6nc6o4/h8vtGkd1kulyvmvxltnnbGBgBgLPx+v4qKiq54HTfdWLz66quqr6/Xli1btGjRIjU3N2vp0qXq7e1Vbm7uFc+/ePsjGokyW9fOPBPl/xEAIDlc6TpuevLmxo0b9ZOf/ES1tbWaO3eutmzZoquvvlp/+MMfRp0kAABIDqYai6GhIXV3d6uysvK/P5CersrKSh05cmTYcwKBgPx+f8QGAACSk6nG4ssvv1QwGFReXl7E/ry8PPX19Q17TmNjo1wuV3hj4iYAAMnL8nUsGhoa5PP5wpvX67U6JAAAsImpyZvXXnutMjIydObMmYj9Z86cUX5+/rDnOBwOORyO0WcIAAAShqkRi6ysLC1cuFDt7e3hfaFQSO3t7aqoqIh5cgAAILGYfty0vr5eNTU1KisrU3l5uZqbmzU4OKja2lor8gMAAAnEdGNxzz336IsvvtBjjz2mvr4+ffe739Xbb799yYTOK4nmrXJm1ryIg5e0AgCQ8sZ9SW8zr6u1orEw85vJFBsAgLGI9vpt+qmQgwcPavny5SooKFBaWpp27do1ljwBAEASMd1YDA4OqrS0VJs2bbIiHwAAkMBMz7GoqqpSVVWVFbkAAIAEN6q3m5oRCAQUCATCn1nSGwCA5GX5ypss6Q0AQOpgSW8AABAzlt8KYUlvAABSh+UjFgAAIHWYHrE4d+6cTpw4Ef588uRJ9fT0KCcnR8XFxTFNDgAAJBbTjUVXV5duu+228Of6+npJUk1NjV566aWYJSaZW1XSilUtkyk2K3QCAMaDqcaisbFRr7/+uiZPnqyJEyfqlltu0fr163X99ddblR8AAEggpuZYeDweud1udXR0aN++fbpw4YLuvPNODQ4OWpUfAABIIGN6CdkXX3yh3NxceTwe/fCHP4zqHDMvITPDztsRiYBbIQCAsYj2+j2mx019Pp8kKScnZ8RjWHkTAIDUMerHTUOhkOrq6rR48WLNnz9/xONYeRMAgNQx6lshDzzwgPbs2aNDhw6psLBwxOOGG7EoKiriVsg441YIAGAsLL0VsmbNGr355ps6ePDgZZsKiZU3AQBIJaYaC8Mw9NBDD6mtrU0HDhxQSUmJVXkBAIAEZKqxcLvdam1t1e7du+V0OtXX1ydJcrlcmjhxoiUJAgCAxGFqjsVI8xhaWlp03333RfUbVj1uGi0r5mJE+78wEWJbMReD2MQmNrFTNbYZ8X4tifb6beqpkOeff1433HCDnE6nnE6nbr75Zr311ltRNxUAACC5mWosCgsL1dTUpO7ubnV1den222/XihUr9OGHH1qVHwAASCBjWnlT+npxrA0bNmj16tVRHc+tkPiOnarDlcQmNrGJbUVsM+L9WmL5ypvBYFA7d+7U4OCgKioqRjyOlTcBAEgdplfePHbsmCZPniyHw6Gf/vSnamtr09y5c0c8npU3AQBIHaZvhQwNDenUqVPy+Xx67bXX9OKLL8rj8YzYXIzXypvRSsXhKzOxU3W4ktjEJjaxrYhtRrxfS6K9FTLmORaVlZWaNWuWtm7dGtXxzLGI79ip+sdPbGITm9hWxDYj3q8lljxuOpxQKBQxIgEAAFKXqcmbDQ0NqqqqUnFxsQYGBtTa2qoDBw5o7969VuUHAAASiKnGor+/Xz/+8Y/1+eefy+VyacGCBdq7d6/uuOMOq/JDjFgxxBbtbxKb2MQmdrLFxshMNRa///3vrcoDAAAkgTHNsWhqalJaWprq6upilA4AAEhko24sOjs7tXXrVi1YsCCW+QAAgAQ2qsbi3Llzqq6u1gsvvKApU6bEOicAAJCgRtVYuN1uLVu2TJWVlVc8NhAIyO/3R2wAACA5mX5XyI4dO3T06FF1dnZGdXxjY6OefPJJ04kBAIDEY2rEwuv1at26dXrllVc0YcKEqM5paGiQz+cLb16vd1SJAgCA+GdqxKK7u1v9/f268cYbw/uCwaAOHjyo3/72twoEAsrIyIg4x+FwyOFwxCZbAAAQ10w1FkuWLNGxY8ci9tXW1mrOnDn6+c9/fklTAQAAUoupxsLpdGr+/PkR+yZNmqSpU6desh8AAKQe05M3E12qvmEv1kvkEpvYxCY2sWMrEWJHw9TkzSeeeEJpaWkRW19fn5qbm2OWEAAASFymRyzmzZun/fv3//cHMlNu0AMAAIzAdFeQmZmp/Px8K3IBAAAJzvTKm8ePH1dBQYGuu+46VVdX69SpU5c9npU3AQBIHaYai0WLFumll17S22+/rc2bN+vkyZP6wQ9+oIGBgRHPaWxslMvlCm9FRUVjThoAAMSnNGMM00vPnj2rGTNmaOPGjVq9evWwxwQCAQUCgfBnv9+voqIi+Xw+ZWdnjzZ0XEmEmbzEJjaxiU1sYo81tqQrXr/HNPPymmuu0be//W2dOHFixGNYeRMAgNQxqrebXnTu3Dl9+umnmj59eqzyAQAACcxUY/Gzn/1MHo9H//jHP3T48GHdddddysjI0L333mtVfgAAIIGYuhXy2Wef6d5779W//vUvTZs2Td///vfV0dGhadOmWZVfQrDifhexiU1sYhM7fmPHcqXKRInt9/vlcrmueJypEYsdO3aos7NTq1at0ldffaXdu3dr5cqV6urqMvMzAAAgSZkasfj3v/+txYsX67bbbtOePXs0bdo0HT9+XFOmTLEqPwAAkEBMNRbr169XUVGRWlpawvtKSkpinhQAAEhMpm6F/OlPf1JZWZlWrVql3Nxcfe9739MLL7xw2XNYeRMAgNRhqrH4+9//rs2bN2v27Nnau3evHnjgAa1du1bbtm0b8RxW3gQAIHWYWnkzKytLZWVlOnz4cHjf2rVr1dnZqSNHjgx7TiqsvAkASC2p/FTIla7fpkYspk+frrlz50bs+853vnPZF5E5HA5lZ2dHbAAAIDmZaiwWL16s3t7eiH2ffPKJZsyYEdOkAABAYjLVWDz88MPq6OjQL3/5S504cUKtra363e9+J7fbbVV+AAAggZhqLG666Sa1tbVp+/btmj9/vp566ik1NzerurraqvwAAEACGdNr00cj2skfAADEKyZvxmjy5syZM5WWlnbJxq0QAAAgmVx5s7OzU8FgMPz5gw8+0B133KFVq1bFPDEAAJB4TDUW//sW06amJs2aNUu33nprTJMCAACJyVRj8U1DQ0N6+eWXVV9ff9n7PcMtkAUAAJKTqTkW37Rr1y6dPXtW991332WPY0lvAABSx6ifClm6dKmysrL0xhtvXPY4lvQGACQbngoZ+fo9qlsh//znP7V//369/vrrVzzW4XDI4XCMJgwAAEgwo7oV0tLSotzcXC1btizW+QAAgARmurEIhUJqaWlRTU2NMjNHPfcTAAAkIdOdwf79+3Xq1Cndf//9VuQDAEDcs2LR6mjnTtgZOxqmRiyCwaD+8pe/aObMmSotLdWsWbP01FNPWfIfCQAAEo+pEYv169dr8+bN2rZtm+bNm6euri7V1tbK5XJp7dq1VuUIAAAShKnG4vDhw1qxYkV40ubMmTO1fft2vf/++5YkBwAAEoupWyG33HKL2tvb9cknn0iS/va3v+nQoUOqqqoa8ZxAICC/3x+xAQCA5GRqxOKRRx6R3+/XnDlzlJGRoWAwqGeeeUbV1dUjntPY2Kgnn3xyzIkCAID4Z2rE4o9//KNeeeUVtba26ujRo9q2bZt+/etfa9u2bSOe09DQIJ/PF968Xu+YkwYAAPHJ1JLeRUVFeuSRR+R2u8P7nn76ab388sv6+OOPo/qNaJcEBQAglSTK46ZXun6bGrH4z3/+o/T0yFMyMjIUCoXM/AwAAEhSpuZYLF++XM8884yKi4s1b948/fWvf9XGjRtNLZZ1sdNiEicAAObZff284oiJYYLf7zfWrVtnFBcXGxMmTDCuu+464xe/+IURCASi/g2v12tIYmNjY2NjY0vAzev1XvY6P+rXpo9WKBTS6dOn5XQ6w/d0Lr5K3ev1Mu8izlCb+EVt4hv1iV/UZnQMw9DAwIAKCgoumRbxTeP+FrH09HQVFhYO+112djZFjlPUJn5Rm/hGfeIXtTHP5XJd8ZhRvTYdAABgODQWAAAgZuKisXA4HHr88cflcDjsTgX/g9rEL2oT36hP/KI21hr3yZsAACB5xcWIBQAASA40FgAAIGZoLAAAQMzQWAAAgJihsQAAADFDYwEAAGKGxgIAAMQMjQUAAIiZ/wNSVPIl1RR5+AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.spy(gradient)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Current chi2 = 2308145.482959392\n", + "chi2 after solve: 688044.6019549619\n", + "Current chi2 = 2936626.1219638903\n", + "chi2 after solve: 1000716.1428231375\n", + "Current chi2 = 2405935.8282908117\n", + "chi2 after solve: 1000444.6336990754\n", + "Current chi2 = 2453001.0364193833\n", + "chi2 after solve: 822690.95734589\n" + ] + }, + { + "data": { + "image/png": "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oe7y7UxeXh4AOLy/csn3pjl79gIiIiJXtmXLFqHRaMTmzZvFmTNnxCOPPCICAgIcZhaSq6eeekrs379fFBcXiy+++EKkpqaK4OBgUVVVJYQQ4tFHHxXR0dFi79694ujRo0Kv1wu9Xu/kqHuurq5OHD9+XBw/flwAEC+//LI4fvy4uHjxohBCiA0bNoiAgACxY8cOceLECTFv3jwRGxsrmpqa7PuYNWuWmDBhgsjJyREHDx4U8fHxYvHixc5K6YZulG9dXZ14+umnRVZWliguLhaff/65uP3220V8fLxobm6270Mu+a5YsUJotVqxf/9+UVFRYV8aGxvtbbo7fi0Wixg3bpyYOXOmyMvLE7t27RIhISFizZo1zkjphrrLt7CwUDz//PPi6NGjori4WOzYsUPExcWJadOm2fchp3xvFgsbIiKibrz22msiOjpaqNVqMXnyZJGdne3skPrEokWLRHh4uFCr1WLo0KFi0aJForCw0L6+qalJPPbYY2LIkCHC29tb3H///aKiosKJEffOvn37BIDrlqVLlwoh2qZ8fvbZZ0VYWJjQaDRixowZIj8/32EfNTU1YvHixcLX11f4+/uLZcuWibq6Oidk070b5dvY2ChmzpwpQkJChIeHh4iJiREPP/zwdQW6XPLtLE8AYtOmTfY2PTl+L1y4IGbPni28vLxEcHCweOqpp4TZbB7gbLrXXb4lJSVi2rRpIjAwUGg0GjFixAjxzDPPCKPR6LAfueR7syQhhBi460NERERERER9j2NsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LlfYbNy4EcOGDYOnpydSUlJw+PBhZ4fUJ9avXw9JkhyWhIQE+/rm5makp6cjKCgIvr6+WLhwISorK50Yce8cOHAAc+fORUREBCRJwkcffeSwXgiBtWvXIjw8HF5eXkhNTUVBQYFDmytXrmDJkiXw9/dHQEAAli9fjvr6+gHMoue6y/ehhx667v2eNWuWQxu55JuRkYFJkybBz88PoaGhmD9/PvLz8x3a9OT4LSkpwZw5c+Dt7Y3Q0FA888wzsFgsA5lKj/Qk3+nTp1/3/j766KMObeSSLxERkbtwqcJm69atWL16NdatW4djx44hKSkJaWlpqKqqcnZofWLs2LGoqKiwLwcPHrSvW7VqFXbu3Ilt27YhMzMT5eXlWLBggROj7Z2GhgYkJSVh48aNna5/8cUX8eqrr+LNN99ETk4OfHx8kJaWhubmZnubJUuW4PTp09i9ezc+/vhjHDhwAI888shApdAr3eULALNmzXJ4v99//32H9XLJNzMzE+np6cjOzsbu3bthNpsxc+ZMNDQ02Nt0d/xarVbMmTMHra2tOHTo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D19XoMsl387yBCA2bdpkb9OT4/fChQti9uzZwsvLSwQHB4unnnpKmM3mAc6me93lW1JSIqZNmyYCAwOFRqMRI0aMEM8884wwGo0O+5FLvjdLEkKIgbs+RERERERE1Pc4xoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREsudy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LE6fPi0efvhh4evra9ezkFw9+eSTYt++faKgoEB88803Ijk5WQQGBory8nIhhBCPPPKIiIyMFHv27BFHjx4VSUlJIikpycFR91xtba3IysoSWVlZAoB45ZVXRFZWlrh48aIQQogNGzYIX19fsX37dnH8+HGxYMECER0dLRobG23bmDt3rpg8ebLIyMgQBw4cELGxsWLp0qWOSqlLXeVbW1srnnrqKZGeni4KCgrE119/LW666SYRGxsrmpqabNuQS74rV64UOp1O7Nu3T5SWltqmhoYG2zLd7b9ms1mMHz9ezJ49W2RnZ4udO3eKoKAgkZqa6oiUutRdvnl5eeLFF18UR48eFQUFBWL79u0iJiZGzJgxw7YNOeV7o1jYEBERdeONN94QkZGRQqPRiGnTpolDhw45OqR+sWTJEhEaGio0Go0YNmyYWLJkicjLy7PNb2xsFI8++qjw8/MTHh4e4p577hGlpaUOjLh39u7dKwB0mB544AEhRGuXz88995wICQkRWq1WzJo1S+Tk5Nhto7KyUixdulR4eXkJHx8fsXz5clFbW+uAbLrXVb4NDQ1i9uzZIigoSKjVahEVFSUeeuihDgW6XPLtLE8A4t1337Ut05P998KFC2LevHnC3d1dBAYGiieffFKYTKZBzqZ73eVbWFgoZsyYIfz9/YVWqxUjR44UTz/9tDAajXbbkUu+N0oSQojBuz5ERERERETU/9jGhoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkj4UNERERERHJHgsbIiIiIiKSPRY2REREREQkeyxsiIiIiIhI9ljYEBERERGR7LGwISIiIiIi2WNhQ0REREREssfChoiIiIiIZI+FDRERERERyR4LGyIiIiIikj0WNkREREREJHssbIiIiIiISPZY2BARERERkeyxsCEiIiIiItljYUNERERERLLHwoaIiIiIiGSPhQ0REREREckeCxsiIiIiIpI9FjZERERERCR7LGyIiIiIiEj2WNgQEREREZHssbAhIiIiIiLZY2FDRERERESyx8KGiIiIiIhkz+kKm02bNmH48OFwc3NDYmIiDh8+7OiQ+sXzzz8PSZLspri4ONv8pqYmpKSkICAgAF5eXli8eDHKysocGHHv7N+/H3fffTfCwsIgSRI+//xzu/lCCKxduxahoaFwd3dHcnIycnNz7ZapqqrCsmXL4OPjA19fX6xYsQJ1dXWDmEXPdZfvgw8+2OHznjt3rt0ycsl3/fr1mDp1Kry9vREcHIyFCxciJyfHbpme7L+FhYWYP38+PDw8EBwcjKeffhpms3kwU+mRnuQ7c+bMDp/vI488YreMXPIlIiJyFU5V2Hz88cdYs2YN1q1bh2PHjmHixImYM2cOysvLHR1avxg3bhxKS0tt04EDB2zzVq9ejR07dmDLli1IS0tDSUkJFi1a5MBoe6e+vh4TJ07Epk2bOp2/ceNGvP7663jrrbeQkZEBT09PzJkzB01NTbZlli1bhlOnTmHXrl344osvsH//fjz88MODlUKvdJcvAMydO9fu8/7www/t5ssl37S0NKSkpODQoUPYtWsXTCYTZs+ejfr6etsy3e2/FosF8+fPR0tLCw4ePIj33nsPmzdvxtq1ax2RUpd6ki8APPTQ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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from graph_generator import generate_random_graph\n", + "\n", + "N_graphs = 4\n", + "\n", + "fig,ax = plt.subplots(N_graphs,2,figsize=(10,10))\n", + "\n", + "for i in range(N_graphs):\n", + " graph = generate_random_graph(20, 100)\n", + "\n", + " graph.solve(mrob.FGraphDiff_GN)\n", + " print(f'chi2 after solve: {graph.chi2()}')\n", + " gradient = graph.get_dchi2_dz()\n", + " ax[i,0].spy(gradient)\n", + " ax[i,1].imshow(np.log(gradient**2+0.001))" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "graph" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "mrob", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/python_examples/graph_generator.py b/python_examples/graph_generator.py new file mode 100644 index 0000000..a633ab2 --- /dev/null +++ b/python_examples/graph_generator.py @@ -0,0 +1,52 @@ +import mrob +import numpy as np +import matplotlib.pyplot as plt + +def generate_random_graph(nodes: int = 5, factors : int = 10) -> mrob.FGraphDiff: + + assert factors >= nodes*2 + graph = mrob.FGraphDiff() + + x = np.random.randn(3)*1e-1 + n = graph.add_node_pose_2d(x, mrob.NODE_ANCHOR) + + addional_factor_counter = 0 + + max_additional_factors = factors - nodes*2 + + indexes = [n] + for i in range(1, nodes): + x = np.array([i,0,0]) + np.random.randn(3)*1e-1 + n = graph.add_node_pose_2d(x) + + invCov = np.identity(3) + graph.add_factor_1pose_2d_diff(np.array([i,0,0] + np.random.randn(3)*1e-1),n,1e6*invCov) + graph.add_factor_2poses_2d_diff(np.array([1,0,0]),indexes[-1],n,invCov) + if addional_factor_counter < max_additional_factors: + if np.random.random() > 0.5: + graph.add_factor_1pose_2d_diff(np.array([i,0,0] + np.random.randn(3)*1e-1), n, 1e6*invCov) + addional_factor_counter += 1 + + indexes.append(n) + + node_index = 0 + while addional_factor_counter < max_additional_factors: + if np.random.random() > 0.5: + graph.add_factor_1pose_2d_diff(np.array([node_index,0,0] + np.random.randn(3)*1e-1), node_index, 1e6*invCov) + addional_factor_counter += 1 + + else: + node_index += 1 + + node_index = node_index % nodes + + print('Current chi2 = ', graph.chi2() ) # re-evaluates the error, on print it is only the error on evalation before update + + return graph + +if __name__ == "__main__": + graph = generate_random_graph(10,20) + + print(graph) + + graph.solve() diff --git a/src/FGraphDiff/examples/example_solver_2d.cpp b/src/FGraphDiff/examples/example_solver_2d.cpp index f19b9e5..6d24f26 100644 --- a/src/FGraphDiff/examples/example_solver_2d.cpp +++ b/src/FGraphDiff/examples/example_solver_2d.cpp @@ -78,6 +78,18 @@ int main () obs << 2, 2, 0; std::shared_ptr gnss_3(new mrob::Factor1Pose2d_diff(obs,n3,obsInformation*1e4)); diff_factor_idx.emplace_back(graph.add_factor(gnss_3)); + + // obs << 2,2,0; + // std::shared_ptr gnss_4(new mrob::Factor1Pose2d_diff(obs,n3,obsInformation*1e4)); + // diff_factor_idx.emplace_back(graph.add_factor(gnss_4)); + + // obs << 2, 2, 0; + // std::shared_ptr gnss_5(new mrob::Factor1Pose2d_diff(obs,n3,obsInformation*1e4)); + // diff_factor_idx.emplace_back(graph.add_factor(gnss_5)); + + // obs << 2,2,0; + // std::shared_ptr gnss_6(new mrob::Factor1Pose2d_diff(obs,n3,obsInformation*1e4)); + // diff_factor_idx.emplace_back(graph.add_factor(gnss_6)); } // solve the Gauss Newton optimization @@ -96,51 +108,70 @@ int main () std::cout << x << std::endl; } - // composing the gradient dr_dz for the problem - auto A = graph.get_adjacency_matrix(); // has size |z| by |x| - std::cout << "\nA = \n" << MatX(A) << std::endl; + if (true) + { + + // composing the gradient dr_dz for the problem + auto A = graph.get_adjacency_matrix(); // has size |z| by |x| + std::cout << "\nA = \n" << MatX(A) << std::endl; + + auto info = graph.get_information_matrix(); + std::cout << "\ninfo =\n" << MatX(info) << std::endl; - auto info = graph.get_information_matrix(); - std::cout << "\ninfo =\n" << MatX(info) << std::endl; + auto b = graph.get_vector_b(); + std::cout << "\nb =\n" << MatX(b) << std::endl; - auto b = graph.get_vector_b(); - std::cout << "\nb =\n" << MatX(b) << std::endl; + auto W = graph.get_W_matrix(); + std::cout << "\nW =\n" << MatX(W) << std::endl; - auto W = graph.get_W_matrix(); - std::cout << "\nW =\n" << MatX(W) << std::endl; + auto r = graph.get_vector_r(); - auto r = graph.get_vector_r(); - std::cout << "Residuals = " << r << std::endl; + std::cout << "Residuals = " << r << std::endl; - Eigen::SimplicialLDLT> alpha_solve; - alpha_solve.compute(A.transpose()*W*A); - SMatCol rhs(A.cols(),A.cols()); - rhs.setIdentity(); - std::cout << rhs << std::endl; + Eigen::SimplicialLDLT> alpha_solve; + std::cout << "\ninfo =\n" << MatX(info) << std::endl; - MatX alpha = alpha_solve.solve(rhs); // get information matrix graph - should be the same #TODO - std::cout << "\nalpha =\n" << alpha << std::endl; + std::cout << MatX(A.transpose()*W*A) << std::endl; + alpha_solve.compute(A.transpose()*W*A); + SMatCol rhs(A.cols(),A.cols()); + rhs.setIdentity(); + std::cout << rhs << std::endl; - MatX info_matrix = graph.get_information_matrix(); - std::cout << "\ninfo matrix =\n" << info_matrix << std::endl; + MatX alpha = alpha_solve.solve(rhs); // get information matrix graph - should be the same #TODO + std::cout << "\nalpha =\n" << alpha << std::endl; - std::cout << "\nA = \n" << MatX(graph.get_adjacency_matrix()) << std::endl; + MatX info_matrix = graph.get_information_matrix(); + std::cout << "\ninfo matrix =\n" << info_matrix << std::endl; - graph.build_dr_dz(); + std::cout << "\nA = \n" << MatX(graph.get_adjacency_matrix()) << std::endl; - std::cout << "\nA = \n" << MatX(graph.get_adjacency_matrix()) << std::endl; + std::cout << "\nA = \n" << MatX(graph.get_adjacency_matrix()) << std::endl; - SMatRow dr_dz_full = graph.get_dr_dz(); - std::cout << "\nMatrix B aka dr_dz matrix =\n" << MatX(dr_dz_full) << std::endl; + SMatRow dr_dz_full = graph.get_dr_dz(); + std::cout << "\nMatrix B aka dr_dz matrix =\n" << MatX(dr_dz_full) << std::endl; - MatX errors_grads; - errors_grads.resize(graph.get_dimension_state(), graph.get_dimension_obs()); + MatX errors_grads; + errors_grads.resize(graph.get_dimension_state(), graph.get_dimension_obs()); - errors_grads = -alpha*dr_dz_full.transpose()*W*dr_dz_full; + std::cout << MatX(dr_dz_full) << std::endl; - std::cout << "\nError_grads = \n" << errors_grads << std::endl; + std::cout << MatX(dr_dz_full.transpose()*W*dr_dz_full) << std::endl; + + std::cout << MatX(alpha) << std::endl; + std::cout << MatX(W) << std::endl; + std::cout << MatX(dr_dz_full) << std::endl; + std::cout << MatX(W*dr_dz_full) << std::endl; + + errors_grads = MatX(-(A.transpose()*W*dr_dz_full)); + + std::cout << "\nError_grads = \n" << errors_grads << std::endl; + + auto dchi2_dz = graph.get_dchi2_dz(); + + std::cout << "\nError_grads = \n" << MatX(dchi2_dz) << std::endl; + } return 0; } diff --git a/src/FGraphDiff/factor_graph_diff_solve.cpp b/src/FGraphDiff/factor_graph_diff_solve.cpp index 75b33d6..a6c3993 100644 --- a/src/FGraphDiff/factor_graph_diff_solve.cpp +++ b/src/FGraphDiff/factor_graph_diff_solve.cpp @@ -255,100 +255,132 @@ void FGraphDiffSolve::build_index_nodes_matrix() } } -void FGraphDiffSolve::build_dr_dz() +// void FGraphDiffSolve::build_dr_dz() +// { + +// indNodesMatrix_.clear(); +// this->build_index_nodes_matrix(); +// assert(N_ == stateDim_ && "FGraphDiffSolve::buildAdjacency: State Dimensions are not coincident\n"); + + +// // 2.1) Check for consistency. With 0 observations the problem does not need to be build, EF may still build it +// if (obsDim_ == 0) +// { +// buildAdjacencyFlag_ = false; +// return; +// } +// buildAdjacencyFlag_ = true; + +// // 2) resize properly matrices (if needed) +// // r_.resize(obsDim_,1);//dense vector TODO is it better to reserve and push_back?? +// // A_.resize(obsDim_, stateDim_);//Sparse matrix clears data, but keeps the prev reserved space +// // W_.resize(obsDim_, obsDim_);//TODO should we reinitialize this all the time? an incremental should be fairly easy +// //=============================================== +// B_.resize(obsDim_, obsDim_); + +// std::vector reservationB; +// reservationB.reserve( obsDim_ ); +// std::vector reservationW; +// // reservationW.reserve( obsDim_ ); +// std::vector indFactorsMatrix; +// indFactorsMatrix.reserve(diff_factors_.size()); +// M_ = 0; + +// for (uint_t i = 0; i < diff_factors_.size(); ++i) +// { +// auto f = diff_factors_[i]; +// f->evaluate_residuals(); +// f->evaluate_jacobians(); +// f->evaluate_chi2(); +// f->evaluate_dr_dz(); + +// // calculate dimensions for reservation and bookeping vector +// uint_t dim = f->get_dim_obs(); +// uint_t allDim = f->get_all_nodes_dim(); +// for (uint_t j = 0; j < dim; ++j) +// { +// reservationB.push_back(allDim); +// // reservationW.push_back(dim-j);//XXX this might be allocating more elements than necessary, check +// } +// indFactorsMatrix.push_back(M_); +// M_ += dim; +// } +// assert(M_ == obsDim_ && "FGraphDiffSolve::buildAdjacency: Observation dimensions are not coincident\n"); +// B_.reserve(reservationB); //Exact allocation for elements. +// // W_.reserve(reservationW); //same + +// for (factor_id_t i = 0; i < diff_factors_.size(); ++i) +// { +// auto f = diff_factors_[i]; + +// // 4) Get the calculated residual +// r_.block(indFactorsMatrix[i], 0, f->get_dim_obs(), 1) << f->get_residual(); + +// // 5) build Adjacency matrix as a composition of rows +// // 5.1) Get the number of nodes involved. It is a vector of nodes +// auto neighNodes = f->get_neighbour_nodes(); +// // Iterates over the Jacobian row +// for (uint_t l=0; l < f->get_dim_obs() ; ++l) +// { +// uint_t totalK = 0; +// // Iterates over the number of neighbour Nodes (ordered by construction) +// for (uint_t j=0; j < neighNodes->size(); ++j) +// { +// uint_t dimNode = (*neighNodes)[j]->get_dim(); +// // check for node if it is an anchor node, then skip emplacement of Jacobian in the Adjacency +// if ((*neighNodes)[j]->get_node_mode() == Node::nodeMode::ANCHOR) +// { +// totalK += dimNode;// we need to account for the dim in the Jacobian, to read the next block +// continue;//skip this loop +// } +// factor_id_t id = (*neighNodes)[j]->get_id(); +// for(uint_t k = 0; k < dimNode; ++k) +// { +// // order according to the permutation vector +// uint_t iRow = indFactorsMatrix[i] + l; +// // In release mode, indexes outside will not trigger an exception +// uint_t iCol = indFactorsMatrix[id] + k; +// // This is an ordered insertion +// B_.insert(iRow,iCol) = f->get_dr_dz()(l, k); +// } +// totalK += dimNode; +// } +// } +// } +// } + +MatX FGraphDiffSolve::get_dchi2_dz() { + // composing the gradient dr_dz for the problem + auto A = get_adjacency_matrix(); // has size |z| by |x| + // std::cout << "\nA = \n" << MatX(A) << std::endl; - indNodesMatrix_.clear(); - this->build_index_nodes_matrix(); - assert(N_ == stateDim_ && "FGraphDiffSolve::buildAdjacency: State Dimensions are not coincident\n"); + auto info = get_information_matrix(); + // std::cout << "\ninfo =\n" << MatX(info) << std::endl; + auto b = get_vector_b(); + // std::cout << "\nb =\n" << MatX(b) << std::endl; - // 2.1) Check for consistency. With 0 observations the problem does not need to be build, EF may still build it - if (obsDim_ == 0) - { - buildAdjacencyFlag_ = false; - return; - } - buildAdjacencyFlag_ = true; + auto W = get_W_matrix(); + // std::cout << "\nW =\n" << MatX(W) << std::endl; - // 2) resize properly matrices (if needed) - // r_.resize(obsDim_,1);//dense vector TODO is it better to reserve and push_back?? - // A_.resize(obsDim_, stateDim_);//Sparse matrix clears data, but keeps the prev reserved space - // W_.resize(obsDim_, obsDim_);//TODO should we reinitialize this all the time? an incremental should be fairly easy - //=============================================== - B_.resize(obsDim_, stateDim_); + MatX info_matrix = get_information_matrix(); + // std::cout << "\ninfo matrix =\n" << info_matrix << std::endl; - std::vector reservationB; - reservationB.reserve( obsDim_ ); - std::vector reservationW; - // reservationW.reserve( obsDim_ ); - std::vector indFactorsMatrix; - indFactorsMatrix.reserve(diff_factors_.size()); - M_ = 0; + // build_dr_dz(); - for (uint_t i = 0; i < diff_factors_.size(); ++i) - { - auto f = diff_factors_[i]; - f->evaluate_residuals(); - f->evaluate_jacobians(); - f->evaluate_chi2(); - f->evaluate_dr_dz(); - - // calculate dimensions for reservation and bookeping vector - uint_t dim = f->get_dim_obs(); - uint_t allDim = f->get_all_nodes_dim(); - for (uint_t j = 0; j < dim; ++j) - { - reservationB.push_back(allDim); - // reservationW.push_back(dim-j);//XXX this might be allocating more elements than necessary, check - } - indFactorsMatrix.push_back(M_); - M_ += dim; - } - assert(M_ == obsDim_ && "FGraphDiffSolve::buildAdjacency: Observation dimensions are not coincident\n"); - B_.reserve(reservationB); //Exact allocation for elements. - // W_.reserve(reservationW); //same + SMatRow dr_dz_full = get_dr_dz(); - for (factor_id_t i = 0; i < diff_factors_.size(); ++i) - { - auto f = diff_factors_[i]; + MatX errors_grads; + errors_grads.resize(get_dimension_state(), get_dimension_obs()); - // 4) Get the calculated residual - r_.block(indFactorsMatrix[i], 0, f->get_dim_obs(), 1) << f->get_residual(); + errors_grads = - A.transpose() * W * dr_dz_full; - // 5) build Adjacency matrix as a composition of rows - // 5.1) Get the number of nodes involved. It is a vector of nodes - auto neighNodes = f->get_neighbour_nodes(); - // Iterates over the Jacobian row - for (uint_t l=0; l < f->get_dim_obs() ; ++l) - { - uint_t totalK = 0; - // Iterates over the number of neighbour Nodes (ordered by construction) - for (uint_t j=0; j < neighNodes->size(); ++j) - { - uint_t dimNode = (*neighNodes)[j]->get_dim(); - // check for node if it is an anchor node, then skip emplacement of Jacobian in the Adjacency - if ((*neighNodes)[j]->get_node_mode() == Node::nodeMode::ANCHOR) - { - totalK += dimNode;// we need to account for the dim in the Jacobian, to read the next block - continue;//skip this loop - } - factor_id_t id = (*neighNodes)[j]->get_id(); - for(uint_t k = 0; k < dimNode; ++k) - { - // order according to the permutation vector - uint_t iRow = indFactorsMatrix[i] + l; - // In release mode, indexes outside will not trigger an exception - uint_t iCol = indNodesMatrix_[id] + k; - // This is an ordered insertion - B_.insert(iRow,iCol) = f->get_dr_dz()(l, k); - } - totalK += dimNode; - } - } - } + return errors_grads; } + + void FGraphDiffSolve::build_adjacency() { // 1) Node indexes bookkept. We use a map to ensure the index from nodes to the current active_node @@ -369,7 +401,7 @@ void FGraphDiffSolve::build_adjacency() r_.resize(obsDim_,1);//dense vector TODO is it better to reserve and push_back?? A_.resize(obsDim_, stateDim_);//Sparse matrix clears data, but keeps the prev reserved space W_.resize(obsDim_, obsDim_);//TODO should we reinitialize this all the time? an incremental should be fairly easy - B_.resize(obsDim_, stateDim_); + B_.resize(obsDim_, obsDim_); // 3) Evaluate every factor given the current state and bookeeping of DiffFactor indices std::vector reservationA; @@ -441,7 +473,7 @@ void FGraphDiffSolve::build_adjacency() uint_t iCol = indNodesMatrix_[id] + k; // This is an ordered insertion A_.insert(iRow,iCol) = f->get_jacobian()(l, k + totalK); - B_.insert(iRow,iCol) = f->get_dr_dz()(l, k); + // B_.insert(iRow,iCol) = f->get_dr_dz()(l, k); } totalK += dimNode; } @@ -461,6 +493,8 @@ void FGraphDiffSolve::build_adjacency() // Weights are then applied both to the residual and the Hessian by modifying the information matrix. robust_weight = f->evaluate_robust_weight(std::sqrt(f->get_chi2())); W_.insert(iRow,iCol) = robust_weight * f->get_information_matrix()(l,k); + B_.insert(iRow,iCol) = f->get_dr_dz()(l, k); + } } } //end factors loop diff --git a/src/FGraphDiff/mrob/factor_graph_diff_solve.hpp b/src/FGraphDiff/mrob/factor_graph_diff_solve.hpp index 4fd090d..b481706 100644 --- a/src/FGraphDiff/mrob/factor_graph_diff_solve.hpp +++ b/src/FGraphDiff/mrob/factor_graph_diff_solve.hpp @@ -136,8 +136,17 @@ class FGraphDiffSolve: public FGraphDiff * TODO If true, it re-evaluates the problem */ SMatCol get_adjacency_matrix() { return A_;} - void build_dr_dz(); - SMatRow get_dr_dz() {return B_;} + // void build_dr_dz(); + SMatRow get_dr_dz() {return B_;} + + /** + * @brief Get the derivative of chi2 by observations z. + * + * dchi2_dz = -alpha*dr_dz_full.transpose()*W*dr_dz_full; + * + * @return SMatRow of shape dim_state X dim_obs + */ + MatX get_dchi2_dz(); /** * Returns a copy to the W matrix. diff --git a/src/pybind/FGraphDiffPy.cpp b/src/pybind/FGraphDiffPy.cpp index c70c59e..0550d5a 100644 --- a/src/pybind/FGraphDiffPy.cpp +++ b/src/pybind/FGraphDiffPy.cpp @@ -163,6 +163,8 @@ void init_FGraphDiff(py::module &m) .def("number_nodes", &FGraphDiffSolve::number_nodes, "Returns the number of nodes") .def("number_factors", &FGraphDiffSolve::number_factors, "Returns the number of factors") .def("print", &FGraphDiff::print, "By default False: does not print all the information on the Fgraph", py::arg("completePrint") = false) + .def("get_dchi2_dz", &FGraphDiffSolve::get_dchi2_dz, + "Calculate chi2 gradient with reference to all obzervations z in all factors") // Robust factors GUI // TODO, we want to set a default robust function? maybe at ini? // TODO we want a way to change the robust factor for each node, maybe accesing by id? This could be away to inactivate factors... @@ -173,8 +175,8 @@ void init_FGraphDiff(py::module &m) "output, node id, for later usage", py::arg("x"), py::arg("mode") = Node::nodeMode::STANDARD) - .def("add_factor_1pose_2d", &FGraphDiffPy::add_factor_1pose_2d_diff) - .def("add_factor_2poses_2d", &FGraphDiffPy::add_factor_2poses_2d_diff, + .def("add_factor_1pose_2d_diff", &FGraphDiffPy::add_factor_1pose_2d_diff) + .def("add_factor_2poses_2d_diff", &FGraphDiffPy::add_factor_2poses_2d_diff, "Factors connecting 2 poses. If last input set to true (by default false), also updates " "the value of the target Node according to the new obs + origin node", py::arg("obs"),