Haskell线性代数库,具有多种类型*

时间:2014-03-10 03:26:09

标签: haskell linear-algebra applicative

我想在netwire中使用线性代数库。由于netwire的类型是Applicative的实例,因此它为其类型提供NumFractional个实例,以自动liftA2相应的函数。这很好,因为你可以做一些事情,比如增加时变值,而不需要额外的努力。

我一直在使用线性,但它的函数被定义为非*类型的多态,即矩阵乘积:

(!*!) :: (Functor m, Foldable t, Additive t, Additive n, Num a)
    => m (t a) -> t (n a) -> m (n a)

这意味着,如果我没有太多错误,我无法为Additive和公司定义实例,因为实例没有合理的形式。虽然我可以写

instance Num b => Num (Wire s e m a b) where ...

没有办法写

instance Additive n => Additive (Wire s e m a (n x)) where ...

因为(Wire s e m a (n x))的类型错误(*而不是* -> *)。我见过的其他图书馆根本就没有多态性。

我想知道的是,哪种线性代数库是多态的*

我看过Vec,看起来好多了。它的矩阵乘法有

类型
(Map v v' m1 m3, Map v a b v', Transpose m2 b, Fold v a, Num v, Num a)
    => m1 -> m2 -> m3

这就是我想要的。还有其他这样的图书馆吗?

2 个答案:

答案 0 :(得分:3)

vector-space,它确实在许多方面比通过其标量参数化的库更优雅(VectorSpace将该字段替换为关联类型同义词。)

我喜欢它的部分原因是它完全不是基于免费向量空间linear,这意味着基于Foldables的签名不会任何意义上的首要任务。 (实际上,它根本没有讨论矩阵,只讨论linear mappings,这只是the morphisms of the category of vector spaces

instance (AdditiveGroup a) => AdditiveGroup (Wire a) where
  ...

instance (VectorSpace v) => VectorSpace (Wire v) where
  type Scalar (Wire v) = Scalar v  -- Or perhaps `Wire (Scalar v)`
  ...

答案 1 :(得分:1)

我做了一些其他图书馆的调查,这是我发现的:

  • hmatrix - 积极维护;类* -> *,GPL许可
  • vect - OpenGL绑定;没有积极维护;使用硬连线标量类型,因此dot之类的内容无法解除
  • Vec - 积极维护;没有正确超载(见下文);有用的辅助功能;没有OpenGL绑定
  • 线性 - 积极维护;由GLUtil和vinyl-gl支持; * -> *个班级
  • 矢量空间 - 积极维护;正确超载; OpenGL绑定,但仅适用于向量;一小时后我仍然无法弄清楚如何使用它,特别是线性映射
  • Tensor - 内置于OpenGL中;没有数学函数
  • 床和早餐 - 积极维护;使用未装箱的数组;在值类型上使用类型族,因此它可能会重载但看起来很奇怪(即Matrix (Wire s e m a Double)是一个携带基质的电线);没有OpenGL接口

除了Vec,矢量空间和住宿加早餐外,它们除外。不稳定的类型消除了床和早餐(不幸的是,因为它不是很好)。最后,Vec最终在矢量空间上获得了一点点,因为它似乎是为图形而不是抽象代数研究而设计的。而且因为我似乎无法弄清楚如何使用线性地图进行透视变换。

我将不得不编写一个OpenGL接口(因为它已经Storable,所以不应该太糟糕)。唯一的缺点是我无法想到一个合理的类型类依赖于维度的参数/辅助函数的结果(即rotationX :: Floating a => a -> Mat44 a)。这是我用Vec输掉的向量空间的优势之一。

更新:Vec不起作用。这些类不仅适用于结果类型,它们也适用于放入向量的类型。例如,Fold类。

最终更新:我最终放弃了这个想法并为Wire创建了单独的函数。