As @mauro3 suggested, all you need to do is create a new anonymous function for each of your g_i
, where each anonymous function takes only one argument (x_i
) and stores the appropriate values of the other arguments to f
. A function with some of its arguments already bound to values is a closure and we usually write them in Julia with anonymous functions.
For example, given f(x, y)
, we can make g1
an anonymous function that only takes x
and holds a default value for y
:
julia> f(x, y) = x + y
f (generic function with 1 method)
julia> g1 = x -> f(x, 2.0) # y = 2.0
(::#1) (generic function with 1 method)
julia> g2 = y -> f(1.5, y) # x = 1.5
(::#3) (generic function with 1 method)
julia> g1(1.5) == g2(2.0) == f(1.5, 2.0)
true
To automate this across all the inputs to some function f
, we just need to build up those anonymous functions in a loop.
Here’s one way to do it. I’m using the helpful setindex
function from StaticArrays.jl
to make this a bit more efficient:
julia> using StaticArrays: setindex
julia> function make_closures(f, default_values...)
[xi -> f(setindex(default_values, xi, i)...) for i in 1:length(default_values)]
end
make_closures (generic function with 1 method)
julia> gs = make_closures(f, 0.75, 1.5, 0.8)
3-element Array{##11#13{Int64,#f,Tuple{Float64,Float64,Float64}},1}:
#11
#11
#11
julia> gs[1](1.0) == f(1.0, 1.5, 0.8)
true
julia> gs[2](1.0) == f(0.75, 1.0, 0.8)
true
julia> gs[3](1.0) == f(0.75, 1.5, 1.0)
true
A very nice feature of Julia is that you can do this with essentially no performance penalty. Using BenchmarkTools.jl:
julia> using BenchmarkTools
julia> @btime $(gs[1])(0.75)
14.931 ns (0 allocations: 0 bytes)
Also, as @mauro3 suggested, it will be easier for us to read your code and help you if you quote it properly