gpt4 book ai didi

types - Julia 设计 : Silently Defining/Naming Types in Macros

转载 作者:行者123 更新时间:2023-12-02 03:12:00 24 4
gpt4 key购买 nike

我在定义新功能时遇到了开发问题,涉及如何“静默定义类型”。目前我有这样的宏:

f = @ode_define begin
dx = a*x - b*x*y
dy = -c*y + d*x*y
end a=>1.5 b=>1 c=3 d=1

这将扩展到

f = (t,u,du) -> begin 
du[1] = 1.5*u[1] - u[1]*u[2]
du[2] = -3*u[2] + u[1]*u[2]
end

这些定义了用于 ODE 求解器的函数。 ODE 求解器的某些功能需要知道参数(即灵敏度分析需要采用参数导数)以便使其更通用我想内联用 = 定义的参数,并有一个“命名方式使用 => 定义的访问”参数。例如,我想将宏扩展为:

f,p = (t,u,du,p) -> begin 
du[1] = p.a*u[1] - p.b*u[1]*u[2]
du[2] = -3*u[2] + u[1]*u[2]
end

问题是,如何定义参数?我可以让宏也这样做:

type Parameters
a::Float64
b::Float64
end
p = Parameters(a,b)

然后您每个 session 只能使用一次宏,因为每次都需要定义一个参数类型。有没有一种安全的方法来命名这种类型,以便可以重复使用宏?从本质上讲,参数类型除了是包含 ab 的容器之外没有其他意义,并且可以通过名称访问它(至关重要,因为我计划做一些事情,询问你想对哪些参数进行操作,比如 fork 图)。这就是我所说的“默默地”的意思——我希望宏吐出一个 p ,其中 p.ap.b 工作,没有引用/用户不必关心这是如何定义的。此外,此设计路径有一个限制,即无法在函数内部定义类型,因此此宏不能用于在函数内部定义 ODE 函数。

Julia 是否提供了一种不牺牲性能的解决这些问题的好方法? (我可以使用字典,但这会导致性能下降)。


编辑

总结一下设计目标,我想要一些东西,以便像我在开头展示的那样的宏可以编写如下代码:

f,p = (t,u,du,p) -> begin 
du[1] = p.a*u[1] - p.b*u[1]*u[2]
du[2] = -3*u[2] + u[1]*u[2]
end
type Parameters
a::Float64
b::Float64
end
p = Parameters(a,b)

打电话

solve(f,p,y0)

在本质上做的求解器中使用

for i = 1:numiterations
y = y + dt*f(t,u,du,p)
end

问题在于 p 的正确形式是否是一种类型,或者 Julia 是否有其他东西可以“用名字来称呼事物”。如果它是一种类型,您如何解决类型必须具有唯一名称的事实(因此宏不能简单地将其扩展为类型参数,因为每次它可能具有不同的字段)但是自动生成什么在您只知道字段名称的地方键入?

最佳答案

gensym 创建全局唯一的名称,可以将其拼接到类型定义表达式,例如:

Expr(:type, true, gensym(:parameter), Expr(:(::), :x, :Int))

I could use a dictionary, but that would cause a performance hit

不完全确定我理解这里的设计目标,但在您的示例中,您将实例 p 包装在闭包中。如果您将 ODE 名称设为宏参数 (@ode_def f = ...),那么您可以在来自 f => f_metadata 的某个全局字典中设置映射p 的句柄以及您可能需要修改的任何内容。

关于types - Julia 设计 : Silently Defining/Naming Types in Macros,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39485715/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com