2016-07-03 53 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

非常漂亮。謝謝。 –