Skip to content

Commit

Permalink
Merge pull request #50 from JuliaArrays/Scalar
Browse files Browse the repository at this point in the history
Added a `Scalar` type for 0-dimensional array
  • Loading branch information
andyferris authored Oct 12, 2016
2 parents 6f50031 + bba07c3 commit 437802e
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 2 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,18 @@ easier to define the types without the extra tuple characters (compare
because it is so easy to define new `StaticArray` subtypes, and they naturally
work together.

### `Scalar`

Sometimes you want to broadcast an operation, but not over one of your inputs.
A classic example is attempting to displace a collection of vectors by the
same vector. We can now do this with the `Scalar` type:

```julia
[[1,2,3], [4,5,6]] .+ Scalar([1,0,-1]) # [[2,2,2], [5,5,5]]
```

`Scalar` is simply an implementation of an immutable, 0-dimensional `StaticArray`.

### Mutable arrays: `MVector`, `MMatrix` and `MArray`

These statically sized arrays are identical to the above, but are defined as
Expand Down
27 changes: 27 additions & 0 deletions src/Scalar.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""
Scalar{T}(x::T)
Construct a statically-sized 0-dimensional array that contains a single element,
`x`. This type is particularly useful for influencing broadcasting operations.
"""
immutable Scalar{T} <: StaticArray{T,0}
data::T
end

@inline (::Type{Scalar{T}}){T}(x::Tuple{T}) = Scalar{T}(x[1])

@pure size(::Type{Scalar}) = ()
@pure size{T}(::Type{Scalar{T}}) = ()

getindex(v::Scalar) = v.data
@inline function getindex(v::Scalar, i::Int)
@boundscheck if i != 1
error("Attempt to index Scalar at index $i")
end
v.data
end

@inline Tuple(v::Scalar) = (v.data,)

# A lot more compact than the default array show
Base.show{T}(io::IO, ::MIME"text/plain", x::Scalar{T}) = print(io, "Scalar{$T}(", x.data, ")")
5 changes: 3 additions & 2 deletions src/StaticArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import Base: @pure, @propagate_inbounds, getindex, setindex!, size, similar,
ones, zeros, eye, cross, vecdot, reshape, fill, fill!, det, inv,
eig, trace, vecnorm, dot

export StaticArray, StaticVector, StaticMatrix
export SArray, SVector, SMatrix
export StaticScalar, StaticArray, StaticVector, StaticMatrix
export Scalar, SArray, SVector, SMatrix
export MArray, MVector, MMatrix
export FieldVector, MutableFieldVector

Expand All @@ -21,6 +21,7 @@ export similar_type
include("util.jl")

include("core.jl")
include("Scalar.jl")
include("SVector.jl")
include("FieldVector.jl")
include("SMatrix.jl")
Expand Down
4 changes: 4 additions & 0 deletions src/abstractarray.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
typealias StaticScalar{T} StaticArray{T,0}

@pure length{T<:StaticArray}(a::Union{T,Type{T}}) = prod(size(a))
@pure length{T<:StaticScalar}(a::Union{T,Type{T}}) = 1

@pure function size{T<:StaticArray}(a::Union{T,Type{T}}, d::Integer)
s = size(a)
Expand Down Expand Up @@ -104,6 +107,7 @@ end

# Some fallbacks

@pure similar_type{SA<:StaticArray}(::Union{SA,Type{SA}}, size::Tuple{}) = Scalar{eltype(SA)} # No mutable fallback here...
@pure similar_type{SA<:StaticArray}(::Union{SA,Type{SA}}, size::Int) = SVector{size, eltype(SA)}
@pure similar_type{SA<:StaticArray}(::Union{SA,Type{SA}}, sizes::Tuple{Int}) = SVector{sizes[1], eltype(SA)}

Expand Down
5 changes: 5 additions & 0 deletions test/Scalar.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@testset "Scalar" begin
@test Scalar(2) .* [1, 2, 3] == [2, 4, 6]
@test Scalar([1 2; 3 4]) .+ [[1 1; 1 1], [2 2; 2 2]] == [[2 3; 4 5], [3 4; 5 6]]
@test (Scalar(1) + Scalar(1.0))::Scalar{Float64} Scalar(2.0)
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using Base.Test
include("SArray.jl")
include("MArray.jl")
include("FieldVector.jl")
include("Scalar.jl")

include("core.jl")
include("abstractarray.jl")
Expand Down

0 comments on commit 437802e

Please sign in to comment.