Skip to content

Commit

Permalink
chore(stdlib)!: Remove sin, cos, tan, gamma, factorial from…
Browse files Browse the repository at this point in the history
… `Number` module (#2046)
  • Loading branch information
phated committed Feb 22, 2024
1 parent aead774 commit 85c4389
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 344 deletions.
60 changes: 0 additions & 60 deletions compiler/test/stdlib/number.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -651,37 +651,6 @@ assert Number.sign(BI.toNumber(1t)) == 1
assert 1 / Number.sign(0.0) == Infinity
assert 1 / Number.sign(-0.0) == -Infinity

// Number.sin - These test a range as we approximate sin
assert Number.sin(0.0) == 0
assert Number.sin(1) > 0.84147 && Number.sin(1) < 0.84148
assert Number.sin(-1) < -0.84147 && Number.sin(-1) > -0.84148
assert Number.sin(20) > 0.91294 && Number.sin(20) < 0.91295
assert Number.sin(1/2) > 0.4794 && Number.sin(1/2) < 0.4795
// TODO(#1478): Update this test when sin is unbounded
assert Number.sin(9223372036854775809) == 0.0
assert Number.isNaN(Number.sin(Infinity))
assert Number.isNaN(Number.sin(NaN))

// Number.cos - These test a range as we approximate sin
assert Number.cos(1) > 0.5403 && Number.cos(1) < 0.5404
assert Number.cos(-1) > 0.5403 && Number.cos(-1) < 0.5404
assert Number.cos(15) < -0.7596 && Number.cos(15) > -0.7597
assert Number.cos(1/2) > 0.8775 && Number.cos(1/2) < 0.8776
// TODO(#1478): Update this test when sin is unbounded
assert Number.cos(9223372036854775809) == 0.0
assert Number.isNaN(Number.cos(Infinity))
assert Number.isNaN(Number.cos(NaN))

// Number.tan - These test a range as we approximate sin
assert Number.tan(1) > 1.5574 && Number.tan(1) < 1.5575
assert Number.tan(-1) > -1.5575 && Number.tan(-1) < -1.5574
assert Number.tan(15) < -0.8559 && Number.tan(15) > -0.8560
assert Number.tan(1/2) > 0.5463 && Number.tan(1/2) < 0.5464
// TODO(#1478): Update this test when sin is unbounded
assert Number.isNaN(Number.tan(9223372036854775809))
assert Number.isNaN(Number.tan(Infinity))
assert Number.isNaN(Number.tan(NaN))

// Number.asin
assert Number.isNaN(Number.asin(-8.06684839057968084))
assert Number.isNaN(Number.asin(-1.1))
Expand Down Expand Up @@ -839,35 +808,6 @@ assert Number.isClose(
)
assert Number.isNaN(Number.atan(NaN))

// Number.gamma
// Note: Currently gamma will overflow the memory when using a bigint as such there are no tests for this
assert Number.gamma(10.5) < 1133278.3889488 &&
Number.gamma(10.5) > 1133278.3889487
assert Number.gamma(10) == 362880
assert Number.gamma(1) == 1
assert Number.gamma(0.5) == 1.7724538509055159
assert Number.gamma(-0.5) < -3.544907 && Number.gamma(-0.5) > -3.544909
assert Number.gamma(-1) == Infinity
assert Number.gamma(-10) == Infinity
assert Number.gamma(0.2) > 4.59084 && Number.gamma(0.2) < 4.59085
assert Number.gamma(1/5) > 4.59084 && Number.gamma(1/5) < 4.59085
assert Number.gamma(1/2) == 1.7724538509055159
assert Number.isNaN(Number.gamma(Infinity))
assert Number.isNaN(Number.gamma(NaN))

// Number.factorial
// Note: Currently factorial will overflow the memory when using a bigint as such there are no tests for this
assert Number.factorial(10) == 3628800
assert Number.factorial(5) == 120
assert Number.factorial(0) == 1
assert Number.factorial(-5) == -120
assert Number.factorial(-10) == -3628800
assert Number.factorial(10.5) == 11899423.083962297
assert Number.factorial(0.5) == 0.886226925452759
assert Number.factorial(1/2) == 0.886226925452759
assert Number.isNaN(Number.factorial(Infinity))
assert Number.isNaN(Number.factorial(NaN))

// Number.toDegrees
assert Number.toDegrees(0) == 0
assert Number.toDegrees(Number.pi) == 180
Expand Down
133 changes: 0 additions & 133 deletions stdlib/number.gr
Original file line number Diff line number Diff line change
Expand Up @@ -552,62 +552,6 @@ let chebyshevSine = (radians: Number) => {
(radians - pi - pi_minor) * (radians + pi + pi_minor) * p1 * radians
}

/**
* Computes the sine of a number (in radians) using Chebyshev polynomials.
*
* @param radians: The input in radians
* @returns The computed sine
*
* @since v0.5.2
* @history v0.5.4: Handle NaN and Infinity
*/
provide let sin = (radians: Number) => {
if (radians != radians || radians == Infinity) {
NaN
} else {
let quot = reduceToPiBound(radians)
let bounded = radians - pi * quot
if (quot % 2 == 0) {
chebyshevSine(bounded)
} else {
neg(chebyshevSine(bounded))
}
}
}

/**
* Computes the cosine of a number (in radians) using Chebyshev polynomials.
*
* @param radians: The input in radians
* @returns The computed cosine
*
* @since v0.5.2
* @history v0.5.4: Handle NaN and Infinity
*/
provide let cos = (radians: Number) => {
if (radians != radians || radians == Infinity) {
NaN
} else {
sin(pi / 2 + radians)
}
}

/**
* Computes the tangent of a number (in radians) using Chebyshev polynomials.
*
* @param radians: The input in radians
* @returns The computed tangent
*
* @since v0.5.4
*/
provide let tan = (radians: Number) => {
if (isNaN(radians) || isInfinite(radians)) {
NaN
} else {
sin(radians) / cos(radians)
}
}

@unsafe
let rf = z => {
// see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE at top of file
Expand Down Expand Up @@ -851,83 +795,6 @@ provide let atan = angle => {
return WasmI32.toGrain(newFloat64(WasmF64.copySign(z, sx))): Number
}

// Math.gamma implemented using the Lanczos approximation
// https://en.wikipedia.org/wiki/Lanczos_approximation
/**
* Computes the gamma function of a value using Lanczos approximation.
*
* @param z: The value to interpolate
* @returns The gamma of the given value
*
* @throws InvalidArgument(String): When `z` is zero
*
* @since v0.5.4
*/
provide let rec gamma = z => {
if (z == 0) {
throw Exception.InvalidArgument("Gamma of 0 is undefined")
} else if (isInteger(z) && z > 0) {
let mut output = 1
for (let mut i = 1; i < z; i += 1) {
output *= i
}
output
} else {
let mut z = z
let g = 7
let c = [>
0.99999999999980993,
676.5203681218851,
-1259.1392167224028,
771.32342877765313,
-176.61502916214059,
12.507343278686905,
-0.13857109526572012,
9.9843695780195716e-6,
1.5056327351493116e-7,
]
let mut output = 0
if (z < 0.5) {
output = pi / (sin(pi * z) * gamma(1 - z))
} else if (z == 0.5) {
// Handle this case separately because it is out of the domain of Number.pow when calculating
output = 1.7724538509055159
} else {
z -= 1
let mut x = c[0]
for (let mut i = 1; i < g + 2; i += 1) {
x += c[i] / (z + i)
}

let t = z + g + 0.5
output = sqrt(2 * pi) * (t ** (z + 0.5)) * exp(t * -1) * x
}
if (abs(output) == Infinity) Infinity else output
}
}

/**
* Computes the product of consecutive integers for an integer input and computes the gamma function for non-integer inputs.
*
* @param n: The value to factorialize
* @returns The factorial of the given value
*
* @throws InvalidArgument(String): When `n` is negative
*
* @since v0.5.4
*/
provide let rec factorial = n => {
if (isInteger(n) && n < 0) {
gamma(abs(n) + 1) * -1
} else if (!isInteger(n) && n < 0) {
throw Exception.InvalidArgument(
"Cannot compute the factorial of a negative non-integer",
)
} else {
gamma(n + 1)
}
}

/**
* Converts degrees to radians.
*
Expand Down
151 changes: 0 additions & 151 deletions stdlib/number.md
Original file line number Diff line number Diff line change
Expand Up @@ -815,95 +815,6 @@ Returns:
|----|-----------|
|`Result<Number, String>`|`Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise|

### Number.**sin**

<details>
<summary>Added in <code>0.5.2</code></summary>
<table>
<thead>
<tr><th>version</th><th>changes</th></tr>
</thead>
<tbody>
<tr><td><code>0.5.4</code></td><td>Handle NaN and Infinity</td></tr>
</tbody>
</table>
</details>

```grain
sin : (radians: Number) => Number
```

Computes the sine of a number (in radians) using Chebyshev polynomials.

Parameters:

|param|type|description|
|-----|----|-----------|
|`radians`|`Number`|The input in radians|

Returns:

|type|description|
|----|-----------|
|`Number`|The computed sine|

### Number.**cos**

<details>
<summary>Added in <code>0.5.2</code></summary>
<table>
<thead>
<tr><th>version</th><th>changes</th></tr>
</thead>
<tbody>
<tr><td><code>0.5.4</code></td><td>Handle NaN and Infinity</td></tr>
</tbody>
</table>
</details>

```grain
cos : (radians: Number) => Number
```

Computes the cosine of a number (in radians) using Chebyshev polynomials.

Parameters:

|param|type|description|
|-----|----|-----------|
|`radians`|`Number`|The input in radians|

Returns:

|type|description|
|----|-----------|
|`Number`|The computed cosine|

### Number.**tan**

<details disabled>
<summary tabindex="-1">Added in <code>0.5.4</code></summary>
No other changes yet.
</details>

```grain
tan : (radians: Number) => Number
```

Computes the tangent of a number (in radians) using Chebyshev polynomials.

Parameters:

|param|type|description|
|-----|----|-----------|
|`radians`|`Number`|The input in radians|

Returns:

|type|description|
|----|-----------|
|`Number`|The computed tangent|

### Number.**asin**

<details disabled>
Expand Down Expand Up @@ -979,68 +890,6 @@ Returns:
|----|-----------|
|`Number`|The inverse tangent (angle in radians between `-pi/2` and `pi/2`) of the given `angle` or `NaN` if the given `angle` is not between`-1` and `1`|

### Number.**gamma**

<details disabled>
<summary tabindex="-1">Added in <code>0.5.4</code></summary>
No other changes yet.
</details>

```grain
gamma : (z: Number) => Number
```

Computes the gamma function of a value using Lanczos approximation.

Parameters:

|param|type|description|
|-----|----|-----------|
|`z`|`Number`|The value to interpolate|

Returns:

|type|description|
|----|-----------|
|`Number`|The gamma of the given value|

Throws:

`InvalidArgument(String)`

* When `z` is zero

### Number.**factorial**

<details disabled>
<summary tabindex="-1">Added in <code>0.5.4</code></summary>
No other changes yet.
</details>

```grain
factorial : (n: Number) => Number
```

Computes the product of consecutive integers for an integer input and computes the gamma function for non-integer inputs.

Parameters:

|param|type|description|
|-----|----|-----------|
|`n`|`Number`|The value to factorialize|

Returns:

|type|description|
|----|-----------|
|`Number`|The factorial of the given value|

Throws:

`InvalidArgument(String)`

* When `n` is negative

### Number.**toRadians**

<details disabled>
Expand Down

0 comments on commit 85c4389

Please sign in to comment.