Storage of functions with pre-defined argument values

Hi all,

I am trying to store a vector of functions, which can later be retrieved and applied to one or more vectors. An example:

using ShiftedArrays

fs = Function[ShiftedArrays.lag, diff]
x = rand(10)

for f in fs
    x = fs(x)
end

The above works. My issue is that I don’t know how to do it (optimally) if I want to specify some of the argument values before storing them. Let’s say that I want the third lag, e.g. lag(x, n = 3). While I could store this as, say, lag3(x) = ShiftedArrays.lag(x, 3), the argument ‘n’ is randomly selected when the code runs, and hence I would have to pre-define maybe 100 such functions lag1(x)…lag100(x) which seems not ideal.

I have thought about storing this in structs, but don’t know if this is the “correct”/optimal way to go either, e.g.:

using ShiftedArrays

mutable struct Lag
    n::Int
end

my_lag(x::AbstractVector, t::Lag) = ShiftedArrays.lag(x, t.n)

x = rand(10)
my_lag(x, Lag(3)

Going down this road, I would store the struct Lag(3) for later usage.

Is there a more elegant way to solve this given that the lag parameter ‘n’ isn’t determined until the program runs and with the understanding that there may be many more functions than just lag and diff?

Thank you in advance!

Does this help?

julia> f(x, y) = x + y
f (generic function with 1 method)

julia> fix_f(y) = x -> f(x, y)
fix_f (generic function with 1 method)

julia> f_3 = fix_f(3)
#3 (generic function with 1 method)

julia> f_3(10)
13
1 Like

You might be looking for anonymous functions. Then you can do for example:

using ShiftedArrays
randlag = rand(0:10)
fs = [x -> ShiftedArrays.lag(x,3), x -> ShiftedArrays.lag(x,5), x -> ShiftedArrays.lag(x, randlag)]

You can use anonymous functions like every other value, e.g. pass the around or store them in variables for later use.

3 Likes

You can make the struct approach more elegant by making it callable.

(t::Lag)(x::AbstractVector) = ShiftedArrays.lag(x, t.n)

f = Lag(3)
x = rand(10)
f(x)
2 Likes

Thank you @barucden, @abraemer, and @GunnarFarneback for your quick feedback! All of your suggestions could well end up being the final solution. For now I will try out the anonymous function approach.