# [swift-evolution] TrigonometricFloatingPoint/MathFloatingPoint protocol?

Taylor Swift kelvin13ma at gmail.com
Fri Aug 4 15:56:14 CDT 2017

```update:

I’ve managed to improve the algorithm to the point where it’s arguably more
accurate than Glibc.cos(_:), and runs just as fast. Removing one term makes
the Swift implementation faster than _cos(_:), but worses the divergence by
like 23% (137 ULPs from 0° ..< 90°, as opposed to 111 ULPs).

Relative time (lower is better)

_cos(_:) instrinsic       : 3.096
pure Swift implementation : 3.165

Almost everywhere the pure Swift implementation is within ±1 ULP of the
Glibc/llvm implementation. Adding more terms to the approximation actually
worsens the divergence, so I guess we are in the range where we have to
start talking about error in the Glibc implementation as well. Here’s an output
dump
<https://github.com/kelvin13/swift-math/blob/d82e8b1df848879ba6ac6071883fde7f9a15c967/tests/output.txt>
with input from −360° to +360°.

The _cos(_:) intrinsic seems to be asymmetric across the positive and
negative halves of the function, which causes the divergence to rise to
about 3–5 ULPs on the far side of the unit circle. This could be due to
rounding differences in the arguments, since π/2 and 3π/2 are impossible to
represent in floating point. However I don’t know which implementation is
“wrong” here. The Swift one gives the “right” output for all special
angles; i.e. cos(90°) == 0, cos(60°) == 0.5, etc , whereas _cos(_:) gives
slightly fuzzy values.

If anyone wants to try it, I put the cosine implementation in an actual
module on github; and the given benchmark numbers are for cross-module
calls. <https://github.com/kelvin13/swift-math>

On Thu, Aug 3, 2017 at 7:32 PM, Taylor Swift <kelvin13ma at gmail.com> wrote:

>
>
> On Thu, Aug 3, 2017 at 7:12 PM, Karl Wagner via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> On 3. Aug 2017, at 13:04, Stephen Canon via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> On Aug 2, 2017, at 7:03 PM, Karl Wagner via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>
>> It’s important to remember that computers are mathematical machines, and
>> some functions which are implemented in hardware on essentially every
>> platform (like sin/cos/etc) are definitely best implemented as compiler
>> intrinsics.
>>
>>
>> sin/cos/etc are implemented in software, not hardware. x86 does have the
>> FSIN/FCOS instructions, but (almost) no one actually uses them to implement
>> the sin( ) and cos( ) functions; they are a legacy curiosity, both too slow
>> and too inaccurate for serious use today. There are no analogous
>> instructions on ARM or PPC.
>>
>> – Steve
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> Hah that’s pretty cool; I think I learned in EE years ago that it was
>> implemented with a lookup table inside the CPU and never bothered to
>> question it.
>>
>> The pure-Swift cosine implementation looks cool.
>>
>
> I’m pretty sure it can be improved greatly, at least for Double.
> Unfortunately performance falls off a cliff for Float for some reason, i
> don’t know why.
>
>>
>> As for the larger discussion about a Swift maths library: in general,
>> it’s hard for any new Swift-only package to get off the ground without a
>> more comprehensive package manager. The current version doesn’t support
>> most of the Swift projects being worked on every day. Swift is also still a
>> relatively young language - the new integer protocols have never even
>> shipped in a stable release. Considering where we are, it’s not really
>> surprising that most of the Swift maths libraries are still a bit
>> rudimentary; I expect they will naturally evolve and develop in time, the
>> way open-source code does.
>>
>>
> Most of the SPM’s limitations have workarounds, the problem is it’s just
> not very convenient, i.e. local and non-git dependencies. Other features
> like gyb, I’m not sure if it’s a good idea to bring to the SPM. gyb is a
> band-aid over deeper limitations of the language.
>
>
>> It’s also worth considering that our excellent bridging with C removes
>> some of the impetus to rewrite all your battle-tested maths code in Swift.
>> The benefits are not obvious; the stage is set for pioneers to experiment
>> and show the world why they should be writing their maths code in Swift.
>>
>>
> The glibc/llvm functions are not generic. You cannot use _cos(_:) on a
> protocol type like BinaryFloatingPoint. A pure Swift implementation would
> allow generic programming with trig and other math functions; right now
> anything beyond sqrt() requires manual specialization.
>
>
>> - Karl
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170804/0efff0a3/attachment.html>
```