2016-07-03 22 views
2

不知道如何来填充DenseMatrix类型:DenseMatrix无效转让

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 mutable data_logdiff = DenseMatrix.zero<float> (data.RowCount-1) (data.ColumnCount) 

for i in [0 .. data.ColumnCount-1] do 
    for j in [1 .. data.RowCount-1] do 
     data_logdiff.At(j-1, i) <- data.At(j, i)/data.At(j-1, i) |> log 

最后一行生成错误“无效的分配”。

还想知道是否有功能性的方式来表达上述逻辑。

谢谢。

+6

不要假设每个人都知道你在使用哪个库以及你打开了哪些命名空间,将它们包含在代码中。 – Gustavo

回答

6

我会假设你正在使用MathNet,不知道哪个版本。首先,我不认为你的data_logdiff需要是可变的,它已经是一个可以改变属性的对象,我的意思是你想改变它的属性而不是对象本身。

然后在你的代码的问题是如何变异的特性,你应该使用一个索引来代替.At将只返回值:

#r @"packages\MathNet.Numerics.3.8.0\lib\net40\MathNet.Numerics.dll" 
#r @"packages\MathNet.Numerics.FSharp.3.8.0\lib\net40\MathNet.Numerics.FSharp.dll" 

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.zero<float> (data.RowCount-1) (data.ColumnCount) 

for i in [0 .. data.ColumnCount-1] do 
    for j in [1 .. data.RowCount-1] do 
     data_logdiff.[j-1, i] <- data.At(j, i)/data.At(j-1, i) |> log 

为了使更多的功能使用DenseMatrix.init代替DenseMatrix.zero和然后循环:您使用.zero

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) 

一般来说,每次和环路初始化矩阵或矢量考虑使用.init functi反而,它需要一个额外的参数,就像循环体一样。

+0

非常漂亮。谢谢。 –