【问题标题】:Julia: Macros for vector aliasingJulia:用于矢量混叠的宏
【发布时间】:2016-05-21 09:47:30
【问题描述】:

我希望能够允许我的包的用户以更数学的方式定义函数,我认为宏是正确的方向。问题如下。该代码允许用户定义函数,然后在专门的求解器中使用这些函数来求解 PDE。但是,为了使求解器更容易,一些输入是以您通常不会认为的方式的“矩阵”。例如,求解器可以接收函数 f(x,t),但 x[:,1] 是您认为的 xx[:,2] 是您认为的 y(有时是 3D) .

更大的问题是,当 PDE 是非线性的时,我将所有内容都放在一个 u 向量中,而在许多情况下(例如反应扩散方程)这些东西都被命名了。所以在这种一般情况下,我希望能够写

@mathdefine f(RA,RABP,RAR,x,y,t) = RA*RABP + RA*x + RAR*t

然后翻译成

f(u,x,t) = u[:,1].*u[:,2] + u[:,1].*x[:,1] + u[:,3]*t

我无法对我的宏 foo 嗤之以鼻,所以我希望有人能让我开始(或者如果宏不是解决这个问题的正确方法,请解释原因)。

如果用户必须将要翻译的内容提供给什么,这并不太难,但我希望它尽可能干净易用,所以不知何故知道它是空间变量,所以之前的一切都是u 的一部分,但之后是 x 的一部分。

【问题讨论】:

    标签: macros metaprogramming julia


    【解决方案1】:

    宏“查找/替换”的技巧只是将处理传递给更新表达式 args 的递归函数。您的签名将作为一堆符号出现,因此您可以循环调用签名并添加到两个字典,将变量名称映射到列索引。然后当您看到任何变量时递归替换 arg 树。这是未经测试的:

    function replace_vars!(expr::Expr, xd::Dict{Symbol,Int}, ud::Dict{Symbol,Int})
      for (i,arg) in enumerate(expr.args)
        if haskey(xd, arg)
          expr.arg[i] = :(x[:,$(xd[arg])])
        elseif haskey(ud, arg)
          expr.arg[i] = :(u[:,$(ud[arg])])
        elseif isa(arg,Expr)
          replace_vars!(arg, xd, ud)
        end
      end
    end
    
    macro mathdefine(expr)
      # todo: loop through function signature (expr.args[1]?) to build xd/ud
      replace_vars!(expr)
      expr
    end
    

    我给你留了一点作业,但这应该可以帮助你开始。

    【讨论】:

      猜你喜欢
      • 2019-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 2019-12-02
      • 1970-01-01
      相关资源
      最近更新 更多