LoadError: UndefVarError in julia for loop - julia

I am defining a variable phi_old at the start of my function, and assigning it a value of phi_start.
I then have an iterative loop that:
uses phi_old
solves a PDE to get a solution T
uses the solution T to calculate phi_new
checks the difference between phi_new and phi_old, if it is larger than error the iterative loop begins again, with phi_old using the values of phi_new.
if the difference is less than the error, the iteration stops.
But I am getting this error:
Warning: Assignment to `T` in soft scope is ambiguous because a global variable by the same name exists:
ERROR: LoadError: UndefVarError: phi_old not defined
Here is an example of my code's structure:
phi_old = createCellVariable(m,phi_start)
for i=1:i_end
phi_new = myfunction(T)
error = sum(phi_new.value[2,1:end]-phi_old.value[2,1:end])
if error > 1E-03
phi_old = phi_new
else
i=i+1
break
end
end
Are there any techniques I could use to better initialize/assign my arrays and fix this error? The arrays are quite large, so I would like to preallocate if possible, and only copy arrays if necessary.

Related

Julia: Even-number datatype for functions

I have about 50 functions which should consume only even positive numbers. Right now I am checking each time with an "if" whether the number put in is zero or not:
function grof(x::Int)
if (x % 2) == 0
println("good")
else
throw("x is not an even number!!!!!!!!!!!!! Stupid programmer!")
end
end
Ideally, I would like to have a datatype which produces this automatically, i.e.
function grof(x::EvenInt)
println("good")
end
However, I am not able to produce this datatype by my own since I am unable to understand the documentary. Thanks for your help!
Best, v.
I don't think creating a type is warranted in such a situation: I would simply #assert that the condition is verified at the beginning of the function(s). (Funnily enough, checking the whether a number is even is the example that was chosen in the documentation to illustrate the effect of #assert)
For example:
julia> function grof(x::Int)
#assert iseven(x) "Stupid programmer!"
println("good")
end
grof (generic function with 1 method)
julia> grof(2)
good
julia> grof(3)
ERROR: AssertionError: Stupid programmer!
Stacktrace:
[1] grof(::Int64) at ./REPL[5]:2
[2] top-level scope at REPL[7]:1
EDIT: If you really want to create a type enforcing such a constraint, it is possible. The way to do this would be to
create a type (possibly subtyping one of the Number abstract types; maybe Signed)
define an inner constructor ensuring that such a type cannot hold an odd value
A very simple example to build upon would be along the lines of:
# A wrapper around an even integer value
struct EvenInt
val :: Int
# inner constructor
function EvenInt(val)
#assert iseven(val)
new(val)
end
end
# Accessor to the value of an EvenInt
val(x::EvenInt) = x.val
# A method working only on even numbers
grof(x::EvenInt) = println("good: $(val(x)) is even")
You'd use this like so:
julia> x = EvenInt(42)
EvenInt(42)
julia> grof(x)
good: 42 is even
julia> y = EvenInt(1)
ERROR: AssertionError: iseven(val)
Stacktrace:
[1] EvenInt(::Int64) at ./REPL[1]:5
[2] top-level scope at REPL[6]:1
but note that you can't do anything on EvenInts yet: you need to either unwrap them (using val() in this case), or define operations on them (a task which can be vastly simplified if you make EvenInt a subtype of one of the abstract number types and follow the relevant interface).
All integers multiplied by two are even, so redefine your function to take half the number it currently takes.
function grof2(halfx::Int)
x=2*halfx
println("good")
end

Error: Symbol at (1) is not a DUMMY variable [duplicate]

This question already has answers here:
"Unclassifiable statement" when referencing a function
(1 answer)
Fortran array cannot be returned in function: not a DUMMY variable
(1 answer)
Closed 3 years ago.
I tried to write a code which gives GCD of two number:
program main
implicit none
integer::A,B,gcd,ans=0
read*,A,B
gcd(A,B)
write(*,*)'GCD of ',A,' and ',B,': ',ans
end program main
recursive function gcd(A,B) result(ans)
implicit none
integer,intent(in)::A,B
integer::ans
if (A==0) ans=B
if (B==0) ans=A
!base_case
if (A==B) ans=A
!recursive_case
if (A>B)then
ans=gcd(A-B,B)
else
ans=gcd(A,B-A)
end if
end function gcd
My input was:
98 56
I expect 14 but got this error:
source_file.f:5:4:
gcd(A,B)
1
Error: Unclassifiable statement at (1)
I didn't understand why I am getting this error? I heartily thank if anyone explain me why am I getting error.
You cannot specify intent(out) or any other intent or related attribute for the result variable. See Fortran array cannot be returned in function: not a DUMMY variable
Use just
integer::ans
In addition, just
gcd(A,B)
is not a valid way to use a function in Fortran. Use
ans = gcd(A,B)
or
print *, gcd(A,B)
or similar.
Please realize that ans declared in the main program is a variable that is not related to the result variable of the function. Even if the name is the same, they are two different things. It will be better to rename one of them to make it clear.

