我正在计算一些形式为
的递归表达式
现在,假设我有一个索引列表 t,u,v ([t,u,v]::Int)
为简单起见,我们可以将其表示为[[Int]]
,并且我想计算每个索引[t,u,v]
的 R 函数使用类似于以下代码的内容:
import qualified Data.Vector.Unboxed as U
import qualified Data.Map.Strict as M
data HermiteStateIntegral = HermiteStateIntegral {
getmapI :: M.Map [Int] Double
,getkeyI :: [[Int]]
} deriving Show
calcIntegrals :: [Double] ->[[Int]] -> Double -> Vector Double
calcIntegrals vs listIndex f0 = U.unfoldr (calcRecExpr vs) seedI
seedI = HermiteStateIntegral mapI0 listIndex
mapI0 = M.insert [0,0,0] f0 M.empty
calcRecExpr :: [Double] -> HermiteStateIntegral -> Maybe (Double,HermiteStateIntegral)
calcRecExpr vs hs@(HermiteStateIntegral m is)= do
i <- safeHead is -- safeHead :: [a] -> Maybe a
-- if the value associated with the indexes t,u,v is not in the map
-- calculate it using the recursive equations
let Just (val,newMap) = (lookupM i m) `mplus` (fun vs i m)
newSt = hs{getmapI = newMap,getkeyI = tail is}
return (val,newSt)
where lookupM :: Ord k => k -> M.Map k a -> Maybe (a , M.Map k a)
lookupM k m = do
val <- M.lookup k m
return (val,m)
fun :: [Double] -> [Int] -> M.Map [Int] Double -> Maybe (Double, M.Map [Int] Double)
fun vs i m = -- fun computes the value associated with some index [t,u,v]
-- that is not in the Map, using the recursive equations. And
-- insert this value on the Map.
所以,我使用Map
来明确存储 R 子表达式。如果我想计算例如索引[1,1,1],Map将存储我可以使用的索引[0,1,1],[0,0,1],[0,0,0]未来的计算。
我的问题是:这是明确缓存 R 子表达式的有效实现吗?是否有更有效的方式来表达使用延迟评估的记忆?