Haskell 使用hmatrix应用元素数学函数(带矢量化)

Haskell 使用hmatrix应用元素数学函数(带矢量化),haskell,vector,vectorization,linear-algebra,hmatrix,Haskell,Vector,Vectorization,Linear Algebra,Hmatrix,我需要以一种有效的方式在Haskell中的向量元素上应用一个函数,这意味着我不是在寻找这样的东西: sigmoid :: [Float] -> [Float] sigmoid [] = [] sigmoid (z:zs) = ( 1/(1+exp (-z)) ):(sigmoid zs) 更具体地说,是否有exp、log、。。。etc用于使用Haskell的hmatrix中的元素矢量操作,类似于使用Python的numpy中的元素矢量操作?如果我没有使用向量处理功能,我的代码运行非常慢

我需要以一种有效的方式在Haskell中的向量元素上应用一个函数,这意味着我不是在寻找这样的东西:

sigmoid :: [Float] -> [Float]
sigmoid [] = []
sigmoid (z:zs) = ( 1/(1+exp (-z)) ):(sigmoid zs) 
更具体地说,是否有
exp、log、。。。etc
用于使用Haskell的hmatrix中的元素矢量操作,类似于使用Python的numpy中的元素矢量操作?如果我没有使用向量处理功能,我的代码运行非常慢

如果您使用的是hmatrix,:

类似于
fmap
(由于元素类约束,无法实现实例函子)

如果您使用的是hmatrix,则:

类似于
fmap
(由于元素类约束,无法实现实例函子)



不要将Python(或Matlab等)的性能考虑因素转换为Haskell。这些语言所称的矢量化之所以明智,是因为它们是缓慢的、动态的语言,因此在语言中的单个元素上循环的开销大于几个中间数组分配的开销。但在快速、静态编译的语言中,如Rust、C、Java以及Haskell,情况并非如此。(当然,这并不意味着仅仅使用Haskell列表是一个好主意——这引入了缓存局部性问题,这使得语言比C等慢得多。是的,还有一种矢量化总是有意义的,即大规模并行化或使用可在单个AVX指令中处理的小块并行化n、 )@leftaroundabout这就是我所说的矢量化。我希望我的Haskell代码能够利用SIMD执行。很有趣,但我不会对这种sigmoid的执行有太高的期望。AVX指令集中没有指数函数。要用SIMD真正加速类似的操作,你需要在GPU上运行它;请检查。不要这样做从Python(或Matlab等)中转换性能注意事项这些语言称之为矢量化是明智的,因为它们是缓慢的、动态的语言,因此在语言中循环单个元素的开销大于几个中间数组分配的开销。但在快速、静态编译的语言中,如Rust、C、Java和,哈斯克尔。(当然,这并不意味着仅仅使用Haskell列表是一个好主意——这引入了缓存局部性问题,这使得语言比C等慢得多。是的,还有一种矢量化总是有意义的,即大规模并行化或使用可在单个AVX指令中处理的小块并行化n、 )@leftaroundabout这就是我所说的矢量化。我希望我的Haskell代码能够利用SIMD执行。很有趣,但我不会对这种sigmoid的执行有太高的期望。AVX指令集中没有指数函数。要用SIMD真正加速这种速度,你需要在GPU上运行它;请查看。这是看起来很合理,我会在回到我的机器后尝试评估计算。我希望它不会占用与常规模式匹配相同的时间,我正在这样做是为了机器学习。那么..这是否利用SIMD,因为这是我技术上的意思?“我希望它不会占用与常规模式匹配相同的时间”--我建议您不要将注意力完全集中在模式匹配上,因为它最多只是其他任何情况的一种症状。表面上,
map(\z->1/(1+exp(-z))::[Double]->[Double]
似乎没有进行任何模式匹配,但它可以归结为您问题中基本相同的代码。真正重要的是,
[Double]
数据结构不适合您的用例。“那么……这是否利用了SIMD,因为这在技术上是我的意思?”--,但请参见。(还要注意的是,他对这类问题的了解比我多得多)。顺便说一句,像往常一样,找出某个东西是否能为您的用例提供足够好的性能的最佳方法是测试它。我测试了它,它显然比使用普通的haskell列表快得多。这似乎很合理,我会在回到我的机器后尝试评估计算。我希望它不会花费同样的时间作为规则模式匹配,我这样做是为了机器学习。那么..这是否利用了SIMD,因为这就是我技术上的意思?“我希望它不会花费与规则模式匹配相同的时间”--我建议您不要将注意力完全集中在模式匹配上,因为它最多只是其他任何情况的一种症状。表面上,
map(\z->1/(1+exp(-z))::[Double]->[Double]
似乎没有进行任何模式匹配,但它可以归结为您问题中基本相同的代码。真正重要的是,
[Double]
数据结构不适合您的用例。“那么……这是否利用了SIMD,因为这在技术上是我的意思?”--,但请参见。(还要注意的是,他对这类问题的了解要比我多得多)。顺便说一句,像往常一样,找出某个东西是否能为您的用例提供足够好的性能的最佳方法是测试它。我测试了它,它显然比使用普通的haskell列表快得多
cmap :: (Element b, Container c e) => (e -> b) -> c e -> c b
sigmoid :: Vector Double -> Vector Double
sigmoid = cmap (\z -> 1/(1+exp (-z)))