Thanks for the reply!
I forgot that the @generated
function does not support closure, so we can’t write an anonymous function inside an Expr
to be generated when it is first called with a specific Val(N)
.
However, I don’t understand why we cannot design a macro to automate the process of generating functions like the following without knowing the types of x
and y
:
function f2(x, y)
@hyperopt for i=1:2, sampler=y,
x1 = x[1],
x2 = x[2]
model([x1, x2])
end
end
function f3(x, y)
@hyperopt for i=1:2, sampler=y,
x1 = x[1],
x2 = x[2],
x3 = x[3]
model([x1, x2, x3])
end
end
As far as I understand, we just need to know how to construct a for
loop expression without explicitly writing it out but using some functions to build the sub-expressions and concatenate them. I found a possibly relevant thread about concatenating assignment expressions, but I don’t know how to make them part of the for
loop expression. I think if I use the dump
function you mentioned to analyze the expression structure of a for loop, then I might be able to do it.
If you have better ideas, I would much appreciate it! FYI, an example of those variables are:
varRanges = LinRange.([0:0.01:1, 0:0.02:2, 0:0.03:6]) # the values (ranges) for all the parameters
numOfSamples = 10 # to be assigned to `i` in the for loop
someSample = Hyperopt.RandomSampler() # The sampler provided by Hyperopt.jl
We actually don’t need pars
if we can name the hyperparameters inside the macro before for loop expression. e.g., construct pars = [Symbol(:a, j) for j=1:N]
, then interpolate its element values as the variable names for the assignments in the expression.