Boost C++ Libraries: Ticket #7290: complex acos is occasionally wrong https://svn.boost.org/trac10/ticket/7290 <p> I am finding that the acos function is getting some of them wrong. For example, your program evaluates acos(1.00000002785941 + I*5.72464869028403e-200) as 0 - I*0.000236048349018331 whereas it should be 2.42520172707401e-196 - I*0.000236048349018331. </p> <p> Looking at <a href="http://www.boost.org/doc/libs/1_51_0/boost/math/complex/acos.hpp">http://www.boost.org/doc/libs/1_51_0/boost/math/complex/acos.hpp</a>, I am somewhat sure that the mistake is in the last line of this code fragment: </p> <blockquote> <p> <em> </em> This is the Hull et al exception handling code from Fig 6 of their paper: <em> if(y &lt;= (std::numeric_limits&lt;T&gt;::epsilon() * std::fabs(xm1))) { </em></p> <blockquote> <p> if(x &lt; one) { </p> <blockquote> <p> real = std::acos(x); imag = y / std::sqrt(xp1*(one-x)); </p> </blockquote> <p> } else { </p> <blockquote> <p> real = 0; </p> </blockquote> </blockquote> </blockquote> <p> For asin, setting real = half_pi does just fine. But for acos, real should be something extremely small, but definitely not 0. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7290 Trac 1.4.3 John Maddock Sun, 26 Aug 2012 17:02:52 GMT component changed; owner set https://svn.boost.org/trac10/ticket/7290#comment:1 https://svn.boost.org/trac10/ticket/7290#comment:1 <ul> <li><strong>owner</strong> set to <span class="trac-author">John Maddock</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">math</span> </li> </ul> Ticket Stephen Montgomery-Smith <stephen@…> Sun, 26 Aug 2012 18:31:37 GMT <link>https://svn.boost.org/trac10/ticket/7290#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7290#comment:2</guid> <description> <p> It looks like the mistake is in Figure 6 of the paper by Hull, Fairgrieve and Tang. It looks like this patch fixes it. </p> <pre class="wiki">diff -u boost-trunk/boost/math/complex/acos.hpp boost-trunk-new/boost/math/complex/acos.hpp --- boost-trunk/boost/math/complex/acos.hpp 2012-08-26 18:24:02.000000000 +0000 +++ boost-trunk-new/boost/math/complex/acos.hpp 2012-08-26 18:25:48.000000000 +0000 @@ -172,14 +172,15 @@ } else { - real = 0; if(((std::numeric_limits&lt;T&gt;::max)() / xp1) &gt; xm1) { // xp1 * xm1 won't overflow: + real = y / std::sqrt(xm1*xp1); imag = boost::math::log1p(xm1 + std::sqrt(xp1*xm1)); } else { + real = y / x; imag = log_two + std::log(x); } } </pre> </description> <category>Ticket</category> </item> <item> <author>Stephen Montgomery-Smith <stephen@…></author> <pubDate>Sun, 26 Aug 2012 19:02:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7290#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7290#comment:3</guid> <description> <p> Looking at page 327 of the paper by Hull et al, they say that the real part can be set to zero, because the absolute error will be negligible compared to the absolute error in the imaginary part. But everywhere else in the paper, they manage to control the relative error of the real and imaginary parts separately. </p> <p> Looking at page 304, it seems that their goal is only to control the relative error of the real and imaginary parts together. So this wasn't really a mistake in their paper. </p> <p> But I think the "higher goal" of controlling the relative error of the real and imaginary parts separately is worthy, so I still commend my patch to you. </p> </description> <category>Ticket</category> </item> <item> <author>Stephen Montgomery-Smith <stephen@…></author> <pubDate>Mon, 27 Aug 2012 01:22:30 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/7290#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7290#comment:4</guid> <description> <p> Another thing - through experiment I have found that setting a_crossover to 10 instead of 1.5 works a little better. This is for asin as well as acos. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>John Maddock</dc:creator> <pubDate>Thu, 29 Nov 2012 13:27:36 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/7290#comment:5 https://svn.boost.org/trac10/ticket/7290#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/81624" title="Lots of small patches. Update and regenerate docs. Fixes #7183. Fixes ...">[81624]</a>) Lots of small patches. Update and regenerate docs. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7183" title="#7183: Bugs: math::isinf compilation failure on FBSD (closed: fixed)">#7183</a>. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7290" title="#7290: Bugs: complex acos is occasionally wrong (closed: fixed)">#7290</a>. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7291" title="#7291: Bugs: complex atan is not the best it could be (closed: fixed)">#7291</a>. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7649" title="#7649: Bugs: Minor comment typo in boost/math/constants/calculate_constants.hpp (closed: fixed)">#7649</a>. Refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/7492" title="#7492: Bugs: add support of libc++ (closed: fixed)">#7492</a>. </p> Ticket