Why is a Julia function name (without arguments) silently ignored?

I have a script that defines a function, and later intended to call the function but forgot to add the parentheses, like this:
function myfunc()
println("inside myfunc")
end
myfunc # This line is silently ignored. The function isn't invoked and there's no error message.
After a while I did figure out that I was missing the parentheses, but since Julia didn't give me an error, I'm wondering what that line is actually doing? I'm assuming that it must be doing something with the myfunc statement, but I don't know Julia well enough to understand what is happening.
I tried --depwarn=yes but don't see a julia command line switch to increase the warning level or verbosity. Please let me know if one exists.
For background context, the reason this came up is that I'm trying to translate a Bash script to Julia, and there are numerous locations where an argument-less function is defined and then invoked, and in Bash you don't need parentheses after the function name to invoke it.
The script is being run from command line (julia stub.jl) and I'm using Julia 1.0.3 on macOS.
It doesn't silently ignore the function. Calling myfunc in an interactive session will show you what happens: the call returns the function object to the console, and thus call's the show method for Function, showing how many methods are currently defined for that function in your workspace.
julia> function myfunc()
println("inside myfunc")
end
myfunc (generic function with 1 method)
julia> myfunc
myfunc (generic function with 1 method)
Since you're calling this in a script, show is never called, and thus you don't see any result. But it doesn't error, because the syntax is valid.
Thanks to DNF for the helpful comment on it being in a script.
It does nothing.
As in c, an expression has a value: in c the expression _ a=1+1; _ has the value _ 2 _ In c, this just fell out of the parser: they wanted to be able to evaluate expressions like _ a==b _
In Julia, it's the result of designing a language where the code you write is handled as a data object of the language. In Julia, the expression "a=1+1" has the value "a=1+1".
In c, the fact that
a=1+1;
is an acceptable line of code means that, accidentally,
a;
is also an acceptable line of code. The same is true in Julia: the compiler expects to see a data value there: any data value you put may be acceptable: even for example the data value that represents the calculated value returned by a function:
myfunc()
or the value that represents the function object itself:
myfunc
As in c, the fact that data values are everywhere in your code just indicates that the syntax allows data values everywhere in your code and that the compiler does nothing with data values that are everywhere in your code.

log() negative number throwing domain error

I am attempting to broadcast the log function in a script I am writing.
It is throwing a domain error
julia> log(100)
4.605170185988092
julia> log(-100)
ERROR: DomainError:
Is there a way around this at all? I have a mix of - , + in my array.
For real input the log function returns real numbers. If the log function were to promote the type of log(-100) automatically (to complex numbers) it would be type unstable.
You can do log(complex(-100)) to get complex output (or log.(complex.(array)) for your array of numbers).

Debugging unexpected errors in R -- how can I find where the error occurred?

Sometimes R throws me errors such as
Error in if (ncol(x) != 2) { : argument is of length zero
with no additional information, when I've written no such code. Is there a general way for finding which function in which package causes an error?
Since most packages come compressed, it isn't trivial to grep /usr/lib/R/library.
You can use traceback() to locate where the last error occurred. Usually it will point you to a call you make in your function. Then I typically put browser() at that point, run the function again and see what is going wrong.
For example, here are two functions:
f2 <- function(x)
{
if (x==1) "foo"
}
f <- function(x)
{
f2(x)
}
Note that f2() assumes an argument of length 1. We can misuse f:
> f(NULL)
Error in if (x == 1) "foo" : argument is of length zero
Now we can use traceback() to locate what went wrong:
> traceback()
2: f2(x) at #3
1: f(NULL)
The number means how deep we are in the nested functions. So we see that f calls f2 and that gives an error at line 3. Pretty clear. We could reassign f with browser placed just before the f2 call now to check it's input. browser() simply allows you to stop executing a function and look around in its environment. Similar to debug and debugonce except that you don't have to execute every line up until the point you know something goes wrong.
Just to add to what #SachaEpskamp has already suggested, setting options(error=recover) and options(show.error.locations=TRUE) can be extremely helpful when debugging unfamiliar code. The first causes R to launch a debugging session on error, giving you the option to invoke the browser at any point in the call stack up to that error. The second option will tell R to include the source line number in the error.

Resources