# Vector of Vectors: Type Issue and Tuple Question

**URL:** https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640
**Category:** New to Julia
**Created:** [September 15, 2020, 2:25pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640 "2020-09-15T14:25:27Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)
#### Post date: [September 15, 2020, 2:25pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/1 "2020-09-15T14:25:27Z")

</div>

I am trying to understand the difference between the two ways I found to create a vector of vectors below. I found Option 1 in [this post](https://discourse.julialang.org/t/whats-the-proper-way-to-create-and-initialize-a-vector-of-vectors-of-matrices-and-vectors/40515), which works nicely but isn’t very customizable. Option 2 also works, but it can’t seem to obtain the type. Why aren’t the types the same between Option 1 and 2, and what does “_where T,1_” mean? How can I fix Option 2’s typing, so that I don’t take a performance hit?

**Bonus Question:** My understanding is that tuples are faster than vectors because they are immutable. How can I construct a tuple of vectors and then fill the vectors in a loop? Neither replacing `[]` with `()` in Option 1 nor `Vector` with `Tuple` in Option 2 worked. I see in my testing that I may modify the interior vectors `v[j][i]=`, but not the tuples indices themselves `v[j]=` once created. However, I can’t figure out how to set up this structure if I don’t know the values in the vectors at creation time. How can I achieve this and is the performance gain worth the hassle?

```julia
#Vector Lengths
J=4
I=11

#Creation Option 1
v=[Vector{Int}(undef, I) for _ = 1:J]

#Creation Option 2
v=Vector{Vector}(undef, J) # Outer Vector (May in practice want outer type to be a tuple.)
for j in 1:J
    v[j]=Vector{Int}(undef, I) # Inner Vector (May in practice have different lengths.)
end

#Fill with test values.
for j=1:J
    for i=1:I
        v[j][i]=(j-1)*I+i
    end
end

#Show Results
v

```

Output of Option 1:

```julia
4-element Array{Array{Int64,1},1}:
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
 [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
 [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
 [34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]

```

Output of Option 2:

```julia
4-element Array{Array{T,1} where T,1}:
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
 [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
 [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
 [34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]

```

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [September 15, 2020, 2:28pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/2 "2020-09-15T14:28:37Z")

</div>

The type of option 2 is different because you specified `v=Vector{Vector}(undef, J)`. The inner `Vector` is an abstract type, because to be concrete, a `Vector` needs a type parameter. The outer one has that, the inner doesn’t. You could have written `Vector{Vector{Int}}` instead.

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [September 15, 2020, 2:33pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/3 "2020-09-15T14:33:11Z")

</div>

Also, the difference between a Tuple and a Vector as a collection of things is not just that one is immutable, it’s also that the Tuple type tells the compiler exactly how many elements it has. That can make a big difference for compiling efficient code (you know how many steps unrolled loops over all the elements must have, for example). So you wouldn’t use a Tuple in a context where code can produce wildly different numbers of elements that need to be stored, because for each new amount of elements, there’s a new Tuple type and therefore a new compilation overhead for methods that work on it.

---

<div class="post-metadata">

### Author: ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)
#### Post date: [September 15, 2020, 2:53pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/4 "2020-09-15T14:53:31Z")

</div>

Ah, okay. This version of Option 2 now gives equivalent results to Option 1 with concrete types.

```julia
#Creation Option 2
v=Vector{Vector{Int}}(undef, J)
for j in 1:J
    v[j]=Vector(undef, I) # May in practice have different lengths.
end

```

I thought that the type of the inner vector could be picked up when I defined its length, but apparently all the types need to be defined at creation time?

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [September 15, 2020, 3:03pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/5 "2020-09-15T15:03:01Z")

</div>

I think even in that version you have a problem, because the Vector you create is of abstract type. It just works because it gets converted to a `Vector{Int}` when you assign it as an element of a `Vector{Vector{Int}}`, which can not hold anything other than `Vector{Int}` elements. But that conversion could cost you.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 15, 2020, 3:03pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/6 "2020-09-15T15:03:55Z")

</div>

> [@Nathan\_Boyer](#):
>
> I thought that the type of the inner vector could be picked up when I defined its length, but apparently all the types need to be defined at creation time?

The issue is not the types of the inner vectors, the issue is the type of the _container_. A `Vector{Vector}` is different from a `Vector{Vector{Int}}` because the former is a container for _any_ type of a vector. For example:

```julia
julia> vvi = Vector{Int}[] # a Vector{Vector{Int}}
Array{Int64,1}[]

julia> vv = Vector[] # a Vector{Vector}
Array{T,1} where T[]

julia> push!(vvi, [1,2,3])
1-element Array{Array{Int64,1},1}:
 [1, 2, 3]

julia> push!(vv, [1,2,3]) # vv can also store integer vectors
1-element Array{Array{T,1} where T,1}:
 [1, 2, 3]

julia> vvi[1]
3-element Array{Int64,1}:
 1
 2
 3

julia> vv[1] # this element is also a Vector{Int} == Array{Int64,1}
3-element Array{Int64,1}:
 1
 2
 3

julia> push!(vv, ["a", "b", "c"]) # vv can also store vectors of strings
2-element Array{Array{T,1} where T,1}:
 [1, 2, 3]
 ["a", "b", "c"]

julia> push!(vvi, ["a", "b", "c"]) # but vvi cannot
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Int64
Closest candidates are:
  convert(::Type{T}, ::T) where T<:Number at number.jl:6
  convert(::Type{T}, ::Number) where T<:Number at number.jl:7
  convert(::Type{T}, ::Ptr) where T<:Integer at pointer.jl:23
  ...
Stacktrace:
 [1] setindex!(::Array{Int64,1}, ::String, ::Int64) at ./array.jl:847
 [2] _unsafe_copyto!(::Array{Int64,1}, ::Int64, ::Array{String,1}, ::Int64, ::Int64) at ./array.jl:257
 [3] unsafe_copyto! at ./array.jl:311 [inlined]
 [4] _copyto_impl! at ./array.jl:335 [inlined]
 [5] copyto! at ./array.jl:321 [inlined]
 [6] copyto! at ./array.jl:347 [inlined]
 [7] copyto_axcheck! at ./abstractarray.jl:946 [inlined]
 [8] Array at ./array.jl:562 [inlined]
 [9] convert at ./array.jl:554 [inlined]
 [10] push!(::Array{Array{Int64,1},1}, ::Array{String,1}) at ./array.jl:934
 [11] top-level scope at REPL[9]:1

```

So, `vv` (my `Vector{Vector}` above) is more flexible than `vvi` (my `Vector{Vector{Int}}`), because the latter can _only_ store `Vector{Int}` objects. But this flexibility comes at a price — operations on `vv` will be slower because the compiler can’t determine the types of the elements until runtime (when the elements are actually assigned), so it must pay the price of runtime type-checks and dynamic dispatch.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [September 15, 2020, 3:33pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/7 "2020-09-15T15:33:50Z")

</div>

> [@jules](#):
>
> That can make a big difference for compiling efficient code

This seems to suggest that tuples could be indicated for use in place of vectors in general numerical calculations, with advantages. From the docs what I understand is that tuples are mostly used to represent function arguments. There has been more than one post comparing tuples to vectors in terms of speed, maybe someone can provide a clarification on why tuples should not in general be used to substitute immutable vectors? Or should they?

---

<div class="post-metadata">

### Author: ![phg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phg/32/17184_2.png) [@phg](https://discourse.julialang.org/u/phg)
#### Post date: [September 15, 2020, 3:48pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/8 "2020-09-15T15:48:52Z")

</div>

[That is a completely correct observation](https://github.com/JuliaArrays/StaticArrays.jl), up to a certain size. (`SArray`s are implemented in terms of tuples.)

---

<div class="post-metadata">

### Author: ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)
#### Post date: [September 15, 2020, 4:10pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/9 "2020-09-15T16:10:59Z")

</div>

Thank you. Your answer was very insightful. I see now that I need to concretely type both the container and the inner components if I want that speed boost.

> [@stevengj](#):
>
> ```julia
> julia> vvi = Vector{Int}[] # a Vector{Vector{Int}}
> Array{Int64,1}[]
> 
> ```

I also spent a while exploring the syntax you used to create your vectors as I had never seen it before with type information. Do you usually create them empty like this and then `push!` to them? I would think that allocating undefined as I did would be better for speed and finding errors, but perhaps there are other benefits to your method.

---

<div class="post-metadata">

### Author: ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)
#### Post date: [September 15, 2020, 5:50pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/10 "2020-09-15T17:50:52Z")

</div>

> [@Nathan\_Boyer](#):
>
> I would think that allocating undefined as I did would be better for speed and finding errors, but perhaps there are other benefits to your method.

I think, it was for illustrative purposes, as `Vector{Int}[]` is faster to type than `Vector{Vector{Int}}(undef, m)`.

Another advantage is the guarantee that there would be no uninitialized elements if the end result is built from an empty array and filled by `push!`.

The best use of `Vector{T}(undef, m)` is inside some function that then initializes all of the elements, otherwise forgetting to initialize some of them and `push!`ing new elements may result in undefined references / garbage in the middle.

---

<div class="post-metadata">

### Author: ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)
#### Post date: [September 15, 2020, 7:46pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/11 "2020-09-15T19:46:26Z")

</div>

Can anyone answer the bonus question?

When should you use `Vector` v.s. `Tuple` v.s. `SVector` as an outer container, and how can you allocate each such that the inner data can be populated later?

---

<div class="post-metadata">

### Author: ![danielw2904](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielw2904/32/10890_2.png) [@danielw2904](https://discourse.julialang.org/u/danielw2904)
#### Post date: [September 15, 2020, 8:14pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/12 "2020-09-15T20:14:35Z")

</div>

`SVector`s are immutable and faster for linear algebra operations if they are small (\<100 elements according to the github readme). Idk about vectors vs tuples though.

---

<div class="post-metadata">

### Author: ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)
#### Post date: [September 15, 2020, 8:29pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/13 "2020-09-15T20:29:50Z")

</div>

The GitHub readme that @phg linked says specifically that SVectors are not immutable.

> Note that here “statically sized” means that the size can be determined from the _type_ , and “static” does **not** necessarily imply `immutable` .

The difference between the three types may boil down to mutable vs. static vs. immutable, but I don’t understand all the nuance there either.

---

<div class="post-metadata">

### Author: ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)
#### Post date: [September 15, 2020, 8:33pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/14 "2020-09-15T20:33:01Z")

</div>

`SArray`s are immutable as well as statically sized. StaticArrays.jl also provides `MArray` for statically sized mutable arrays though.

---

<div class="post-metadata">

### Author: ![danielw2904](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielw2904/32/10890_2.png) [@danielw2904](https://discourse.julialang.org/u/danielw2904)
#### Post date: [September 15, 2020, 8:56pm UTC](https://discourse.julialang.org/t/vector-of-vectors-type-issue-and-tuple-question/46640/15 "2020-09-15T20:56:33Z")

</div>

See the docs

> The package also provides some concrete static array types: [`SVector`](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.SVector), [`SMatrix`](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.SMatrix) and [`SArray`](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.SArray), which may be used as-is (or else embedded in your own type). Mutable versions [`MVector`](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.MVector), [`MMatrix`](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.MMatrix) and [`MArray`](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.MArray) are also exported, as well as [`SizedArray`](https://juliaarrays.github.io/StaticArrays.jl/stable/pages/api/#StaticArrays.SizedArray) for annotating standard `Array` s with static size information.
