2

Friends, the following code runs fine when using Seq.unfold. However, List.unfold or Array.unfold (as shown below) causes the program to never terminate. I'm mostly just curious as to why that is. However, I am biased in general towards only using Arrays. Can anyone explain what is the reason for this behavior and if possible how to work within the confines of Arrays for a problem with this general structure.

open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.Distributions

let randn() = Normal.Sample(0., 1.)
let N = 100
let y = DenseVector.init N (fun _ -> 10. + sqrt(1.) * randn())
let SIM = 
    Array.unfold (fun (c1_, c2_) ->
        let D  = 1./(1. / 100. + float(N) / c2_)
        let c1 = D *(0. / 100. + y.Sum() / c2_) + sqrt(D) * randn() 
        let a1 = (3. + float(N) / 2.)
        let a2 = (0.5 + ((y-c1).PointwisePower(2.)).Sum() / 2.)
        let c2  = InverseGamma.Sample(a1, a2)
        Some((c1_, c2_), (c1, c2))
    ) (0., 1.)
    |> Array.take (100000)
let result = SIM |> Array.map (fun (i, j) -> i) 
FoggyFinder
  • 2,230
  • 2
  • 20
  • 34

1 Answers1

4

I think the problem is caused by your generator since it never terminates the unfold algorithm by returning None.

Your code is working with Seq because sequences are evaluated lazily and Seq.unfold execute the generator only when you try to read a value from the sequence. The fact that the generator never terminates is not a problem because sequences can be infinite.

On the other hand, lists and arrays are not lazily evaluated and the generator is run until it returns None. With your generator, you end up with an "infinite loop".