Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to do recursive definitions with unboxed vectors?

I would like to generate an unboxed vector recursively. As a simple example:

import qualified Data.Vector as V

fib :: V.Vector Int
fib = V.generate 10 f
  where
    f 0 = 0
    f 1 = 1
    f x = (fib V.! (x - 1)) + (fib V.! (x - 2))

the function correctly generates the fibonacci sequence. However, if I use Data.Vector.Unboxed instead, the code will hang. I understand the reason why this is, but I'd still like to be able to do a recursive definition and get the speed of an unboxed vector. Are there any possibilities in doing this?

like image 745
rityzmon Avatar asked Dec 11 '22 16:12

rityzmon


1 Answers

One possibility is to use an unboxed mutable vector and freeze it once done with construction:

import Control.Monad.ST (runST)
import Control.Monad (forM_, ap)
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as M

fib :: Int -> U.Vector Int
fib s = runST $ M.new s >>= ap ((>>) . forM_ [0..s - 1] . f) U.unsafeFreeze
    where
    f v 0 = M.write v 0 0
    f v 1 = M.write v 1 1
    f v i = do
        a <- M.read v (i - 1)
        b <- M.read v (i - 2)
        M.write v i (a + b)
like image 108
behzad.nouri Avatar answered Feb 16 '23 00:02

behzad.nouri