Skip to content

Preserve real-axis branches in complex asin and acos - #1437

Closed
agourakis82 wants to merge 1 commit into
xtensor-stack:masterfrom
agourakis82:fix/complex-asin-real-axis-1432
Closed

agourakis82 wants to merge 1 commit into
xtensor-stack:masterfrom
agourakis82:fix/complex-asin-real-axis-1432

Conversation

@agourakis82

@agourakis82 agourakis82 commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

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 of x on pi/2 and the signed acosh magnitude; inside, it keeps the input imaginary part. acos follows, because it is pi/2 - asin. Both functions are checked on an 8 by 8 grid against std::asin and std::acos, with and without fast-math.

Part of #1432.

Written by me with AI assistance.

@DiamonDinoia DiamonDinoia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@agourakis82
agourakis82 force-pushed the fix/complex-asin-real-axis-1432 branch from af4c656 to 5026f05 Compare November 6, 2026 01:49
Comment thread test/test_complex_trigonometric.cpp Resolved

@DiamonDinoia DiamonDinoia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think this can be cleaned up a bit for the sake of future maintainability

Comment thread test/test_complex_trigonometric.cpp Resolved
@agourakis82

Copy link
Copy Markdown
Contributor Author

Sure, I'll do it! Thanks for the comments!!

Outside [-1, 1], keep a signed half-pi and the imaginary magnitude from acosh.
@cursor
cursor Bot force-pushed the fix/complex-asin-real-axis-1432 branch from 5fdc347 to 9f14e6f Compare November 11, 2026 00:09

@DiamonDinoia DiamonDinoia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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));
    }
}

@DiamonDinoia

Copy link
Copy Markdown
Contributor

Superseded by #1456

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants