Vasu Balakrishnan’s Blog

Learning F#

leave a comment »

Since I’ve started to use LINQ, I was interested to learn about Functional Programming. Its a programming paradigm that embraces functions as first class citizens, enables higher order functions, avoids mutable state, etc. The more I started to use in my projects, I began to appreciate the functional style of programming, and  that’s how I got me learn F#.

We have built a statistical module in C# to calculate mean, standard deviation, etc. I wanted to try implementing them in F#.

module stats =

    let sqr x = x * x
    let mean (data : vector)  = data |> Seq.average
    let max  (data : vector)  = data |> Seq.max
    let min  (data : vector)  = data |> Seq.min
    let range (data : vector) = max data - min data

    let avggain (data : vector) =
        data |> Seq.filter (fun x -> x > 0.0) |> Seq.average

    let avgloss (data : vector) =
        data |> Seq.filter (fun x -> x < 0.0) |> Seq.average
        
    let variance (data : vector) = 
        let mean = mean(data)
        (data |> Seq.sum_by(fun x -> sqr(x - mean))) / float (data.Length - 1)

    let stddev (data : vector) = sqrt(variance(data)) 
    let stddev3 (data : vector) = stddev(data) * sqrt(3.0)
    let stddev12 (data : vector) = stddev(data) * sqrt(12.0)

    let skew (data : vector) = 
        let mean = mean(data)
        let stddev = stddev(data)
        let sum = data |> Seq.sum_by(fun x -> ((x - mean) / stddev) ** 3.0)
        let fact = (float data.Length / float ((data.Length - 1) * (data.Length - 2)))
        sum * fact

    let kurtosis (data : vector) =
        let mean = data |> mean
        let stddev = data |> stddev
        let len = float data.Length
        let fact1 = len * (len + 1.0) / ((len - 1.0) * (len - 2.0) * (len - 3.0))
        let fact2 = 3.0 * Math.Pow((len - 1.0), 2.0) / ((len - 2.0) * (len - 3.0))
        let sum = data |> Seq.sum_by(fun x -> Math.Pow(((x - mean) / stddev), 4.0))
        sum * fact1 - fact2

 

Here is how you use them.

    let data = vector [0.20; -2.70; 1.59; 0.74; 0.31; 1.87]
    printfn "Input Data\n %A"  (data)
    printfn "Mean - %A"  (stats.mean data)
    printfn "Max - %A" (stats.max data)
    printfn "Min - %A" (stats.min data)
    printfn "Range - %A" (stats.range data)
    printfn "AvgGain - %A" (stats.avggain data)
    printfn "AvgLoss - %A" (stats.avgloss data)
    printfn "Variance - %A" (stats.variance data)
    printfn "StdDev - %A" (stats.stddev data)
    printfn "StdDev3 - %A" (stats.stddev3 data)
    printfn "StdDev12 - %A" (stats.stddev12 data)
    printfn "Skew - %A" (stats.skew data)
    printfn "Kurtosis - %A" (stats.kurtosis data)

    

Its pretty straight forward code. I could’ve done the same in C# and with LINQ it would be pretty much be the same number of Lines. The one thing I like in this implementation is pipe forwarding operator (|>) in F#. To me it makes it so much easier to read the code. I wish I could do that in C#.

 
Advertisements

Written by nbvasu

June 10, 2009 at 4:35 pm

Posted in F#

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: