0

Suppose I have the following data:

var1,var2,var3
0.942856823,0.568425866,0.325885379
1.227681099,1.335672206,0.925331054
1.952671045,1.829479996,1.512280854
2.45428731,1.990174152,1.534456808
2.987783477,2.78975186,1.725095748
3.651682331,2.966399127,1.972274564
3.768010479,3.211381506,1.993080807
4.509429614,3.642983433,2.541071547
4.81498729,3.888415006,3.218031802

Here is the code:

open System.IO
open MathNet.Numerics.LinearAlgebra
let rows = [|for line in File.ReadAllLines("Z:\\mypath.csv") 
            |> Seq.skip 1 do yield line.Split(',') |> Array.map float|]
let data = DenseMatrix.ofRowArrays rows

let data_logdiff = 
    DenseMatrix.init (data.RowCount-1) (data.ColumnCount) 
        (fun j i -> if j = 0 then 0. else data.At(j, i) / data.At(j-1, i) |> log)

let alpha = vector [for i in data_logdiff.EnumerateColumns() -> i |> Statistics.Mean]

let sigsq (values:Vector<float>) (avg: float) =
    let sqr x = x * x
    let result = values |> (fun i -> sqr (i - avg))
    result

sigsq (data_logdiff.Column(i), alpha.[0]) |> printfn "%A"

Error: The type ''a * 'b' is not compatible with the type 'Vector<float>'

This is all for a broadcast operation between a matrix and a vector. All these acrobatics to do a simple mean((y-alpha).^2) in MATLAB.

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • 1
    You can show MCVE? – FoggyFinder Jul 03 '16 at 20:15
  • 1
    [MCVE - How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – Guy Coder Jul 03 '16 at 21:14
  • matlab is a domain specific language for matrix operations. Why would you expect a general language to match that kind of terseness. Btw, nothing stops you from defining .^ in F#. – s952163 Jul 03 '16 at 23:14
  • 1
    Could you also add the `mathdotnet` tag, as some of this is mathdotnet related and you might get better/quicker help from someone who is familiar with the library. Also, there is `.*` and also `PointwisePower` so you can say something like `data.Column(0) .* data.Column(0)` or `data.Column(0).PointwisePower(2.)`. – s952163 Jul 04 '16 at 01:59
  • 1
    @s952163 I often edit the tags for questions at SO and even remove redundant ones and convert some to more specific ones. Sometimes I even use Google to search for questions in SO and then use those results to add tags that are missing to better find answers using only tags in the future. So don't be shy about editing tags. – Guy Coder Jul 04 '16 at 13:17

1 Answers1

0

You have a mistake in your code, and the F# compiler complains about it, albeit in a somewhat obscure way. You define your function:

let sigsq (values:Vector<float>) (avg: float) =

This is a function that takes two arguments. (Actually it's a function taking one argument, returning another function taking one argument.) But you call it like this:

sigsq (data_logdiff.Column(i), alpha.[0]) |> printfn "%A"

You tuple the arguments, and for F# functions (a,b) is one argument, which is a tuple. You should call your function like this:

sigsq (data_logdiff.Column(0)) (alpha.[0]) 

or

sigsq <| data_logdiff.Column(0) <| alpha.[0]

and my favorite one:

data_logdiff.Column(0) |> sigsq <| alpha.[0]

I replaced the (i) with 0 in your code. You can map through the columns if you want to loop:

data_logdiff.EnumerateColumnsIndexed() |> Seq.map (fun (i,col) -> sigsq col alpha.[i])

s952163
  • 6,276
  • 4
  • 23
  • 47