In Julia: BigFloat RoundFromZero Seems Strange - julia

In the Julia 1.0.0 REPL I get the following behavior. The first line is an example from the documentation
https://docs.julialang.org/en/v1/base/math/#Base.Rounding.RoundFromZero
julia> BigFloat("1.0000000000000001", 5, RoundFromZero)
1.06
The meaning of the 5 in the above example is not clear to me. For example,
julia> BigFloat("1.01", 5, RoundFromZero)
1.06
It would seem that the two numbers being rounded should round to different outputs in the REPL. What am I missing?

The value is rounded from zero with 5 bits precision and in both cases this is the same value equal to 1.0625. You can check it using e.g.:
julia> Float64(BigFloat("1.01", 5, RoundFromZero))
1.0625
or
julia> big(0)+BigFloat("1.01", 5, RoundFromZero)
1.0625
or (this is hacking and should not be done):
julia> x = BigFloat("1.01", 5, RoundFromZero)
1.06
julia> x.prec = 10
10
julia> x
1.0625
or
julia> Base.MPFR._string(x, 10)
"1.0625"
Now the reason why 1.06 is printed is that Julia rounds the output (and this is a default rounding from MPFR external library in this case).

Related

Julia: Vectorize function along a specific axis of a matrix

What is the best way in Julia to vectorize a function along a specific axis? For example sum up all the rows of a matrix. Is it possible with the dot notation?
sum.(ones(4,4))
Does not yield the desired result.
Try using the dims argument on a lot of functions that deal with sets of values.
sum([1 2; 3 4], dims=2)
2×1 Matrix{Int64}:
3
7
# or
using Statistics
mean([1 2; 3 4], dims=1)
1×2 Matrix{Float64}:
2.0 3.0
There is already a standard function called mapslices, looks like exactly what you need.
julia> mapslices(sum, ones(4, 4), dims = 2)
4-element Vector{Float64}:
4.0
4.0
4.0
4.0
You can find the documentation here or by typing ? followed by mapslices in REPL.
If in your example you want to use the dot notation you should pass an array of rows, not the array itself. Otherwise, sum is applied to each element resulting in the same matrix. It can be done with eachrow and eachcol for rows and columns respectively.
julia> sum.(eachrow(ones(4, 4)))
4-element Vector{Float64}:
4.0
4.0
4.0
4.0
EDIT: I tried to suggest a more general solution, but if you have this option I would recommend using Andre's answer.

Lag and lead in Julia

I want to turn an array like this
[1,2,3,4,5]
into a lagged version
[missing,1,2,3,4] # lag 1
[missing,missing,1,2,3] # lag 2
or a led version
[2,3,4,5,missing] # lead 1
[3,4,5,missing,missing] # lead 2
As Julia is designed for scientific computing, there must be something like this, right?
Add ShiftedArrays. See: https://discourse.julialang.org/t/ann-shiftedarrays-and-support-for-shiftedarrays-in-groupederrors/9162
Quoting from the above:
lag, lead functions, to shift an array and add missing (or a custom default value in the latest not yet released version) where the data is not available, or circshift for shifting circularly in a lazy (non allocating) way:
julia> v = [1.2, 2.3, 3.4]
3-element Array{Float64,1}:
1.2
2.3
3.4
julia> lag(v)
3-element ShiftedArrays.ShiftedArray{Float64,Missings.Missing,1,Array{Float64,1}}:
missing
1.2
2.3
Note the ShiftedArray version of lag keeps the array size the same. You might add a short function to make it behave the way you asked:
biglag(v, n) = lag(vcat(v, v[1:n]), n)

Is there a way to swap columns in O(1) in Julia?

