On Tue, Jan 13, 2009 at 5:29 PM, Phil <pbeadl...@mail2web.com> wrote:
> Many thanks for the replies.
>
> Using 'modify' cleans the syntax up nicely.
>
> With regard to using 'iterate' as shown by David here:
>
>>> mcSimulate :: Double -> Double -> Word64 -> [Double]
>>> mcSimulate startStock endTime seedForSeed = fst expiryStock : mcSimulate
>>> startStock endTime newSeedForSeed
>>>  where
>>>    expiryStock = iterate evolveUnderlying (startStock, ranq1Init 
>>> seedForSeed)
>>> !! truncate (endTime/timeStep)
>>>    newSeedForSeed = seedForSeed + 246524
>
> My only concern with using this method is - Will 'iterate' not create a full
> list of type [Double] and then take the final position once the list has
> been fully realized?

iterate creates the elements of the list as they are requested, and !!
will discard everything until it hits the answer it wants. That being
said, it's not the best way to repeatedly apply a function, as Luke
pointed out. A better way would probably be something like this,

    applyNTimes :: Int -> (a -> a) -> a -> a
    applyNTimes n f a
        | n <= 0    = a
        | otherwise = applyNTimes (n-1) $! f a

That ($!) is there to make sure "f a" gets evaluated before calling
applyNTimes again.

> The key reason for using the Monad was to tell Haskell to discard all but
> the current state.  If I'm wrong about please let me know, as I don't want
> to be guilty of overcomplicating my algorithm, and more importantly it means
> I'm not yet totally grasping the power of Haskell!

I'm not entirely sure what you mean by "discard all but the current
state", but Haskell implementations are pretty good about discarding
values that are no longer needed.

That being said, here's one way I might implement your algorithm. It's
a sketch, and I haven't tested it, but the general idea should be
clear.

    mcSimulate stock endTime seed = map (evolve n stock) $ iterate
(+246524) seed
        where
        n = truncate (endTime / timeStep)

    evolve :: Int -> Double -> Word64 -> Double
    evolve n stock seed
        | n <= 0    = stock
        | otherwise = evolve (n-1) (evolveStock stock seed)
(ranq1Increment seed)

    evolveStock :: Double -> Word64 -> Double
    evolveStock stock seed = stock * exp (a + b * normalFromRngState seed)
        where
        a = (ir - 0.5 * vol * vol) * timeStep
        b = vol * sqrt timeStep

-- 
Dave Menendez <d...@zednenem.com>
<http://www.eyrie.org/~zednenem/>
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to