Guest User

Untitled

a guest
Jan 21st, 2018
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.98 KB | None | 0 0
  1.  
  2. import Data.IntMap (IntMap)
  3. import qualified Data.IntMap as IntMap
  4. import Data.List (transpose)
  5. import Control.Monad (zipWithM_)
  6.  
  7. newtype Vector a = Vector { unVector :: IntMap a }
  8.  
  9. vector :: Num a => IntMap a -> Vector a
  10. vector = Vector
  11.  
  12. newtype Vector1 a = Vector1 { unVector1 :: Int }
  13.  
  14. vector1 :: Num a => Int -> Vector1 a
  15. vector1 = Vector1
  16.  
  17. class VectorLike v where
  18. toVector :: Num a => v a -> Vector a
  19.  
  20. instance VectorLike Vector where
  21. toVector = id
  22.  
  23. instance VectorLike Vector1 where
  24. toVector (Vector1 p) = Vector (IntMap.singleton p 1)
  25.  
  26. instance Functor Vector where
  27. fmap f = Vector . IntMap.map f . unVector
  28.  
  29. unVector' :: (Num a, VectorLike v) => v a -> IntMap a
  30. unVector' = unVector . toVector
  31.  
  32. (<+>) :: (Num a, VectorLike v1, VectorLike v2) => v1 a -> v2 a -> Vector a
  33. a <+> b = Vector $ IntMap.unionWith (+) (unVector' a) (unVector' b)
  34.  
  35. (<->) :: (Num a, VectorLike v1, VectorLike v2) => v1 a -> v2 a -> Vector a
  36. a <-> b = a <+> fmap negate (toVector b)
  37.  
  38. (*>) :: (Num a, VectorLike v) => v a -> a -> Vector a
  39. a *> b = fmap (*b) (toVector a)
  40.  
  41. (<*) :: (Num a, VectorLike v) => a -> v a -> Vector a
  42. a <* b = fmap (a*) (toVector b)
  43.  
  44. infixl 6 <+>,<->
  45. infixl 7 *>
  46. infixr 7 <*
  47.  
  48. emptyVector :: Num a => Vector a
  49. emptyVector = Vector IntMap.empty
  50.  
  51.  
  52.  
  53.  
  54.  
  55. data Matrix a = Matrix { unMatrix :: [[a]] }
  56. | Diagonal { unDiagonal :: [a] }
  57. deriving (Show, Eq)
  58.  
  59. toMatrix :: Num a => Matrix a -> Matrix a
  60. toMatrix (Matrix a) = Matrix a
  61. toMatrix (Diagonal a) = Matrix [replicate i 0 ++ [aii] ++ repeat 0 | (i, aii) <- zip [0..] a]
  62.  
  63. unMatrix' :: Num a => Matrix a -> [[a]]
  64. unMatrix' = unMatrix . toMatrix
  65.  
  66. matrix :: [[a]] -> Matrix a
  67. matrix = Matrix
  68.  
  69. diagonal :: [a] -> Matrix a
  70. diagonal = Diagonal
  71.  
  72. instance Num a => Num (Matrix a) where
  73. Diagonal a + Diagonal b = diagonal (zipWith (+) a b)
  74. a + b = matrix (zipWith (zipWith (+)) (unMatrix' a) (unMatrix' b))
  75.  
  76. negate (Matrix a) = matrix (map (map negate) a)
  77. negate (Diagonal a) = diagonal (map negate a)
  78.  
  79. fromInteger = diagonal . repeat . fromInteger
  80.  
  81. Matrix a * Matrix b = let tb = transpose b
  82. c = [[sum (zipWith (*) ra cb) | cb <- tb] | ra <- a]
  83. in
  84. matrix c
  85. Diagonal a * Diagonal b = diagonal (zipWith (*) a b)
  86. Diagonal a * Matrix b = matrix (zipWith (\v row -> map (v*) row) a b)
  87. Matrix a * Diagonal b = matrix (map (\row -> zipWith (*) row b) a)
  88.  
  89. abs = error "Matrix: abs undefined"
  90. signum = error "Matrix: abs undefined"
  91.  
  92.  
  93.  
  94.  
  95.  
  96. data LRVariable a = LRV { initialValue :: a, dependency :: Vector a }
  97.  
  98. dmap :: Num a => (Vector a -> Vector a) -> LRVariable a -> LRVariable a
  99. dmap f (LRV val dep) = LRV val (f dep)
  100.  
  101. type LRVariables a = IntMap (LRVariable a)
  102.  
  103. data LinearRecursive a b = LR { unLR :: Int -> (b, Int, LRVariables a -> LRVariables a) }
  104.  
  105. instance Num a => Monad (LinearRecursive a) where
  106. return a = LR (const (a, 0, id))
  107. a >>= b = LR $ \v -> let (ra, nva, ma) = unLR a v
  108. (rb, nvb, mb) = unLR (b ra) (v + nva)
  109. in
  110. (rb, nva + nvb, mb . ma)
  111.  
  112. newVariable :: Num a => a -> LinearRecursive a (Vector1 a)
  113. newVariable val0 = LR $ \v -> (vector1 v, 1, IntMap.insert v variable)
  114. where
  115. variable = LRV { initialValue = val0, dependency = emptyVector }
  116.  
  117. newVariables :: Num a => [a] -> LinearRecursive a [Vector1 a]
  118. newVariables vals = do
  119. ret <- mapM newVariable vals
  120. zipWithM_ (<:-) (tail ret) ret
  121. return ret
  122.  
  123. newConstant :: Num a => a -> LinearRecursive a (Vector a)
  124. newConstant val = do
  125. ret <- newVariable val
  126. ret <:- ret
  127. return (toVector ret)
  128.  
  129. (<+-) :: (Num a, VectorLike v) => Vector1 a -> v a -> LinearRecursive a ()
  130. (<+-) var dep = LR (const ((), 0, IntMap.adjust (dmap (<+>toVector dep)) (unVector1 var)))
  131.  
  132. (<:-) :: (Num a, VectorLike v) => Vector1 a -> v a -> LinearRecursive a ()
  133. (<:-) var dep = LR (const ((), 0, IntMap.adjust (dmap (const (toVector dep))) (unVector1 var)))
  134.  
  135. infix 1 <:-,<+-
  136.  
  137. buildMatrix :: Num a => LRVariables a -> (Matrix a, Matrix a)
  138. buildMatrix mapping = (Matrix trans, Matrix $ map (\x -> [x]) initValues)
  139. where
  140. initValues = map initialValue (IntMap.elems mapping)
  141. rawDep = map (unVector'.dependency) (IntMap.elems mapping)
  142. varCount = length initValues
  143. trans = map (\m -> [IntMap.findWithDefault 0 i m | i <- [0..varCount-1]]) rawDep
  144.  
  145. runLinearRecursive :: (Num a, Integral b, VectorLike v) => LinearRecursive a (v a) -> b -> a
  146. runLinearRecursive monad steps = sum [head (res !! i) * ai | (i, ai) <- IntMap.assocs (unVector' target)]
  147. where
  148. (target, nv, g) = unLR monad 0
  149. dep = g IntMap.empty
  150. (trans, init) = buildMatrix dep
  151.  
  152. Matrix res = trans^steps * init
  153.  
  154. fib = do
  155. a <- newVariable 1
  156. b <- newVariable 1
  157. a <:- b
  158. b <:- a <+> b
  159. return a
  160.  
  161. fib2 = do
  162. [f0,f1] <- newVariables [1, 1]
  163. f0 <:- f0 <+> f1
  164. return f1
  165.  
  166. a004146 = do
  167. two <- newConstant 2
  168. [a0, a1] <- newVariables [1, 0]
  169. a0 <:- a0 *> 3 <-> a1 <+> two
  170. return a1
  171.  
  172. main = print $ map (runLinearRecursive fib2) [0..10]
Add Comment
Please, Sign In to add comment