UndefVarError but variable is clearly defined - julia

Suppose I have the following code which has two nested while loops.
struct Parameters
maxIter1::Float64
maxIter2::Float64
tolerance1::Float64
tolerance2::Float64
end
mutable struct Guess
x1::Float64
x2::Float64
end
function solveModel(par::Parameters,initGuess::Guess)
iterate1 = 0
error1 = 0
guess = initGuess
while (par.iterate1 < par.maxIter1 && error1 > par.tolerance1)
iterate1 += 1
iterate2 = 0
error2 = 0
guess.x2 = initGuess.x2
while (iterate2 < par.maxIter2 && error2 > par.tolerance2)
iterate2 += 1
z2 = solveInnerProblem(par,guess)
newGuess = update2(par,guess,z2)
error2 = computeError2(newGuess,guess)
guess = newGuess
end
guess = newGuess
end
end
I get an error message,
Note: the reference to the line number is erroenous - line 294 of my code contains no mention whatsoever of newGuess.
The error message goes away if I comment out the line
guess = newGuess
In the outer loop (last line before the final two end lines in the code snippet). I'm quite confused as to why this is happening. The variable newGuess is clearly defined, but Julia says it is not defined...

newGuess is a local variable, which means that it is defined in a localized part of the program rather than all the program. In the case of a local variable defined within a loop like a while statement, the variable is undefined outside the while loop within which it is defined, which is the inner while loop of your function. So the "not defined" error is because the program is trying to access the variable outside of its local scope-- it was defined before, but not when the error occurs.
You may need to define newGuess higher up, within the function, but before the inner while statement.

Related

How can I fix the error Stackoverflow in julia

I write some code below and it works correctly.
function value_counter(data, feature_name)
feature_col = unique(data, feature_name)
unique_val = unique!(unique(data, feature_name))
count_val = []
value_counts_dict = Dict()
for val in unique_val
counter = 0
for col_val in feature_col
if val == col_val
counter += 1
end
end
append!(count_val, counter)
value_counts_dict[val] = counter
end
return value_counts_dict
end
But when I run it over three times. It appears a bug 'Stackoverflow' and I think the error from the unique method. How can I free the stack after running the code?
Update: I try to redefine unique method. It is still errors but this time it's in 'in' method
ERROR: LoadError: StackOverflowError:
Stacktrace:
[1] in(x::SubString{String}, itr::Vector{Any})
# Base .\operators.jl:1283
[2] redefine_unique(data::Vector{Any})
# Main E:\Study\3_grade\Csttnt\Project03_decision_tree\Decision_Tree.jl:35
It's probably not the in method or unique method itself that's causing the stack overflow. Rather, you have some large, probably recursive, stack that just happens to hit the stack size limit when it gets to that downstream function. What you should look for in the stack is where the recursive part is. What functions are being called repeatedly? You may be missing a base case somewhere, or perhaps introduced unexpected recursion into an overwritten Base function, as Sundar mentioned.

Julia: Append to an array

Someone please help me understand this. I have the following code below. I am trying to append index[i]-1 to an empty array. However I am getting this error: "BoundsError: attempt to access 0-element Array{Any,1} at index [1]" :
sample_size_array = [9,5,6,9,2,6,9]
n_minus_1 = []
array_length = length(sample_size_array)
for i in 1:array_length
n_minus_1[i].append(sample_size_array[i] -1)
end
println(n_minus_1)
If Julia does not understand array[0] then why is i starting at 0 and not at 1?
Your code has two problems:
in the first iteration you are trying to access n_minus_1 array at index 1 while this array is still empty (has 0 length) - this throws you an error;
in Julia you do not invoke methods using a . (this symbol is used for different purposes - in this case it is parsed as field access and also would throw an error later)
To solve both those problems use push! function which appends an element at the end of an array. The code could look like this:
sample_size_array = [9,5,6,9,2,6,9]
n_minus_1 = []
array_length = length(sample_size_array)
for i in 1:array_length
push!(n_minus_1, sample_size_array[i]-1)
end
println(n_minus_1)
However in this case the whole operation can be written even simpler as:
n_minus_1 = sample_size_array .- 1
and you do not need any loop (and here you see another use of . in Julia - in this case we use it to signal that we want to subtract 1 from every element of sample_size_array).

