ekmett / ekmett/rounded

Sine and cosine return incorrect intervals on negative intervals

Open
#40 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
35
Forks
13
PR merge metrics
No merged PRs in 30d

Description

# Description
On some negative intervals, `sin` and `cos` produce an invalid interval.

# Example
```haskell
> cos $ (-pi/4) ... (-pi/8)
0.92387953251128685 ... 0.70710678118654746
```
Note how the lower bound is greater than the upper bound!

# Expected behaviour
The computed interval should be the same as for the positive version of the same interval
```haskell
> cos (pi/8) ... (pi/4)
0.39269908169872414 ... 0.78539816339744828
```

# Root cause
The algorithm for `cos` is the following (`sin` is implemented in terms of `cos`):
```
cos x
| width t >= pi = negate 1 ... 1
| inf t >= pi = negate $ cos (t - pi)
| sup t <= pi = decreasing cos t
| sup t <= 2 * pi = negate 1 ... cos (((pi * 2 - sup t) `min` coerce (inf t)))
| otherwise = negate 1 ... 1
where
t = fmod x (pi * 2)
```
Note that $\cos(x)$ is *increasing* over $[-\pi/4, -\pi/8]$ whereas the code assumes that $\cos(x)$ is decreasing over anything with a supremum $\leq \pi$ is decreasing. Perhaps it assumes that `fmod` will always return a value $0 \leq x < 2\pi$?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.