2017-03-25 41 views
1

我剛開始接觸的Haskell Haskell的數據類型,我已讀了LYAH的定義數據類型的部分,我試圖實現對信仰傳播和積算法。其中一項基本任務是定義概率圖形模型。爲HMATRIX向量和矩陣

如下所示,我已經嘗試通過綁結來表示,其中每個節點代表一個高斯分佈,並且具有恆重鏈接(現在)的圖表將它的鄰居來創建的曲線圖。然而,當試圖定義均值和協方差類型時,我在指定矩陣和矢量類型的類型時遇到了一些困難,即浮點或雙精度。

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類型的向量和協方差類型爲Double類型的Matrix的語法是什麼。此外,如何推廣MeanCovariance可以是浮點型還是雙精度型?

我目前得到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. 

我用HMATRIX包描述here

回答

2

VectorMatrix的參數化標量型(這樣你不僅可以有浮動的矩陣點「實數」,還包括整數矩陣,複數等)。這是由GHC ‘Vector’ has kind ‘* -> *’告訴你:本身Vector不是一個類型(類型有一種*,又名Type)。相反,它是一個型功能映射類型的種類*到類型的種類*。像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標籤,並保持邊緣單獨的結構。

+0

多麼美妙的答案;謝謝!這已經爲我清除了一些東西。我對打結和無意造成無限的結構有一些懷疑。另一種方式(保持鄰接矩陣等)看起來很不雅觀。 –