Ring probabilities in F#

B1zvtamCQAAKsFv

A few months back I took a look at Elixir. More recently I’ve been exploring F# and I’m very pleased with the experience so far. Here is the ring probabilities algorithm implemented using F#. It’s unlikely that I will ever use Elixir again because having a powerful static type system provided by F# at my disposal is just too good.

let rec calcStateProbs (prob: float, i: int,
                        currProbs: float [], newProbs: float []) = 
  if i < 0 then
    newProbs
  else
    let maxIndex = currProbs.Length-1
    // Match prev, next probs based on the fact that this is a
    // ring structure.
    let (prevProb, nextProb) =
      match i with
        | i when i = maxIndex -> (currProbs.[i-1], currProbs.[0])
        | 0 -> (currProbs.[maxIndex], currProbs.[i+1])
        | _ -> (currProbs.[i-1], currProbs.[i+1])
    let newProb = prob * prevProb + (1.0 - prob) * nextProb
    Array.set newProbs i newProb
    calcStateProbs(prob, i-1, currProbs, newProbs)



let calcRingProbs parsedArgs =
  // Probs at S = 0.
  //   Make certain that we are positioned at only start location.
  //     e.g. P(Start Node) = 1
  let startProbs =
    Array.concat [ [| 1.0 |] ; [| for _ in 1 .. parsedArgs.nodes - 1 -> 0.0 |] ] 
  let endProbs =
    List.fold (fun probs _ ->
               calcStateProbs(parsedArgs.probability, probs.Length-1,
                              probs, Array.create probs.Length 0.0))
              startProbs [1..parsedArgs.states]
  endProbs

Here’s the code.
No promises this time but I may follow this sequential version up with a parallelized version.