stan-dev / math

The Stan Math Library is a C++ template library for automatic differentiation of any order using forward, reverse, and mixed modes. It includes a range of built-in functions for probabilistic modeling, linear algebra, and equation solving.
https://mc-stan.org
BSD 3-Clause "New" or "Revised" License
722 stars 183 forks source link

add sincos function #3082

Open spinkney opened 2 weeks ago

spinkney commented 2 weeks ago

Neither boost nor Eigen has a sincos function however Julia has a succinct implementation in C at https://github.com/JuliaLang/julia/blob/eabd0212ed974b7128ec77180424090edb4a6d04/base/fastmath.jl#L299. The code is MIT license that is compatible with ours.

A few questions:

The output from this function will be a tuple of whatever the input type was. So if the input is a real the output will be a tuple of reals. If the input is complex then this falls back to calculating sin and cos separately and returning a tuple of complex types.

andrjohns commented 2 weeks ago

It looks like Julia is actually just wrapping the sincos() function in libm and it can just be called directly:

#include <cmath>

double f(double X){
    double s,c;
    sincos(X, &s, &c);
    return s + c;
}

Apparently GCC will automatically optimise separate sin and cos calls for this, but clang won't.

It looks like clang will only optimise sin and cos to sincos when -ffast-math is set, because of differences in error-handling.

If we're explicitly managing error cases, then I don't see any reason against us using sincos directly