假设我想使用有限差分法为看涨期权定价并重新计算,那么下面的工作就完成了:
import Data.Array.Repa as Repa
r, sigma, k, t, xMax, deltaX, deltaT :: Double
m, n, p :: Int
r = 0.05
sigma = 0.2
k = 50.0
t = 3.0
m = 3
p = 1
xMax = 150
deltaX = xMax / (fromIntegral m)
n = 800
deltaT = t / (fromIntegral n)
singleUpdater a = traverse a id f
where
Z :. m = extent a
f _get (Z :. ix) | ix == 0 = 0.0
f _get (Z :. ix) | ix == m-1 = xMax - k
f get (Z :. ix) = a * get (Z :. ix-1) +
b * get (Z :. ix) +
c * get (Z :. ix+1)
where
a = deltaT * (sigma^2 * (fromIntegral ix)^2 - r * (fromIntegral ix)) / 2
b = 1 - deltaT * (r + sigma^2 * (fromIntegral ix)^2)
c = deltaT * (sigma^2 * (fromIntegral ix)^2 + r * (fromIntegral ix)) / 2
priceAtT :: Array U DIM1 Double
priceAtT = fromListUnboxed (Z :. m+1) [max 0 (deltaX * (fromIntegral j) - k) | j <- [0..m]]
testSingle :: IO (Array U DIM1 Double)
testSingle = computeP $ singleUpdater priceAtT
但现在假设我想并行定价期权(比如做一个现货阶梯),那么我可以这样做:
multiUpdater a = fromFunction (extent a) f
where
f :: DIM2 -> Double
f (Z :. ix :. jx) = (singleUpdater x)!(Z :. ix)
where
x :: Array D DIM1 Double
x = slice a (Any :. jx)
priceAtTMulti :: Array U DIM2 Double
priceAtTMulti = fromListUnboxed (Z :. m+1 :. p+1)
[max 0 (deltaX * (fromIntegral j) - k) | j <- [0..m], _l <- [0..p]]
testMulti :: IO (Array U DIM2 Double)
testMulti = computeP $ multiUpdater priceAtTMulti
问题:
- 在 repa 中是否有更惯用的方式来做到这一点?
- 上述方法实际上会并行定价吗?
- 如何确定我的代码是否真的在生成将并行执行的东西?
我尝试了 3 次,但遗憾的是在 ghc 中遇到了一个错误:
bash-3.2$ ghc -fext-core --make Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
ghc: panic! (the 'impossible' happened)
(GHC version 7.4.1 for x86_64-apple-darwin):
MkExternalCore died: make_lit