2015-04-22 61 views
3

儘可能簡單,只要我需要在Haskell上使用矩陣,我就會掙扎。我的策略是選擇具體類型(REPA,Vector,List,IntMap等)併爲其編程。例如,我用REPA來解決歐拉的problem 11,我經常在馬拉松上使用它。不幸的是,REPA並不是一個特別友好的API--它需要複雜的類型註釋,考慮表示並跟蹤它,並將其轉換......還有,索引被逆轉。所有這些意味着我花了大量的時間只是看着文檔,並嘗試正確地對齊類型,這在你參加馬拉松比賽時是致命的。在Haskell上編程矩陣的語言學方法是什麼?

我可以使用矢量/列表,但這也是很尷尬,因爲那時我需要使用toIndex :: [Int] → Int; fromIndex Int → [Int]函數,每次我索引矢量。

我也嘗試創建Data.Vector的包裝,如data Matrix a = Matrix { shape :: [a], buffer :: Vector a },但很快我注意到我還必須爲每個單獨的矢量函數創建一個包裝,並且使用不同的類型來匹配可變的矢量等等,一團糟。

最後,我需要的是一個簡單的方法來處理矩陣 - 類似:

matrix = Matrix.fromList [3,3] [1,2,3,4,5,6,7,8,9] 
main = do 
    matrix' <- set matrix [1,1] 0 
    print $ get matrix [1,1] 
    print $ sum matrix 

或其他任何東西,讓我想想矩陣作爲數學對象,而不是一個具體的實現,但我沒有找到一種簡單的語言學方法。你會怎麼做?我不知道鏡頭能不能幫助嗎?

+0

[linear](https://hackage.haskell.org/package/linear-1.18.0.1/docs/Linear-Matrix.html)包中有一些通用的矩陣運算,用少數的泛型類型類,但是我不能很好地解釋它是如何工作的。 –

+1

如果你想要一個簡單的「Haskell中的Matlab」包,請嘗試[hmatrix](http://hackage.haskell.org/package/hmatrix) - 它有一個相當全面和易於理解的API。 –

回答

4
  • 你是說,真的只是矩陣(即有兩個索引維的數組)?那麼hmatrix可能是最適合你的。它的矩陣類型與你的Vector包裝器有點不同,它的界面真的很像「純功能性的Matlab 」(我個人無法遵守的哲學,但是很好......)無論如何,代數運算,切片等通過底層GSL例程。請注意,這個庫並沒有真正做有狀態的東西,它保留了一個純粹的功能接口,並依賴於內置例程的優化。

  • 你的意思是說,一般的多維數組/張量對元素操作而不是線性代數更感興趣,並且需要有狀態更新?然後好的舊array圖書館可能是正確的。在過去的幾年中,似乎已經被vectorrepa黯然失色,但IMO,Data.Ix索引模式實際上相當不錯。排序不太成熟,但也更少「過度工程」版本repa

  • 如果你實際上大多是感興趣的線性代數,那麼你至少應該檢查一些更抽象的庫。我非常喜歡vector-space界面,這是非常一般的和數學的,它完全避免了在特定基礎上的書寫操作,這對於捕捉「數學錯誤」確實有很大幫助。

  • 雖然你提到lens es,有linear –這是優雅和抽象的不同方式。國際海事組織(IMO)錯過了線性化的一點(數學),但它仍然非常酷,並且絕對提供比vector-space更多的操作。

  • 哦,最後還有matrix。它與hmatrix非常相似,但在本機Haskell中實現而不是在GSL綁定中實現,這意味着它在高度優化的LA算法中並不豐富,但也不是那麼重的依賴。除此之外,它似乎稍微更優雅。

+0

我真的只想要一個N維**方便的**數據結構。也就是說,我可以創建一個三維地圖,複製/粘貼塊,修改有界卷,壓縮,映射,過濾器等。REPA非常快,但使用起來很麻煩。陣列也非常糟糕。例如,我不能使用線性矢量來索引這些數組。這太糟糕了......我不認爲這些答案中有任何答案。 :( – MaiaVictor

+0

嗯,或許你不應該要求_matrices_然後......無論如何,我認爲'array'對於你的應用來說是非常正確的事情,尤其是你可以使用線性''' V'類型來索引它們,因爲它們有一個'Ix'實例。你在那裏有什麼問題? – leftaroundabout

+0

不知道如何用V創建多維數組並使用V3索引它們例如 – MaiaVictor