I am trying to calculate covariance matrix
The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints
CovMatrix.[a,b]
How to fix this and why it happens?
let FirstSeq = {1.0..10.0}
let SecondSeq = {20.0..30.0}
let All = seq {yield (0,FirstSeq); yield (1,SecondSeq)}
let cov(first:seq<float>)(second:seq<float>) =
Seq.map2 (*) first second
|> Seq.average
|> fun x -> x - Seq.average first * Seq.average second
let CreateCovMatrix(strangeList:seq<int * seq<float>>) =
let Size = Seq.length strangeList
let CovMatrix = Array2D.init Size Size
let CalculateCovMatrix =
for (a, i) in strangeList do
for (b, j) in strangeList do
CovMatrix.[a,b]=cov(i)(j)
CalculateCovMatrix
let result = CreateCovMatrix(All)
printf "%A" result
The function Array2D.init takes 3 parameters, you're missing the last one, which is the initialization function.
You can quick-fix it by writing:
let CovMatrix = Array2D.init Size Size (fun _ _ -> 0.)
Then you'll discover the next problem: assignment for mutable references is the <- operator, not = which is for comparison and let bindings.
So your function will look like this:
let CreateCovMatrix(strangeList:seq<int * seq<float>>) =
let Size = Seq.length strangeList
let CovMatrix = Array2D.init Size Size (fun _ _ -> 0.)
let CalculateCovMatrix =
for (a, i) in strangeList do
for (b, j) in strangeList do
CovMatrix.[a,b] <- cov(i)(j)
CalculateCovMatrix
But instead of specifying a function that ignores the inputs and return always zero, you can use the function Array2D.zeroCreate :
let CovMatrix = Array2D.zeroCreate Size Size
This kind of math is where functional programming excels,
although you're currently residing in the imperative paradigm. Gustavo handled your warnings, but even so your function won't give the desired result. Mixing functional and imperative concepts CreateCovMatrix now returns unit.
Good imperative:
let createCovMatrix(strangeList:seq<int * seq<float>>) =
let size = Seq.length strangeList
let covMatrix = Array2D.zeroCreate size size
for (a, i) in strangeList do
for (b, j) in strangeList do
covMatrix.[a,b]<-cov(i)(j)
covMatrix
Going functional:
let createCovMatrix strangeList =
strangeList
|> Seq.map (fun (a, i) -> Seq.map (fun (b, j) -> cov i j) strangeList)
|> array2D
Multi functional:
let createCovMatrix strangeList =
let mapper f = Seq.map f strangeList
mapper (fun (a, i) -> mapper (fun (b, j) -> cov i j))
|> array2D
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With