Ring probabilities in F#
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.