I would like to define a struct to hold a vector of 3 elements
mutable struct Coords
r::Array{Float64,3} # essentially holds x,y,z coords
end
I now want to make an array of these structures, and give random values to the vector inside each structure.
This is where I fade out. I have tried a few things which I will describe, but none of them worked.
trial 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
The error message is
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
I don't get why it thinks there are integers involved.
I have tried changing the inside of the for loop to be
arrayOfStructs[i] = Coords(rand(3))
to no avail.
I have also tried initializing arrayOfStructs = []
Arrays are mutable type collections in Julia, hence, their values can be modified with the use of certain pre-defined keywords. Julia allows adding new elements in an array with the use of push! command.
Create an array filled with the value x . For example, fill(1.0, (10,10)) returns a 10x10 array of floats, with each element initialized to 1.0 . If x is an object reference, all elements will refer to the same object. fill(Foo(), dims) will return an array filled with the result of evaluating Foo() once.
Julia provides a very simple notation to create matrices. A matrix can be created using the following notation: A = [1 2 3; 4 5 6]. Spaces separate entries in a row and semicolons separate rows. We can also get the size of a matrix using size(A).
A Vector in Julia can be created with the use of a pre-defined keyword Vector() or by simply writing Vector elements within square brackets([]). There are different ways of creating Vector. vector_name = [value1, value2, value3,..] or vector_name = Vector{Datatype}([value1, value2, value3,..])
N
in Array{T,N}
defines the dimensionality of the array, that is, an N
-dimensional array of type T
.
You are not defining an array of size 3 to hold x
, y
, z
coordinates in your struct
definition, instead you are defining a 3D Array, which does not suit your purpose.
Yet again, you just declare the type of arrayOfStructs
to be a 10-dimensional array without constructing it. You need to define and construct your array properly before using it.
Array
types in Julia does not have static size information. Array
is a dynamic structure and does not suit your case. For array types with static size information you might want to take a look at StaticArrays.jl
.
Here is how I would go with your problem.
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
You might instead create an empty outer constructor for your type that initializes the fields randomly.
# 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
You may also use comprehensions to easily construct your array.
arrayOfStructs = [Coords() for i in 1:x]
If you still want to use an Array
for your field, you may define r
as a 1D-array and handle the construction of r
in your constructors.
You might want to take a look at the relevant sections in the documentation for Array
s and Composite Types
:
https://docs.julialang.org/en/v1/manual/arrays/
https://docs.julialang.org/en/v1/manual/types/#Composite-Types-1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With