создание и присвоение значений массиву структур в Julia - PullRequest
0 голосов
/ 17 января 2019

Я хотел бы определить структуру для хранения вектора из 3 элементов

mutable struct Coords
    r::Array{Float64,3} # essentially holds x,y,z coords
end

Теперь я хочу создать массив из этих структур и дать случайные значения для вектора внутри каждой структуры.

Это где я исчезаю. Я попробовал несколько вещей, которые я опишу, но ни одна из них не сработала.


пробная версия 1:

x = 10                            # I want the array to be of length 10
arrayOfStructs::Array{Coords,x}
for i=1:x
    arrayOfStructs[i].r = rand(3)
end

Сообщение об ошибке:

ERROR: LoadError: MethodError: Cannot `convert` an object of type Int64 to an object of type Array{C
oords,10}
Closest candidates are:
  convert(::Type{T<:Array}, ::AbstractArray) where T<:Array at array.jl:489
  convert(::Type{T<:AbstractArray}, ::T<:AbstractArray) where T<:AbstractArray at abstractarray.jl:1
4
  convert(::Type{T<:AbstractArray}, ::LinearAlgebra.Factorization) where T<:AbstractArray at C:\User
s\julia\AppData\Local\Julia-1.0.2\share\julia\stdlib\v1.0\LinearAlgebra\src\factorization.jl:46
  ...
Stacktrace:
 [1] setindex!(::Array{Array{Coords,10},1}, ::Int64, ::Int64) at .\array.jl:769
 [2] getindex(::Type{Array{Coords,10}}, ::Int64) at .\array.jl:366
 [3] top-level scope at C:\Users\Zarathustra\Documents\JuliaScripts\energyTest.jl:68 [inlined]
 [4] top-level scope at .\none:0
in expression starting at C:\Users\Zarathustra\Documents\JuliaScripts\energyTest.jl:67

Я не понимаю, почему он думает, что здесь задействованы целые числа.

Я попытался изменить внутреннюю часть цикла for на

arrayOfStructs[i] = Coords(rand(3))

безрезультатно.

Я также попытался инициализировать arrayOfStructs = []

1 Ответ

0 голосов
/ 17 января 2019

N в Array{T,N} определяет размерность массива, то есть N -мерный массив типа T.

Вы не определяете массив размером 3 для хранения x, y, z координат в своем определении struct, вместо этого вы определяете 3D-массив, который не соответствует вашим целям.

Еще раз, вы просто объявляете тип arrayOfStructs как 10-мерный массив без конструирования it. Вы должны правильно определить и построить свой массив перед его использованием.

Array типов в Julia не имеет статической информации о размере. Array - это динамическая структура, которая не подходит для вашего случая. Для типов массивов со статической информацией о размере вы можете взглянуть на StaticArrays.jl.

Вот как я бы поступил с вашей проблемой.

mutable struct Coords
    x::Float64
    y::Float64
    z::Float64
end

x = 10 # I want the array to be of length 10
# create an uninitialized 1D array of size `x`
arrayOfStructs = Array{Coords, 1}(undef, x) # or `Vector{Coords}(undef, x)`

# initialize the array elements using default constructor
# `Coords(x, y, z)`
for i = 1:x
    arrayOfStructs[i] = Coords(rand(), rand(), rand())
    # or you can use splatting if you already have values
    # arrayOfStructs[i] = Coords(rand(3)...)
end

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

# outer constructor that randomly initializes fields
Coords() = Coords(rand(), rand(), rand())

# initialize the array elements using new constructor
for i = 1:x
    arrayOfStructs[i] = Coords()
end

Вы также можете использовать понимания, чтобы легко построить свой массив.

arrayOfStructs = [Coords() for i in 1:x]

Если вы все еще хотите использовать Array для своего поля, вы можете определить r как одномерный массив и обработать конструкцию r в своих конструкторах.

Возможно, вы захотите взглянуть на соответствующие разделы документации для Array s и Composite Types:

https://docs.julialang.org/en/v1/manual/arrays/

https://docs.julialang.org/en/v1/manual/types/#Composite-Types-1

...