JoshGough (1) [Avatar] Offline
#1
I noticed when I coded the Binomial function using the formula presented in the completing Listing 2 code, it didn't work.

That code was:

Seq.sumBy (fun k -> f(!n) / (f(!k) * f(!(n-k))) * p**(f(k) * (1. - p)**f(n-k)))

However, the explanation text repeats the formula, but it's different and this code does work:

Seq.sumBy (fun k -> f(!n) / (f(!k * !(n-k))) * (p**(f(k)) * ((1. - p)**f(n-k))))

It wasn't clear to me in the text that we were supposed to modify the formula from the Listing code before the unit tests would work, so I feel like this is an error.

Thanks!
Josh


Tomas Petricek (160) [Avatar] Offline
#2
Hi Josh,
thanks very much for reporting this. The two versions of the code should certainly be the same. I'll let Kit investigate what exactly is happening (I suspect there could be some issue with floating-point precision). In any case, I'll add it to errata to warn other readers!

Thanks,
Tomas
342555 (1) [Avatar] Offline
#3
Hi Josh,

sorry about - yes, it is a mistake on my part.

The problem is that in F# the exponentiation operator ** doesn't have a higher precedence than other operators (such as * ). Obviously when we write formulae 'the maths way' exponentiation has the highest precedence.

The extra brackets (as in the downloadable code sample) fix this - but I forgot to paste this version into the book text.

Well spotted - and apologies!

Kit
Russ Freeman (1) [Avatar] Offline
#4
Hi Kit

Is there still a gremlin in the published code? I have to introduce some extra casts to get it to build:

    [0..x]
    |> Seq.sumBy (fun k -> (f(!n) / (f(!k * !(n - k))) 
    * (p**(f(System.Numerics.BigInteger(k))) 
        * ((1. - p)**f(System.Numerics.BigInteger(n)-System.Numerics.BigInteger(k))))))