Skip to content

SVector(1, 2, 3)[1:2] isa Array #372

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tkf opened this issue Feb 28, 2018 · 3 comments
Closed

SVector(1, 2, 3)[1:2] isa Array #372

tkf opened this issue Feb 28, 2018 · 3 comments

Comments

@tkf
Copy link
Member

tkf commented Feb 28, 2018

It seems that indexing with UnitRange and StepRange turns a SArray to an Array.

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

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

Tried it with current master (b454bc9) and Julia 0.6.2 and 0.7 (3a47cd4b2e).

@andyferris
Copy link
Member

That’s intentional, because we can’t statically determine the size of the output matrix it is fastest to treat it as a dynamically allocates array.

You can index with another static array, if that helps.

@tkf
Copy link
Member Author

tkf commented Feb 28, 2018

Thanks. But how about dynamically calculate the length and then use the same code as in inds::StaticVector? Is it still slower than going to Array?

import Base: getindex
import StaticArrays: _getindex
using Base: @propagate_inbounds, @_propagate_inbounds_meta
using StaticArrays

const Indexer = Union{StaticVector{<:Any, Int},
                      OrdinalRange{<:Int, <:Int}}

@propagate_inbounds function getindex(a::StaticArray, inds::OrdinalRange{<:Int, <:Int})
    _getindex(a, Length(length(inds)), inds)
end

# getindex for inds::StaticVector is the same as in the current master:
@propagate_inbounds function getindex(a::StaticArray, inds::StaticVector{<:Any, Int})
    _getindex(a, Length(inds), inds)
end

@generated function _getindex(a::StaticArray, ::Length{L}, inds::Indexer) where {L}
    exprs = [:(a[inds[$i]]) for i = 1:L]
    return quote
        @_propagate_inbounds_meta
        similar_type(a, Size(L))(tuple($(exprs...)))
    end
end


@assert SVector(1, 2, 3)[1:2] == SVector(1, 2)
@assert SVector(1, 2, 3)[end:-1:1] == SVector(3, 2, 1)

@tkf
Copy link
Member Author

tkf commented Feb 28, 2018

OK. I run a quick benchmark and going to the standard array is a lot faster, even though it takes some time to do GC. But I guess actually it makes sense since each inds[$i] call is done separately without utilizing any kind of continuity.

But I suppose range-based indexing to SArray will come once you define static ranges, as mentioned here?:
#223 (comment)

Anyway, I'm closing it since it was just my luck of understanding of StaticArrays.

@tkf tkf closed this as completed Feb 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants