F# 对可变变量的赋值会干扰其他有效计算的类型推断
我正在尝试一些Newton Raphson更新。下面是一段编译并运行的代码(警告:无限循环) 在F# 对可变变量的赋值会干扰其他有效计算的类型推断,f#,math.net,mathnet-numerics,F#,Math.net,Mathnet Numerics,我正在尝试一些Newton Raphson更新。下面是一段编译并运行的代码(警告:无限循环) 在gm下出现一条扭曲的红线,编译器抱怨类型“Vector”与类型“DenseVector”不兼容 但是,函数grad被明确告知返回一个DenseVector,并且通常按预期工作 let grad (yt : Vector<float>) (xt : Vector<float>) (beta : float) (sigSq : float) = let T = (float
gm
下出现一条扭曲的红线,编译器抱怨类型“Vector”与类型“DenseVector”不兼容
但是,函数grad被明确告知返回一个DenseVector,并且通常按预期工作
let grad (yt : Vector<float>) (xt : Vector<float>) (beta : float) (sigSq : float) =
let T = (float yt.Count)
let gradBeta = (yt - beta * xt)*xt / sigSq
let gradSigSq = -0.5*T/sigSq + 0.5/sigSq**2.*(yt - beta * xt)*(yt - beta * xt)
[|gradBeta; gradSigSq|] |> DenseVector
您应该至少将let mutable thetam=[| beta;sigSq]|>DenseVector
更改为
let mutable thetam=[| beta;sigSq |]|>DenseVector.ofArray
(可能还有其他DenseVector
参考)。出于性能原因,Mathnet会进行就地更改,因此如果您使用可变引用,则可能会绊倒您:
DenseVector(双[]存储)
创建直接绑定到原始数组的新密集向量。阵列
直接使用,无需复制。效率很高,但是改变了
数组和向量会相互影响
与:
阵列密集角(双[]阵列)
创建一个新的密集向量作为给定数组的副本。这个新的
向量将独立于数组。将创建一个新的内存块
分配用于存储向量
事实上,我们已经在whenindex.Samples
中看到了这种行为
API文档(虽然不是超级用户友好的)是 您应该至少将DenseVectorlet mutable thetam=[| beta;sigSq][124;]更改为
let mutable thetam=[| beta;sigSq |]|>DenseVector.ofArray
(可能还有其他DenseVector
参考)。出于性能原因,Mathnet会进行就地更改,因此如果您使用可变引用,则可能会绊倒您:
DenseVector(双[]存储)
创建直接绑定到原始数组的新密集向量。阵列
直接使用,无需复制。效率很高,但是改变了
数组和向量会相互影响
与:
阵列密集角(双[]阵列)
创建一个新的密集向量作为给定数组的副本。这个新的
向量将独立于数组。将创建一个新的内存块
分配用于存储向量
事实上,我们已经在whenindex.Samples
中看到了这种行为
API文档(虽然不是超级用户友好的)是 是否有可能获得带有一些数据的工作代码?跟踪实际类型有点困难。如果您的类型实际上是正确的,那么您可能需要说[|gradBeta;gradSigSq |].\124;>DenseVector.OfArray
,因为mathnet有时会更改内容,有时会复制内容。@s952163我认为您对DenseVector.OfArray的看法是正确的。请把答案贴出来,我会打勾的。太快了。你在哪个时区?你能投票支持matnet/mathdotnet标签吗?谢谢!我在纽约。我刚试过投票,但没有接受,因为我没有达到要求的分数。谢谢您的帮助。非常感谢。(hess yt xt beta sigSq).Inverse()
->((hess yt xt beta sigSq).Inverse():?>DenseMatrix)
是否可以使用一些数据获取工作代码?跟踪实际类型有点困难。如果您的类型实际上是正确的,那么您可能需要说[|gradBeta;gradSigSq |].\124;>DenseVector.OfArray
,因为mathnet有时会更改内容,有时会复制内容。@s952163我认为您对DenseVector.OfArray的看法是正确的。请把答案贴出来,我会打勾的。太快了。你在哪个时区?你能投票支持matnet/mathdotnet标签吗?谢谢!我在纽约。我刚试过投票,但没有接受,因为我没有达到要求的分数。谢谢您的帮助。非常感谢。(hess-yt-xt-beta-sigSq.Inverse()
->((hess-yt-xt-beta-sigSq.Inverse():?>DenseMatrix)
while gm*gm > 0.0001 do
gm <- grad yt xt betah sigSqh
thetam <- thetam - (hess yt xt betah sigSqh).Inverse() * gm // gm here has problems
let grad (yt : Vector<float>) (xt : Vector<float>) (beta : float) (sigSq : float) =
let T = (float yt.Count)
let gradBeta = (yt - beta * xt)*xt / sigSq
let gradSigSq = -0.5*T/sigSq + 0.5/sigSq**2.*(yt - beta * xt)*(yt - beta * xt)
[|gradBeta; gradSigSq|] |> DenseVector
open System
open System.IO
open System.Windows.Forms
open System.Windows.Forms.DataVisualization
open FSharp.Data
open FSharp.Charting
open FSharp.Core.Operators
open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.Random
open MathNet.Numerics.Distributions
open MathNet.Numerics.Statistics
let beta, sigSq = 3., 9.
let xt = DenseVector [|23.; 78.; 43.; 32.; 90.; 66.; 89.; 34.; 72.; 99.|]
let T = xt.Count
let genProc () =
beta * xt + DenseVector [|for i in 1 .. T do yield Normal.Sample(0., Math.Sqrt(sigSq))|]
let llNormal (yt : Vector<float>) (xt : Vector<float>) (beta : float) (sigSq : float) =
let T = (float yt.Count)
let z = (yt - beta * xt) / Math.Sqrt(sigSq)
-0.5 * log (2. * Math.PI) - 0.5 * log (sigSq) - z*z/2./T/sigSq
let grad (yt : Vector<float>) (xt : Vector<float>) (beta : float) (sigSq : float) =
let T = (float yt.Count)
let gradBeta = (yt - beta * xt)*xt / sigSq
let gradSigSq = -0.5*T/sigSq + 0.5/sigSq**2.*(yt - beta * xt)*(yt - beta * xt)
[|gradBeta; gradSigSq|] |> DenseVector
let hess (yt : Vector<float>) (xt : Vector<float>) (beta : float) (sigSq : float) =
let T = (float yt.Count)
let z = yt - beta * xt
let h11 = -xt*xt/sigSq
let h22 = T*0.5/sigSq/sigSq - z*z/sigSq/sigSq/sigSq
let h12 = -1./sigSq**2.*((yt - beta * xt)*xt)
array2D [[h11;h12];[h12;h22]] |> DenseMatrix.ofArray2
let yt = genProc()
// until convergence
let mutable thetam = [|beta; sigSq|] |> DenseVector
let mutable gm = grad yt xt beta sigSq
while gm*gm > 0.0001 do
gm <- grad yt xt beta sigSq
// 'gm' here is complaining upon equation being assigned to thetam
thetam <- thetam - (hess yt xt beta sigSq).Inverse() * gm