Although I'm VERY far from being skillful F# programmer, I am slowly moving forward.
Not far ago I implemented one of the measures of association in R - Somers' D.
Somers' D is sometimes used for testing concordance of internal and external risk scores / rankings.
I had some problems with finding the right formula for Somers' D Asymptotic Standard Error, and when I finally found the solution I didn't have much energy to clean up my R code ;)
I thought, using this dirty code as a base for Somers' D implementation in F# may bring interesting results. My intention was not to give R too large a head start over F#.
Still, the differences are visible in many places...
First of all, I have been pretty surprised that basic matrix operations are not available in the core F# version.
It is necessary to add F# PowerPack to work with matrices.
Even then, working with matrices in F# does not seem so natural as in R (or Matlab). Or, probably, I still know too little about F#.
A couple of examples:
constructing matrix in R:
- PD <- c(0.05,0.10,0.50,1,2,5,25)/100
- total <- c(5,10,20,25,20,15,5)/100
- defaulted <- total*PD
- nondefaulted <- total*(1-PD)
- n <- sum(total)
- portfolio <- rbind(defaulted,nondefaulted)/n
constructing matrix in F#:
- #r "FSharp.PowerPack.dll"
- let PD = [ 0.05; 0.10; 0.50; 1.00; 2.00; 5.00; 25.00 ]
- let counterparties = [ 5.; 10.; 20.; 25.; 20.; 15.; 5. ]
- let groups = PD.Length // risk groups no.
- let div100 x = x / 100.0
- let PDprct = [ for x in PD do yield div100 x ]
- let CPprct = [ for x in counterparties do yield div100 x ]
- let n = CPprct |> Seq.sum
- let defaulted = [ for i in 1..groups do yield CPprct.[i-1]*PDprct.[i-1]/n ]
- let nondefaulted = [ for i in 1..groups do yield CPprct.[i-1]*(1.0-PDprct.[i-1])/n ]
- let x = matrix [ defaulted; nondefaulted ]
calculating WR/DR in R:
- wr <- n^2-sum(sapply(1:nrow(x), function(i) sum(x[i,])^2))
calculating WR/DR in F#:
- let xr = x.NumRows
- let rowSum (x : matrix) (i : int) = Array.sum (RowVector.toArray (x.Row(i-1)))
- // WR / DR
- let wr =
- let mutable mat_sum = 0.0
- for i in 1..xr do
- let row2 = rowSum x i ** 2.0
- mat_sum <- mat_sum + row2
- n ** 2.0 - mat_sum
Later it gets a little better, but...
'A' function in R:
- A <- function(x,i,j) {
- xr <- nrow(x)
- xc <- ncol(x)
- sum(x[1:xr>i,1:xc>j])+sum(x[1:xr<i,1:xc<j])
- }
'A' function in F#:
- let A (x : matrix) i j =
- let xr = x.NumRows
- let xc = x.NumCols
- let rowIdx1 = List.filter (fun x -> x>i) [ 1..xr ]
- let colIdx1 = List.filter (fun x -> x>j) [ 1..xc ]
- let rowIdx2 = List.filter (fun x -> x<i) [ 1..xr ]
- let colIdx2 = List.filter (fun x -> x<j) [ 1..xc ]
- let mutable Asum = 0.0
- for r_i in rowIdx1 do
- for r_j in colIdx1 do
- Asum <- Asum + x.[r_i-1,r_j-1]
- for r_i in rowIdx2 do
- for r_j in colIdx2 do
- Asum <- Asum + x.[r_i-1,r_j-1]
- Asum
As I've mentioned at the beginning of the post - both codes are "dirty". Also, I definitely know R better than F# (even if it may not be apparent from the R code above ;)
Still, F# seems to require more coding and many "simple" operations (matrices...) may not be so easy in F# in comparison to R.
I'm still to find where F# excels :)
[ dirty R code ]
[ dirty F# code ]
No comments:
Post a Comment