I am taking the next step with Julia, and trying to learn more. Up to now, I have used it mostly just as a calculator, but I recently started to make my own modules and so on.
One thing I am having trouble understanding is how mutating functions work.
In the code below, I send in a mutable struct, GLMFit, and want to set some of its fields/attributes with this function (full code at the end).
If I do not include this part after the loop is finished, the \beta-, \mu-, and \eta-vectors have the same value as before the loop.
M.Fit.β = β M.Fit.μ = μ M.Fit.η = η
But the \beta is still changed inside the function, before the loop, since I set the first element equal to the mean of y, with this code:
if sum(β) == 0 β = sum(y)/length(y) end
It is just the changes to \beta that happen inside the loop which are not captured, unless I specifically include the
M.Fit.β = β after the loop.
Am I doing something wrong, or is the
M.Fit.β = β and same for the other vectors strictly necessary in these cases?
The full code for the function:
function FisherScoring!(M::GLMFit, maxiter=25, tol=1e-10) dist, lp, link = M.Model.d, M.Model.lp, M.Model.g X = lp.X β = M.Fit.β μ = M.Fit.μ y = M.Fit.y η = M.Fit.η p = length(β) local J, Jinv, w if sum(β) == 0 β = sum(y)/length(y) end for i in 1:maxiter η = X * β μ = InverseLinkFunction(link, η) w = Var(dist, μ) U = Score(X, y, μ, dist, link) J = FisherInformation(X, w, dist, link) Jinv = inv(J) βtemp = β β = β + Jinv * U δ = β - βtemp if sqrt(δ' * δ) < tol println(@sprintf "Stopping after %d iterations" i) M.Fit.SE = sqrt.(diag(Jinv)) break else L = Likelihood(dist, μ, y) println(@sprintf "Fisher Iteration %d 𝐿(β) = %.12f" i L) M.Fit.SE = sqrt.(diag(Jinv)) end end M.Fit.β = β M.Fit.μ = μ M.Fit.η = η M.Fit.𝐃 = Deviance(dist, μ, y) M.Fit.DoF = length(y) - length(β) L = Likelihood(dist, μ, y) M.Fit.AIC = AIC(length(β), L) M.IsFitted = true end