在 Julia 中迭代具有不同数量参数的不同函数

Iterating over different functions with different number of parameters in Julia

我正在尝试 运行 对具有不同数量参数的不同函数进行循环。变量是在循环内的 运行 时间创建的,我想在每次迭代中使用 eval 来使用变量 :symbol 实例化一个 Struct。但是,我不能这样做,因为 eval 只适用于全局范围。这是适用于案例的 MWE:

function f1(x); return x; end
function f2(x1,x2); return x1+x2; end

handles = [f1,f2]
args =[:(x1),:(x1,x2)]

x1 = 1; x2 = 1;
for (i,f) in enumerate(handles)
    params = eval(args[i])
    @show f(params...)
end

f(params...) = 1
f(params...) = 2

但是,如果我在循环内移动变量定义,这正是我真正想要的,在重新启动 Julia 以清除工作区后它不起作用。

function f1(x); return x; end
function f2(x1,x2); return x1+x2; end

handles = [f1,f2]
args =[:(x1),:(x1,x2)]

for (i,f) in enumerate(handles)
    x1 = 1; x2 = 1;
    params = eval(args[i])
    @show f(params...)
end

ERROR: UndefVarError: x1 not defined

我已经尝试了几个答案,例如 this one,但我似乎无法让它发挥作用。我可以编写一个自定义调度函数,它接受 [x1,x2] 并使用正确的参数调用 f1 或 f2。但是,有没有办法用 eval 或其他优雅的解决方案来做到这一点?

编辑:这里有更多关于我在我的代码中尝试做的事情的细节。我为每个算法都有一个配置结构,在此我想预先定义它需要的参数

KMF_config = AlgConfig( 
    name = "KMF",
    constructor = KMC.KMF,
    parameters = :(mu,N,L,p),
    fit = KMC.fit!)
MF_config = AlgConfig( 
    name = "MF",
    constructor = KMC.MF,
    parameters = :(mu,N,L),
    fit = KMC.fit!)

alg_config_list = [KMF_config, MF_config]
for (i,alg_config) in enumerate(alg_config_list)
    mu,N,L,p,A,B,C,D,data = gen_vars() #this returns a bunch of variables that are used in different algorithms
    method = alg_config.constructor(eval(method.parameters)...)
    method.fit(data)
end

一个可能的解决方案是让一个函数获取所有变量和方法,并且 return 一个包含根据 method.name 的变量子集的元组。但我不确定这是否是最好的方法。

这是一种使用多重分派而不是 eval 的方法:

run_a(x, y) = x + 10*y
run_b(x, y, z) = x + 10*y + 100*z

extract(p, ::typeof(run_a)) = (p.x, p.y)
extract(p, ::typeof(run_b)) = (p.x, p.y, p.z)
genvars() = (x=1, y=2, z=3)

function doall()
    todo = [
        run_a,
        run_b,
    ]
    for runalg in todo
        v = genvars()
        p = extract(v, runalg)
        @show runalg(p...)
    end
end

在您的示例中,您会将 run_arun_b 替换为 KMC.KMFKMC.MF

编辑:清理示例以避免示例中不存在的结构。