【发布时间】:2019-10-24 09:14:52
【问题描述】:
我有两个具体类型,分别称为 CreationOperator 和 AnnihilationOperator,我想定义一个新的具体类型,它表示一串运算符和一个乘以它的实系数。
我发现定义一个抽象类型 FermionicOperator 是很自然的,CreationOperator 和 AnnihilationOperator 都从该类型继承,即
abstract type FermionicOperator end
struct CreationOperator <: FermionicOperator
...
end
struct AnnihilationOperator <: FermionicOperator
...
end
因为我可以定义很多带有function(op1::FermionicOperator, op2::FermionicOperator) = ...类型签名的函数,比如算术运算(我正在构建一个代数系统,所以我必须在运营商)。
然后我会继续定义一个具体类型OperatorString
struct OperatorString
coef::Float64
ops::Vector{FermionicOperator}
end
但是,根据 Julia 手册,我认为 OperatorString 对性能来说并不理想,因为编译器对 FermionicOperator 一无所知,因此涉及 OperatorString 的函数将是低效的(我会有很多操作字符串的函数)。
我找到了以下解决方案,但我不确定它的含义以及它是否真的有所作为。
我没有将FermionicOperator定义为抽象类型,而是将其定义为CreationOperator和AnnihilationOperator的Union,即
struct CreationOperator
...
end
struct AnnihilationOperator
...
end
FermionicOperator = Union{CreationOperator,AnnihilationOperator}
这仍然允许function(op1::FermionicOperator, op2::FermionicOperator) = ... 形式的函数,但同时,据我了解,Union{CreationOperator,AnnihilationOperator} 是一个具体类型,因此OperatorString 是明确定义的,编译器可以优化事情,如果它是案例。
我特别怀疑,因为我还考虑使用内置的Expr 结构来定义我的运算符字符串(实际上它会更通用),其字段args 是具有抽象类型元素的向量: 与我的第一次设计尝试非常相似。然而,在Expr 上实现算术运算时,我感觉自己做错了什么,最好定义自己的类型。
【问题讨论】:
-
>
Union{CreationOperator,AnnihilationOperator}是一个具体类型。很不幸的是,不行。您可以使用isconcretetype进行检查。我认为julialang.org/blog/2018/08/union-splitting 会在一定程度上帮助你。 -
确实联合拆分是我认为编译器能够对联合进行的操作。实际上,如果它们不是具体类型的,只要可以优化结果函数,我并不在意。
标签: performance struct julia union-types abstract-type