F# 中的可变向量字段未更新

Mutable Vector field is not updating in F#

let gradientDescent (X : Matrix<double>) (y :Vector<double>) (theta : Vector<double>) alpha (num_iters : int) =
    let J_history = Vector<double>.Build.Dense(num_iters)
    let m = y.Count |> double
    theta.At(0, 0.0)
    let x =  (X.Column(0).PointwiseMultiply(X*theta-y)) |> Vector.sum
    for i in 0 .. (num_iters-1) do
        let next_theta0 = theta.[0] - (alpha / m) * ((X.Column(0).PointwiseMultiply(X*theta-y)) |> Vector.sum)
        let next_theta1 = theta.[1] - (alpha / m) * ((X.Column(1).PointwiseMultiply(X*theta-y)) |> Vector.sum)
        theta.[0] = next_theta0 |> ignore
        theta.[1] = next_theta1 |> ignore
        J_history.[i] = computeCost X y theta |> ignore
        ()
    (theta, J_history)

Even though matrices and vectors are mutable, their dimension is fixed and cannot be changed after creation.

http://numerics.mathdotnet.com/Matrix.html

我有 theta,它是一个大小为 2x1 的向量 我正在尝试更新 theta。[0]和θ。 [1]迭代但是当我在每次迭代后查看它时它仍然是 [0;0]。我知道 F# 是不可变的,但我在他们的网站上引用了 Vectors 和 Matrix 是可变的,所以我不确定为什么这不起作用。

我的直觉是它与阴影有关...因为我在 for 循环中声明了一个 let next_theta0 但我不太确定

另外,作为后续问题。我觉得我实现它的方式非常糟糕。实际上,我没有理由在 F# 中实现它,因为它在 C# 中会更容易(使用这种方法),因为它感觉不是很“实用” 任何人都可以建议批准它以使其更具功能性的方法。

F#中的破坏性更新运算符写成<-,所以:

theta.[0] <- next_theta0

您在代码中所做的是 比较 theta.[0]next_theta0,该操作会导致 bool ,这就是为什么你必须在它之后添加一个 ignore 调用,以避免编译器警告。

这里有一个很好的通用规则:当您看到编译器警告时,不要只是想方设法安抚编译器。相反,请尝试了解出现警告的原因。很有可能,它指向一个合理的问题。

这里有一个更特定于 F# 的规则:使用 ignore 是一种代码味道。 ignore 是一种 hack,主要用于与外部代码交互,当外部代码 return 是某种东西时,但并不真正期望消费者使用那个 return 值。