I'm using Julia version 1.6.2
julia> 2 < 1
false
julia> 2.0f32 < 1.0f32
false
julia> 2 < 1.0f32
true
Is this expected behavior? I don't understand what's going on here.
The reason is that 32 is exponent value, so you have:
julia> Float32(1)
1.0f0
julia> big(1.0f32)
1.00000003318135351409612647563264e+32
and therefore:
julia> 1 == 1.0f32
false
julia> 1 == 1.0f0
true
Related
Here is the problem. I want to write a convolution for two simple signals x[n]=0.2^n*u[n] and h[n]=u[n+2] for some values of n. This is how I implement it:
using Plots, DSP
x(n) = if n<0 0 else 0.2^n end
h(n) = if n<-2 0 else 1 end
n = -10:10
conv(h.(n),x.(n))
It doesn't work. Here is the error:
`float` not defined on abstractly-typed arrays; please convert to a more specific type
Any idea how may I fix it?
I ran it fine with a fresh REPL session:
julia> using Plots, DSP
[ Info: Precompiling Plots [91a5bcdd-55d7-5caf-9e0b-520d859cae80]
[ Info: Precompiling DSP [717857b8-e6f2-59f4-9121-6e50c889abd2]
julia> x(n) = if n<0 0 else 2^n end
x (generic function with 1 method)
julia> h(n) = if n<-2 0 else 1 end
h (generic function with 1 method)
julia> n = -10:10
-10:10
julia> conv(h.(n),x.(n))
41-element Array{Int64,1}:
0
0
(etc)
1984
1920
1792
1536
1024
julia> plot(conv(h.(n),x.(n)))
(plots ok)
If you change the 2 in 2^n to a float you need to specify Float64:
julia> x(n) = if n<0 0 else 0.2^n end
x (generic function with 1 method)
julia> conv(h.(n),Float64.(x.(n)))
41-element Array{Float64,1}:
0.0
8.458842092382145e-17
2.5376526277146434e-16
4.229421046191072e-17
2.1147105230955362e-16
(etc)
7.997440000004915e-5
1.597440000003685e-5
3.1744000002024485e-6
6.144000000924524e-7
1.0240000015600833e-7
Why does this happen in Julia?
My input is
A = []
for i = 17:21
t = 1/(10^(i))
push!(A, t)
end
return(A)
And the output was:
5-element Array{Any,1}:
1.0e-17
1.0e-18
-1.1838881245526248e-19
1.2876178137472069e-19
2.5800991659088344e-19
I observed that
A[3]>0
false
I want to find the number which act to 0 of Julia, but I found this and don’t understand.
The reason for this problem is when you have i = 19, note that then:
julia> 10^19
-8446744073709551616
and it is unrelated to floating point numbers, but is caused by Int64 overflow.
Here is the code that will work as you expect. Either use 10.0 instead of 10 as 10.0 is a Float64 value:
julia> A=[]
Any[]
julia> for i=17:21
t=1/(10.0^(i))
push!(A,t)
end
julia> A
5-element Array{Any,1}:
1.0e-17
1.0e-18
1.0e-19
1.0e-20
1.0e-21
or using high precision BigInt type that is created using big(10)
julia> A=[]
Any[]
julia> for i=17:21
t=1/(big(10)^(i))
push!(A,t)
end
julia> A
5-element Array{Any,1}:
9.999999999999999999999999999999999999999999999999999999999999999999999999999967e-18
9.999999999999999999999999999999999999999999999999999999999999999999999999999997e-19
9.999999999999999999999999999999999999999999999999999999999999999999999999999997e-20
1.000000000000000000000000000000000000000000000000000000000000000000000000000004e-20
9.999999999999999999999999999999999999999999999999999999999999999999999999999927e-22
You can find more discussion of this here https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#Overflow-behavior.
For example notice that (which you might find surprising not knowing about the overflow):
julia> x = typemin(Int64)
-9223372036854775808
julia> x^2
0
julia> y = typemax(Int64)
9223372036854775807
julia> y^2
1
Finally to find smallest positive Float64 number use:
julia> nextfloat(0.0)
5.0e-324
or
julia> eps(0.0)
5.0e-324
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
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.
How do you do simply select a subset of an array based on a condition? I know Julia doesn't use vectorization, but there must be a simple way of doing the following without an ugly looking multi-line for loop
julia> map([1,2,3,4]) do x
return (x%2==0)?x:nothing
end
4-element Array{Any,1}:
nothing
2
nothing
4
Desired output:
[2, 4]
Observed output:
[nothing, 2, nothing, 4]
You are looking for filter
http://docs.julialang.org/en/release-0.4/stdlib/collections/#Base.filter
Here is example an
filter(x->x%2==0,[1,2,3,5]) #anwers with [2]
There are element-wise operators (beginning with a "."):
julia> [1,2,3,4] % 2 .== 0
4-element BitArray{1}:
false
true
false
true
julia> x = [1,2,3,4]
4-element Array{Int64,1}:
1
2
3
4
julia> x % 2 .== 0
4-element BitArray{1}:
false
true
false
true
julia> x[x % 2 .== 0]
2-element Array{Int64,1}:
2
4
julia> x .% 2
4-element Array{Int64,1}:
1
0
1
0
You can use the find() function (or the .== syntax) to accomplish this. E.g.:
julia> x = collect(1:4)
4-element Array{Int64,1}:
1
2
3
4
julia> y = x[find(x%2.==0)]
2-element Array{Int64,1}:
2
4
julia> y = x[x%2.==0] ## more concise and slightly quicker
2-element Array{Int64,1}:
2
4
Note the .== syntax for the element-wise operation. Also, note that find() returns the indices that match the criteria. In this case, the indices matching the criteria are the same as the array elements that match the criteria. For the more general case though, we want to put the find() function in brackets to denote that we are using it to select indices from the original array x.
Update: Good point #Lutfullah Tomak about the filter() function. I believe though that find() can be quicker and more memory efficient. (though I understand that anonymous functions are supposed to get better in version 0.5 so perhaps this might change?) At least in my trial, I got:
x = collect(1:100000000);
#time y1 = filter(x->x%2==0,x);
# 9.526485 seconds (100.00 M allocations: 1.554 GB, 2.76% gc time)
#time y2 = x[find(x%2.==0)];
# 3.187476 seconds (48.85 k allocations: 1.504 GB, 4.89% gc time)
#time y3 = x[x%2.==0];
# 2.570451 seconds (57.98 k allocations: 1.131 GB, 4.17% gc time)
Update2: Good points in comments to this post that x[x%2.==0] is faster than x[find(x%2.==0)].
Another updated version:
v[v .% 2 .== 0]
Probably, for the newer versions of Julia, one needs to add broadcasting dot before both % and ==