Julia中具有函数字段的不可变类型

时间:2016-01-17 17:55:30

标签: math types julia

据我了解,功能设计用于操作类型而不是属于它们,但显然我可以执行以下操作:

immutable Sphere
    dimension::Int
    metric::Function
end

sphere = Sphere(2, (x1, x2)->dot(x1, x2))

然后我可以从类型中调用此函数:

sphere.metric([1,2],[2,3])

朱莉娅这是不好的做法吗?将其定义为immutable使我无法改变其维度,但假设我对此有所了解,它也使我无法更改度量标准,这模仿了无法在传统OOP中更改对象内部的那些方法。

这是因为我正在努力寻找在朱莉娅开发Riemmanian流形的正确方法。例如,我说我有以下代码:

abstract Manifold

immutable Sphere <: Manifold
    dimension::Int
end

immutable Torus <: Manifold
    dimension::Int
end

metrc(M::Sphere, x1, x2) = ...
metric(M::Torus, x1, x2) = ...

现在如果我想在我的球体歧管上添加不同的度量标准怎么办?使用多次调度似乎不是一个好方法。此外,从概念上讲,黎曼度量通常被认为是流形结构的一部分,因此把它看作一个以多方面为参数的函数似乎是错误的,特别是考虑到你可以放同一歧管上的许多不同指标。

更好的方法似乎是在我的原始示例中执行此操作,其中我可以使用特定度量实例化具有特定维度的不可变类型的球体流形。如果我想要一个具有不同维度和不同度量的新球体流形,那么我可以实例化它。

我想我要问的是,是否有更好的方法来构造对其点和切向量进行操作的流形和函数?我可以完全放弃定义它们,而是直接直接处理点类型和切线向量类型,这将更紧密地遵循Julia范式,并且有关于它的帖子here,但它变得非常毛茸茸。

2 个答案:

答案 0 :(得分:1)

在Julia中使用复合类型中的函数类型字段来模拟成员函数(在may OO语言中使用)是不好的做法。

但是,据我了解您的用例,该指标实际上被视为select item_id, cost, price, sum(quantity) from table group by item_id, cost, price 类型中的另一个字段,而不是成员函数。那么我就不会说这是不好的做法。

然后是效率问题。现在,将度量函数存储在字段中意味着编译器几乎不知道在运行时调用哪个函数,在每次调用时会产生相当多的开销。最终(在Julia 0.5?中)可以对要存储的函数的Sphere类型进行参数化,与其他解决方案相比,这可以恢复效率。

答案 1 :(得分:0)

这是一个很老的话题,但我们在 Manifolds.jl 中设计流形时遇到了类似的问题(实际上完全相同),我们选择了我称之为“一开始懒惰”的东西。

因此,正如您对 \ 类型所做的那样,您将实现内积(也称为黎曼度量,但它并不是在每个点都更像度量张量的度量)。这为任何用户实现自己的流形提供了一个良好的开端,并为流形(将其视为一个集合)提供了第一个(也是一种默认)指标。

然后我们设计了一个 Sphere <: Manifold,它将流形(再次作为一个集合)与一个不同的度量耦合,例如参见 SPD 上的线性仿射度量 (https://juliamanifolds.github.io/Manifolds.jl/stable/manifolds/symmetricpositivedefinite.html#Manifolds.LinearAffineMetric),这是默认的和日志 cholesky 指标 (https://juliamanifolds.github.io/Manifolds.jl/stable/manifolds/symmetricpositivedefinite.html#log-Cholesky-metric),这不是其默认指标

所以 MetricManifold{Manifold,Metric}SymmetricPositiveDefinite(n) 相同,要获得具有不同度量的流形,请使用 MetricManifold(SymmetricPositiveDefinite(3),LinearAffineMetric())。请注意,您的指标中也可以包含参数,因此甚至可以考虑一系列指标。