Джулия предварительно выделяет массив против MATLAB предварительно выделяет массив - PullRequest
2 голосов
/ 06 мая 2019

В MATLAB рекомендуется предварительное выделение массивов, которые в противном случае изменили бы размер во время итераций.Исходя из предположения, что рекомендация также для Джулии, я хотел бы знать, как это сделать.

В MATLAB следующий код предварительно выделяет массив 5 на 10:

A = nan(5,10)

Как то же самое можно получить в Юлии?

Ответы [ 2 ]

8 голосов
/ 07 мая 2019

A = nan(5,10) не только выделяет массив double с, но также инициализирует записи массива с NaN с (хотя MATLAB может не заполнять массив под капотом).

Краткий ответ A = nan(5, 10) в MATLAB эквивалентен в семантическом до A = fill(NaN, 5, 10) в Юлии.

Длинный ответ таков: у вас есть много опций и больше возможностей для выделения и инициализации массива в Julia.

Распределение массива без инициализация

В Юлии можно выделить массив или матрицу (которая является двумерным массивом) и оставить записи неинициализированными.

# 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}`

Распределение массива без инициализации с использованием другого массива

В Julia вы можете использовать функцию similar для выделения массива, используя тип, тип элемента и информацию о размерности другой матрицы, и оставить его неинициализированным.

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`

Выделить пустой массив

Вы можете использовать синтаксис построения массива выше, передав 0 в качестве измерения, или просто T[], чтобы создать пустой массив типа T.

A = Float64[]

Распределение массива с инициализация

# 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]`

Вы можете использовать fill!(A, value) или просто использовать A .= value, чтобы заполнить уже выделенный массив тем же значением. Если вы импортируете модуль Random, вы можете использовать rand! или randn! для заполнения уже выделенного массива случайными значениями. Это может дать вам значительный выигрыш в производительности, так как выделения будут исключены.

Вы можете взглянуть на раздел Многомерных массивов документации Julia, чтобы узнать больше о массивах в Julia.


Примечания

В Julia вы не можете изменить размер многомерного (не 1D) встроенного Array.

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

Но вы можете push! значений в одномерные Array. Это позволит эффективно изменить размер массива.

julia> A = Int[];
julia> push!(A, 1);
julia> push!(A, 2, 3);
julia> A
3-element Array{Int64,1}:
 1
 2
 3
2 голосов
/ 06 мая 2019

В MATLAB nan () выделяет массив NaN в виде значений с плавающей запятой.Так что в Юлии

 A = fill(NaN, (5,10))

делает это.

...