0

I'm trying to plot the first 100 values of this random walk function using F#/Xamarin. Whenever I call the function, my application freezes. I tried to get the count on this.RW, but that also freezes the application. Help appreciated!

module SimulatingAndAnalyzingAssetPrices = 
    type RandomWalk(price : float) = 
        let sample = Normal(0.0, 1.0).Sample()

        // Generate random walk from 'value' recursively
        let rec randomWalk price = 
            seq { 
                yield price
                yield! randomWalk (price + sample)
            }

        let rw = randomWalk 10.0

        member this.RW = rw

Note: This is from tryfsharp.org's finance section. My intent is to port it to iOS using Xamarin.

Edit: Tried using the following code, but still getting an infinite sequence:

    let rw = randomWalk 10.0

    let rwTake = Seq.take 100 rw

    member this.RwTake = rwTake

Edit 2: Also tried

    let rw = randomWalk 10.0 |> Seq.take 100

    member this.RwTake = rw
Ian Leatherbury
  • 364
  • 4
  • 11
  • When you say "still getting an infinite sequence", have you updated the graphing code to try to graph `this.RwTake` instead of graphing `this.RW`? Because "Oops, I forgot to update the other half of my code" is an easy mistake to make... – rmunn Nov 09 '15 at 03:07
  • You are a smart man. That was it. Thank you! – Ian Leatherbury Nov 09 '15 at 03:08

1 Answers1

2

Your randomWalk function produces an infinite sequence, so you should never call it without using Seq.take to limit the number of items to, say, the 100 you're trying to graph. If you call it directly, the app freezes because you'll never find the end of the infinite sequence. But if you graph somePrice |> this.RW |> Seq.take 100, you should no longer have your application freezing up any more.

And getting the count of an infinite sequence is also going to freeze up, because it will be going through the sequence trying to reach the end so it can return a count, but there's no end! You can never take a count of an infinite sequence.

Update: There's also Seq.truncate. The difference between Seq.take and Seq.truncate lies in what happens if there are fewer items than expected. (This won't be the case for your randomWalk function, so you can use either take or truncate and you'll be fine, but in other situations you might need to know the difference.) If a sequence has only 5 items but you try to Seq.take 10 from it, it will throw an exception. Seq.truncate, on the other hand, will return just 5 items.

So Seq.take 10 will either return exactly 10 items, no more nor less, or else throw an exception. Seq.truncate 10 will return up to 10 items, but might return fewer, and will never throw an exception.

For more details, see Does F# have an equivalent to Haskell's take?

Community
  • 1
  • 1
rmunn
  • 34,942
  • 10
  • 74
  • 105
  • Also, this random walk isn't going to be very random because `let sample = Normal(0.0, 1.0).Sample()` is bound once. It would be better to use `let sample() = Normal(0.0, 1.0).Sample()` such that the value of the random walk was generated at each step of the recursion. – TheInnerLight Nov 09 '15 at 02:17
  • Hey guys, thank you for the quick answers! Tried your suggestion rmunn, and getting an unexpected behaviour. Have updated question to reflect that. – Ian Leatherbury Nov 09 '15 at 03:00