Array definition error

When I wrote the following code, an error occurred in the definition of the array.
I think that the definition of array u is done, but I do not know why the error occurs.

Changing the definition of [array u] to [global u] did not work well.

using Plots
gr()
function calc_nrm(a::Matrix{Float64},b::Matrix{Float64})
    n=size(a,1)
    nrm=a-b
    sum=0
    for i in 1:n
        for j in 1:n
            sum+=abs(nrm[i,j]^2)
        end
    end
    ans=sum^0.5

    return ans
end

w=1.
h=1.
Nx=200
Ny=200

delta_x=w/Nx
delta_y=h/Ny

u=zeros(Nx+1,Ny+1)
u_new=zeros(Nx+1,Ny+1)

u[1,:].=0.
u[:,1].=0.
u[Nx+1,:].=40.
u[:,Ny+1].=80.

u_new[1,:].=0.
u_new[:,1].=0.
u_new[Nx+1,:].=40.
u_new[:,Ny+1].=80.

err=0

num=2/(delta_x)^2+2/(delta_y)^2

while err==0
    for j in 2:Nx
        for k in 2:Ny
            u_new[j,k]=(1/num)*((u[j-1,k]+u[j+1,k])/(delta_x^2)+(u[j,k-1]+u[j,k+1])/(delta_y^2))
        end
    end
    if calc_nrm(u,u_new)<2.1
        err=1
    end
    u=u_new
end

ERROR: LoadError: UndefVarError: u not defined
Stacktrace:
 [1] top-level scope at C:\Users\yuki-\Documents\juliapra\wave\laplace.jl:45 [inlined]
 [2] top-level scope at .\none:0
in expression starting at C:\Users\yuki-\Documents\juliapra\wave\laplace.jl:42

You need to add a global to your u:

    ....
    global u
    u = u_new
end

But note that after above statement your u and u_new point to the same array, which is probably not what you want. Probably best to swap bindings:

    ....
    global u, u_new
    u, u_new = u_new, u
end

Next time, please post a minimal, working (or erroring) example to make it easy on your helpers: PSA: make it easier to help you

Also, note that running stuff in global scope, i.e. not in a function is not performant. Check the performance-tips of the docs.

I wrapped the code around the function f1!(u), that modifies the input u. this code works:

using Plots
gr()
function calc_nrm(a::Matrix{Float64},b::Matrix{Float64})
    n=size(a,1)
    nrm=a-b
    sum=0
    for i in 1:n
        for j in 1:n
            sum+=abs(nrm[i,j]^2)
        end
    end
    ans=sum^0.5

    return ans
end

#wrapped function, with parameters passed as arguments

function f1!(u,params)
w,h,Nx,Ny = params  
delta_x=w/Nx
delta_y=h/Ny
u_new=zeros(Nx+1,Ny+1)

u[1,:].=0.
u[:,1].=0.
u[Nx+1,:].=40.
u[:,Ny+1].=80.

u_new[1,:].=0.
u_new[:,1].=0.
u_new[Nx+1,:].=40.
u_new[:,Ny+1].=80.

err=0

num=2/(delta_x)^2+2/(delta_y)^2

while err==0
    for j in 2:Nx
        for k in 2:Ny
            u_new[j,k]=(1/num)*((u[j-1,k]+u[j+1,k])/(delta_x^2)+(u[j,k-1]+u[j,k+1])/(delta_y^2))
        end
    end
    if calc_nrm(u,u_new)<2.1
        err=1
    end
    u=u_new
    
end
return u
end

#execution

w=1.
h=1.
Nx=200
Ny=200
u=zeros(Nx+1,Ny+1)


params = (w,h,Nx,Ny)
u = f1!(u,params)
1 Like

Yes, in a function, the global is not needed (and would be wrong). But the comment about swapping bindings still applies, I think. If you’re from a matlab background, read this http://www.johnmyleswhite.com/notebook/2014/09/06/values-vs-bindings-the-map-is-not-the-territory/.

1 Like

Thanks. It worked!!

I have one more question about swapping array.

u,u_new=u_new,u

I changed this code as follows.

u=deepcopy(u_new)

But, it didn’t work. (It seemed u and u_new pointed to the same array)

So, is there any ways to do deepcopy() like python??

It seems that’s what you asked for.

If you are swapping arrays, what is the point of deepcopy? But if you insist,

u, u_new = deepcopy(u_new), deepcopy(u)