Julia 中函数的抽象类型和多次调度
Posted
技术标签:
【中文标题】Julia 中函数的抽象类型和多次调度【英文标题】:Abstract typing and multiple dispatch for functions in julia 【发布时间】:2020-11-27 07:36:39 【问题描述】:我想让对象根据它们的类型与特定的交互进行交互。
示例问题:我有四个粒子,两个是A型,两个是B型。当A型交互时我想使用函数
function interaction(parm1, parm2)
return parm1 + parm2
end
当B型交互时我想使用该功能
function interaction(parm1, parm2)
return parm1 * parm2
end
当类型 A 与类型 B 交互时我想使用函数
function interaction(parm1, parm2)
return parm1 - parm2
end
这些函数故意过于简单。
我想计算一个依赖于成对交互的简单求和:
struct part
parm::Float64
end
# part I need help with:
# initialize a list of length 4, where the entries are `struct part`, and the abstract types
# are `typeA` for the first two and `typeB` for the second two. The values for the parm can be
# -1.0,3, 4, 1.5 respectively
energy = 0.0
for i in range(length(particles)-1)
for j = i+1:length(particles)
energy += interaction(particles[i].parm, particles[j].parm)
end
end
println(energy)
假设使用的参数为particle[1].parm = -1
、particle[2].parm = 3
、particle[3].parm = 4
、particle[4].parm = 1.5
,则能量应考虑到相互作用
(1,2) = -1 + 3 = 2
(1,3) = -1 - 4 = -5
(1,4) = -1 - 1.5 = -2.5
(2,3) = 3 - 4 = -1
(2,4) = 3 - 1.5 = 1.5
(3,4) = 4 * 1.5 = 6
energy = 1
使用if statements
执行此操作几乎是微不足道的,但不可扩展。我追求干净、整洁的 Julia 方法......
【问题讨论】:
【参考方案1】:您可以这样做(我使用最简单的实现形式,因为在这种情况下就足够了,而且我希望发生的事情很明确):
struct A
parm::Float64
end
struct B
parm::Float64
end
interaction(p1::A, p2::A) = p1.parm + p2.parm
interaction(p1::B, p2::B) = p1.parm * p2.parm
interaction(p1::A, p2::B) = p1.parm - p2.parm
interaction(p1::B, p2::A) = p1.parm - p2.parm # I added this rule, but you can leave it out and get MethodError if such case happens
function total_energy(particles)
energy = 0.0
for i in 1:length(particles)-1
for j = i+1:length(particles)
energy += interaction(particles[i], particles[j])
end
end
return energy
end
particles = UnionA, B[A(-1), A(3), B(4), B(1.5)] # Union makes sure things are compiled to be fast
total_energy(particles)
【讨论】:
【参考方案2】:我不知道如何在您的语言中执行此操作,但您需要的是类似于我们在面向对象编程中所谓的策略模式。策略是一种可插入、可重用的算法。在 Java 中,我会创建一个类似的接口:
interface Interaction<A, B>
double interact(A a, B b)
然后执行此操作 3 次,并在需要交互的任何地方重复使用这些部分。另一种方法可以在不知道如何实现的情况下进行交互并使用它。我想这就是你想要的效果。对不起,我不知道如何翻译成你的方言。
【讨论】:
这个答案从根本上说是糟糕的,一些多重调度是 Julia 的一个特性,如果 4 种“设计模式”的憎恶团伙几乎已经过时了。 呃,多分派并不是万灵药,原因有很多。 也许不是全部,但令人惊讶的是很多:youtube.com/watch?v=kc9HwsxE1OY。其余的,我猜,被高阶函数覆盖了:) 好吧。您可以在图灵机中实现一切。在我看来,问题是“什么是适合这项工作的工具?” 多次调度绝对是解决这种特殊模式的方法。但是,用没有多次分派的语言来演示这是多么尴尬,这当然很有趣。以上是关于Julia 中函数的抽象类型和多次调度的主要内容,如果未能解决你的问题,请参考以下文章