I picked up Julia to do some numerical analysis stuff and was trying to implement a full pivot LU decomposition (as in, trying to get an LU decomposition that is as stable as possible). I thought that the best way of doing so was finding the maximum value for each column and then resorting the columns in descending order of their maximum values.
Is there a way of avoiding swapping every element of two columns and instead doing something like changing two references/pointers?
Following up on #longemen3000's answer, you can use views to swap columns. For example:
julia> A = reshape(1:12, 3, 4)
3×4 reshape(::UnitRange{Int64}, 3, 4) with eltype Int64:
1 4 7 10
2 5 8 11
3 6 9 12
julia> V = view(A, :, [3,2,4,1])
3×4 view(reshape(::UnitRange{Int64}, 3, 4), :, [3, 2, 4, 1]) with eltype Int64:
7 4 10 1
8 5 11 2
9 6 12 3
That said, whether this is a good strategy depends on access patterns. If you'll use elements of V once or a few times, this view strategy is a good one. In contrast, if you access elements of V many times, you may be better off making a copy or moving values in-place, since that's a price you pay once whereas here you pay an indirection cost every time you access a value.
Just for "completeness", in case you actually want to swap columns in-place,
function swapcols!(X::AbstractMatrix, i::Integer, j::Integer)
#inbounds for k = 1:size(X,1)
X[k,i], X[k,j] = X[k,j], X[k,i]
end
end
is simple and fast.
In fact, in an individual benchmark for small matrices this is even faster than the view approach mentioned in the other answers (views aren't always free):
julia> A = rand(1:10,4,4);
julia> #btime view($A, :, $([3,2,1,4]));
31.919 ns (3 allocations: 112 bytes)
julia> #btime swapcols!($A, 1,3);
8.107 ns (0 allocations: 0 bytes)
in julia there is the #view macro, that allows you to create an array that is just a reference to another array, for example:
A = [1 2;3 4]
Aview = #view A[:,1] #view of the first column
Aview[1,1] = 10
julia> A
2×2 Array{Int64,2}:
10 2
3 4
with that said, when working with concrete number types (Float64,Int64,etc), julia uses contiguous blocks of memory with the direct representation of the number type. that is, a julia array of numbers is not an array of pointers were each element of an array is a pointer to a value. if the values of an array can be represented by a concrete binary representation (an array of structs, for example) then an array of pointers is used.
I'm not a computer science expert, but i observed that is better to have your data tightly packed that using a lot of pointers when doing number crunching.
Another different case is Sparse Arrays. the basic julia representation of an sparse array is an array of indices and an array of values. here you can simply swap the indices instead of copying the values

Getting index of subarray in Julia

I'm new to Julia and wonder what is the best way to get the index of subarray, consider the following array of vectors
vec = [[1, 2, 3], [4, 5, 6]]
I would like to get the index of the element [4, 5, 6], however I can not use getindex(), execution of the following code:
getindex(vec, [1, 2, 3])
gives:
BoundsError: attempt to access 2-element Array{Array{Int64,1},1} at index [[1, 2, 3]]
So I wonder if there are any effective build-in methods for doing this. Of course I can map this array of vectors into another array of numbers and do a search inside new array of numbers, but it isn't really a solution what I expect.
Second question is how do I learn more about search methods in Julia and their performances. I guess the theoretical speed of search scales like \sqrt(N) however depending on the certain method the real code time may vary significantly.
Judging by the name of the function you might be mislead: getindex retrieves the value stored at an index.
If you want to find the index of something in an array you can make use of find* methods findfirst, findall...
julia> vec=[[1,2,3],[4,5,6]]
2-element Array{Array{Int64,1},1}:
[1, 2, 3]
[4, 5, 6]
julia> i = findfirst(x->x==[4,5,6],vec)
2
julia> vec[i]
3-element Array{Int64,1}:
4
5
6
Concerning your second question:
It's best to inform yourself about search/sort algorithms in general (e.g. https://codeburst.io/algorithms-i-searching-and-sorting-algorithms-56497dbaef20?gi=3bdbf8cbaca0), because the performance depends much more on the chosen algorithm than on the language specific implementation. E.g. time complexity can be very different (O(n), O(log(n),...).
I think you've misunderstood what getindex does. It's the function that gets called by [], so
julia> getindex(vec, 2)
3-element Array{Int64,1}:
4
5
6
All search (or "find") methods in Julia take a function as it's first argument, and find where the function evaluates to true. To find a particular element, use isequal or == (they are equivalent):
julia> findall(==([1,2,3]), vec)
1-element Array{Int64,1}:
1

Julia and big numbers

How does Julia compute big numbers?
For example, this works as expected:
julia> 10^18
1000000000000000000
But for bigger numbers, there is a problem with integers:
julia> 10^19
-8446744073709551616
julia> 10^20
7766279631452241920
But it works if a decimal number is used:
julia> 10.0^20
1.0e20
Do you know why?
Check this documentation page: https://docs.julialang.org/en/release-0.4/manual/integers-and-floating-point-numbers/
As you can see, Int64 have a max length of: 2^63 - 1 ~ 1.0 * 10^19
So your 10^19 is greater than this max value. That's why there is a problem.
You can try to convert your 10 to another type.
10.0^20 works because 10.0 is a float, so it has a superior max value.
If you want unlimited precision for integers, you can use BigInts:
julia> BigInt(10)^100
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Resources