【问题标题】:Automatic differentiation with unboxed vectors使用未装箱向量进行自动微分
【发布时间】:2014-03-27 17:23:41
【问题描述】:

是否有适用于未装箱向量的自动微分 Haskell 库?来自Numeric.ADgrad 函数需要Traversable 的实例,而Data.Vector.Unboxed 不需要。

【问题讨论】:

  • grad 不需要进行太多更改即可使其适用于未装箱的向量。您必须从Numeric.AD.Internal.Var 重新实现bindunbindVariable 类型未拆箱,但您可以将其替换为元组。 (我现在不能尝试,因为ad 不是基于 GHC 7.8)
  • @SjoerdVisscher 我认为您的评论足以很好地回答这个问题?

标签: haskell vector unboxing


【解决方案1】:

我不知道为什么成对的向量被存储为成对的向量,但是您可以轻松地为您的数据类型编写实例来顺序存储元素。

{-# LANGUAGE TypeFamilies, MultiParamTypeClasses #-}

import qualified Data.Vector.Generic as G 
import qualified Data.Vector.Generic.Mutable as M 
import Control.Monad (liftM, zipWithM_)
import Data.Vector.Unboxed.Base

data Point3D = Point3D {-# UNPACK #-} !Int {-# UNPACK #-} !Int {-# UNPACK #-} !Int

newtype instance MVector s Point3D = MV_Point3D (MVector s Int)
newtype instance Vector    Point3D = V_Point3D  (Vector    Int)
instance Unbox Point3D

此时最后一行将导致错误,因为没有针对 Point3D 的矢量类型的实例。它们可以写成:

instance M.MVector MVector Point3D where 
  basicLength (MV_Point3D v) = M.basicLength v `div` 3 
  basicUnsafeSlice a b (MV_Point3D v) = MV_Point3D $ M.basicUnsafeSlice (a*3) (b*3) v 
  basicOverlaps (MV_Point3D v0) (MV_Point3D v1) = M.basicOverlaps v0 v1 
  basicUnsafeNew n = liftM MV_Point3D (M.basicUnsafeNew (3*n))
  basicUnsafeRead (MV_Point3D v) n = do 
    [a,b,c] <- mapM (M.basicUnsafeRead v) [3*n,3*n+1,3*n+2]
    return $ Point3D a b c 
  basicUnsafeWrite (MV_Point3D v) n (Point3D a b c) = zipWithM_ (M.basicUnsafeWrite v) [3*n,3*n+1,3*n+2] [a,b,c]

instance G.Vector Vector Point3D where 
  basicUnsafeFreeze (MV_Point3D v) = liftM V_Point3D (G.basicUnsafeFreeze v)
  basicUnsafeThaw (V_Point3D v) = liftM MV_Point3D (G.basicUnsafeThaw v)
  basicLength (V_Point3D v) = G.basicLength v `div` 3
  basicUnsafeSlice a b (V_Point3D v) = V_Point3D $ G.basicUnsafeSlice (a*3) (b*3) v 
  basicUnsafeIndexM (V_Point3D v) n = do 
    [a,b,c] <- mapM (G.basicUnsafeIndexM v) [3*n,3*n+1,3*n+2]
    return $ Point3D a b c 

我认为大多数函数定义都是不言自明的。点的向量存储为 Ints 的向量,第 n 个点是 3n,3n+1,3n+2 个 Ints。

【讨论】:

  • a b 返回一个从第 a 个元素开始到第 b 个元素结束的向量。第n个元素的开始是3*n;结尾是 3*n+2。 2)您从不使用这些函数,但它们用于在未装箱的向量上定义所有其他函数,因此这些是您需要定义的所有函数才能在未装箱的向量上使用任何函数。 3)您的“点”类型应包含 n 个相同类型的元素。这适用于数据 Point3D a = P3d {-# UNPACK #-} !a {-# UNPACK #-} !a {-# UNPACK #-} !a 和新类型实例 MVector s (Point3D a) = MV_Point3D (MVector s a )
猜你喜欢
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多