julia inf by inf different results - julia

I'm quite new to Julia - version 1.0.0 on Windows. The documentation states the following
julia> Inf / Inf
NaN
But when I perform the following I'm getting different results
julia> 1/0
Inf
julia> 1/0 / 1/0 # this should be NaN right, tried (1/0)/(1/0) as well
Inf
julia> 1/0
Inf
julia> ans/ans
NaN
Why 1/0 / 1/0 is not NaN, whereas ans/ans is?

You actually have:
julia> (1/0)/(1/0)
NaN
so this is consistent.
Now regarding:
julia> 1/0 / 1/0
Inf
Please observe how it is evaluated:
julia> :(1/0 / 1/0)
:(((1 / 0) / 1) / 0)
so we get a standard left to right evaluation (as should be expected). And you get:
julia> 1/0
Inf
julia> (1/0)/1
Inf
julia> ((1/0)/1)/0
Inf
And all is OK.
Actually here you have one special thing to observe (this is not directly related to your question but is good to know as it might come up as a next question):
julia> Inf / 0
Inf
julia> Inf / (-0)
Inf
julia> Inf / (0.0)
Inf
julia> Inf / (-0.0)
-Inf
The reason is that integer 0 is the same as -0:
julia> 0 === -0
true
but floats carry sign bit:
julia> 0.0 === -0.0
false

Related

What is the difference between Mapreduce and Filter with sum in Julia?

