How to use Base.Rounding.RoundNearestTiesAway : rounded away from zero in Julia - julia

How to round away from zero in Julia?
I have seen the documentation here:
https://docs.julialang.org/en/v1/base/math/#Base.Rounding.RoundNearestTiesAway
How to use this in Julia?
Can it be used along with round ?
-1.5 gives -2
1.5 gives 2

Pass rounding mode as an argument to round. By default ties are rounded to even number:
julia> tuple.(x, round.(-4.5:4.5))
10-element Vector{Tuple{Float64, Float64}}:
(-4.5, -4.0)
(-3.5, -4.0)
(-2.5, -2.0)
(-1.5, -2.0)
(-0.5, -0.0)
(0.5, 0.0)
(1.5, 2.0)
(2.5, 2.0)
(3.5, 4.0)
(4.5, 4.0)
but if you want to round ties away from zero use:
julia> tuple.(x, round.(-4.5:4.5, RoundNearestTiesAway))
10-element Vector{Tuple{Float64, Float64}}:
(-4.5, -5.0)
(-3.5, -4.0)
(-2.5, -3.0)
(-1.5, -2.0)
(-0.5, -1.0)
(0.5, 1.0)
(1.5, 2.0)
(2.5, 3.0)
(3.5, 4.0)
(4.5, 5.0)
As you can see for 1.5 and -1.5 there is no difference between default rounding mode and the rounding mode you want. But for 2.5 and -2.5 there is a difference.

Related

Calculating n-roots of unity in Julia

I would like to have an algorithm in Julia depending on $n$, such that it generates the n-roots of unity.
(1,w^{1}, w^{2}, ..., w^{n-1}. Such that for every 1\leq i\leq n, we have that (w^{i})^{n}-1=0 )
Thank you so much for your collaboration,
julia> roots(n) = map(cispi, range(0, 2, length=n+1)[1:end-1])
roots (generic function with 1 method)
julia> roots(8)
8-element Vector{ComplexF64}:
1.0 + 0.0im
0.7071067811865476 + 0.7071067811865476im
0.0 + 1.0im
-0.7071067811865476 + 0.7071067811865476im
-1.0 + 0.0im
-0.7071067811865476 - 0.7071067811865476im
0.0 - 1.0im
0.7071067811865476 - 0.7071067811865476im
You could write roots_exp(n) = exp.(im .* range(0, 2pi, length=n+1)[1:end-1]), but for a pure imaginary argument, cis is slightly more efficient than exp. And cispi is slightly more accurate, or at least, more likely to give you nice round numbers when you expect them, as shown above.

Error using in() with an array of tuples using Julia

I have 2 arrays of tuples and I have a loop asking if one element is in the other.
At each step I ask if the tuple contained in the coord array is in the Y array. The loop works fine except for one element which I cant explain why. Here is what I have :
Y[55:65] # This is the array I want to check at each step if my state is in or not.
11-element Array{Any,1}: (2.0, 1.0) (3.0, 1.0) (4.0, 1.0) (5.0,
1.0) (6.0, 1.0) (7.0, 1.0) (8.0, 1.0) (9.0, 1.0) (10.0, 1.0) (11.0, 1.0) (12.0, 1.0)
coord[i-1] # this is one element of coord that is in Y
0-dimensional Array{Tuple{Float64,Float64},0}: (6.0, 1.0)
coord[i] # this is an other element of coord that is in Y
0-dimensional Array{Tuple{Float64,Float64},0}: (7.0, 1.0)
But then when I test when they are in Y:
in(coord[i],Y[55:65]) # testing if coord[i] is in Y
false
in(coord[i-1],Y[55:65]) # testing if coord[i-1] is in Y
true
I dont understand: they are both represented in the same way in Y, they have the same type, why do I get from using in() that one is in and not the other?
I use Julia version 0.6.3.
Thanks in advance for the help!
How did you get coord and Y? If you get them by calculations rather than direct assignments, they may not be exactly equal even if they are displayed so. For example:
julia> p1 = fill((6.0, 1.0))
0-dimensional Array{Tuple{Float64,Float64},0}:
(6.0, 1.0)
julia> p2 = fill((7.0 + 3eps(), 1.0))
0-dimensional Array{Tuple{Float64,Float64},0}:
(7.000000000000001, 1.0)
julia> Y = [p1, p2]
2-element Array{Array{Tuple{Float64,Float64},0},1}:
(6.0, 1.0)
(7.0, 1.0) # NOTE that it get truncated in display but the content did not changed!
julia> x = fill((6.0, 1.0))
0-dimensional Array{Tuple{Float64,Float64},0}:
(6.0, 1.0)
julia> x in Y
true
julia> x = fill((7.0, 1.0))
0-dimensional Array{Tuple{Float64,Float64},0}:
(7.0, 1.0)
julia> x in Y
false
If this is the case, you can either round them before comparing or write the in function mannually using isapprox (or the ≈ operator, typed in Julia by \approx + Tab)

What's Julia's equivalent of R's seq(..., length.out = n)

