0

サンプリングを行うためにMath.netを接続していますが、想定どおりに機能しません...ここで何が欠けていますか?

let mm  =  Double.DenseMatrix.Identity(2)
let ida =  Double.DenseMatrix.Identity(2)
let idb =  Double.DenseMatrix.Identity(2)
let generator = MatrixNormal(mm, ida, idb)
generator.Density(mm)

私は得る

System.ArgumentOutOfRangeException: Matrix dimensions must agree.
Parameter name: x
   at MathNet.Numerics.Distributions.MatrixNormal.Density(Matrix`1 x) in c:\TeamCity\buildAgent\work\392bcd0e1411b00f\src\Numerics\Distributions\Multivariate\MatrixNormal.cs:line 241
   at <StartupCode$FSI_0079>.$FSI_0079.main@()
Stopped due to error

奇妙なことに、githubソースを見るとここにスローされます

  public double Density(Matrix<double> x)        { 
       if (x.RowCount != _m.RowCount || x.ColumnCount != _m.ColumnCount) 
       {                
           throw Matrix.DimensionsDontMatch<ArgumentOutOfRangeException>(x, _m, "x");                         
       }

編集

すべてを再起動した後、2 * 2の行列平均では機能しましたが、2 * 1では機能しませんでした(列の分散を調整した後)。非常に奇妙なのは、定義時にいくつかのディメンションチェックがあることです。それでも、エラーメッセージは呼び出し時に表示されます。チェックが行の分散と列の分散を間違えていて、呼び出し時に正しいものを使用している可能性があります。これはすべて、リッチタイプチェックの強力な利点を強調しています。

好奇心旺盛な方のために、ここに多変量実装があります。まだチェックしていません。

let sampleNormal = 
   let rnd = new MersenneTwister()
   fun () ->
      let rec randomNormal () = 
          let u1, u2 = rnd.NextDouble(),rnd.NextDouble()
          let r = sqrt (-2. * (log u1))
          let theta = 2. * System.Math.PI * u2  
          seq { yield r * sin theta
                yield r * cos theta 
                yield! randomNormal() }
      randomNormal ()


let generate covar = 
   let chol = Double.Factorization.DenseCholesky(covar)
   let a = chol.Factor
   fun () -> let v = vector ( sampleNormal() |> Seq.take(covar.ColumnCount) |> List.ofSeq )
             a * v
//generate covar  

let generatecovar = generate covar
let generaten n covar = Seq.init n (fun _ -> generatecovar ()) 

編集

コレスキーは完全に相関する入力に対して失敗します、これは問題ありません

let mapply (m:Generic.Matrix<float>) f = m.IndexedEnumerator() |> Seq.iter(fun (i,j,v) -> m.[i,j] <- f v ); m

let generate (covar:Generic.Matrix<float>) = 
   let R = if covar.Determinant() = 0. then   // we want covar = R.RT  // C = U D1/2.D1/2 U' = (RT.QT) Q.R = RT.RTT  
               let u, d, vt = let t = covar.Svd(true) in t.U(), t.W(), t.VT()  
               let A = (mapply d sqrt) * u.Transpose()                    
               let qr = A.QR() in qr.R.Transpose()                                 
            else
               let chol = covar.Cholesky()
               chol.Factor
   fun () -> let v = vector ( sampleNormal() |> Seq.take(covar.ColumnCount) |> List.ofSeq )
             R * v
4

1 に答える 1

1

コードに問題は見つかりません。正しいコードを実行していることを確認しますか?たぶん、ライブラリコードのバージョンが間違っているのでしょうか、それともあなた自身のものでしょうか?FSIを再起動するか、ライブラリを再コンパイルしてみてください。

于 2012-06-30T20:55:19.460 に答える