Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia pre-allocate array vs. MATLAB pre-allocate array

Tags:

julia

In MATLAB, pre-allocation of arrays that would otherwise change size during iterations, is recommended. On the assumption the recommendation also ges for Julia, I would like to know how to do that.

In MATLAB, the following code pre-allocates a 5 by 10 array:

A = nan(5,10)

How would the same be obtained in Julia?

like image 234
user120911 Avatar asked Dec 06 '22 09:12

user120911


1 Answers

A = nan(5,10) does not just allocate an array of doubles, but also initializes the entries of the array with NaNs (although MATLAB may not really fill the array under the hood).

The short answer is A = nan(5, 10) in MATLAB is equivalent in semantic to A = fill(NaN, 5, 10) in Julia.

The long answer is that, you have many options and more control for array allocation and initialization in Julia.

Array allocation without initialization

In Julia, it is possible to allocate an array or a matrix (which is a 2D array) and leave the entries uninitialized.

# Allocate an "uninitialized" m-by-n `Float64` (`double`) matrix
A = Array{Float64, 2}(undef, m, n)
# or equivalently
A = Matrix{Float64}(undef, m, n) # `Matrix{T}` is equivalent to `Array{T, 2}`
# you do not need to type dimensionality even with `Array`,
# the dimensionality will be inferred from the number of parameters
A = Array{Float64}(undef, m, n)

# You can do the same for arrays of different dimensions or other types
A = Array{Float64, 3}(undef, m, n, k) # 3D `Float64` array of size m*n*k
A = Array{Int64}(undef, m) # 1D `Int64` array
A = Vector{Float32}(undef, m) # 1D `Float32` (i.e. `single`) array. `Vector{T} === Array{T, 1}`

Array allocation without initialization using another array

In Julia, you can use the function similar to allocate an array using the type, element type and dimensionality information of another matrix and leave it uninitialized.

A = zeros(UInt8, m, n)
B = similar(A) # allocates the same type of array (dense, sparse, etc.) with the same element type, and the same dimensions as `A`

C = similar(A, Float64) # allocates the same type of array with the same dimensions as `A` but with the element type of `Float64`

Allocate an empty array

You can use the array construction syntax above passing 0 as the dimension, or simply T[] to create an empty array of type T.

A = Float64[]

Array allocations with initialization

# Allocate a `Float64` array and fill it with 0s
A = zeros(m, n) # m-by-n Float64 matrix filled with zeros
A = zeros(m, n, k, l) # a 4D Float64 array filled with zeros

# similarly to fill with `Float64` 1s
A = ones(m, n)
A = ones(m) # a 1D array of size `m`
A = ones(m, 1) # an `m`-by-1 2D array

# you can use these functions with other types as well
A = zeros(Float32, m, n)
A = ones(UInt8, m, n, k)


# you can allocate an array/matrix and fill it with any value you like using `fill`
# the type is inferred by the value entered
A = fill(4.0, (m, n)) # m-by-n matrix filled with `4.0`
A = fill(0.50f, m, n, k) # a 3D Float32 array filled `0.5`s

# so to fill with `NaN`s you can use
A = fill(NaN, m, n)

# random initialization
A = rand(m, n) # m-by-n Float64 matrix with uniformly distributed values in `[0,1)`
A = rand(Float32, m) # an array of size `m` with uniformly distributed values in `[0,1)`

A = randn(m, n) # the same as `rand` but with normally distributed values

# you can initialize the array with values randomly (uniform) picked from a collection
A = rand([1, 5, 7], m, n) # values will be picked from the array `[1,5,7]`

You can use fill!(A, value) or simply use A .= value to fill an already allocated array with the same value. If you import the module Random, you may use rand! or randn! to fill an already allocated array with random values. This might give you significant performance benefits as allocations will be avoided.

You may take a look at the Multi-dimensional Arrays section of Julia documentation to learn more about arrays in Julia.


Notes

In Julia, you cannot change the size of a multi-dimensional (not 1D) built-in Array.

A = zeros(5,5)
A[6,5] = 2 # bounds error

But you can push! values into a one-dimensional Array. This will efficiently resize the array.

julia> A = Int[];
julia> push!(A, 1);
julia> push!(A, 2, 3);
julia> A
3-element Array{Int64,1}:
 1
 2
 3
like image 109
hckr Avatar answered Dec 07 '22 23:12

hckr