{"id":14874,"date":"2014-11-01T15:42:46","date_gmt":"2014-11-01T20:42:46","guid":{"rendered":"http:\/\/www.johndcook.com\/blog\/?page_id=14874"},"modified":"2024-05-16T20:20:19","modified_gmt":"2024-05-17T01:20:19","slug":"standard_deviation","status":"publish","type":"page","link":"https:\/\/www.johndcook.com\/blog\/standard_deviation\/","title":{"rendered":"Accurately computing running variance"},"content":{"rendered":"<div id=\"main\">\n<p>The most direct way of computing sample variance or standard deviation can have severe numerical problems. Mathematically, sample variance can be computed as follows.<\/p>\n<p style=\"text-align: center;\"><img decoding=\"async\" style=\"background-color: white;\" src=\"\/\/www.johndcook.com\/variance2.svg\" alt=\"\\sigma^2 = \\frac{1}{ n(n-1)}\\left(n \\sum_{i=1}^n x_i^2 -\\left(\\sum_{i=1}^n x_i\\right)^2\\right)\" width=\"300\" \/><\/p>\n<p>The most obvious way to compute variance then would be to\u00a0have two sums: one to accumulate the sum of the <em>x<\/em>&#8216;s and another to accumulate the sums of the squares of the <em>x<\/em>&#8216;s. If the <em>x<\/em>&#8216;s are large and the differences between them small, direct evaluation of the equation above would require computing a small number as the difference of two large numbers, a red flag for numerical computing. The loss of precision can be so bad that the expression above evaluates to a <em>negative<\/em> number even though variance is always positive. See <a href=\"\/\/www.johndcook.com\/blog\/2008\/09\/26\/comparing-three-methods-of-computing-standard-deviation\/\"> Comparing three methods of computing standard deviation<\/a> for examples of just how bad the above formula can be.<\/p>\n<p>There is a way to compute variance that is more accurate and is guaranteed to always give positive results. Furthermore, the method computes a running variance. That is, the method computes the variance as the <em>x<\/em>&#8216;s arrive one at a time. The data do not need to be saved for a second pass.<\/p>\n<p>This better way of computing variance goes back to a 1962 paper by B. P. Welford and is presented in Donald Knuth&#8217;s <a href=\"https:\/\/amzn.to\/2U15nmf\">Art of Computer Programming<\/a>, Vol 2, page 232, 3rd edition. Although this solution has been known for decades, not enough people know about it. Most people are probably unaware that computing sample variance can be difficult until the first time they compute a standard deviation and get an exception for taking the square root of a negative number.<\/p>\n<p>It is not obvious that the method is correct even in exact arithmetic. It&#8217;s even less obvious that the method has superior numerical properties, but it does. The algorithm is as follows.<\/p>\n<p style=\"padding-left: 30px;\">Initialize <em>M<\/em><sub>1<\/sub> = <em>x<\/em><sub>1<\/sub> and <em>S<\/em><sub>1<\/sub> = 0.<\/p>\n<p style=\"padding-left: 30px;\">For subsequent <em>x<\/em>&#8216;s, use the recurrence formulas<\/p>\n<p style=\"padding-left: 30px;\"><em>M<sub>k<\/sub><\/em> = <em>M<\/em><sub><em>k<\/em>&minus;1<\/sub>+ (<em>x<sub>k<\/sub><\/em> &minus; <em>M<\/em><sub><em>k<\/em>&minus;1<\/sub>)\/<em>k<\/em><br \/>\n<em>S<sub>k<\/sub><\/em> = <em>S<\/em><sub><em>k<\/em>&minus;1<\/sub> + (<em>x<sub>k<\/sub><\/em> &minus; <em>M<\/em><sub><em>k<\/em>&minus;1<\/sub>)*(<em>x<sub>k<\/sub><\/em> &minus; <em>M<sub>k<\/sub><\/em>).<\/p>\n<p style=\"padding-left: 30px;\">For 2 \u2264 <em>k<\/em> \u2264 <em>n<\/em>, the <em>k<\/em><sup>th<\/sup> estimate of the variance is <em>s<\/em><sup>2<\/sup> = <em>S<sub>k<\/sub><\/em>\/(<em>k<\/em> &minus; 1).<\/p>\n<p>The C++ class <code>RunningStat<\/code> given below uses this method to compute the mean, sample variance, and standard deviation of a stream of data. This code sample shows how to use the class.<\/p>\n<pre>int main()\r\n    {\r\n        RunningStat rs;\r\n\r\n        rs.Push(17.0);\r\n        rs.Push(19.0);\r\n        rs.Push(24.0);\r\n\r\n        double mean = rs.Mean();\r\n        double variance = rs.Variance();\r\n        double stdev = rs.StandardDeviation();\r\n    }\r\n\r\n<\/pre>\n<p>As new values arrive, say from a simulation, they enter the <code>RunningStat<\/code> class via the <code>Push<\/code> method. To check on the mean, variance, or standard deviation at any time, call the corresponding methods.<\/p>\n<p>The source code for the <code>RunningStat<\/code> class follows:<\/p>\n<pre>class RunningStat\r\n    {\r\n    public:\r\n        RunningStat() : m_n(0) {}\r\n\r\n        void Clear()\r\n        {\r\n            m_n = 0;\r\n        }\r\n\r\n        void Push(double x)\r\n        {\r\n            m_n++;\r\n\r\n            \/\/ See Knuth TAOCP vol 2, 3rd edition, page 232\r\n            if (m_n == 1)\r\n            {\r\n                m_oldM = m_newM = x;\r\n                m_oldS = 0.0;\r\n            }\r\n            else\r\n            {\r\n                m_newM = m_oldM + (x - m_oldM)\/m_n;\r\n                m_newS = m_oldS + (x - m_oldM)*(x - m_newM);\r\n    \r\n                \/\/ set up for next iteration\r\n                m_oldM = m_newM; \r\n                m_oldS = m_newS;\r\n            }\r\n        }\r\n\r\n        int NumDataValues() const\r\n        {\r\n            return m_n;\r\n        }\r\n\r\n        double Mean() const\r\n        {\r\n            return (m_n &gt; 0) ? m_newM : 0.0;\r\n        }\r\n\r\n        double Variance() const\r\n        {\r\n            return ( (m_n &gt; 1) ? m_newS\/(m_n - 1) : 0.0 );\r\n        }\r\n\r\n        double StandardDeviation() const\r\n        {\r\n            return sqrt( Variance() );\r\n        }\r\n\r\n    private:\r\n        int m_n;\r\n        double m_oldM, m_newM, m_oldS, m_newS;\r\n    };\r\n\r\n<\/pre>\n<hr \/>\n<p>Here are a couple references on computing sample variance.<\/p>\n<p>Chan, Tony F.; Golub, Gene H.; LeVeque, Randall J. (1983). Algorithms for Computing the Sample Variance: Analysis and Recommendations. The American Statistician 37, 242-247.<\/p>\n<p>Ling, Robert F. (1974). Comparison of Several Algorithms for Computing Sample Means and Variances. Journal of the American Statistical Association, Vol. 69, No. 348, 859-866.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Update<\/strong>: See <a href=\"\/\/www.johndcook.com\/skewness_kurtosis.html\">this page<\/a> for an extension of this code that supports computing skewness and kurtosis as well. Also, the new code supports combining <code>RunningStat<\/code> objects via the <code>+<\/code> and <code>+=<\/code> operators.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The most direct way of computing sample variance or standard deviation can have severe numerical problems. Mathematically, sample variance can be computed as follows. The most obvious way to compute variance then would be to\u00a0have two sums: one to accumulate the sum of the x&#8216;s and another to accumulate the sums of the squares of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-with-simple-sidebar.php","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-14874","page","type-page","status-publish","hentry"],"acf":[],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"How to compute sample variance (standard deviation) as samples arrive sequentially, avoiding numerical problems that could degrade accuracy.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.johndcook.com\/blog\/standard_deviation\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"John D. Cook | Applied Mathematics Consulting\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Accurately computing sample variance online\" \/>\n\t\t<meta property=\"og:description\" content=\"How to compute sample variance (standard deviation) as samples arrive sequentially, avoiding numerical problems that could degrade accuracy.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.johndcook.com\/blog\/standard_deviation\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2014-11-01T20:42:46+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2024-05-17T01:20:19+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Accurately computing sample variance online\" \/>\n\t\t<meta name=\"twitter:description\" content=\"How to compute sample variance (standard deviation) as samples arrive sequentially, avoiding numerical problems that could degrade accuracy.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Accurately computing sample variance online","description":"How to compute sample variance (standard deviation) as samples arrive sequentially, avoiding numerical problems that could degrade accuracy.","canonical_url":"https:\/\/www.johndcook.com\/blog\/standard_deviation\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"John D. Cook | Applied Mathematics Consulting","og:type":"article","og:title":"Accurately computing sample variance online","og:description":"How to compute sample variance (standard deviation) as samples arrive sequentially, avoiding numerical problems that could degrade accuracy.","og:url":"https:\/\/www.johndcook.com\/blog\/standard_deviation\/","article:published_time":"2014-11-01T20:42:46+00:00","article:modified_time":"2024-05-17T01:20:19+00:00","twitter:card":"summary","twitter:title":"Accurately computing sample variance online","twitter:description":"How to compute sample variance (standard deviation) as samples arrive sequentially, avoiding numerical problems that could degrade accuracy.","twitter:image":"https:\/\/www.johndcook.com\/blog\/wp-content\/uploads\/2022\/05\/twittercard.png"},"aioseo_meta_data":{"post_id":"14874","title":"Accurately computing sample variance online","description":"How to compute sample variance (standard deviation) as samples arrive sequentially, avoiding numerical problems that could degrade accuracy.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"WebPage","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":"{\"article\":{\"articleType\":\"BlogPosting\"},\"course\":{\"name\":\"\",\"description\":\"\",\"provider\":\"\"},\"faq\":{\"pages\":[]},\"product\":{\"reviews\":[]},\"recipe\":{\"ingredients\":[],\"instructions\":[],\"keywords\":[]},\"software\":{\"reviews\":[],\"operatingSystems\":[]},\"webPage\":{\"webPageType\":\"WebPage\"}}","pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"created":"2020-12-21 02:35:08","updated":"2025-06-03 19:16:13","ai":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.johndcook.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tAccurately computing running variance\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.johndcook.com\/blog"},{"label":"Accurately computing running variance","link":"https:\/\/www.johndcook.com\/blog\/standard_deviation\/"}],"_links":{"self":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/pages\/14874","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/comments?post=14874"}],"version-history":[{"count":0,"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/pages\/14874\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.johndcook.com\/blog\/wp-json\/wp\/v2\/media?parent=14874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}