Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: scipy.special.sindg returns 0.0 for large argument #20723

Open
fancidev opened this issue May 16, 2024 · 3 comments
Open

BUG: scipy.special.sindg returns 0.0 for large argument #20723

fancidev opened this issue May 16, 2024 · 3 comments
Labels
defect A clear bug or issue that prevents SciPy from being installed or used as expected scipy.special

Comments

@fancidev
Copy link
Contributor

fancidev commented May 16, 2024

Describe your issue.

scipy.special.sindg(x) computes the sine of x where x is measured in degree. It returns 0.0 when x > 1e14.

From the source code it appears this behavior is expected. However, when I use Jupyter Notebook I didn’t get an error or warning message and the function “silently” returned zero.

Though the large argument is probably not so commonly used in practice, it may still be desirable to support it if possible. (One possibility is to provide a function that converts degree to radian and reduce it into [-pi,pi] in one step.)

Reproducing Code Example

import scipy.special
print(scipy.special.sindg(2e14))

# prints 0.0
# expects sindg(2e14 % 360) = sindg(200) = -0.34

Error message

No error is displayed

SciPy/NumPy/Python version and system information

SciPy 1.12 / Python 3.10 / Windows, though I think the issue is platform independent and also exists in HEAD.
@fancidev fancidev added the defect A clear bug or issue that prevents SciPy from being installed or used as expected label May 16, 2024
@fancidev
Copy link
Contributor Author

It seems the limit 1e14 is imposed because the function uses a naive formula to do range reduction: x = x - 45 * floor(x / 45.0). This is inaccurate for large x. By using a more sophisticated fmod, the limit 1e14 should be unnecessary.

@nickodell
Copy link
Contributor

nickodell commented May 17, 2024

However, when I use Jupyter Notebook I didn’t get an error or warning message and the function “silently” returned zero.

I believe this error is only shown if you enable the error:

scipy.special.seterr(no_result='raise')

Results in:

>>> scipy.special.sindg(1e14 + 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
scipy.special._sf_error.SpecialFunctionError: scipy.special/sindg: no result obtained

Though the large argument is probably not so commonly used in practice, it may still be desirable to support it if possible.

I'm not sure there's an accurate way to do this for large x. If x is large, then x is not very precise in an absolute sense. If x is about 1e14, then x % 360 can be accurate, at most, to 5 decimal digits of precision.

I agree that the current state of things is not great, though. At minimum, this ought to be documented.

@fancidev
Copy link
Contributor Author

fancidev commented May 17, 2024

Thanks for the comments @nickodell. The seterr call works!

With some googling, I find this StackOverflow thread that elaborates the issues with large argument, and this pdf that explains range reduction when the argument is in radian.

My take away is that when the argument is very large, the result is almost certainly useless for the practical problem because a tiny relative error in the argument can lead to completely different result. So the best practice is never to work with huge angles. On the other hand, if the huge angle is against all odds exact, then it would be ideal to return a correct result for sindg. This is actually easy when the argument is in degrees, since 360 is exact while pi is approximate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
defect A clear bug or issue that prevents SciPy from being installed or used as expected scipy.special
Projects
None yet
Development

No branches or pull requests

3 participants