{"id":1759,"date":"2024-05-24T23:30:00","date_gmt":"2024-05-25T03:30:00","guid":{"rendered":"http:\/\/aristotle2digital.blogwyrm.com\/?p=1759"},"modified":"2024-04-30T05:28:03","modified_gmt":"2024-04-30T09:28:03","slug":"time-series-6-recursive-least-squares","status":"publish","type":"post","link":"https:\/\/aristotle2digital.blogwyrm.com\/?p=1759","title":{"rendered":"Time Series 6 &#8211; Recursive Least Squares"},"content":{"rendered":"\n<p>The last post introduced the notion of the recursive least squares estimation approach as a natural precursor to the Kalman filter and derived the Kalman-like gain that governed the state estimation update equation.&nbsp; Before moving on to a simple example of the Kalman filter, it seemed prudent to show the recursive least squares filter in action with a numerical example.<\/p>\n\n\n\n<p>The example involves a mass falling in an unknown uniform gravitational field with unknown initial conditions.&nbsp; At regular time intervals, a measurement device measures the height of the mass above the ground but only to within certain precision due to inherent noise in it measuring processes.&nbsp; The challenge is then to deliver the best estimate of the unknowns (initial height, initial speed, and the uniform gravitational acceleration).&nbsp;&nbsp; We will assume that, beyond a measurement of the initial height, the other initial conditions are inaccessible to the measurement device since it only measures range.&nbsp; This example is adapted from the excellent article <em><a href=\"https:\/\/aleksandarhaber.com\/introduction-to-kalman-filter-derivation-of-the-recursive-least-squares-method-with-python-codes\/\">Introduction to Kalman Filter: Derivation of the Recursive Least Squares Method<\/a><\/em> by Aleksander Haber.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"857\" height=\"689\" src=\"http:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_ball-drop-experiment.png\" alt=\"\" class=\"wp-image-1761\" srcset=\"https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_ball-drop-experiment.png 857w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_ball-drop-experiment-300x241.png 300w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_ball-drop-experiment-768x617.png 768w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_ball-drop-experiment-810x651.png 810w\" sizes=\"auto, (max-width: 857px) 100vw, 857px\" \/><\/figure><\/div>\n\n\n\n<p>To prove that the recursive least squares method does generate a real least squares estimation, let\u2019s first look at how a batch least squares approach to this problem would be performed.<\/p>\n\n\n\n<p>The dynamics of the falling mass are given by<\/p>\n\n\n\n<p>\\[ d(t) = d_0 + v_0 t + \\frac{1}{2} a t^2 \\; , \\]<\/p>\n\n\n\n<p>where $d(t)$ is the height above the ground at a given instant.<\/p>\n\n\n\n<p>We assume that the above equation is exact; in other words, there are no unknown forces in the problem.&nbsp; In the language of Kalman-filtering and related optimal estimation, there is said to be no process noise, with it understood that the word \u2018process\u2019 is a genetic umbrella meaning the dynamics by which the state evolves in time, for which Newton\u2019s laws are an important subset.<\/p>\n\n\n\n<p>By design, measurements come in every $\\Delta t$ seconds and so the time evolution of the fall of the mass is sampled at times $t_k = k \\Delta t$.&nbsp; At measurement time $t_k$ the amount the mass has dropped is<\/p>\n\n\n\n<p>\\[ x_k = x_0 + v_0 k \\Delta t + \\frac{1}{2} k^2 \\Delta t^2 &nbsp;a \\; \\]<\/p>\n\n\n\n<p>and the corresponding measurement is<\/p>\n\n\n\n<p>\\[ z_k = x_k + \\eta_k \\; , \\]<\/p>\n\n\n\n<p>where $\\eta_k$ is the noise the measuring device introduces in performing its job.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"723\" height=\"462\" src=\"http:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_noisy_mass_drop.png\" alt=\"\" class=\"wp-image-1755\" srcset=\"https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_noisy_mass_drop.png 723w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_noisy_mass_drop-300x192.png 300w\" sizes=\"auto, (max-width: 723px) 100vw, 723px\" \/><\/figure><\/div>\n\n\n\n<p>The batch least squares estimation begins by writing the evolution equation in a matrix form<\/p>\n\n\n\n<p>\\[ z_k = \\left[ \\begin{array}{ccc} 1 &amp; k \\Delta t &amp; \\frac{1}{2} k^2 \\Delta t^2 \\end{array} \\right] \\left[ \\begin{array}{c} x_0 \\\\ v_0 \\\\ a \\end{array} \\right] &nbsp;+ \\eta_k \\equiv H_{k,p} x_p + \\eta_k \\; . &nbsp;\\]<\/p>\n\n\n\n<p>The array $x_p$ contains the constant initial conditions and unknown acceleration that is being estimated.<\/p>\n\n\n\n<p>For this numerical experiment, $x_0 = -4m$, $v_0 = 2 m\/s$ (positive being downward), and $a = 9.8 m\/s^2$ the usual value for surface of the Earth (give or take regional variations).&nbsp; Measurements are taken every $\\Delta t = 1\/150 s$ over a time span of 14.2 seconds.&nbsp; To illustrate the meaning of $H_{k,p}$, the value of the matrix at $k=0$ is<\/p>\n\n\n\n<p>\\[ H_{k=0,p} = \\left[ \\begin{array}{ccc} 1 &amp; 0 &amp; 0 \\end{array} \\right] \\; \\]<\/p>\n\n\n\n<p>corresponding to an elapsed time of $t_k = 0$ and at $k = 75$<\/p>\n\n\n\n<p>\\[ H_{k=0,p} = \\left[ \\begin{array}{ccc} 1 &amp; 0.5 &amp; 0.125 \\end{array} \\right] \\; \\]<\/p>\n\n\n\n<p>corresponding to an elapsed time of $t_k = 0.5$.&nbsp;<\/p>\n\n\n\n<p>The merit of this matrix approach is that by putting every measurement into a batch we can write the entire measured dynamics in a single equation as:<\/p>\n\n\n\n<p>\\[ z = H x + \\eta \\; . \\]<\/p>\n\n\n\n<p>The array $z$ has $M$ elements (for the number of measurement), where $M$ is the maximum value of the time index $k$ (for this specific example $M$ = 2131).&nbsp; The matrix $H$ is a $M \\times n$ where $n$ is the number of estimate parameters ($n$ = 3, in this case) and $x$ is the array of parameters to be estimated).&nbsp; The array $\\eta$ represents the $M$ values of random noise (assumed to be stationary) that were present in the measurements.&nbsp; The values of $\\eta$ used in this numerical example were drawn from a normal distribution with a zero mean and a standard deviation of 1; the latter value determines the value of $R_k = 1$.<\/p>\n\n\n\n<p>Since, in the matrix equation above, the matrix $H$ isn\u2019t square, it may not be obvious how to solve for $x$.&nbsp; However, there is a well-known technique using what is known as the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Moore%E2%80%93Penrose_inverse\">Moore-Penrose pseudoinverse<\/a>.&nbsp;<\/p>\n\n\n\n<p>In short, to solve for $x$ in a least squares sense, we set $\\eta$ to zero (i.e., we ignore the noise assuming the classical argument that with enough measurements the influence of the noise will average to zero).&nbsp; We then left-multiply by the transpose of $H$ to get<\/p>\n\n\n\n<p>\\[ H^T z = (H^T H) x \\; .\\]<\/p>\n\n\n\n<p>The quantity $H^T H$ is a $(n \\times K) \\cdot (K \\times n) = n \\times n $ matrix (in this case $3\\times 3$, which is invertible.&nbsp; We then arrive at the compact form of the estimate for $x$ as<\/p>\n\n\n\n<p>\\[ x_{est} = (H^T H)^{-1} H^T z \\; .\\]<\/p>\n\n\n\n<p>For this numerical experiment, the resulting estimate is<\/p>\n\n\n\n<p>\\[ x_{est} = \\left[ \\begin{array}{c} -3.95187658 \\\\ 1.99300377 \\\\ 9.80040125 \u00a0\\end{array}\u00a0\u00a0\u00a0 \\right] \\; .\\]<\/p>\n\n\n\n<p>This is the same value one gets by using a package like numpy\u2019s linalg.lstsq.<\/p>\n\n\n\n<p>In the recursive method, all of the data are not stored and handled at once but rather each point is taken and processed as it comes in.&nbsp;<\/p>\n\n\n\n<p>The algorithm developed in the last post is summarized as:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Start each step with the current time $t_k$, measurement $z_k$, and the previous estimates of the state $x_{k-1}$ and the covariance $P_{k-1}$<\/li><li>Perform the $k$-th calculation of the gain: $K_k = P_{k-1} \\cdot H_k^T \\cdot S_k^{-1}$, where $S_k = H_k \\cdot P_{k-1} \\cdot H_k^T + R_k$<\/li><li>Make the $k$-th estimate of the unknowns: ${\\hat x}_k = {\\hat x}_{k-1} + K_k \\left( z_k &#8211; H_k {\\hat x}_{k-1} \\right)$<\/li><li>Make the $k$-th update of the covariance matrix: $P_k = \\left(I &#8211; K_k H_k \\right)P_{k-1} $<\/li><\/ul>\n\n\n\n<p>Using this algorithm, the time evolution of the estimated initial position is<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"582\" height=\"432\" src=\"http:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_x0.png\" alt=\"\" class=\"wp-image-1763\" srcset=\"https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_x0.png 582w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_x0-300x223.png 300w\" sizes=\"auto, (max-width: 582px) 100vw, 582px\" \/><\/figure><\/div>\n\n\n\n<p>with a final value of -3.95170034.<\/p>\n\n\n\n<p>Likewise, the time evolution of the estimated initial speed is<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"569\" height=\"432\" src=\"http:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_v0.png\" alt=\"\" class=\"wp-image-1753\" srcset=\"https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_v0.png 569w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_v0-300x228.png 300w\" sizes=\"auto, (max-width: 569px) 100vw, 569px\" \/><\/figure><\/div>\n\n\n\n<p>with a final value of 1.99295453.<\/p>\n\n\n\n<p>And, finally, the time evolution of the estimated acceleration is<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_a.png\" alt=\"\" class=\"wp-image-1752\" width=\"565\" height=\"433\" srcset=\"https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_a.png 564w, https:\/\/aristotle2digital.blogwyrm.com\/wp-content\/uploads\/2024\/04\/A2D_05May_2024_estimated_a-300x230.png 300w\" sizes=\"auto, (max-width: 565px) 100vw, 565px\" \/><\/figure>\n\n\n\n<p>with a final value of 9.80040698.<\/p>\n\n\n\n<p>These estimated values, up to the numerical noise introduced by a different set of floating point operations, are identical with the batch least squares numbers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The last post introduced the notion of the recursive least squares estimation approach as a natural precursor to the Kalman filter and derived the Kalman-like gain that governed the state&#8230; <a class=\"read-more-button\" href=\"https:\/\/aristotle2digital.blogwyrm.com\/?p=1759\">Read more &gt;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1759","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/posts\/1759","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1759"}],"version-history":[{"count":4,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/posts\/1759\/revisions"}],"predecessor-version":[{"id":1765,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=\/wp\/v2\/posts\/1759\/revisions\/1765"}],"wp:attachment":[{"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1759"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1759"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aristotle2digital.blogwyrm.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1759"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}