# NAME

Math::NumSeq::Tetrahedral -- tetrahedral numbers i*(i+1)*(i+2)/6

# SYNOPSIS

`````` use Math::NumSeq::Tetrahedral;
my \$seq = Math::NumSeq::Tetrahedral->new;
my (\$i, \$value) = \$seq->next;``````

# DESCRIPTION

The tetrahedral numbers, i*(i+1)*(i+2)/6.

``    0, 1, 4, 10, 20, 35, 56, 84, 120, ...``

# FUNCTIONS

See "FUNCTIONS" in Math::NumSeq for behaviour common to all sequence classes.

`\$seq = Math::NumSeq::Tetrahedral->new ()`

Create and return a new sequence object.

## Random Access

`\$value = \$seq->ith(\$i)`

Return `\$i*(\$i+1)*(\$i+2)/6`.

`\$bool = \$seq->pred(\$value)`

Return true if `\$value` has the form i*(i+1)*(i+2)/6 for some positive integer i.

`\$i = \$seq->value_to_i_floor(\$value)`

Return the index i of `\$value` or of the next tetrahedral number below `\$value`.

`\$i = \$seq->value_to_i_estimate(\$value)`

Return an estimate of the i corresponding to `\$value`.

In the current code this `\$i` gives the tetrahedral above or below `\$value`, so is out by no more than 1.

# FORMULAS

## Value to i Estimate

i*(i+1)*(i+2) always fall in between cubes, so

``````    T(i) = i*(i+1)*(i+2)/6
= (i^3 + 3*i^2 + 2*i)/6

i^3 < 6*T(i) < (i+1)^3``````

For `value_to_i_estimate()` it's enough to apply a cube root,

``    i_estimate = floor(cbrt(6*value))``

## Value to i Floor

For `value_to_i_floor()` the cube root can be 1 too big when the given value is in between successive T() tetrahedrals. For example if value=57 floor(cbrt(6*57))=6 is correct, but value=58 floor(cbrt(6*58))=7 is 1 too big.

``````    i = floor(cbrt(6*value))
if i*(i+1)*(i+2) <= 6*value
then i_floor = i
else i_floor = i-1    # cbrt was 1 too big``````