Apply the function repeatedly a specified number of times

If you have a function, there is a simple or built-in way to apply it nonce, or until the result is something concrete. So, for example, if you want to apply the function sqrt4 times, with the effect:

julia> sqrt(sqrt(sqrt(sqrt(11231))))
1.791229164345863

you can enter something like:

repeatf(sqrt, 11231, 4)
+3
source share
4 answers

[Edit: see below for a simple solution without Iterators, although I suggest using it and all the useful features inside the package]

With the Iterators package, the following might be the solution:

julia> using Iterators   # install with Pkg.add("Iterators")
julia> reduce((x,y)->y,take(iterate(sqrt,11231.0),5))
1.791229164345863

iterate (Do ?iterate REPL ). Iterators ( ) nth, :

nth(iterate(sqrt,11231.0),5)

(x,y)->y , reduce, :

first(x,y) = x
second(x,y) = y

,

julia> reduce(second,take(iterate(sqrt,11231.0),5))
1.791229164345863

. , ( ) , , , , 5.

Iterators foldl -

julia> foldl((x,y)->sqrt(x),11231.0,1:4)
1.791229164345863

, , sqrt, , (, , 1:4, )

+4

,

julia> repeatf(f, x, n) = n > 1 ? f(repeatf(f, x, n-1)) : f(x)

julia> repeatf(sqrt, 11321, 4)
 106.40018796975878

repeatf(n, f, x...) = n > 1 ? f(repeatf(n-1, f, x...)...) : f(x...)

+3

, ^ Function Int s

julia> (^)(f::Function, i::Int) = i==1 ? f : x->(f^(i-1))(f(x))
^ (generic function with 1 method)

julia> (sqrt^1)(2)
1.4142135623730951

julia> (sqrt^2)(2)
1.189207115002721

julia> (sqrt^3)(2)
1.0905077326652577

@DNF, julia , ;

`` `

julia> function (∧)(f::Function, i::Int)
           function inner(x)
              for ii in i:-1:1
                 x=f(x)
              end
           x
           end
       end

:

julia> @time((sqrt1_000)(20e300)) #Iterative
  0.000018 seconds (6 allocations: 192 bytes)
1.0

julia> @time((sqrt ^ 1_000)(20e300)) #Recursive
  0.000522 seconds (2.00 k allocations: 31.391 KB)
1.0

#########

julia> @time((sqrt10_000)(20e300)) #Iterative
  0.000091 seconds (6 allocations: 192 bytes)
1.0


julia> @time((sqrt ^ 10_000)(20e300)) #Recursive
  0.003784 seconds (20.00 k allocations: 312.641 KB)
1.0

#########

julia> @time((sqrt30_000)(20e300)) # Iterative
  0.000224 seconds (6 allocations: 192 bytes)
1.0

julia> @time((sqrt ^ 30_000)(20e300)) #Recursive
  0.008128 seconds (60.00 k allocations: 937.641 KB)
1.0


#############

julia> @time((sqrt100_000)(20e300)) #Iterative
  0.000393 seconds (6 allocations: 192 bytes)
1.0

julia> @time((sqrt ^ 100_000)(20e300)) #Recursive
ERROR: StackOverflowError:
 in (::##5#6{Base.#sqrt,Int64})(::Float64) at ./REPL[1]:1 (repeats 26667 times)

, StackOverflowError - .

+3
function apply(f, x, n=1)
    for _ in 1:n
        x = f(x)
    end
    return x
end
+2

Source: https://habr.com/ru/post/1656928/


All Articles