Skip to content

Commit

Permalink
Merge pull request #655 from rben01/math-sequences
Browse files Browse the repository at this point in the history
Added fibonacci, lucas, and catalan sequences
  • Loading branch information
sharkdp authored Nov 22, 2024
2 parents 6aa6254 + 4691a2f commit 9983277
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 18 deletions.
60 changes: 57 additions & 3 deletions book/src/list-functions-math.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,9 @@ Truncate in centimeters.

### `fract` (Fractional part)
Returns the fractional part of \\( x \\), i.e. the remainder when divided by 1.
If \\( x < 0 \\), then so will be `fract(x)`. Note that due to floating point error, a
number’s fractional part can be slightly “off”; for instance, `fract(1.2) ==
0.1999...996 != 0.2`.
If \\( x < 0 \\), then so will be `fract(x)`. Note that due to floating point error, a
number’s fractional part can be slightly “off”; for instance, `fract(1.2) ==
0.1999...996 != 0.2`.
More information [here](https://doc.rust-lang.org/std/primitive.f64.html#method.fract).

```nbt
Expand Down Expand Up @@ -691,6 +691,60 @@ fn binom(n: Scalar, k: Scalar) -> Scalar

</details>

### `fibonacci` (Fibonacci numbers)
The nth Fibonacci number, where n is a nonnegative integer. The Fibonacci sequence is given by \\( F_0=0 \\), \\( F_1=1 \\), and \\( F_n=F_{n-1}+F_{n-2} \\) for \\( n≥2 \\). The first several elements, starting with \\( n=0 \\), are \\( 0, 1, 1, 2, 3, 5, 8, 13 \\).
More information [here](https://en.wikipedia.org/wiki/Fibonacci_sequence).

```nbt
fn fibonacci(n: Scalar) -> Scalar
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=fibonacci%285%29')""></button></div><code class="language-nbt hljs numbat">fibonacci(5)

= 5
</code></pre>

</details>

### `lucas` (Lucas numbers)
The nth Lucas number, where n is a nonnegative integer. The Lucas sequence is given by \\( L_0=2 \\), \\( L_1=1 \\), and \\( L_n=L_{n-1}+L_{n-2} \\) for \\( n≥2 \\). The first several elements, starting with \\( n=0 \\), are \\( 2, 1, 3, 4, 7, 11, 18, 29 \\).
More information [here](https://en.wikipedia.org/wiki/Lucas_number).

```nbt
fn lucas(n: Scalar) -> Scalar
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=lucas%285%29')""></button></div><code class="language-nbt hljs numbat">lucas(5)

= 11
</code></pre>

</details>

### `catalan` (Catalan numbers)
The nth Catalan number, where n is a nonnegative integer. The Catalan sequence is given by \\( C_n=\frac{1}{n+1}\binom{2n}{n}=\binom{2n}{n}-\binom{2n}{n+1} \\). The first several elements, starting with \\( n=0 \\), are \\( 1, 1, 2, 5, 14, 42, 132, 429 \\).
More information [here](https://en.wikipedia.org/wiki/Catalan_number).

```nbt
fn catalan(n: Scalar) -> Scalar
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=catalan%285%29')""></button></div><code class="language-nbt hljs numbat">catalan(5)

= 42
</code></pre>

</details>

## Random sampling, distributions

Defined in: `core::random`, `math::distributions`
Expand Down
13 changes: 13 additions & 0 deletions examples/tests/math_functions.nbt
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,19 @@ assert_eq(binom(1.5, 2), 0.375)
assert_eq(binom(1.5, 3), -0.0625)
assert_eq(binom(1.5, 4), 0.0234375)

# combinatoric sequences
assert_eq(fibonacci(0), 0)
assert_eq(fibonacci(1), 1)
assert_eq(fibonacci(5), 5)

assert_eq(lucas(0), 2)
assert_eq(lucas(1), 1)
assert_eq(lucas(5), 11)

assert_eq(catalan(0), 1)
assert_eq(catalan(1), 1)
assert_eq(catalan(5), 42)

# maximum

assert_eq(maximum([1]), 1)
Expand Down
6 changes: 3 additions & 3 deletions numbat/modules/core/functions.nbt
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ fn trunc_in<D: Dim>(base: D, value: D) -> D = trunc(value / base) × base

@name("Fractional part")
@description("Returns the fractional part of $x$, i.e. the remainder when divided by 1.
If $x < 0$, then so will be `fract(x)`. Note that due to floating point error, a
number’s fractional part can be slightly “off”; for instance, `fract(1.2) ==
0.1999...996 != 0.2`.")
If $x < 0$, then so will be `fract(x)`. Note that due to floating point error, a
number’s fractional part can be slightly “off”; for instance, `fract(1.2) ==
0.1999...996 != 0.2`.")
@url("https://doc.rust-lang.org/std/primitive.f64.html#method.fract")
@example("fract(0.0)")
@example("fract(5.5)")
Expand Down
58 changes: 46 additions & 12 deletions numbat/modules/math/combinatorics.nbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,55 @@ fn factorial(n: Scalar) -> Scalar = n!
@url("https://en.wikipedia.org/wiki/Falling_and_rising_factorials")
@example("falling_factorial(4, 2)")
fn falling_factorial(n: Scalar, k: Scalar) -> Scalar =
if k < 0 || !is_integer(k) then
error("in falling_factorial(n, k), k must be a nonnegative integer")
else if is_zero(k) then
1
else
n * falling_factorial(n-1, k-1)
if k < 0 || !is_integer(k) then
error("in falling_factorial(n, k), k must be a nonnegative integer")
else if is_zero(k) then
1
else
n * falling_factorial(n-1, k-1)

@name("Binomial coefficient")
@description("Equal to falling_factorial(n, k)/k!, this is the coefficient of $x^k$ in the series expansion of $(1+x)^n$ (see “binomial series”). If n is an integer, then this this is the number of k-element subsets of a set of size n, often read \"n choose k\". k must always be an integer.")
@url("https://en.wikipedia.org/wiki/Binomial_coefficient")
@example("binom(5, 2)")
fn binom(n: Scalar, k: Scalar) -> Scalar =
if !is_integer(k) then
error("in binom(n, k), k must be an integer")
else if k < 0 || (k > n && is_integer(n)) then
0
else
falling_factorial(n, k) / k!
if !is_integer(k) then
error("in binom(n, k), k must be an integer")
else if k < 0 || (k > n && is_integer(n)) then
0
else
falling_factorial(n, k) / k!

@name("Fibonacci numbers")
@description("The nth Fibonacci number, where n is a nonnegative integer. The Fibonacci sequence is given by $F_0=0$, $F_1=1$, and $F_n=F_\{n-1\}+F_\{n-2\}$ for $n≥2$. The first several elements, starting with $n=0$, are $0, 1, 1, 2, 3, 5, 8, 13$.")
@url("https://en.wikipedia.org/wiki/Fibonacci_sequence")
@example("fibonacci(5)")
fn fibonacci(n: Scalar) -> Scalar =
if !(is_integer(n) && n >= 0) then
error("the argument to fibonacci(n) must be a nonnegative integer")
else
# use Binet's formula for constant time
round((phi^n - (-phi)^(-n))/sqrt(5))
where phi = (1+sqrt(5))/2

@name("Lucas numbers")
@description("The nth Lucas number, where n is a nonnegative integer. The Lucas sequence is given by $L_0=2$, $L_1=1$, and $L_n=L_\{n-1\}+L_\{n-2\}$ for $n≥2$. The first several elements, starting with $n=0$, are $2, 1, 3, 4, 7, 11, 18, 29$.")
@url("https://en.wikipedia.org/wiki/Lucas_number")
@example("lucas(5)")
fn lucas(n: Scalar) -> Scalar =
if !(is_integer(n) && n >= 0) then
error("the argument to lucas(n) must be a nonnegative integer")
else
# use Binet's formula for constant time
round(phi^n + (1-phi)^n)
where phi = (1+sqrt(5))/2

@name("Catalan numbers")
@description("The nth Catalan number, where n is a nonnegative integer. The Catalan sequence is given by $C_n=\frac\{1\}\{n+1\}\binom\{2n\}\{n\}=\binom\{2n\}\{n\}-\binom\{2n\}\{n+1\}$. The first several elements, starting with $n=0$, are $1, 1, 2, 5, 14, 42, 132, 429$.")
@url("https://en.wikipedia.org/wiki/Catalan_number")
@example("catalan(5)")
fn catalan(n: Scalar) -> Scalar =
if !(is_integer(n) && n >= 0) then
error("the argument to catalan(n) must be a nonnegative integer")
else
binom(2*n, n) / (n+1)

0 comments on commit 9983277

Please sign in to comment.