Search code examples
algorithmkotlinlogarithm

Function which increases fast and slows down reaching predefined maximum


I am creating a count up algorithm where I increase the number with bigger increments and then the increments get smaller over time, ideally reaching zero or 1. The final sum value should be predefined. The number of steps should be an input parameter and can vary. It seems like it is a logarithmic function with a maximum value. However, the logarithmic function grows until infinity.

The best I've found is square root of logarithm:

val log = (1..10).map { Math.sqrt(Math.log(it * 1.0)) }
    val max = log.max()
    val rounded = log.map { it * 1000 / max!! }.map { Math.round(it) }

    rounded.forEachIndexed { i, l ->
        if (i + 1 < rounded.size)
            println("${rounded[i + 1] - rounded[i]}")
    }

However, i still do not get to very small increments in the end. If range is from zero to 10: 549, 142, 85, 60, 46, 37, 31, 27, 23 If the range is 20: 481, 125, 74, 53, 40, 33, 27, 23, 21, 18, 16, 14, 14, 12, 11, 10, 10, 9, 9

What algorthm to use to get to 1 in the end?

Update: Based on Patricks formula I made this solution:

`  val N = 18981.0
    val log = (1..50).map { N - N/it }
    val max = log.max()
    log.map { print("$it, ") }
    val rounded = log.map { it * N / max!! }.map { Math.round(it) }` 

It is important that N is Double and not the whole number


Solution

  • Square root of the logarithm also grows to infinity. Try

    f(n) = N - N/n
    

    This has the value 0 at n = 1 and tends towards N as n grows without bound. If you need finer granularity, add some coefficients and play around with them until you get something reasonable. For instance, you can use [1 + (n/1000)] and get similar but much slower growth. You can also use exp(-x) or any function with a horizontal asymptote and get similar behavior.

    f(n) = N - exp(-n)
    

    Again, add some coefficients and see how the function changes