Skip to content

Preserve imaginary sign in complex tan overflow handling - #1434

Draft
agourakis82 wants to merge 1 commit into
xtensor-stack:masterfrom
agourakis82:fix/complex-tan-overflow-sign-1432
Draft

agourakis82 wants to merge 1 commit into
xtensor-stack:masterfrom
agourakis82:fix/complex-tan-overflow-sign-1432

Conversation

@agourakis82

Copy link
Copy Markdown

For complex inputs with a sufficiently large negative imaginary part, xsimd::tan returns an imaginary component of +1 instead of -1. For example, tan(complex<float>(1, -45)) and tan(complex<double>(1, -356)) both produce (0, +1) on the unchanged base, while std::tan produces (0, -1).

The overflow handling detects isinf(sinh(2 * imag(z))) but selects +1 for either sign. Use copysign to retain the overflowing value's sign. The denominator-zero handling and the fast-math path are unchanged.

Add float/double regression tests with mixed SIMD lanes, both imaginary signs, zero/nonzero real parts, maximum finite imaginary magnitudes and ordinary finite controls. The tests check finite results and both component values against a C++23 scalar reference.

Validation on base ebe9991 plus this patch:

  • Native Apple clang 21, arm64/NEON64, C++23: the same new regression fails on the unchanged headers for both types, then passes with the correction. All four cases in the complex trigonometric unit pass (96 assertions).
  • The same unit passes AddressSanitizer and UndefinedBehaviorSanitizer.
  • Full native CMake/CTest suite passes on arm64: 432 doctest cases, 77,716 assertions; CTest 1/1.
  • Native GCC 13.3, Linux x86-64, C++23: the before/after comparison and complete complex trigonometric unit pass in SSE2 and AVX2 builds (Slurm 17825, exit 0:0).
  • The original issue reproducer was compiled unchanged with C++23 before and after the fix. Its negative-imaginary tan examples acquire the correct imaginary sign; other reported defects remain visible.

This addresses only the imaginary saturation-sign cases in #1432 and should not close the issue. The original reproducer also exposes real-component signed-zero differences, which remain outside this patch. The remaining tan pole cases, other complex functions and fast-math behavior are not addressed here. This is independent of the finite-real-axis sqrt correction in #1433.

AI assistance supported investigation, implementation and validation. A local model review was attempted but did not return within the bounded review window; the results above are executable checks, not model approval.

When sinh(2*imag(z)) overflows, retain its sign in the saturated imaginary result instead of returning +1 unconditionally. Add mixed-lane finite-input regressions for float and double, including both signs, maximum finite imaginary magnitudes and ordinary controls.

Validated with C++23: native arm64 complete CMake suite and focused ASan/UBSan; native GCC13 SSE2 and AVX2 before/after tests in Slurm17825. Other complex functions, fast-math and real signed-zero discrepancies remain outside this change.

Assisted-by: OpenAI Codex

This branch has not been deployed

No deployments
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.

1 participant