Updating a list of StaticArrays

Viewed 48

Suppose I have this function, implemented without StaticArrays

function example_svector_bad(G) 
    vector_list = [ randn(G) for q in 1:1000]
    for i in size(vector_list)
        for g in 1:G
            vector_list[i][g] = vector_list[i][g] * g
        end
    end

    return vector_list
end

I'm hoping to implement it using StaticArrays for speed gains. However, I don't know how to do it without losing the flexibility of specifying G. For example, I could do

function example_svector()
    vector_list = [@SVector randn(3) for q in 1:1000]
    for i in size(vector_list)
        vector_list[i] = SVector(vector_list[i][1] * 1, vector_list[i][1] * 2,
        vector_list[i][1] * 3)
    end

    return vector_list
end

if I knew that G = 3 and I had to write out SVector(vector_list[i][1] * 1, vector_list[i][1] * 2, vector_list[i][1] * 3).

Is there a way to implement this for any arbitrary number of G?

2 Answers

The size of a static vector or array must be known at the compile time. At the compile time only types are known (rather than values).

Hence your function could look like this:

function myRandVec(::Val{G}) where G
    SVector{G}(rand(G))
end

Note that G is passed as type rather than as value and hence can be used to create a static vector.

This function could be used as:

julia> myRandVec(Val{2}())
2-element SVector{2, Float64} with indices SOneTo(2):
 0.7618992223709563
 0.5979657793050613

Firstly, there is a mistake in how you are indexing vector_list, where you do

for i in size(vector_list)

Let's see what that does:

julia> x = 1:10;

julia> size(x)
(10,)

The size of x is its length in each dimension, for a vector that is just (10,) since it has only one dimension. Let's try iterating:

julia> for i in size(x)
           println(i)
       end
10

It just prints out the number 10.

You probably meant

for i in 1:length(vector_list)

but it's better to write

for i in eachindex(vector_list)

since it is more general and safer.

As for your actual question, you can use StaticArrays.SOneTo which provides a static version of [1,2,3]:

function example_svector()
    vector_list = [@SVector randn(3) for q in 1:1000]
    N = length(eltype(vector_list))
    c = SOneTo(N)
    for i in eachindex(vector_list)
        vector_list[i] = vector_list[i] .* c
    end
    return vector_list
end
Related