I have a very simple Julia code:
x=0
for n in 1:10
x = x + n
end
println(x)
And it gives me an error:
ERROR: LoadError: UndefVarError: x not defined
Stacktrace:
[1] top-level scope at /home/piotr/julia_codes/t4.jl:3
[2] include(::Module, ::String) at ./Base.jl:377
[3] exec_options(::Base.JLOptions) at ./client.jl:288
[4] _start() at ./client.jl:484
in expression starting at /home/piotr/julia_codes/t4.jl:2
What should I check?
Julia 1.6.0 has changed how scoping mechanism within REPL so now this works
Basically your goal is to have the code in functions rather than "naked"
Version independent code could look like this (or you could use global as in the other answer):
let x=0
for n in 1:10
x = x + n
end
println(x)
end
Try this
x=0
for n in 1:10
global x
x = x + n
end
println(x)
This is related to the scope in JuliaLang.
For more info refer to this JuliaLang discussion.
Related
The following code fails.
global Θ=1.0
function f(a)
c=sin(a+θ)
return c
end
f(1)
UndefVarError: θ not defined
Stacktrace:
[1] f(a::Int64)
# Main ./In[1]:3
[2] top-level scope
# In[1]:6
[3] eval
# ./boot.jl:373 [inlined]
[4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
# Base ./loading.jl:1196
It has no reason to fails.
Why this is incorrect??
If this doesn't work, I can say that people can't do anything using Julia.
You're using two different characters: the global variable is an uppercase Theta, while the variable you're referring to inside the function is a lowercase theta.
julia> 'Θ'
'Θ': Unicode U+0398 (category Lu: Letter, uppercase)
julia> 'θ'
'θ': Unicode U+03B8 (category Ll: Letter, lowercase)
The lowercase theta θ is a new variable that's never been defined, hence the UndefVarError.
Fixing that:
julia> Θ=1.0
1.0
julia> function f(a)
c=sin(a+Θ)
return c
end
f (generic function with 2 methods)
julia> f(1)
0.9092974268256817
Note that you don't need to mark the global variable as global - it's global by default just by being defined outside any function or other local scope. (global is only needed when you're in a local scope and want to assign to an existing global variable.)
I get an unexpected type error when running the following Julia code in Jupyter, where a seemingly straightforward import goes wrong:
include("./imp.jl")
include("./imp2.jl")
n = Main.Imp.Network([1,2])
Imp2.p2(n)
This results in the following error:
MethodError: no method matching p(::Main.Imp.Network)
Closest candidates are:
p(::Main.Imp2.Imp.Network) at /Users/cg/Dropbox/code/Julia/learning/imp.jl:11
The code is the below. How does this happen?
Imp.jl:
module Imp
export Network, p
mutable struct Network
a::Array{Any,1}
end
function p(network::Network)
network
end
end
Imp2.jl:
module Imp2
include("./imp.jl")
function p2(network)
Imp.p(network)
end
end
More error below:
Stacktrace:
[1] p2(network::Main.Imp.Network)
# Main.Imp2 ~/Dropbox/code/Julia/learning/imp2.jl:5
[2] top-level scope
# In[3]:4
[3] eval
# ./boot.jl:360 [inlined]
[4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
# Base ./loading.jl:1116
You can either do:
module Imp2
using Main.Imp
function p2(network)
Imp.p(network)
end
end
OR (without sourcing imp.jl outside of module defintion)
module Imp2
include("./imp.jl")
using .Imp
function p2(network)
Imp.p(network)
end
end
In the second case your Julia code could look like:
julia> using Main.Imp2
julia> n = Imp2.Imp.Network([1,2])
Main.Imp2.Imp.Network(Any[1, 2])
julia> Imp2.p2(n)
Main.Imp2.Imp.Network(Any[1, 2])
Addtionally if you add export Imp to the Imp2 module, you could write Imp.Network([1,2]) instead of Imp2.Imp.Network([1,2]).
I have a piece of code about JuMP. When I run it ,it says that LoadError: UndefVarError: #defVar not defined. I have tried using global forward or backward but both fails.
See:
function T1(w_func,grid_b,β,u,z)
# objective for each grid point
for j in 1:cp.Nb
b = grid_b[j]
choice1 = Model(solver=GLPKSolverLP())
#defVar (choice1, a >= 0)
#setObjective(choice1, Max, u(a) + cp.β * (w_func.((b*(1+cp.r)+cp.w-a) .* cp.z[i])))
results1 = solve(choice1)
Tw1 = getObjectiveValue(choice1)
c_choice1 = getValue(x)
return Tw, σ
end
end
LoadError: UndefVarError: #defVar not defined
in expression starting at In[44]:37
Stacktrace:
[1] top-level scope
# :0
[2] eval
# ./boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
# Base ./loading.jl:1094
thanks
It seems that you're using an outdated code. Look at the fresh documentation and make sure you have installed the latest versions of libraries and Julia.
In short, #defVar and #setObjective were replaced by #variable and #objective correspondingly.
function T1(w_func,grid_b,β,u,z)
# objective for each grid point
for j in 1:cp.Nb
b = grid_b[j]
choice1 = Model(solver=GLPKSolverLP())
#variable(choice1, a >= 0)
#objective(choice1, Max, u(a) + cp.β * (w_func.((b*(1+cp.r)+cp.w-a) .* cp.z[i])))
results1 = solve(choice1)
Tw1 = getObjectiveValue(choice1)
c_choice1 = getValue(x)
return Tw, σ
end
end
with Julia 1.5.3, I wanted to pass a list or parameters to the distributed workers.
I first tried in a non distributed way :
using Distributed
#everywhere begin
using SharedArrays
solve(a,b,c) = return (1,2,3)
d_rates = LinRange(0.01, 0.33, 5)
m_rates = LinRange(0.01, 0.25, 5)
population_size = 10^3
max_iterations_perloop = 10^3
nb_repeats = 2
nb_params = length(d_rates)*length(m_rates)*nb_repeats
para = enumerate(Base.product(d_rates, m_rates, population_size, max_iterations_perloop, 1:nb_repeats))
results = SharedArray{Tuple{Int, Int, Int}}(nb_params)
end
for (y , x) in para
results[y] = solve(x[1], x[2], x[3])
end
which worked fine. And then changed the final loop to:
#sync #distributed for (y , x) in para
results[y] = solve(x[1], x[2], x[3])
end
I then got an error (truncated):
ERROR: LoadError: TaskFailedException:
MethodError: no method matching firstindex(::Base.Iterators.Enumerate{Base.Iterators.ProductIterator{Tuple{LinRange{Float64},LinRange{Float64},Int64,Int64,UnitRange{Int64}}}})
Closest candidates are:
firstindex(::Cmd) at process.jl:638
firstindex(::Core.SimpleVector) at essentials.jl:599
firstindex(::Base64.Buffer) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/Base64/src/buffer.jl:18
...
Stacktrace:
[1] (::Distributed.var"#159#161"{var"#271#272",Base.Iterators.Enumerate{Base.Iterators.ProductIterator{Tuple{LinRange{Float64},LinRange{Float64},Int64,Int64,UnitRange{Int64}}}}})() at ./task.jl:332
Stacktrace:
[1] sync_end(::Channel{Any}) at ./task.jl:314
[2] top-level scope at task.jl:333
[3] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1088
[4] include_string(::Module, ::String, ::String) at ./loading.jl:1096
[5] invokelatest(::Any, ::Any, ::Vararg{Any,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at ./essentials.jl:710
[6] invokelatest(::Any, ::Any, ::Vararg{Any,N} where N) at ./essentials.jl:709
Is it possible to pass such a list, if so how?
I assume that all your workers are on a single server and that you have actually added some workers using the addprocs command. The first problem with your code is that you create the SharedArray on all workers. Rather than that the syntax of a SharedArray is the following:
help?> SharedArray
SharedArray{T}(dims::NTuple; init=false, pids=Int[])
SharedArray{T,N}(...)
Construct a SharedArray of a bits type T and size dims across the processes specified by pids - all of which have to be on the same host. (...)
This means that you create SharedArray only once from the master worker and you can specify the workers that are aware of it using the pids argument (if you do not specify pids all worker processes have the access).
Hence your code will look like this:
using Distributed, SharedArrays
addprocs(4)
#everywhere using SharedArrays
#everywhere solve(a,b,c) = return (1,2,3)
#(...) # your setup code without #everywhere
results = SharedArray{Tuple{Int, Int, Int}}(nb_params)
#sync #distributed for (y , x) in collect(para)
results[y] = solve(x[1], x[2], x[3])
end
Note that you will need collect because #distributed macro needs to know the size of the Vector and it does not work good with iterators.
When I tried to calculate
julia> -2.3^-7.6
-0.0017818389423254909
But the result given by my calculator is
0.0005506 + 0.001694 i
Just to be safe I tried it again and this time it complains. Why does it not complain when I tried it the first time?
julia> a = -2.3; b = -7.6; a^b
ERROR: DomainError with -2.6:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.
Stacktrace:
[1] throw_exp_domainerror(::Float64) at ./math.jl:35
[2] ^(::Float64, ::Float64) at ./math.jl:769
[3] top-level scope at none:0
[4] eval at ./boot.jl:319 [inlined]
[5] #85 at /Users/ssiew/.julia/packages/Atom/jodeb/src/repl.jl:129 [inlined]
[6] with_logstate(::getfield(Main, Symbol("##85#87")),::Base.CoreLogging.LogState) at ./logging.jl:397
[7] with_logger(::Function, ::Atom.Progress.JunoProgressLogger) at ./logging.jl:493
[8] top-level scope at /Users/ssiew/.julia/packages/Atom/jodeb/src/repl.jl:128
This is an order of operations issue. You can see how Julia's parsing that expression:
julia> parse("-2.3^-7.6")
:(-(2.3 ^ -7.6))
and so the reason you don't have any problems is because you're actually taking 2.3 ^ (-7.6), which is 0.0017818389423254909, and then flipping the sign.
Your second approach is equivalent to making sure that the "x" in "x^y" is really negative, or:
julia> parse("(-2.3)^-7.6")
:(-2.3 ^ -7.6)
julia> eval(parse("(-2.3)^-7.6"))
ERROR: DomainError:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.
Stacktrace:
[1] nan_dom_err at ./math.jl:300 [inlined]
[2] ^(::Float64, ::Float64) at ./math.jl:699
[3] eval(::Module, ::Any) at ./boot.jl:235
[4] eval(::Any) at ./boot.jl:234
And if we follow that instruction, we get what you expect:
julia> Complex(-2.3)^-7.6
0.0005506185144176565 + 0.0016946295370871215im