Skip to contents

Determine the stopping time, or "total" stopping time, for an initial value.

Usage

stopping_time(
  initial_value,
  P = 2,
  a = 3,
  b = 1,
  max_stopping_time = 1000,
  total_stopping_time = FALSE
)

Arguments

initial_value

(int): The value for which to find the stopping time.

P

(numeric|bigz): Modulus used to divide n, iff n is equivalent to (0 mod P). Default is 2.

a

(numeric|bigz) Factor by which to multiply n. Default is 3.

b

(numeric|bigz) Value to add to the scaled value of n. Default is 1.

max_stopping_time

(int) Maximum amount of times to iterate the function, if the stopping time is not reached. IF the max_stopping_time is reached, the function will return NaN. Default is 1000.

total_stopping_time

(bool) Whether or not to execute until the "total" stopping time (number of iterations to obtain 1) rather than the regular stopping time (number of iterations to reach a value less than the initial value). Default is FALSE.

Value

An integer numeral if stopped, Inf if a cycle, NaN if OOB, else NA.

Details

Returns the stopping time, the amount of iterations required to reach a value less than the initial value, or NaN if max_stopping_time is exceeded. Alternatively, if total_stopping_time is TRUE, then it will instead count the amount of iterations to reach 1. If the sequence does not stop, but instead ends in a cycle, the result will be (Inf). If (P,a,b) are such that it is possible to get stuck on zero, the result will be the negative of what would otherwise be the "total stopping time" to reach 1, where 0 is considered a "total stop" that should not occur as it does form a cycle of length 1.

Examples

# Calculates the "stopping time", or optionally the "total" stopping time.
# Without `gmp` or parameterisation, we can try something simple like
stopping_time(27)
#> [1] 96
stopping_time(27, total_stopping_time=TRUE)
#> [1] 111
# If we want change the default parameterisation we can;
stopping_time(3, 5, 2, 1)
#> [1] Inf
# Or if we only want to change one of them
stopping_time(17, a=5)
#> [1] Inf
# All the above work fine, but the function doesn't offer protection against
# overflowing integers by default. To venture into the world of arbitrary
# integer inputs we can use an `as.bigz` from `gmp`. Compare the two;
stopping_time(99999999999999999999)
#> Warning: probable complete loss of accuracy in modulus
#> Warning: probable complete loss of accuracy in modulus
#> [1] 1
stopping_time(as.bigz("99999999999999999999"))
#> [1] 114
# As an extra note, the original motivation for creating a range of Collatz
# themed packages came from some earlier scripts for calculating the stopping
# distances under certain parameterisations. An inconsequential result of
# which was observing that all of the following, for however high `k` goes,
# should equal `96`!
stopping_time(27)
#> [1] 96
stopping_time(27+as.bigz("576460752303423488"))
#> [1] 96
stopping_time(27+(2*as.bigz("576460752303423488")))
#> [1] 96
stopping_time(27+(3*as.bigz("576460752303423488")))
#> [1] 96
stopping_time(27+(4*as.bigz("576460752303423488")))
#> [1] 96