# Value Function - Scoping problem

Hi everyone. I am trying to create a simple Value Function Iteration routine for a basic econ. problem.
I’m facing the common problem of global and local variable definition, but I don’t know how to correct in this case. Below is a simple version of the problem I am trying to solve:

``````agrid = 10
zgrid = 3

Pz = [0.11 0.85 0.04; 0.07 0.87 0.06; 0.03 0.85 0.12]

a = zeros(agrid, 1)
V = zeros(agrid, zgrid)
V_new = zeros(agrid, zgrid)

u = zeros(agrid)
erro = 100

while erro > 0.1
for ia = 1:agrid
for iz = 1:zgrid

for ja = 1:agrid
c = 0.02*a[ia] + exp(z[iz]) - a[ja]
EV = transpose(Pz[iz,:])*V[ja,:]
u[ja] = -1/c + 0.95*EV

end
Vmax, imax = findmax(u)
V_new[ia,iz] = Vmax

end
end
erro = maximum(abs.(V_new - V))
V = V_new
end
``````

The message I get is ‘UndefVarError: V not defined’. In this case, I don’t know how I can use ‘global definition variable’ or the ‘let’ operator to fix my problem.

Thanks!

I get `ERROR: UndefVarError: z not defined`.
If I define a `z`, and use `global V = V_new` in the last line I don’t get any error.

1 Like

It is a well-known behaviour, just put the code inside a function (not change is required), and it should be working.

Outside functions, variables like V or z are global (for be defined out of any function or loop), so you need to put inside the loop the sentences like “global V” to use them.

Yup. Use a function or stay in jupyter. For now, better to never use loops at top level scripts.

1 Like

Sorry, we could define z as `z = [-0.43 0 0.43]`, for instance. In this case, I do not get an error, but the code does not run.

``````    agrid = 10
zgrid = 3

Pz = [0.11 0.85 0.04; 0.07 0.87 0.06; 0.03 0.85 0.12]

a = zeros(agrid, 1)
z = [-0.43 0 0.43]
V = zeros(agrid, zgrid)
V_new = zeros(agrid, zgrid)

u = zeros(agrid)
erro = 100

while erro > 0.1
for ia = 1:agrid
for iz = 1:zgrid

for ja = 1:agrid
c = 0.02*a[ia] + exp(z[iz]) - a[ja]
EV = transpose(Pz[iz,:])*V[ja,:]
u[ja] = -1/c + 0.95*EV
end
Vmax, imax = findmax(u)
V_new[ia,iz] = Vmax
end
end
erro = maximum(abs.(V_new - V))
V = V_new
println("Error is \$erro\tV is \$V")
end # of loop

end # Of main

main()
``````

Yes, because your code is not right, z was not defined anyway in your original code, and it was used in line 19. So, there is an error, and we cannot fix it, because it is not a problem with the language, it is a logic error. Using a function (or using Jupyter( avoid the problem to access variables.

I have update the code with the z values you say, and it is working (I cannot help you more because I have not idea what are you trying to calculate).

1 Like

I think that’s a bit extreme. If the purpose of this piece of code if to compute `V`, it can say

``````V = let
# ...
# original code here
# ...
V
end
``````

without requiring `global` annotations.

1 Like

Perfect! Now, my second (and main) doubt is the following:
We begin with `V = [0 0 0; ...]` and `V_new = [0 0 0; ...]`

In the first while iteration we have `V_new = [-1.53 -1.0 -0.65; ...]`. Hence the error is 1.53 and V becomes `[-1.53 -1.0 -0.65; ...]`.

Since `1.53 > 0.1` we go to the second while iteration but now with `V = [-1.53 -1.0 -0.65; ...]`

Hence, by the algorithm, we updated `V_new = [-2.53 -1.96 -1.57; ...]`.
In this case, the error should be `maximum(abs.(V_new - V)) = max(abs.([-2.53 -1.96 -1.57; ...]- [-1.53 -1.0 -0.65; ...]))`.

However, in the second while iteration, the algorithm is updating `V` before computing the error, making `maximum(abs.(V_new - V)) = max(abs.([-2.53 -1.96 -1.57; ...]- [-2.53 -1.96 -1.57; ....])) = 0 > 0.1` and stoping the iteration.

Matlab doesnt have this ‘behavior’ and dont know how to handle it in Julia.

I dont know if it is clear.
Any way, you already contributed a lot. Thanks!

You’ve got a lot of code here, so it’s hard to be sure, but I would suspect that the problem is here:

``````V = V_new
``````

in Matlab, this would copy `V_new` and create a new vector called `V`. Any future changes to `V_new` would not affect `V`. In Julia, however, this just makes `V` a label for the same vector as `V_new`, so any changes to `V_new` will be shared with `V`. This is actually how all assignment operations in Julia work: Julia doesn’t silently copy things when you assign them or when you pass them to functions (unlike Matlab).

If you do want a copy, you can simply do: `V = copy(V_new)`.

Perhaps that will help you figure out what’s different in the results you’re seeing.

3 Likes

It is precisely this point. I was skipping this detail in Julia.
Thanks a lot.