# Referring to a vector in a vector of svectors

**URL:** <https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682>\
**Category:** New to Julia\
**Tags:** staticarrays\
**Created:** [August 12, 2022, 9:07pm UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682 "2022-08-12T21:07:01Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![jrhalket](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jrhalket/32/38750_2.png) [@jrhalket](https://discourse.julialang.org/u/jrhalket)\
**Post date:** [August 12, 2022, 9:07pm UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/1 "2022-08-12T21:07:01Z")

</div>

I am trying to grab a vector within a vector of static vectors. I’ve tried below but it doesn’t seem to work (perhaps since sims is a vector of Svectors and not a vector of vectors?).

```julia
sims = Vector{SVector{3,Float64}}(undef, 1000)
data = rand(3,1000)
diff1 = data(1,:) - sims[:][1] 
diff2 = data(2,:) - sims[:][2]

```

when I do

```julia
typeof(sims[:][1])

```

I get: SVector{3, Float64}

Any ideas?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 13, 2022, 5:47am UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/2 "2022-08-13T05:47:32Z")

</div>

What exactly doesn’t work? What error do you get?

---

<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:** [August 13, 2022, 6:09am UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/3 "2022-08-13T06:09:04Z")

</div>

> [@jrhalket](#):
>
> `sims[:][1]`

You assumed that this would return a vector with 1000 elements that includes all first elements of the SVectors right? That’s not how this works though. You have a vector of SVectors and what you do is retrieve the first element of all elements, which is just the first element, an SVector with 3 elements.

However, because SVectors are packed contiguously in memory you can reinterpret the whole vector as a matrix, I think `r = reinterpret(Float64, sims)` should create a 3x1000 array. And then you could just do one operation for all your diffs like `data .- r`. Or slice like `r[1, :]`.

Also you use Matlab slicing notation on `data`. I think this is where your confusion comes from anyway, because Matlab lets you access struct arrays in a way similar to what you’re trying here.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [August 13, 2022, 7:40am UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/4 "2022-08-13T07:40:38Z")

</div>

`StructArrays` provide convenient and performant access to components of all array elements. You can use them instead of regular arrays:

```julia
julia> using StructArrays, StaticArrays

julia> sims = StructArray{SVector{3, Float64}}(undef, 10)

# first element, as in a regular array:
julia> sims[1]
3-element SVector{3, Float64} with indices SOneTo(3):
 6.9246147411839e-310
 1.5e-323
 0.0

# first component of each SVector:
julia> sims.:1
10-element Vector{Float64}:
 6.9246147411839e-310
 6.9246148476744e-310
 6.9246154120934e-310
 6.92461485226882e-310
 6.92461491037964e-310
 6.924614910382e-310
 6.9246149103844e-310
 6.9246148522372e-310
 6.92461485224037e-310
 6.92461485224353e-310

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 13, 2022, 9:29am UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/5 "2022-08-13T09:29:08Z")

</div>

> [@jules](#):
>
> I think `r = reinterpret(Float64, sims)` should create a 3x1000 array.

This does not seem to be the case, but the following is :

```julia
r = reshape(reinterpret(Float64, sims), (3,:)) 

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 13, 2022, 10:27am UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/6 "2022-08-13T10:27:31Z")

</div>

> [@jrhalket](#):
>
> Any ideas?

Just in case, you could also grab each component using:

```julia
getindex.(sims,1)
getindex.(sims,2)
...

```

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [August 13, 2022, 10:34pm UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/7 "2022-08-13T22:34:08Z")

</div>

MATLAB style indexing `data(1,:)` is (fortunately) not allowed in Julia, use square brackets `data[1,:]` instead. Also, `sims[:][1]` doesn’t do what you thought it does. `sims[:]` is the same as just `sims`, so this only means `sims[1]`, the first `SVector` in `sims`. You cannot subtract 3-element vector from 1000-element vector.

To get first element from all `SVector`s in `sims`, use `getindex.(sims,1)`, and to get the second element, use `getindex.(sims,2)`, etc.

This is how you might write that code snippet efficiently in Julia. Notice the use of `view` and dot broadcasting to avoid allocating extra temporary arrays.

```julia
sims = Vector{SVector{3,Float64}}(undef, 1000)
data = rand(3,1000)
diff1 = view(data,1,:) .- getindex.(sims,1) 
diff2 = view(data,2,:) .- getindex.(sims,2)

```

---

<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:** [August 13, 2022, 11:31pm UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/8 "2022-08-13T23:31:55Z")

</div>

or, more explicitly:

```julia
diff1 = [data[1,i] - sims[i][1] for i in eachindex(sims) ]

```

ps: you can also write `@view(data[1,:])` in the examples above, to avoid copying the data.

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [August 13, 2022, 11:40pm UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/9 "2022-08-13T23:40:44Z")

</div>

True, the easiest approach that I use a lot is just tossing a `@views` macro before the `function` keyword. This makes the code much cleaner and covers all function scope, I might forget some instances if I write it manually.

```julia
@views function ...
end

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 14, 2022, 6:00am UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/10 "2022-08-14T06:00:30Z")

</div>

> [@jrhalket](#):
>
> `sims[:][1] `

As others say `sims[:][1] == sims[1]`, you just need to look at the expression like this: `(sims[:])[1]`. The expression inside the parentheses is equal to `sims` itself, except that slicing also makes a copy.

You’re far from the first person I’ve seen to try this approach, so I’m a bit curious about the mental model behind it.

Besides `getindex` you can use `first.(sims)` and `last.(sims)` to get all the first and last elements.

Another thing is that you are accessing `sims` even though it’s just full of garbage data, initialized with `undef`. Shouldn’t you put some actual data in there before you start using it?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 14, 2022, 9:25am UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/11 "2022-08-14T09:25:32Z")

</div>

Fyi, the `TensorCast` package uses similar notation as OP in order to extract the vector components:

```julia
using TensorCast
@cast c1[i] := sims[i][1]
@cast c2[i] := sims[i][2]
...

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 14, 2022, 10:50am UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/12 "2022-08-14T10:50:08Z")

</div>

Not sure I see the similarity, this is basically just

```julia
for i in eachindex(sims) c1[i] = sims[i][1] end

```

`sims[i][1]` is exactly what you want, then iterate over `i`.

But maybe it’s related to array slicing:

```julia
c1 = sims[:, 1]

```

I can see how one might guess that `sims[:][1]` did something similar. The difference is that `[:, 1]` is a single action, while `[:][1]` are two independent operations. I wonder, how do languages where multidimensional indexes are written as `[i][j][k]` deal with slicing?

---

<div class="post-metadata">

**Author:** ![jrhalket](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jrhalket/32/38750_2.png) [@jrhalket](https://discourse.julialang.org/u/jrhalket)\
**Post date:** [August 15, 2022, 6:32pm UTC](https://discourse.julialang.org/t/referring-to-a-vector-in-a-vector-of-svectors/85682/13 "2022-08-15T18:32:42Z")

</div>

Thank you everyone. I went the `getindex` and `view` route and it worked like a charm.
