Repository navigation
Preserve real-axis branches in complex asin and acos - #1437
agourakis82 wants to merge 1 commit into
Conversation
DiamonDinoia
left a comment
There was a problem hiding this comment.
Okay, rebase this one too.
I am not sure about the tests though. It feels a lot of code and we can test in all cases even if fast math is false. adding cases should be okay.
af4c656 to
5026f05
Compare
DiamonDinoia
left a comment
There was a problem hiding this comment.
I still think this can be cleaned up a bit for the sake of future maintainability
|
Sure, I'll do it! Thanks for the comments!! |
5026f05 to
5fdc347
Compare
Outside [-1, 1], keep a signed half-pi and the imaginary magnitude from acosh.
5fdc347 to
9f14e6f
Compare
DiamonDinoia
left a comment
There was a problem hiding this comment.
Okay. Now this looks nice and it is also easy to understand.
I would just make the change I suggested to be in the realm of c++17. This now is more of a nit than an actual necessary change.
If you could also apply something similar to the other PRs then we I would merge them.
| } | ||
|
|
||
| private: | ||
| template <class BatchFn, class ScalarFn> |
There was a problem hiding this comment.
I would do this:
template <class BatchFn, class ScalarFn>
void check_real_axis(BatchFn batch_fn, ScalarFn scalar_fn)
{
using R = real_value_type;
const R outside = std::nextafter(R(1), R(2));
const std::array<R, 8> re = { -R(4), -outside, -R(1), -R(0), R(0), R(1), outside, R(4) };
const std::array<R, 8> im = { -R(2), -R(1), -R(0.5), -R(0), R(0), R(0.5), R(1), R(2) };
const std::size_t n = re.size() * im.size();
// Round up to a multiple of `size`. The tail stays value_type(0, 0),
// which is already in the grid.
vector_type inputs((n + size - 1) / size * size);
auto it = inputs.begin();
for (R real : re)
{
for (R imag : im)
{
*it++ = value_type(real, imag);
}
}
vector_type expected(inputs.size());
std::transform(inputs.cbegin(), inputs.cend(), expected.begin(), scalar_fn);
for (std::size_t i = 0; i < inputs.size(); i += size)
{
batch_type in, ref;
detail::load_batch(in, inputs, i);
detail::load_batch(ref, expected, i);
CHECK_BATCH_EQ(ref, batch_fn(in));
}
}|
Superseded by #1456 |
On the real axis, complex asin returned a positive half-pi and a zero imaginary part for every
|x| > 1, and it flushed the imaginary zero inside[-1, 1]. Outside the interval it now keeps the sign ofxonpi/2and the signed acosh magnitude; inside, it keeps the input imaginary part. acos follows, because it ispi/2 - asin. Both functions are checked on an 8 by 8 grid againststd::asinandstd::acos, with and without fast-math.Part of #1432.
Written by me with AI assistance.