<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-GB" link="blue" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi – thanks for your suggestion, though it’s a bit of a challenge! Do you know of an example where the existing haddocks have something similar?</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The branch cuts and behaviour of negative zeros are just part of the spec for what the functions do. Hence I would expect that anyone who reads the Data.Complex page should want to know about them. (Else it’s a bit like saying “I want to
 use sqrt but have no interest in knowing that it will only return a positive value”).</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Here’s my best attempt at pithy so far:</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b><i><span style="background:yellow;mso-highlight:yellow">Data.Complex<o:p></o:p></span></i></b></p>
<p class="MsoNormal"><i><span style="background:yellow;mso-highlight:yellow">Complex numbers that comply with the LIA standards with regard to signed zeros and branch cuts.<o:p></o:p></span></i></p>
<p class="MsoNormal"><i><span style="background:yellow;mso-highlight:yellow"><o:p> </o:p></span></i></p>
<p class="MsoNormal"><b><i><span style="background:yellow;mso-highlight:yellow">Branch Cuts & Principle Values<o:p></o:p></span></i></b></p>
<p class="MsoNormal"><i><span style="background:yellow;mso-highlight:yellow">The “inverse” complex functions (such as sqrt, log, asin, which are mathematically multivalued) return only a single principal value within a defined range. In general, inverse(fn
 z) == z only when z is within the defined range. The inverse functions are continuous throughout the complex plane except for discontinuities at certain lines on the axes called “branch cuts”.<o:p></o:p></span></i></p>
<p class="MsoNormal"><i><span style="background:yellow;mso-highlight:yellow"><o:p> </o:p></span></i></p>
<p class="MsoNormal"><i><span style="background:yellow;mso-highlight:yellow">The ranges and branch cuts comply with the LIA standards and are detailed below. In particular, two (==) points on a branch cut will map to different points on the range boundary if
 they have zeros of different signs. In some cases this allows apparently identical expressions to be computationally equivalent, for example sqrt(z/(z-1)) * sqrt(1/(z-1)) and sqrt z / (z-1), although detailed analysis is required to determine the behaviour
 and equivalence of expressions in general.</span><o:p></o:p></i></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Note that currently in Haskell:</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="text-indent:36.0pt">f1 z = sqrt(z/(z-1)) * sqrt(1/(z-1))</p>
<p class="MsoNormal" style="text-indent:36.0pt">f1 ((-4) :+ 0) = 0.0 :+ 0.4</p>
<p class="MsoNormal" style="text-indent:36.0pt">f2 z = sqrt z / (z-1)</p>
<p class="MsoNormal" style="text-indent:36.0pt">f2 ((-4) :+ 0) = 0.0 :+ (-0.4)</p>
<p class="MsoNormal" style="text-indent:36.0pt"><o:p> </o:p></p>
<p class="MsoNormal">Negative zeros (which GHC supports) provide a mechanism to address this, but only if sqrt makes correct use of it for points on the branch (which it currently does not – hence my proposed fixes, which also address other issues such as overflow,
 etc).</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">[If you’re also asking about -0.0 in non-complex functions, here’s an example:</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">                f x = atan(1/x)</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Mathematically, f x is undefined at x=0. But, in Haskell, we get f 0 = 1.57.. and f(-0) = -1.57. This mirrors the maths f(x) -> pi/2 as x -> 0 from above, and f(x) -> -pi/2 as x -> 0 from below. (Whether this is what’s required is for the
 programmer/analyst to determine, depending on the problem being solved).]</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Sorry, a not very pithy response <span style="font-family:"Segoe UI Emoji",sans-serif">
😊</span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Regards, David.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="border:none;padding:0cm"><b>From: </b><a href="mailto:b@chreekat.net">Bryan Richter</a><br>
<b>Sent: </b>23 October 2021 07:06<br>
<b>To: </b><a href="mailto:dj112358@outlook.com">David James</a><br>
<b>Cc: </b><a href="mailto:haskell-cafe@haskell.org">Haskell Cafe</a><br>
<b>Subject: </b>Re: [Haskell-cafe] Numerics (was: Re: Trouble with asinh)</p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">Hi David, <o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I have one suggestion for the haddocks. I made a solid effort to wade into the explanation of branch cuts and negative zeros, but I never managed to figure out why I should care. ;) In other words: tl;dr.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Would it be possible to write a pithy few words right at the beginning as an introduction that motivates the topic? If, as you say, few other languages take the subject into account, it's very likely that few programmers take it into account
 either.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">In general, as a math-conscious member of the community, I'm happy to see this kind of work being accomplished, so thanks!<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">-Bryan<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Fri, 22 Oct 2021, 17.48 David James, <<a href="mailto:dj112358@outlook.com">dj112358@outlook.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
Hi all – I now have fixes for all the issues I’m aware of. However, it’s quite possible I’ve made a mistake somewhere (either in the new code or the testing), so if anyone would like to help review either please let me know.</p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
 </p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
<b>Group 1 issues</b> (real numbers in Windows, where the defects are in mingw-w64: I’ve raised issue
<a href="https://gitlab.haskell.org/ghc/ghc/-/issues/20424" target="_blank">#20424</a> for this. The fixes (commits
<a href="https://github.com/mingw-w64/mingw-w64/commit/66ba5f3221c786de24f5fc4b9c0236b704c2d31d" target="_blank">
66ba5f32</a> and <a href="https://github.com/mingw-w64/mingw-w64/commit/021dffb8a482eb9d1b39569cd1ea42b87226fdf7" target="_blank">
021dffb8a</a>) have been made in mingw-w64 and are getting integrated into Haskell soon.</p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
 </p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
<b>Group 2 issues</b> (complex numbers, where the defects are in Complex.hs). I’ve raised issue
<a href="https://gitlab.haskell.org/ghc/ghc/-/issues/20425" target="_blank">#20425</a> for this and have the code fixes
<a href="https://gitlab.haskell.org/davjam/ghc/-/blob/ComplexBranchCuts/libraries/base/Data/Complex.hs" target="_blank">
here</a>. The new code changes many of the functions (I’ve given examples in the issue) and adds a few. I’ve also put the Haddock output
<a href="https://davjam.github.io/HaskellNumericsTestsFixes/TrigDiags/Data-Complex.html" target="_blank">
here</a>. (It now defines and gives an explanation of the branch cuts). I’ve also put some diagrams
<a href="https://davjam.github.io/HaskellNumericsTestsFixes/TrigDiags/Curr.html" target="_blank">
here</a> illustrating some of the problems.</p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
 </p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
I’ve done about as much testing as I can think of, using the code <a href="https://github.com/davjam/HaskellNumericsTestsFixes/blob/main/ComplexTests.hs" target="_blank">
here</a>. Ideally I’d bulk-test against a reliable independent source, but can’t find one. AFAICT
<a href="https://www.wolframalpha.com/input/?i=sin%28-0.0%29" target="_blank">WolframAlpha</a>, Excel, gnumeric, CLISP don’t support negative zeros.
<a href="https://www.python.org/" target="_blank">Python</a> seems to, but cmath has incorrect branch cuts (cmath.sqrt(-4-0j) gives 2j).
<a href="https://www.advanpix.com/2016/04/28/branch-cuts-and-signed-zeros-in-matlab/" target="_blank">
Matlab</a> also seems deficient in a number of areas. (Hmmm: maybe no one cares about these working correctly??)</p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
 </p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
Sorry about the delay in sending this, David.</p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
 </p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
 </p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:28.8pt">
 </p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal" style="margin-left:4.8pt">_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>