Defining tables - strange bug

I got a strange kind of issue. When I define this table:
function test()
a = Float32[0.3010299957,0.3010299957,-0.3010299957,0.3010299957,0.3010299957]
return a[1]*a[3]
end
It's fine. After call test() i got correct output. But when I define this one, there is an error ErrorException("−3 not defined"):
function test()
a = Float32[2.718281828, −3.141592654 , 1.414213562 , 0.5772156649 , 0.3010299957]
return a[1]*a[2]
end
You're using two different dashes: - (HYPHEN-MINUS) in the first, and − (MINUS SIGN) in the second. Issues like these often happen when you copy text from a formatted source (web page, document, etc.) You want to use HYPHEN-MINUS:
julia> -1 # hyphen-minus
-1
julia> −1 # minus sign
ERROR: syntax: invalid character "−"

How can one give command line arguments to variables in a separate procedure using object references?

IDL beginner here! Let's say I have two procedures, PRO1 and PRO2. If I receive a command line argument in PRO2, how can I give the argument value to a variable in PRO1?
I have previously tried to make an object reference ,'My', to PRO1, but I receive a syntax error on line 6.
PRO PRO2
opts = ob_new('mg_options)
opts.addOption, 'value', 'v'
opts.parseArgs,error_message = errorMsg
My = obj_new('PRO1')
My.A=opts.get('value')
END
For reference, I attempted to follow these instructions for receiving command line arguments: http://michaelgalloy.com/2009/05/11/command-line-options-for-your-idl-program.html
I had something else here, but I think your example above is actually what you want to avoid, yes? I'm not sure how it ends up being all that different, but if you want to make your procedure an object, you'll have to define an actual object (see here) and create methods for it containing your code functionality. Here's something close-ish.
In a file called pro1__define.pro:
function pro1::Init
self.A = 0L
return, 1
end
pro pro1::process, in_val
self.A = in_val
print, self.A
end
pro pro1__define
struct = {pro1, A:0L}
end
Then in pro2 you would do something like
arg = 2
pro1_obj = pro1()
pro1_obj->process, arg
Depending on which version of IDL you are using you may have to modify the initialization line to the obj_new() syntax.

Stack overflow error when do a loop inside another loop

In a classic ASP function, when I do a loop inside another as shown in the code below I have a stack overflow error.
Function shift(x,y)
shift = x
For i = 1 to y
shift = shift*2
Next
End Function
Function translate_url(iVal)
sAlpha = "abcdefghijklmnopqrstuvwxyz-_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
doWrite = False
iBase = 63 'DO NOT CHANGE
For i = 4 to 0 step -1
iPos = (iVal and shift(iBase, i*6))/shift(1, i*6)
If iPos Then doWrite = True
If doWrite Then translate_url = translate_url & Mid(sAlpha, iPos + 1,1)
Next
End Function
arr = Split("1,2,3,4,5,6,7,8,9,0",",")
For Each i In arr
response.Write(translate_url(arr(i)))
next
The error does not occur when I remove the loop outside the function. Eg:
response.Write(translate_url(arr(1)))
return "c".
What I need to do to make the code flows down the array and return the corresponding values ​​according to the function?
VBScript has a dark side. Variables scope is one of them.
When you don't declare a variable, VBScript will do it for you, free of charge or error and give it global scope.
What does it mean? Take a look in the main loop:
For Each i In arr
response.Write(translate_url(arr(i)))
next
The i variable becomes global. When you have this later in the function:
For i = 4 to 0 step -1
'...
Next
It's changing the same i variable. This is causing endless loop of function calls.
To resolve this, declare i locally in each function:
Function shift(x,y)
Dim i
'...
End Function
Function translate_url(iVal)
Dim i
'...
End Function
And it will be different variable and no overflow.
As the EVIL global variable i is used in your top level loop and in the functions shift() and translate_url(), you got what you deserve.
Evidence: Just change your loop to
For Each NoliMeTangere In arr
response.Write translate_url(arr(NoliMeTangere))
next
Remedy: Use "Option Explicit" and Dim all local variables in your Subs/Functions/Methods.

Resources