UndefVarError for some variables

Hey all. I’ve been trying to write some functions in Julia, but I’ve been getting many errors of the
UndefVarError: variable not defined type. The main source of the errors is this part here (which is inside my function):

            global pi = rand(C)
            global pi = pi/sum(pi)
            global mu = reshape(randn(C * d), (C, d))
            sigma = zeros(Float64, (d, d, C))
            for c in 1:C
                sigma[:, :, c] = Diagonal(ones(d))
            global lloss = -Inf
            not_saturated = true
            for i in 1:max_iter
                former_loss = copy(lloss)
                gamma = E_step(X, pi, mu, sigma)
                pi, mu, sigma = M_step(X, gamma)
               lloss = compute_vlb(X, pi, mu, sigma, gamma)
                if(former_loss[1] > lloss[1])
                not_saturated = abs((lloss[1]/former_loss[1]) - 1) > rtol

where I get that my pi, mu, and sigma are not defined (I even tried making it global but no success so far). I know this is not reproducible (sorry for that), so I’ll try to explain. The E_step, M_step and compute_vlb functions will receive the parameters inside the for loop there, and what I expect is that the parameters can be updated at each iteration (as is written there). I’m imagining that there’s something very simple that I’m missing here. Does anyone have any idea?

It’s really hard to say anything helpful without being able to run the code. Here are some general steps you can take to figure out what’s going on:

  1. Inside of a function, you should almost never need to use the global keyword. The only time you would need it is if you want your function to mutate a global variable, but that’s (A) bad programming practice and (B) very slow in Julia. So just don’t do it. So, as a first step, remove the global keyword from inside your function entirely and don’t assume your function will mutate any global variables.
  2. If you still have errors, practice making a minimal reproducible example. Make a copy of your code and delete everything that is not directly involved in the problem you’re having. Keep deleting until either (A) you understand the problem or (B) you have something simple enough to past here as a complete example. That will make it much easier for us to help you.
1 Like

Yes, I’m aware of that @rdeits, thanks, it’s just that the code is big (and messy at the moment), so if that was something simple maybe someone could just spot it by looking. The code is here, actually: https://github.com/brunaw/jubs/blob/master/code/ml/em.jl (it’s not so simple or organised but it runs quickly) and the data is in the same folder inside the repository.

The function that creates the issues is the last one, because of undefined variable errors. What I’m doing is trying to build it from inside out, so when I run what’s inside, I get the errors :confused:

Welcome to the Julia’s discourse forum!
I was trying your function and i find some problems in the functioncompute_vlb(X, pi, mu, sigma, gamma, C = 3), there were a lots of variable_var, but those variables weren’t defined. i supposed that those variables are the function imputs so i changed those names., can you try that?.

function compute_vlb(X, _pi, mu, sigma, gamma, C = 3)
    N = size(X[1])[1]
    #C = size(pi)[1]

    d = size(mu)[2]
    loss = zeros(Float64, 1)
    for c in 1:C
        for n in 1:N
            mv_norm = MvNormal(mu[c, :], Symmetric(sigma[:, :, c]))
            logd = logpdf(mv_norm, [X[1][n], X[2][n]])
            gamma_c = gamma[n, c]
            loss_here   = gamma_c * ((log(_pi[c]) + logd) - log(gamma_c))
            loss[1] = loss[1] + loss_here[1]
return loss

also, pi is the value 3.1415…, and you where replacing it with a vector, maybe changing the variable can help (Pi, i used _pi hahaah)

Remove the globals and work in jupyter. If you are having issues there, then it is more fundamental than a global variable issue