Hmatrix Vector和Matrix的Haskell数据类型

时间:2017-03-25 14:08:51

标签: haskell graph functional-programming ghci

我刚刚开始使用Haskell,我已阅读了LYAH的定义数据类型部分,并尝试实现信念传播的Sum-Product算法。其中一项基本任务是定义概率图形模型。

如下图所示,我试图通过打结来创建图形来表示图形,其中每个节点代表高斯分布并且具有恒定的权重链接(现在)到它的邻居。但是,在尝试定义Mean和Covariance类型时,我在指定Matrix和Vector类型的类型时遇到了一些困难,即Float或Double。

module Graph(Graph) where

import Numeric.LinearAlgebra

data Mean = Mean Vector
data Covariance = Covariance Matrix
data Gaussian = Gaussian Mean Covariance

data Node = Node [Node] Gaussian
data Graph = Graph [Node]

在这个简单的例子中,将Mean定义为Double和Covariance类型的Vector作为Double类型的矩阵的语法是什么。另外,如何推广MeanCovariance可以是Float或Double类型?

我目前从GHCi

获得以下内容
Graph.hs:5:18: error:
    • Expecting one more argument to ‘Vector’
      Expected a type, but ‘Vector’ has kind ‘* -> *’
    • In the type ‘Vector’
      In the definition of data constructor ‘Mean’
      In the data declaration for ‘Mean’
Failed, modules loaded: none.

我正在使用h {here

所述的hmatrix包

1 个答案:

答案 0 :(得分:2)

VectorMatrix在标量类型上进行参数化(因此您不仅可以使用浮点数“实数”矩阵,还可以使用整数矩阵,复数等矩阵)。这就是GHC通过‘Vector’ has kind ‘* -> *’告诉您的内容:Vector本身不是一种类型(类型有种*,又名Type)。而是{em>类型函数将类型*的类型映射到类型*的类型。像Double这样的标量已经是普通类型,因此您只需将Vector应用于它们。

GHCi> :kind Vector
Vector :: * -> *
GHCi> :k Double
Double :: *
GHCi> :k Vector Double
Vector Double :: *

因此你需要

newtype Mean = Mean (Vector Double)
newtype Covariance = Covariance (Matrix Double)

newtype在这里与data做同样的事情,但它更有效率,因为不需要额外的框/指针。)

或者,您可以使用更有意义类型的向量空间,例如

import Math.LinearMap.Category

newtype Mean v = Mean v
newtype Covariance v = Covariance (v +> DualVector v)

这样做的好处是在编译时检查维度,这可以防止恶劣的运行时错误(原则上也可以提高性能,但坦率地说linearmap-category库还没有优化)。

然后,您还可以在向量空间中参数化其他类型:

data Gaußian v = Gaußian (Mean v) (Covariance v)
data Node v = Node [Node v] (Gaussian v)
data Graph v = Graph [Node v]

与你的问题有点无关:这种打结确实很优雅,但它并不是一种表示图形的合适方式,因为节点无法进行身份检查。对于所有可区分的手段,图中的任何循环都会导致无限结构。在实践中,你不会绕过给你的节点,例如Int标记并为边缘保留单独的结构。