{"id":2334,"date":"2016-09-16T13:54:10","date_gmt":"2016-09-16T17:54:10","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=2334"},"modified":"2019-11-01T16:48:39","modified_gmt":"2019-11-01T20:48:39","slug":"getting-the-math-right","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2016\/09\/16\/getting-the-math-right\/","title":{"rendered":"Getting the math right"},"content":{"rendered":"<div class=\"content\"><p>Because I work regularly with developers on the MATLAB Math team, I see the questions that come to them from tech support. Today there was an interesting one.<\/p><p>A user observed that computing the <tt>sin<\/tt> function takes longer for very big numbers. The user asked, \"Why is that?\"<\/p><p>Well, first let's see if we can reproduce the observation. Start by making a vector with one million numbers in the interval [0,1].<\/p><pre class=\"codeinput\">rng(42)\r\nx = rand(1000000,1);\r\n<\/pre><p>(I seeded the random number generator using <tt>rng<\/tt> so that the numbers below don't change each time I run this script.)<\/p><p>How long does it take to compute the sin of all those numbers?<\/p><pre class=\"codeinput\">f = @() sin(x);\r\ntimeit(f)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n   0.002102730998500\r\n\r\n<\/pre><p>Now repeat the timing experiment with another vector containing one million numbers in the interval [100000000,100000000+1].<\/p><pre class=\"codeinput\">x2 = x + 100000000;\r\ng = @() sin(x2);\r\ntimeit(g)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n   0.027343141998500\r\n\r\n<\/pre><p>The user is right, it does take longer!<\/p><p>Here's the straightforward explanation: For large numbers, it takes more computation to produce an accurate result.<\/p><p>To illustrate, let's look at the output of <tt>sin<\/tt> for one large number in MATLAB and compare it the result from another application. I'm going to use Excel for this comparison, but the results will be similar for code you write in C that calls the standard C math library function, <tt>sin()<\/tt>.<\/p><pre class=\"codeinput\">z = x2(1)\r\n<\/pre><pre class=\"codeoutput\">\r\nz =\r\n\r\n     1.000000003745401e+08\r\n\r\n<\/pre><pre class=\"codeinput\">matlab_result = sin(z)\r\n<\/pre><pre class=\"codeoutput\">\r\nmatlab_result =\r\n\r\n   0.734111589042897\r\n\r\n<\/pre><pre class=\"codeinput\">excel_result = 0.734111669990523\r\n<\/pre><pre class=\"codeoutput\">\r\nexcel_result =\r\n\r\n   0.734111669990523\r\n\r\n<\/pre><p>These two results agree to only 6 digits!<\/p><p>Let's use the Symbolic Math Toolbox to compute <tt>sin(z)<\/tt> with 20 decimal digits of accuracy.<\/p><pre class=\"codeinput\">sym_result = sin(sym(z))\r\n<\/pre><pre class=\"codeoutput\"> \r\nsym_result =\r\n \r\nsin(3355443212567481\/33554432)\r\n \r\n<\/pre><pre class=\"codeinput\">vpa(sym_result,20)\r\n<\/pre><pre class=\"codeoutput\"> \r\nans =\r\n \r\n0.73411158904289725019\r\n \r\n<\/pre><p>From this calculation, you can see that the MATLAB result is accurate to 15 decimal digits, whereas the Excel result is accurate to only 6 digits.<\/p><p>That's called <a href=\"https:\/\/www.mathworks.com\/company\/aboutus\/mission_values\/values\/continuous.html\">sweating the details<\/a>.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_0780227fb97d40c488b0f8999338a84e() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='0780227fb97d40c488b0f8999338a84e ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 0780227fb97d40c488b0f8999338a84e';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2016 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_0780227fb97d40c488b0f8999338a84e()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2016b<br><\/p><\/div><!--\r\n0780227fb97d40c488b0f8999338a84e ##### SOURCE BEGIN #####\r\n%%\r\n% Because I work regularly with developers on the MATLAB Math team, I see\r\n% the questions that come to them from tech support. Today there was an\r\n% interesting one.\r\n%\r\n% A user observed that computing the |sin| function takes longer for very\r\n% big numbers. The user asked, \"Why is that?\"\r\n%\r\n% Well, first let's see if we can reproduce the observation. Start by\r\n% making a vector with one million numbers in the interval [0,1].\r\n\r\nrng(42)\r\nx = rand(1000000,1);\r\n\r\n%%\r\n% (I seeded the random number generator using |rng| so that the numbers\r\n% below don't change each time I run this script.)\r\n\r\n%%\r\n% How long does it take to compute the sin of all those numbers?\r\n\r\nf = @() sin(x);\r\ntimeit(f)\r\n\r\n%%\r\n% Now repeat the timing experiment with another vector containing one\r\n% million numbers in the interval [100000000,100000000+1].\r\n\r\nx2 = x + 100000000;\r\ng = @() sin(x2);\r\ntimeit(g)\r\n\r\n%%\r\n% The user is right, it does take longer!\r\n%\r\n% Here's the straightforward explanation: For large numbers, it takes more\r\n% computation to produce an accurate result.\r\n%\r\n% To illustrate, let's look at the output of |sin| for one large number in\r\n% MATLAB and compare it the result from another application. I'm going to\r\n% use Excel for this comparison, but the results will be similar for code\r\n% you write in C that calls the standard C math library function, |sin()|.\r\n\r\nz = x2(1)\r\n\r\n%%\r\n\r\nmatlab_result = sin(z)\r\n\r\n%%\r\n\r\nexcel_result = 0.734111669990523\r\n\r\n%%\r\n% These two results agree to only 6 digits!\r\n%\r\n% Let's use the Symbolic Math Toolbox to compute |sin(z)| with 20 decimal\r\n% digits of accuracy.\r\n\r\nsym_result = sin(sym(z))\r\n\r\n%%\r\nvpa(sym_result,20)\r\n\r\n%%\r\n% From this calculation, you can see that the MATLAB result is accurate to\r\n% 15 decimal digits, whereas the Excel result is accurate to only 6\r\n% digits.\r\n%\r\n% That's called\r\n% <https:\/\/www.mathworks.com\/company\/aboutus\/mission_values\/values\/continuous.html\r\n% sweating the details>.\r\n\r\n\r\n\r\n\r\n##### SOURCE END ##### 0780227fb97d40c488b0f8999338a84e\r\n-->","protected":false},"excerpt":{"rendered":"<p>Because I work regularly with developers on the MATLAB Math team, I see the questions that come to them from tech support. Today there was an interesting one.A user observed that computing the sin... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2016\/09\/16\/getting-the-math-right\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[460,807,34,1173,474,1175],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2334"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=2334"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2334\/revisions"}],"predecessor-version":[{"id":2335,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2334\/revisions\/2335"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=2334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=2334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=2334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}