At a point in my real code, I want to generate a number of independent vectors based on parameter N(which is calculated at a certain point in the code). For example, if N=3, then I need to generate the following vectors:
So, I tried to write something like below. However, there are two problems:
1- Syntax of vector_"$i" gives error . How to write the correct syntax?
2- Assuming the syntax is correct, an error is given at S = vector_"$i" since the vectors are not seen out of the for-loop scope. How to make the generated vectors seen out of for-loop scope?
function dd()
N =3;
for i = 1:N
vector_"$i" = zeros(i+1); # gives `ERROR: UndefVarError: @vector__str not defined`
end
S = vector_1; # gives `ERROR: UndefVarError: vector_1 not defined`
end
dd()
julia> vectors = Vector{Int}[]
for i in 1:3
push!(vectors, zeros(i))
end
julia> vectors
3-element Vector{Vector{Int64}}:
[0]
[0, 0]
[0, 0, 0]
(also I would recommend typing the Dict, if the case Dict{Int,Vector{Int}}(():
julia> d = Dict{Int,Vector{Int}}()
Dict{Int64, Vector{Int64}}()
julia> for i in 1:3
d[i] = zeros(i)
end
julia> d
Dict{Int64, Vector{Int64}} with 3 entries:
2 => [0, 0]
3 => [0, 0, 0]
1 => [0]
You can dynamically generate variables using eval, but they will necessarily live in global scope. Don’t do it. Seriously. It leads to hard to read and reason about code, and a cluttered global namespace. Nevertheless:
julia> for i = 1:N
var = Symbol("vector_$i")
eval( :( $var = zeros($i+1) ));
end
julia> vector_1
2-element Vector{Float64}:
0.0
0.0
julia> vector_2
3-element Vector{Float64}:
0.0
0.0
0.0
Thanks for your comment. The issue here is that I need to connect the generated vectors to other ones (which are changing in time-domain loop. For example, vectors[2] = @view(D[:]). However, a change in D will not be updated in vectors[2]/
D = [55,69];
vectors = Vector{Int}[]
for i in 1:3
push!(vectors, zeros(i))
end
vectors[2] = @view(D[:]);
D[1] = 77;
julia> vectors
3-element Vector{Vector{Int64}}:
[0]
[55, 69]
[0, 0, 0]
That’s because vectors is of type Vector{Vector{Int}} whereas @view(D[:]) is a subarray. Upon assignment vector[2] = @view(D[:]) a conversion to the former type, i.e. an implicit copy is made.
You could widen the container type
Thank you very much!
From a performance point of view, Do the values of vectors[2] are allocated in order in memory (column-major)? In other words, do working on the vector vector_2 is the same as on vectors[2]?
Yes, they form a concrete vector. Accessing vectors[2] is bad performance-wise because of the abstract container type. If you can live with that depends on the kind of work and how much indexing is done. Using a function barrier might be sufficient to make the overhead from the type instability due to indexing into vectors negligible.
I am sorry if I could not deliver my point clearly from the beginning.
Thanks for pointing this out. I will be more precise and accurate next times to make the discussion more productive.
From a performance point of view, can you recommend someting?