I can see from this link that R's equivalent of seq is n:m in (http://www.johnmyleswhite.com/notebook/2012/04/09/comparing-julia-and-rs-vocabularies/).
But the case of seq(a,b, length.out = n) is not covered.
For example seq(1, 6, length.out=3) gives c(1.0, 3.5, 6.0). It is a really nice way to specify the number of outputs.
What's its equivalent in Julia?
As of Julia 1.0:
linspace has been deprecated. You can still use range:
julia> range(0, stop = 5, length = 3)
0.0:2.5:5.0
As #TasosPapastylianou noted, if you want this to be a vector of values, you can use collect:
julia> collect( range(0, stop = 5, length = 3) )
3-element Array{Float64,1}:
0.0
2.5
5.0
You are looking for the linspace function. Note this is synonymous to the equivalent function in matlab / octave.
Also note that this returns a "steprange" type object:
julia> a = linspace(1,5,9)
1.0:0.5:5.0
julia> typeof(a)
StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}
julia> collect(a)
9-element Array{Float64,1}:
1.0
1.5
2.0
2.5
3.0
3.5
4.0
4.5
5.0
PS: similarly, there exists a range function which is equivalent to the start:step:stop syntax, similar to the seq(from=, to=, by=) syntax in R.

How to use comprehensions on linspace to create matrix

I would like to produce an n x 3 matrix where n is the number of pixels (width * height).
x = linspace(-1, 1, width)
y = linspace(-1, 1, height)
r = 1.0
viewDirections = [[i j 1.0] for i in x for j in y]
However, when I run this I get a:
16-element Array{Array{Float64,2},1}
and not my desired a 16x3 Array{Float64,2}. I am obviously not using comprehensions properly to construct matrices. I tried using comprehensions to create an array of tuples, but I can't then convert those tuples into a matrix.
The problem here is array comprehension will give us a nested array instead of a Matrix. This is the right behavior of comprehension, it won't do extra guesswork for us, so we need to convert the nested array to matrix manually, which can be done using vcat with splating operator(...):
julia> vcat(viewDirections...)
6×3 Array{Float64,2}:
-1.0 -1.0 1.0
-1.0 1.0 1.0
0.0 -1.0 1.0
0.0 1.0 1.0
1.0 -1.0 1.0
1.0 1.0 1.0
It seems like you're constructing homogeneous coordinates from 2D Euclidean space. Using Base.Iterators.product is a more concise and robust way to create the iterator:
julia> w = linspace(-1,1,3)
-1.0:1.0:1.0
julia> h = linspace(-1,1,2)
-1.0:2.0:1.0
julia> r = 1.0
1.0
julia> viewDirections = [collect(i) for i in Iterators.product(w, h, r)]
3×2 Array{Array{Float64,1},2}:
[-1.0, -1.0, 1.0] [-1.0, 1.0, 1.0]
[0.0, -1.0, 1.0] [0.0, 1.0, 1.0]
[1.0, -1.0, 1.0] [1.0, 1.0, 1.0]
julia> hcat(viewDirections...).'
6×3 Array{Float64,2}:
-1.0 -1.0 1.0
0.0 -1.0 1.0
1.0 -1.0 1.0
-1.0 1.0 1.0
0.0 1.0 1.0
1.0 1.0 1.0
Note that, the order of coordinates is different from your original version, that's because Julia is column-major, Iterators.product will iterate the rightest dimension "outestly" i.e. [[i j r] for j in y for i in x ]. If the order is important in your use case, just pay attention to it.
Here are some benchmark results when width/height goes large:
julia> w = linspace(-1,1,300)
-1.0:0.006688963210702341:1.0
julia> h = linspace(-1,1,200)
-1.0:0.010050251256281407:1.0
julia> foo(w,h,r) = hcat([collect(i) for i in Iterators.product(w, h, r)]...).'
julia> bar(w,h,r) = vcat([[i j r] for i in w for j in h]...)
julia> #btime foo($w,$h,$r);
6.172 ms (60018 allocations: 10.99 MiB)
julia> #btime bar($w,$h,$r);
11.294 ms (360028 allocations: 17.02 MiB)

Cos, Acos with complex numbers

In Matlab I can write:
real(cos(kron(acos(-1.25),[0:4])))
and get:
1.0000 -1.2506 2.1282 -4.0725 8.0583
How to do the same in Julia. acos does not work with numbers less than -1.0. Even if I write:
r = max(-1.25,-1)
v = collect(0:4).';
cc =kron(acos(r),v)
I get only this:
1.0 -1.0 1.0 -1.0 1.0
It seems that I need to make cos/acos work with complex numbers.
Is this what you are looking for?
julia> real(cos.(kron(acos(complex(-1.25)),(0:4)')))
1×5 RowVector{Float64,Array{Float64,1}}:
1.0 -1.25 2.125 -4.0625 8.03125
or
julia> real(cos.(kron(acos(complex(-1.25)),0:4)))
5-element Array{Float64,1}:
1.0
-1.25
2.125
-4.0625
8.03125
Looks like Julia's acos requires a complex argument for a complex output.

Resources