Julia version: 1.4.0
I have these two snippets, I think they should be equivalent but they produce very different results. What am I missing?
samples is Vector{Float64} with 1000000 elements. Moreover, it's a random sampling of a posterior distribution.
mapreduce(p -> p < 0.5 ? 1 : 0, +, samples) / N
sum(filter(x-> x<0.5, samples))/N
Your mapreduce is mapping each element to either 1 or 0. Instead, you want to map each element to either p or 0.
julia> N = 1000000;
julia> samples = randn(1000000);
julia> mapreduce(p -> p < 0.5 ? 1 : 0, +, samples) / N
0.690901
julia> mapreduce(p -> p < 0.5 ? p : -0.0, +, samples) / N
-0.35058272143615
julia> sum(filter(x-> x<0.5, samples))/N
-0.35058272143615005
These may still see a very very slight difference (in this case it's just 1 unit-in-the-last-place) because the results will depend upon the order of summation.

How to check if two arrays are equal even if they contain NaN values in Julia?

I am trying to compare two arrays. It just so happens that the data for the arrays contains NaN values and when you compare arrays with NaN values, the results are not what I would have expected.
julia> a = [1,2, NaN]
3-element Array{Float64,1}:
1.0
2.0
NaN
julia> b = [1,2, NaN]
3-element Array{Float64,1}:
1.0
2.0
NaN
julia> a == b
false
Is there an elegant way to ignore these Nan's during comparison or replace them efficiently?
Use isequal:
Similar to ==, except for the treatment of floating point numbers and
of missing values. isequal treats all floating-point NaN values as
equal to each other, treats -0.0 as unequal to 0.0, and missing as
equal to missing. Always returns a Bool value.
julia> a = [1,2, NaN]
3-element Array{Float64,1}:
1.0
2.0
NaN
julia> b = [1,2, NaN]
3-element Array{Float64,1}:
1.0
2.0
NaN
julia> isequal(a, b)
true
You probably want to use isequal(a, b) (which also treats missing equal to missing, but -0.0 as unequal to 0.0).
You could filter out the NaN's on each array:
a = [1, 2, NaN]
filteredA = filter(x -> !isnan(x), a)
b = [1, 2, NaN]
filteredB = filter(x -> !isnan(x), b)
print(a == b)
print(filteredA == filteredB)
You could then create a function that does the filtering, and a custom compare function that uses the filtering function on both arguments and compare. Not sure if there is a more Julia-esque way.
Or create a new type. And create a Singleton nan which you use instead of NaN.
struct MyNaN end
nan = MyNaN()
and write a function for replacing NaNs by it.
with_nan(l) = map((x) -> if isnan(x) nan else x end, l)
Then you can wrap your lists using this function.
a = [1, 2, NaN]
b = [1, 2, NaN]
with_nan(a) == with_nan(b)
## true

Julia: Finding values larger than 0 in vector with missing

I'm fairly new to Julia and as a Matlab/R User I find it, for the most part, really nice to work with.
However, I'm a little confused by the missing values and how to work with them.
Let's say I have a vector:
a=[missing -1 2 3 -12] #Julia
a=[NaN -1 2 3 -12] #Matlab
In Matlab I would just do the following to find the values below 0
a(a<0)
which gives me
-1 -12
The same unfortunately doesn't work in Julia and when I try
a[a.<0]
in Julia I just get the following error
ERROR: ArgumentError: unable to check bounds for indices of type Missing
I also tried the following
a[findall(skipmissing(a).<0)]
which gives me
missing
3
since, of course, I skipped the missing value in the findall-function. I'm pretty sure there is an easy and logical way to do this, but I don't seem to be able to find it.
Can someone please show me the way?
Best,
Richard
Here is the simplest way to do it:
julia> a=[missing -1 2 3 -12]
1×5 Array{Union{Missing, Int64},2}:
missing -1 2 3 -12
julia> a[isless.(a, 0)]
2-element Array{Union{Missing, Int64},1}:
-1
-12
This uses the fact that missing is considered larger than any number by isless.
Another way to write it:
julia> filter(x -> isless(x, 0), a)
2-element Array{Union{Missing, Int64},1}:
-1
-12
Now in order to avoid this special trick with isless you can do the following (using coalesce is a general approach that can be used for safe handling of missing values):
julia> a[coalesce.(a .< 0, false)]
2-element Array{Union{Missing, Int64},1}:
-1
-12
or
julia> filter(x -> coalesce(x < 0, false), a)
2-element Array{Union{Missing, Int64},1}:
-1
-12
finally you can be more explicit like:
julia> filter(x -> !ismissing(x) && x < 0, a)
2-element Array{Union{Missing, Int64},1}:
-1
-12
or
julia> [v for v in a if !ismissing(v) && v < 0]
2-element Array{Int64,1}:
-1
-12
(you could use comprehension syntax also in the examples above)

In Julia: Equality of Float64 and BigFloat

In the Julia 1.0.0 REPL I get the following results:
# Line 1: This make sense. I did not expect a Float64 to equal a BigFloat.
julia> 26.1 == big"26.1"
false
# Line 2: This surprised me when Line 1 is considered. Again, like Line 1, I
# did not expect a Float64 to equal an equivalent BigFloat.
julia> 26.0 == big"26.0"
true
# Line 3: This I expected based on Line 1 behavior.
julia> 26.1 - 0.1 == big"26.1" - 0.1
false
# Line 4: This surprised me based on Line 1 behavior, but it might be
# explained based on Line 2 behavior. It seems to imply that if a Float64
# can be converted to an Integer it will compare equal to an equivalent BigFloat.
julia> 26.1 - 0.1 == big"26.1" - big"0.1"
true
It seems that Julia is doing something under the hood here for equality comparisons with Float64 and BigFloat that makes lines 2 and 4 true, while lines 1 and 3 are false. Any suggestions?
The Julia doc regarding "==" does not seem to cover this kind of thing:
https://docs.julialang.org/en/v1/base/math/#Base.:==
EDIT:
Based on a helpful comment by #EPo below, it is easy to make all comparisons above come out to true. For example, Line 1 and Line 3 are true below, though they were false above:
# Line 1 is now true.
julia> 26.1 ≈ big"26.1"
true
# Line 3 is now true.
julia> 26.1 - 0.1 ≈ big"26.1" - 0.1
true
Some floating point number can be represented exactly (26.0) but not all, for instance:
julia> using Printf
julia> #printf("%.80f",26.0)
26.00000000000000000000000000000000000000000000000000000000000000000000000000000000
julia> #printf("%.80f",0.1)
0.10000000000000000555111512312578270211815834045410156250000000000000000000000000
The decimals 0.5, 0.25, 0.125 for example can be also represented exactly with the binary based floating point representation. So for instance you have:
julia> 26.125 - 0.125 == big"26.125" - 0.125
true
But 0.1 is a periodic number in the binary system, so it is rounded.
julia> bitstring(0.1)
"0011111110111001100110011001100110011001100110011001100110011010"
The last 52 bits represent the fraction in binary. (https://en.wikipedia.org/wiki/Double-precision_floating-point_format)
The reason they are not the same is because they are not the same
julia> using Printf
julia> string(BigFloat("26.1")-BigFloat("26"))
"1.000000000000000000000000000000000000000000000000000000000000000000000000000553e-01"
julia> #printf("%.17e",Float64(26.1)-Float64(26))
1.00000000000001421e-01
julia> Float64(26.1)-Float64(26) > BigFloat("26.1")-BigFloat("26")
true

Understanding Julia Int overflow behaviour

Coming from a Python / Matlab background, I'd like to understand better how Julia's Int64 overflow behaviour works.
From the documentation:
In Julia, exceeding the maximum representable value of a given type
results in a wraparound behavior.
julia> x = typemax(Int64)
9223372036854775807
julia> x + 1
-9223372036854775808
Now, I did some experiments with numbers obviously larger than typemax(Int64), but the behaviour I see isn't consistent with the documentation. It seems like things don't always just wrap around. Is only a single wraparound allowed?
julia> x = (10^10)^(10^10)
0
julia> x = 10^10^10^10
1 # ??
julia> x = 10^10^10^10^10
10 # I'd expect it to be 1? 1^10 == 1?
julia> x = 10^10^10^10^10^10
10000000000 # But here 10^10 == 10000000000, so now it works?
julia> typemax(Int64) > 10^19
true
julia > typemax(Int64) > -10^19
true
Can anyone shed light on the behaviour I am seeing?
EDIT:
Why does 9 overflow correctly, and 10 doesn't?
julia> 9^(10^14)
-1193713557845704703
julia> 9^(10^15)
4900281449122627585
julia> 10^(10^2)
0
julia> 10^(10^3)
0
Julia 0.5.0 (2016-09-19)
What you are seeing the result of PEMDAS order of operations, specifically the parenthesis before exponentiation portion. This effectively becomes a right-to-left solving of these expressions.
julia> 10^(10^10) #happens to overflow to 0
0
julia> 10^(10^(10^10)) # same as 10 ^ 0
1
julia> 10^(10^(10^(10^(10^10)))) # same as x = 10^(10^(10^(10^(10000000000)))) -> 10^(10^(10^(0))) -> 10^(10^(1)) -> 10^ 10
10000000000
So it's really just a matter of working through the arithmetic. Or realizing you are going to have such large operations that you start using BigInt from the outset.

Resources